diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9a7a08c38..d783e16e2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,13 @@ # Modifications to the source code should be handled by the review team -*.java @Slimefun/code-reviewers +*.java @Slimefun/code-reviewers # Modifications to sensitive files should be reviewed by maintainers -/.github/ @Slimefun/slimefun4-maintainers -pom.xml @Slimefun/slimefun4-maintainers -CONTRIBUTING.md @Slimefun/slimefun4-maintainers +/.github/ @Slimefun/slimefun4-maintainers +pom.xml @Slimefun/slimefun4-maintainers +CONTRIBUTING.md @Slimefun/slimefun4-maintainers + +# Changes to the Issue templates need to be checked by the triage team +/.github/ISSUE_TEMPLATE/ @Slimefun/bug-testers + +# This file is handled by TheBusyBiscuit (admins have overwrite access anyway) +/.github/CODEOWNERS @TheBusyBiscuit diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 2948bee8b..60e045b94 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -2,7 +2,7 @@ name: Bug Report about: Report a Bug or an Issue with Slimefun 4. title: '' -labels: '🐞 Bug Report' +labels: "\U0001F3AF Needs testing, \U0001F41E Bug Report" assignees: '' --- @@ -51,4 +51,4 @@ assignees: '' - Server Software: - Minecraft Version: - Slimefun Version: - - CS-CoreLib Version: + - CS-CoreLib Version: diff --git a/.github/workflows/discord-webhook.yml b/.github/workflows/discord-webhook.yml index d6edc5e08..5ff92bfd4 100644 --- a/.github/workflows/discord-webhook.yml +++ b/.github/workflows/discord-webhook.yml @@ -6,6 +6,8 @@ on: - 'src/**' - '!src/main/resources/languages/**' - 'pom.xml' + tags-ignore: + - 'RC.*' jobs: report: diff --git a/CHANGELOG.md b/CHANGELOG.md index 04a0b95ad..e694541bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ **Table of contents** -- [Release Candidate 19 (TBD)](#release-candidate-19-tbd) +- [Release Candidate 19 (11 Jan 2021)](#release-candidate-19-11-jan-2021) - [Release Candidate 18 (03 Dec 2020)](#release-candidate-18-03-dec-2020) - [Release Candidate 17 (17 Oct 2020)](#release-candidate-17-17-oct-2020) - [Release Candidate 16 (07 Sep 2020)](#release-candidate-16-07-sep-2020) @@ -24,14 +24,28 @@ -## Release Candidate 19 (TBD) +## Release Candidate 20 (TBD) + +#### Additions + +#### Changes + +#### Fixes +* Fixed elevator floor order + +## Release Candidate 19 (11 Jan 2021) #### Additions * Added Bee Armor (1.15+ only) +* (API) Added AndroidFarmEvent #### Changes * Performance optimizations for Cargo networks * Removed an old version of bStats +* CraftBukkit is officially no longer supported, Slimefun will now be disabled on old builds of CraftBukkit +* Removed the deprecated ItemManipulationAPI for BlockMenus +* Removed the "Written Book" variant of the Slimefun Guide +* The Elevator has an Inventory menu now #### Fixes * Fixed a couple of compatibility issues with ItemsAdder @@ -41,6 +55,8 @@ * Fixed #2647 * Fixed #2664 * Fixed #2655 +* Fixed /sf timings --verbose not working correctly +* Fixed #2675 ## Release Candidate 18 (03 Dec 2020) diff --git a/pom.xml b/pom.xml index fca4b564f..02a4dd503 100644 --- a/pom.xml +++ b/pom.xml @@ -9,10 +9,11 @@ - 4.8-UNOFFICIAL + 4.9-UNOFFICIAL 2013 jar + Slimefun is a Spigot/Paper plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server. https://github.com/Slimefun/Slimefun4 @@ -33,11 +34,13 @@ target/site/jacoco/jacoco.xml + GitHub Issues https://github.com/Slimefun/Slimefun4/issues + GNU General Public License v3.0 @@ -46,6 +49,7 @@ + spigot-repo @@ -77,11 +81,13 @@ + ${project.basedir}/src/main/java ${project.basedir}/src/test/java clean package + ${project.name} v${project.version} @@ -104,6 +110,7 @@ org.apache.maven.plugins maven-source-plugin 3.2.1 + attach-sources @@ -119,6 +126,11 @@ org.apache.maven.plugins maven-surefire-plugin 3.0.0-M5 + + + org.junit.jupiter:junit-jupiter + false + @@ -137,6 +149,7 @@ prepare + prepare-agent @@ -145,6 +158,7 @@ report test + report @@ -159,8 +173,7 @@ 3.2.4 - - + io.github.thebusybiscuit.cscorelib2 @@ -328,7 +341,7 @@ org.mockito mockito-core - 3.6.28 + 3.7.0 test @@ -336,7 +349,7 @@ com.github.TheBusyBiscuit CS-CoreLib2 - 0.27.4 + 0.29.1 compile @@ -348,7 +361,7 @@ com.konghq unirest-java - 3.11.09 + 3.11.10 compile @@ -362,7 +375,7 @@ com.sk89q.worldedit worldedit-bukkit - 7.2.0 + 7.2.1 provided @@ -380,7 +393,7 @@ com.gmail.nossr50.mcMMO mcMMO - 2.1.164 + 2.1.171 provided @@ -397,6 +410,13 @@ com.sk89q.worldguard worldguard-legacy + + + + + net.kyori + * + diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java index 7dbffa628..8aa6f31c6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java @@ -35,6 +35,9 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage; * an {@link ErrorReport} instead. * Error reports get saved in the plugin folder. * + * @param + * The type of {@link Throwable} which has spawned this {@link ErrorReport} + * * @author TheBusyBiscuit * */ @@ -222,6 +225,16 @@ public class ErrorReport { return newFile; } + /** + * This helper method wraps the given {@link Runnable} into a try-catch block. + * When an {@link Exception} occurs, a new {@link ErrorReport} will be generated using + * the provided {@link Function}. + * + * @param function + * The {@link Function} to generate a new {@link ErrorReport} + * @param runnable + * The code to execute + */ public static void tryCatch(@Nonnull Function> function, @Nonnull Runnable runnable) { try { runnable.run(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java index 73c3f855e..17238d76d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java @@ -6,6 +6,7 @@ import org.apache.commons.lang.Validate; import org.bukkit.Server; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.papermc.lib.PaperLib; /** * This enum holds all versions of Minecraft that we currently support. @@ -21,19 +22,19 @@ public enum MinecraftVersion { * This constant represents Minecraft (Java Edition) Version 1.14 * (The "Village & Pillage" Update) */ - MINECRAFT_1_14("1.14.x"), + MINECRAFT_1_14(14, "1.14.x"), /** * This constant represents Minecraft (Java Edition) Version 1.15 * (The "Buzzy Bees" Update) */ - MINECRAFT_1_15("1.15.x"), + MINECRAFT_1_15(15, "1.15.x"), /** * This constant represents Minecraft (Java Edition) Version 1.16 * (The "Nether Update") */ - MINECRAFT_1_16("1.16.x"), + MINECRAFT_1_16(16, "1.16.x"), /** * This constant represents an exceptional state in which we were unable @@ -51,18 +52,22 @@ public enum MinecraftVersion { private final String name; private final boolean virtual; - private final String prefix; + private final int majorVersion; /** * This constructs a new {@link MinecraftVersion} with the given name. * This constructor forces the {@link MinecraftVersion} to be real. * It must be a real version of Minecraft. * + * @param majorVersion + * The major version of minecraft as an {@link Integer} * @param name * The display name of this {@link MinecraftVersion} */ - MinecraftVersion(@Nonnull String name) { - this(name, false); + MinecraftVersion(int majorVersion, @Nonnull String name) { + this.name = name; + this.majorVersion = majorVersion; + this.virtual = false; } /** @@ -77,8 +82,8 @@ public enum MinecraftVersion { */ MinecraftVersion(@Nonnull String name, boolean virtual) { this.name = name; + this.majorVersion = 0; this.virtual = virtual; - this.prefix = name().replace("MINECRAFT_", "v") + '_'; } /** @@ -105,18 +110,21 @@ public enum MinecraftVersion { } /** - * This method checks whether the given version matches with this + * This tests if the given minecraft version number matches with this * {@link MinecraftVersion}. + *

+ * You can obtain the version number by doing {@link PaperLib#getMinecraftVersion()}. + * It is equivalent to the "major" version + *

+ * Example: {@literal "1.13"} returns {@literal 13} * - * @param version - * The version to compare + * @param minecraftVersion + * The {@link Integer} version to match * - * @return Whether the version matches with this one + * @return Whether this {@link MinecraftVersion} matches the specified version id */ - public boolean matches(@Nonnull String version) { - Validate.notNull(version, "The input version must not be null!"); - - return version.startsWith(prefix); + public boolean isMinecraftVersion(int minecraftVersion) { + return !isVirtual() && this.majorVersion == minecraftVersion; } /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunAddon.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunAddon.java index 610791493..39a402501 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunAddon.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunAddon.java @@ -1,21 +1,15 @@ package io.github.thebusybiscuit.slimefun4.api; -import java.util.Collection; -import java.util.Locale; import java.util.logging.Logger; -import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.commons.lang.Validate; -import org.bukkit.NamespacedKey; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** @@ -106,16 +100,4 @@ public interface SlimefunAddon { return description.getDepend().contains(dependency) || description.getSoftDepend().contains(dependency); } - /** - * This returns a {@link Collection} holding every {@link Category} that can be directly - * linked to this {@link SlimefunAddon} based on its {@link NamespacedKey}. - * - * @return A {@link Collection} of every {@link Category} from this addon - */ - @Nonnull - default Collection getCategories() { - String namespace = getJavaPlugin().getName().toLowerCase(Locale.ROOT); - return SlimefunPlugin.getRegistry().getCategories().stream().filter(cat -> cat.getKey().getNamespace().equals(namespace)).collect(Collectors.toList()); - } - } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java index a71bb461b..2e282d966 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AncientAltarCraftEvent.java @@ -34,10 +34,10 @@ public class AncientAltarCraftEvent extends PlayerEvent implements Cancellable { private boolean cancelled; /** - * @param block - * The altar {@link Block} * @param output * The {@link ItemStack} that would be dropped by the ritual + * @param block + * The altar {@link Block} * @param player * The {@link Player} that started the ritual. */ diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidFarmEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidFarmEvent.java new file mode 100644 index 000000000..e2a3d1c9c --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidFarmEvent.java @@ -0,0 +1,122 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInstance; +import io.github.thebusybiscuit.slimefun4.implementation.items.androids.FarmerAndroid; + +/** + * This {@link Event} is fired before a {@link FarmerAndroid} harvests a {@link Block}. + * If this {@link Event} is cancelled, the {@link Block} will not be harvested. + *

+ * The {@link Event} will still be fired for non-harvestable blocks. + * + * @author TheBusyBiscuit + * + */ +public class AndroidFarmEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private final Block block; + private final AndroidInstance android; + private final boolean isAdvanced; + private ItemStack drop; + private boolean cancelled; + + /** + * @param block + * The harvested {@link Block} + * @param android + * The {@link AndroidInstance} that triggered this {@link Event} + * @param isAdvanced + * Whether this is an advanced farming action + * @param drop + * The item to be dropped or null + */ + public AndroidFarmEvent(@Nonnull Block block, @Nonnull AndroidInstance android, boolean isAdvanced, @Nullable ItemStack drop) { + this.block = block; + this.android = android; + this.isAdvanced = isAdvanced; + this.drop = drop; + } + + /** + * This method returns the mined {@link Block} + * + * @return the mined {@link Block} + */ + @Nonnull + public Block getBlock() { + return block; + } + + /** + * This returns the harvested item or null. + * + * @return The harvested item or null + */ + @Nullable + public ItemStack getDrop() { + return drop; + } + + /** + * Whether this was invoked via an advanced farming action + * + * @return Whether it is advanced + */ + public boolean isAdvanced() { + return isAdvanced; + } + + /** + * This will set the {@link ItemStack} result. + * + * @param drop + * The result or null + */ + public void setDrop(@Nullable ItemStack drop) { + this.drop = drop; + } + + /** + * This method returns the {@link AndroidInstance} who + * triggered this {@link Event} + * + * @return the involved {@link AndroidInstance} + */ + @Nonnull + public AndroidInstance getAndroid() { + return android; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Nonnull + public static HandlerList getHandlerList() { + return handlers; + } + + @Nonnull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerPreResearchEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerPreResearchEvent.java index d80efd9b1..9edcb48a0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerPreResearchEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerPreResearchEvent.java @@ -3,16 +3,16 @@ package io.github.thebusybiscuit.slimefun4.api.events; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import org.apache.commons.lang.Validate; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; -import org.apache.commons.lang.Validate; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + import io.github.thebusybiscuit.slimefun4.core.researching.Research; -import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; -import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** * This {@link Event} is called whenever a {@link Player} clicks to unlock a {@link Research}. @@ -21,8 +21,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefu * * @author uiytt * - * @see ChestSlimefunGuide - * @see BookSlimefunGuide + * @see SurvivalSlimefunGuide * */ public class PlayerPreResearchEvent extends Event implements Cancellable { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java index 4d09ebbed..f292df16e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/PlayerRightClickEvent.java @@ -16,7 +16,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; -import io.github.thebusybiscuit.cscorelib2.data.ComputedOptional; +import io.github.thebusybiscuit.cscorelib2.data.TriStateOptional; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -46,8 +46,8 @@ public class PlayerRightClickEvent extends PlayerEvent { private final EquipmentSlot hand; private final BlockFace face; - private ComputedOptional slimefunItem = ComputedOptional.createNew(); - private ComputedOptional slimefunBlock = ComputedOptional.createNew(); + private TriStateOptional slimefunItem = TriStateOptional.createNew(); + private TriStateOptional slimefunBlock = TriStateOptional.createNew(); private Result itemResult; private Result blockResult; @@ -127,7 +127,7 @@ public class PlayerRightClickEvent extends PlayerEvent { if (itemStack.isPresent()) { slimefunItem.compute(SlimefunItem.getByItem(itemStack.get())); } else { - slimefunItem = ComputedOptional.empty(); + slimefunItem = TriStateOptional.empty(); } } @@ -140,7 +140,7 @@ public class PlayerRightClickEvent extends PlayerEvent { if (clickedBlock.isPresent()) { slimefunBlock.compute(BlockStorage.check(clickedBlock.get())); } else { - slimefunBlock = ComputedOptional.empty(); + slimefunBlock = TriStateOptional.empty(); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java index 2fdbe469a..f4892242a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java @@ -9,14 +9,14 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; /** * This {@link Event} is called whenever a {@link Player} tries to open the Slimefun Guide book. * * @author Linox * - * @see SlimefunGuideLayout + * @see SlimefunGuideMode */ public class SlimefunGuideOpenEvent extends Event implements Cancellable { @@ -24,10 +24,10 @@ public class SlimefunGuideOpenEvent extends Event implements Cancellable { private final Player player; private final ItemStack guide; - private SlimefunGuideLayout layout; + private SlimefunGuideMode layout; private boolean cancelled; - public SlimefunGuideOpenEvent(@Nonnull Player p, @Nonnull ItemStack guide, @Nonnull SlimefunGuideLayout layout) { + public SlimefunGuideOpenEvent(@Nonnull Player p, @Nonnull ItemStack guide, @Nonnull SlimefunGuideMode layout) { Validate.notNull(p, "The Player cannot be null"); Validate.notNull(guide, "Guide cannot be null"); Validate.notNull(layout, "Layout cannot be null"); @@ -59,23 +59,23 @@ public class SlimefunGuideOpenEvent extends Event implements Cancellable { } /** - * This returns the {@link SlimefunGuideLayout} of the Slimefun Guide + * This returns the {@link SlimefunGuideMode} of the Slimefun Guide * that {@link Player} tries to open. * - * @return The {@link SlimefunGuideLayout} + * @return The {@link SlimefunGuideMode} */ @Nonnull - public SlimefunGuideLayout getGuideLayout() { + public SlimefunGuideMode getGuideLayout() { return layout; } /** - * Changes the {@link SlimefunGuideLayout} that was tried to be opened with. + * Changes the {@link SlimefunGuideMode} that was tried to be opened with. * * @param layout - * The new {@link SlimefunGuideLayout} + * The new {@link SlimefunGuideMode} */ - public void setGuideLayout(@Nonnull SlimefunGuideLayout layout) { + public void setGuideLayout(@Nonnull SlimefunGuideMode layout) { Validate.notNull(layout, "You must specify a layout that is not-null!"); this.layout = layout; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java index 649a0ea48..69a8a0d72 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java @@ -23,7 +23,6 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatInput; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.api.events.WaypointCreateEvent; import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.api.geo.ResourceManager; @@ -34,6 +33,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSTransmitte import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -157,7 +157,7 @@ public class GPSNetwork { if (sfi instanceof GPSTransmitter) { int slot = inventory[index]; - menu.addItem(slot, new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&bGPS Transmitter", "&8\u21E8 &7World: &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "", "&8\u21E8 &7Signal Strength: &f" + ((GPSTransmitter) sfi).getMultiplier(l.getBlockY()), "&8\u21E8 &7Ping: &f" + DoubleHandler.fixDouble(1000D / l.getY()) + "ms")); + menu.addItem(slot, new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&bGPS Transmitter", "&8\u21E8 &7World: &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "", "&8\u21E8 &7Signal Strength: &f" + ((GPSTransmitter) sfi).getMultiplier(l.getBlockY()), "&8\u21E8 &7Ping: &f" + NumberUtils.roundDecimalNumber(1000D / l.getY()) + "ms")); menu.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler()); index++; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java index eb0ee827a..2d11263fa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java @@ -20,11 +20,11 @@ import org.bukkit.potion.PotionEffectType; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.papermc.lib.PaperLib; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; @@ -64,7 +64,7 @@ public final class TeleportationManager { int slot = teleporterInventory[index]; Location l = waypoint.getLocation(); - double time = DoubleHandler.fixDouble(0.5 * getTeleportationTime(complexity, source, l)); + double time = NumberUtils.reparseDouble(0.5 * getTeleportationTime(complexity, source, l)); String[] lore = { "", "&8\u21E8 &7" + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.world") + ": &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "&8\u21E8 &7" + SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.gui.time") + ": &f" + time + "s", "", "&8\u21E8 &c" + SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.gui.tooltip") }; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java index 8d0a27c14..b2f8ed180 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java @@ -10,7 +10,6 @@ import org.apache.commons.lang.Validate; import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This class represents a Setting for a {@link SlimefunItem} that can be modified via @@ -152,19 +151,19 @@ public class ItemSetting { if (validateInput(newValue)) { this.value = newValue; } else { - Slimefun.getLogger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!"); - Slimefun.getLogger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getId(), getKey() }); - Slimefun.getLogger().log(Level.WARNING, "{0} is not a valid input!", configuredValue); - Slimefun.getLogger().log(Level.WARNING, getErrorMessage()); + SlimefunPlugin.logger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!"); + SlimefunPlugin.logger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getId(), getKey() }); + SlimefunPlugin.logger().log(Level.WARNING, "{0} is not a valid input!", configuredValue); + SlimefunPlugin.logger().log(Level.WARNING, getErrorMessage()); } } else { this.value = defaultValue; String found = configuredValue == null ? "null" : configuredValue.getClass().getSimpleName(); - Slimefun.getLogger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!"); - Slimefun.getLogger().log(Level.WARNING, "Please only use settings that are valid."); - Slimefun.getLogger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getId(), getKey() }); - Slimefun.getLogger().log(Level.WARNING, "Expected \"{0}\" but found: \"{1}\"", new Object[] { defaultValue.getClass().getSimpleName(), found }); + SlimefunPlugin.logger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!"); + SlimefunPlugin.logger().log(Level.WARNING, "Please only use settings that are valid."); + SlimefunPlugin.logger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getId(), getKey() }); + SlimefunPlugin.logger().log(Level.WARNING, "Expected \"{0}\" but found: \"{1}\"", new Object[] { defaultValue.getClass().getSimpleName(), found }); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/settings/EnumSetting.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/settings/EnumSetting.java index d952286af..480c4afb8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/settings/EnumSetting.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/settings/EnumSetting.java @@ -12,6 +12,9 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; * This variation of {@link ItemSetting} allows you to allow {@link Enum} constants to be * used for {@link ItemSetting} validation. * + * @param + * The {@link Enum} type + * * @author TheBusyBiscuit * * @see ItemSetting @@ -41,6 +44,7 @@ public class EnumSetting> extends ItemSetting { * * @return An array of allowed {@link Enum} constants */ + @Nonnull public T[] getAllowedValues() { return enumClass.getEnumConstants(); } @@ -50,6 +54,7 @@ public class EnumSetting> extends ItemSetting { * * @return The value as an {@link Enum} constant */ + @Nonnull public T getAsEnumConstant() { return Enum.valueOf(enumClass, getValue()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java index e6d745773..d54bd75c0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java @@ -43,7 +43,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * A class that can store a Player's {@link Research} progress for caching purposes. @@ -96,7 +95,7 @@ public final class PlayerProfile { waypoints.add(new Waypoint(this, key, loc, waypointName)); } } catch (Exception x) { - Slimefun.getLogger().log(Level.WARNING, x, () -> "Could not load Waypoint \"" + key + "\" for Player \"" + p.getName() + '"'); + SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Could not load Waypoint \"" + key + "\" for Player \"" + p.getName() + '"'); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java index e3af4f416..c7133aa03 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -14,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nonnull; import org.apache.commons.lang.Validate; +import org.bukkit.NamespacedKey; import org.bukkit.Server; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -25,12 +26,12 @@ import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock; import io.github.thebusybiscuit.slimefun4.core.researching.Research; -import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; -import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -71,12 +72,16 @@ public final class SlimefunRegistry { private final Set radioactive = new HashSet<>(); private final Set barterDrops = new HashSet<>(); + private NamespacedKey soulboundKey; + private NamespacedKey itemChargeKey; + private NamespacedKey guideKey; + private final KeyMap geoResources = new KeyMap<>(); private final Map profiles = new ConcurrentHashMap<>(); private final Map worlds = new ConcurrentHashMap<>(); private final Map chunks = new HashMap<>(); - private final Map layouts = new EnumMap<>(SlimefunGuideLayout.class); + private final Map guides = new EnumMap<>(SlimefunGuideMode.class); private final Map> mobDrops = new EnumMap<>(EntityType.class); private final Map blockMenuPresets = new HashMap<>(); @@ -84,14 +89,17 @@ public final class SlimefunRegistry { private final Map, Set> globalItemHandlers = new HashMap<>(); private final Map blockHandlers = new HashMap<>(); - public void load(@Nonnull Config cfg) { + public void load(@Nonnull SlimefunPlugin plugin, @Nonnull Config cfg) { + Validate.notNull(plugin, "The Plugin cannot be null!"); Validate.notNull(cfg, "The Config cannot be null!"); - boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); + soulboundKey = new NamespacedKey(plugin, "soulbound"); + itemChargeKey = new NamespacedKey(plugin, "item_charge"); + guideKey = new NamespacedKey(plugin, "slimefun_guide_mode"); - layouts.put(SlimefunGuideLayout.CHEST, new ChestSlimefunGuide(showVanillaRecipes)); - layouts.put(SlimefunGuideLayout.CHEAT_SHEET, new CheatSheetSlimefunGuide()); - layouts.put(SlimefunGuideLayout.BOOK, new BookSlimefunGuide()); + boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); + guides.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide(showVanillaRecipes)); + guides.put(SlimefunGuideMode.CHEAT_MODE, new CheatSheetSlimefunGuide()); researchRanks.addAll(cfg.getStringList("research-ranks")); @@ -132,6 +140,7 @@ public final class SlimefunRegistry { automaticallyLoadItems = mode; } + @Nonnull public List getCategories() { return categories; } @@ -141,6 +150,7 @@ public final class SlimefunRegistry { * * @return A {@link List} containing every {@link SlimefunItem} */ + @Nonnull public List getAllSlimefunItems() { return slimefunItems; } @@ -150,18 +160,22 @@ public final class SlimefunRegistry { * * @return A {@link List} containing every enabled {@link SlimefunItem} */ + @Nonnull public List getEnabledSlimefunItems() { return enabledItems; } + @Nonnull public List getResearches() { return researches; } + @Nonnull public Set getCurrentlyResearchingPlayers() { return researchingPlayers; } + @Nonnull public List getResearchRanks() { return researchRanks; } @@ -186,12 +200,31 @@ public final class SlimefunRegistry { return researchFireworks; } + @Nonnull public List getMultiBlocks() { return multiblocks; } - public SlimefunGuideImplementation getGuideLayout(SlimefunGuideLayout layout) { - return layouts.get(layout); + /** + * This returns the corresponding {@link SlimefunGuideImplementation} for a certain + * {@link SlimefunGuideMode}. + * + * @param mode + * The {@link SlimefunGuideMode} + * + * @return The corresponding {@link SlimefunGuideImplementation} + */ + @Nonnull + public SlimefunGuideImplementation getSlimefunGuide(@Nonnull SlimefunGuideMode mode) { + Validate.notNull(mode, "The Guide mode cannot be null"); + + SlimefunGuideImplementation guide = guides.get(mode); + + if (guide == null) { + throw new IllegalStateException("Slimefun Guide '" + mode + "' has no registered implementation."); + } + + return guide; } /** @@ -200,6 +233,7 @@ public final class SlimefunRegistry { * * @return The {@link Map} of custom mob drops */ + @Nonnull public Map> getMobDrops() { return mobDrops; } @@ -210,50 +244,62 @@ public final class SlimefunRegistry { * * @return A {@link Set} of bartering drops */ + @Nonnull public Set getBarteringDrops() { return barterDrops; } + @Nonnull public Set getRadioactiveItems() { return radioactive; } + @Nonnull public Set getTickerBlocks() { return tickers; } + @Nonnull public Map getSlimefunItemIds() { return slimefunIds; } + @Nonnull public Map getMenuPresets() { return blockMenuPresets; } + @Nonnull public Map getUniversalInventories() { return universalInventories; } + @Nonnull public Map getPlayerProfiles() { return profiles; } + @Nonnull public Map, Set> getPublicItemHandlers() { return globalItemHandlers; } + @Nonnull public Map getBlockHandlers() { return blockHandlers; } + @Nonnull public Map getWorlds() { return worlds; } + @Nonnull public Map getChunks() { return chunks; } + @Nonnull public KeyMap getGEOResources() { return geoResources; } @@ -262,4 +308,19 @@ public final class SlimefunRegistry { return logDuplicateBlockEntries; } + @Nonnull + public NamespacedKey getSoulboundDataKey() { + return soulboundKey; + } + + @Nonnull + public NamespacedKey getItemChargeDataKey() { + return itemChargeKey; + } + + @Nonnull + public NamespacedKey getGuideDataKey() { + return guideKey; + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java index b0e47b1a5..65ea56133 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java @@ -28,7 +28,6 @@ import net.md_5.bungee.api.ChatColor; */ final class RechargeableHelper { - private static final NamespacedKey CHARGE_KEY = new NamespacedKey(SlimefunPlugin.instance(), "item_charge"); private static final String LORE_PREFIX = ChatColors.color("&8\u21E8 &e\u26A1 &7"); private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "[0-9.]+ / [0-9.]+ J"); @@ -38,7 +37,8 @@ final class RechargeableHelper { BigDecimal decimal = BigDecimal.valueOf(charge).setScale(2, RoundingMode.HALF_UP); float value = decimal.floatValue(); - meta.getPersistentDataContainer().set(CHARGE_KEY, PersistentDataType.FLOAT, value); + NamespacedKey key = SlimefunPlugin.getRegistry().getItemChargeDataKey(); + meta.getPersistentDataContainer().set(key, PersistentDataType.FLOAT, value); List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); for (int i = 0; i < lore.size(); i++) { @@ -56,7 +56,8 @@ final class RechargeableHelper { } static float getCharge(@Nonnull ItemMeta meta) { - Float value = meta.getPersistentDataContainer().get(CHARGE_KEY, PersistentDataType.FLOAT); + NamespacedKey key = SlimefunPlugin.getRegistry().getItemChargeDataKey(); + Float value = meta.getPersistentDataContainer().get(key, PersistentDataType.FLOAT); // If persistent data is available, we just return this value if (value != null) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/FlexCategory.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/FlexCategory.java index 28a05cfa9..2d7d2994d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/FlexCategory.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/FlexCategory.java @@ -11,7 +11,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -45,12 +45,12 @@ public abstract class FlexCategory extends Category { * @param profile * The {@link PlayerProfile} of the {@link Player} * @param layout - * The {@link SlimefunGuideLayout} in which this {@link FlexCategory} is viewed + * The {@link SlimefunGuideMode} in which this {@link FlexCategory} is viewed * * @return Whether to display this {@link FlexCategory} */ @ParametersAreNonnullByDefault - public abstract boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideLayout layout); + public abstract boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideMode layout); /** * This method is called when a {@link Player} opens this {@link FlexCategory}. @@ -62,13 +62,13 @@ public abstract class FlexCategory extends Category { * @param profile * The corresponding {@link PlayerProfile} for that {@link Player} * @param layout - * The current {@link SlimefunGuideLayout} + * The current {@link SlimefunGuideMode} */ - public abstract void open(Player p, PlayerProfile profile, SlimefunGuideLayout layout); + public abstract void open(Player p, PlayerProfile profile, SlimefunGuideMode layout); @Override public final boolean isHidden(@Nonnull Player p) { - /** + /* * We can stop this method right here. * We provide a custom method with more parameters for this. * See isVisible(...) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/LockedCategory.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/LockedCategory.java index 69b2434cd..7056eadcf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/LockedCategory.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/LockedCategory.java @@ -14,6 +14,7 @@ import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -76,8 +77,8 @@ public class LockedCategory extends Category { } @Override - public void register() { - super.register(); + public void register(@Nonnull SlimefunAddon addon) { + super.register(addon); List namespacedKeys = new ArrayList<>(); @@ -94,7 +95,7 @@ public class LockedCategory extends Category { } for (NamespacedKey key : namespacedKeys) { - Slimefun.getLogger().log(Level.INFO, "Parent \"{0}\" for Category \"{1}\" was not found, probably just disabled.", new Object[] { key, getKey() }); + SlimefunPlugin.logger().log(Level.INFO, "Parent \"{0}\" for Category \"{1}\" was not found, probably just disabled.", new Object[] { key, getKey() }); } } @@ -148,12 +149,13 @@ public class LockedCategory extends Category { * The {@link Player} to check * @param profile * The {@link PlayerProfile} that belongs to the given {@link Player} + * * @return Whether the {@link Player} has fully completed all parent categories, otherwise false */ public boolean hasUnlocked(@Nonnull Player p, @Nonnull PlayerProfile profile) { for (Category category : parents) { for (SlimefunItem item : category.getItems()) { - /** + /* * Should probably be replaced with Slimefun.hasUnlocked(...) * However this will result in better performance because we don't * request the PlayerProfile everytime diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java index ce0c4ea94..c0f6a1949 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GuideCommand.java @@ -6,7 +6,7 @@ import org.bukkit.entity.Player; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class GuideCommand extends SubCommand { @@ -19,7 +19,7 @@ class GuideCommand extends SubCommand { public void onExecute(CommandSender sender, String[] args) { if (sender instanceof Player) { if (sender.hasPermission("slimefun.command.guide")) { - SlimefunGuideLayout design = SlimefunGuide.getDefaultLayout(); + SlimefunGuideMode design = SlimefunGuide.getDefaultMode(); ((Player) sender).getInventory().addItem(SlimefunGuide.getItem(design).clone()); } else { SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java index a4af9f2bd..8947d989f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/OpenGuideCommand.java @@ -1,12 +1,14 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class OpenGuideCommand extends SubCommand { @@ -16,11 +18,11 @@ class OpenGuideCommand extends SubCommand { } @Override + @ParametersAreNonnullByDefault public void onExecute(CommandSender sender, String[] args) { if (sender instanceof Player) { if (sender.hasPermission("slimefun.command.open_guide")) { - boolean book = SlimefunPlugin.getCfg().getBoolean("guide.default-view-book"); - SlimefunGuide.openGuide((Player) sender, book ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST); + SlimefunGuide.openGuide((Player) sender, SlimefunGuideMode.SURVIVAL_MODE); } else { SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java index af311645f..c52927221 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SearchCommand.java @@ -9,6 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class SearchCommand extends SubCommand { @@ -23,7 +24,7 @@ class SearchCommand extends SubCommand { if (sender.hasPermission("slimefun.command.search")) { if (args.length > 1) { String query = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); - PlayerProfile.get((Player) sender, profile -> SlimefunGuide.openSearch(profile, query, true, true)); + PlayerProfile.get((Player) sender, profile -> SlimefunGuide.openSearch(profile, query, SlimefunGuideMode.SURVIVAL_MODE, true)); } else { SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search ")); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java index 5498a5e9d..3673f48a6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/TimingsCommand.java @@ -1,26 +1,97 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; +import io.github.thebusybiscuit.slimefun4.core.services.profiler.PerformanceInspector; +import io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors.ConsolePerformanceInspector; +import io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors.PlayerPerformanceInspector; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; class TimingsCommand extends SubCommand { + private static final String FLAG_PREFIX = "--"; + private final Set flags = new HashSet<>(Arrays.asList("verbose")); + TimingsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { super(plugin, cmd, "timings", false); } + @Override + protected String getDescription() { + return "commands.timings.description"; + } + @Override public void onExecute(CommandSender sender, String[] args) { if (sender.hasPermission("slimefun.command.timings") || sender instanceof ConsoleCommandSender) { - sender.sendMessage("Please wait a second... The results are coming in!"); - SlimefunPlugin.getProfiler().requestSummary(sender); + if (hasInvalidFlags(sender, args)) { + return; + } + + boolean verbose = hasFlag(args, "verbose"); + + if (verbose && sender instanceof Player) { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.timings.verbose-player", true); + return; + } + + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.timings.please-wait", true); + + PerformanceInspector inspector = inspectorOf(sender, verbose); + SlimefunPlugin.getProfiler().requestSummary(inspector); } else { SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); } } + @ParametersAreNonnullByDefault + private boolean hasInvalidFlags(CommandSender sender, String[] args) { + boolean hasInvalidFlags = false; + + // We start at 1 because args[0] will be "timings". + for (int i = 1; i < args.length; i++) { + String argument = args[i].toLowerCase(Locale.ROOT); + + if (argument.startsWith(FLAG_PREFIX) && !flags.contains(argument.substring(2))) { + hasInvalidFlags = true; + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.timings.unknown-flag", true, msg -> msg.replace("%flag%", argument)); + } + } + + return hasInvalidFlags; + } + + @ParametersAreNonnullByDefault + private boolean hasFlag(String[] args, String flag) { + // We start at 1 because args[0] will be "timings". + for (int i = 1; i < args.length; i++) { + if (args[i].equalsIgnoreCase(FLAG_PREFIX + flag)) { + return true; + } + } + + return false; + } + + @Nonnull + private PerformanceInspector inspectorOf(@Nonnull CommandSender sender, boolean verbose) { + if (sender instanceof Player) { + return new PlayerPerformanceInspector((Player) sender); + } else { + return new ConsolePerformanceInspector(sender, verbose); + } + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java index 0ede8e61f..d9e135ffe 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java @@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands; import java.util.Collection; +import javax.annotation.Nonnull; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -9,7 +10,6 @@ import org.bukkit.command.ConsoleCommandSender; import org.bukkit.plugin.Plugin; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -22,14 +22,14 @@ class VersionsCommand extends SubCommand { } @Override - public void onExecute(CommandSender sender, String[] args) { + public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) { if (sender.hasPermission("slimefun.command.versions") || sender instanceof ConsoleCommandSender) { // After all these years... Spigot still displays as "CraftBukkit" // so we will just fix this inconsistency for them :) String serverSoftware = PaperLib.isSpigot() && !PaperLib.isPaper() ? "Spigot" : Bukkit.getName(); sender.sendMessage(ChatColor.GRAY + "This Server uses the following setup of Slimefun:"); - sender.sendMessage(ChatColors.color("&a" + serverSoftware + " &2" + ReflectionUtils.getVersion())); + sender.sendMessage(ChatColors.color("&a" + serverSoftware + " &2" + Bukkit.getVersion())); sender.sendMessage(ChatColors.color("&aCS-CoreLib &2v" + SlimefunPlugin.getCSCoreLibVersion())); sender.sendMessage(ChatColors.color("&aSlimefun &2v" + SlimefunPlugin.getVersion())); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java index 94970ac43..779f634d1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java @@ -3,15 +3,19 @@ package io.github.thebusybiscuit.slimefun4.core.guide; import java.util.Optional; import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; -import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; + import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; +import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -22,36 +26,35 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; * @author TheBusyBiscuit * * @see SlimefunGuideImplementation - * @see ChestSlimefunGuide - * @see BookSlimefunGuide + * @see SurvivalSlimefunGuide * */ public final class SlimefunGuide { private SlimefunGuide() {} - public static ItemStack getItem(@Nonnull SlimefunGuideLayout design) { - return SlimefunPlugin.getRegistry().getGuideLayout(design).getItem(); + @Nonnull + public static ItemStack getItem(@Nonnull SlimefunGuideMode design) { + return SlimefunPlugin.getRegistry().getSlimefunGuide(design).getItem(); } - public static void openCheatMenu(Player p) { - openMainMenuAsync(p, SlimefunGuideLayout.CHEAT_SHEET, 1); + public static void openCheatMenu(@Nonnull Player p) { + openMainMenuAsync(p, SlimefunGuideMode.CHEAT_MODE, 1); } - public static void openGuide(Player p, ItemStack guide) { - if (SlimefunUtils.isItemSimilar(guide, getItem(SlimefunGuideLayout.CHEST), true)) { - openGuide(p, SlimefunGuideLayout.CHEST); - } else if (SlimefunUtils.isItemSimilar(guide, getItem(SlimefunGuideLayout.BOOK), true)) { - openGuide(p, SlimefunGuideLayout.BOOK); - } else if (SlimefunUtils.isItemSimilar(guide, getItem(SlimefunGuideLayout.CHEAT_SHEET), true)) { - openGuide(p, SlimefunGuideLayout.CHEAT_SHEET); + public static void openGuide(@Nonnull Player p, @Nullable ItemStack guide) { + if (getItem(SlimefunGuideMode.CHEAT_MODE).equals(guide)) { + openGuide(p, SlimefunGuideMode.CHEAT_MODE); } else { - // When using /sf cheat or /sf open_guide, ItemStack is null. - openGuide(p, SlimefunGuideLayout.CHEST); + /* + * When using /sf cheat or /sf open_guide the ItemStack is null anyway, + * so we don't even need to check here at this point. + */ + openGuide(p, SlimefunGuideMode.SURVIVAL_MODE); } } - public static void openGuide(Player p, SlimefunGuideLayout layout) { + public static void openGuide(@Nonnull Player p, @Nonnull SlimefunGuideMode mode) { if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) { return; } @@ -60,58 +63,72 @@ public final class SlimefunGuide { if (optional.isPresent()) { PlayerProfile profile = optional.get(); - SlimefunGuideImplementation guide = SlimefunPlugin.getRegistry().getGuideLayout(layout); + SlimefunGuideImplementation guide = SlimefunPlugin.getRegistry().getSlimefunGuide(mode); profile.getGuideHistory().openLastEntry(guide); } else { - openMainMenuAsync(p, layout, 1); + openMainMenuAsync(p, mode, 1); } } - private static void openMainMenuAsync(Player player, SlimefunGuideLayout layout, int selectedPage) { - if (!PlayerProfile.get(player, profile -> SlimefunPlugin.runSync(() -> openMainMenu(profile, layout, selectedPage)))) { + @ParametersAreNonnullByDefault + private static void openMainMenuAsync(Player player, SlimefunGuideMode mode, int selectedPage) { + if (!PlayerProfile.get(player, profile -> SlimefunPlugin.runSync(() -> openMainMenu(profile, mode, selectedPage)))) { SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide"); } } - public static void openMainMenu(PlayerProfile profile, SlimefunGuideLayout layout, int selectedPage) { - SlimefunPlugin.getRegistry().getGuideLayout(layout).openMainMenu(profile, selectedPage); + @ParametersAreNonnullByDefault + public static void openMainMenu(PlayerProfile profile, SlimefunGuideMode mode, int selectedPage) { + SlimefunPlugin.getRegistry().getSlimefunGuide(mode).openMainMenu(profile, selectedPage); } - public static void openCategory(PlayerProfile profile, Category category, SlimefunGuideLayout layout, int selectedPage) { - if (category == null) { - return; - } - - SlimefunPlugin.getRegistry().getGuideLayout(layout).openCategory(profile, category, selectedPage); + @ParametersAreNonnullByDefault + public static void openCategory(PlayerProfile profile, Category category, SlimefunGuideMode mode, int selectedPage) { + SlimefunPlugin.getRegistry().getSlimefunGuide(mode).openCategory(profile, category, selectedPage); } - public static void openSearch(PlayerProfile profile, String input, boolean survival, boolean addToHistory) { - SlimefunGuideImplementation layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEST); - - if (!survival) { - layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEAT_SHEET); - } - - layout.openSearch(profile, input, addToHistory); + @ParametersAreNonnullByDefault + public static void openSearch(PlayerProfile profile, String input, SlimefunGuideMode mode, boolean addToHistory) { + SlimefunGuideImplementation guide = SlimefunPlugin.getRegistry().getSlimefunGuide(mode); + guide.openSearch(profile, input, addToHistory); } + @ParametersAreNonnullByDefault public static void displayItem(PlayerProfile profile, ItemStack item, boolean addToHistory) { - SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEST).displayItem(profile, item, 0, addToHistory); + SlimefunPlugin.getRegistry().getSlimefunGuide(SlimefunGuideMode.SURVIVAL_MODE).displayItem(profile, item, 0, addToHistory); } + @ParametersAreNonnullByDefault public static void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) { - SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.CHEST).displayItem(profile, item, addToHistory); + SlimefunPlugin.getRegistry().getSlimefunGuide(SlimefunGuideMode.SURVIVAL_MODE).displayItem(profile, item, addToHistory); } - public static boolean isGuideItem(ItemStack item) { - return SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.CHEST), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.BOOK), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.CHEAT_SHEET), true); - } - - public static SlimefunGuideLayout getDefaultLayout() { - if (SlimefunPlugin.getCfg().getBoolean("guide.default-view-book")) { - return SlimefunGuideLayout.BOOK; + /** + * This method checks if a given {@link ItemStack} is a {@link SlimefunGuide}. + * + * @param item + * The {@link ItemStack} to check + * + * @return Whether this {@link ItemStack} represents a {@link SlimefunGuide} + */ + public static boolean isGuideItem(@Nullable ItemStack item) { + if (item == null || item.getType() != Material.ENCHANTED_BOOK) { + return false; + } else if (item instanceof SlimefunGuideItem) { + return true; } else { - return SlimefunGuideLayout.CHEST; + return SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideMode.SURVIVAL_MODE), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideMode.CHEAT_MODE), true); } } + + /** + * Get the default mode for the Slimefun guide. + * Currently this is only {@link SlimefunGuideMode#SURVIVAL_MODE}. + * + * @return The default {@link SlimefunGuideMode}. + */ + @Nonnull + public static SlimefunGuideMode getDefaultMode() { + return SlimefunGuideMode.SURVIVAL_MODE; + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java index 5ed728760..873ce5105 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java @@ -11,8 +11,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; -import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -22,21 +21,20 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; * * @author TheBusyBiscuit * - * @see SlimefunGuideLayout - * @see ChestSlimefunGuide - * @see BookSlimefunGuide + * @see SlimefunGuideMode + * @see SurvivalSlimefunGuide * */ public interface SlimefunGuideImplementation { /** * Every {@link SlimefunGuideImplementation} can be associated with a - * {@link SlimefunGuideLayout}. + * {@link SlimefunGuideMode}. * - * @return The layout this {@link SlimefunGuideImplementation} represents + * @return The mode this {@link SlimefunGuideImplementation} represents */ @Nonnull - SlimefunGuideLayout getLayout(); + SlimefunGuideMode getMode(); /** * Returns the {@link ItemStack} representation for this {@link SlimefunGuideImplementation}. @@ -48,14 +46,6 @@ public interface SlimefunGuideImplementation { @Nonnull ItemStack getItem(); - /** - * This method returns whether this {@link SlimefunGuideImplementation} is meant - * for Survival Mode. - * - * @return Whether this is a survival mode implementation - */ - boolean isSurvivalMode(); - void openMainMenu(PlayerProfile profile, int page); void openCategory(PlayerProfile profile, Category category, int page); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideLayout.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideMode.java similarity index 74% rename from src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideLayout.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideMode.java index 562fe5981..8c439f436 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideLayout.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideMode.java @@ -13,24 +13,17 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; * @see SlimefunGuideImplementation * */ -public enum SlimefunGuideLayout { - - /** - * This design is a book representation of the {@link SlimefunGuide} - */ - BOOK, +public enum SlimefunGuideMode { /** * This design is the standard layout, it uses a {@link ChestMenu} */ - CHEST, + SURVIVAL_MODE, /** * This is an admin-only design which creates a {@link SlimefunGuide} that allows * you to spawn in any {@link SlimefunItem} */ - CHEAT_SHEET; - - public static final SlimefunGuideLayout[] valuesCache = values(); + CHEAT_MODE; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java similarity index 55% rename from src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java index 38564d077..007a1d3cc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideLayoutOption.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/GuideModeOption.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -13,35 +16,41 @@ import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -class GuideLayoutOption implements SlimefunGuideOption { +class GuideModeOption implements SlimefunGuideOption { + @Nonnull @Override public SlimefunAddon getAddon() { return SlimefunPlugin.instance(); } + @Nonnull @Override public NamespacedKey getKey() { return new NamespacedKey(SlimefunPlugin.instance(), "guide_layout"); } + @Nonnull @Override public Optional getDisplayItem(Player p, ItemStack guide) { - Optional current = getSelectedOption(p, guide); + if (!p.hasPermission("slimefun.cheat.items")) { + // Only Players with the appropriate permission can access the cheat sheet + return Optional.empty(); + } + + Optional current = getSelectedOption(p, guide); if (current.isPresent()) { - SlimefunGuideLayout layout = current.get(); + SlimefunGuideMode layout = current.get(); ItemStack item = new ItemStack(Material.AIR); - if (layout == SlimefunGuideLayout.CHEST) { + if (layout == SlimefunGuideMode.SURVIVAL_MODE) { item.setType(Material.CHEST); - } else if (layout == SlimefunGuideLayout.BOOK) { - item.setType(Material.BOOK); } else { item.setType(Material.COMMAND_BLOCK); } @@ -50,12 +59,9 @@ class GuideLayoutOption implements SlimefunGuideOption { meta.setDisplayName(ChatColor.GRAY + "Slimefun Guide Design: " + ChatColor.YELLOW + ChatUtils.humanize(layout.name())); List lore = new ArrayList<>(); lore.add(""); - lore.add((layout == SlimefunGuideLayout.CHEST ? ChatColor.GREEN : ChatColor.GRAY) + "Chest"); - lore.add((layout == SlimefunGuideLayout.BOOK ? ChatColor.GREEN : ChatColor.GRAY) + "Book"); + lore.add((layout == SlimefunGuideMode.SURVIVAL_MODE ? ChatColor.GREEN : ChatColor.GRAY) + "Chest"); - if (p.hasPermission("slimefun.cheat.items")) { - lore.add((layout == SlimefunGuideLayout.CHEAT_SHEET ? ChatColor.GREEN : ChatColor.GRAY) + "Cheat Sheet"); - } + lore.add((layout == SlimefunGuideMode.CHEAT_MODE ? ChatColor.GREEN : ChatColor.GRAY) + "Cheat Sheet"); lore.add(""); lore.add(ChatColor.GRAY + "\u21E8 " + ChatColor.YELLOW + "Click to change your layout"); @@ -69,47 +75,44 @@ class GuideLayoutOption implements SlimefunGuideOption { } @Override - public void onClick(Player p, ItemStack guide) { - Optional current = getSelectedOption(p, guide); + public void onClick(@Nonnull Player p, @Nonnull ItemStack guide) { + Optional current = getSelectedOption(p, guide); if (current.isPresent()) { - SlimefunGuideLayout next = getNextLayout(p, current.get()); + SlimefunGuideMode next = getNextMode(p, current.get()); setSelectedOption(p, guide, next); } SlimefunGuideSettings.openSettings(p, guide); } - private SlimefunGuideLayout getNextLayout(Player p, SlimefunGuideLayout layout) { + @Nonnull + private SlimefunGuideMode getNextMode(@Nonnull Player p, @Nonnull SlimefunGuideMode mode) { if (p.hasPermission("slimefun.cheat.items")) { - if (layout == SlimefunGuideLayout.CHEST) { - return SlimefunGuideLayout.BOOK; + if (mode == SlimefunGuideMode.SURVIVAL_MODE) { + return SlimefunGuideMode.CHEAT_MODE; + } else { + return SlimefunGuideMode.SURVIVAL_MODE; } - - if (layout == SlimefunGuideLayout.BOOK) { - return SlimefunGuideLayout.CHEAT_SHEET; - } - - return SlimefunGuideLayout.CHEST; } else { - return layout == SlimefunGuideLayout.CHEST ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST; + return SlimefunGuideMode.SURVIVAL_MODE; + } + } + + @Nonnull + @Override + public Optional getSelectedOption(@Nonnull Player p, @Nonnull ItemStack guide) { + if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(SlimefunGuideMode.CHEAT_MODE), true, false)) { + return Optional.of(SlimefunGuideMode.CHEAT_MODE); + } else { + return Optional.of(SlimefunGuideMode.SURVIVAL_MODE); } } @Override - public Optional getSelectedOption(Player p, ItemStack guide) { - for (SlimefunGuideLayout layout : SlimefunGuideLayout.valuesCache) { - if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true, false)) { - return Optional.of(layout); - } - } - - return Optional.empty(); - } - - @Override - public void setSelectedOption(Player p, ItemStack guide, SlimefunGuideLayout value) { + @ParametersAreNonnullByDefault + public void setSelectedOption(Player p, ItemStack guide, SlimefunGuideMode value) { guide.setItemMeta(SlimefunGuide.getItem(value).getItemMeta()); } -} +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java index 1ed862a13..310271e2b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/SlimefunGuideSettings.java @@ -13,7 +13,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.core.services.localization.Language; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; @@ -39,7 +39,7 @@ public final class SlimefunGuideSettings { private static final List> options = new ArrayList<>(); static { - options.add(new GuideLayoutOption()); + options.add(new GuideModeOption()); options.add(new FireworksOption()); options.add(new PlayerLanguageOption()); } @@ -65,7 +65,7 @@ public final class SlimefunGuideSettings { } private static void addHeader(Player p, ChestMenu menu, ItemStack guide) { - menu.addItem(0, new CustomItem(SlimefunGuide.getItem(SlimefunGuideLayout.CHEST), "&e\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"), "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide")), (pl, slot, item, action) -> { + menu.addItem(0, new CustomItem(SlimefunGuide.getItem(SlimefunGuideMode.SURVIVAL_MODE), "&e\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"), "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide")), (pl, slot, item, action) -> { SlimefunGuide.openGuide(pl, guide); return false; }); @@ -141,7 +141,7 @@ public final class SlimefunGuideSettings { for (SlimefunGuideOption option : options) { if (option instanceof FireworksOption) { FireworksOption fireworks = (FireworksOption) option; - return fireworks.getSelectedOption(p, SlimefunGuide.getItem(SlimefunGuideLayout.CHEST)).orElse(true); + return fireworks.getSelectedOption(p, SlimefunGuide.getItem(SlimefunGuideMode.SURVIVAL_MODE)).orElse(true); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java index a7abb9eae..210125e80 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.Optional; import java.util.Queue; import java.util.Set; -import java.util.logging.Level; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -32,16 +31,14 @@ import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.api.network.Network; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.papermc.lib.PaperLib; -import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; @@ -368,7 +365,7 @@ abstract class AbstractItemNetwork extends Network { ItemMeta im = stack.getItemMeta(); List lore = new ArrayList<>(); lore.add(""); - lore.add(ChatColors.color("&7Stored Items: &f" + DoubleHandler.getFancyDouble(item.getInt()))); + lore.add(ChatColors.color("&7Stored Items: &f" + NumberUtils.getCompactDouble(item.getInt()))); if (stack.getMaxStackSize() > 1) { int amount = item.getInt() > stack.getMaxStackSize() ? stack.getMaxStackSize() : item.getInt(); @@ -426,12 +423,7 @@ abstract class AbstractItemNetwork extends Network { } } else if (BlockStorage.hasInventory(target)) { BlockMenu blockMenu = BlockStorage.getInventory(target); - - if (blockMenu.getPreset().getID().startsWith("BARREL_")) { - gatherItemsFromBarrel(l, blockMenu, items); - } else { - handleWithdraw(blockMenu, items, l); - } + handleWithdraw(blockMenu, items, l); } else if (CargoUtils.hasInventory(target)) { BlockState state = PaperLib.getBlockState(target, false).getState(); @@ -445,41 +437,6 @@ abstract class AbstractItemNetwork extends Network { } } - @ParametersAreNonnullByDefault - private void gatherItemsFromBarrel(Location l, BlockMenu blockMenu, List items) { - try { - Config cfg = BlockStorage.getLocationInfo(blockMenu.getLocation()); - String data = cfg.getString("storedItems"); - - if (data == null) { - return; - } - - int stored = Integer.parseInt(data); - - for (int slot : blockMenu.getPreset().getSlotsAccessedByItemTransport((DirtyChestMenu) blockMenu, ItemTransportFlow.WITHDRAW, null)) { - ItemStack stack = blockMenu.getItemInSlot(slot); - - if (stack != null && CargoUtils.matchesFilter(this, l.getBlock(), stack)) { - boolean add = true; - - for (ItemStackAndInteger item : items) { - if (SlimefunUtils.isItemSimilar(stack, item.getItemStackWrapper(), true, false)) { - add = false; - item.add(stack.getAmount() + stored); - } - } - - if (add) { - items.add(new ItemStackAndInteger(stack, stack.getAmount() + stored)); - } - } - } - } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, "An Exception occurred while trying to read data from a Barrel", x); - } - } - @ParametersAreNonnullByDefault private void handleWithdraw(DirtyChestMenu menu, List items, Location l) { for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.WITHDRAW, null)) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java index 34b83e260..ba0d14a10 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java @@ -20,7 +20,6 @@ import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link CargoNet} is a type of {@link Network} which deals with {@link ItemStack} transportation. @@ -250,7 +249,7 @@ public class CargoNet extends AbstractItemNetwork { String str = BlockStorage.getLocationInfo(node).getString("frequency"); return str == null ? 0 : Integer.parseInt(str); } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing a Cargo Node Frequency (" + node.getWorld().getName() + " - " + node.getBlockX() + "," + node.getBlockY() + "," + +node.getBlockZ() + ")"); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while parsing a Cargo Node Frequency (" + node.getWorld().getName() + " - " + node.getBlockX() + "," + node.getBlockY() + "," + +node.getBlockZ() + ")"); return 0; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java index 143744ca6..7b73eafe8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java @@ -22,9 +22,20 @@ import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; +/** + * This is a helper class for the {@link CargoNet} which provides + * a free static utility methods to let the {@link CargoNet} interact with + * an {@link Inventory} or {@link BlockMenu}. + * + * @author TheBusyBiscuit + * @author Walshy + * @author DNx5 + * + */ final class CargoUtils { /** @@ -32,6 +43,10 @@ final class CargoUtils { */ private static final int[] FILTER_SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 }; + /** + * This is a utility class and should not be instantiated. + * Therefore we just hide the public constructor. + */ private CargoUtils() {} /** @@ -51,10 +66,6 @@ final class CargoUtils { Material type = block.getType(); - if (SlimefunTag.SHULKER_BOXES.isTagged(type)) { - return true; - } - switch (type) { case CHEST: case TRAPPED_CHEST: @@ -68,10 +79,11 @@ final class CargoUtils { case SMOKER: return true; default: - return false; + return SlimefunTag.SHULKER_BOXES.isTagged(type); } } + @Nonnull static int[] getInputSlotRange(@Nonnull Inventory inv, @Nullable ItemStack item) { if (inv instanceof FurnaceInventory) { if (item != null && item.getType().isFuel()) { @@ -101,7 +113,8 @@ final class CargoUtils { } } - static int[] getOutputSlotRange(Inventory inv) { + @Nonnull + static int[] getOutputSlotRange(@Nonnull Inventory inv) { if (inv instanceof FurnaceInventory) { // Slot 2-3 return new int[] { 2, 3 }; @@ -114,6 +127,7 @@ final class CargoUtils { } } + @Nullable static ItemStack withdraw(AbstractItemNetwork network, Map inventories, Block node, Block target, ItemStack template) { DirtyChestMenu menu = getChestMenu(target); @@ -145,7 +159,7 @@ final class CargoUtils { if (SlimefunUtils.isItemSimilar(is, wrapper, true) && matchesFilter(network, node, is)) { if (is.getAmount() > template.getAmount()) { is.setAmount(is.getAmount() - template.getAmount()); - menu.replaceExistingItem(slot, is.clone()); + menu.replaceExistingItem(slot, is); return template; } else { menu.replaceExistingItem(slot, null); @@ -157,6 +171,7 @@ final class CargoUtils { return null; } + @Nullable static ItemStack withdrawFromVanillaInventory(AbstractItemNetwork network, Block node, ItemStack template, Inventory inv) { ItemStack[] contents = inv.getContents(); int[] range = getOutputSlotRange(inv); @@ -184,6 +199,7 @@ final class CargoUtils { return null; } + @Nullable static ItemStackAndInteger withdraw(AbstractItemNetwork network, Map inventories, Block node, Block target) { DirtyChestMenu menu = getChestMenu(target); @@ -215,6 +231,7 @@ final class CargoUtils { return null; } + @Nullable private static ItemStackAndInteger withdrawFromVanillaInventory(AbstractItemNetwork network, Block node, Inventory inv) { ItemStack[] contents = inv.getContents(); int[] range = getOutputSlotRange(inv); @@ -233,6 +250,7 @@ final class CargoUtils { return null; } + @Nullable static ItemStack insert(AbstractItemNetwork network, Map inventories, Block node, Block target, ItemStack stack) { if (!matchesFilter(network, node, stack)) { return stack; @@ -273,7 +291,7 @@ final class CargoUtils { int maxStackSize = itemInSlot.getType().getMaxStackSize(); int currentAmount = itemInSlot.getAmount(); - if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false) && currentAmount < maxStackSize) { + if (currentAmount < maxStackSize && SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false)) { int amount = currentAmount + stack.getAmount(); itemInSlot.setAmount(Math.min(amount, maxStackSize)); @@ -291,6 +309,7 @@ final class CargoUtils { return stack; } + @Nullable private static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) { ItemStack[] contents = inv.getContents(); int[] range = getInputSlotRange(inv, stack); @@ -309,7 +328,7 @@ final class CargoUtils { } else { int maxStackSize = itemInSlot.getType().getMaxStackSize(); - if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false) && itemInSlot.getAmount() < maxStackSize) { + if (itemInSlot.getAmount() < maxStackSize && SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false)) { int amount = itemInSlot.getAmount() + stack.getAmount(); if (amount > maxStackSize) { @@ -327,12 +346,13 @@ final class CargoUtils { return stack; } + @Nullable static DirtyChestMenu getChestMenu(@Nonnull Block block) { if (BlockStorage.hasInventory(block)) { return BlockStorage.getInventory(block); + } else { + return BlockStorage.getUniversalInventory(block); } - - return BlockStorage.getUniversalInventory(block); } static boolean matchesFilter(@Nonnull AbstractItemNetwork network, @Nonnull Block node, @Nullable ItemStack item) { @@ -365,20 +385,12 @@ final class CargoUtils { } private static boolean isPotion(@Nullable ItemStack item) { - return item != null && (item.getType() == Material.POTION || item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION); - } - - /** - * Get the whitelist/blacklist slots in a Cargo Input Node. If you wish to access the items - * in the cargo (without hardcoding the slots in case of change) then you can use this method. - * - * @deprecated Renamed to {@link #getFilteringSlots()} - * - * @return The slot indexes for the whitelist/blacklist section. - */ - @Deprecated - public static int[] getWhitelistBlacklistSlots() { - return FILTER_SLOTS; + if (item != null) { + Material type = item.getType(); + return type == Material.POTION || type == Material.SPLASH_POTION || type == Material.LINGERING_POTION; + } else { + return false; + } } /** @@ -387,6 +399,7 @@ final class CargoUtils { * * @return The slots where the {@link ItemFilter} section for a cargo node sits */ + @Nonnull public static int[] getFilteringSlots() { return FILTER_SLOTS; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java index b28c6d086..75112519b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/AutoSavingService.java @@ -15,7 +15,6 @@ import org.bukkit.entity.Player; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This Service is responsible for automatically saving {@link Player} and {@link Block} @@ -66,7 +65,7 @@ public class AutoSavingService { } if (players > 0) { - Slimefun.getLogger().log(Level.INFO, "Auto-saved all player data for {0} player(s)!", players); + SlimefunPlugin.logger().log(Level.INFO, "Auto-saved all player data for {0} player(s)!", players); } } @@ -89,7 +88,7 @@ public class AutoSavingService { } if (!worlds.isEmpty()) { - Slimefun.getLogger().log(Level.INFO, "Auto-saving block data... (Next auto-save: {0}m)", interval); + SlimefunPlugin.logger().log(Level.INFO, "Auto-saving block data... (Next auto-save: {0}m)", interval); for (BlockStorage storage : worlds) { storage.save(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java index cb7a2bde1..cacc4f411 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java @@ -20,7 +20,6 @@ import javax.annotation.Nonnull; import org.apache.commons.lang.Validate; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This Service creates a Backup of your Slimefun world data on every server shutdown. @@ -43,7 +42,7 @@ public class BackupService implements Runnable { try { purgeBackups(backups); } catch (IOException e) { - Slimefun.getLogger().log(Level.WARNING, "Could not delete an old backup", e); + SlimefunPlugin.logger().log(Level.WARNING, "Could not delete an old backup", e); } } @@ -56,12 +55,12 @@ public class BackupService implements Runnable { createBackup(output); } - Slimefun.getLogger().log(Level.INFO, "Backed up Slimefun data to: {0}", file.getName()); + SlimefunPlugin.logger().log(Level.INFO, "Backed up Slimefun data to: {0}", file.getName()); } else { - Slimefun.getLogger().log(Level.WARNING, "Could not create backup-file: {0}", file.getName()); + SlimefunPlugin.logger().log(Level.WARNING, "Could not create backup-file: {0}", file.getName()); } } catch (IOException x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while creating a backup for Slimefun " + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while creating a backup for Slimefun " + SlimefunPlugin.getVersion()); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BlockDataService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BlockDataService.java index feea594a0..c525d312e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BlockDataService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BlockDataService.java @@ -19,8 +19,8 @@ import org.bukkit.persistence.PersistentDataHolder; import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.Plugin; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.papermc.lib.PaperLib; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link BlockDataService} is similar to the {@link CustomItemDataService}, @@ -78,12 +78,12 @@ public class BlockDataService implements Keyed { container.set(namespacedKey, PersistentDataType.STRING, value); state.update(); } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, "Please check if your Server Software is up to date!"); + SlimefunPlugin.logger().log(Level.SEVERE, "Please check if your Server Software is up to date!"); String serverSoftware = PaperLib.isSpigot() && !PaperLib.isPaper() ? "Spigot" : Bukkit.getName(); - Slimefun.getLogger().log(Level.SEVERE, () -> serverSoftware + " | " + Bukkit.getVersion() + " | " + Bukkit.getBukkitVersion()); + SlimefunPlugin.logger().log(Level.SEVERE, () -> serverSoftware + " | " + Bukkit.getVersion() + " | " + Bukkit.getBukkitVersion()); - Slimefun.getLogger().log(Level.SEVERE, "An Exception was thrown while trying to set Persistent Data for a Block", x); + SlimefunPlugin.logger().log(Level.SEVERE, "An Exception was thrown while trying to set Persistent Data for a Block", x); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java index 6100fb821..dceed3241 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java @@ -30,6 +30,9 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; */ public class CustomItemDataService implements Keyed { + /** + * This is the {@link NamespacedKey} used to store/read data. + */ private final NamespacedKey namespacedKey; /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java index f14fe320b..5577c0a64 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java @@ -23,11 +23,10 @@ import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.core.services.localization.Language; import io.github.thebusybiscuit.slimefun4.core.services.localization.SlimefunLocalization; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.api.Slimefun; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; /** * As the name suggests, this Service is responsible for Localization. @@ -78,7 +77,7 @@ public class LocalizationService extends SlimefunLocalization { plugin.getLogger().log(Level.WARNING, "Could not recognize the given language: \"{0}\"", serverDefaultLanguage); } - Slimefun.getLogger().log(Level.INFO, "Available languages: {0}", String.join(", ", languages.keySet())); + SlimefunPlugin.logger().log(Level.INFO, "Available languages: {0}", String.join(", ", languages.keySet())); save(); } else { translationsEnabled = false; @@ -178,7 +177,7 @@ public class LocalizationService extends SlimefunLocalization { defaultLanguage.setCategoriesFile(streamConfigFile("categories_" + language + ".yml", null)); defaultLanguage.setRecipeTypesFile(streamConfigFile("recipes_" + language + ".yml", null)); - Slimefun.getLogger().log(Level.INFO, "Loaded language \"{0}\"", language); + SlimefunPlugin.logger().log(Level.INFO, "Loaded language \"{0}\"", language); getConfig().setValue(LANGUAGE_PATH, language); // Loading in the defaults from our resources folder @@ -188,7 +187,7 @@ public class LocalizationService extends SlimefunLocalization { FileConfiguration config = YamlConfiguration.loadConfiguration(reader); getConfig().getConfiguration().setDefaults(config); } catch (IOException e) { - Slimefun.getLogger().log(Level.SEVERE, e, () -> "Failed to load language file: \"" + path + "\""); + SlimefunPlugin.logger().log(Level.SEVERE, e, () -> "Failed to load language file: \"" + path + "\""); } save(); @@ -245,13 +244,15 @@ public class LocalizationService extends SlimefunLocalization { } } - return Math.min(DoubleHandler.fixDouble(100.0 * (matches / (double) defaultKeys.size())), 100.0); + return Math.min(NumberUtils.reparseDouble(100.0 * (matches / (double) defaultKeys.size())), 100.0); } + @Nonnull private Set getTotalKeys(@Nonnull Language lang) { return getKeys(lang.getFiles()); } + @Nonnull private Set getKeys(FileConfiguration... files) { Set keys = new HashSet<>(); @@ -278,7 +279,7 @@ public class LocalizationService extends SlimefunLocalization { return config; } catch (IOException e) { - Slimefun.getLogger().log(Level.SEVERE, e, () -> "Failed to load language file into memory: \"" + path + "\""); + SlimefunPlugin.logger().log(Level.SEVERE, e, () -> "Failed to load language file into memory: \"" + path + "\""); return null; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MinecraftRecipeService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MinecraftRecipeService.java index 9366dcb27..694f1b352 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MinecraftRecipeService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MinecraftRecipeService.java @@ -20,14 +20,14 @@ import org.bukkit.plugin.Plugin; import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe; import io.github.thebusybiscuit.cscorelib2.recipes.RecipeSnapshot; -import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; +import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; /** * This Service is responsible for accessing a {@link RecipeSnapshot}. * This snapshot contains a compiled list of all recipes that could be found on the * Server at the time the Service was loaded. * - * This Service is primarily used by the {@link ChestSlimefunGuide}. + * This Service is primarily used by the {@link SurvivalSlimefunGuide}. * * @author TheBusyBiscuit * diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java index 3d2368cea..8f68d852e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java @@ -9,10 +9,10 @@ import java.util.logging.Level; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import kong.unirest.JsonNode; import kong.unirest.json.JSONArray; import kong.unirest.json.JSONObject; -import me.mrCookieSlime.Slimefun.api.Slimefun; class ContributionsConnector extends GitHubConnector { @@ -84,7 +84,7 @@ class ContributionsConnector extends GitHubConnector { if (response.isArray()) { computeContributors(response.getArray()); } else { - Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response); + SlimefunPlugin.logger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java index 0bc34a0fa..130198a82 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java @@ -15,7 +15,7 @@ import javax.annotation.Nullable; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; -import io.github.thebusybiscuit.cscorelib2.data.ComputedOptional; +import io.github.thebusybiscuit.cscorelib2.data.TriStateOptional; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; @@ -35,7 +35,7 @@ public class Contributor { private final String profileLink; private final ConcurrentMap contributions = new ConcurrentHashMap<>(); - private final ComputedOptional headTexture = ComputedOptional.createNew(); + private final TriStateOptional headTexture = TriStateOptional.createNew(); private Optional uuid = Optional.empty(); private boolean immutable = false; @@ -181,10 +181,10 @@ public class Contributor { public String getTexture() { if (!headTexture.isComputed() || !headTexture.isPresent()) { GitHubService github = SlimefunPlugin.getGitHubService(); + String cached = github.getCachedTexture(githubUsername); - if (github != null) { - String cached = github.getCachedTexture(githubUsername); - return cached != null ? cached : HeadTexture.UNKNOWN.getTexture(); + if (cached != null) { + return cached; } else { return HeadTexture.UNKNOWN.getTexture(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java index e06e00129..ec05d2953 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java @@ -14,12 +14,12 @@ import java.util.logging.Level; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import kong.unirest.HttpResponse; import kong.unirest.JsonNode; import kong.unirest.Unirest; import kong.unirest.UnirestException; import kong.unirest.json.JSONException; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link GitHubConnector} is used to connect to the GitHub API service. @@ -100,7 +100,7 @@ abstract class GitHubConnector { file = new File("plugins/Slimefun/cache/github/" + getFileName() + ".json"); if (github.isLoggingEnabled()) { - Slimefun.getLogger().log(Level.INFO, "Retrieving {0}.json from GitHub...", getFileName()); + SlimefunPlugin.logger().log(Level.INFO, "Retrieving {0}.json from GitHub...", getFileName()); } try { @@ -116,7 +116,7 @@ abstract class GitHubConnector { writeCacheFile(response.getBody()); } else { if (github.isLoggingEnabled()) { - Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { url, response.getStatus(), response.getBody() }); + SlimefunPlugin.logger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { url, response.getStatus(), response.getBody() }); } // It has the cached file, let's just read that then @@ -130,7 +130,7 @@ abstract class GitHubConnector { } } catch (UnirestException e) { if (github.isLoggingEnabled()) { - Slimefun.getLogger().log(Level.WARNING, "Could not connect to GitHub in time.", e); + SlimefunPlugin.logger().log(Level.WARNING, "Could not connect to GitHub in time.", e); } // It has the cached file, let's just read that then @@ -153,7 +153,7 @@ abstract class GitHubConnector { try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { return new JsonNode(reader.readLine()); } catch (IOException | JSONException e) { - Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] { file.getName(), e.getClass().getSimpleName(), e.getMessage() }); + SlimefunPlugin.logger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] { file.getName(), e.getClass().getSimpleName(), e.getMessage() }); return null; } } @@ -162,7 +162,7 @@ abstract class GitHubConnector { try (FileOutputStream output = new FileOutputStream(file)) { output.write(node.toString().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { - Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] { e.getClass().getSimpleName(), e.getMessage() }); + SlimefunPlugin.logger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] { e.getClass().getSimpleName(), e.getMessage() }); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java index 38335e529..ab539efbb 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java @@ -7,10 +7,10 @@ import java.util.logging.Level; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import kong.unirest.JsonNode; import kong.unirest.json.JSONArray; import kong.unirest.json.JSONObject; -import me.mrCookieSlime.Slimefun.api.Slimefun; class GitHubIssuesConnector extends GitHubConnector { @@ -42,7 +42,7 @@ class GitHubIssuesConnector extends GitHubConnector { callback.accept(issues, pullRequests); } else { - Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response); + SlimefunPlugin.logger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java index 26e1f2c63..cfc214538 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java @@ -14,9 +14,8 @@ import javax.annotation.Nullable; import org.bukkit.Bukkit; import io.github.thebusybiscuit.cscorelib2.players.MinecraftAccount; -import io.github.thebusybiscuit.cscorelib2.players.MinecraftAccount.TooManyRequestsException; +import io.github.thebusybiscuit.cscorelib2.players.TooManyRequestsException; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This {@link GitHubTask} represents a {@link Runnable} that is run every X minutes. @@ -101,8 +100,8 @@ class GitHubTask implements Runnable { contributor.setTexture(null); } catch (IOException x) { // Too many requests - Slimefun.getLogger().log(Level.WARNING, "Attempted to connect to mojang.com, got this response: {0}: {1}", new Object[] { x.getClass().getSimpleName(), x.getMessage() }); - Slimefun.getLogger().log(Level.WARNING, "This usually means mojang.com is temporarily down or started to rate-limit this connection, this is not an error message!"); + SlimefunPlugin.logger().log(Level.WARNING, "Attempted to connect to mojang.com, got this response: {0}: {1}", new Object[] { x.getClass().getSimpleName(), x.getMessage() }); + SlimefunPlugin.logger().log(Level.WARNING, "This usually means mojang.com is temporarily down or started to rate-limit this connection, this is not an error message!"); // Retry after 5 minutes if it was rate-limiting if (x.getMessage().contains("429")) { @@ -111,7 +110,7 @@ class GitHubTask implements Runnable { return -1; } catch (TooManyRequestsException x) { - Slimefun.getLogger().log(Level.WARNING, "Received a rate-limit from mojang.com, retrying in 4 minutes"); + SlimefunPlugin.logger().log(Level.WARNING, "Received a rate-limit from mojang.com, retrying in 4 minutes"); Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 4 * 60 * 20L); return -1; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java index 30c1728b3..c8ef61b9b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java @@ -36,6 +36,8 @@ public class Translators { addTranslator("ishi-sama", SupportedLanguage.FRENCH, true); addTranslator("amarcais53", SupportedLanguage.FRENCH, true); addTranslator("NinoFutur", SupportedLanguage.FRENCH, true); + addTranslator("TheRetix", SupportedLanguage.FRENCH, true); + addTranslator("Aeris1One", SupportedLanguage.FRENCH, true); // Translators - Italian addTranslator("xXDOTTORXx", SupportedLanguage.ITALIAN, true); @@ -50,6 +52,8 @@ public class Translators { // Translators - Hungarian addTranslator("andris155", SupportedLanguage.HUNGARIAN, true); + addTranslator("KingDeadZ", SupportedLanguage.HUNGARIAN, true); + addTranslator("poma123", SupportedLanguage.HUNGARIAN, false); // Translators - Vietnamese addTranslator("HSGamer", SupportedLanguage.VIETNAMESE, false); @@ -164,6 +168,7 @@ public class Translators { // Translators - Bulgarian addTranslator("DNBGlol", SupportedLanguage.BULGARIAN, true); + addTranslator("Pukejoy", SupportedLanguage.BULGARIAN, true); // Translators - Tagalog addTranslator("sccooottttie", SupportedLanguage.TAGALOG, true); @@ -177,8 +182,10 @@ public class Translators { addTranslator("Sakanas", SupportedLanguage.PORTUGUESE_BRAZIL, true); addTranslator("krazybeat", SupportedLanguage.PORTUGUESE_BRAZIL, true); addTranslator("FaolanMalcadh", SupportedLanguage.PORTUGUESE_BRAZIL, true); - addTranslator("G4stavoM1ster", SupportedLanguage.PORTUGUESE_BRAZIL, true); addTranslator("Gusstavo", SupportedLanguage.PORTUGUESE_BRAZIL, true); + addTranslator("Day-OS", SupportedLanguage.PORTUGUESE_BRAZIL, true); + addTranslator("ooicram", SupportedLanguage.PORTUGUESE_BRAZIL, true); + addTranslator("Sxigames", SupportedLanguage.PORTUGUESE_BRAZIL, true); } @ParametersAreNonnullByDefault diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java deleted file mode 100644 index 56f1be98e..000000000 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.thebusybiscuit.slimefun4.core.services.plugins; - -import java.util.Optional; -import java.util.function.Function; - -import javax.annotation.Nonnull; - -import org.bukkit.block.Block; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; - -import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.integrations.IntegrationsManager; - -/** - * This Service holds all interactions and hooks with third-party {@link Plugin Plugins} - * that are not necessarily a dependency or a {@link SlimefunAddon}. - * - * Integration with these plugins happens inside Slimefun itself. - * - * @author TheBusyBiscuit - * - * @deprecated Renamed to {@link IntegrationsManager} - * - * @see SlimefunPlugin - * - */ -@Deprecated -public class ThirdPartyPluginService extends IntegrationsManager { - - /** - * This gets overridden if ExoticGarden is loaded - */ - private Function> exoticGardenIntegration = b -> Optional.empty(); - - /** - * This initializes the {@link ThirdPartyPluginService} - * - * @param plugin - * Our instance of {@link SlimefunPlugin} - */ - public ThirdPartyPluginService(@Nonnull SlimefunPlugin plugin) { - super(plugin); - } - - @Deprecated - public void loadExoticGarden(Plugin plugin, Function> method) { - // TODO: Move this method to IntegrationsManager and think of a better way to handle this - if (plugin.getName().equals("ExoticGarden")) { - exoticGardenIntegration = method; - } - } - - @Deprecated - public Optional harvestExoticGardenPlant(Block block) { - return exoticGardenIntegration.apply(block); - } - -} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/package-info.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/package-info.java deleted file mode 100644 index 572feaade..000000000 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * This package contains all hooks to external plugins - */ -package io.github.thebusybiscuit.slimefun4.core.services.plugins; \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceInspector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceInspector.java new file mode 100644 index 000000000..6a8fd5900 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceInspector.java @@ -0,0 +1,41 @@ +package io.github.thebusybiscuit.slimefun4.core.services.profiler; + +import javax.annotation.Nonnull; + +import org.bukkit.Server; + +/** + * This interface is used to identify someone as a {@link PerformanceInspector}. + * A {@link PerformanceInspector} can query the {@link SlimefunProfiler} and get the + * results send to them as a {@link PerformanceSummary}. + * + * @author TheBusyBiscuit + * + */ +public interface PerformanceInspector { + + /** + * This returns whether this {@link PerformanceInspector} is still valid. + * An inspector will become invalid if they leave the {@link Server}. + * + * @return Whether this inspector is still valid + */ + boolean isValid(); + + /** + * This will send a text message to the {@link PerformanceInspector}. + * + * @param msg + * The message to send + */ + void sendMessage(@Nonnull String msg); + + /** + * This determines whether the {@link PerformanceInspector} will get the full view + * or a trimmed version which only shows the most urgent samples. + * + * @return Whether to send the full {@link PerformanceSummary} or a trimmed version + */ + boolean isVerbose(); + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceSummary.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceSummary.java index 4b46d9352..b5ace61f8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceSummary.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/PerformanceSummary.java @@ -11,10 +11,8 @@ import java.util.stream.Stream; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; +import io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors.PlayerPerformanceInspector; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import net.md_5.bungee.api.ChatColor; @@ -54,7 +52,7 @@ class PerformanceSummary { items = profiler.getByItem(); } - public void send(@Nonnull CommandSender sender) { + public void send(@Nonnull PerformanceInspector sender) { sender.sendMessage(""); sender.sendMessage(ChatColor.GREEN + "===== Slimefun Lag Profiler ====="); sender.sendMessage(ChatColor.GOLD + "Total time: " + ChatColor.YELLOW + NumberUtils.getAsMillis(totalElapsedTime)); @@ -91,17 +89,17 @@ class PerformanceSummary { } @ParametersAreNonnullByDefault - private void summarizeTimings(int count, String name, CommandSender sender, Map map, Function, String> formatter) { + private void summarizeTimings(int count, String name, PerformanceInspector inspector, Map map, Function, String> formatter) { Stream> stream = map.entrySet().stream(); List> results = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList()); String prefix = count + " " + name + (count != 1 ? 's' : ""); - if (sender instanceof Player) { + if (inspector instanceof PlayerPerformanceInspector) { TextComponent component = summarizeAsTextComponent(count, prefix, results, formatter); - sender.spigot().sendMessage(component); + ((PlayerPerformanceInspector) inspector).sendMessage(component); } else { - String text = summarizeAsString(count, prefix, results, formatter); - sender.sendMessage(text); + String text = summarizeAsString(inspector, count, prefix, results, formatter); + inspector.sendMessage(text); } } @@ -143,7 +141,7 @@ class PerformanceSummary { @Nonnull @ParametersAreNonnullByDefault - private String summarizeAsString(int count, String prefix, List> results, Function, String> formatter) { + private String summarizeAsString(PerformanceInspector inspector, int count, String prefix, List> results, Function, String> formatter) { int shownEntries = 0; int hiddenEntries = 0; @@ -154,7 +152,7 @@ class PerformanceSummary { builder.append(ChatColor.YELLOW); for (Map.Entry entry : results) { - if (shownEntries < MAX_ITEMS && (shownEntries < MIN_ITEMS || entry.getValue() > VISIBILITY_THRESHOLD)) { + if (inspector.isVerbose() || (shownEntries < MAX_ITEMS && (shownEntries < MIN_ITEMS || entry.getValue() > VISIBILITY_THRESHOLD))) { builder.append("\n "); builder.append(ChatColor.stripColor(formatter.apply(entry))); shownEntries++; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java index 514b4d32e..5a5eac91b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java @@ -19,7 +19,6 @@ import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.block.Block; -import org.bukkit.command.CommandSender; import org.bukkit.scheduler.BukkitScheduler; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; @@ -27,7 +26,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link SlimefunProfiler} works closely to the {@link TickerTask} and is @@ -69,7 +67,7 @@ public class SlimefunProfiler { private long totalElapsedTime; private final Map timings = new ConcurrentHashMap<>(); - private final Queue requests = new ConcurrentLinkedQueue<>(); + private final Queue requests = new ConcurrentLinkedQueue<>(); /** * This method terminates the {@link SlimefunProfiler}. @@ -183,7 +181,7 @@ public class SlimefunProfiler { // If we waited for too long, then we should just abort if (iterations <= 0) { - Iterator iterator = requests.iterator(); + Iterator iterator = requests.iterator(); while (iterator.hasNext()) { iterator.next().sendMessage("Your timings report has timed out, we were still waiting for " + queued.get() + " samples to be collected :/"); @@ -193,7 +191,7 @@ public class SlimefunProfiler { return; } } catch (InterruptedException e) { - Slimefun.getLogger().log(Level.SEVERE, "A Profiler Thread was interrupted", e); + SlimefunPlugin.logger().log(Level.SEVERE, "A Profiler Thread was interrupted", e); Thread.currentThread().interrupt(); } } @@ -207,7 +205,7 @@ public class SlimefunProfiler { if (!requests.isEmpty()) { PerformanceSummary summary = new PerformanceSummary(this, totalElapsedTime, timings.size()); - Iterator iterator = requests.iterator(); + Iterator iterator = requests.iterator(); while (iterator.hasNext()) { summary.send(iterator.next()); @@ -217,16 +215,16 @@ public class SlimefunProfiler { } /** - * This method requests a summary for the given {@link CommandSender}. + * This method requests a summary for the given {@link PerformanceInspector}. * The summary will be sent upon the next available moment in time. * - * @param sender - * The {@link CommandSender} who shall receive this summary. + * @param inspector + * The {@link PerformanceInspector} who shall receive this summary. */ - public void requestSummary(@Nonnull CommandSender sender) { - Validate.notNull(sender, "Cannot request a summary for null"); + public void requestSummary(@Nonnull PerformanceInspector inspector) { + Validate.notNull(inspector, "Cannot request a summary for null"); - requests.add(sender); + requests.add(inspector); } @Nonnull diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/ConsolePerformanceInspector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/ConsolePerformanceInspector.java new file mode 100644 index 000000000..4520e0ec1 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/ConsolePerformanceInspector.java @@ -0,0 +1,62 @@ +package io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors; + +import javax.annotation.Nonnull; + +import org.apache.commons.lang.Validate; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; + +import io.github.thebusybiscuit.slimefun4.core.services.profiler.PerformanceInspector; + +/** + * This implementation of {@link PerformanceInspector} refers to a {@link CommandSender} + * which is preferabbly a {@link ConsoleCommandSender}. + * But it can theoretically be used for any type of {@link CommandSender} as it uses uncolored texts. + * + * @author TheBusyBiscuit + * + */ +public class ConsolePerformanceInspector implements PerformanceInspector { + + /** + * Our reference to the actual underlying {@link CommandSender}. + */ + private final CommandSender console; + + /** + * Whether a summary will be verbose or trimmed of. + */ + private final boolean verbose; + + /** + * This creates a new {@link ConsolePerformanceInspector} for the given {@link CommandSender}. + * + * @param console + * The {@link CommandSender}, preferabbly a {@link ConsoleCommandSender} + * @param verbose + * Whether the summary will be verbose or not + */ + public ConsolePerformanceInspector(@Nonnull CommandSender console, boolean verbose) { + Validate.notNull(console, "CommandSender cannot be null"); + + this.console = console; + this.verbose = verbose; + } + + @Override + public boolean isValid() { + // The console is always "online". + return true; + } + + @Override + public boolean isVerbose() { + return verbose; + } + + @Override + public void sendMessage(@Nonnull String msg) { + console.sendMessage(msg); + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/PlayerPerformanceInspector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/PlayerPerformanceInspector.java new file mode 100644 index 000000000..2e0697ff4 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/PlayerPerformanceInspector.java @@ -0,0 +1,74 @@ +package io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors; + +import java.util.UUID; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import io.github.thebusybiscuit.slimefun4.core.services.profiler.PerformanceInspector; +import net.md_5.bungee.api.chat.TextComponent; + +/** + * This implementation of {@link PerformanceInspector} refers to a {@link Player}. + * It also supports {@link TextComponent TextComponents} for rich text messages. + * + * @author TheBusyBiscuit + * + */ +public class PlayerPerformanceInspector implements PerformanceInspector { + + /** + * Our reference to the {@link UUID} of the {@link Player}. + */ + private final UUID uuid; + + /** + * This creates a new {@link PlayerPerformanceInspector} for the given {@link Player}. + * + * @param player + * The {@link Player} + */ + public PlayerPerformanceInspector(@Nonnull Player player) { + Validate.notNull(player, "Player cannot be null"); + + this.uuid = player.getUniqueId(); + } + + @Nullable + private Player getPlayer() { + return Bukkit.getPlayer(uuid); + } + + @Override + public boolean isValid() { + Player player = getPlayer(); + return player != null && player.isOnline(); + } + + @Override + public boolean isVerbose() { + return false; + } + + @Override + public void sendMessage(@Nonnull String msg) { + Player player = getPlayer(); + + if (player != null) { + player.sendMessage(msg); + } + } + + public void sendMessage(@Nonnull TextComponent component) { + Player player = getPlayer(); + + if (player != null) { + player.spigot().sendMessage(component); + } + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/package-info.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/package-info.java new file mode 100644 index 000000000..e6921498b --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/inspectors/package-info.java @@ -0,0 +1,5 @@ +/** + * This package holds the different implementations of + * {@link io.github.thebusybiscuit.slimefun4.core.services.profiler.PerformanceInspector}. + */ +package io.github.thebusybiscuit.slimefun4.core.services.profiler.inspectors; \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java index 189260e02..b2a49b7ba 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -20,6 +21,7 @@ import org.bukkit.Server; import org.bukkit.command.Command; import org.bukkit.entity.Player; import org.bukkit.event.Listener; +import org.bukkit.inventory.Recipe; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; @@ -27,9 +29,7 @@ import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.scheduler.BukkitTask; import io.github.thebusybiscuit.cscorelib2.config.Config; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager; -import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException; @@ -50,7 +50,6 @@ import io.github.thebusybiscuit.slimefun4.core.services.PerWorldSettingsService; import io.github.thebusybiscuit.slimefun4.core.services.PermissionsService; import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService; import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService; -import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService; import io.github.thebusybiscuit.slimefun4.core.services.profiler.SlimefunProfiler; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; @@ -113,6 +112,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.integrations.IntegrationsManager; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; @@ -148,14 +148,14 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { private final BackupService backupService = new BackupService(); private final PermissionsService permissionsService = new PermissionsService(this); private final PerWorldSettingsService worldSettingsService = new PerWorldSettingsService(this); - private final ThirdPartyPluginService thirdPartySupportService = new ThirdPartyPluginService(this); private final MinecraftRecipeService recipeService = new MinecraftRecipeService(this); - private final SlimefunProfiler profiler = new SlimefunProfiler(); - private LocalizationService local; + private final IntegrationsManager integrations = new IntegrationsManager(this); + private final SlimefunProfiler profiler = new SlimefunProfiler(); + + private LocalizationService local; private GPSNetwork gpsNetwork; private NetworkManager networkManager; - private ProtectionManager protections; // Important config files for Slimefun private final Config config = new Config(this); @@ -199,121 +199,25 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { */ @Override public void onEnable() { - instance = this; - if (minecraftVersion == MinecraftVersion.UNIT_TEST) { + // We handle Unit Tests seperately. + setInstance(this); onUnitTestStart(); + } else if (isVersionUnsupported()) { + // We wanna ensure that the Server uses a compatible version of Minecraft. + setInstance(this); + getLogger().log(Level.WARNING, "Slimefun was not installed properly! Disabling..."); + getServer().getPluginManager().disablePlugin(this); } else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) { + // The Environment and dependencies have been validated. + setInstance(this); getLogger().log(Level.INFO, "CS-CoreLib was detected!"); - long timestamp = System.nanoTime(); - PaperLib.suggestPaper(this); - - if (PaperLib.isPaper()) { - getLogger().log(Level.INFO, "Paper was detected! Performance optimizations have been applied."); - } - - // We wanna ensure that the Server uses a compatible version of Minecraft - if (isVersionUnsupported()) { - getServer().getPluginManager().disablePlugin(this); - return; - } - - // Disabling backwards-compatibility for fresh Slimefun installs - if (!new File("data-storage/Slimefun").exists()) { - config.setValue("options.backwards-compatibility", false); - config.save(); - - isNewlyInstalled = true; - } - - // Creating all necessary Folders - getLogger().log(Level.INFO, "Creating directories..."); - createDirectories(); - registry.load(config); - - // Set up localization - getLogger().log(Level.INFO, "Loading language files..."); - local = new LocalizationService(this, config.getString("options.chat-prefix"), config.getString("options.language")); - - // Setting up Networks - gpsNetwork = new GPSNetwork(); - - int networkSize = config.getInt("networks.max-size"); - - if (networkSize < 1) { - getLogger().log(Level.WARNING, "Your 'networks.max-size' setting is misconfigured! It must be at least 1, it was set to: {0}", networkSize); - networkSize = 1; - } - - networkManager = new NetworkManager(networkSize, config.getBoolean("networks.enable-visualizer"), config.getBoolean("networks.delete-excess-items")); - - // Setting up bStats - new Thread(metricsService::start, "Slimefun Metrics").start(); - - // Starting the Auto-Updater - if (config.getBoolean("options.auto-update")) { - getLogger().log(Level.INFO, "Starting Auto-Updater..."); - updaterService.start(); - } else { - updaterService.disable(); - } - - // Registering all GEO Resources - getLogger().log(Level.INFO, "Loading GEO-Resources..."); - GEOResourcesSetup.setup(); - - getLogger().log(Level.INFO, "Loading Tags..."); - loadTags(); - - getLogger().log(Level.INFO, "Loading items..."); - loadItems(); - - getLogger().log(Level.INFO, "Loading researches..."); - loadResearches(); - - registry.setResearchingEnabled(getResearchCfg().getBoolean("enable-researching")); - PostSetup.setupWiki(); - - getLogger().log(Level.INFO, "Registering listeners..."); - registerListeners(); - - // Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading) - runSync(new SlimefunStartupTask(this, () -> { - protections = new ProtectionManager(getServer()); - textureService.register(registry.getAllSlimefunItems(), true); - permissionsService.register(registry.getAllSlimefunItems(), true); - - // This try/catch should prevent buggy Spigot builds from blocking item loading - try { - recipeService.refresh(); - } catch (Exception | LinkageError x) { - getLogger().log(Level.SEVERE, x, () -> "An Exception occurred while iterating through the Recipe list on Minecraft Version " + minecraftVersion.getName() + " (Slimefun v" + getVersion() + ")"); - } - - }), 0); - - // Setting up the command /sf and all subcommands - command.register(); - - // Armor Update Task - if (config.getBoolean("options.enable-armor-effects")) { - boolean radioactiveFire = config.getBoolean("options.burn-players-when-radioactive"); - getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(radioactiveFire), 0L, config.getInt("options.armor-update-interval") * 20L); - } - - autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes")); - ticker.start(this); - - getLogger().log(Level.INFO, "Loading Third-Party plugin integrations..."); - thirdPartySupportService.start(); - - gitHubService.start(this); - - // Hooray! - getLogger().log(Level.INFO, "Slimefun has finished loading in {0}", getStartupTime(timestamp)); + onPluginStart(); } else { - instance = null; + // Terminate our Plugin instance + setInstance(null); + // CS-CoreLib has not been installed! getLogger().log(Level.INFO, "#################### - INFO - ####################"); getLogger().log(Level.INFO, " "); getLogger().log(Level.INFO, "Slimefun could not be loaded (yet)."); @@ -321,6 +225,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { getLogger().log(Level.INFO, "Please download and install CS-CoreLib manually:"); getLogger().log(Level.INFO, "https://thebusybiscuit.github.io/builds/TheBusyBiscuit/CS-CoreLib/master/"); + // Send a message upon doing /slimefun getCommand("slimefun").setExecutor((sender, cmd, label, args) -> { sender.sendMessage("You have forgotten to install CS-CoreLib! Slimefun is disabled."); sender.sendMessage("https://thebusybiscuit.github.io/builds/TheBusyBiscuit/CS-CoreLib/master/"); @@ -337,10 +242,131 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { gpsNetwork = new GPSNetwork(); networkManager = new NetworkManager(200); command.register(); - registry.load(config); + registry.load(this, config); loadTags(); } + /** + * This is our start method for a correct Slimefun installation. + */ + private void onPluginStart() { + long timestamp = System.nanoTime(); + + if (PaperLib.isPaper()) { + getLogger().log(Level.INFO, "Paper was detected! Performance optimizations have been applied."); + } else { + PaperLib.suggestPaper(this); + } + + // Disabling backwards-compatibility for fresh Slimefun installs + if (!new File("data-storage/Slimefun").exists()) { + config.setValue("options.backwards-compatibility", false); + config.save(); + + isNewlyInstalled = true; + } + + // Creating all necessary Folders + getLogger().log(Level.INFO, "Creating directories..."); + createDirectories(); + registry.load(this, config); + + // Set up localization + getLogger().log(Level.INFO, "Loading language files..."); + local = new LocalizationService(this, config.getString("options.chat-prefix"), config.getString("options.language")); + + // Setting up Networks + gpsNetwork = new GPSNetwork(); + + int networkSize = config.getInt("networks.max-size"); + + if (networkSize < 1) { + getLogger().log(Level.WARNING, "Your 'networks.max-size' setting is misconfigured! It must be at least 1, it was set to: {0}", networkSize); + networkSize = 1; + } + + networkManager = new NetworkManager(networkSize, config.getBoolean("networks.enable-visualizer"), config.getBoolean("networks.delete-excess-items")); + + // Setting up bStats + new Thread(metricsService::start, "Slimefun Metrics").start(); + + // Starting the Auto-Updater + if (config.getBoolean("options.auto-update")) { + getLogger().log(Level.INFO, "Starting Auto-Updater..."); + updaterService.start(); + } else { + updaterService.disable(); + } + + // Registering all GEO Resources + getLogger().log(Level.INFO, "Loading GEO-Resources..."); + GEOResourcesSetup.setup(); + + getLogger().log(Level.INFO, "Loading Tags..."); + loadTags(); + + getLogger().log(Level.INFO, "Loading items..."); + loadItems(); + + getLogger().log(Level.INFO, "Loading researches..."); + loadResearches(); + + registry.setResearchingEnabled(getResearchCfg().getBoolean("enable-researching")); + PostSetup.setupWiki(); + + getLogger().log(Level.INFO, "Registering listeners..."); + registerListeners(); + + // Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading) + runSync(new SlimefunStartupTask(this, () -> { + textureService.register(registry.getAllSlimefunItems(), true); + permissionsService.register(registry.getAllSlimefunItems(), true); + + // This try/catch should prevent buggy Spigot builds from blocking item loading + try { + recipeService.refresh(); + } catch (Exception | LinkageError x) { + getLogger().log(Level.SEVERE, x, () -> "An Exception occurred while iterating through the Recipe list on Minecraft Version " + minecraftVersion.getName() + " (Slimefun v" + getVersion() + ")"); + } + + }), 0); + + // Setting up our commands + try { + command.register(); + } catch (Exception | LinkageError x) { + getLogger().log(Level.SEVERE, "An Exception occurred while registering the /slimefun command", x); + } + + // Armor Update Task + if (config.getBoolean("options.enable-armor-effects")) { + boolean radioactiveFire = config.getBoolean("options.burn-players-when-radioactive"); + getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(radioactiveFire), 0L, config.getInt("options.armor-update-interval") * 20L); + } + + // Starting our tasks + autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes")); + ticker.start(this); + + // Loading integrations + getLogger().log(Level.INFO, "Loading Third-Party plugin integrations..."); + integrations.start(); + gitHubService.start(this); + + // Hooray! + getLogger().log(Level.INFO, "Slimefun has finished loading in {0}", getStartupTime(timestamp)); + } + + @Override + public JavaPlugin getJavaPlugin() { + return this; + } + + @Override + public String getBugTrackerURL() { + return "https://github.com/Slimefun/Slimefun4/issues"; + } + /** * This method gets called when the {@link Plugin} gets disabled. * Most often it is called when the {@link Server} is shutting down or reloading. @@ -378,6 +404,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + // Save all "universal" inventories (ender chests for example) for (UniversalBlockMenu menu : registry.getUniversalInventories().values()) { menu.save(); } @@ -388,20 +415,11 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { // Close and unload any resources from our Metrics Service metricsService.cleanUp(); - /** - * Prevent Memory Leaks for reloads... - * These static Maps should really be removed at some point... - */ - AContainer.processing = null; - AContainer.progress = null; + // Terminate our Plugin instance + setInstance(null); - AGenerator.processing = null; - AGenerator.progress = null; - - Reactor.processing = null; - Reactor.progress = null; - - instance = null; + // Clean up any static fields + cleanUp(); /** * Close all inventories on the server to prevent item dupes @@ -412,17 +430,55 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This is a private internal method to set the de-facto instance of {@link SlimefunPlugin}. + * Having this as a seperate method ensures the seperation between static and non-static fields. + * It also makes sonarcloud happy :) + * Only ever use it during {@link #onEnable()} or {@link #onDisable()}. + * + * @param pluginInstance + * Our instance of {@link SlimefunPlugin} or null + */ + private static void setInstance(@Nullable SlimefunPlugin pluginInstance) { + instance = pluginInstance; + } + + /** + * This returns the time it took to load Slimefun (given a starting point). + * + * @param timestamp + * The time at which we started to load Slimefun. + * + * @return The total time it took to load Slimefun (in ms or s) + */ @Nonnull private String getStartupTime(long timestamp) { long ms = (System.nanoTime() - timestamp) / 1000000; if (ms > 1000) { - return DoubleHandler.fixDouble(ms / 1000.0) + "s"; + return NumberUtils.roundDecimalNumber(ms / 1000.0) + "s"; } else { - return DoubleHandler.fixDouble(ms) + "ms"; + return NumberUtils.roundDecimalNumber(ms) + "ms"; } } + /** + * Cleaning up our static fields prevents memory leaks from a reload. + * + * @deprecated These static Maps should really be removed at some point... + */ + @Deprecated + private static void cleanUp() { + AContainer.processing = null; + AContainer.progress = null; + + AGenerator.processing = null; + AGenerator.progress = null; + + Reactor.processing = null; + Reactor.progress = null; + } + /** * This method checks for the {@link MinecraftVersion} of the {@link Server}. * If the version is unsupported, a warning will be printed to the console. @@ -430,32 +486,74 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { * @return Whether the {@link MinecraftVersion} is unsupported */ private boolean isVersionUnsupported() { - String currentVersion = ReflectionUtils.getVersion(); + try { + // First check if they still use the unsupported CraftBukkit software. + if (!PaperLib.isSpigot() && Bukkit.getName().equals("CraftBukkit")) { + getLogger().log(Level.SEVERE, "###############################################"); + getLogger().log(Level.SEVERE, "### Slimefun was not installed correctly!"); + getLogger().log(Level.SEVERE, "### CraftBukkit is no longer supported!"); + getLogger().log(Level.SEVERE, "###"); + getLogger().log(Level.SEVERE, "### Slimefun requires you to use Spigot, Paper or"); + getLogger().log(Level.SEVERE, "### any supported fork of Spigot or Paper."); + getLogger().log(Level.SEVERE, "### (We recommend Paper)"); + getLogger().log(Level.SEVERE, "###############################################"); - if (currentVersion.startsWith("v")) { - for (MinecraftVersion version : MinecraftVersion.valuesCache) { - if (version.matches(currentVersion)) { - minecraftVersion = version; - return false; - } + return true; } - // Looks like you are using an unsupported Minecraft Version - getLogger().log(Level.SEVERE, "#############################################"); - getLogger().log(Level.SEVERE, "### Slimefun was not installed correctly!"); - getLogger().log(Level.SEVERE, "### You are using the wrong version of Minecraft!"); - getLogger().log(Level.SEVERE, "###"); - getLogger().log(Level.SEVERE, "### You are using Minecraft {0}", currentVersion); - getLogger().log(Level.SEVERE, "### but Slimefun {0} requires you to be using", getDescription().getVersion()); - getLogger().log(Level.SEVERE, "### Minecraft {0}", String.join(" / ", getSupportedVersions())); - getLogger().log(Level.SEVERE, "#############################################"); + // Now check the actual Version of Minecraft + int version = PaperLib.getMinecraftVersion(); + + if (version > 0) { + // Check all supported versions of Minecraft + for (MinecraftVersion supportedVersion : MinecraftVersion.valuesCache) { + if (supportedVersion.isMinecraftVersion(version)) { + minecraftVersion = supportedVersion; + return false; + } + } + + // Looks like you are using an unsupported Minecraft Version + getLogger().log(Level.SEVERE, "#############################################"); + getLogger().log(Level.SEVERE, "### Slimefun was not installed correctly!"); + getLogger().log(Level.SEVERE, "### You are using the wrong version of Minecraft!"); + getLogger().log(Level.SEVERE, "###"); + getLogger().log(Level.SEVERE, "### You are using Minecraft 1.{0}.x", version); + getLogger().log(Level.SEVERE, "### but Slimefun {0} requires you to be using", getDescription().getVersion()); + getLogger().log(Level.SEVERE, "### Minecraft {0}", String.join(" / ", getSupportedVersions())); + getLogger().log(Level.SEVERE, "#############################################"); + return true; + } else { + getLogger().log(Level.WARNING, "We could not determine the version of Minecraft you were using? ({0})", Bukkit.getVersion()); + + /* + * If we are unsure about it, we will assume "supported". + * They could be using a non-Bukkit based Software which still + * might support Bukkit-based plugins. + * Use at your own risk in this case. + */ + return false; + } + } catch (Exception | LinkageError x) { + getLogger().log(Level.SEVERE, x, () -> "Error: Could not determine Environment or version of Minecraft for Slimefun v" + getDescription().getVersion()); + + // We assume "unsupported" if something went wrong. return true; } - - getLogger().log(Level.WARNING, "We could not determine the version of Minecraft you were using ({0})", currentVersion); - return false; } + /** + * This private method gives us a {@link Collection} of every {@link MinecraftVersion} + * that Slimefun is compatible with (as a {@link String} representation). + *

+ * Example: + * + *

+     * { 1.14.x, 1.15.x, 1.16.x }
+     * 
+ * + * @return A {@link Collection} of all compatible minecraft versions as strings + */ @Nonnull private Collection getSupportedVersions() { List list = new ArrayList<>(); @@ -469,6 +567,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return list; } + /** + * This method creates all necessary directories (and sub directories) for Slimefun. + */ private void createDirectories() { String[] storageFolders = { "Players", "blocks", "stored-blocks", "stored-inventories", "stored-chunks", "universal-inventories", "waypoints", "block-backups" }; String[] pluginFolders = { "scripts", "error-reports", "cache/github", "world-settings" }; @@ -564,6 +665,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new PlayerProfileListener(this); } + /** + * This (re)loads every {@link SlimefunTag}. + */ private void loadTags() { for (SlimefunTag tag : SlimefunTag.valuesCache) { try { @@ -577,6 +681,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This loads all of our items. + */ private void loadItems() { try { SlimefunItemSetup.setup(this); @@ -585,6 +692,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This loads our researches. + */ private void loadResearches() { try { ResearchSetup.setupResearches(); @@ -593,6 +703,19 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This private static method allows us to throw a proper {@link Exception} + * whenever someone tries to access a static method while the instance is null. + * This happens when the method is invoked before {@link #onEnable()} or after {@link #onDisable()}. + *

+ * Use it whenever a null check is needed to avoid a non-descriptive {@link NullPointerException}. + */ + private static void validateInstance() { + if (instance == null) { + throw new IllegalStateException("Cannot invoke static method, Slimefun instance is null."); + } + } + /** * This returns the global instance of {@link SlimefunPlugin}. * This may return null if the {@link Plugin} was disabled. @@ -604,24 +727,17 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance; } - public static Config getCfg() { - return instance.config; - } - - public static Config getResearchCfg() { - return instance.researches; - } - - public static Config getItemCfg() { - return instance.items; - } - - public static GPSNetwork getGPSNetwork() { - return instance.gpsNetwork; - } - - public static TickerTask getTickerTask() { - return instance.ticker; + /** + * This returns the {@link Logger} instance that Slimefun uses. + *

+ * Any {@link SlimefunAddon} should use their own {@link Logger} instance! + * + * @return Our {@link Logger} instance + */ + @Nonnull + public static Logger logger() { + validateInstance(); + return instance.getLogger(); } /** @@ -629,59 +745,96 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { * * @return The currently installed version of Slimefun */ + @Nonnull public static String getVersion() { + validateInstance(); return instance.getDescription().getVersion(); } + @Nonnull + public static Config getCfg() { + validateInstance(); + return instance.config; + } + + @Nonnull + public static Config getResearchCfg() { + validateInstance(); + return instance.researches; + } + + @Nonnull + public static Config getItemCfg() { + validateInstance(); + return instance.items; + } + + @Nonnull + public static GPSNetwork getGPSNetwork() { + validateInstance(); + return instance.gpsNetwork; + } + + @Nonnull + public static TickerTask getTickerTask() { + validateInstance(); + return instance.ticker; + } + /** * This returns the {@link LocalizationService} of Slimefun. * * @return The {@link LocalizationService} of Slimefun */ + @Nonnull public static LocalizationService getLocalization() { + validateInstance(); return instance.local; } - public static ProtectionManager getProtectionManager() { - return instance.protections; - } - + /** + * This method returns out {@link MinecraftRecipeService} for Slimefun. + * This service is responsible for finding/identifying {@link Recipe Recipes} + * from vanilla Minecraft. + * + * @return Slimefun's {@link MinecraftRecipeService} instance + */ + @Nonnull public static MinecraftRecipeService getMinecraftRecipeService() { + validateInstance(); return instance.recipeService; } + @Nonnull public static CustomItemDataService getItemDataService() { + validateInstance(); return instance.itemDataService; } + @Nonnull public static CustomTextureService getItemTextureService() { + validateInstance(); return instance.textureService; } + @Nonnull public static PermissionsService getPermissionsService() { + validateInstance(); return instance.permissionsService; } + @Nonnull public static BlockDataService getBlockDataService() { + validateInstance(); return instance.blockDataService; } + @Nonnull public static PerWorldSettingsService getWorldSettingsService() { + validateInstance(); return instance.worldSettingsService; } - /** - * This method has been renamed. - * - * @deprecated Please use {@link #getIntegrations()} instead. - * - * @return the {@link ThirdPartyPluginService} - */ - @Deprecated - public static ThirdPartyPluginService getThirdPartySupportService() { - return instance.thirdPartySupportService; - } - /** * This returns our instance of {@link IntegrationsManager}. * This is responsible for managing any integrations with third party {@link Plugin plugins}. @@ -690,7 +843,19 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { */ @Nonnull public static IntegrationsManager getIntegrations() { - return instance.thirdPartySupportService; + validateInstance(); + return instance.integrations; + } + + /** + * This returns out instance of the {@link ProtectionManager}. + * This bridge is used to hook into any third-party protection {@link Plugin}. + * + * @return Our instanceof of the {@link ProtectionManager} + */ + @Nonnull + public static ProtectionManager getProtectionManager() { + return getIntegrations().getProtectionManager(); } /** @@ -699,7 +864,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { * * @return The {@link UpdaterService} for Slimefun */ + @Nonnull public static UpdaterService getUpdater() { + validateInstance(); return instance.updaterService; } @@ -709,7 +876,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { * * @return The {@link MetricsService} for Slimefun */ + @Nonnull public static MetricsService getMetricsService() { + validateInstance(); return instance.metricsService; } @@ -719,30 +888,105 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { * * @return The {@link GitHubService} for Slimefun */ + @Nonnull public static GitHubService getGitHubService() { + validateInstance(); return instance.gitHubService; } - public static SlimefunRegistry getRegistry() { - return instance.registry; - } - + /** + * This returns our {@link NetworkManager} which is responsible + * for handling the Cargo and Energy networks. + * + * @return Our {@link NetworkManager} instance + */ + @Nonnull public static NetworkManager getNetworkManager() { + validateInstance(); return instance.networkManager; } + @Nonnull + public static SlimefunRegistry getRegistry() { + validateInstance(); + return instance.registry; + } + + @Nonnull public static GrapplingHookListener getGrapplingHookListener() { + validateInstance(); return instance.grapplingHookListener; } + @Nonnull public static BackpackListener getBackpackListener() { + validateInstance(); return instance.backpackListener; } + @Nonnull public static SlimefunBowListener getBowListener() { + validateInstance(); return instance.bowListener; } + /** + * The {@link Command} that was added by Slimefun. + * + * @return Slimefun's command + */ + @Nonnull + public static SlimefunCommand getCommand() { + validateInstance(); + return instance.command; + } + + /** + * This returns our instance of the {@link SlimefunProfiler}, a tool that is used + * to analyse performance and lag. + * + * @return The {@link SlimefunProfiler} + */ + @Nonnull + public static SlimefunProfiler getProfiler() { + validateInstance(); + return instance.profiler; + } + + /** + * This returns the currently installed version of Minecraft. + * + * @return The current version of Minecraft + */ + @Nonnull + public static MinecraftVersion getMinecraftVersion() { + validateInstance(); + return instance.minecraftVersion; + } + + /** + * This method returns whether this version of Slimefun was newly installed. + * It will return true if this {@link Server} uses Slimefun for the very first time. + * + * @return Whether this is a new installation of Slimefun + */ + public static boolean isNewlyInstalled() { + validateInstance(); + return instance.isNewlyInstalled; + } + + @Nonnull + public static String getCSCoreLibVersion() { + validateInstance(); + Plugin cscorelib = instance.getServer().getPluginManager().getPlugin("CS-CoreLib"); + + if (cscorelib == null) { + throw new IllegalStateException("CS-CoreLib is not installed."); + } else { + return cscorelib.getDescription().getVersion(); + } + } + /** * This method returns a {@link Set} of every {@link Plugin} that lists Slimefun * as a required or optional dependency. @@ -753,66 +997,17 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { */ @Nonnull public static Set getInstalledAddons() { - return Arrays.stream(instance.getServer().getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains(instance.getName()) || plugin.getDescription().getSoftDepend().contains(instance.getName())).collect(Collectors.toSet()); - } + validateInstance(); - /** - * The {@link Command} that was added by Slimefun. - * - * @return Slimefun's command - */ - public static SlimefunCommand getCommand() { - return instance.command; - } + String pluginName = instance.getName(); - /** - * This returns our instance of the {@link SlimefunProfiler}, a tool that is used - * to analyse performance and lag. - * - * @return The {@link SlimefunProfiler} - */ - public static SlimefunProfiler getProfiler() { - return instance.profiler; - } - - /** - * This returns the currently installed version of Minecraft. - * - * @return The current version of Minecraft - */ - public static MinecraftVersion getMinecraftVersion() { - return instance.minecraftVersion; - } - - /** - * This method returns whether this version of Slimefun was newly installed. - * It will return true if this {@link Server} uses Slimefun for the very first time. - * - * @return Whether this is a new installation of Slimefun - */ - public static boolean isNewlyInstalled() { - return instance.isNewlyInstalled; - } - - @Nonnull - public static String getCSCoreLibVersion() { - Plugin cscorelib = instance.getServer().getPluginManager().getPlugin("CS-CoreLib"); - - if (cscorelib == null) { - throw new IllegalStateException("CS-CoreLib is not installed."); - } else { - return cscorelib.getDescription().getVersion(); - } - } - - @Override - public JavaPlugin getJavaPlugin() { - return this; - } - - @Override - public String getBugTrackerURL() { - return "https://github.com/Slimefun/Slimefun4/issues"; + // @formatter:off + return Arrays.stream(instance.getServer().getPluginManager().getPlugins()) + .filter(plugin -> { + PluginDescriptionFile description = plugin.getDescription(); + return description.getDepend().contains(pluginName) || description.getSoftDepend().contains(pluginName); + }).collect(Collectors.toSet()); + // @formatter:on } /** @@ -874,4 +1069,4 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance.getServer().getScheduler().runTask(instance, runnable); } -} +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java deleted file mode 100644 index a5c7c1d29..000000000 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java +++ /dev/null @@ -1,253 +0,0 @@ -package io.github.thebusybiscuit.slimefun4.implementation.guide; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; - -import org.bukkit.ChatColor; -import org.bukkit.NamespacedKey; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import io.github.thebusybiscuit.cscorelib2.chat.ChatInput; -import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent; -import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent; -import io.github.thebusybiscuit.cscorelib2.chat.json.CustomBookInterface; -import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; -import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; -import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; -import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; -import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; -import io.github.thebusybiscuit.slimefun4.core.researching.Research; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; -import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; -import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem; -import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; - -/** - * The {@link BookSlimefunGuide} is a {@link SlimefunGuideImplementation} which - * uses a {@link CustomBookInterface} to display the contents of the {@link SlimefunGuide}. - * {@link Player Players} have the option to choose this Written Book layout over the - * standard {@link Inventory} variant. - * - * @author TheBusyBiscuit - * - * @see SlimefunGuide - * @see SlimefunGuideImplementation - * @see ChestSlimefunGuide - * @see CheatSheetSlimefunGuide - * - */ -public class BookSlimefunGuide implements SlimefunGuideImplementation { - - private final NamespacedKey guideSearch = new NamespacedKey(SlimefunPlugin.instance(), "search"); - private final ItemStack item; - - public BookSlimefunGuide() { - item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Book GUI)"); - } - - @Override - public SlimefunGuideLayout getLayout() { - return SlimefunGuideLayout.BOOK; - } - - @Override - public boolean isSurvivalMode() { - return true; - } - - @Override - public ItemStack getItem() { - return item; - } - - private void openBook(Player p, PlayerProfile profile, List lines, boolean backButton) { - CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance()); - book.setTitle(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main")); - - for (int i = 0; i < lines.size(); i = i + 10) { - ChatComponent page = new ChatComponent(""); - ChatComponent header = new ChatComponent(ChatColors.color("&b&l- " + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main") + " -\n\n")); - header.setHoverEvent(new HoverEvent(ChestMenuUtils.getSearchButton(p))); - - header.setClickEvent(new ClickEvent(guideSearch, player -> SlimefunPlugin.runSync(() -> { - SlimefunPlugin.getLocalization().sendMessage(player, "guide.search.message"); - ChatInput.waitForPlayer(SlimefunPlugin.instance(), player, msg -> SlimefunGuide.openSearch(profile, msg, true, true)); - }, 1))); - - page.append(header); - - for (int j = i; j < lines.size() && j < i + 10; j++) { - page.append(lines.get(j)); - } - - page.append(new ChatComponent("\n")); - - if (backButton) { - ChatComponent button = new ChatComponent(ChatColor.DARK_BLUE + "\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title")); - button.setHoverEvent(new HoverEvent(ChatColor.DARK_BLUE + "\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"), "", ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide"))); - button.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance(), "slimefun_guide"), pl -> openMainMenu(profile, 1))); - page.append(button); - } - - book.addPage(page); - } - - book.open(p); - } - - @Override - public void openMainMenu(PlayerProfile profile, int page) { - Player p = profile.getPlayer(); - - if (p == null) { - return; - } - - List lines = new LinkedList<>(); - int tier = 0; - - for (Category category : SlimefunPlugin.getRegistry().getCategories()) { - if (!category.isHidden(p) && (!(category instanceof FlexCategory) || ((FlexCategory) category).isVisible(p, profile, getLayout()))) { - if (tier < category.getTier()) { - tier = category.getTier(); - - if (tier > 1) { - for (int i = 0; i < 10 && lines.size() % 10 != 0; i++) { - lines.add(new ChatComponent("\n")); - } - } - - lines.add(new ChatComponent(ChatColor.DARK_GRAY + "\u21E8" + ChatColor.DARK_BLUE + " Tier " + tier + "\n")); - } - - addCategory(p, profile, category, lines); - } - } - - openBook(p, profile, lines, false); - } - - private void addCategory(Player p, PlayerProfile profile, Category category, List lines) { - if (category instanceof LockedCategory && !((LockedCategory) category).hasUnlocked(p, profile)) { - List lore = new LinkedList<>(); - lore.add(ChatColor.DARK_RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked") + " " + ChatColor.GRAY + "- " + ChatColor.RESET + category.getItem(p).getItemMeta().getDisplayName()); - lore.add(""); - - for (String line : SlimefunPlugin.getLocalization().getMessages(p, "guide.locked-category")) { - lore.add(ChatColor.RESET + line); - } - - lore.add(""); - - for (Category parent : ((LockedCategory) category).getParents()) { - lore.add(parent.getItem(p).getItemMeta().getDisplayName()); - } - - ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.RED, ItemUtils.getItemName(category.getItem(p))) + "\n"); - chatComponent.setHoverEvent(new HoverEvent(lore)); - lines.add(chatComponent); - } else { - ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, ItemUtils.getItemName(category.getItem(p))) + "\n"); - chatComponent.setHoverEvent(new HoverEvent(ItemUtils.getItemName(category.getItem(p)), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category"))); - chatComponent.setClickEvent(new ClickEvent(category.getKey(), pl -> openCategory(profile, category, 1))); - lines.add(chatComponent); - } - } - - @Override - public void openCategory(PlayerProfile profile, Category category, int page) { - Player p = profile.getPlayer(); - - if (p == null) { - return; - } - - if (category instanceof FlexCategory) { - ((FlexCategory) category).open(p, profile, getLayout()); - } else if (category.getItems().size() < 250) { - profile.getGuideHistory().add(category, page); - - List items = new LinkedList<>(); - - for (SlimefunItem slimefunItem : category.getItems()) { - if (Slimefun.hasPermission(p, slimefunItem, false)) { - if (Slimefun.isEnabled(p, slimefunItem, false)) { - addSlimefunItem(category, page, p, profile, slimefunItem, items); - } - } else { - ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_RED, ItemUtils.getItemName(slimefunItem.getItem())) + "\n"); - - List lore = new ArrayList<>(); - lore.add(ChatColor.DARK_RED + ChatColor.stripColor(ItemUtils.getItemName(slimefunItem.getItem()))); - lore.add(""); - - for (String line : SlimefunPlugin.getPermissionsService().getLore(slimefunItem)) { - lore.add(ChatColors.color(line)); - } - - component.setHoverEvent(new HoverEvent(lore)); - items.add(component); - } - } - - openBook(p, profile, items, true); - } else { - p.sendMessage(ChatColor.RED + "That Category is too big to open :/"); - } - } - - private void addSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List items) { - NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getId().toLowerCase(Locale.ROOT)); - - if (!Slimefun.hasUnlocked(p, item, false) && item.getResearch() != null) { - Research research = item.getResearch(); - - ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.RED, item.getItemName()) + "\n"); - component.setHoverEvent(new HoverEvent(ChatColor.RESET + item.getItemName(), ChatColor.DARK_RED.toString() + ChatColor.BOLD + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", ChatColor.GREEN + "> Click to unlock", "", ChatColor.GRAY + "Cost: " + ChatColor.AQUA.toString() + research.getCost() + " Level(s)")); - component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> research.unlockFromGuide(this, player, profile, item, category, page)))); - - items.add(component); - } else { - ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, item.getItemName()) + "\n"); - - List lore = new ArrayList<>(); - lore.add(item.getItemName()); - - if (item.getItem().hasItemMeta() && item.getItem().getItemMeta().hasLore()) { - lore.addAll(item.getItem().getItemMeta().getLore()); - } - - component.setHoverEvent(new HoverEvent(lore)); - component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> displayItem(profile, item, true)))); - items.add(component); - } - } - - @Override - public void openSearch(PlayerProfile profile, String input, boolean addToHistory) { - // We need to write a book implementation for this at some point - SlimefunGuide.openSearch(profile, input, true, addToHistory); - } - - @Override - public void displayItem(PlayerProfile profile, ItemStack item, int index, boolean addToHistory) { - SlimefunGuide.displayItem(profile, item, addToHistory); - } - - @Override - public void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) { - SlimefunGuide.displayItem(profile, item, addToHistory); - } - -} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java index d02c04c7e..f45f47272 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java @@ -12,7 +12,7 @@ import org.bukkit.inventory.Recipe; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem; @@ -21,13 +21,13 @@ import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** - * This is an admin-variant of the {@link ChestSlimefunGuide} which allows a {@link Player} + * This is an admin-variant of the {@link SurvivalSlimefunGuide} which allows a {@link Player} * to spawn in a {@link SlimefunItem} via click rather than showing their {@link Recipe}. * * @author TheBusyBiscuit * */ -public class CheatSheetSlimefunGuide extends ChestSlimefunGuide { +public class CheatSheetSlimefunGuide extends SurvivalSlimefunGuide { private final ItemStack item; @@ -37,11 +37,6 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide { item = new SlimefunGuideItem(this, "&cSlimefun Guide &4(Cheat Sheet)"); } - @Override - public boolean isSurvivalMode() { - return false; - } - /** * Returns a {@link List} of visible {@link Category} instances that the {@link SlimefunGuide} would display. * @@ -65,11 +60,13 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide { return categories; } + @Nonnull @Override - public SlimefunGuideLayout getLayout() { - return SlimefunGuideLayout.CHEAT_SHEET; + public SlimefunGuideMode getMode() { + return SlimefunGuideMode.CHEAT_MODE; } + @Nonnull @Override public ItemStack getItem() { return item; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java index 51917a37e..acb1b57f9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java @@ -21,7 +21,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; * A {@link RecipeChoiceTask} is an asynchronously repeating task that cycles * through the different variants of {@link Material} that a {@link MaterialChoice} or {@link Tag} can represent. * - * It is used in the {@link ChestSlimefunGuide} for any {@link ItemStack} from Minecraft + * It is used in the {@link SurvivalSlimefunGuide} for any {@link ItemStack} from Minecraft * that accepts more than one {@link Material} in its {@link Recipe}. * * @author TheBusyBiscuit diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java similarity index 94% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java index e140f2b7c..2f8964939 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java @@ -27,6 +27,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatInput; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe; +import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; @@ -34,7 +35,7 @@ import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory; import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; @@ -51,18 +52,17 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.Slimefun; /** - * The {@link ChestSlimefunGuide} is the standard version of our {@link SlimefunGuide}. + * The {@link SurvivalSlimefunGuide} is the standard version of our {@link SlimefunGuide}. * It uses an {@link Inventory} to display {@link SlimefunGuide} contents. * * @author TheBusyBiscuit * * @see SlimefunGuide * @see SlimefunGuideImplementation - * @see BookSlimefunGuide * @see CheatSheetSlimefunGuide * */ -public class ChestSlimefunGuide implements SlimefunGuideImplementation { +public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { private static final int CATEGORY_SIZE = 36; private static final Sound sound = Sound.ITEM_BOOK_PAGE_TURN; @@ -71,14 +71,14 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { private final ItemStack item; private final boolean showVanillaRecipes; - public ChestSlimefunGuide(boolean showVanillaRecipes) { + public SurvivalSlimefunGuide(boolean showVanillaRecipes) { this.showVanillaRecipes = showVanillaRecipes; item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)"); } @Override - public SlimefunGuideLayout getLayout() { - return SlimefunGuideLayout.CHEST; + public SlimefunGuideMode getMode() { + return SlimefunGuideMode.SURVIVAL_MODE; } @Override @@ -86,9 +86,8 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { return item; } - @Override - public boolean isSurvivalMode() { - return true; + protected final boolean isSurvivalMode() { + return getMode() != SlimefunGuideMode.CHEAT_MODE; } /** @@ -105,8 +104,18 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { List categories = new LinkedList<>(); for (Category category : SlimefunPlugin.getRegistry().getCategories()) { - if (!category.isHidden(p) && (!(category instanceof FlexCategory) || ((FlexCategory) category).isVisible(p, profile, getLayout()))) { - categories.add(category); + try { + if (!category.isHidden(p) && (!(category instanceof FlexCategory) || ((FlexCategory) category).isVisible(p, profile, getMode()))) { + categories.add(category); + } + } catch (Exception | LinkageError x) { + SlimefunAddon addon = category.getAddon(); + + if (addon != null) { + addon.getLogger().log(Level.SEVERE, x, () -> "Could not display Category: " + category); + } else { + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "Could not display Category: " + category); + } } } @@ -204,7 +213,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { } if (category instanceof FlexCategory) { - ((FlexCategory) category).open(p, profile, getLayout()); + ((FlexCategory) category).open(p, profile, getMode()); return; } @@ -561,7 +570,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { pl.closeInventory(); SlimefunPlugin.getLocalization().sendMessage(pl, "guide.search.message"); - ChatInput.waitForPlayer(SlimefunPlugin.instance(), pl, msg -> SlimefunGuide.openSearch(profile, msg, isSurvivalMode(), isSurvivalMode())); + ChatInput.waitForPlayer(SlimefunPlugin.instance(), pl, msg -> SlimefunGuide.openSearch(profile, msg, getMode(), isSurvivalMode())); return false; }); @@ -698,7 +707,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { private void printErrorMessage(Player p, Throwable x) { p.sendMessage(ChatColor.DARK_RED + "An internal server error has occurred. Please inform an admin, check the console for further info."); - Slimefun.getLogger().log(Level.SEVERE, "An error has occurred while trying to open a SlimefunItem in the guide!", x); + SlimefunPlugin.logger().log(Level.SEVERE, "An error has occurred while trying to open a SlimefunItem in the guide!", x); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java deleted file mode 100644 index 01117440f..000000000 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.github.thebusybiscuit.slimefun4.implementation.items.androids; - -import java.util.Optional; - -import javax.annotation.ParametersAreNonnullByDefault; - -import org.bukkit.Effect; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.Lists.RecipeType; -import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; - -/** - * The {@link AdvancedFarmerAndroid} is an extension of the {@link FarmerAndroid}. - * It also allows the {@link Player} to harvest plants from the addon ExoticGarden. - * - * @author John000708 - * @author TheBusyBiscuit - * - * @see FarmerAndroid - * - */ -public class AdvancedFarmerAndroid extends FarmerAndroid { - - @ParametersAreNonnullByDefault - public AdvancedFarmerAndroid(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { - super(category, tier, item, recipeType, recipe); - } - - @Override - public AndroidType getAndroidType() { - return AndroidType.ADVANCED_FARMER; - } - - @Override - protected void exoticFarm(BlockMenu menu, Block block) { - farm(menu, block); - - if (SlimefunPlugin.getIntegrations().isExoticGardenInstalled()) { - Optional result = SlimefunPlugin.getThirdPartySupportService().harvestExoticGardenPlant(block); - - if (result.isPresent()) { - ItemStack drop = result.get(); - menu.pushItem(drop, getOutputSlots()); - block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); - } - } - } - -} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java index 732c998a3..fbbbdb108 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java @@ -29,7 +29,7 @@ public enum AndroidType { FARMER, /** - * The {@link AdvancedFarmerAndroid} is an extension of the {@link FarmerAndroid}, + * The Advanced Farmer is an extension of the {@link FarmerAndroid}, * it can also harvest plants from ExoticGarden. */ ADVANCED_FARMER, diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java index e46721c84..44948ab4b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java @@ -3,6 +3,9 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Material; import org.bukkit.block.Block; @@ -10,6 +13,7 @@ import org.bukkit.block.data.Ageable; import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.events.AndroidFarmEvent; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; @@ -17,37 +21,41 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; public class FarmerAndroid extends ProgrammableAndroid { + @ParametersAreNonnullByDefault public FarmerAndroid(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, tier, item, recipeType, recipe); } @Override public AndroidType getAndroidType() { - return AndroidType.FARMER; - } - - private boolean isFullGrown(Block block) { - BlockData data = block.getBlockData(); - - if (!(data instanceof Ageable)) { - return false; - } - - Ageable ageable = (Ageable) data; - return ageable.getAge() >= ageable.getMaximumAge(); + return getTier() == 1 ? AndroidType.FARMER : AndroidType.ADVANCED_FARMER; } @Override - protected void farm(BlockMenu menu, Block block) { - if (isFullGrown(block)) { - ItemStack drop = getDropFromCrop(block.getType()); + protected void farm(Block b, BlockMenu menu, Block block, boolean isAdvanced) { + Material blockType = block.getType(); + BlockData data = block.getBlockData(); + ItemStack drop = null; - if (drop != null && menu.fits(drop, getOutputSlots())) { - menu.pushItem(drop, getOutputSlots()); - Ageable ageable = (Ageable) block.getBlockData(); - ageable.setAge(0); - block.setBlockData(ageable); - block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); + if (data instanceof Ageable && ((Ageable) data).getAge() >= ((Ageable) data).getMaximumAge()) { + drop = getDropFromCrop(blockType); + } + + AndroidInstance instance = new AndroidInstance(this, b); + + AndroidFarmEvent event = new AndroidFarmEvent(block, instance, isAdvanced, drop); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + drop = event.getDrop(); + + if (drop != null && menu.pushItem(drop, getOutputSlots()) == null) { + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, blockType); + + if (data instanceof Ageable) { + ((Ageable) data).setAge(0); + block.setBlockData(data); + } } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java index 6c707c979..4f1ffef80 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java @@ -1,11 +1,12 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; + import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Predicate; import org.apache.commons.lang.Validate; import org.bukkit.Location; @@ -191,7 +192,7 @@ public enum Instruction { */ FARM_FORWARD(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> { Block target = b.getRelative(face); - android.farm(inv, target); + android.farm(b, inv, target, false); }), /** @@ -200,7 +201,7 @@ public enum Instruction { */ FARM_DOWN(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> { Block target = b.getRelative(BlockFace.DOWN); - android.farm(inv, target); + android.farm(b, inv, target, false); }), /** @@ -211,7 +212,7 @@ public enum Instruction { */ FARM_EXOTIC_FORWARD(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> { Block target = b.getRelative(face); - android.exoticFarm(inv, target); + android.farm(b, inv, target, true); }), /** @@ -222,7 +223,7 @@ public enum Instruction { */ FARM_EXOTIC_DOWN(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> { Block target = b.getRelative(BlockFace.DOWN); - android.exoticFarm(inv, target); + android.farm(b, inv, target, true); }), /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index c4b1dde5f..c44b3b358 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -58,7 +58,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -425,7 +424,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, openScriptEditor(player, b); } } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, "An Exception was thrown when a User tried to download a Script!", x); + SlimefunPlugin.logger().log(Level.SEVERE, "An Exception was thrown when a User tried to download a Script!", x); } return false; @@ -844,6 +843,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, } } + @ParametersAreNonnullByDefault protected void move(Block b, BlockFace face, Block block) { if (block.getY() > 0 && block.getY() < block.getWorld().getMaxHeight() && block.isEmpty()) { BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { @@ -881,11 +881,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, throw new UnsupportedOperationException("Non-woodcutter Android tried to chop a Tree!"); } - protected void farm(BlockMenu menu, Block block) { - throw new UnsupportedOperationException("Non-farming Android tried to farm!"); - } - - protected void exoticFarm(BlockMenu menu, Block block) { + protected void farm(Block b, BlockMenu menu, Block block, boolean isAdvanced) { throw new UnsupportedOperationException("Non-farming Android tried to farm!"); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Script.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Script.java index 6437e91f6..4d77461da 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Script.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Script.java @@ -21,9 +21,9 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * A {@link Script} represents runnable code for a {@link ProgrammableAndroid}. @@ -244,7 +244,7 @@ public final class Script { scripts.add(new Script(config)); } } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception occurred while trying to load Android Script '" + file.getName() + "'"); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Exception occurred while trying to load Android Script '" + file.getName() + "'"); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/StomperBoots.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/StomperBoots.java index da217cf57..3888d6506 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/StomperBoots.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/StomperBoots.java @@ -105,7 +105,6 @@ public class StomperBoots extends SlimefunItem { * @return If the entity can move. */ protected boolean canPush(@Nonnull Player player, @Nonnull LivingEntity entity) { - return entity.isValid() && !entity.getUniqueId().equals(player.getUniqueId()) - && entity.isCollidable() && entity.hasGravity(); + return entity.isValid() && !entity.getUniqueId().equals(player.getUniqueId()) && entity.isCollidable() && entity.hasGravity(); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java index f1e76e80c..67d40365b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/HologramProjector.java @@ -11,13 +11,13 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Lists.RecipeType; @@ -90,9 +90,9 @@ public class HologramProjector extends SlimefunItem implements HologramOwner { return false; }); - menu.addItem(1, new CustomItem(Material.CLOCK, "&7Offset: &e" + DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + 1.0D), "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1")); + menu.addItem(1, new CustomItem(Material.CLOCK, "&7Offset: &e" + NumberUtils.roundDecimalNumber(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + 1.0D), "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1")); menu.addMenuClickHandler(1, (pl, slot, item, action) -> { - double offset = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + (action.isRightClicked() ? -0.1F : 0.1F)); + double offset = NumberUtils.reparseDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + (action.isRightClicked() ? -0.1F : 0.1F)); ArmorStand hologram = getArmorStand(projector, true); Location l = new Location(projector.getWorld(), projector.getX() + 0.5, projector.getY() + offset, projector.getZ() + 0.5); hologram.teleport(l); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java index 3a985b381..6ae364082 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/AbstractEnergyProvider.java @@ -14,7 +14,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; @@ -114,7 +113,7 @@ public abstract class AbstractEnergyProvider extends SlimefunItem implements Inv List lore = new ArrayList<>(); lore.add(ChatColors.color("&8\u21E8 &7Lasts " + NumberUtils.getTimeLeft(fuel.getTicks() / 2))); lore.add(ChatColors.color("&8\u21E8 &e\u26A1 &7" + getEnergyProduction() * 2) + " J/s"); - lore.add(ChatColors.color("&8\u21E8 &e\u26A1 &7" + DoubleHandler.getFancyDouble((double) fuel.getTicks() * getEnergyProduction()) + " J in total")); + lore.add(ChatColors.color("&8\u21E8 &e\u26A1 &7" + NumberUtils.getCompactDouble((double) fuel.getTicks() * getEnergyProduction()) + " J in total")); im.setLore(lore); item.setItemMeta(im); list.add(item); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java index cba3f71cf..eae1b162b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/MultiTool.java @@ -52,8 +52,7 @@ public class MultiTool extends SlimefunItem implements Rechargeable { if (index >= modes.size()) { index = 0; } - } - while (index != i && !modes.get(index).isEnabled()); + } while (index != i && !modes.get(index).isEnabled()); return index; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java index b6eb0c527..8c9959b58 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java @@ -11,7 +11,6 @@ import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; @@ -20,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponen import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; @@ -166,7 +166,7 @@ public abstract class AbstractEntityAssembler extends SimpleSl menu.replaceExistingItem(31, new CustomItem(Material.PISTON, "&7Offset: &3" + offset + " Block(s)", "", "&fLeft Click: &7+0.1", "&fRight Click: &7-0.1")); menu.addMenuClickHandler(31, (p, slot, item, action) -> { - double offsetv = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)) + (action.isRightClicked() ? -0.1F : 0.1F)); + double offsetv = NumberUtils.reparseDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)) + (action.isRightClicked() ? -0.1F : 0.1F)); BlockStorage.addBlockInfo(b, KEY_OFFSET, String.valueOf(offsetv)); updateBlockInventory(menu, b); return false; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java new file mode 100644 index 000000000..24e6f2b9c --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java @@ -0,0 +1,93 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.elevator; + +import javax.annotation.Nonnull; + +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +/** + * This represents an {@link ElevatorFloor} to which a {@link Player} + * can travel to using an {@link ElevatorPlate}. + * + * @author TheBusyBiscuit + * + */ +class ElevatorFloor { + + /** + * The name of this floor. + */ + private final String name; + + /** + * The floor number. + */ + private final int number; + + /** + * The {@link Location} of this floor. + */ + private final Location location; + + /** + * This constructs a new {@link ElevatorFloor} with the given name + * and the {@link Location} of the provided {@link Block}. + * + * @param name + * The name of this {@link ElevatorFloor} + * @param block + * The {@link Block} of this floor + */ + public ElevatorFloor(@Nonnull String name, int number, @Nonnull Block block) { + Validate.notNull(name, "An ElevatorFloor must have a name"); + Validate.notNull(block, "An ElevatorFloor must have a block"); + + this.name = name; + this.number = number; + this.location = block.getLocation(); + } + + /** + * This returns the name of this {@link ElevatorFloor}. + * + * @return The name of this floor + */ + @Nonnull + public String getName() { + return name; + } + + /** + * This returns the {@link Location} of this {@link ElevatorFloor}. + * + * @return The {@link Location} of this floor + */ + @Nonnull + public Location getLocation() { + return location; + } + + /** + * This returns the "altitude" of this floor. + * This is equivalent to the Y level of {@link #getLocation()}. + * + * @return The altitude of this floor + */ + public int getAltitude() { + return location.getBlockY(); + } + + /** + * This returns the number of this floor. + * The lowest floor will have the number 0 and it + * increments from there. + * + * @return The number of this floor. + */ + public int getNumber() { + return number; + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorPlate.java similarity index 59% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorPlate.java index 1d7dc7ae0..59e6dab5c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorPlate.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.items.gps; +package io.github.thebusybiscuit.slimefun4.implementation.items.elevator; import java.util.HashSet; import java.util.LinkedList; @@ -12,22 +12,19 @@ import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.NamespacedKey; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent; -import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent; -import io.github.thebusybiscuit.cscorelib2.chat.json.CustomBookInterface; -import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.papermc.lib.PaperLib; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; @@ -40,9 +37,9 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * The {@link ElevatorPlate} is a quick way of teleportation. * You can place multiple {@link ElevatorPlate ElevatorPlates} along the y axis * to teleport between them. - * - * @author TheBusyBiscuit * + * @author TheBusyBiscuit + * @author Walshy */ public class ElevatorPlate extends SimpleSlimefunItem { @@ -51,6 +48,11 @@ public class ElevatorPlate extends SimpleSlimefunItem { */ private static final String DATA_KEY = "floor"; + /** + * This is the size of our {@link Inventory}. + */ + private static final int GUI_SIZE = 27; + /** * This is our {@link Set} of currently teleporting {@link Player Players}. * It is used to prevent them from triggering the {@link ElevatorPlate} they land on. @@ -77,6 +79,7 @@ public class ElevatorPlate extends SimpleSlimefunItem { }; } + @Nonnull @Override public BlockUseHandler getItemHandler() { return e -> { @@ -89,19 +92,24 @@ public class ElevatorPlate extends SimpleSlimefunItem { } @Nonnull - public List getFloors(@Nonnull Block b) { - List floors = new LinkedList<>(); + public List getFloors(@Nonnull Block b) { + LinkedList floors = new LinkedList<>(); + int index = 0; - for (int y = b.getWorld().getMaxHeight(); y > 0; y--) { + for (int y = 0; y < b.getWorld().getMaxHeight(); y++) { if (y == b.getY()) { - floors.add(b); + String name = ChatColors.color(BlockStorage.getLocationInfo(b.getLocation(), DATA_KEY)); + floors.addFirst(new ElevatorFloor(name, index, b)); + index++; continue; } Block block = b.getWorld().getBlockAt(b.getX(), y, b.getZ()); if (block.getType() == getItem().getType() && BlockStorage.check(block, getId())) { - floors.add(block); + String name = ChatColors.color(BlockStorage.getLocationInfo(block.getLocation(), DATA_KEY)); + floors.addFirst(new ElevatorFloor(name, index, block)); + index++; } } @@ -114,54 +122,69 @@ public class ElevatorPlate extends SimpleSlimefunItem { return; } - List floors = getFloors(b); + List floors = getFloors(b); if (floors.size() < 2) { SlimefunPlugin.getLocalization().sendMessage(p, "machines.ELEVATOR.no-destinations", true); } else { - openFloorSelector(b, floors, p); + openFloorSelector(b, floors, p, 1); } } @ParametersAreNonnullByDefault - private void openFloorSelector(Block b, List floors, Player p) { - CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance()); - ChatComponent page = null; + private void openFloorSelector(Block b, List floors, Player p, int page) { + ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.pick-a-floor")); + menu.setEmptySlotsClickable(false); - for (int i = 0; i < floors.size(); i++) { - if (i % 10 == 0) { - if (page != null) { - book.addPage(page); - } + int index = GUI_SIZE * (page - 1); - page = new ChatComponent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.pick-a-floor")) + "\n"); - } + for (int i = 0; i < Math.min(GUI_SIZE, floors.size() - index); i++) { + ElevatorFloor floor = floors.get(index + i); - Block block = floors.get(i); - String floor = ChatColors.color(BlockStorage.getLocationInfo(block.getLocation(), DATA_KEY)); - ChatComponent line; - - if (block.getY() == b.getY()) { - line = new ChatComponent("\n" + ChatColor.GRAY + "> " + (floors.size() - i) + ". " + ChatColor.BLACK + floor); - line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.current-floor")), "", ChatColor.WHITE + floor, "")); + // @formatter:off + if (floor.getAltitude() == b.getY()) { + menu.addItem(i, new CustomItem( + Material.COMPASS, + ChatColor.GRAY.toString() + floor.getNumber() + ". " + ChatColor.BLACK + floor.getName(), + SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.current-floor") + ' ' + ChatColor.WHITE + floor.getName() + ), ChestMenuUtils.getEmptyClickHandler()); } else { - line = new ChatComponent("\n" + ChatColor.GRAY + (floors.size() - i) + ". " + ChatColor.BLACK + floor); - line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.click-to-teleport")), "", ChatColor.WHITE + floor, "")); - line.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance(), DATA_KEY + i), player -> teleport(player, floor, block))); + menu.addItem(i, new CustomItem( + Material.PAPER, + ChatColor.GRAY.toString() + floor.getNumber() + ". " + ChatColor.BLACK + floor.getName(), + SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.click-to-teleport") + ' ' + ChatColor.WHITE + floor.getName() + ), (player, slot, itemStack, clickAction) -> { + teleport(player, floor); + return false; + }); } - - page.append(line); + // @formatter:on } - if (page != null) { - book.addPage(page); + int pages = 1 + (floors.size() / GUI_SIZE); + + // 0 index so size is the first slot of the last row. + for (int i = GUI_SIZE; i < GUI_SIZE + 9; i++) { + if (i == GUI_SIZE + 2 && pages > 1 && page != 1) { + menu.addItem(i, ChestMenuUtils.getPreviousButton(p, page, pages), (player, i1, itemStack, clickAction) -> { + openFloorSelector(b, floors, p, page - 1); + return false; + }); + } else if (i == GUI_SIZE + 6 && pages > 1 && page != pages) { + menu.addItem(i, ChestMenuUtils.getNextButton(p, page, pages), (player, i1, itemStack, clickAction) -> { + openFloorSelector(b, floors, p, page + 1); + return false; + }); + } else { + menu.addItem(i, ChestMenuUtils.getBackground(), (player, i1, itemStack, clickAction) -> false); + } } - book.open(p); + menu.open(p); } @ParametersAreNonnullByDefault - private void teleport(Player player, String floorName, Block target) { + private void teleport(Player player, ElevatorFloor floor) { SlimefunPlugin.runSync(() -> { users.add(player.getUniqueId()); @@ -171,11 +194,12 @@ public class ElevatorPlate extends SimpleSlimefunItem { yaw = -180 + (yaw - 180); } - Location destination = new Location(player.getWorld(), target.getX() + 0.5, target.getY() + 0.4, target.getZ() + 0.5, yaw, player.getEyeLocation().getPitch()); + Location loc = floor.getLocation(); + Location destination = new Location(player.getWorld(), loc.getX() + 0.5, loc.getY() + 0.4, loc.getZ() + 0.5, yaw, player.getEyeLocation().getPitch()); PaperLib.teleportAsync(player, destination).thenAccept(teleported -> { if (teleported.booleanValue()) { - player.sendTitle(ChatColor.WHITE + ChatColors.color(floorName), null, 20, 60, 20); + player.sendTitle(ChatColor.WHITE + ChatColors.color(floor.getName()), null, 20, 60, 20); } }); }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/package-info.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/package-info.java new file mode 100644 index 000000000..46e84ac6f --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/package-info.java @@ -0,0 +1,5 @@ +/** + * This package holds the {@link io.github.thebusybiscuit.slimefun4.implementation.items.elevator.ElevatorPlate} and any + * related classes to making the elevator work. + */ +package io.github.thebusybiscuit.slimefun4.implementation.items.elevator; \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/MagicianTalisman.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/MagicianTalisman.java index 2d9ff2068..2d9959a11 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/MagicianTalisman.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/MagicianTalisman.java @@ -17,8 +17,8 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchantment; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -42,7 +42,7 @@ public class MagicianTalisman extends Talisman { enchantments.add(new TalismanEnchantment(enchantment, i)); } } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "The following Exception occurred while trying to register the following Enchantment: " + enchantment); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "The following Exception occurred while trying to register the following Enchantment: " + enchantment); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java index 9c548d7f2..236a46f8a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java @@ -27,7 +27,6 @@ import io.github.thebusybiscuit.cscorelib2.scheduling.TaskQueue; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This represents a running instance of an {@link IndustrialMiner}. @@ -198,7 +197,7 @@ class ActiveMiner implements Runnable { nextColumn(); } catch (Exception e) { - Slimefun.getLogger().log(Level.SEVERE, e, () -> "An Error occurred while running an Industrial Miner at " + new BlockPosition(chest)); + SlimefunPlugin.logger().log(Level.SEVERE, e, () -> "An Error occurred while running an Industrial Miner at " + new BlockPosition(chest)); stop(); } }); @@ -350,7 +349,7 @@ class ActiveMiner implements Runnable { stop("machines.INDUSTRIAL_MINER.destroyed"); } } catch (Exception e) { - Slimefun.getLogger().log(Level.SEVERE, e, () -> "An Error occurred while moving a Piston for an Industrial Miner at " + new BlockPosition(block)); + SlimefunPlugin.logger().log(Level.SEVERE, e, () -> "An Error occurred while moving a Piston for an Industrial Miner at " + new BlockPosition(block)); stop(); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java index 4b401f1bc..b14d02d8e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java @@ -67,12 +67,13 @@ public class BlockListener implements Listener { SlimefunItem sfItem = BlockStorage.check(block); if (sfItem != null) { - /* Temp fix for #2636 - for (ItemStack item : sfItem.getDrops()) { - if (item != null && !item.getType().isAir()) { - block.getWorld().dropItemNaturally(block.getLocation(), item); - } - } + /* + * Temp fix for #2636 + * for (ItemStack item : sfItem.getDrops()) { + * if (item != null && !item.getType().isAir()) { + * block.getWorld().dropItemNaturally(block.getLocation(), item); + * } + * } */ BlockStorage.clearBlockInfo(block); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java index 9475d4b86..bc0548cdb 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java @@ -29,7 +29,6 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This {@link Listener} is responsible for handling our debugging tool, the debug fish. @@ -99,7 +98,7 @@ public class DebugFishListener implements Listener { try { sendInfo(p, b); } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, "An Exception occurred while using a Debug-Fish", x); + SlimefunPlugin.logger().log(Level.SEVERE, "An Exception occurred while using a Debug-Fish", x); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java index 5575ce2aa..97a64076f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java @@ -12,10 +12,10 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; -import io.github.thebusybiscuit.slimefun4.api.events.SlimefunGuideOpenEvent; import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; +import io.github.thebusybiscuit.slimefun4.api.events.SlimefunGuideOpenEvent; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; @@ -38,7 +38,7 @@ public class SlimefunGuideListener implements Listener { return; } - SlimefunGuideLayout type = SlimefunGuide.getDefaultLayout(); + SlimefunGuideMode type = SlimefunGuide.getDefaultMode(); p.getInventory().addItem(SlimefunGuide.getItem(type).clone()); } } @@ -47,31 +47,27 @@ public class SlimefunGuideListener implements Listener { public void onInteract(PlayerRightClickEvent e) { Player p = e.getPlayer(); - if (tryOpenGuide(p, e, SlimefunGuideLayout.BOOK) == Result.ALLOW) { + if (tryOpenGuide(p, e, SlimefunGuideMode.SURVIVAL_MODE) == Result.ALLOW) { if (p.isSneaking()) { SlimefunGuideSettings.openSettings(p, e.getItem()); } else { - openGuide(p, e, SlimefunGuideLayout.BOOK); + openGuide(p, e, SlimefunGuideMode.SURVIVAL_MODE); } - } else if (tryOpenGuide(p, e, SlimefunGuideLayout.CHEST) == Result.ALLOW) { + } else if (tryOpenGuide(p, e, SlimefunGuideMode.CHEAT_MODE) == Result.ALLOW) { if (p.isSneaking()) { SlimefunGuideSettings.openSettings(p, e.getItem()); } else { - openGuide(p, e, SlimefunGuideLayout.CHEST); - } - } else if (tryOpenGuide(p, e, SlimefunGuideLayout.CHEAT_SHEET) == Result.ALLOW) { - if (p.isSneaking()) { - SlimefunGuideSettings.openSettings(p, e.getItem()); - } else { - // We rather just run the command here, - // all necessary permission checks will be handled there. + /* + * We rather just run the command here, all + * necessary permission checks will be handled there. + */ p.chat("/sf cheat"); } } } @ParametersAreNonnullByDefault - private void openGuide(Player p, PlayerRightClickEvent e, SlimefunGuideLayout layout) { + private void openGuide(Player p, PlayerRightClickEvent e, SlimefunGuideMode layout) { SlimefunGuideOpenEvent event = new SlimefunGuideOpenEvent(p, e.getItem(), layout); Bukkit.getPluginManager().callEvent(event); @@ -83,7 +79,7 @@ public class SlimefunGuideListener implements Listener { @Nonnull @ParametersAreNonnullByDefault - private Result tryOpenGuide(Player p, PlayerRightClickEvent e, SlimefunGuideLayout layout) { + private Result tryOpenGuide(Player p, PlayerRightClickEvent e, SlimefunGuideMode layout) { ItemStack item = e.getItem(); if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true, false)) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TeleporterListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TeleporterListener.java index 158d38092..b10f1cdbe 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TeleporterListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TeleporterListener.java @@ -15,7 +15,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.items.gps.ElevatorPlate; +import io.github.thebusybiscuit.slimefun4.implementation.items.elevator.ElevatorPlate; import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java index 315bc295d..eb35c10ff 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/WorldListener.java @@ -11,7 +11,6 @@ import org.bukkit.event.world.WorldUnloadEvent; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; public class WorldListener implements Listener { @@ -32,7 +31,7 @@ public class WorldListener implements Listener { if (storage != null) { storage.saveAndRemove(); } else { - Slimefun.getLogger().log(Level.SEVERE, "Could not save Slimefun Blocks for World \"{0}\"", e.getWorld().getName()); + SlimefunPlugin.logger().log(Level.SEVERE, "Could not save Slimefun Blocks for World \"{0}\"", e.getWorld().getName()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java index 996142f26..f0d7ecdb2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java @@ -35,14 +35,13 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smelt import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; -import me.mrCookieSlime.Slimefun.api.Slimefun; public final class PostSetup { private PostSetup() {} public static void setupWiki() { - Slimefun.getLogger().log(Level.INFO, "Loading Wiki pages..."); + SlimefunPlugin.logger().log(Level.INFO, "Loading Wiki pages..."); JsonParser parser = new JsonParser(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream("/wiki.json"), StandardCharsets.UTF_8))) { @@ -57,7 +56,7 @@ public final class PostSetup { } } } catch (IOException e) { - Slimefun.getLogger().log(Level.SEVERE, "Failed to load wiki.json file", e); + SlimefunPlugin.logger().log(Level.SEVERE, "Failed to load wiki.json file", e); } } @@ -68,7 +67,7 @@ public final class PostSetup { SlimefunItem item = iterator.next(); if (item == null) { - Slimefun.getLogger().log(Level.WARNING, "Removed bugged Item ('NULL?')"); + SlimefunPlugin.logger().log(Level.WARNING, "Removed bugged Item ('NULL?')"); iterator.remove(); } else { try { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java index 10ab60b09..d285c9758 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java @@ -25,7 +25,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem; import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; -import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AdvancedFarmerAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInterface; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ButcherAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.FarmerAndroid; @@ -110,6 +109,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.XPCollector; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.NetherStarReactor; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.NuclearReactor; +import io.github.thebusybiscuit.slimefun4.implementation.items.elevator.ElevatorPlate; import io.github.thebusybiscuit.slimefun4.implementation.items.food.BirthdayCake; import io.github.thebusybiscuit.slimefun4.implementation.items.food.DietCookie; import io.github.thebusybiscuit.slimefun4.implementation.items.food.FortuneCookie; @@ -122,7 +122,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.OilPump; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.PortableGEOScanner; -import io.github.thebusybiscuit.slimefun4.implementation.items.gps.ElevatorPlate; import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSControlPanel; import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSMarkerTool; import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSTransmitter; @@ -1895,7 +1894,7 @@ public final class SlimefunItemSetup { new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.DIAMOND_SWORD), null, SlimefunItems.ELECTRIC_MOTOR, null}) .register(plugin); - new AdvancedFarmerAndroid(categories.androids, 2, SlimefunItems.PROGRAMMABLE_ANDROID_2_FARMER, RecipeType.ENHANCED_CRAFTING_TABLE, + new FarmerAndroid(categories.androids, 2, SlimefunItems.PROGRAMMABLE_ANDROID_2_FARMER, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] {null, SlimefunItems.GPS_TRANSMITTER, null, new ItemStack(Material.DIAMOND_HOE), SlimefunItems.PROGRAMMABLE_ANDROID_2, new ItemStack(Material.DIAMOND_HOE), null, SlimefunItems.ELECTRIC_MOTOR, null}) .register(plugin); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java index 9434cbeeb..e9244d387 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java @@ -10,8 +10,8 @@ import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; public class JetBootsTask extends AbstractPlayerTask { @@ -30,7 +30,7 @@ public class JetBootsTask extends AbstractPlayerTask { return; } - double accuracy = DoubleHandler.fixDouble(boots.getSpeed() - 0.7); + double accuracy = NumberUtils.reparseDouble(boots.getSpeed() - 0.7); if (boots.removeItemCharge(p.getInventory().getBoots(), COST)) { p.getWorld().playSound(p.getLocation(), Sound.ENTITY_TNT_PRIMED, (float) 0.25, 1); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java index 066a50b45..d66081420 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java @@ -12,7 +12,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.TeleporterLis import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This Task initializes all items, some listeners and various other stuff. @@ -54,7 +53,7 @@ public class SlimefunStartupTask implements Runnable { try { new BlockStorage(world); } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while trying to load World \"" + world.getName() + "\" for Slimefun v" + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while trying to load World \"" + world.getName() + "\" for Slimefun v" + SlimefunPlugin.getVersion()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java index 11fe81551..5b86f5e55 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java @@ -27,7 +27,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link TickerTask} is responsible for ticking every {@link BlockTicker}, @@ -132,7 +131,7 @@ public class TickerTask implements Runnable { reset(); SlimefunPlugin.getProfiler().stop(); } catch (Exception | LinkageError x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion()); reset(); } } @@ -147,7 +146,7 @@ public class TickerTask implements Runnable { } } } catch (ArrayIndexOutOfBoundsException | NumberFormatException x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occurred while trying to resolve Chunk: " + chunk); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Exception has occurred while trying to resolve Chunk: " + chunk); } } @@ -204,10 +203,10 @@ public class TickerTask implements Runnable { new ErrorReport<>(x, l, item); bugs.put(position, errors); } else if (errors == 4) { - Slimefun.getLogger().log(Level.SEVERE, "X: {0} Y: {1} Z: {2} ({3})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), item.getId() }); - Slimefun.getLogger().log(Level.SEVERE, "has thrown 4 error messages in the last 4 Ticks, the Block has been terminated."); - Slimefun.getLogger().log(Level.SEVERE, "Check your /plugins/Slimefun/error-reports/ folder for details."); - Slimefun.getLogger().log(Level.SEVERE, " "); + SlimefunPlugin.logger().log(Level.SEVERE, "X: {0} Y: {1} Z: {2} ({3})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), item.getId() }); + SlimefunPlugin.logger().log(Level.SEVERE, "has thrown 4 error messages in the last 4 Ticks, the Block has been terminated."); + SlimefunPlugin.logger().log(Level.SEVERE, "Check your /plugins/Slimefun/error-reports/ folder for details."); + SlimefunPlugin.logger().log(Level.SEVERE, " "); bugs.remove(position); BlockStorage.deleteLocationInfoUnsafely(l, true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java index f280b55ca..92ef1ec56 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java @@ -14,9 +14,9 @@ import org.bukkit.plugin.Plugin; import com.gmail.nossr50.events.fake.FakeBlockBreakEvent; import dev.lone.itemsadder.api.ItemsAdder; +import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This Service holds all interactions and hooks with third-party {@link Plugin Plugins} @@ -36,6 +36,11 @@ public class IntegrationsManager { */ protected final SlimefunPlugin plugin; + /** + * Our {@link ProtectionManager} instance. + */ + private ProtectionManager protectionManager; + /** * This boolean determines whether {@link #start()} was run. */ @@ -50,7 +55,6 @@ public class IntegrationsManager { // Addon support private boolean isChestTerminalInstalled = false; - private boolean isExoticGardenInstalled = false; /** * This initializes the {@link IntegrationsManager} @@ -127,13 +131,27 @@ public class IntegrationsManager { * This method is called when the {@link Server} has finished loading all its {@link Plugin Plugins}. */ private void onServerStart() { + try { + // Load Protection plugin integrations + protectionManager = new ProtectionManager(plugin.getServer()); + } catch (Exception | LinkageError x) { + SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Failed to load Protection plugin integrations for Slimefun v" + SlimefunPlugin.getVersion()); + } + isChestTerminalInstalled = isAddonInstalled("ChestTerminal"); - isExoticGardenInstalled = isAddonInstalled("ExoticGarden"); } + /** + * This method checks if the given addon is installed. + * + * @param addon + * The name of the addon + * + * @return Whether that addon is installed on the {@link Server} + */ private boolean isAddonInstalled(@Nonnull String addon) { if (plugin.getServer().getPluginManager().isPluginEnabled(addon)) { - Slimefun.getLogger().log(Level.INFO, "Hooked into Slimefun Addon: {0}", addon); + SlimefunPlugin.logger().log(Level.INFO, "Hooked into Slimefun Addon: {0}", addon); return true; } else { return false; @@ -154,18 +172,29 @@ public class IntegrationsManager { if (integration != null && integration.isEnabled()) { String version = integration.getDescription().getVersion(); - Slimefun.getLogger().log(Level.INFO, "Hooked into Plugin: {0} v{1}", new Object[] { pluginName, version }); + SlimefunPlugin.logger().log(Level.INFO, "Hooked into Plugin: {0} v{1}", new Object[] { pluginName, version }); try { // Run our callback consumer.accept(integration); } catch (Exception | LinkageError x) { - Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating {0} or Slimefun?", pluginName); - Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to hook into " + pluginName + " v" + version); + SlimefunPlugin.logger().log(Level.WARNING, "Maybe consider updating {0} or Slimefun?", pluginName); + SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Failed to hook into " + pluginName + " v" + version); } } } + /** + * This returns out instance of the {@link ProtectionManager}. + * This bridge is used to hook into any third-party protection {@link Plugin}. + * + * @return Our instanceof of the {@link ProtectionManager} + */ + @Nonnull + public ProtectionManager getProtectionManager() { + return protectionManager; + } + /** * This checks if one of our third party integrations faked an {@link Event}. * Faked {@link Event Events} should be ignored in our logic. @@ -218,8 +247,4 @@ public class IntegrationsManager { return isChestTerminalInstalled; } - public boolean isExoticGardenInstalled() { - return isExoticGardenInstalled; - } - } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java index ce1b5b7c7..4c041af0f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java @@ -114,8 +114,6 @@ public enum HeadTexture { PIGLIN_HEAD("2882af1294a74023e6919a31d1a027310f2e142afb4667d230d155e7f21dbb41"), NECROTIC_SKULL("7953b6c68448e7e6b6bf8fb273d7203acd8e1be19e81481ead51f45de59a8"); - public static final HeadTexture[] valuesCache = values(); - private final String texture; private final UUID uuid; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java index e4e23bfc2..b16a05922 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java @@ -223,10 +223,15 @@ public final class NumberUtils { } } + @Nonnull public static String roundDecimalNumber(double number) { return DECIMAL_FORMAT.format(number); } + public static double reparseDouble(double number) { + return Double.valueOf(roundDecimalNumber(number)); + } + public static long getLong(@Nullable Long value, long defaultValue) { return value == null ? defaultValue : value; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java index 2369a6898..8b6eff1ac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -47,8 +47,6 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public final class SlimefunUtils { private static final String NO_PICKUP_METADATA = "no_pickup"; - - private static final NamespacedKey SOULBOUND_KEY = new NamespacedKey(SlimefunPlugin.instance(), "soulbound"); private static final String SOULBOUND_LORE = ChatColor.GRAY + "Soulbound"; private SlimefunUtils() {} @@ -110,8 +108,9 @@ public final class SlimefunUtils { private static boolean hasSoulboundFlag(@Nullable ItemMeta meta) { if (meta != null) { PersistentDataContainer container = meta.getPersistentDataContainer(); + NamespacedKey key = SlimefunPlugin.getRegistry().getSoulboundDataKey(); - if (container.has(SOULBOUND_KEY, PersistentDataType.BYTE)) { + if (container.has(key, PersistentDataType.BYTE)) { return true; } } @@ -142,13 +141,14 @@ public final class SlimefunUtils { ItemMeta meta = item.getItemMeta(); PersistentDataContainer container = meta.getPersistentDataContainer(); + NamespacedKey key = SlimefunPlugin.getRegistry().getSoulboundDataKey(); if (makeSoulbound && !isSoulbound) { - container.set(SOULBOUND_KEY, PersistentDataType.BYTE, (byte) 1); + container.set(key, PersistentDataType.BYTE, (byte) 1); } if (!makeSoulbound && isSoulbound) { - container.remove(SOULBOUND_KEY); + container.remove(key); } List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/SlimefunGuideItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/SlimefunGuideItem.java index 2cb93cf15..ded9609c3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/SlimefunGuideItem.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/SlimefunGuideItem.java @@ -1,6 +1,6 @@ package io.github.thebusybiscuit.slimefun4.utils.itemstack; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; @@ -10,10 +10,11 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; +import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; /** * This is just a helper {@link ItemStack} class for the {@link SlimefunGuide} {@link ItemStack}. @@ -32,12 +33,15 @@ public class SlimefunGuideItem extends ItemStack { ItemMeta meta = getItemMeta(); meta.setDisplayName(ChatColors.color(name)); - List lore = new LinkedList<>(); - lore.add(implementation instanceof CheatSheetSlimefunGuide ? ChatColors.color("&4&lOnly openable by Admins") : ""); + List lore = new ArrayList<>(); + SlimefunGuideMode type = implementation.getMode(); + lore.add(type == SlimefunGuideMode.CHEAT_MODE ? ChatColors.color("&4&lOnly openable by Admins") : ""); lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items")); lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits")); meta.setLore(lore); + + PersistentDataAPI.setString(meta, SlimefunPlugin.getRegistry().getGuideDataKey(), type.name()); SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE"); setItemMeta(meta); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/tags/SlimefunTag.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/tags/SlimefunTag.java index 1a7869875..855485681 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/tags/SlimefunTag.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/tags/SlimefunTag.java @@ -62,7 +62,7 @@ public enum SlimefunTag implements Tag { * All command block variants */ COMMAND_BLOCKS, - + /** * All variants of Spawn Eggs */ diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java index 8c788e94f..cf95721f3 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java @@ -7,6 +7,7 @@ import java.util.Comparator; import java.util.List; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import org.apache.commons.lang.Validate; @@ -19,6 +20,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory; import io.github.thebusybiscuit.slimefun4.core.categories.SeasonalCategory; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; @@ -37,6 +39,8 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; */ public class Category implements Keyed { + private SlimefunAddon addon; + protected final List items = new ArrayList<>(); protected final NamespacedKey key; protected final ItemStack item; @@ -94,12 +98,29 @@ public class Category implements Keyed { * Registers this category. *

* By default, a category is automatically registered when a {@link SlimefunItem} was added to it. + * + * @param addon + * The {@link SlimefunAddon} that wants to register this {@link Category} */ - public void register() { + public void register(@Nonnull SlimefunAddon addon) { + Validate.notNull(addon, "The Addon cannot be null"); + this.addon = addon; + SlimefunPlugin.getRegistry().getCategories().add(this); Collections.sort(SlimefunPlugin.getRegistry().getCategories(), Comparator.comparingInt(Category::getTier)); } + /** + * This returns the {@link SlimefunAddon} which has registered this {@link Category}. + * Or null if it has not been registered yet. + * + * @return The {@link SlimefunAddon} or null if unregistered + */ + @Nullable + public final SlimefunAddon getAddon() { + return addon; + } + /** * Adds the given {@link SlimefunItem} to this {@link Category}. * @@ -247,7 +268,7 @@ public class Category implements Keyed { /** * This method returns whether this {@link Category} has been registered yet. - * More specifically: Whether {@link #register()} was called or not. + * More specifically: Whether {@link #register(SlimefunAddon)} was called or not. * * @return Whether this {@link Category} has been registered */ diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java index 666f8dae4..6c82dd51a 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -12,6 +12,7 @@ import java.util.logging.Logger; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import org.apache.commons.lang.Validate; import org.bukkit.Material; @@ -130,6 +131,7 @@ public class SlimefunItem implements Placeable { * @param recipe * An Array representing the recipe of this {@link SlimefunItem} */ + @ParametersAreNonnullByDefault public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { this(category, item, recipeType, recipe, null); } @@ -148,6 +150,7 @@ public class SlimefunItem implements Placeable { * @param recipeOutput * The result of crafting this item */ + @ParametersAreNonnullByDefault public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { Validate.notNull(category, "'category' is not allowed to be null!"); Validate.notNull(item, "'item' is not allowed to be null!"); @@ -162,6 +165,7 @@ public class SlimefunItem implements Placeable { } // Previously deprecated constructor, now only for internal purposes + @ParametersAreNonnullByDefault protected SlimefunItem(Category category, ItemStack item, String id, RecipeType recipeType, ItemStack[] recipe) { Validate.notNull(category, "'category' is not allowed to be null!"); Validate.notNull(item, "'item' is not allowed to be null!"); @@ -371,7 +375,7 @@ public class SlimefunItem implements Placeable { * @return The {@link SlimefunAddon} that registered this {@link SlimefunItem} */ @Nonnull - public SlimefunAddon getAddon() { + public final SlimefunAddon getAddon() { if (addon == null) { throw new UnregisteredItemException(this); } @@ -476,12 +480,22 @@ public class SlimefunItem implements Placeable { private final void onEnable() { // Register the Category too if it hasn't been registered yet if (!category.isRegistered()) { - category.register(); + category.register(addon); } // Send out deprecation warnings for any classes or interfaces checkForDeprecations(getClass()); + // Check for an illegal stack size + if (itemStackTemplate.getAmount() != 1) { + // @formatter:off + warn("This item has an illegal stack size: " + itemStackTemplate.getAmount() + + "An Item size of 1 is recommended. Please inform the autho of " + addon.getName() + + " to fix this. Crafting Results with amounts of higher should be handled" + + " via the recipeOutput parameter!"); + // @formatter:on + } + // Add it to the list of enabled items SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(this); @@ -501,13 +515,17 @@ public class SlimefunItem implements Placeable { if (exception.isPresent()) { throw exception.get(); } else { - // Make developers or at least Server admins aware that - // an Item is using a deprecated ItemHandler + /* + * Make developers or at least Server admins aware that an Item + * is using a deprecated ItemHandler + */ checkForDeprecations(handler.getClass()); } - // If this ItemHandler is "public" (not bound to this SlimefunItem), - // we add it to the list of public Item handlers + /* + * If this ItemHandler is "public" (not bound to this SlimefunItem), + * we add it to the list of public Item handlers + */ if (!handler.isPrivate()) { Set handlerset = getPublicItemHandlers(handler.getIdentifier()); handlerset.add(handler); @@ -563,15 +581,19 @@ public class SlimefunItem implements Placeable { */ private void checkForDeprecations(@Nullable Class c) { if (SlimefunPlugin.getUpdater().getBranch() == SlimefunBranch.DEVELOPMENT) { - // This method is currently way too spammy with all the restructuring going on... - // Since DEV builds are anyway under "development", things may be relocated. - // So we fire these only for stable versions, since devs should update then, so - // it's the perfect moment to tell them to act. + /* + * This method is currently way too spammy with all the restructuring going on... + * Since DEV builds are anyway under "development", things may be relocated. + * So we fire these only for stable versions, since devs should update then, so + * it's the perfect moment to tell them to act. + */ return; } - // We do not wanna throw an Exception here since this could also mean that - // we have reached the end of the Class hierarchy + /* + * We do not wanna throw an Exception here since this could also mean that. + * We have reached the end of the Class hierarchy + */ if (c != null) { // Check if this Class is deprecated if (c.isAnnotationPresent(Deprecated.class)) { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java index ef0817484..07a3a1a70 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java @@ -32,8 +32,8 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.stream.JsonWriter; -import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; @@ -97,7 +97,7 @@ public class BlockStorage { return new Location(w, Integer.parseInt(components[1]), Integer.parseInt(components[2]), Integer.parseInt(components[3])); } } catch (NumberFormatException x) { - Slimefun.getLogger().log(Level.WARNING, "Could not parse Number", x); + SlimefunPlugin.logger().log(Level.WARNING, "Could not parse Number", x); } return null; } @@ -114,8 +114,8 @@ public class BlockStorage { return; } - Slimefun.getLogger().log(Level.INFO, "Loading Blocks for World \"{0}\"", w.getName()); - Slimefun.getLogger().log(Level.INFO, "This may take a long time..."); + SlimefunPlugin.logger().log(Level.INFO, "Loading Blocks for World \"{0}\"", w.getName()); + SlimefunPlugin.logger().log(Level.INFO, "This may take a long time..."); File dir = new File(PATH_BLOCKS + w.getName()); @@ -142,13 +142,13 @@ public class BlockStorage { try { for (File file : directory.listFiles()) { if (file.getName().equals("null.sfb")) { - Slimefun.getLogger().log(Level.WARNING, "File with corrupted blocks detected!"); - Slimefun.getLogger().log(Level.WARNING, "Slimefun will simply skip this File, you should look inside though!"); - Slimefun.getLogger().log(Level.WARNING, file.getPath()); + SlimefunPlugin.logger().log(Level.WARNING, "File with corrupted blocks detected!"); + SlimefunPlugin.logger().log(Level.WARNING, "Slimefun will simply skip this File, you should look inside though!"); + SlimefunPlugin.logger().log(Level.WARNING, file.getPath()); } else if (file.getName().endsWith(".sfb")) { if (timestamp + delay < System.currentTimeMillis()) { int progress = Math.round((((done * 100.0F) / total) * 100.0F) / 100.0F); - Slimefun.getLogger().log(Level.INFO, "Loading Blocks... {0}% done (\"{1}\")", new Object[] { progress, world.getName() }); + SlimefunPlugin.logger().log(Level.INFO, "Loading Blocks... {0}% done (\"{1}\")", new Object[] { progress, world.getName() }); timestamp = System.currentTimeMillis(); } @@ -164,11 +164,11 @@ public class BlockStorage { } } finally { long time = (System.currentTimeMillis() - start); - Slimefun.getLogger().log(Level.INFO, "Loading Blocks... 100% (FINISHED - {0}ms)", time); - Slimefun.getLogger().log(Level.INFO, "Loaded a total of {0} Blocks for World \"{1}\"", new Object[] { totalBlocks, world.getName() }); + SlimefunPlugin.logger().log(Level.INFO, "Loading Blocks... 100% (FINISHED - {0}ms)", time); + SlimefunPlugin.logger().log(Level.INFO, "Loaded a total of {0} Blocks for World \"{1}\"", new Object[] { totalBlocks, world.getName() }); if (totalBlocks > 0) { - Slimefun.getLogger().log(Level.INFO, "Avg: {0}ms/Block", DoubleHandler.fixDouble((double) time / (double) totalBlocks, 3)); + SlimefunPlugin.logger().log(Level.INFO, "Avg: {0}ms/Block", NumberUtils.roundDecimalNumber((double) time / (double) totalBlocks)); } } } @@ -193,7 +193,7 @@ public class BlockStorage { * error to the console (if enabled). */ if (SlimefunPlugin.getRegistry().logDuplicateBlockEntries()) { - Slimefun.getLogger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2} ({3} -> {4})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id") }); + SlimefunPlugin.logger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2} ({3} -> {4})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id") }); } return; @@ -206,7 +206,7 @@ public class BlockStorage { } } } catch (Exception x) { - Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion()); } } @@ -223,7 +223,7 @@ public class BlockStorage { SlimefunPlugin.getRegistry().getChunks().put(key, data); } } catch (Exception x) { - Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + chunks.getName() + " in World " + world.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Failed to load " + chunks.getName() + " in World " + world.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion()); } } } @@ -245,7 +245,7 @@ public class BlockStorage { inventories.put(l, new BlockMenu(preset, l, cfg)); } } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while loading this Block Inventory: " + file.getName()); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while loading this Block Inventory: " + file.getName()); } } } @@ -260,7 +260,7 @@ public class BlockStorage { SlimefunPlugin.getRegistry().getUniversalInventories().put(preset.getID(), new UniversalBlockMenu(preset, cfg)); } } catch (Exception x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while loading this universal Inventory: " + file.getName()); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while loading this universal Inventory: " + file.getName()); } } } @@ -291,7 +291,7 @@ public class BlockStorage { return; } - Slimefun.getLogger().log(Level.INFO, "Saving block data for world \"{0}\" ({1} change(s) queued)", new Object[] { world.getName(), changes }); + SlimefunPlugin.logger().log(Level.INFO, "Saving block data for world \"{0}\" ({1} change(s) queued)", new Object[] { world.getName(), changes }); Map cache = new HashMap<>(blocksCache); for (Map.Entry entry : cache.entrySet()) { @@ -305,7 +305,7 @@ public class BlockStorage { try { Files.delete(file.toPath()); } catch (IOException e) { - Slimefun.getLogger().log(Level.WARNING, e, () -> "Could not delete file \"" + file.getName() + '"'); + SlimefunPlugin.logger().log(Level.WARNING, e, () -> "Could not delete file \"" + file.getName() + '"'); } } } else { @@ -315,7 +315,7 @@ public class BlockStorage { try { Files.move(tmpFile.toPath(), cfg.getFile().toPath(), StandardCopyOption.ATOMIC_MOVE); } catch (IOException x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while copying a temporary File for Slimefun " + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Error occurred while copying a temporary File for Slimefun " + SlimefunPlugin.getVersion()); } } } @@ -431,7 +431,7 @@ public class BlockStorage { try { return new BlockInfoConfig(parseJSON(json)); } catch (Exception x) { - Logger logger = Slimefun.getLogger(); + Logger logger = SlimefunPlugin.logger(); logger.log(Level.WARNING, x.getClass().getName()); logger.log(Level.WARNING, "Failed to parse BlockInfo for Block @ {0}, {1}, {2}", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ() }); logger.log(Level.WARNING, json); @@ -457,7 +457,7 @@ public class BlockStorage { writer.endObject(); return string.toString(); } catch (IOException x) { - Slimefun.getLogger().log(Level.SEVERE, "An error occurred while serializing BlockInfo", x); + SlimefunPlugin.logger().log(Level.SEVERE, "An error occurred while serializing BlockInfo", x); return null; } } @@ -508,7 +508,7 @@ public class BlockStorage { BlockStorage storage = getStorage(l.getWorld()); if (storage == null) { - Slimefun.getLogger().warning("Could not set Block info for non-registered World '" + l.getWorld().getName() + "'. Is some plugin trying to store data in a fake world?"); + SlimefunPlugin.logger().warning("Could not set Block info for non-registered World '" + l.getWorld().getName() + "'. Is some plugin trying to store data in a fake world?"); return; } @@ -817,7 +817,7 @@ public class BlockStorage { return cfg; } catch (Exception e) { - Slimefun.getLogger().log(Level.SEVERE, e, () -> "Failed to parse ChunkInfo for Slimefun " + SlimefunPlugin.getVersion()); + SlimefunPlugin.logger().log(Level.SEVERE, e, () -> "Failed to parse ChunkInfo for Slimefun " + SlimefunPlugin.getVersion()); return emptyBlockData; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java b/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java index 2507d50bb..6b843802c 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java @@ -1,9 +1,6 @@ package me.mrCookieSlime.Slimefun.api; import java.util.Optional; -import java.util.logging.Logger; - -import javax.annotation.Nonnull; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -25,11 +22,6 @@ public final class Slimefun { private Slimefun() {} - @Nonnull - public static Logger getLogger() { - return SlimefunPlugin.instance().getLogger(); - } - /** * Checks if this player can use this item. * diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java index fd11bc506..b561400d7 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java @@ -10,8 +10,9 @@ import org.bukkit.block.Block; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.config.Config; -import me.mrCookieSlime.Slimefun.api.Slimefun; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +// This class will be deprecated, relocated and rewritten in a future version. public class BlockMenu extends DirtyChestMenu { private Location location; @@ -117,7 +118,7 @@ public class BlockMenu extends DirtyChestMenu { try { Files.delete(file.toPath()); } catch (IOException e) { - Slimefun.getLogger().log(Level.WARNING, e, () -> "Could not delete file \"" + file.getName() + '"'); + SlimefunPlugin.logger().log(Level.WARNING, e, () -> "Could not delete file \"" + file.getName() + '"'); } } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java index 3239d8f19..f2b451f18 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java @@ -20,6 +20,7 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; +// This class will be deprecated, relocated and rewritten in a future version. public abstract class BlockMenuPreset extends ChestMenu { private final Set occupiedSlots = new HashSet<>(); @@ -32,8 +33,6 @@ public abstract class BlockMenuPreset extends ChestMenu { private final boolean universal; private boolean locked; - private ItemManipulationEvent event; - public BlockMenuPreset(@Nonnull String id, @Nonnull String title) { this(id, title, false); } @@ -75,19 +74,6 @@ public abstract class BlockMenuPreset extends ChestMenu { public abstract int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow); - /** - * This method is deprecated. - * - * @deprecated Override {@link #onItemStackChange(DirtyChestMenu, int, ItemStack, ItemStack)} instead - * - * @param event - * The event - */ - @Deprecated - public void registerEvent(ItemManipulationEvent event) { - this.event = event; - } - /** * This method is called whenever an {@link ItemStack} changes. * You can override this as necessary if you need to listen to these events @@ -259,7 +245,6 @@ public abstract class BlockMenuPreset extends ChestMenu { menu.addMenuOpeningHandler(getMenuOpeningHandler()); menu.addMenuCloseHandler(getMenuCloseHandler()); - menu.registerEvent(event); } public void newInstance(@Nonnull BlockMenu menu, @Nonnull Location l) { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java index e6d31b065..5155fe76d 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java @@ -18,10 +18,10 @@ import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; +// This class will be deprecated, relocated and rewritten in a future version. public class DirtyChestMenu extends ChestMenu { protected final BlockMenuPreset preset; - protected ItemManipulationEvent event; protected int changes = 1; public DirtyChestMenu(@Nonnull BlockMenuPreset preset) { @@ -61,35 +61,20 @@ public class DirtyChestMenu extends ChestMenu { return preset.canOpen(b, p); } + @Override + public void open(Player... players) { + super.open(players); + + // The Inventory will likely be modified soon + markDirty(); + } + public void close() { for (HumanEntity human : new ArrayList<>(toInventory().getViewers())) { human.closeInventory(); } } - /** - * This method has been deprecated. - * - * @deprecated The {@link ItemManipulationEvent} has been deprecated. - * - * @param event - * deprecated class - */ - @Deprecated - public void registerEvent(ItemManipulationEvent event) { - this.event = event; - } - - @Override - public ChestMenu addMenuOpeningHandler(MenuOpeningHandler handler) { - if (handler instanceof MenuSavingHandler) { - MenuOpeningHandler openingHandler = ((MenuSavingHandler) handler).getOpeningHandler(); - return super.addMenuOpeningHandler(new MenuSavingHandler(this, openingHandler)); - } else { - return super.addMenuOpeningHandler(new MenuSavingHandler(this, handler)); - } - } - public boolean fits(@Nonnull ItemStack item, int... slots) { for (int slot : slots) { // A small optimization for empty slots @@ -161,11 +146,6 @@ public class DirtyChestMenu extends ChestMenu { public void replaceExistingItem(int slot, ItemStack item, boolean event) { if (event) { ItemStack previous = getItemInSlot(slot); - - if (this.event != null) { - item = this.event.onEvent(slot, previous, item); - } - item = preset.onItemStackChange(this, slot, previous, item); } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java deleted file mode 100644 index ce6591b0a..000000000 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.mrCookieSlime.Slimefun.api.inventory; - -import org.bukkit.inventory.ItemStack; - -/** - * @deprecated Please use {@link BlockMenuPreset#onItemStackChange(DirtyChestMenu, int, ItemStack, ItemStack)} instead. - * - * @author TheBusyBiscuit - * - */ -@Deprecated -@FunctionalInterface -public interface ItemManipulationEvent { - - ItemStack onEvent(int slot, ItemStack previous, ItemStack next); - -} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/MenuSavingHandler.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/MenuSavingHandler.java deleted file mode 100644 index 74d556f0f..000000000 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/MenuSavingHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package me.mrCookieSlime.Slimefun.api.inventory; - -import javax.annotation.ParametersAreNonnullByDefault; - -import org.bukkit.entity.Player; - -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.MenuOpeningHandler; - -public class MenuSavingHandler implements MenuOpeningHandler { - - private final DirtyChestMenu menu; - private final MenuOpeningHandler handler; - - @ParametersAreNonnullByDefault - public MenuSavingHandler(DirtyChestMenu menu, MenuOpeningHandler handler) { - this.menu = menu; - this.handler = handler; - } - - @Override - public void onOpen(Player p) { - handler.onOpen(p); - menu.markDirty(); - } - - public MenuOpeningHandler getOpeningHandler() { - return handler; - } - -} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalBlockMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalBlockMenu.java index e4af0ebb3..66a3d9d76 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalBlockMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalBlockMenu.java @@ -4,6 +4,7 @@ import java.io.File; import io.github.thebusybiscuit.cscorelib2.config.Config; +// This class will be deprecated, relocated and rewritten in a future version. public class UniversalBlockMenu extends DirtyChestMenu { public UniversalBlockMenu(BlockMenuPreset preset) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9413104e2..84aff21b3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -20,7 +20,6 @@ options: drop-excess-sf-give-items: false guide: - default-view-book: false show-vanilla-recipes: true receive-on-first-join: true diff --git a/src/main/resources/languages/categories_bg.yml b/src/main/resources/languages/categories_bg.yml index 49dc67d43..84ac6f1f7 100644 --- a/src/main/resources/languages/categories_bg.yml +++ b/src/main/resources/languages/categories_bg.yml @@ -2,25 +2,25 @@ slimefun: weapons: Оръжия tools: Инструменти - items: Полезни предмети + items: Полезни Предмети food: Храна - basic_machines: Основни машини + basic_machines: Основни Машини electricity: Енергия и Eлектричество gps: GPS Машини - armor: Броня + armor: Брони magical_items: Магически Предмети magical_gadgets: Магически Джаджи misc: Разни Предмети - technical_gadgets: Технически джаджи + technical_gadgets: Технически Джаджи resources: Ресурси cargo: Товарно Управление tech_misc: Технически Компоненти - magical_armor: Магическа Броня + magical_armor: Магически Брони talismans: Талисмани (Ниво I) ender_talismans: Ендър Талисмани (Ниво II) christmas: Коледа (Декември) valentines_day: Свети Валентин (14ти Февруари) - easter: Великден (април) + easter: Великден (Април) birthday: Рожденият Ден на TheBusyBiscuit (26ти Октомври) halloween: Хелоуин (31и Октомври) androids: Програмируеми Андроиди diff --git a/src/main/resources/languages/messages_de.yml b/src/main/resources/languages/messages_de.yml index 18dcd879f..369335a38 100644 --- a/src/main/resources/languages/messages_de.yml +++ b/src/main/resources/languages/messages_de.yml @@ -4,7 +4,6 @@ commands: cheat: Ermöglicht das Cheaten von Items give: Gibt jemandem ein bestimmtes Item guide: Gibt dir das Slimefun-Handbuch - timings: Zeigt einige Informationen über die Performance teleporter: Erlaubt es dir Wegpunkte anderer Spieler anzusehen versions: Eine Liste aller installierter Addons search: Durchsucht dein Slimefun-Handbuch nach einem Begriff @@ -25,6 +24,11 @@ commands: description: Lädt das Item in deiner Hand auf charge-success: Dein Item wurde erfolgreich aufgeladen! not-rechargeable: Dieses Item kann nicht aufgeladen werden! + timings: + description: Performance-Info für Slimefun und dessen Addons + please-wait: "&eEine Sekunde Geduld bitte... Die Ergebnisse werden aufbereitet!" + verbose-player: '&4Das "verbose" Argument kann nicht von Spielern verwendet werden.' + unknown-flag: "&4Unbekanntes Argument: &c%flag%" guide: search: message: "&bWonach möchtest du suchen?" diff --git a/src/main/resources/languages/messages_en.yml b/src/main/resources/languages/messages_en.yml index 14727df62..c8e76cf51 100644 --- a/src/main/resources/languages/messages_en.yml +++ b/src/main/resources/languages/messages_en.yml @@ -3,7 +3,6 @@ commands: cheat: Allows you to cheat Items give: Give somebody some Slimefun Items guide: Gives yourself a Slimefun Guide - timings: Lag-Info about your Server teleporter: See other Player's Waypoints versions: Lists all installed Addons search: Searches your Guide for the given term @@ -27,6 +26,12 @@ commands: charge-success: Item has been charged! not-rechargeable: This item can not be charged! + timings: + description: Timings for Slimefun and its addon + please-wait: '&ePlease wait a second... The results are coming in!' + verbose-player: '&4The verbose flag cannot be used by a Player!' + unknown-flag: '&4Unknown flag: &c%flag%' + guide: locked: 'LOCKED' work-in-progress: 'This feature is not fully finished yet!' diff --git a/src/main/resources/languages/messages_fr.yml b/src/main/resources/languages/messages_fr.yml index 45789bdf8..a3d15040a 100644 --- a/src/main/resources/languages/messages_fr.yml +++ b/src/main/resources/languages/messages_fr.yml @@ -110,12 +110,8 @@ messages: no-permission: "&4Vous n'avez pas les permissions requises pour faire ceci" usage: "&4Utilisation: &c%usage%" not-online: "&4%player% &cn'est pas en ligne!" - invalid-item: "&4%item% &cn'est pas un item valide!" - invalid-amount: "&4%amount% &cn'est pas un montant valide: il doit être supérieur - à 0!" given-item: '&bVous avez reçu &a%amount%&7 "%item%&7"' give-item: '&bVous avez donné &a%amount% &7"%item%&7" à %player%' - invalid-research: "&4%research% &cn'est pas une recherche valide!" give-research: '&bVous avez débloqué la recherche "%research%&7" à %player%' hungry: "&cVous avez trop faim pour faire ça!" disabled-in-world: "&4&lCet item a été désactivé dans ce monde" @@ -193,7 +189,13 @@ messages: utiliser !" wrong-material: "&cVous ne pouvez pas escalader cette surface. Consultez votre guide Slimefun pour plus d'informations !" + invalid-item: "&4%item% &cn'est pas un item valide!" + invalid-amount: "&4%amount% &cn'est pas un montant valide: il doit être supérieur + à 0!" + invalid-research: "&4%research% &cn'est pas une recherche valide!" mode-change: 'Vous avez changé votre &b%device% en mode : &9%mode%' + bee-suit-slow-fall: "&eVos ailes d'abeille vous aideront à revenir au sol lentement + et en toute sécurité" machines: pattern-not-found: "&eDésolé, je ne reconnais pas cette recette. Veuillez disposer les objets correctement dans le distributeur." @@ -341,7 +343,6 @@ languages: zh-CN: Chinois (Chine) el: Grec he: Hébreu - pt: Portugais (Portugal) ar: Arabe af: Afrikaans da: Danois @@ -353,6 +354,7 @@ languages: fa: Persan th: Thaï ro: Roumain + pt: Portugais (Portugal) pt-BR: Portugais (Brésil) bg: Bulgare ko: Coréen diff --git a/src/main/resources/languages/messages_hu.yml b/src/main/resources/languages/messages_hu.yml index 7f98f2f13..7a806b08e 100644 --- a/src/main/resources/languages/messages_hu.yml +++ b/src/main/resources/languages/messages_hu.yml @@ -4,7 +4,6 @@ commands: cheat: Ezzel lekérhetsz tárgyakat give: Slimefun tárgyak lekérése egy játékosnak guide: Slimefun Útmutató lekérése - timings: Lag-információ a szerverről teleporter: Játékosok útpontjainak megtekintése versions: A kiegészítők listázása search: Keresés egy kifejezésre az Útmutatóban @@ -24,6 +23,11 @@ commands: description: Feltölti a kezedben lévő tárgyat charge-success: Tárgy feltöltve! not-rechargeable: Ez a tárgy nem tölthető fel! + timings: + description: Teljesítményinformáció a Slimefunról és a kiegészítőiről + please-wait: "&eKérjük várj... Érkeznek az eredmények!" + verbose-player: "&4A részletes megjelenítés flag nem használható játékosként!" + unknown-flag: "&4Ismeretlen flag: &c%flag%" guide: search: message: "&bMire szeretnél keresni?" @@ -122,13 +126,13 @@ messages: water: "&a&oA talizmánod megmentett a fulladástól" angel: "&a&oA talizmánod megmentett a zuhanási sérüléstől" fire: "&a&oA talizmánod megmentett a halálra elégéstől" - magician: "&a&oA talizmánod adott további fejlesztéseket is" + magician: "&a&oA talizmánod adott további varázslatokat is" traveller: "&a&oA talizmánod gyors sebességet adott neked" warrior: "&a&oA talizmánodtól növelte az erőd egy kis időre" knight: "&a&oA talizmánod adott 5 másodpercre Regenerációt" whirlwind: "&a&oA talizmánod visszavert egy lövedéket" - wizard: "&a&oA talizmánod erősítette a Szerencse enchantot, de néhány egyéb enchantot - gyengített" + wizard: "&a&oA talizmánod erősítette a Szerencse varázslatot, de néhány egyéb + varázslatot gyengített" caveman: "&a&oA talizmánod adott Sietség effektet" soulbound-rune: fail: "&cEgyszerre csak egy tárgyat köthetsz a lelkedhez." @@ -151,24 +155,24 @@ messages: - "&7Segítség, csapdába estem egy szerencsesüti gyárban!" - "&7Holnap meghalsz... egy Creeper által" - "&7Valamikor az életedben valami rossz fog történni!!!" - - "&7A következő héten észreveszed, hogy ez nem az igazi világ, hanem egy számítógépes + - "&7A jövő héten észreveszed, hogy ez nem az igazi világ, hanem egy számítógépes játékban vagy" - "&7Ez a süti néhány másodperc múlva jó ízű lesz" - '&7Az utolsó szó, amelyet hallani fogsz: "KIÍRTANI!!!"' - "&7Bármit is teszel, ne ölelj meg egy Creepert... Kipróbáltam. Jó érzés, de nem éri meg." - "&742. A válasz 42." - - "&7Walshy egy nap távol tartja a bajokat." + - "&7Minden nap egy Walshy távol tartja a bajokat." - "&7Soha ne áss egyenesen!" - "&7Ez csak egy kis karcolás!" - "&7Mindig nézd az élet jó oldalát!" - "&7Ez valójában keksz volt, és nem süti" - "&7A neon táblák VILÁGÍTANAK!" - piglin-barter: "&4Slimefun tárgyakat nem cserélhetsz el piglinekkel." + piglin-barter: "&4Slimefun tárgyakat nem cserélhetsz el a piglinekkel." enchantment-rune: - fail: "&cNem enchantolhatod ezt a tárgyat." - no-enchantment: "&cNem található megfelelő enchant ehhez az tárgyhoz." - success: "&aSikeresen alkalmaztál egy véletlenszerű enchantot erre a tárgyra." + fail: "&cNem varázsolhatod el ezt a tárgyat." + no-enchantment: "&cNem található megfelelő varázslat ehhez az tárgyhoz." + success: "&aSikeresen alkalmaztál egy véletlenszerű varázslatot erre a tárgyra." tape-measure: no-anchor: "&cBe kell állítanod egy kezdőpontot, mielőtt megkezdenéd a mérést!" wrong-world: "&cA kezdőpont úgy tűnik, hogy egy másik világban van!" @@ -259,7 +263,7 @@ gps: max: "&4Elérted a maximális útpontok számát" duplicate: "&4Már létrehoztál egy ilyen nevű útpontot: &f%waypoint%" insufficient-complexity: - - "&4Nem megfelelő a GPS-hálózat komplexitása: &c%complexity%" + - "&4Nem megfelelő a GPS-hálózat összetettsége: &c%complexity%" - "&4a) Még nem telepítetted a GPS-hálózatot" - "&4b) A GPS-hálózatod nem eléggé összetett" geo: @@ -325,12 +329,11 @@ languages: ru: Orosz sk: Szlovák zh-TW: Kínai (Tajvan) - vi: Vietnami + vi: Vietnámi id: Indonéz zh-CN: Kínai (Kína) el: Görög he: Héber - pt-BR: Portugál (Brazília) ar: Arab af: Afrikaans da: Dán @@ -343,6 +346,7 @@ languages: th: Thai ro: Román pt: Portugál (Portugália) + pt-BR: Portugál (Brazília) bg: Bolgár ko: Koreai tr: Török diff --git a/src/main/resources/languages/messages_ja.yml b/src/main/resources/languages/messages_ja.yml index 3d9493a41..5b402ca54 100644 --- a/src/main/resources/languages/messages_ja.yml +++ b/src/main/resources/languages/messages_ja.yml @@ -4,7 +4,6 @@ commands: cheat: Slimefunガイドをチートモードで開く give: 指定したプレイヤーにSlimefunアイテムを与える guide: Slimefunガイドを取得 - timings: サーバの負荷状況を表示 teleporter: 指定したプレイヤーのウェイポイントを表示 versions: バージョンについて search: Slimefunガイド内を検索 @@ -21,9 +20,14 @@ commands: backpack-does-not-exist: "&4指定したバックパックは存在しません!" restored-backpack-given: "&aバックパックが返還されました!" charge: - description: 手に持っているアイテムを充電 - charge-success: アイテムは充電されました! + description: 手に持っているアイテムを充電する + charge-success: アイテムが充電されました! not-rechargeable: このアイテムは充電できません! + timings: + description: Slimefunに関連する負荷の計測 + please-wait: "&e数秒お待ちください… 負荷の測定中です!" + verbose-player: "&4プレイヤーはverboseフラグを使用できません!" + unknown-flag: "&4未知のフラグです: &c%flag%" guide: search: message: "&b検索ワードをチャットで入力してください" @@ -314,7 +318,6 @@ languages: el: ギリシャ語 he: ヘブライ語 pt: ポルトガル語(ポルトガル) - pt-BR: ポルトガル語(ブラジル) ar: アラビア語 af: アフリカーンス語 da: デンマーク語 @@ -326,6 +329,7 @@ languages: fa: ペルシア語 th: タイ語 ro: ルーマニア語 + pt-BR: ポルトガル語(ブラジル) bg: ブルガリア語 ko: 韓国語 tr: トルコ語 diff --git a/src/main/resources/languages/messages_pt-BR.yml b/src/main/resources/languages/messages_pt-BR.yml index df1a164f5..fb2383dc3 100644 --- a/src/main/resources/languages/messages_pt-BR.yml +++ b/src/main/resources/languages/messages_pt-BR.yml @@ -1,214 +1,154 @@ --- -android: - scripts: - already-uploaded: "&4Este script já foi enviado." - editor: Editor de Scripts - enter-name: - - - - "&eDigite um nome para o seu script" - instructions: - ATTACK_ANIMALS: "&4Atacar &c(Animais)" - ATTACK_ANIMALS_ADULT: "&4Atacar &c(Animais &7[Adultos]&c)" - ATTACK_MOBS: "&4Atacar &c(Mobs Hostis)" - ATTACK_MOBS_ANIMALS: "&4Atacar &c(Mobs Hostis & Animais)" - CATCH_FISH: "&bPegar Peixe" - CHOP_TREE: "&cCortar & Replantar" - DIG_DOWN: "&bCavar Para Baixo" - DIG_FORWARD: "&bCavar Para a Frente" - DIG_UP: "&bCavar Para Cima" - FARM_DOWN: "&bColheita e Replantio &7(Bloco abaixo)" - FARM_EXOTIC_DOWN: "&bColheita e Replantio Avançado &7(Bloco abaixo)" - FARM_EXOTIC_FORWARD: "&bColheita e Replantio Avançado" - FARM_FORWARD: "&bColheita e Replantio" - GO_DOWN: "&7Mover Para Baixo" - GO_FORWARD: "&7Mover Para Frente" - GO_UP: "&7Mover Para Cima" - INTERFACE_FUEL: "&cPuxe o combustível da interface voltada." - INTERFACE_ITEMS: "&9Envie o conteúdo do inventário para a interface exibida." - MOVE_AND_DIG_DOWN: "&bMover e Cavar Para Baixo" - MOVE_AND_DIG_FORWARD: "&bMover e Cavar Para a Frente" - MOVE_AND_DIG_UP: "&bMover & Cavar Para Cima" - REPEAT: "&9Repetir Script" - START: "&2Iniciar Script" - TURN_LEFT: "&7Virar à Esquerda" - TURN_RIGHT: "&7Virar à Direita" - WAIT: "&eAguarde 0.5s" - rating: - already: "&4Você já avaliou este script!" - own: "&4Você não pode avaliar seu próprio script!" - uploaded: - - "&bEnviando..." - - "&aO script foi enviado com sucesso!" - started: "&7Seu Android voltou a executar o script." - stopped: "&7Seu Android pausou o script." -anvil: - not-working: "&4Você não pode usar os itens do Slimefun em uma bigorna!" -backpack: - already-open: "&cEsta mochila já está aberta em outro lugar!" - no-stack: "&cVocê não pode empilhar mochilas!" commands: + help: Exibe esta tela de ajuda cheat: Permite que você "trapaceie" itens give: Dá a alguém algum item do Slimefun guide: Dá a si mesmo um Guia do Slimefun - help: Exibe esta tela de ajuda + timings: Lag-Info sobre o seu servidor + teleporter: Vê os Waypoints de outros jogadores + versions: Exibe todos os Add-ons instalados + search: Pesquisa no seu Guia o termo especificado open_guide: Abre o guia do Slimefun sem usar o livro + stats: Mostra algumas estatísticas sobre um jogador research: description: Desbloqueia/Redefine pesquisas para um jogador reset: "&cVocê redifiniu o Conhecimento de %player%" reset-target: "&cSeu Conhecimento foi redefinido" - search: Pesquisa no seu Guia o termo especificado - stats: Mostra algumas estatísticas sobre um jogador - teleporter: Vê os Waypoints de outros jogadores - timings: Lag-Info sobre o seu servidor - versions: Exibe todos os Add-ons instalados -gps: - deathpoint: "&4Ponto de Morte &7%date%" - geo: - scan-required: "&4Scan Geográfico necessário! &cEscaneie esta chunk usando um - Scan Geográfico primeiro!" - insufficient-complexity: - - "&4Complexidade insuficiente da rede de GPS: &c%complexity%" - - "&4a) Você ainda não tem uma configuração de rede de GPS!" - - "&4b) Sua rede de GPS não é complexa o suficiente!" - waypoint: - added: "&aNovo WayPoint adicionado com sucesso." - max: "&4Você atingiu a quantidade máxima de WayPoints!" - new: "&eDigite o nome do WayPoint no bate-papo. &7(Códigos de cores suportados!)" + backpack: + description: Recuperar uma cópia de uma mochila existente + invalid-id: "&4O id deve ser um número não negativo!" + player-never-joined: Nenhum jogador com esse nome foi encontrado! + backpack-does-not-exist: "&4A mochila especificada não existe!" + restored-backpack-given: "&aSua mochila foi restaurada e foi adicionada ao seu + inventário!" + charge: + description: Carrega o item que você está segurando + charge-success: O item foi carregado! + not-rechargeable: Este item não pode ser carregado! guide: - back: - guide: Voltar Para o Guia do Slimefun - settings: Voltar Para o Painel de Configurações - title: Voltar - cheat: - no-multiblocks: '&4Você não pode "trapacear" em Multiblocks, você precisa construí-los!' - credits: - commit: Comissão - commits: Comissões - profile-link: Clique aqui para visitar o perfil deles no GitHub - roles: - developer: "&6Desenvolvedor(a)" - resourcepack: "&cArtista de ResourcePack" - translator: "&9Tradutor(a)" - wiki: "&3Editor(a) da Wiki" - languages: - select: Clique aqui para selecionar este idioma - select-default: Clique aqui para selecionar o idioma padrão - selected-language: 'Idioma atual:' - translations: - lore: Clique aqui para adicionar seu próprio idioma - name: "&aHá algum idioma faltando?" - updated: "&aSeu idioma foi definido com sucesso para: &b%lang%" - pages: - next: Próxima Página - previous: Página Anterior search: + message: "&bO que você gostaria de pesquisar?" + name: "&7Pesquisar..." lore: - "&bO que você gostaria de pesquisar?" - "&7Digite seu termo de pesquisa no bate-papo." - message: "&bO que você gostaria de pesquisar?" - name: "&7Pesquisar..." + inventory: 'Procurando por: %item%' + tooltip: "&bClique para procurar um item" + cheat: + no-multiblocks: '&4Você não pode "trapacear" em Multiblocks, você precisa construí-los!' + languages: + updated: "&aSeu idioma foi definido com sucesso para: &b%lang%" + translations: + name: "&aHá algum idioma faltando?" + lore: Clique aqui para adicionar seu próprio idioma + select: Clique aqui para selecionar este idioma + select-default: Clique aqui para selecionar o idioma padrão + selected-language: 'Idioma atual:' + change: Clique para selecionar um novo idioma + description: + - "&7Agora você tem a opção de alterar" + - "&7o idioma no qual Slimefun" + - "&7será apresentado a você. Itens" + - "&7não podem ser traduzido por enquanto." title: - addons: Add-ons do Slimefun4 - bugs: Relatório de Erros - credits: Contribuidores do Slimefun4 - languages: Selecione seu idioma preferido main: Guia do Slimefun settings: Config & Info - source: Código Fonte + languages: Selecione seu idioma preferido + credits: Contribuidores do Slimefun4 wiki: Wiki do Slimefun4 + addons: Add-ons do Slimefun4 + bugs: Relatório de Erros + source: Código Fonte + versions: Versões instaladas + credits: + commit: Comissão + commits: Comissões + roles: + developer: "&6Desenvolvedor(a)" + wiki: "&3Editor(a) da Wiki" + resourcepack: "&cArtista de ResourcePack" + translator: "&9Tradutor(a)" + profile-link: Clique aqui para visitar o perfil deles no GitHub + description: + - "&7Slimefun é um projeto de código aberto" + - "&7e mantido por uma grande comunidade de pessoas." + - "&7Mais de &e%contributors% &7pessoas trabalharam" + - "&7no Slimefun ao longo de todos esses anos." + open: Clique para ver nossos colaboradores + pages: + previous: Página Anterior + next: Próxima Página tooltips: open-category: Clique aqui para abrir - recipes: - generator: Tipos disponíveis de combustível - gold-pan: Recursos que você pode obter - machine: Receitas utilizadas nessa maquina - miner: Recursos que você pode obter com essa Mineradora versions-notice: Isso é muito importante ao relatar erros! wiki: Veja mais sobre esse item na Wiki oficial do Slimefun -inventory: - no-access: "&4Você não tem permissão para acessar este bloco." -languages: - af: Africano - ar: Árabe - cs: Tcheco - da: Dinamarquês - de: Alemão - default: Padrão do Servidor - el: Grego - en: Inglês - es: Espanhol - fa: Persa - fi: Finlandês - fr: Francês - he: Hebraico - hu: Húngaro - id: Indonésio - it: Italiano - ja: Japonês - lv: Letão - ms: Malaio - nl: Holandês - 'no': Norueguês - pl: Polonês - pt: Português (Portugal) - pt-BR: Português (Brasil) - ro: Romena - ru: Russo - sk: Eslovaco - sv: Sueco - th: Tailandês - uk: Ucraniano - vi: Vietnamita - zh-CN: Chinês (China) - zh-TW: Chinês (Taiwan) - bg: Búlgaro - ko: Coreano - tr: Turco -machines: - ANCIENT_ALTAR: - not-enough-pedestals: "&4O altar não está rodeado pela quantidade necessária de - pedestais &c(%pedestals% de 8)&4." - unknown-catalyst: "&4Catalisador desconhecido! &cUse a receita correta." - unknown-recipe: "&4Receita desconhecida! &cUse a receita correta." - ANCIENT_PEDESTAL: - obstructed: "&4O pedestal está obstruído! &cRemova qualquer coisa acima do pedestal." - CARGO_NODES: - must-be-placed: "&4Deve ser colocado em um baú ou uma máquina!" - ELEVATOR: - click-to-teleport: "&eClique aqui &7para teleportar-se para o andar:" - current-floor: "&eEste é o andar em que você está atualmente:" - enter-name: "&7Digite o nome do andar no bate-papo. &r(Códigos de cores são suportados!)" - named: "&2Andar nomeado com sucesso para: &r%floor%" - no-destinations: "&4Nenhum destino encontrado!" - pick-a-floor: "&3- Escolha um andar -" - full-inventory: "&eDesculpe, meu inventário está muito cheio!" - GPS_CONTROL_PANEL: - title: GPS - Painel de Controle - transmitters: Informação de Transmissores - waypoints: Informação de Locais de Teleporte - HOLOGRAM_PROJECTOR: - enter-text: "&7Digite o nome do holograma no bate-papo. &r(Códigos de cores são - suportados!)" - inventory-title: Editor de Holograma - ignition-chamber-no-flint: "&cEstá faltando uma Pederneira na Câmara de Ignição." - in-use: "&cO inventário deste bloco está atualmente aberto por um jogador diferente." - pattern-not-found: "&eDesculpe, não pude reconhecer esta receita. Coloque os itens - no padrão correto no Ejetor." - TELEPORTER: - cancelled: "&4Teleporte cancelado!" - invulnerability: "&b&lVocê recebeu 30 segundos de invulnerabilidade!" - teleported: "&3Teleportado(a)!" - teleporting: "&3Teleportando-se..." - unknown-material: "&eDesculpe, não pude reconhecer o item no meu ejetor. Por favor, - coloque algo que eu sei." - wrong-item: "&eDesculpe, não pude reconhecer o item com o qual você clica com o - botão direito. Verifique as receitas e veja quais itens você pode usar." + recipes: + machine: Receitas utilizadas nessa maquina + miner: Recursos que você pode obter com essa Mineradora + generator: Tipos disponíveis de combustível + gold-pan: Recursos que você pode obter + climbing-pick: Superfícies que você pode escalar + back: + title: Voltar + guide: Voltar Para o Guia do Slimefun + settings: Voltar Para o Painel de Configurações + locked: BLOQUEADO + locked-category: + - Para desbloquear esta categoria, você + - precisa desbloquear todos os itens das + - seguintes categorias + work-in-progress: Este recurso não está totalmente concluído ainda! messages: - cannot-place: "&cVocê não pode colocar esse bloco lá!" - diet-cookie: "&eVocê está começando a se sentir muito leve..." + not-researched: "&4Você não tem conhecimento suficiente para entender sobre isso." + not-enough-xp: "&4Você não tem XP suficiente para desbloquear isso!" + unlocked: '&bVocê desbloqueou &7"%research%"&b.' + only-players: "&4Este comando é apenas para jogadores" + unknown-player: "&4Jogador Desconhecido: &c%player%&4." + no-permission: "&4Você não tem a permissão necessária para fazer isso." + usage: "&4Uso: &c%usage%" + not-online: "&4%player% &cnão está online!" + given-item: '&bVocê deu &a%amount% &7"%item%&7"' + give-item: '&bVocê deu para %player% &a%amount% &7"%item%&7"' + give-research: '&bVocêu deu para %player% a Pesquisa &7"%research%&7"' + hungry: "&cVocê está com muita fome para fazer isso!" disabled-in-world: "&4&lEste item foi desativado neste mundo." disabled-item: "&4&lEste item foi desativado! Como você conseguiu isso?" + no-tome-yourself: "&cVocê não pode usar o &4Tomo do Conhecimento &cem si mesmo..." + multimeter: "&bEnergia Armazenada: &3%stored% &b/ &3%capacity%" + talisman: + anvil: "&a&oSeu Talismã salvou sua ferramenta de quebrar." + miner: "&a&oSeu talismã dobrou os drops." + hunter: "&a&oSeu talismã dobrou os minerios." + lava: "&a&oSeu talismã salvou você de queimar até a morte." + water: "&a&oSeu talismã salvou você de se afogar." + angel: "&a&oSeu talismã salvou você de sofrer dano de queda." + fire: "&a&oSeu talismã salvou você de queimar até a morte." + magician: "&a&oSeu talismã deu a você um encantamento adicional." + traveller: "&a&oSeu talismã deu a você um aumento de velocidade." + warrior: "&a&oSeu talismã melhorou sua força por um tempo." + knight: "&a&oSeu talismã lhe deu 5 segundos de regeneração." + whirlwind: "&a&oSeu talismã refletiu o projétil." + wizard: "&a&oSeu talismã deu a você um nível de Fortuna melhor, mas talvez tenha + diminuído alguns outros Níveis de Encantamento." + caveman: "&a&oSeu talismã te deu pressa" + soulbound-rune: + fail: "&cVocê pode vincular apenas um item à sua alma por vez." + success: "&aVocê vinculou com sucesso este item à sua alma! Você o manterá quando + morrer." + research: + start: "&7Os Espíritos Antigos sussurram palavras misteriosas no seu ouvido!" + progress: "&7Você começa a se perguntar sobre &b%research% &e(%progress%)" fire-extinguish: "&7Você se extinguiu." + cannot-place: "&cVocê não pode colocar esse bloco lá!" + no-pvp: "&cVocê não pode lutar aqui!" + radiation: "&4Você foi exposto a uma radiação mortal! &cLivre-se do item radioativo + ou vista-se com um traje apropriado." + opening-guide: "&bAbrindo o guia, isso pode levar alguns segundos..." + opening-backpack: "&bAbrindo a mochila, isso pode levar alguns segundos..." + no-iron-golem-heal: "&cIsso não é uma barra de ferro. Você não pode usar isso para + curar Golens de Ferro!" + link-prompt: "&eClique aqui:" + diet-cookie: "&eVocê está começando a se sentir muito leve..." fortune-cookie: - "&7Ajude-me, estou preso em uma Fábrica de Biscoitos da Sorte!" - "&7Você vai morrer amanhã... por um Creeper!" @@ -222,57 +162,208 @@ messages: - "&742. A resposta é 42." - "&7Um Walshy por dia manterá os problemas afastados." - "&7Nunca cave para baixo!" - give-item: '&bVocê deu para %player% &a%amount% &7"%item%&7"' - given-item: '&bVocê deu &a%amount% &7"%item%&7"' - give-research: '&bVocêu deu para %player% a Pesquisa &7"%research%&7"' - hungry: "&cVocê está com muita fome para fazer isso!" - link-prompt: "&eClique aqui:" - mode-change: "&bO modo do dispositivo %device% foi alterado para: &9%mode%" - multimeter: "&bEnergia Armazenada: &3%stored% &b/ &3%capacity%" - no-iron-golem-heal: "&cIsso não é uma barra de ferro. Você não pode usar isso para - curar Golens de Ferro!" - no-permission: "&4Você não tem a permissão necessária para fazer isso." - no-pvp: "&cVocê não pode lutar aqui!" - not-enough-xp: "&4Você não tem XP suficiente para desbloquear isso!" - no-tome-yourself: "&cVocê não pode usar o &4Tomo do Conhecimento &cem si mesmo..." - not-online: "&4%player% &cnão está online!" - not-researched: "&4Você não tem conhecimento suficiente para entender sobre isso." + - "&7É apenas uma ferida de carne!" + - "&7Sempre olhe para o lado positivo da vida!" + - "&7Este foi realmente um bolacha e não um biscoito" + - "&7Os sinais de néon estão ILUMINADOS!" + invalid-item: "&4%item% &cnão é um item válido!" invalid-amount: "&4%amount% &cnão é uma quantidade válida (precisa ser maior que 0)!" - invalid-item: "&4%item% &cnão é um item válido!" invalid-research: "&4%research% &cnão é uma Pesquisa válida!" - only-players: "&4Este comando é apenas para jogadores" - opening-backpack: "&bAbrindo a mochila, isso pode levar alguns segundos..." - opening-guide: "&bAbrindo o guia, isso pode levar alguns segundos..." - radiation: "&4Você foi exposto a uma radiação mortal! &cLivre-se do item radioativo - ou vista-se com um traje apropriado." - research: - progress: "&7Você começa a se perguntar sobre &b%research% &e(%progress%)" - start: "&7Os Espíritos Antigos sussurram palavras misteriosas no seu ouvido!" - soulbound-rune: - fail: "&cVocê pode vincular apenas um item à sua alma por vez." - success: "&aVocê vinculou com sucesso este item à sua alma! Você o manterá quando - morrer." - talisman: - angel: "&a&oSeu talismã salvou você de sofrer dano de queda." - anvil: "&a&oSeu Talismã salvou sua ferramenta de quebrar." - fire: "&a&oSeu talismã salvou você de queimar até a morte." - hunter: "&a&oSeu talismã dobrou os minerios." - knight: "&a&oSeu talismã lhe deu 5 segundos de regeneração." - lava: "&a&oSeu talismã salvou você de queimar até a morte." - magician: "&a&oSeu talismã deu a você um encantamento adicional." - miner: "&a&oSeu talismã dobrou os drops." - traveller: "&a&oSeu talismã deu a você um aumento de velocidade." - warrior: "&a&oSeu talismã melhorou sua força por um tempo." - water: "&a&oSeu talismã salvou você de se afogar." - whirlwind: "&a&oSeu talismã refletiu o projétil." - wizard: "&a&oSeu talismã deu a você um nível de Fortuna melhor, mas talvez tenha - diminuído alguns outros Níveis de Encantamento." - unknown-player: "&4Jogador Desconhecido: &c%player%&4." - unlocked: '&bVocê desbloqueou &7"%research%"&b.' - usage: "&4Uso: &c%usage%" -miner: - no-ores: "&eDesculpe, não encontrei nenhum minério por perto!" + mode-change: "&bO modo do dispositivo %device% foi alterado para: &9%mode%" + tape-measure: + no-anchor: "&cVocê precisa definir uma âncora antes de começar a medir!" + wrong-world: "&cSua âncora parece estar em um mundo diferente!" + distance: "&7Medição realizada. \n&eDistância: %distance%" + anchor-set: "&aConfigurou a âncora com sucesso: &e%anchor%" + piglin-barter: "&4Você não pode negociar com piglins usando itens do Slimefun" + enchantment-rune: + fail: "&cVocê não pode encantar este item." + no-enchantment: "&cNão foi possível encontrar nenhum encantamento aplicável para + este item." + success: "&aVocê aplicou com sucesso um encantamento aplicável aleatório a este + item." + multi-tool: + mode-change: "&b%device% modo alterado para: &9%mode%" + not-shears: "&cA Multi Tool não pode ser usada como tesoura!" + climbing-pick: + dual-wielding: "&4Você precisa segurar as Escolhas de Escalada com as duas mãos + para usá-las!" + wrong-material: "&cVocê não pode escalar esta superfície. Verifique o seu Guia + do Slimefun para mais informações!" + bee-suit-slow-fall: "&eSuas Assas de Abelhas irão te ajudar a retornar ao chão em + segurança e lentamente" +machines: + pattern-not-found: "&eDesculpe, não pude reconhecer esta receita. Coloque os itens + no padrão correto no Ejetor." + unknown-material: "&eDesculpe, não pude reconhecer o item no meu ejetor. Por favor, + coloque algo que eu sei." + wrong-item: "&eDesculpe, não pude reconhecer o item com o qual você clica com o + botão direito. Verifique as receitas e veja quais itens você pode usar." + full-inventory: "&eDesculpe, meu inventário está muito cheio!" + in-use: "&cO inventário deste bloco está atualmente aberto por um jogador diferente." + ignition-chamber-no-flint: "&cEstá faltando uma Pederneira na Câmara de Ignição." + ANCIENT_ALTAR: + not-enough-pedestals: "&4O altar não está rodeado pela quantidade necessária de + pedestais &c(%pedestals% de 8)&4." + unknown-catalyst: "&4Catalisador desconhecido! &cUse a receita correta." + unknown-recipe: "&4Receita desconhecida! &cUse a receita correta." + ANCIENT_PEDESTAL: + obstructed: "&4O pedestal está obstruído! &cRemova qualquer coisa acima do pedestal." + HOLOGRAM_PROJECTOR: + enter-text: "&7Digite o nome do holograma no bate-papo. &r(Códigos de cores são + suportados!)" + inventory-title: Editor de Holograma + ELEVATOR: + no-destinations: "&4Nenhum destino encontrado!" + pick-a-floor: "&3- Escolha um andar -" + current-floor: "&eEste é o andar em que você está atualmente:" + click-to-teleport: "&eClique aqui &7para teleportar-se para o andar:" + enter-name: "&7Digite o nome do andar no bate-papo. &r(Códigos de cores são suportados!)" + named: "&2Andar nomeado com sucesso para: &r%floor%" + TELEPORTER: + teleporting: "&3Teleportando-se..." + teleported: "&3Teleportado(a)!" + cancelled: "&4Teleporte cancelado!" + invulnerability: "&b&lVocê recebeu 30 segundos de invulnerabilidade!" + gui: + title: Seus waypoints + tooltip: Clique para se teleportar + time: Tempo estimado + CARGO_NODES: + must-be-placed: "&4Deve ser colocado em um baú ou uma máquina!" + GPS_CONTROL_PANEL: + title: GPS - Painel de Controle + transmitters: Informação de Transmissores + waypoints: Informação de Locais de Teleporte + INDUSTRIAL_MINER: + finished: "&eSua Mineradora Industrial terminou! Obteve um total de %ores% minério + (s)!" + no-fuel: "&aSua mineradora industrial ficou sem combustível! Coloque seu combustível + no peito acima." + piston-facing: "&cSua Mineradora Industrial exige pistões para cima!" + piston-space: "&cOs dois pistões precisam ter um bloco vazio acima deles!" + destroyed: "&cO sua Mineradora industrial parece ter sido destruída." + already-running: "&cEsta Mineradora industrial já está em execução!" + full-chest: "&cO baú do sua Mineradora industrial está cheio!" + no-permission: "&4Você não parece ter permissão para operar uma Mineradora industrial + aqui!" +anvil: + not-working: "&4Você não pode usar os itens do Slimefun em uma bigorna!" + mcmmo-salvaging: "&4Você não pode reciclar itens do Slimefun!" +backpack: + already-open: "&cEsta mochila já está aberta em outro lugar!" + no-stack: "&cVocê não pode empilhar mochilas!" workbench: not-enhanced: "&4Você não pode usar itens do Slimefun em uma bancada de trabalho normal." +gps: + deathpoint: "&4Ponto de Morte &7%date%" + waypoint: + new: "&eDigite o nome do WayPoint no bate-papo. &7(Códigos de cores suportados!)" + added: "&aNovo WayPoint adicionado com sucesso." + max: "&4Você atingiu a quantidade máxima de WayPoints!" + duplicate: "&4Você já criou um waypoint chamado: &f%waypoint%" + insufficient-complexity: + - "&4Complexidade insuficiente da rede de GPS: &c%complexity%" + - "&4a) Você ainda não tem uma configuração de rede de GPS!" + - "&4b) Sua rede de GPS não é complexa o suficiente!" + geo: + scan-required: "&4Scan Geográfico necessário! &cEscaneie esta chunk usando um + Scan Geográfico primeiro!" +inventory: + no-access: "&4Você não tem permissão para acessar este bloco." +android: + started: "&7Seu Android voltou a executar o script." + stopped: "&7Seu Android pausou o script." + scripts: + already-uploaded: "&4Este script já foi enviado." + instructions: + START: "&2Iniciar Script" + REPEAT: "&9Repetir Script" + WAIT: "&eAguarde 0.5s" + GO_FORWARD: "&7Mover Para Frente" + GO_UP: "&7Mover Para Cima" + GO_DOWN: "&7Mover Para Baixo" + TURN_LEFT: "&7Virar à Esquerda" + TURN_RIGHT: "&7Virar à Direita" + DIG_UP: "&bCavar Para Cima" + DIG_FORWARD: "&bCavar Para a Frente" + DIG_DOWN: "&bCavar Para Baixo" + MOVE_AND_DIG_UP: "&bMover & Cavar Para Cima" + MOVE_AND_DIG_FORWARD: "&bMover e Cavar Para a Frente" + MOVE_AND_DIG_DOWN: "&bMover e Cavar Para Baixo" + ATTACK_MOBS_ANIMALS: "&4Atacar &c(Mobs Hostis & Animais)" + ATTACK_MOBS: "&4Atacar &c(Mobs Hostis)" + ATTACK_ANIMALS: "&4Atacar &c(Animais)" + ATTACK_ANIMALS_ADULT: "&4Atacar &c(Animais &7[Adultos]&c)" + CHOP_TREE: "&cCortar & Replantar" + CATCH_FISH: "&bPegar Peixe" + FARM_FORWARD: "&bColheita e Replantio" + FARM_DOWN: "&bColheita e Replantio &7(Bloco abaixo)" + FARM_EXOTIC_FORWARD: "&bColheita e Replantio Avançado" + FARM_EXOTIC_DOWN: "&bColheita e Replantio Avançado &7(Bloco abaixo)" + INTERFACE_ITEMS: "&9Envie o conteúdo do inventário para a interface exibida." + INTERFACE_FUEL: "&cPuxe o combustível da interface voltada." + enter-name: + - + - "&eDigite um nome para o seu script" + uploaded: + - "&bEnviando..." + - "&aO script foi enviado com sucesso!" + rating: + own: "&4Você não pode avaliar seu próprio script!" + already: "&4Você já avaliou este script!" + editor: Editor de Scripts +languages: + default: Padrão do Servidor + en: Inglês + de: Alemão + fr: Francês + it: Italiano + es: Espanhol + pl: Polonês + sv: Sueco + nl: Holandês + cs: Tcheco + hu: Húngaro + lv: Letão + ru: Russo + sk: Eslovaco + zh-TW: Chinês (Taiwan) + vi: Vietnamita + id: Indonésio + zh-CN: Chinês (China) + el: Grego + he: Hebraico + ar: Árabe + af: Africano + da: Dinamarquês + fi: Finlandês + uk: Ucraniano + ms: Malaio + 'no': Norueguês + ja: Japonês + fa: Persa + th: Tailandês + ro: Romena + pt: Português (Portugal) + pt-BR: Português (Brasil) + bg: Búlgaro + ko: Coreano + tr: Turco + hr: Croatian + mk: Macedonian + sr: Serbian + be: Belarusian + tl: Tagalog +miner: + no-ores: "&eDesculpe, não encontrei nenhum minério por perto!" +cauldron: + no-discoloring: "&4Você não pode descolorir uma Armadura do Slimefun" +cartography_table: + not-working: "&4Você não pode usar itens Slimefun em uma tabela de cartografia!" +brewing_stand: + not-working: "&4Você não pode usar itens Slimefun em um Suporte de poções!" +villagers: + no-trading: "&4Você não pode trocar itens Slimefun com os aldeões!" diff --git a/src/main/resources/languages/messages_vi.yml b/src/main/resources/languages/messages_vi.yml index 0cdcc4902..ca9ade11f 100644 --- a/src/main/resources/languages/messages_vi.yml +++ b/src/main/resources/languages/messages_vi.yml @@ -1,250 +1,158 @@ --- -android: - scripts: - already-uploaded: "&4Đoạn mã này đã được tải lên." - editor: Trình chỉnh sửa kịch bản - enter-name: - - - - "&eVui lòng nhập tên cho đoạn mã của bạn" - instructions: - ATTACK_ANIMALS: "&4Tấn công &c(Động vật)" - ATTACK_ANIMALS_ADULT: "&4Tấn công &c(Động vật &7[Trường thành]&c)" - ATTACK_MOBS: "&4Tấn công &c(Các mob hung dữ)" - ATTACK_MOBS_ANIMALS: "&4Tấn công &c(Mob và Động vật hung giữ)" - CATCH_FISH: "&bBắt cá" - CHOP_TREE: "&cChặt và trồng lại" - DIG_DOWN: "&bĐào xuống" - DIG_FORWARD: "&bĐào thẳng" - DIG_UP: "&bĐào lên" - FARM_DOWN: "&bThu hoạch và trồng lại &7(Khối bên dưới)" - FARM_EXOTIC_DOWN: "&bThu hoạch và thay thế nâng ca o&7(Khối ở dưới)" - FARM_EXOTIC_FORWARD: "&bThu hoạch và thay thế nâng cao" - FARM_FORWARD: "&bThu hoạch và trồng lại" - GO_DOWN: "&7Đi xuống" - GO_FORWARD: "&7Đi thẳng" - GO_UP: "&7Đi lên" - INTERFACE_FUEL: "&cKéo nhiên liệu từ giao diện" - INTERFACE_ITEMS: "&9Đẩy nội dung túi đồ lên giao diện" - MOVE_AND_DIG_DOWN: "&bDi chuyển và đào xuống" - MOVE_AND_DIG_FORWARD: "&bDi chuyển và đào thẳng" - MOVE_AND_DIG_UP: "&bDi chuyển và đào lên" - REPEAT: "&9Lặp lại Đoạn Mã" - START: "&2Bắt đầu chạy Đoạn Mã" - TURN_LEFT: "&7Rẽ trái" - TURN_RIGHT: "&7Rẽ phải" - WAIT: "&eĐợi 0.5s" - rating: - already: "&4Bạn đã để lại Xếp Hạng cho đoạn mã này!" - own: "&4Bạn không thể xếp hạng đoạn mã của chính mình!" - uploaded: - - "&bĐang tải lên..." - - "&aTải đoạn mã lên thành công!" - started: "&7Thiết bị Android của bạn đã tiếp tục chạy đoạn mã của nó" - stopped: "&7Thiết bị Android của bạn đã dùng chạy đoạn mã của nó" -anvil: - not-working: "&4Bạn không thể sử dụng vật phẩm Slimefun trên cái đê!" -backpack: - already-open: "&cXin lỗi, cái Ba lô này đã được mở ở một nơi nào khác!" - no-stack: "&cBạn không thể xếp nhiều Ba lô lại với nhau" commands: - backpack: - backpack-does-not-exist: "&4Không tìm thấy ba lô đó!" - description: Lấy bản sao của một ba lô đã có sẵn - invalid-id: "&4ID phải là số nguyên dương!" - player-never-joined: "&4Không tìm thấy người chơi với tên như vậy!" - restored-backpack-given: "&aBa lô của bạn được khôi phục và được thêm vào túi - đồ của bạn!" + help: Hiển thị màn hình trợ giúp này cheat: Cho phép bạn gian lận vật phẩm give: Đưa cho ai đó vài món đồ Slimefun guide: Cung cấp cho bạn một cuốn hướng dẫn Slimefun - help: Hiển thị màn hình trợ giúp này + timings: Thông tin Lag về máy chủ của bạn + teleporter: Xem các điểm dịch chuyển của người chơi khác + versions: Liệt kê tất cả các tiện ích mở rộng đã cài đặt + search: Tìm kiếm Hướng dẫn của bạn cho cụm từ đã cho open_guide: Mở hướng dẫn của Slimefun mà không cần sử dụng sách + stats: Hiển thị một số thống kê về người chơi research: description: Mở khóa / Đặt lại nghiên cứu cho người chơi reset: "&cBạn đã đặt lại Kiến thức của %player%" reset-target: "&cKiến thức của bạn đã được đặt lại" - search: Tìm kiếm Hướng dẫn của bạn cho cụm từ đã cho - stats: Hiển thị một số thống kê về người chơi - teleporter: Xem các điểm dịch chuyển của người chơi khác - timings: Thông tin Lag về máy chủ của bạn - versions: Liệt kê tất cả các tiện ích mở rộng đã cài đặt -gps: - deathpoint: "&4Điểm chết &7%date%" - geo: - scan-required: "&4Yêu cầu Quét GEO! &cQuét chunk này bằng Máy Quét GEO trước!" - insufficient-complexity: - - "&4Độ phức tạp của mạng GPS không đủ: &c%complexity%" - - "&4a) Bạn chưa có thiết lập Mạng GPS" - - "&4b) Mạng GPS của bạn không đủ phức tạp" - waypoint: - added: "&aĐã thêm thành công một điểm tham chiếu mới" - max: "&4Bạn đã đạt đến số lượng điểm tham chiếu tối đa" - new: "&eVui lòng nhập tên cho điểm tham chiếu mới của bạn trên khung chat. &7(Mã - màu được hỗ trợ!)" + backpack: + description: Lấy bản sao của một ba lô đã có sẵn + invalid-id: "&4ID phải là số nguyên dương!" + player-never-joined: "&4Không tìm thấy người chơi với tên như vậy!" + backpack-does-not-exist: "&4Không tìm thấy ba lô đó!" + restored-backpack-given: "&aBa lô của bạn được khôi phục và được thêm vào túi + đồ của bạn!" + charge: + description: Sạc vật phẩm bạn đang cầm + charge-success: Vật phẩm này đã sạc xong! + not-rechargeable: Vật phẩm này không thể sạc được! guide: - back: - guide: Quay trở lại Hướng dẫn Slimefun - settings: Quay trở lại Bảng Cài đặt - title: Quay lại + search: + message: "&bBạn muốn tìm kiếm cái gì?" + name: "&7Tìm kiếm..." + tooltip: "&bBấm để tìm vật phẩm" + inventory: 'Đang tìm: %item%' + lore: + - "&bBạn muốn tìm kiếm cái gì?" + - "&7Nhập cụm từ tìm kiếm của bạn vào khung chat" cheat: no-multiblocks: "&4Bạn không thể gian lận trong chế độ Đa khối, bạn phải xây dựng chúng!" - credits: - commit: Commit - commits: Commits - profile-link: Nhấp để truy cập hồ sơ của họ trên GitHub - roles: - developer: "&6Nhà phát triển" - resourcepack: "&cNghệ sĩ gói tài nguyên" - translator: "&9Đóng góp bản dịch" - wiki: "&3Người chỉnh sửa Wiki" languages: + updated: "&aNgôn ngữ của bạn đã được đặt thành công: &b%lang%" + translations: + name: "&aThiếu một cái gì đó?" + lore: Nhấn vào đây để thêm bản dịch của riêng bạn select: Nhấn vào đây để chọn ngôn ngữ này select-default: Nhấn vào đây để chọn ngôn ngữ mặc định selected-language: 'Ngôn ngữ hiện đang chọn:' - translations: - lore: Nhấn vào đây để thêm bản dịch của riêng bạn - name: "&aThiếu một cái gì đó?" - updated: "&aNgôn ngữ của bạn đã được đặt thành công: &b%lang%" + change: Nhấp để chọn ngôn ngữ mới + description: + - "&7Bạn hiện có tùy chọn để thay đổi" + - "&7ngôn ngữ trong đó Slimefun" + - "&7sẽ được giới thiệu cho bạn. Vật phẩm" + - "& 7hiện không thể dịch được." + title: + main: Hướng dẫn sử dụng Slimefun + settings: Cài đặt và thông tin + languages: Chọn ngôn ngữ ưa thích của bạn + credits: Người đóng góp cho Slimefun4 + wiki: Tài liệu Slimefun4 + addons: Các bổ sung cho Slimefun4 + bugs: Báo cáo lỗi + source: Mã nguồn + versions: Phiên bản đã cài + credits: + commit: Commit + commits: Commits + roles: + developer: "&6Nhà phát triển" + wiki: "&3Người chỉnh sửa Wiki" + resourcepack: "&cNghệ sĩ gói tài nguyên" + translator: "&9Đóng góp bản dịch" + profile-link: Nhấp để truy cập hồ sơ của họ trên GitHub + open: Nhấp để xem những người đóng góp của chúng tôi + description: + - "&7Slimefun là một dự án mã nguồn mở" + - "&7và được duy trì bởi một cộng đồng lớn." + - "&7Hơn &e%contributors% &7người đã làm việc" + - "&7Slimefun trong suốt những năm qua." + pages: + previous: Trang trước + next: Trang tiếp theo + tooltips: + open-category: Nhấn vào đây để mở + versions-notice: Đây là rất quan trọng khi báo cáo lỗi! + wiki: Xem vật phẩm này trên trang wiki chính thức của Slimefun + recipes: + machine: Các công thức được chế tạo ở máy này + miner: Tài nguyên bạn có thể kiếm được với máy đào này + generator: Các loại nguyên liệu có thể dùng + gold-pan: Tài nguyên bạn có thể kiếm được + climbing-pick: Những bề mặt bạn có thể leo lên + back: + title: Quay lại + guide: Quay trở lại Hướng dẫn Slimefun + settings: Quay trở lại Bảng Cài đặt locked: ĐÃ KHÓA locked-category: - Để mở khóa danh mục này, bạn - cần phải mở khóa các vật phẩm trong - danh mục sau - pages: - next: Trang tiếp theo - previous: Trang trước - search: - inventory: 'Đang tìm: %item%' - lore: - - "&bBạn muốn tìm kiếm cái gì?" - - "&7Nhập cụm từ tìm kiếm của bạn vào khung chat" - message: "&bBạn muốn tìm kiếm cái gì?" - name: "&7Tìm kiếm..." - tooltip: "&bBấm để tìm vật phẩm" - title: - addons: Các bổ sung cho Slimefun4 - bugs: Báo cáo lỗi - credits: Người đóng góp cho Slimefun4 - languages: Chọn ngôn ngữ ưa thích của bạn - main: Hướng dẫn sử dụng Slimefun - settings: Cài đặt và thông tin - source: Mã nguồn - wiki: Tài liệu Slimefun4 - tooltips: - open-category: Nhấn vào đây để mở - recipes: - generator: Các loại nguyên liệu có thể dùng - gold-pan: Tài nguyên bạn có thể kiếm được - machine: Các công thức được chế tạo ở máy này - miner: Tài nguyên bạn có thể kiếm được với máy đào này - versions-notice: Đây là rất quan trọng khi báo cáo lỗi! - wiki: Xem vật phẩm này trên trang wiki chính thức của Slimefun -inventory: - no-access: "&4Bạn không được phép truy cập vào khối này" -languages: - af: Tiếng Nam Phi - ar: Tiếng Ả Rập - be: Tiếng Bêlarut - bg: Tiếng Bulgaria - cs: Tiếng Séc - da: Tiếng Đan Mạch - de: Tiếng Đức - default: Máy chủ-Mặc định - el: Tiếng Hy Lạp - en: Tiếng Anh - es: Tiếng Tây Ban Nha - fa: Tiếng Ba Tư - fi: Tiếng Phần Lan - fr: Tiếng Pháp - he: Tiếng Do Thái - hr: Tiếng Croatia - hu: Tiếng Hungary - id: Tiếng Indonesia - it: Tiếng Ý - ja: Tiếng Nhật - ko: Tiếng Hàn - lv: Tiếng Latvia - ms: Tiếng Mã Lai - nl: Tiếng Hà Lan - 'no': Tiếng Na Uy - pl: Tiếng Ba Lan - pt: Tiếng Bồ Đào Nha (Bồ Đào Nha) - pt-BR: Tiếng Bồ Đào Nha (Brazil) - ro: Tiếng Rumani - ru: Tiếng Nga - sk: Tiếng Slovak - sr: Tiếng Serbia - sv: Tiếng Thụy Điển - th: Tiếng Thái - tr: Tiếng Thổ Nhĩ Kỳ - uk: Tiếng Ukraina - vi: Tiếng Việt - zh-CN: Tiếng Trung (Trung Quốc) - zh-TW: Tiếng Trung Quốc (Đài Loan) - mk: Tiếng Macedonia -machines: - ANCIENT_ALTAR: - not-enough-pedestals: "&4Bàn thờ không được bao quanh bởi số lượng cần thiết của - các bệ &c(%pedestals% / 8)" - unknown-catalyst: "&4Không rõ Chất Xúc Tác! &cSử dụng đúng công thức thay thế!" - unknown-recipe: "&4Không rõ Công Thức! &cSử dụng đúng công thức thay thế!" - ANCIENT_PEDESTAL: - obstructed: "&4Bệ bị cản trở! &cLoại bỏ bất kì thứ gì trên bệ!" - CARGO_NODES: - must-be-placed: "&4Phải được đặt trên hòm hoặc máy!" - ELEVATOR: - click-to-teleport: "&eẤn &7để dịch chuyển đến tầng:" - current-floor: "&eĐây là tầng mà bạn hiện đang ở:" - enter-name: "&7Vui lòng nhập tên tầng mong muốn của bạn vào Khung trò chuyện. - &r(Mã màu được hỗ trợ)" - named: "&2Đặt tên thành công cho tầng này: &r%floor%" - no-destinations: "&4Không tìm thấy điểm đến" - pick-a-floor: "&4- Chọn một tầng -" - full-inventory: "&eXin lỗi, kho đồ của tôi đã quá đầy!" - GPS_CONTROL_PANEL: - title: GPS - Bảng điều khiển - transmitters: Tổng quan về các máy phát tín hiệu - waypoints: Tổng quan về các vị trí dịch chuyển - HOLOGRAM_PROJECTOR: - enter-text: "&7Vui lòng nhập Văn Bản Ba Chiều mong muốn của bạn vào Khung trò - chuyện. &r(Mã màu được hỗ trợ!)" - inventory-title: Trình chỉnh sửa ảnh ba chiều - ignition-chamber-no-flint: "&cIgnition Chamber đang thiếu Bật Lửa." - INDUSTRIAL_MINER: - already-running: "&cMáy đào công nghiệp này đang chạy!" - destroyed: "&cMáy đào công nghiệp của bạn có vẻ như bị phá hủy." - finished: "&eMáy đào công nghiệp của bạn đã chạy xong! Nó đã đào được %ores% khoáng - sản(s)!" - full-chest: "&cRương của máy đào công nghiệp đã đầy!" - no-fuel: "&cMáy đào công nghiệp của bạn hết nhiên liệu! Bỏ nhiên liệu vào rương - ở trên." - no-permission: "&4Có vẻ như bạn không có quyền để sử dụng máy đào ở đây!" - piston-facing: "&cMáy đào công nghiệp của bạn cần 2 pít-tông hướng lên trên!" - piston-space: "&cHai cái pít-tông cần hai khối không khí ở trên!" - in-use: "&cKhối trong túi đồ này hiện đang được mở bởi người chơi khác." - pattern-not-found: "&eXin lỗi, tôi không thể nhận ra Công Thức này. Vui lòng đặt - các vật phẩm với mẫu nhất định vào trong Máy Phân Phát." - TELEPORTER: - cancelled: "&4Dịch chuyển bị hủy bỏ!" - gui: - time: Thời gian dự kiến - title: Địa điểm của bạn - tooltip: Bấm để dịch chuyển - invulnerability: "&b&lBạn đã được cho 30 giây Bất Tử!" - teleported: "&3Đã dịch chuyển!" - teleporting: "&3Đang dịch chuyển..." - unknown-material: "&eXin lỗi, tôi không thể nhận ra vật phẩm trong máy phân phát. - Vui lòng đặt thứ gì đó trong đó mà tôi biết." - wrong-item: "&eXin lỗi, tôi không thể nhận ra vật phẩm mà bạn nhấp chuột phải vào - tôi. Kiểm tra Công Thức và xem những vật phẩm nào bạn có thể sử dụng." + work-in-progress: Tính năng này vẫn chưa hoàn thành! messages: - cannot-place: "&cBạn không thể đặt khối ở đó!" - diet-cookie: "&eBạn đang bắt đầu cảm thấy rất nhẹ..." + not-researched: "&4Bạn không có đủ kiến thức để hiểu điều này" + not-enough-xp: "&4Bạn không có đủ kinh nghiệm để mở khóa" + unlocked: '&bBạn đã mở khóa &7"%research%"' + only-players: "&4Lệnh này chỉ dành cho người chơi" + unknown-player: "&4Người chơi chưa biết: &c%player%" + no-permission: "&4Bạn không có quyền để làm điều này" + usage: "&4Cách sử dụng: &c%usage%" + not-online: "&4%player% &cđang không trực tuyến!" + given-item: '&bBạn đã được nhận &a%amount% &7"%item%&7"' + give-item: '&bBạn đã gửi đến %player% &a%amount% &7"%item%&7"' + give-research: '&bBạn đã cho %player% nghiên cứu &7"%research%&7"' + hungry: "&cBạn quá đói để làm vậy!" disabled-in-world: "&4&lVật phẩm này đã bị vô hiệu hóa ở thế giới này!" disabled-item: "&4&lVật phẩm này đã bị vô hiệu hóa! Sao bạn có thể lấy được vật phẩm đó?" + no-tome-yourself: "&cBạn không thể sử dụng &4Bộ kiến thức &ccho chính bạn..." + multimeter: "&bNăng lượng được tích trữ: &3%stored% &b/ &3%capacity%" + talisman: + anvil: "&a&oBùa hộ mệnh của bạn đã lưu công cụ của bạn khỏi bị phá vỡ" + miner: "&a&oBùa hộ mệnh của bạn vừa nhân đôi vật phẩm rớt" + hunter: "&a&oBùa hộ mệnh của bạn vừa nhân đôi vật phẩm rớt" + lava: "&a&oBùa hộ mệnh của bạn cứu bạn khỏi bị thiêu chết" + water: "&a&oBùa hộ mệnh của bạn vừa cứu bạn khỏi đuối nước" + angel: "&a&oBùa hộ mệnh của bạn vừa cứu bạn khỏi bị sát thương khi rơi" + fire: "&a&oBùa hộ mệnh của bạn cứu bạn khỏi bị thiêu chết" + magician: "&a&oBùa hộ mệnh của bạn cho bạn một phù phép bổ sung" + traveller: "&a&oBùa hộ mệnh của bạn cho bạn hiệu ứng Chạy Nhanh" + warrior: "&a&oBùa hộ mệnh của bạn đã cải thiện Sức mạnh của bạn trong một thời + gian" + knight: "&a&oBùa hộ mệnh của bạn đã cho bạn 5 giây hiệu ứng Hồi Máu" + whirlwind: "&a&oBùa hộ mệnhcủa bạn phản lại Phát Bắn" + wizard: "&a&oBùa hộ mệnh của bạn đã cho bạn một Cấp độ may mắn tốt hơn nhưng cũng + có thể hạ thấp một số Cấp độ phù phép khác" + caveman: "&a&oBùa ma thuật của bạn cho bạn hiệu ứng Đào nhanh" + soulbound-rune: + fail: "&cBạn chỉ có thể liên kết một vật phẩm với linh hồn của bạn trong cùng + một thời điểm." + success: "&aBạn đã liên kết thành công vật phẩm với linh hồn của bạn! Bạn sẽ giữ + vật phẩm khi chết." + research: + start: "&7Các Linh Hồn Cổ Đại nói thì thầm những từ ngữ bí ẩn vào tai bạn! " + progress: "&7Bạn bắt đầu thắc mắc về: &b%research% &e(%progress%)" fire-extinguish: "&7Bạn đã tự dập tắt lửa chính bản thân" + cannot-place: "&cBạn không thể đặt khối ở đó!" + no-pvp: "&cBạn không thể đánh nhau ở đây!" + radiation: "&4Bạn đã tiếp xúc với bức xạ chết người! &cLoại bỏ vật phẩm phóng xạ + hoặc trang bị bộ đồ hazmat!" + opening-guide: "&bĐang mở hướng dẫn, việc này có thể mất một vài giây..." + opening-backpack: "&bĐang mở ba lô, việc này có thể mất một vài giây..." + no-iron-golem-heal: "&cĐây khỏi phải là Thỏi Sắt. Bạn không thể sử dụng thứ này + để hồi máu cho Người Khổng Lồ Sắt!" + link-prompt: "&eẤn vào đây:" + diet-cookie: "&eBạn đang bắt đầu cảm thấy rất nhẹ..." fortune-cookie: - "&7Cứu tôi, tôi bị bẫy trong một Nhà Máy Bánh Quy May Mắn" - "&7Bạn sẽ chết vào ngày mai... bởi Creeper" @@ -258,58 +166,207 @@ messages: - "&742. Câu trả lời là 42." - "&7Một Walshy mỗi ngày sẽ giữ những rắc rối đi." - "&7Không bao giờ đào thẳng xuống!" - give-item: '&bBạn đã gửi đến %player% &a%amount% &7"%item%&7"' - given-item: '&bBạn đã được nhận &a%amount% &7"%item%&7"' - give-research: '&bBạn đã cho %player% nghiên cứu &7"%research%&7"' - hungry: "&cBạn quá đói để làm vậy!" - link-prompt: "&eẤn vào đây:" - mode-change: "&b%device% đổi chế độ thành: &9%mode%" - multimeter: "&bNăng lượng được tích trữ: &3%stored% &b/ &3%capacity%" - no-iron-golem-heal: "&cĐây khỏi phải là Thỏi Sắt. Bạn không thể sử dụng thứ này - để hồi máu cho Người Khổng Lồ Sắt!" - no-permission: "&4Bạn không có quyền để làm điều này" - no-pvp: "&cBạn không thể đánh nhau ở đây!" - not-enough-xp: "&4Bạn không có đủ kinh nghiệm để mở khóa" - no-tome-yourself: "&cBạn không thể sử dụng &4Bộ kiến thức &ccho chính bạn..." - not-online: "&4%player% &cđang không trực tuyến!" - not-researched: "&4Bạn không có đủ kiến thức để hiểu điều này" - invalid-amount: "&4%amount% &ckhông hợp lệ : phải lớn hơn 0!" + - "&7Đó chỉ là một vết thương da thịt!" + - "&7Luôn nhìn theo hướng tích cực!" + - "&7 Cái này là bánh giòn chứ không phải bánh phồng" + - "&7Bảng đèn neon đẹp dữ!" invalid-item: "&4%item% &ckhông phải là vật phẩm hợp lệ!" + invalid-amount: "&4%amount% &ckhông hợp lệ : phải lớn hơn 0!" invalid-research: "&4%research% &ckhông phải là nghiên cứu hợp lệ!" - only-players: "&4Lệnh này chỉ dành cho người chơi" - opening-backpack: "&bĐang mở ba lô, việc này có thể mất một vài giây..." - opening-guide: "&bĐang mở hướng dẫn, việc này có thể mất một vài giây..." - radiation: "&4Bạn đã tiếp xúc với bức xạ chết người! &cLoại bỏ vật phẩm phóng xạ - hoặc trang bị bộ đồ hazmat!" - research: - progress: "&7Bạn bắt đầu thắc mắc về: &b%research% &e(%progress%)" - start: "&7Các Linh Hồn Cổ Đại nói thì thầm những từ ngữ bí ẩn vào tai bạn! " - soulbound-rune: - fail: "&cBạn chỉ có thể liên kết một vật phẩm với linh hồn của bạn trong cùng - một thời điểm." - success: "&aBạn đã liên kết thành công vật phẩm với linh hồn của bạn! Bạn sẽ giữ - vật phẩm khi chết." - talisman: - angel: "&a&oBùa hộ mệnh của bạn vừa cứu bạn khỏi bị sát thương khi rơi" - anvil: "&a&oBùa hộ mệnh của bạn đã lưu công cụ của bạn khỏi bị phá vỡ" - fire: "&a&oBùa hộ mệnh của bạn cứu bạn khỏi bị thiêu chết" - hunter: "&a&oBùa hộ mệnh của bạn vừa nhân đôi vật phẩm rớt" - knight: "&a&oBùa hộ mệnh của bạn đã cho bạn 5 giây hiệu ứng Hồi Máu" - lava: "&a&oBùa hộ mệnh của bạn cứu bạn khỏi bị thiêu chết" - magician: "&a&oBùa hộ mệnh của bạn cho bạn một phù phép bổ sung" - miner: "&a&oBùa hộ mệnh của bạn vừa nhân đôi vật phẩm rớt" - traveller: "&a&oBùa hộ mệnh của bạn cho bạn hiệu ứng Chạy Nhanh" - warrior: "&a&oBùa hộ mệnh của bạn đã cải thiện Sức mạnh của bạn trong một thời - gian" - water: "&a&oBùa hộ mệnh của bạn vừa cứu bạn khỏi đuối nước" - whirlwind: "&a&oBùa hộ mệnhcủa bạn phản lại Phát Bắn" - wizard: "&a&oBùa hộ mệnh của bạn đã cho bạn một Cấp độ may mắn tốt hơn nhưng cũng - có thể hạ thấp một số Cấp độ phù phép khác" - unknown-player: "&4Người chơi chưa biết: &c%player%" - unlocked: '&bBạn đã mở khóa &7"%research%"' - usage: "&4Cách sử dụng: &c%usage%" -miner: - no-ores: "&eXin lỗi, tôi không thể tìm bất kì Khoáng sản nào xung quanh!" + mode-change: "&b%device% đổi chế độ thành: &9%mode%" + piglin-barter: "&4Bạn không thể trao đổi với piglin bằng vật phẩm của Slimefun" + multi-tool: + mode-change: "&b%device% chế độ thay đổi thành: &9%mode%" + not-shears: "&cA Đa dụng cụ này không thể sử dụng như cái kéo!" + climbing-pick: + dual-wielding: "&4Bạn cần cầm Rìu leo ở cả 2 tay để dùng nó!" + wrong-material: "&cBạn không thể leo bề mặt này. Hãy xem hướng dẫn của Slimefun + để biết thêm!" + bee-suit-slow-fall: "&eCánh ong của bạn sẽ giúp bạn tiếp đất an toàn và chậm" + enchantment-rune: + fail: "&cBạn không thể phù phép vật phẩm này." + success: "&aBạn đã áp dụng thành công một loại phù phép ngẫu nhiên cho vật phẩm + này." + no-enchantment: "&cKhông thể tìm được bất kì loại phù phép nào phù hợp cho vật + phẩm" + tape-measure: + no-anchor: "&cBạn cần đặt neo trước khi có thể bắt đầu đo!" + wrong-world: "&cNeo của bạn dường như đang ở trong một thế giới khác!" + distance: |- + &7Đo lường được thực hiện. + &eKhoảng cách: %distance% + anchor-set: "&aĐặt thành công neo:&e%anchor%" +machines: + pattern-not-found: "&eXin lỗi, tôi không thể nhận ra Công Thức này. Vui lòng đặt + các vật phẩm với mẫu nhất định vào trong Máy Phân Phát." + unknown-material: "&eXin lỗi, tôi không thể nhận ra vật phẩm trong máy phân phát. + Vui lòng đặt thứ gì đó trong đó mà tôi biết." + wrong-item: "&eXin lỗi, tôi không thể nhận ra vật phẩm mà bạn nhấp chuột phải vào + tôi. Kiểm tra Công Thức và xem những vật phẩm nào bạn có thể sử dụng." + full-inventory: "&eXin lỗi, kho đồ của tôi đã quá đầy!" + in-use: "&cKhối trong túi đồ này hiện đang được mở bởi người chơi khác." + ignition-chamber-no-flint: "&cIgnition Chamber đang thiếu Bật Lửa." + ANCIENT_ALTAR: + not-enough-pedestals: "&4Bàn thờ không được bao quanh bởi số lượng cần thiết của + các bệ &c(%pedestals% / 8)" + unknown-catalyst: "&4Không rõ Chất Xúc Tác! &cSử dụng đúng công thức thay thế!" + unknown-recipe: "&4Không rõ Công Thức! &cSử dụng đúng công thức thay thế!" + ANCIENT_PEDESTAL: + obstructed: "&4Bệ bị cản trở! &cLoại bỏ bất kì thứ gì trên bệ!" + HOLOGRAM_PROJECTOR: + enter-text: "&7Vui lòng nhập Văn Bản Ba Chiều mong muốn của bạn vào Khung trò + chuyện. &r(Mã màu được hỗ trợ!)" + inventory-title: Trình chỉnh sửa ảnh ba chiều + ELEVATOR: + no-destinations: "&4Không tìm thấy điểm đến" + pick-a-floor: "&4- Chọn một tầng -" + current-floor: "&eĐây là tầng mà bạn hiện đang ở:" + click-to-teleport: "&eẤn &7để dịch chuyển đến tầng:" + enter-name: "&7Vui lòng nhập tên tầng mong muốn của bạn vào Khung trò chuyện. + &r(Mã màu được hỗ trợ)" + named: "&2Đặt tên thành công cho tầng này: &r%floor%" + TELEPORTER: + teleporting: "&3Đang dịch chuyển..." + teleported: "&3Đã dịch chuyển!" + cancelled: "&4Dịch chuyển bị hủy bỏ!" + invulnerability: "&b&lBạn đã được cho 30 giây Bất Tử!" + gui: + title: Địa điểm của bạn + tooltip: Bấm để dịch chuyển + time: Thời gian dự kiến + CARGO_NODES: + must-be-placed: "&4Phải được đặt trên hòm hoặc máy!" + GPS_CONTROL_PANEL: + title: GPS - Bảng điều khiển + transmitters: Tổng quan về các máy phát tín hiệu + waypoints: Tổng quan về các vị trí dịch chuyển + INDUSTRIAL_MINER: + no-fuel: "&cMáy đào công nghiệp của bạn hết nhiên liệu! Bỏ nhiên liệu vào rương + ở trên." + piston-facing: "&cMáy đào công nghiệp của bạn cần 2 pít-tông hướng lên trên!" + piston-space: "&cHai cái pít-tông cần hai khối không khí ở trên!" + destroyed: "&cMáy đào công nghiệp của bạn có vẻ như bị phá hủy." + already-running: "&cMáy đào công nghiệp này đang chạy!" + full-chest: "&cRương của máy đào công nghiệp đã đầy!" + no-permission: "&4Có vẻ như bạn không có quyền để sử dụng máy đào ở đây!" + finished: "&eMáy đào công nghiệp của bạn đã chạy xong! Nó đã đào được %ores% khoáng + sản(s)!" +anvil: + not-working: "&4Bạn không thể sử dụng vật phẩm Slimefun trên cái đê!" + mcmmo-salvaging: "&4Bạn không thể phục hồi giáp của Slimefun!" +backpack: + already-open: "&cXin lỗi, cái Ba lô này đã được mở ở một nơi nào khác!" + no-stack: "&cBạn không thể xếp nhiều Ba lô lại với nhau" workbench: not-enhanced: "&4Bạn không thể sử dụng vật phẩm Slimefun ở trên bàn làm việc thông thường" +gps: + deathpoint: "&4Điểm chết &7%date%" + waypoint: + new: "&eVui lòng nhập tên cho điểm tham chiếu mới của bạn trên khung chat. &7(Mã + màu được hỗ trợ!)" + added: "&aĐã thêm thành công một điểm tham chiếu mới" + max: "&4Bạn đã đạt đến số lượng điểm tham chiếu tối đa" + duplicate: "&4Bạn từng tạo vị trí dịch chuyển tên: &f%waypoint% &4rồi" + insufficient-complexity: + - "&4Độ phức tạp của mạng GPS không đủ: &c%complexity%" + - "&4a) Bạn chưa có thiết lập Mạng GPS" + - "&4b) Mạng GPS của bạn không đủ phức tạp" + geo: + scan-required: "&4Yêu cầu Quét GEO! &cQuét chunk này bằng Máy Quét GEO trước!" +inventory: + no-access: "&4Bạn không được phép truy cập vào khối này" +android: + started: "&7Thiết bị Android của bạn đã tiếp tục chạy đoạn mã của nó" + stopped: "&7Thiết bị Android của bạn đã dùng chạy đoạn mã của nó" + scripts: + already-uploaded: "&4Đoạn mã này đã được tải lên." + instructions: + START: "&2Bắt đầu chạy Đoạn Mã" + REPEAT: "&9Lặp lại Đoạn Mã" + WAIT: "&eĐợi 0.5s" + GO_FORWARD: "&7Đi thẳng" + GO_UP: "&7Đi lên" + GO_DOWN: "&7Đi xuống" + TURN_LEFT: "&7Rẽ trái" + TURN_RIGHT: "&7Rẽ phải" + DIG_UP: "&bĐào lên" + DIG_FORWARD: "&bĐào thẳng" + DIG_DOWN: "&bĐào xuống" + MOVE_AND_DIG_UP: "&bDi chuyển và đào lên" + MOVE_AND_DIG_FORWARD: "&bDi chuyển và đào thẳng" + MOVE_AND_DIG_DOWN: "&bDi chuyển và đào xuống" + ATTACK_MOBS_ANIMALS: "&4Tấn công &c(Mob và Động vật hung giữ)" + ATTACK_MOBS: "&4Tấn công &c(Các mob hung dữ)" + ATTACK_ANIMALS: "&4Tấn công &c(Động vật)" + ATTACK_ANIMALS_ADULT: "&4Tấn công &c(Động vật &7[Trường thành]&c)" + CHOP_TREE: "&cChặt và trồng lại" + CATCH_FISH: "&bBắt cá" + FARM_FORWARD: "&bThu hoạch và trồng lại" + FARM_DOWN: "&bThu hoạch và trồng lại &7(Khối bên dưới)" + FARM_EXOTIC_FORWARD: "&bThu hoạch và thay thế nâng cao" + FARM_EXOTIC_DOWN: "&bThu hoạch và thay thế nâng ca o&7(Khối ở dưới)" + INTERFACE_ITEMS: "&9Đẩy nội dung túi đồ lên giao diện" + INTERFACE_FUEL: "&cKéo nhiên liệu từ giao diện" + enter-name: + - + - "&eVui lòng nhập tên cho đoạn mã của bạn" + uploaded: + - "&bĐang tải lên..." + - "&aTải đoạn mã lên thành công!" + rating: + own: "&4Bạn không thể xếp hạng đoạn mã của chính mình!" + already: "&4Bạn đã để lại Xếp Hạng cho đoạn mã này!" + editor: Trình chỉnh sửa kịch bản +languages: + default: Máy chủ-Mặc định + en: Tiếng Anh + de: Tiếng Đức + fr: Tiếng Pháp + it: Tiếng Ý + es: Tiếng Tây Ban Nha + pl: Tiếng Ba Lan + sv: Tiếng Thụy Điển + nl: Tiếng Hà Lan + cs: Tiếng Séc + hu: Tiếng Hungary + lv: Tiếng Latvia + ru: Tiếng Nga + sk: Tiếng Slovak + zh-TW: Tiếng Trung Quốc (Đài Loan) + vi: Tiếng Việt + id: Tiếng Indonesia + zh-CN: Tiếng Trung (Trung Quốc) + el: Tiếng Hy Lạp + he: Tiếng Do Thái + pt: Tiếng Bồ Đào Nha (Bồ Đào Nha) + pt-BR: Tiếng Bồ Đào Nha (Brazil) + ar: Tiếng Ả Rập + af: Tiếng Nam Phi + da: Tiếng Đan Mạch + fi: Tiếng Phần Lan + uk: Tiếng Ukraina + ms: Tiếng Mã Lai + 'no': Tiếng Na Uy + ja: Tiếng Nhật + fa: Tiếng Ba Tư + th: Tiếng Thái + ro: Tiếng Rumani + bg: Tiếng Bulgaria + ko: Tiếng Hàn + tr: Tiếng Thổ Nhĩ Kỳ + hr: Tiếng Croatia + mk: Tiếng Macedonia + sr: Tiếng Serbia + be: Tiếng Bêlarut + tl: Tiếng Filipino +miner: + no-ores: "&eXin lỗi, tôi không thể tìm bất kì Khoáng sản nào xung quanh!" +villagers: + no-trading: "&4Bạn không thể trao đổi các vật phẩm Slimefun với dân làng!" +cartography_table: + not-working: "&4Bạn không thể sử dụng vật phẩm sủa Slimefun trong bàn sửa bản đồ" +cauldron: + no-discoloring: "&4Bạn không thể đổi màu giáp của Slimefun" +brewing_stand: + not-working: "&4Bạn không thể sử dụng các vật phẩm Slimefun trong quầy pha chế thuốc!" diff --git a/src/main/resources/languages/messages_zh-CN.yml b/src/main/resources/languages/messages_zh-CN.yml index d49cafb64..2421eab20 100644 --- a/src/main/resources/languages/messages_zh-CN.yml +++ b/src/main/resources/languages/messages_zh-CN.yml @@ -1,12 +1,11 @@ --- commands: - help: 展示此帮助页面 - cheat: 使用作弊模式获取 Slimefun 的物品 - give: 给某人 Slimefun 物品 - guide: 给你自己一本 Slimefun 指南 - timings: 查看关于 Slimefun 的耗能信息 - teleporter: 查看其他玩家的公开传送点 - versions: 列出已安装的扩展插件 + help: 显示此帮助 + cheat: 直接拿取 Slimefun 物品 + give: 给予玩家 Slimefun 物品 + guide: 获取一本 Slimefun 指南书 + teleporter: 查看其他玩家的公共传送点 + versions: 显示 Slimefun 运行环境 search: 搜索 Slimefun 物品 open_guide: 使用命令打开 Slimefun 指南 stats: 查看玩家的统计数据 @@ -24,9 +23,14 @@ commands: description: 为你手持的物品充电 charge-success: 充电完成! not-rechargeable: 这个物品不能充电! + timings: + description: Slimefun 及其附属插件的性能报告 + please-wait: "&e请稍等一会...结果马上就来!" + verbose-player: "&4该标记不能对玩家使用!" + unknown-flag: "&4未知标记: &c%flag%" guide: search: - message: "&b你想要搜索什么?" + message: "&b今天要搜些什么?" name: "&7搜索..." tooltip: "&b单击搜索物品" inventory: '正在搜索: %item%' @@ -34,28 +38,28 @@ guide: - "&b你想要搜索什么?" - "&7将要搜索的物品的名字输入在聊天栏上" cheat: - no-multiblocks: "&4你不能在作弊模式下直接获得多方块结构的机器, 你必须自己建造!" + no-multiblocks: "&4你不能在作弊模式下获得多方块结构的机器, 必须按书中所示建造!" languages: - updated: "&a你的语言已设为: &b%lang%" + updated: "&a成功修改语言为: &b%lang%" translations: name: "&a少了些什么?" lore: 单击添加你自己的翻译 select: 单击选中此语言 select-default: 单击选中默认语言 selected-language: '目前使用的语言:' - change: 单击选择新的语言 + change: 单击选择要更改的语言 description: - - "&7现在你有了修改 Slimefun" - - "&7展示给你的文本语言选项了." - - "&7物品中的文本" - - "&7还不能够修改." + - "&7现在你可以修改 Slimefun" + - "&7展示的文本消息的语言了." + - "&7注意: 物品中的文本" + - "&7暂时无法修改." title: main: Slimefun 指南 - settings: 设置 & 关于 - languages: 选择你想要的语言 + settings: 设置 & 详情 + languages: 选择你想要更改的语言 credits: Slimefun4 贡献者 wiki: Slimefun4 维基 - addons: Slimefun4 扩展 + addons: Slimefun4 附属插件 bugs: 问题反馈 source: 源代码 versions: 安装的版本 @@ -67,8 +71,8 @@ guide: wiki: "&3Wiki 编辑者" resourcepack: "&c材质制作者" translator: "&9翻译者" - profile-link: 单击访问TA们的 Github 个人主页 - open: 单击查看我们的贡献者 + profile-link: 单击访问他们的 Github 个人主页 + open: 单击查看贡献者名单 description: - "&7Slimefun 是一个开源的项目" - "&7并且由玩家社区维护." @@ -84,7 +88,7 @@ guide: recipes: machine: 此机器可用的合成配方 miner: 此采矿机可以获得的资源 - generator: 可用的燃料种类 + generator: 可用的燃料类型 gold-pan: 你可以获得的资源 climbing-pick: 你可以攀爬的平面 back: @@ -96,14 +100,14 @@ guide: - 为了解锁这一类别 - 你需要先解锁以下 - 类别里的所有物品 - work-in-progress: 这个功能还没完全做完! + work-in-progress: 该功能暂未推出! messages: - not-researched: "&4你没有足够的学识来理解它" + not-researched: "&4你的知识还不足以理解这个物品" not-enough-xp: "&4你没有足够的经验来解锁这个研究" unlocked: '&b成功解锁研究 &7"%research%"' only-players: "&4这个指令只能在游戏内使用" unknown-player: "&4未知玩家: &c%player%" - no-permission: "&4你没有足够的权限做这个" + no-permission: "&4你没有足够的权限这么做" usage: "&4用法: &c%usage%" not-online: "&4%player% &c不在线" given-item: '&b你获得了 &a%amount% &7"%item%&7"' @@ -123,25 +127,25 @@ messages: angel: "&a&o你的护身符使你在信仰之跃时不受伤害" fire: "&a&o你的护身符使你免受火焰伤害" magician: "&a&o你的护身符赠送了你额外的附魔" - traveller: "&a&o你的护身符让你跑起来更快了" - warrior: "&a&o你的护身符使你在一段时间内变强了" + traveller: "&a&o你的护身符让你跑得更快了" + warrior: "&a&o你的护身符使你变强了" knight: "&a&o你的护身符给予了你 5 秒的生命恢复" - whirlwind: "&a&o你的护身符反弹了所有的弹射物" - wizard: "&a&o你的护身符使一个附魔的等级提高了, 同时其他附魔等级将会下降" + whirlwind: "&a&o你的护身符反弹了所有射向你的投掷物" + wizard: "&a&o你的护身符随机提高了一个附魔的等级, 但其他的附魔等级将会下降" caveman: "&a&o你的护身符给予了你急迫效果" soulbound-rune: - fail: "&c一次只能灵魂绑定一个物品." + fail: "&c灵魂一次只能绑定一个物品." success: "&a物品绑定成功! 在你死亡后此物品将不会掉落." research: - start: "&7古老的灵魂正向你诉说神秘的话语!" - progress: "&7你开始慢慢理解研究 &b%research% &e(%progress%)" + start: "&7古老的灵魂正向你低语其中的神秘!" + progress: "&7你逐渐开始理解研究 &b%research% &e(%progress%)" fire-extinguish: "&7你灭掉了身上的火" cannot-place: "&c你不能在这里放置方块!" - no-pvp: "&c你不能在这里 PVP!" + no-pvp: "&c你不能在这里攻击其他玩家!" radiation: "&4你已经暴露在致命的辐射之下! &c快把辐射物品丢掉或者穿上防化服!" opening-guide: "&b正在打开指南书, 请稍等..." opening-backpack: "&b正在打开背包, 请稍等...." - no-iron-golem-heal: "&c这不是铁锭. 你不能用这个治疗铁傀儡!" + no-iron-golem-heal: "&c这不是铁锭. 不能用来治疗铁傀儡!" link-prompt: "&e单击此处:" diet-cookie: "&e你感觉变轻了..." fortune-cookie: @@ -159,7 +163,7 @@ messages: - "&7要总是看着生活中光明的一面!" - "&7这一块其实是饼干而不是曲奇" - "&7霓虹灯亮起来了!" - piglin-barter: "&4你不能使用 Slimefun 的物品和猪灵以物换物" + piglin-barter: "&4你不能使用 Slimefun 的物品和猪灵易物" enchantment-rune: fail: "&c你不能附魔这个物品." no-enchantment: "&c无法找到此物品可用的附魔属性." @@ -167,21 +171,21 @@ messages: tape-measure: no-anchor: "&c在开始测量之前请先选定测量起点!" wrong-world: "&c你设置的起点似乎在另一个世界!" - distance: "&7已测量到距离, &e为: %distance%" + distance: "&7距离已测量, &e为: %distance%" anchor-set: "&a成功在 &e %anchor% &a设置了测量起点" multi-tool: mode-change: "&b%device% 的模式已切换为: &9%mode%" - not-shears: "&c多功能工具 (Multi Tool) 不能当成剪刀来用!" + not-shears: "&c多功能工具 (Multi Tool) 不能作为剪刀使用!" climbing-pick: dual-wielding: "&4你需要双手拿着攀岩镐才能使用!" - wrong-material: "&c你不能爬上这个平面. 查看指南书了解更多!" + wrong-material: "&c你不能爬上这个平面. 查看指南书了解详情!" invalid-item: "&4%item% &c不是一个有效的物品名!" invalid-amount: "&4%amount% &ci不是一个有效的数字 : 它必须大于 0!" invalid-research: "&4%research% &c不是一个有效的研究名!" - bee-suit-slow-fall: "&e你的蜂翅会让你安全且缓慢地回到地面" + bee-suit-slow-fall: "&e你的蜂翅将会让你安全缓降" mode-change: "&b%device% 的模式已切换为: &9%mode%" machines: - pattern-not-found: "&e抱歉, 你记错合成表了吧. 这不是一个正确的合成配方, 请检查发射器里放置物品的顺序." + pattern-not-found: "&e抱歉, 这不是正确的合成配方, 请检查发射器里放置物品的顺序." unknown-material: "&e抱歉, 我无法识别在发射器里的物品. 请按照合成配方放置物品." wrong-item: "&e抱歉, 我无法识别你右键的物品. 检查指南书看看哪些物品可以使用." full-inventory: "&e抱歉, 物品栏已经满了!" @@ -190,14 +194,14 @@ machines: ANCIENT_ALTAR: not-enough-pedestals: "&4古代基座不足. 目前已摆放的基座数: &c(%pedestals% / 8)" unknown-catalyst: "&4无效的催化剂! &c请按照合成配方正确摆放物品!" - unknown-recipe: "&4未知合成表! &c请使用正确的合成配方!" + unknown-recipe: "&4未知合成表! &c请按照合成配方正确摆放物品!" ANCIENT_PEDESTAL: obstructed: "&4基座被挡住了! &c把基座上面的东西移开!" HOLOGRAM_PROJECTOR: enter-text: "&7请写下想显示在全息文本上的话. &r(支持颜色代码)" inventory-title: 全息图像编辑器 ELEVATOR: - no-destinations: "&4找不到目的地" + no-destinations: "&4找不到上下楼" pick-a-floor: "&3- 选择一个楼层 -" current-floor: "&e你现在所在的楼层:" click-to-teleport: "&e单击 &7传送至楼层:" @@ -213,10 +217,10 @@ machines: tooltip: 单击传送 time: 预计时间 CARGO_NODES: - must-be-placed: "&4必须放置在箱子或机器上!" + must-be-placed: "&4货运节点必须放置在箱子或机器上!" GPS_CONTROL_PANEL: title: GPS - 控制面板 - transmitters: 信号发射器概览 + transmitters: 信号发射机详情 waypoints: 传送点列表 INDUSTRIAL_MINER: no-fuel: "&c你的工业矿机没有燃料了! 将燃料放入它上面的箱子里." @@ -225,7 +229,7 @@ machines: destroyed: "&c你的工业矿机被拆除了." already-running: "&c这个工业矿机正在运行!" full-chest: "&c你的工业矿机的箱子已经满了!" - no-permission: "&4你没有权限在此操作此工业矿机!" + no-permission: "&4你没有权限操作这台工业矿机!" finished: "&e你的工业矿机采矿已完成! 总共开采了 %ores% 个矿石!" anvil: not-working: "&4你不能在铁砧里使用 Slimefun 的物品" @@ -236,14 +240,14 @@ backpack: workbench: not-enhanced: "&4你不能在普通的工作台上使用 Slimefun 物品" gps: - deathpoint: "&4死亡地点 &7%date%" + deathpoint: "&4死亡点 &7%date%" waypoint: new: "&e给你的路径点起个名字吧 &7(支持彩色代码!)" added: "&a成功添加了新的传送点" max: "&4你已到达设置传送点个数的最大上限" - duplicate: "&4你已经创建了一个相同名字的传送点了: &f%waypoint%" + duplicate: "&4已经有相同名字的传送点了: &f%waypoint%" insufficient-complexity: - - "&4GPS网络复杂度不足: &c%complexity%" + - "&4GPS 网络复杂度不足: &c%complexity%" - "&4a) 你还没有设置一个 GPS 网络" - "&4b) 你的 GPS 网络复杂度不够, 多放置几个 GPS 信号发射机" geo: @@ -251,10 +255,10 @@ gps: inventory: no-access: "&4你没有权限使用这个方块" android: - started: "&7你的机器人开始运行脚本" - stopped: "&7你的机器人暂停运行了脚本" + started: "&7机器人正在依照脚本运行" + stopped: "&7机器人停止了运行" scripts: - already-uploaded: "&4这个脚本已经上传过了." + already-uploaded: "&4你已经上传过这个脚本了." instructions: START: "&2运行脚本" REPEAT: "&9重复运行脚本" @@ -278,8 +282,8 @@ android: CATCH_FISH: "&b钓鱼" FARM_FORWARD: "&b自动采收并补种作物" FARM_DOWN: "&b自动采收并补种下面的作物" - FARM_EXOTIC_FORWARD: "&b自动采收并补种作物 &7(支持异域花园植物)" - FARM_EXOTIC_DOWN: "&b自动采收并补种下面的作物 &7(支持异域花园植物)" + FARM_EXOTIC_FORWARD: "&b自动采收并补种所有作物" + FARM_EXOTIC_DOWN: "&b自动采收并补种下面的所有作物" INTERFACE_ITEMS: "&9将物品栏里的物品放入面前的容器" INTERFACE_FUEL: "&c从面前的容器中拿出燃料" enter-name: @@ -313,7 +317,6 @@ languages: zh-CN: 简体中文 (中国) el: 希腊语 he: 希伯来语 - pt: 葡萄牙语 (葡萄牙) ar: 阿拉伯语 af: 南非语 da: 丹麦语 @@ -325,6 +328,7 @@ languages: fa: 波斯语 th: 泰语 ro: 罗马尼亚语 + pt: 葡萄牙语 (葡萄牙) pt-BR: 葡萄牙语 (巴西) bg: 保加利亚语 ko: 韩语 @@ -341,6 +345,6 @@ villagers: cartography_table: not-working: "&4你不能在制图台中使用 Slimefun 物品!" cauldron: - no-discoloring: "&4你不能用炼药锅清洗 Slimefun 物品上的颜色" + no-discoloring: "&4你不能用炼药锅洗去 Slimefun 物品的颜色" miner: no-ores: "&e抱歉, 周围找不到矿石了!" diff --git a/src/main/resources/languages/messages_zh-TW.yml b/src/main/resources/languages/messages_zh-TW.yml index 164f90b89..e40aa80a3 100644 --- a/src/main/resources/languages/messages_zh-TW.yml +++ b/src/main/resources/languages/messages_zh-TW.yml @@ -2,17 +2,16 @@ commands: help: 顯示此幫助畫面 cheat: 允許您以作弊取得物品 - give: 給其他玩家Slimefun物品 - guide: 給自己一個Slimefun指南 - timings: 關於您的伺服器的卡頓信息 + give: 給其他玩家 Slimefun 物品 + guide: 給自己一個 Slimefun 指南 teleporter: 查看其他玩家的位置標點 versions: 列出所有已安裝的附屬插件 search: 在指南中搜索輸入的字句 - open_guide: 打開Slimefun指南(不使用書本) + open_guide: 打開 Slimefun 指南(不使用書本) stats: 顯示玩家的統計數據 research: description: 解鎖/重置玩家的研究項目 - reset: "&c你已使%player%變回笨蛋" + reset: "&c你已使 %player% 變回笨蛋" reset-target: "&c你變回笨蛋了" backpack: description: 檢索已存在背包的副本 @@ -24,6 +23,11 @@ commands: description: 為你手中的物品充電 charge-success: 此物品已充電完成! not-rechargeable: 此物品不可被充電! + timings: + description: Slimefun 及其附屬插件的耗能 + please-wait: "&e請稍等⋯⋯結果快出來了!" + verbose-player: "&4玩家不能使用「詳細資訊」標號!" + unknown-flag: "&4未知標號:&c%flag%" guide: search: message: "&c你要搜尋什麼?" @@ -50,10 +54,10 @@ guide: - "&7不過科技物品礙於技術" - "&7暫時沒有辦法翻譯" title: - main: Slimefun指南 + main: Slimefun 指南 settings: 設置及資訊 languages: 請選擇您偏好的語言 - credits: Slimefun4貢獻者 + credits: Slimefun4 貢獻者 wiki: Slimefun4 Wiki addons: Slimefun4的附加插件 bugs: 錯誤報告 @@ -100,15 +104,15 @@ guide: messages: not-researched: "&4你還沒有足夠的知識" not-enough-xp: "&4你沒有足夠的經驗值來解鎖這個" - unlocked: "&b你已解鎖&7“%research%”" + unlocked: "&b你已解鎖 &7“%research%”" only-players: "&4此命令只可由玩家發送" unknown-player: "&4未知玩家:&c%player%" no-permission: "&4您沒有執行此動作所需的權限" usage: "&4用法:&c%usage%" not-online: "&4%player% &c 還未上線!" given-item: '&b你已獲得 &a%amount% &7"%item%&7"' - give-item: '&b你已給予%player% &a%amount% &7"%item%&7"' - give-research: '&b你已給予%player% 研究項目&7"%research%&7"' + give-item: '&b你已給予 %player% &a%amount% &7"%item%&7"' + give-research: '&b你已給予 %player% 研究項目&7"%research%&7"' hungry: "&c你太餓了,做不了這個!" disabled-in-world: "&4&l此物品在此世界中已被禁用" disabled-item: "&4&l此物品已被禁用!你到底是怎樣得到的?" @@ -123,9 +127,9 @@ messages: angel: "&a&o你的護符使你免疫摔落傷害" fire: "&a&o你的護符將你從燒死邊緣中救回" magician: "&a&o你的護符給了你額外的附魔" - traveller: "&a&o你的護符給了你速度3" + traveller: "&a&o你的護符給了你速度 3" warrior: "&a&o你的護符暫時提高了你的力量" - knight: "&a&o你的護符給了你5秒的回復時間" + knight: "&a&o你的護符給了你 5 秒的回復時間" whirlwind: "&a&o你的護符反射了投射物" wizard: "&a&o你的護符為你升高了幸運等級,但也降低了其他附魔等級" caveman: "&a&o你的護符給了你挖掘加速效果" @@ -134,16 +138,16 @@ messages: success: "&a您已成功將此物品綁定靈魂!死後不會掉落。" research: start: "&7遠古之靈在你耳邊低語!" - progress: "&7你開始研究&b%research% &e(%progress%)" + progress: "&7你開始研究 &b%research% &e(%progress%)" fire-extinguish: "&7你熄滅了身上的火焰" cannot-place: "&c不能在那裡放置方塊!" no-pvp: "&c這裡不准打架!" radiation: "&4你正暴露在致命的輻射之下!&c立即丟棄放射性物品或裝備完整的防護服!" opening-guide: "&b正在打開指南,這可能需要幾秒鐘的時間..." opening-backpack: "&b正在打開背包,這可能需要幾秒鐘的時間..." - no-iron-golem-heal: "&c這不是鐵錠。你不能用它來治癒鐵巨人!" + no-iron-golem-heal: "&c這不是鐵錠。你不能用它來治療鐵巨人!" link-prompt: "&e點擊此處:" - diet-cookie: "&e你開始覺得很輕..." + diet-cookie: "&e你開始覺得很輕⋯⋯" fortune-cookie: - "&7快來幫幫我!我被困在幸運餅乾工廠裡!" - "&7明天會有苦力怕歡樂送" @@ -153,7 +157,7 @@ messages: - "&7你死前聽到的最後一句話會是「殲滅他」!!!" - "&7不要試著擁抱苦力怕...我試過,感覺還不錯,但是不值得。" - "&742, 答案是 42。" - - "&7一天一Walshy,煩惱遠離你。\n" + - "&7一天一 Walshy,煩惱遠離你。\n" - "&7永遠不要垂直往下挖!" - "&7這只是一個小傷!" - "&7永遠保持樂觀積極!" @@ -177,7 +181,7 @@ messages: wrong-material: "&c你無法攀爬這種平面。使用你的科技指南書以獲取更多資訊!" invalid-item: "&4%item% &c不存在!" invalid-amount: "&4%amount% &c不是有效數量:數值必須大於 0!" - invalid-research: "&4%research% &c不存在!" + invalid-research: "&4%research% &c不存在!" bee-suit-slow-fall: "&e你的蜂翅將會幫你緩慢且安全的回到地面" mode-change: "&b%device% 模式切換至: &9%mode%" machines: @@ -207,7 +211,7 @@ machines: teleporting: "&3傳送中..." teleported: "&3傳送成功!" cancelled: "&4傳送中止!" - invulnerability: "&b&l你得到了30秒的無敵!" + invulnerability: "&b&l你得到了 30 秒的無敵!" gui: title: 你的標記點 tooltip: 點擊以傳送 @@ -243,9 +247,9 @@ gps: max: "&4傳送點已達上限" duplicate: "&4已經有叫作 &f%waypoint% &4的傳送點了" insufficient-complexity: - - "&4GPS訊號不足:&c%complexity%" - - "&4a) GPS基礎設施未放置" - - "&4b) GPS訊號不足" + - "&4GPS 訊號不足:&c%complexity%" + - "&4a) GPS 基礎設施未放置" + - "&4b) GPS 訊號不足" geo: scan-required: "&4請先做地質掃描" inventory: @@ -258,7 +262,7 @@ android: instructions: START: "&2執行程式" REPEAT: "&9重複程式" - WAIT: "&e等0.5秒" + WAIT: "&e等待 0.5 秒" GO_FORWARD: "&7向前移動" GO_UP: "&7向上移動" GO_DOWN: "&7向下移動" @@ -313,7 +317,7 @@ languages: zh-CN: 中文(簡體) el: 希臘語 he: 希伯來語 - pt-BR: 葡萄牙文(巴西) + pt: 葡萄牙文(葡萄牙) ar: 阿拉伯文 af: 南非語 da: 丹麥文 @@ -325,7 +329,7 @@ languages: fa: 波斯語 th: 泰語 ro: 羅馬尼亞語 - pt: 葡萄牙文(葡萄牙) + pt-BR: 葡萄牙文(巴西) bg: 保加利亞語 ko: 韓語 tr: 土耳其 diff --git a/src/main/resources/languages/recipes_bg.yml b/src/main/resources/languages/recipes_bg.yml new file mode 100644 index 000000000..1fa0e1130 --- /dev/null +++ b/src/main/resources/languages/recipes_bg.yml @@ -0,0 +1,168 @@ +--- +slimefun: + multiblock: + name: Multiblock + lore: + - Постройте показаната структура + - както е показана. Не се craft-ва. + enhanced_crafting_table: + name: Enhanced Crafting Table + lore: + - Направете този Предмет, както е показано + - в Enhanced Crafting Table. + - Нормален Crafting Table(Работна Маса) няма да е достатъчен! + armor_forge: + name: Armor Forge + lore: + - Направете този Предмет, както е показано + - използвайки Armor Forge + grind_stone: + name: Grind Stone + lore: + - Направете този Предмет, както е показано + - използвайки Grind Stone + smeltery: + name: Smeltery + lore: + - Направете този Предмет, както е показано + - използвайки Smeltery + ore_crusher: + name: Ore Crusher + lore: + - Направете този Предмет, както е показано + - използвайки Ore Crusher + mob_drop: + name: Mob Drop + lore: + - Убийте този Mob, за да + - получите този предмет + gold_pan: + name: Gold Pan + lore: + - Използвайте Gold Pan, за да + - получите този предмет + compressor: + name: Compressor + lore: + - Направете този Предмет, както е показано + - използвайки Compressor + pressure_chamber: + name: Pressure Chamber + lore: + - Направете този Предмет, както е показано + - използвайки Pressure Chamber + ore_washer: + name: Ore Washer + lore: + - Направете този Предмет, както е показано + - използвайки Ore Washer + juicer: + name: Juicer + lore: + - Направете този Предмет, както е показано + - използвайки Juicer + magic_workbench: + name: Magic Workbench + lore: + - Направете този Предмет, както е показано + - използвайки Magic Workbench + ancient_altar: + name: Ancient Altar + lore: + - Направете този Предмет, както е показано + - използвайки Ancient Altar. + - Вижте Ancient Altar за повече информация + heated_pressure_chamber: + name: Heated Pressure Chamber + lore: + - Направете този Предмет, както е показано + - използвайки Heated Pressure Chamber + food_fabricator: + name: Food Fabricator + lore: + - Направете този Предмет, както е показано + - използвайки Food Fabricator + food_composter: + name: Food Composter + lore: + - Направете този Предмет, както е показано + - използвайки Food Composter + freezer: + name: Freezer + lore: + - Направете този Предмет, както е показано + - използвайки Freezer + geo_miner: + name: GEO Miner + lore: + - Този Предмет може да бъде събран + - като използвате GEO Miner + nuclear_reactor: + name: Nuclear Reactor + lore: + - Този Предмет е вторичен-продукт + - направен от Nuclear Reactor + oil_pump: + name: Oil Pump + lore: + - Този Предмет може да бъде събран + - като използвате Oil Pump + pickaxe_of_containment: + name: Pickaxe of Containment + lore: + - Този Блок може да бъде получен + - като изкопаете Spawner(Спаунер) с + - предмета Pickaxe of Containment + refinery: + name: Refinery + lore: + - Направете този Предмет, както е показано + - използвайки Refinery + barter_drop: + name: Piglin Bartering Drop + lore: + - Търгувайте с Piglins(Пиглини), като използвате + - Gold Ingots(Златни Кюлчета), за да получите този Предмет +minecraft: + shaped: + name: Shaped Crafting Recipe + lore: + - Направете този Предмет, както е показано + - в нормалния Crafting Table(Работна Маса). + - Формата е много важна. + shapeless: + name: Shapeless Crafting Recipe + lore: + - Направете този Предмет, както е показано + - в нормалния Crafting Table(Работна Маса). + - Тази Рецепта е безформена. + furnace: + name: Furnace Recipe + lore: + - Изпечете този предмет в Furnace(Печка) + - за да си направите желания предмет + blasting: + name: Blast Furnace Recipe + lore: + - Изпечете този предмет в Blast Furnace(Бласт Печка) + - за да си направите желания предмет + smoking: + name: Smoker Recipe + lore: + - Изпечете този предмет в Smoker(Упошвател) + - за да си направите желания предмет + campfire: + name: Campfire Recipe + lore: + - Изпечете този предмет върху Campfire(Огън) + - за да си направите желания предмет + stonecutting: + name: Stonecutter Recipe + lore: + - Направете този Предмет, както е показано + - използвайки Stonecutter + smithing: + name: Smithing Table Recipe + lore: + - Направете този Предмет, както е показано + - използвайки Smithing Table diff --git a/src/main/resources/languages/recipes_ja.yml b/src/main/resources/languages/recipes_ja.yml index 3a482d34f..59bb7f584 100644 --- a/src/main/resources/languages/recipes_ja.yml +++ b/src/main/resources/languages/recipes_ja.yml @@ -118,6 +118,11 @@ slimefun: lore: - このアイテムの作成に使用する - '機械: Refinery' + barter_drop: + name: ピグリンとの物々交換 + lore: + - このアイテムは金インゴットを + - ピグリンとの物々交換で入手 minecraft: shaped: name: 定形レシピ diff --git a/src/main/resources/languages/researches_fr.yml b/src/main/resources/languages/researches_fr.yml index 673bb4c2f..89963d86b 100644 --- a/src/main/resources/languages/researches_fr.yml +++ b/src/main/resources/languages/researches_fr.yml @@ -246,3 +246,5 @@ slimefun: caveman_talisman: Talisman de l'Homme des cavernes even_higher_tier_capacitors: Condensateurs de niveau 3 elytra_cap: Matériel d'urgence + energy_connectors: Connexions filaires + bee_armor: Armure d'abeille diff --git a/src/main/resources/languages/researches_vi.yml b/src/main/resources/languages/researches_vi.yml index 0cbcdb939..e6259c773 100644 --- a/src/main/resources/languages/researches_vi.yml +++ b/src/main/resources/languages/researches_vi.yml @@ -1,232 +1,250 @@ --- slimefun: - 24k_gold_block: Thành phố Vàng - advanced_android: Android nâng cao - advanced_circuit_board: Bảng mạch tiên tiến - advanced_electric_smeltery: Lò rèn điện nâng cao - advanced_farmer_android: Android nâng cao - Nông phu - advanced_output_node: Nút đầu ra nâng cao - alloys: Hợp kim cao cấp - ancient_altar: Tế đài cổ đại - ancient_runes: Ngọc nguyên tố - android_interfaces: Giao diện Android - android_memory_core: Lõi máy móc - angel_talisman: Bùa hộ mệnh thiên sứ - animal_growth_accelerator: Máy tăng trưởng động vật - anvil_talisman: Bùa hộ mệnh của cái đe - armored_jetboots: Giày thép phản lực - armored_jetpack: Giáp phản lực - armor_forge: Bàn chế tạo giáp - auto_anvil: Đe tự động - auto_breeder: Máy cho ăn tự động - auto_drier: Một Ngày Khô ráo - auto_enchanting: Phù phép tự động - automated_crafting_chamber: Chế tạo tự động - automated_panning_machine: Sàng vàng Tự động - automatic_ignition_chamber: Máy đánh lửa tự động - backpacks: Ba lô - basic_circuit_board: Bảng mạch cơ bản - battery: Viên Pin đầu tiên của bạn - better_carbon_press: Máy ép carbon nâng cấp - better_crop_growth_accelerator: Máy tăng tưởng cây trồng nâng cấp - better_electric_crucibles: Máy nung đồ nóng - better_electric_furnace: Lò nung điện nâng cấp - better_food_fabricator: Máy chế tạo thực phẩm nâng cấp - better_freezer: Máy làm lạnh nâng cấp - better_gps_transmitters: Máy phát được nâng cấp - better_heated_pressure_chamber: Máy áp suất nâng cấp - better_solar_generators: Máy phát điện được nâng cấp - bio_reactor: Lò phản ứng sinh học - blade_of_vampires: Gươm ma cà rồng - blistering_ingots: Chất phóng xạ Blistering - block_placer: Máy đặt khối - boosted_uranium: Vòng tròn không kết thúc - boots_of_the_stomper: Giày cao cổ - bound_armor: Giáp linh hồn - bound_backpack: Balo Linh hồn - bound_tools: Dụng cụ linh hồn - bound_weapons: Vũ khí linh hồn - bronze: Tác phẩm đồng - cactus_armor: Bộ đồ xương rồng - capacitors: Tụ điện cấp 1 - carbonado: Kim cương đen - carbonado_furnace: Lò nung cạnh carbon - carbonado_tools: Công cụ kim cương đen - carbon_press: Máy ép carbon - cargo_basics: Máy dịch chuyển đồ cơ bản - cargo_nodes: Thiết lập máy dịch chuyển đồ - charging_bench: Bàn sạc - coal_generator: Máy phát điện bằng than - cobalt_pickaxe: Cúp nhanh nhẹn - combustion_reactor: Lò phản ứng đốt cháy - common_talisman: Bùa hộ mệnh thông thường - composter: Khùng tổng hợp - compressor_and_carbon: Tác phẩm Carbon - cooler: Máy uống di động - copper_wire: Dây dẫn điện đồng - crop_growth_accelerator: Máy tăng trưởng cây trồng - crucible: Nồi nấu kim loại - crushed_ore: Máy nghiền quặng - damascus_steel: Thép Damascus - damascus_steel_armor: Giáp thép Damascus - diet_cookie: Bánh quy ăn kiêng - duct_tape: Băng dính - electric_crucible: Điện khí hóa - electric_furnaces: Lò nung điện - electric_ingot_machines: Máy chế tạo phôi điện - electric_motor: Động cơ điện - electric_ore_grinding: Máy nghiền điện - electric_press: Máy ép chạy bằng điện - electric_smeltery: Lò nung điện - elemental_staff: Trượng nguyên tố - elevator: Thang máy - elytra: Cánh cứng - ender_armor: Giáp Ender - ender_backpack: Balô Ender - ender_talismans: Bùa hộ mệnh Ender - energized_gps_transmitter: Máy phát cấp cao nhất - energized_solar_generator: Máy phát điện toàn thời gian - energy_regulator: Mạng năng lượng 101 - enhanced_furnace: Lò nung cường hóa - essence_of_afterlife: Bột hậu kiếp - explosive_tools: Dụng cụ phát nổ - farmer_shoes: Giầy làm nông - fire_staff: Trượng Lửa - fire_talisman: Bùa hộ mệnh tránh lửa - first_aid: Bộ sơ cứu - flask_of_knowledge: Bình lưu trữ kinh nghiệm - fluid_pump: Máy bơm chất lỏng - fortune_cookie: Bánh quy may mắn - freezer: Máy làm lạnh - fuel: Nhiên liệu - geo_miner: Máy khai thác GEO - geo_scanner: Máy quét GEO - gilded_backpack: Ba lô mạ vàng - gilded_iron: Sắt mạ vàng - gilded_iron_armor: Giáp sắt mạ vàng - glowstone_armor: Giáp quang học - gold_armor: Bộ giáp sáng bóng - gold_carats: Vàng nguyên chất - golden_apple_juice: Thuốc vàng - gold_pan: Sàng vàng - gps_emergency_transmitter: Điểm khẩn cấp GPS - gps_setup: Máy thiết lập GPS cơ bản - grappling_hook: Cái Móc - grind_stone: Máy nghiền đá - hardened_glass: Kính cứng - hazmat_suit: Bộ đồ khử nhiễm - heated_pressure_chamber: Buồng gia nhiệt - hercules_pickaxe: Cúp Thần Hercules - high_tier_capacitors: Tụ điện cấp 2 - high_tier_carbon_press: Máy ép cacbon tối thượng - high_tier_electric_ingot_machines: Máy chế tạo phôi điện siêu tốc - high_tier_enhanced_furnaces: Lò nung cao cấp - hologram_projector: Ảnh ba chiều - infernal_bonemeal: Phân bón âm phủ - infused_hopper: Phễu thu hút - infused_magnet: Nam châm truyền - jetboots: Giày phản lực - jetpacks: Giáp phản lực - juicer: Thức uống ngon - kelp_cookie: Tảo bẹ Ngon - knight_talisman: Bùa hộ mệnh kỵ sỹ - lava_crystal: Pha lê dung nham - lava_generator: Máy phát điện bằng dung nham - lava_talisman: Bùa hộ mệnh dung nham - lightning_rune: Ngọc của Sấm sét - lumber_axe: Búa đốn gỗ ( vjp ) - lumps: Những cục bướu phép - magical_book_cover: Cuốn sách ma thuật liên kết - magic_eye_of_ender: Mắt Ender ma thuật - magician_talisman: Bùa hộ mệnh pháp sư - magic_sugar: Đường ma thuật - magic_workbench: Bài chế tạo-ma thuật - magnesium_generator: Sức mạnh từ Magiê - magnet: Nam Châm - misc_power_items: Vật phẩm quan trọng liên quan đến năng lượng - monster_jerky: Thịt quái quật khô - more_enhanced_furnaces: Lò nung tốt hơn - multimeter: Máy đo công suất điện - multitools: Đa công cụ - nether_gold_pan: Chảo vàng địa ngục - nether_ice: Đá địa ngục làm mát - nether_star_reactor: Lò hạt nhân sao địa ngục - nickel_and_cobalt: Nhiều quặng khác - night_vision_googles: Kính nhìn đêm - nuclear_reactor: Nhà máy điện hạt nhân - oil: Dầu - ore_crusher: Nhân đôi quặng - organic_fertilizer: Phân hữu cơ - organic_food: Thực phẩm hữu cơ - output_chest: Rương máy móc đưa ra cơ bản - pickaxe_of_containment: Cúp ngăn chặn - pickaxe_of_the_seeker: Cúp tìm kiếm - pickaxe_of_vein_mining: Cúp đào tĩnh mạch - plastic_sheet: Nhựa + walking_sticks: Gậy đi bộ portable_crafter: Bàn chế tạo di động + fortune_cookie: Bánh quy may mắn portable_dustbin: Thùng rác di động - pressure_chamber: Buồng áp suất - radiant_backpack: Ba lô phát quang - rainbow_blocks: Khối cầu vòng - reactor_access_port: Lò phản ứng được tiếp xúc - reactor_essentials: Lò phản ứng thiết yếu - redstone_alloy: Hợp kim Đá đỏ - reinforced_alloy: Hợp kim gia cố - reinforced_armor: Giáp gia cố - reinforced_furnace: Lò nung được gia cố - repaired_spawner: Lồng được sửa chữa - scroll_of_dimensional_teleposition: Cuộn giấy của sự xoay chuyển - seismic_axe: Rìu địa chấn - silicon: Thung lũng Silicon + meat_jerky: Thịt Khô + armor_forge: Bàn chế tạo giáp + glowstone_armor: Giáp quang học + lumps: Những cục bướu phép + ender_backpack: Balô Ender + ender_armor: Giáp Ender + magic_eye_of_ender: Mắt Ender ma thuật + magic_sugar: Đường ma thuật + monster_jerky: Thịt quái quật khô slime_armor: Giáp chất nhờn - slimefun_metals: Kim loại mới - slime_steel_armor: Giáp thép trơ - smelters_pickaxe: Cúp nung + sword_of_beheading: Kiếm chặt đầu + basic_circuit_board: Bảng mạch cơ bản + advanced_circuit_board: Bảng mạch tiên tiến smeltery: Lò đút - solar_generators: Máy sản xuất năng lượng mặt trời - solar_panel_and_helmet: Năng lượng mặt trời ( ngôi sao ) - soulbound_rune: Ngọc linh hồn - special_bows: Cung đặc biệt - special_elytras: Cánh cứng đặc biệt - special_runes: Ngọc tím steel: Thời đại thép + misc_power_items: Vật phẩm quan trọng liên quan đến năng lượng + battery: Viên Pin đầu tiên của bạn steel_plate: Mạ thép steel_thruster: Máy đẩy thép - storm_staff: Trượng Sét - sword_of_beheading: Kiếm chặt đầu - synthetic_diamond: Kim cương tổng hợp - synthetic_emerald: ngọc lục bảo tổng hợp - synthetic_sapphire: Ngọc bích tổng hợp - table_saw: Bàn cưa củi - teleporter: Thành phần cơ sở dịch chuyển - teleporter_activation_plates: Kích hoạt dịch chuyển tức thời - tome_of_knowledge_sharing: Bộ chia sẽ kiến thức - totem_of_undying: Vật tổ của sự Bất tử - trash_can: Rác - traveller_talisman: Bùa hộ mệnh du hành - uranium: Phóng xạ - walking_sticks: Gậy đi bộ - warrior_talisman: Bùa hộ mệnh chiến binh - water_staff: Trượng nước - water_talisman: Bùa hộ mệnh nước - whirlwind_talisman: Bùa hộ mệnh vòi rồng - wind_staff: Trượng gió - wither_assembler: Máy giết Wither tự động - wither_proof_glass: Kính chống Wither - wither_proof_obsidian: Hắc diện thạch chống Wither - wizard_talisman: Bùa hộ mệnh Thuật Sĩ - woven_backpack: Ba lô kết lại - xp_collector: Máy thu kinh nghiệm - meat_jerky: Thịt Khô parachute: Dù bay + grappling_hook: Cái Móc + jetpacks: Giáp phản lực + multitools: Đa công cụ + solar_panel_and_helmet: Năng lượng mặt trời ( ngôi sao ) + elemental_staff: Trượng nguyên tố + grind_stone: Máy nghiền đá + cactus_armor: Bộ đồ xương rồng + gold_pan: Sàng vàng + magical_book_cover: Cuốn sách ma thuật liên kết + slimefun_metals: Kim loại mới + ore_crusher: Nhân đôi quặng + bronze: Tác phẩm đồng + alloys: Hợp kim cao cấp + compressor_and_carbon: Tác phẩm Carbon + gilded_iron_armor: Giáp sắt mạ vàng + synthetic_diamond: Kim cương tổng hợp + pressure_chamber: Buồng áp suất + synthetic_sapphire: Ngọc bích tổng hợp + damascus_steel: Thép Damascus + damascus_steel_armor: Giáp thép Damascus + reinforced_alloy: Hợp kim gia cố + carbonado: Kim cương đen + magic_workbench: Bài chế tạo-ma thuật + wind_staff: Trượng gió + reinforced_armor: Giáp gia cố ore_washer: Máy rửa quặng + gold_carats: Vàng nguyên chất + silicon: Thung lũng Silicon + fire_staff: Trượng Lửa + smelters_pickaxe: Cúp nung + common_talisman: Bùa hộ mệnh thông thường + anvil_talisman: Bùa hộ mệnh của cái đe miner_talisman: Bùa hộ mệnh của thợ mỏ hunter_talisman: Bùa hộ mệnh của thợ săn + lava_talisman: Bùa hộ mệnh dung nham + water_talisman: Bùa hộ mệnh nước + angel_talisman: Bùa hộ mệnh thiên sứ + fire_talisman: Bùa hộ mệnh tránh lửa + lava_crystal: Pha lê dung nham + magician_talisman: Bùa hộ mệnh pháp sư + traveller_talisman: Bùa hộ mệnh du hành + warrior_talisman: Bùa hộ mệnh chiến binh + knight_talisman: Bùa hộ mệnh kỵ sỹ + gilded_iron: Sắt mạ vàng + synthetic_emerald: ngọc lục bảo tổng hợp chainmail_armor: Giáp lưới + whirlwind_talisman: Bùa hộ mệnh vòi rồng + wizard_talisman: Bùa hộ mệnh Thuật Sĩ + lumber_axe: Búa đốn gỗ ( vjp ) + hazmat_suit: Bộ đồ khử nhiễm + uranium: Phóng xạ + crushed_ore: Máy nghiền quặng + redstone_alloy: Hợp kim Đá đỏ + carbonado_tools: Công cụ kim cương đen + first_aid: Bộ sơ cứu + gold_armor: Bộ giáp sáng bóng + night_vision_googles: Kính nhìn đêm + pickaxe_of_containment: Cúp ngăn chặn + hercules_pickaxe: Cúp Thần Hercules + table_saw: Bàn cưa củi + slime_steel_armor: Giáp thép trơ + blade_of_vampires: Gươm ma cà rồng + water_staff: Trượng nước + 24k_gold_block: Thành phố Vàng + composter: Khùng tổng hợp + farmer_shoes: Giầy làm nông + explosive_tools: Dụng cụ phát nổ + automated_panning_machine: Sàng vàng Tự động + boots_of_the_stomper: Giày cao cổ + pickaxe_of_the_seeker: Cúp tìm kiếm + backpacks: Ba lô + woven_backpack: Ba lô kết lại + crucible: Nồi nấu kim loại + gilded_backpack: Ba lô mạ vàng + armored_jetpack: Giáp phản lực + ender_talismans: Bùa hộ mệnh Ender + nickel_and_cobalt: Nhiều quặng khác + magnet: Nam Châm + infused_magnet: Nam châm truyền + cobalt_pickaxe: Cúp nhanh nhẹn + essence_of_afterlife: Bột hậu kiếp + bound_backpack: Balo Linh hồn + jetboots: Giày phản lực + armored_jetboots: Giày thép phản lực + seismic_axe: Rìu địa chấn + pickaxe_of_vein_mining: Cúp đào tĩnh mạch + bound_weapons: Vũ khí linh hồn + bound_tools: Dụng cụ linh hồn + bound_armor: Giáp linh hồn + juicer: Thức uống ngon + repaired_spawner: Lồng được sửa chữa + enhanced_furnace: Lò nung cường hóa + more_enhanced_furnaces: Lò nung tốt hơn + high_tier_enhanced_furnaces: Lò nung cao cấp + reinforced_furnace: Lò nung được gia cố + carbonado_furnace: Lò nung cạnh carbon + electric_motor: Động cơ điện + block_placer: Máy đặt khối + scroll_of_dimensional_teleposition: Cuộn giấy của sự xoay chuyển + special_bows: Cung đặc biệt + tome_of_knowledge_sharing: Bộ chia sẽ kiến thức + flask_of_knowledge: Bình lưu trữ kinh nghiệm + hardened_glass: Kính cứng + golden_apple_juice: Thuốc vàng + cooler: Máy uống di động + ancient_altar: Tế đài cổ đại + wither_proof_obsidian: Hắc diện thạch chống Wither + ancient_runes: Ngọc nguyên tố + special_runes: Ngọc tím + infernal_bonemeal: Phân bón âm phủ + rainbow_blocks: Khối cầu vòng + infused_hopper: Phễu thu hút + wither_proof_glass: Kính chống Wither + duct_tape: Băng dính + plastic_sheet: Nhựa + android_memory_core: Lõi máy móc + oil: Dầu + fuel: Nhiên liệu + hologram_projector: Ảnh ba chiều + capacitors: Tụ điện cấp 1 + high_tier_capacitors: Tụ điện cấp 2 + solar_generators: Máy sản xuất năng lượng mặt trời + electric_furnaces: Lò nung điện + electric_ore_grinding: Máy nghiền điện + heated_pressure_chamber: Buồng gia nhiệt + coal_generator: Máy phát điện bằng than + bio_reactor: Lò phản ứng sinh học + auto_enchanting: Phù phép tự động + auto_anvil: Đe tự động + multimeter: Máy đo công suất điện + gps_setup: Máy thiết lập GPS cơ bản + gps_emergency_transmitter: Điểm khẩn cấp GPS programmable_androids: Android lập trình được + android_interfaces: Giao diện Android + geo_scanner: Máy quét GEO + combustion_reactor: Lò phản ứng đốt cháy + teleporter: Thành phần cơ sở dịch chuyển + teleporter_activation_plates: Kích hoạt dịch chuyển tức thời + better_solar_generators: Máy phát điện được nâng cấp + better_gps_transmitters: Máy phát được nâng cấp + elevator: Thang máy + energized_solar_generator: Máy phát điện toàn thời gian + energized_gps_transmitter: Máy phát cấp cao nhất + energy_regulator: Mạng năng lượng 101 butcher_androids: Android đồ tể + organic_food: Thực phẩm hữu cơ + auto_breeder: Máy cho ăn tự động + advanced_android: Android nâng cao advanced_butcher_android: Android nâng cao - Đồ tể advanced_fisherman_android: Android nâng cao - Câu cá + animal_growth_accelerator: Máy tăng trưởng động vật + xp_collector: Máy thu kinh nghiệm + organic_fertilizer: Phân hữu cơ + crop_growth_accelerator: Máy tăng trưởng cây trồng + better_crop_growth_accelerator: Máy tăng tưởng cây trồng nâng cấp + reactor_essentials: Lò phản ứng thiết yếu + nuclear_reactor: Nhà máy điện hạt nhân + freezer: Máy làm lạnh + cargo_basics: Máy dịch chuyển đồ cơ bản + cargo_nodes: Thiết lập máy dịch chuyển đồ + electric_ingot_machines: Máy chế tạo phôi điện + high_tier_electric_ingot_machines: Máy chế tạo phôi điện siêu tốc + automated_crafting_chamber: Chế tạo tự động + better_food_fabricator: Máy chế tạo thực phẩm nâng cấp + reactor_access_port: Lò phản ứng được tiếp xúc + fluid_pump: Máy bơm chất lỏng + better_freezer: Máy làm lạnh nâng cấp + boosted_uranium: Vòng tròn không kết thúc + trash_can: Rác + advanced_output_node: Nút đầu ra nâng cao + carbon_press: Máy ép carbon + electric_smeltery: Lò nung điện + better_electric_furnace: Lò nung điện nâng cấp + better_carbon_press: Máy ép carbon nâng cấp empowered_android: Android siêu cấp empowered_butcher_android: Android siêu cấp - Đồ tể empowered_fisherman_android: Android siêu cấp - Câu cá + high_tier_carbon_press: Máy ép cacbon tối thượng + wither_assembler: Máy giết Wither tự động + better_heated_pressure_chamber: Máy áp suất nâng cấp + elytra: Cánh cứng + special_elytras: Cánh cứng đặc biệt + electric_crucible: Điện khí hóa + better_electric_crucibles: Máy nung đồ nóng + advanced_electric_smeltery: Lò rèn điện nâng cao + advanced_farmer_android: Android nâng cao - Nông phu + lava_generator: Máy phát điện bằng dung nham + nether_ice: Đá địa ngục làm mát + nether_star_reactor: Lò hạt nhân sao địa ngục + blistering_ingots: Chất phóng xạ Blistering + automatic_ignition_chamber: Máy đánh lửa tự động + output_chest: Rương máy móc đưa ra cơ bản + copper_wire: Dây dẫn điện đồng + radiant_backpack: Ba lô phát quang + auto_drier: Một Ngày Khô ráo + diet_cookie: Bánh quy ăn kiêng + storm_staff: Trượng Sét + soulbound_rune: Ngọc linh hồn + geo_miner: Máy khai thác GEO + lightning_rune: Ngọc của Sấm sét + totem_of_undying: Vật tổ của sự Bất tử + charging_bench: Bàn sạc + nether_gold_pan: Chảo vàng địa ngục + electric_press: Máy ép chạy bằng điện + magnesium_generator: Sức mạnh từ Magiê + kelp_cookie: Tảo bẹ Ngon + makeshift_smeltery: Lò rèn cải tiến + tree_growth_accelerator: Cây lớn nhanh hơn + industrial_miner: Máy đào công nghiệp + advanced_industrial_miner: Đào tốt hơn + magical_zombie_pills: Thuốc kháng khuẩn thây ma + auto_brewer: Lò thuốc công nghiệp + enchantment_rune: Đá cường hoá cổ + lead_clothing: Vải pha chì + tape_measure: Thước dây + iron_golem_assembler: Máy lắp Golem Sắt + climbing_pick: Móc kéo + shulker_shell: Shulker tổng hợp + villager_rune: Đá trao đổi + caveman_talisman: Bùa thổ dân + even_higher_tier_capacitors: Pin cấp 3 + elytra_cap: Mũ lượn + energy_connectors: Đầu nối + bee_armor: Giáp ong diff --git a/src/main/resources/languages/resources_hu.yml b/src/main/resources/languages/resources_hu.yml index b90e6cfa6..8b9249387 100644 --- a/src/main/resources/languages/resources_hu.yml +++ b/src/main/resources/languages/resources_hu.yml @@ -12,13 +12,13 @@ resources: salt: Só uranium: Uránium slimefunorechunks: - iron_ore_chunk: Vasérc chunk - gold_ore_chunk: Aranyérc chunk - copper_ore_chunk: Rézérc chunk - tin_ore_chunk: Ónérc chunk - silver_ore_chunk: Ezüstérc chunk - aluminum_ore_chunk: Alumíniumérc chunk - lead_ore_chunk: Ólomérc chunk - zinc_ore_chunk: Cinkérc chunk - nickel_ore_chunk: Nikkelérc chunk - cobalt_ore_chunk: Kobaltérc Chunk + iron_ore_chunk: Vasérctömb + gold_ore_chunk: Aranyérc-tömb + copper_ore_chunk: Rézérctömb + tin_ore_chunk: Ónérctömb + silver_ore_chunk: Ezüstérctömb + aluminum_ore_chunk: Alumíniumérc-tömb + lead_ore_chunk: Ólomérctömb + zinc_ore_chunk: Cinkérctömb + nickel_ore_chunk: Nikkelérctömb + cobalt_ore_chunk: Kobaltérctömb diff --git a/src/main/resources/languages/resources_pt.yml b/src/main/resources/languages/resources_pt.yml new file mode 100644 index 000000000..ee9f8f092 --- /dev/null +++ b/src/main/resources/languages/resources_pt.yml @@ -0,0 +1,24 @@ +--- +tooltips: + results: Resultados de Geo-Scan + chunk: Pedaço Escaneado + world: Mundo + unit: Unidade + units: Unidades +resources: + slimefun: + oil: Óleo + nether_ice: Gelo do Nether + salt: Sal + uranium: 'Urânio ' + slimefunorechunks: + iron_ore_chunk: Pedaço de Minério de Ferro + gold_ore_chunk: Pedaço de Minério de Ouro + copper_ore_chunk: Pedaço de Minério de Cobre + tin_ore_chunk: Pedaço de Minério de Estanho + silver_ore_chunk: Pedaço de Minério de Prata + aluminum_ore_chunk: Pedaço de Minério de Alumínio + lead_ore_chunk: Pedaço de Minério de Chumbo + zinc_ore_chunk: Pedaço de Minério de Zinco + nickel_ore_chunk: Pedaço de Minério de Níquel + cobalt_ore_chunk: Pedaço de Minério de Cobalto diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 692b065ca..fa3936eaa 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -23,7 +23,6 @@ softdepend: # We hook into these plugins too, but they depend on Slimefun. loadBefore: - ChestTerminal -- ExoticGarden # Our commands commands: diff --git a/src/main/resources/wiki.json b/src/main/resources/wiki.json index 7de89de83..789d340ca 100644 --- a/src/main/resources/wiki.json +++ b/src/main/resources/wiki.json @@ -1,247 +1,247 @@ { - "GOLD_PAN" : "Gold-Pan", - "SIFTED_ORE" : "Sifted-Ore", - "SMELTERY" : "Smeltery", - "DIET_COOKIE" : "Diet-Cookie", - "ENHANCED_CRAFTING_TABLE" : "Enhanced-Crafting-Table", - "FORTUNE_COOKIE" : "Fortune-Cookie", - "TABLE_SAW" : "Table-Saw", - "APPLE_JUICE" : "Juices", - "GOLDEN_APPLE_JUICE" : "Juices", - "CARROT_JUICE" : "Juices", - "MELON_JUICE" : "Juices", - "PUMPKIN_JUICE" : "Juices", - "SWEET_BERRY_JUICE" : "Juices", - "MAGIC_SUGAR" : "Magic-Sugar", - "MONSTER_JERKY" : "Monster-Jerky", - "OUTPUT_CHEST" : "Output-Chest", - "BEEF_JERKY" : "Meat-Jerky", - "PORK_JERKY" : "Meat-Jerky", - "CHICKEN_JERKY" : "Meat-Jerky", - "MUTTON_JERKY" : "Meat-Jerky", - "RABBIT_JERKY" : "Meat-Jerky", - "FISH_JERKY" : "Meat-Jerky", - "KELP_COOKIE" : "Kelp-Cookie", - "ANCIENT_ALTAR" : "Ancient-Altar", - "ANCIENT_PEDESTAL" : "Ancient-Pedestal", - "BLADE_OF_VAMPIRES" : "Blade-of-Vampires", - "BROKEN_SPAWNER" : "Broken-Spawner", - "REPAIRED_SPAWNER" : "Reinforced-Spawner", - "NETHER_GOLD_PAN" : "Nether-Gold-Pan", - "PICKAXE_OF_CONTAINMENT" : "Pickaxe-of-Containment", - "SEISMIC_AXE" : "Seismic-Axe", - "SMELTERS_PICKAXE" : "Smelter's-Pickaxe", - "MAGNET" : "Magnet", - "BASIC_CIRCUIT_BOARD" : "Circuit-Boards", - "ADVANCED_CIRCUIT_BOARD" : "Circuit-Boards", - "BATTERY" : "Battery", - "STEEL_THRUSTER" : "Steel-Thruster", - "POWER_CRYSTAL" : "Power-Crystal", - "SOLAR_PANEL" : "Solar-Panel", - "ELECTRO_MAGNET" : "Electromagnet", - "ELECTRIC_MOTOR" : "Electric-Motor", - "HEATING_COIL" : "Heating-Coil", - "COPPER_WIRE" : "Copper-Wire", - "HARDENED_GLASS" : "Hardened-Glass", - "COOLING_UNIT" : "Cooling-Unit", - "WITHER_PROOF_OBSIDIAN" : "Wither-Proof-Blocks", - "WITHER_PROOF_GLASS" : "Wither-Proof-Blocks", - "REACTOR_COOLANT_CELL" : "Coolant-Cells", - "NETHER_ICE_COOLANT_CELL" : "Coolant-Cells", - "IRON_DUST" : "Iron-Dust", - "GOLD_DUST" : "Gold-Dust", - "GOLD_4K" : "Gold-Ingot", - "GOLD_6K" : "Gold-Ingot", - "GOLD_8K" : "Gold-Ingot", - "GOLD_10K" : "Gold-Ingot", - "GOLD_12K" : "Gold-Ingot", - "GOLD_14K" : "Gold-Ingot", - "GOLD_16K" : "Gold-Ingot", - "GOLD_18K" : "Gold-Ingot", - "GOLD_20K" : "Gold-Ingot", - "GOLD_22K" : "Gold-Ingot", - "GOLD_24K" : "Gold-Ingot", - "ENERGY_REGULATOR" : "Energy-Regulator", - "SMALL_CAPACITOR" : "Energy-Capacitors", - "MEDIUM_CAPACITOR" : "Energy-Capacitors", - "BIG_CAPACITOR" : "Energy-Capacitors", - "LARGE_CAPACITOR" : "Energy-Capacitors", - "CARBONADO_EDGED_CAPACITOR" : "Energy-Capacitors", - "SOLAR_GENERATOR" : "Solar-Generator", - "SOLAR_GENERATOR_2" : "Solar-Generator", - "SOLAR_GENERATOR_3" : "Solar-Generator", - "SOLAR_GENERATOR_4" : "Solar-Generator", - "COAL_GENERATOR" : "Coal-Generator", - "COAL_GENERATOR_2" : "Coal-Generator", - "COBALT_PICKAXE" : "Cobalt-Pickaxe", - "EXPLOSIVE_PICKAXE" : "Explosive-Pickaxe", - "EXPLOSIVE_SHOVEL" : "Explosive-Shovel", - "GRAPPLING_HOOK" : "Grappling-Hook", - "HERCULES_PICKAXE" : "Hercules'-Pickaxe", - "LUMBER_AXE" : "Lumber-Axe", - "PICKAXE_OF_VEIN_MINING" : "Pickaxe-of-Vein-Mining", - "PICKAXE_OF_THE_SEEKER" : "Pickaxe-of-the-Seeker", - "CARGO_OUTPUT_ADVANCED" : "Advanced-Output-Node", - "CARGO_MANAGER" : "Cargo-Manager", - "CARGO_MOTOR" : "Cargo-Motor", - "CARGO_NODE" : "Connector-Node", - "CARGO_INPUT" : "Input-Node", - "CARGO_OUTPUT" : "Output-Node", - "TRASH_CAN" : "Trash-Can", - "ORE_WASHER" : "Ore-Washer", - "SCUBA_HELMET" : "Hazmat-Suit", - "HAZMAT_CHESTPLATE" : "Hazmat-Suit", - "HAZMAT_LEGGINGS" : "Hazmat-Suit", - "RUBBER_BOOTS" : "Hazmat-Suit", - "ARMOR_FORGE" : "Armor-Forge", - "AUTOMATED_PANNING_MACHINE" : "Automated-Panning-Machine", - "COMPRESSOR" : "Compressor", - "ORE_CRUSHER" : "Ore-Crusher", - "PRESSURE_CHAMBER" : "Pressure-Chamber", - "GRIND_STONE" : "Grind-Stone", - "MAGIC_WORKBENCH" : "Magic-Workbench", - "PORTABLE_CRAFTER" : "Portable-Crafter", - "PORTABLE_DUSTBIN" : "Portable-Dustbin", - "COOLER" : "Cooler", - "ALUMINUM_BRASS_INGOT" : "Aluminum-Brass-Ingot", - "ALUMINUM_BRONZE_INGOT" : "Aluminum-Bronze-Ingot", - "ALUMINUM_DUST" : "Aluminum-Dust", - "ALUMINUM_INGOT" : "Aluminum-Ingot", - "GLOWSTONE_HELMET" : "Magical-Armor", - "GLOWSTONE_CHESTPLATE" : "Magical-Armor", - "GLOWSTONE_LEGGINGS" : "Magical-Armor", - "GLOWSTONE_BOOTS" : "Magical-Armor", - "ENDER_HELMET" : "Magical-Armor", - "ENDER_CHESTPLATE" : "Magical-Armor", - "ENDER_LEGGINGS" : "Magical-Armor", - "ENDER_BOOTS" : "Magical-Armor", - "SLIME_HELMET" : "Magical-Armor", - "SLIME_CHESTPLATE" : "Magical-Armor", - "SLIME_LEGGINGS" : "Magical-Armor", - "SLIME_BOOTS" : "Magical-Armor", - "CACTUS_HELMET" : "Armor", - "CACTUS_CHESTPLATE" : "Armor", - "CACTUS_LEGGINGS" : "Armor", - "CACTUS_BOOTS" : "Armor", - "DAMASCUS_STEEL_HELMET" : "Armor", - "DAMASCUS_STEEL_CHESTPLATE" : "Armor", - "DAMASCUS_STEEL_LEGGINGS" : "Armor", - "DAMASCUS_STEEL_BOOTS" : "Armor", - "REINFORCED_ALLOY_HELMET" : "Armor", - "REINFORCED_ALLOY_CHESTPLATE" : "Armor", - "REINFORCED_ALLOY_LEGGINGS" : "Armor", - "REINFORCED_ALLOY_BOOTS" : "Armor", - "GILDED_IRON_HELMET" : "Armor", - "GILDED_IRON_CHESTPLATE" : "Armor", - "GILDED_IRON_LEGGINGS" : "Armor", - "GILDED_IRON_BOOTS" : "Armor", - "GOLD_12K_HELMET" : "Armor", - "GOLD_12K_CHESTPLATE" : "Armor", - "GOLD_12K_LEGGINGS" : "Armor", - "GOLD_12K_BOOTS" : "Armor", - "SLIME_STEEL_HELMET" : "Magical-Armor", - "SLIME_STEEL_CHESTPLATE" : "Magical-Armor", - "SLIME_STEEL_LEGGINGS" : "Magical-Armor", - "SLIME_STEEL_BOOTS" : "Magical-Armor", - "BILLON_INGOT" : "Billon-Ingot", - "BLOCK_PLACER" : "Block-Placer", - "EXPLOSIVE_BOW" : "Bows", - "ICY_BOW" : "Bows", - "BRASS_INGOT" : "Brass-Ingot", - "BRONZE_INGOT" : "Bronze-Ingot", - "CHRISTMAS_MILK" : "Christmas-Items", - "CHRISTMAS_CHOCOLATE_MILK" : "Christmas-Items", - "CHRISTMAS_EGG_NOG" : "Christmas-Items", - "CHRISTMAS_APPLE_CIDER" : "Christmas-Items", - "CHRISTMAS_COOKIE" : "Christmas-Items", - "CHRISTMAS_FRUIT_CAKE" : "Christmas-Items", - "CHRISTMAS_APPLE_PIE" : "Christmas-Items", - "CHRISTMAS_HOT_CHOCOLATE" : "Christmas-Items", - "CHRISTMAS_CAKE" : "Christmas-Items", - "CHRISTMAS_CARAMEL" : "Christmas-Items", - "CHRISTMAS_CARAMEL_APPLE" : "Christmas-Items", - "CHRISTMAS_CHOCOLATE_APPLE" : "Christmas-Items", - "CHRISTMAS_PRESENT" : "Christmas-Items", - "RAINBOW_WOOL_XMAS" : "Christmas-Seasonal-Category", - "RAINBOW_GLASS_XMAS" : "Christmas-Seasonal-Category", - "RAINBOW_CLAY_XMAS" : "Christmas-Seasonal-Category", - "RAINBOW_GLASS_PANE_XMAS" : "Christmas-Seasonal-Category", - "RAINBOW_CONCRETE_XMAS" : "Christmas-Seasonal-Category", - "RAINBOW_GLAZED_TERRACOTTA_XMAS" : "Christmas-Seasonal-Category", - "COBALT_INGOT" : "Cobalt-Ingot", - "COPPER_DUST" : "Copper-Dust", - "COPPER_INGOT" : "Copper-Ingot", - "CORINTHIAN_BRONZE_INGOT" : "Corinthian-Bronze-Ingot", - "DAMASCUS_STEEL_INGOT" : "Damascus-Steel-Ingot", - "DURALUMIN_INGOT" : "Duralumin-Ingot", - "ELEVATOR_PLATE" : "Elevator-Plate", - "ELYTRA_SCALE" : "Elytras", - "INFUSED_ELYTRA" : "Elytras", - "SOULBOUND_ELYTRA" : "Elytras", - "ENHANCED_FURNACE" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_2" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_3" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_4" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_5" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_6" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_7" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_8" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_9" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_10" : "Enhanced-Furnaces", - "ENHANCED_FURNACE_11" : "Enhanced-Furnaces", - "REINFORCED_FURNACE" : "Enhanced-Furnaces", - "CARBONADO_EDGED_FURNACE" : "Enhanced-Furnaces", - "FERROSILICON" : "Ferrosilicon", - "GEO_MINER" : "GEO-Miner", - "GPS_ACTIVATION_DEVICE_SHARED" : "GPS-Activation-Device", - "GPS_ACTIVATION_DEVICE_PERSONAL" : "GPS-Activation-Device", - "GPS_CONTROL_PANEL" : "GPS-Control-Panel", - "GPS_EMERGENCY_TRANSMITTER" : "GPS-Emergency-Transmitter", - "GPS_GEO_SCANNER" : "GPS-Geo-Scanner", - "GPS_MARKER_TOOL" : "GPS-Marker-Tool", - "GPS_TELEPORTATION_MATRIX" : "GPS-Teleporter-Matrix", - "GPS_TELEPORTER_PYLON" : "GPS-Teleporter-Pylon", - "GPS_TRANSMITTER" : "GPS-Transmitter", - "GILDED_IRON" : "Gilded-Iron", - "HARDENED_METAL_INGOT" : "Hardened-Metal", - "LEAD_DUST" : "Lead-Dust", - "LEAD_INGOT" : "Lead-Ingot", - "MAGNESIUM_DUST" : "Magnesium-Dust", - "MAGNESIUM_INGOT" : "Magnesium-Ingot", - "NICKEL_INGOT" : "Nickel-Ingot", - "OIL_PUMP" : "Oil-Pump", - "PORTABLE_GEO_SCANNER" : "Portable-Geo-Scanner", - "RAINBOW_WOOL" : "Rainbow-Blocks", - "RAINBOW_GLASS" : "Rainbow-Blocks", - "RAINBOW_CLAY" : "Rainbow-Blocks", - "RAINBOW_GLASS_PANE" : "Rainbow-Blocks", - "RAINBOW_CONCRETE" : "Rainbow-Blocks", - "RAINBOW_GLAZED_TERRACOTTA" : "Rainbow-Blocks", - "REDSTONE_ALLOY" : "Redstone-Alloy-Ingot", - "REINFORCED_ALLOY_INGOT" : "Reinforced-Alloy-Ingot", - "SILVER_DUST" : "Silver-Dust", - "SILVER_INGOT" : "Silver-Ingot", - "SOLDER_INGOT" : "Solder-Ingot", - "SOULBOUND_HELMET" : "Soulbound-Armor", - "SOULBOUND_CHESTPLATE" : "Soulbound-Armor", - "SOULBOUND_LEGGINGS" : "Soulbound-Armor", - "SOULBOUND_BOOTS" : "Soulbound-Armor", - "ANCIENT_RUNE_SOULBOUND" : "Soulbound-Rune", - "SOULBOUND_SWORD" : "Soulbound-Weapons", - "SOULBOUND_BOW" : "Soulbound-Weapons", - "SOULBOUND_PICKAXE" : "Soulbound-Weapons", - "SOULBOUND_AXE" : "Soulbound-Weapons", - "SOULBOUND_SHOVEL" : "Soulbound-Weapons", - "SOULBOUND_HOE" : "Soulbound-Weapons", - "SOULBOUND_TRIDENT" : "Soulbound-Weapons", - "STEEL_INGOT" : "Steel-Ingot", - "SWORD_OF_BEHEADING" : "Sword-of-Beheading", - "COMMON_TALISMAN" : "Talismans", - "ENDER_TALISMAN" : "Talismans", - "TIN_DUST" : "Tin-Dust", - "TIN_INGOT" : "Tin-Ingot", - "GRANDMAS_WALKING_STICK" : "Walking-Sticks", - "GRANDPAS_WALKING_STICK" : "Walking-Sticks", - "ZINC_DUST" : "Zinc-Dust", - "ZINC_INGOT" : "Zinc-Ingot" + "GOLD_PAN" : "Gold-Pan", + "SIFTED_ORE" : "Sifted-Ore", + "SMELTERY" : "Smeltery", + "DIET_COOKIE" : "Diet-Cookie", + "ENHANCED_CRAFTING_TABLE" : "Enhanced-Crafting-Table", + "FORTUNE_COOKIE" : "Fortune-Cookie", + "TABLE_SAW" : "Table-Saw", + "APPLE_JUICE" : "Juices", + "GOLDEN_APPLE_JUICE" : "Juices", + "CARROT_JUICE" : "Juices", + "MELON_JUICE" : "Juices", + "PUMPKIN_JUICE" : "Juices", + "SWEET_BERRY_JUICE" : "Juices", + "MAGIC_SUGAR" : "Magic-Sugar", + "MONSTER_JERKY" : "Monster-Jerky", + "OUTPUT_CHEST" : "Output-Chest", + "BEEF_JERKY" : "Meat-Jerky", + "PORK_JERKY" : "Meat-Jerky", + "CHICKEN_JERKY" : "Meat-Jerky", + "MUTTON_JERKY" : "Meat-Jerky", + "RABBIT_JERKY" : "Meat-Jerky", + "FISH_JERKY" : "Meat-Jerky", + "KELP_COOKIE" : "Kelp-Cookie", + "ANCIENT_ALTAR" : "Ancient-Altar", + "ANCIENT_PEDESTAL" : "Ancient-Pedestal", + "BLADE_OF_VAMPIRES" : "Blade-of-Vampires", + "BROKEN_SPAWNER" : "Broken-Spawner", + "REPAIRED_SPAWNER" : "Reinforced-Spawner", + "NETHER_GOLD_PAN" : "Nether-Gold-Pan", + "PICKAXE_OF_CONTAINMENT" : "Pickaxe-of-Containment", + "SEISMIC_AXE" : "Seismic-Axe", + "SMELTERS_PICKAXE" : "Smelter's-Pickaxe", + "MAGNET" : "Magnet", + "BASIC_CIRCUIT_BOARD" : "Circuit-Boards", + "ADVANCED_CIRCUIT_BOARD" : "Circuit-Boards", + "BATTERY" : "Battery", + "STEEL_THRUSTER" : "Steel-Thruster", + "POWER_CRYSTAL" : "Power-Crystal", + "SOLAR_PANEL" : "Solar-Panel", + "ELECTRO_MAGNET" : "Electromagnet", + "ELECTRIC_MOTOR" : "Electric-Motor", + "HEATING_COIL" : "Heating-Coil", + "COPPER_WIRE" : "Copper-Wire", + "HARDENED_GLASS" : "Hardened-Glass", + "COOLING_UNIT" : "Cooling-Unit", + "WITHER_PROOF_OBSIDIAN" : "Wither-Proof-Blocks", + "WITHER_PROOF_GLASS" : "Wither-Proof-Blocks", + "REACTOR_COOLANT_CELL" : "Coolant-Cells", + "NETHER_ICE_COOLANT_CELL" : "Coolant-Cells", + "IRON_DUST" : "Iron-Dust", + "GOLD_DUST" : "Gold-Dust", + "GOLD_4K" : "Gold-Ingot", + "GOLD_6K" : "Gold-Ingot", + "GOLD_8K" : "Gold-Ingot", + "GOLD_10K" : "Gold-Ingot", + "GOLD_12K" : "Gold-Ingot", + "GOLD_14K" : "Gold-Ingot", + "GOLD_16K" : "Gold-Ingot", + "GOLD_18K" : "Gold-Ingot", + "GOLD_20K" : "Gold-Ingot", + "GOLD_22K" : "Gold-Ingot", + "GOLD_24K" : "Gold-Ingot", + "ENERGY_REGULATOR" : "Energy-Regulator", + "SMALL_CAPACITOR" : "Energy-Capacitors", + "MEDIUM_CAPACITOR" : "Energy-Capacitors", + "BIG_CAPACITOR" : "Energy-Capacitors", + "LARGE_CAPACITOR" : "Energy-Capacitors", + "CARBONADO_EDGED_CAPACITOR" : "Energy-Capacitors", + "SOLAR_GENERATOR" : "Solar-Generator", + "SOLAR_GENERATOR_2" : "Solar-Generator", + "SOLAR_GENERATOR_3" : "Solar-Generator", + "SOLAR_GENERATOR_4" : "Solar-Generator", + "COAL_GENERATOR" : "Coal-Generator", + "COAL_GENERATOR_2" : "Coal-Generator", + "COBALT_PICKAXE" : "Cobalt-Pickaxe", + "EXPLOSIVE_PICKAXE" : "Explosive-Pickaxe", + "EXPLOSIVE_SHOVEL" : "Explosive-Shovel", + "GRAPPLING_HOOK" : "Grappling-Hook", + "HERCULES_PICKAXE" : "Hercules'-Pickaxe", + "LUMBER_AXE" : "Lumber-Axe", + "PICKAXE_OF_VEIN_MINING" : "Pickaxe-of-Vein-Mining", + "PICKAXE_OF_THE_SEEKER" : "Pickaxe-of-the-Seeker", + "CARGO_OUTPUT_ADVANCED" : "Advanced-Output-Node", + "CARGO_MANAGER" : "Cargo-Manager", + "CARGO_MOTOR" : "Cargo-Motor", + "CARGO_NODE" : "Connector-Node", + "CARGO_INPUT" : "Input-Node", + "CARGO_OUTPUT" : "Output-Node", + "TRASH_CAN" : "Trash-Can", + "ORE_WASHER" : "Ore-Washer", + "SCUBA_HELMET" : "Hazmat-Suit", + "HAZMAT_CHESTPLATE" : "Hazmat-Suit", + "HAZMAT_LEGGINGS" : "Hazmat-Suit", + "RUBBER_BOOTS" : "Hazmat-Suit", + "ARMOR_FORGE" : "Armor-Forge", + "AUTOMATED_PANNING_MACHINE" : "Automated-Panning-Machine", + "COMPRESSOR" : "Compressor", + "ORE_CRUSHER" : "Ore-Crusher", + "PRESSURE_CHAMBER" : "Pressure-Chamber", + "GRIND_STONE" : "Grind-Stone", + "MAGIC_WORKBENCH" : "Magic-Workbench", + "PORTABLE_CRAFTER" : "Portable-Crafter", + "PORTABLE_DUSTBIN" : "Portable-Dustbin", + "COOLER" : "Cooler", + "ALUMINUM_BRASS_INGOT" : "Aluminum-Brass-Ingot", + "ALUMINUM_BRONZE_INGOT" : "Aluminum-Bronze-Ingot", + "ALUMINUM_DUST" : "Aluminum-Dust", + "ALUMINUM_INGOT" : "Aluminum-Ingot", + "GLOWSTONE_HELMET" : "Magical-Armor", + "GLOWSTONE_CHESTPLATE" : "Magical-Armor", + "GLOWSTONE_LEGGINGS" : "Magical-Armor", + "GLOWSTONE_BOOTS" : "Magical-Armor", + "ENDER_HELMET" : "Magical-Armor", + "ENDER_CHESTPLATE" : "Magical-Armor", + "ENDER_LEGGINGS" : "Magical-Armor", + "ENDER_BOOTS" : "Magical-Armor", + "SLIME_HELMET" : "Magical-Armor", + "SLIME_CHESTPLATE" : "Magical-Armor", + "SLIME_LEGGINGS" : "Magical-Armor", + "SLIME_BOOTS" : "Magical-Armor", + "CACTUS_HELMET" : "Armor", + "CACTUS_CHESTPLATE" : "Armor", + "CACTUS_LEGGINGS" : "Armor", + "CACTUS_BOOTS" : "Armor", + "DAMASCUS_STEEL_HELMET" : "Armor", + "DAMASCUS_STEEL_CHESTPLATE" : "Armor", + "DAMASCUS_STEEL_LEGGINGS" : "Armor", + "DAMASCUS_STEEL_BOOTS" : "Armor", + "REINFORCED_ALLOY_HELMET" : "Armor", + "REINFORCED_ALLOY_CHESTPLATE" : "Armor", + "REINFORCED_ALLOY_LEGGINGS" : "Armor", + "REINFORCED_ALLOY_BOOTS" : "Armor", + "GILDED_IRON_HELMET" : "Armor", + "GILDED_IRON_CHESTPLATE" : "Armor", + "GILDED_IRON_LEGGINGS" : "Armor", + "GILDED_IRON_BOOTS" : "Armor", + "GOLD_12K_HELMET" : "Armor", + "GOLD_12K_CHESTPLATE" : "Armor", + "GOLD_12K_LEGGINGS" : "Armor", + "GOLD_12K_BOOTS" : "Armor", + "SLIME_STEEL_HELMET" : "Magical-Armor", + "SLIME_STEEL_CHESTPLATE" : "Magical-Armor", + "SLIME_STEEL_LEGGINGS" : "Magical-Armor", + "SLIME_STEEL_BOOTS" : "Magical-Armor", + "BILLON_INGOT" : "Billon-Ingot", + "BLOCK_PLACER" : "Block-Placer", + "EXPLOSIVE_BOW" : "Bows", + "ICY_BOW" : "Bows", + "BRASS_INGOT" : "Brass-Ingot", + "BRONZE_INGOT" : "Bronze-Ingot", + "CHRISTMAS_MILK" : "Christmas-Items", + "CHRISTMAS_CHOCOLATE_MILK" : "Christmas-Items", + "CHRISTMAS_EGG_NOG" : "Christmas-Items", + "CHRISTMAS_APPLE_CIDER" : "Christmas-Items", + "CHRISTMAS_COOKIE" : "Christmas-Items", + "CHRISTMAS_FRUIT_CAKE" : "Christmas-Items", + "CHRISTMAS_APPLE_PIE" : "Christmas-Items", + "CHRISTMAS_HOT_CHOCOLATE" : "Christmas-Items", + "CHRISTMAS_CAKE" : "Christmas-Items", + "CHRISTMAS_CARAMEL" : "Christmas-Items", + "CHRISTMAS_CARAMEL_APPLE" : "Christmas-Items", + "CHRISTMAS_CHOCOLATE_APPLE" : "Christmas-Items", + "CHRISTMAS_PRESENT" : "Christmas-Items", + "RAINBOW_WOOL_XMAS" : "Christmas-Seasonal-Category", + "RAINBOW_GLASS_XMAS" : "Christmas-Seasonal-Category", + "RAINBOW_CLAY_XMAS" : "Christmas-Seasonal-Category", + "RAINBOW_GLASS_PANE_XMAS" : "Christmas-Seasonal-Category", + "RAINBOW_CONCRETE_XMAS" : "Christmas-Seasonal-Category", + "RAINBOW_GLAZED_TERRACOTTA_XMAS" : "Christmas-Seasonal-Category", + "COBALT_INGOT" : "Cobalt-Ingot", + "COPPER_DUST" : "Copper-Dust", + "COPPER_INGOT" : "Copper-Ingot", + "CORINTHIAN_BRONZE_INGOT" : "Corinthian-Bronze-Ingot", + "DAMASCUS_STEEL_INGOT" : "Damascus-Steel-Ingot", + "DURALUMIN_INGOT" : "Duralumin-Ingot", + "ELEVATOR_PLATE" : "Elevator-Plate", + "ELYTRA_SCALE" : "Elytras", + "INFUSED_ELYTRA" : "Elytras", + "SOULBOUND_ELYTRA" : "Elytras", + "ENHANCED_FURNACE" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_2" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_3" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_4" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_5" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_6" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_7" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_8" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_9" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_10" : "Enhanced-Furnaces", + "ENHANCED_FURNACE_11" : "Enhanced-Furnaces", + "REINFORCED_FURNACE" : "Enhanced-Furnaces", + "CARBONADO_EDGED_FURNACE" : "Enhanced-Furnaces", + "FERROSILICON" : "Ferrosilicon", + "GEO_MINER" : "GEO-Miner", + "GPS_ACTIVATION_DEVICE_SHARED" : "GPS-Activation-Device", + "GPS_ACTIVATION_DEVICE_PERSONAL" : "GPS-Activation-Device", + "GPS_CONTROL_PANEL" : "GPS-Control-Panel", + "GPS_EMERGENCY_TRANSMITTER" : "GPS-Emergency-Transmitter", + "GPS_GEO_SCANNER" : "GPS-Geo-Scanner", + "GPS_MARKER_TOOL" : "GPS-Marker-Tool", + "GPS_TELEPORTATION_MATRIX" : "GPS-Teleporter-Matrix", + "GPS_TELEPORTER_PYLON" : "GPS-Teleporter-Pylon", + "GPS_TRANSMITTER" : "GPS-Transmitter", + "GILDED_IRON" : "Gilded-Iron", + "HARDENED_METAL_INGOT" : "Hardened-Metal", + "LEAD_DUST" : "Lead-Dust", + "LEAD_INGOT" : "Lead-Ingot", + "MAGNESIUM_DUST" : "Magnesium-Dust", + "MAGNESIUM_INGOT" : "Magnesium-Ingot", + "NICKEL_INGOT" : "Nickel-Ingot", + "OIL_PUMP" : "Oil-Pump", + "PORTABLE_GEO_SCANNER" : "Portable-Geo-Scanner", + "RAINBOW_WOOL" : "Rainbow-Blocks", + "RAINBOW_GLASS" : "Rainbow-Blocks", + "RAINBOW_CLAY" : "Rainbow-Blocks", + "RAINBOW_GLASS_PANE" : "Rainbow-Blocks", + "RAINBOW_CONCRETE" : "Rainbow-Blocks", + "RAINBOW_GLAZED_TERRACOTTA" : "Rainbow-Blocks", + "REDSTONE_ALLOY" : "Redstone-Alloy-Ingot", + "REINFORCED_ALLOY_INGOT" : "Reinforced-Alloy-Ingot", + "SILVER_DUST" : "Silver-Dust", + "SILVER_INGOT" : "Silver-Ingot", + "SOLDER_INGOT" : "Solder-Ingot", + "SOULBOUND_HELMET" : "Soulbound-Armor", + "SOULBOUND_CHESTPLATE" : "Soulbound-Armor", + "SOULBOUND_LEGGINGS" : "Soulbound-Armor", + "SOULBOUND_BOOTS" : "Soulbound-Armor", + "ANCIENT_RUNE_SOULBOUND" : "Soulbound-Rune", + "SOULBOUND_SWORD" : "Soulbound-Weapons", + "SOULBOUND_BOW" : "Soulbound-Weapons", + "SOULBOUND_PICKAXE" : "Soulbound-Weapons", + "SOULBOUND_AXE" : "Soulbound-Weapons", + "SOULBOUND_SHOVEL" : "Soulbound-Weapons", + "SOULBOUND_HOE" : "Soulbound-Weapons", + "SOULBOUND_TRIDENT" : "Soulbound-Weapons", + "STEEL_INGOT" : "Steel-Ingot", + "SWORD_OF_BEHEADING" : "Sword-of-Beheading", + "COMMON_TALISMAN" : "Talismans", + "ENDER_TALISMAN" : "Talismans", + "TIN_DUST" : "Tin-Dust", + "TIN_INGOT" : "Tin-Ingot", + "GRANDMAS_WALKING_STICK" : "Walking-Sticks", + "GRANDPAS_WALKING_STICK" : "Walking-Sticks", + "ZINC_DUST" : "Zinc-Dust", + "ZINC_INGOT" : "Zinc-Ingot" } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java index 663d1e1bc..cd1055a5b 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestGuideCommand.java @@ -12,7 +12,7 @@ import org.junit.jupiter.params.provider.ValueSource; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; @@ -39,7 +39,7 @@ class TestGuideCommand { player.setOp(op); server.execute("slimefun", player, "guide").assertSucceeded(); - ItemStack guide = SlimefunGuide.getItem(SlimefunGuideLayout.CHEST); + ItemStack guide = SlimefunGuide.getItem(SlimefunGuideMode.SURVIVAL_MODE); Assertions.assertEquals(op, SlimefunUtils.containsSimilarItem(player.getInventory(), guide, true)); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java deleted file mode 100644 index 6d56a54e6..000000000 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestBookSlimefunGuide.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.thebusybiscuit.slimefun4.testing.tests.guide; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import be.seeseemelk.mockbukkit.MockBukkit; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; - -class TestBookSlimefunGuide { - - @BeforeAll - public static void load() { - MockBukkit.mock(); - MockBukkit.load(SlimefunPlugin.class); - } - - @AfterAll - public static void unload() { - MockBukkit.unmock(); - } - - @Test - @DisplayName("Test Getters for Chest Slimefun Guide") - void testBasicGetters() { - BookSlimefunGuide guide = new BookSlimefunGuide(); - - Assertions.assertEquals(SlimefunGuideLayout.BOOK, guide.getLayout()); - Assertions.assertTrue(guide.isSurvivalMode()); - } - -} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java deleted file mode 100644 index 5880e650f..000000000 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/guide/TestChestSlimefunGuide.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.thebusybiscuit.slimefun4.testing.tests.guide; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import be.seeseemelk.mockbukkit.MockBukkit; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; - -class TestChestSlimefunGuide { - - @BeforeAll - public static void load() { - MockBukkit.mock(); - MockBukkit.load(SlimefunPlugin.class); - } - - @AfterAll - public static void unload() { - MockBukkit.unmock(); - } - - @Test - @DisplayName("Test Getters for Chest Slimefun Guide") - void testBasicGetters() { - ChestSlimefunGuide guide = new ChestSlimefunGuide(false); - - Assertions.assertEquals(SlimefunGuideLayout.CHEST, guide.getLayout()); - Assertions.assertTrue(guide.isSurvivalMode()); - } - -} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestGrindstoneListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestGrindstoneListener.java index 19a74a5dc..b171f1570 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestGrindstoneListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestGrindstoneListener.java @@ -22,7 +22,7 @@ import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.GrindstoneListener; @@ -82,8 +82,8 @@ public class TestGrindstoneListener { } @ParameterizedTest - @EnumSource(SlimefunGuideLayout.class) - public void testGrindStoneWithSlimefunGuide(SlimefunGuideLayout layout) { + @EnumSource(SlimefunGuideMode.class) + public void testGrindStoneWithSlimefunGuide(SlimefunGuideMode layout) { InventoryClickEvent event = mockGrindStoneEvent(SlimefunGuide.getItem(layout)); Assertions.assertEquals(Result.DENY, event.getResult()); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java index 91cee4018..7330fcbdc 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java @@ -51,7 +51,7 @@ class TestSlimefunGuideListener { PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide"); listener.onJoin(event); - ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultLayout()); + ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultMode()); Assertions.assertEquals(!hasPlayedBefore && giveSlimefunGuide, hasSlimefunGuide(player, guide)); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java index 5a6d87450..bb0aadca7 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -19,7 +20,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory; import io.github.thebusybiscuit.slimefun4.core.categories.SeasonalCategory; -import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; @@ -28,7 +29,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class TestCategories { +class TestCategories { private static ServerMock server; private static SlimefunPlugin plugin; @@ -45,17 +46,23 @@ public class TestCategories { } @Test - public void testCategoryGetters() { + @DisplayName("Test the Getters for Category") + void testCategoryGetters() { Category category = new Category(new NamespacedKey(plugin, "getter_test"), new CustomItem(Material.DIAMOND_AXE, "&6Testing")); Assertions.assertEquals(3, category.getTier()); Assertions.assertEquals(new NamespacedKey(SlimefunPlugin.instance(), "getter_test"), category.getKey()); Assertions.assertEquals("Testing", category.getUnlocalizedName()); Assertions.assertEquals(0, category.getItems().size()); + + Assertions.assertNull(category.getAddon()); + category.register(plugin); + Assertions.assertEquals(plugin, category.getAddon()); } @Test - public void testAddItem() { + @DisplayName("Test adding an item to a Category") + void testAddItem() { Category category = new Category(new NamespacedKey(plugin, "items_test"), new CustomItem(Material.DIAMOND_AXE, "&6Testing")); SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "CATEGORY_ITEMS_TEST_ITEM", new CustomItem(Material.BAMBOO, "&6Test Bamboo")); item.setCategory(category); @@ -73,7 +80,8 @@ public class TestCategories { } @Test - public void testHidden() { + @DisplayName("Test hidden Categories") + void testHidden() { Category category = new Category(new NamespacedKey(plugin, "hiddenCategory"), new ItemStack(Material.BEACON)); Player player = server.addPlayer(); @@ -103,7 +111,8 @@ public class TestCategories { } @Test - public void testContains() { + @DisplayName("Test Category#contains") + void testContains() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "CATEGORY_TEST_ITEM_2", new CustomItem(Material.BOW, "&6Test Bow")); item.register(plugin); item.load(); @@ -118,16 +127,17 @@ public class TestCategories { } @Test - public void testLockedCategoriesParents() { + @DisplayName("Test LockedCategory parental locking") + void testLockedCategoriesParents() { Assertions.assertThrows(IllegalArgumentException.class, () -> new LockedCategory(new NamespacedKey(plugin, "locked"), new CustomItem(Material.GOLD_NUGGET, "&6Locked Test"), (NamespacedKey) null)); Category category = new Category(new NamespacedKey(plugin, "unlocked"), new CustomItem(Material.EMERALD, "&5I am SHERlocked")); - category.register(); + category.register(plugin); Category unregistered = new Category(new NamespacedKey(plugin, "unregistered"), new CustomItem(Material.EMERALD, "&5I am unregistered")); LockedCategory locked = new LockedCategory(new NamespacedKey(plugin, "locked"), new CustomItem(Material.GOLD_NUGGET, "&6Locked Test"), category.getKey(), unregistered.getKey()); - locked.register(); + locked.register(plugin); Assertions.assertTrue(locked.getParents().contains(category)); Assertions.assertFalse(locked.getParents().contains(unregistered)); @@ -143,17 +153,18 @@ public class TestCategories { } @Test - public void testLockedCategoriesUnlocking() throws InterruptedException { + @DisplayName("Test an unlocked LockedCategory") + void testLockedCategoriesUnlocking() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); Assertions.assertThrows(IllegalArgumentException.class, () -> new LockedCategory(new NamespacedKey(plugin, "locked"), new CustomItem(Material.GOLD_NUGGET, "&6Locked Test"), (NamespacedKey) null)); Category category = new Category(new NamespacedKey(plugin, "parent"), new CustomItem(Material.EMERALD, "&5I am SHERlocked")); - category.register(); + category.register(plugin); LockedCategory locked = new LockedCategory(new NamespacedKey(plugin, "locked"), new CustomItem(Material.GOLD_NUGGET, "&6Locked Test"), category.getKey()); - locked.register(); + locked.register(plugin); // No Items, so it should be unlocked Assertions.assertTrue(locked.hasUnlocked(player, profile)); @@ -176,7 +187,8 @@ public class TestCategories { } @Test - public void testSeasonalCategories() { + @DisplayName("Test a seasonal Category") + void testSeasonalCategories() { // Category with current Month Month month = LocalDate.now().getMonth(); SeasonalCategory category = new SeasonalCategory(new NamespacedKey(plugin, "seasonal"), month, 1, new CustomItem(Material.NETHER_STAR, "&cSeasonal Test")); @@ -196,16 +208,17 @@ public class TestCategories { } @Test - public void testFlexCategory() { + @DisplayName("Test the FlexCategory") + void testFlexCategory() { FlexCategory category = new FlexCategory(new NamespacedKey(plugin, "flex"), new CustomItem(Material.REDSTONE, "&4Weird flex but ok")) { @Override - public void open(Player p, PlayerProfile profile, SlimefunGuideLayout layout) { + public void open(Player p, PlayerProfile profile, SlimefunGuideMode layout) { // Nothing } @Override - public boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideLayout layout) { + public boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideMode layout) { return true; } }; diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java index 601d0d335..c320da673 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestHeadTextures.java @@ -16,7 +16,7 @@ class TestHeadTextures { void testForDuplicates() { Set textures = new HashSet<>(); - for (HeadTexture head : HeadTexture.valuesCache) { + for (HeadTexture head : HeadTexture.values()) { String texture = head.getTexture(); Assertions.assertNotNull(texture); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestMinecraftVersion.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestMinecraftVersion.java index 1bdb43a44..ed1fa31d8 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestMinecraftVersion.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/utils/TestMinecraftVersion.java @@ -11,12 +11,11 @@ class TestMinecraftVersion { @Test @DisplayName("Test if Minecraft versions match themselves") void testMatches() { - Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.matches("v1_14_R2")); - Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.matches("v1_15_R1")); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.isMinecraftVersion(14)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.isMinecraftVersion(15)); - Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.matches("v1_14_R2")); - Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_14.matches("1.14.x")); - Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.MINECRAFT_1_14.matches(null)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.isMinecraftVersion(14)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_14.isMinecraftVersion(0)); } @Test