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/TRIAGE_WORKFLOW.svg b/.github/TRIAGE_WORKFLOW.svg new file mode 100644 index 000000000..d7284d8f7 --- /dev/null +++ b/.github/TRIAGE_WORKFLOW.svg @@ -0,0 +1,3 @@ + + +
Yes
Yes
No
No
Related to
an addon?
Related to...
No
No
Yes
Yes
Using RC-version?
Using RC-versio...
Comment and tell them to update their version and their post
Comment and tell the...
Labels:
- invalid
Labels:...
Comment and post a
link to the correct bug tracker
Comment and post a...
Close Issue
Close Issue
Close Issue
Close Issue
Yes
Yes
Did they
update and respond?
Did they...
New Issue
New Issue
Reopen Issue
Reopen Issue
Set up a local test server and see if
you can reproduce the issue
Set up a local test...
No
No
Yes
Yes
Template
missing or
incomplete?
Template...
Comment and tell them to fill out the template correctly.
Comment and tell the...
Labels:
- invalid
Labels:...
Close Issue
Close Issue
Yes
Yes
No
No
Issue was
reproduced?
Issue was...
Labels:
- Bug Report
- Confirmed Bug
Labels:...
Labels:
- Bug Report
- Cannot reproduce
Labels:...
Comment and tell them that it could
not be reproduced
Comment and tell the...
Close Issue
Close Issue
Comment and give further context on how to reproduce it.

Examples:
- Video footage
- Screenshots
- Plugins list
- /sf versions
- Server log
Comment and give fur...
No
No
Yes
Yes
Is there
an open Issue
about it?
Is there...
Comment:
"Duplicate of #ISSUE"
Comment:...
Labels:
- Bug Report
- Duplicate
Labels:...
Close Issue
Close Issue
Version 1.0.1
By: TheBusyBiscuit
13 Jan 2021
Version 1.0.1...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/.github/workflows/closed-issues-reason.yml b/.github/workflows/closed-issues-reason.yml index f8d4017b3..262b9c54b 100644 --- a/.github/workflows/closed-issues-reason.yml +++ b/.github/workflows/closed-issues-reason.yml @@ -21,7 +21,7 @@ jobs: with: token: ${{ secrets.ACCESS_TOKEN }} issue_number: ${{ github.event.issue.number }} - labels: 'Resolved' + labels: '✔ Resolved' - uses: maxkomarychev/octions/octions/issues/create-comment@master id: comment if: contains(steps.resolved.outputs.issues, github.event.issue.number) == false diff --git a/.github/workflows/url-checker.yml b/.github/workflows/url-checker.yml deleted file mode 100644 index 42483c750..000000000 --- a/.github/workflows/url-checker.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: URL Validator - -on: - push: - branches: - - master - -jobs: - check: - - name: URL Checker - runs-on: ubuntu-latest - - steps: - - name: URL-checker - uses: SuperKogito/URLs-checker@0.2.1 - with: - git_path: https://github.com/Slimefun/Slimefun4 - file_types: .md,.java,.yml - print_all: false - retry_count: 2 - ## These URLs will always be correct, even if their services may be offline right now - white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349,https://gitlocalize.com/repo/3841 diff --git a/CHANGELOG.md b/CHANGELOG.md index 60212f5b5..e7be2c525 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,32 @@ -## Release Candidate 19 (TBD) +## Release Candidate 20 (TBD) + +#### Additions + +#### Changes + +#### Fixes +* Fixed elevator floor order +* Fixed #2449 +* Fixed #2511 +* Fixed #2636 +* Fixed a threading issue related to BlockStates and persistent data + +## 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 @@ -39,6 +57,10 @@ * Fixed ghost blocks to some extent (ghost blocks will now drop and be replaced) * Fixed #2636 (hotfix) * 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 93ce3821e..c84ba0856 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 @@ -314,7 +327,7 @@ com.github.seeseemelk MockBukkit-v1.16 - 0.18.0 + 0.20.0 test @@ -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.161 + 2.1.171 provided @@ -397,6 +410,13 @@ com.sk89q.worldguard worldguard-legacy + + + + + net.kyori + * + @@ -422,7 +442,7 @@ com.github.LoneDev6 itemsadder-api - 0.1.2 + 2.1.25 provided 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/NotHopperable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotHopperable.java new file mode 100644 index 000000000..5e284e569 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotHopperable.java @@ -0,0 +1,14 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; + +/** + * Implement this interface for any {@link AContainer} to prevent + * that {@link AContainer} from being hopperable. + * + * @author CURVX + * + */ +public interface NotHopperable extends ItemAttribute { + +} 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/categories/MultiCategory.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/MultiCategory.java index 9d85332c4..016a67bd3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/MultiCategory.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/MultiCategory.java @@ -1,7 +1,6 @@ package io.github.thebusybiscuit.slimefun4.core.categories; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import javax.annotation.Nonnull; @@ -13,18 +12,12 @@ import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent; -import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent; -import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; -import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; 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 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.utils.ChatUtils; +import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; @@ -68,52 +61,23 @@ public class MultiCategory extends FlexCategory { } @Override - public boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideLayout layout) { + public boolean isVisible(Player p, PlayerProfile profile, SlimefunGuideMode mode) { return true; } @Override - public void open(Player p, PlayerProfile profile, SlimefunGuideLayout layout) { - switch (layout) { - case BOOK: - showBookMenu(p, profile, 1); - break; - case CHEAT_SHEET: - showChestMenu(p, profile, layout, 1, true); - break; - case CHEST: - showChestMenu(p, profile, layout, 1, false); - break; - default: - break; - } + public void open(Player p, PlayerProfile profile, SlimefunGuideMode mode) { + openGuide(p, profile, mode, 1); } @ParametersAreNonnullByDefault - private void showBookMenu(Player p, PlayerProfile profile, int page) { - profile.getGuideHistory().add(this, page); - - List lines = new LinkedList<>(); - - for (SubCategory category : subCategories) { - 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 -> SlimefunGuide.openCategory(profile, category, SlimefunGuideLayout.BOOK, 1))); - lines.add(chatComponent); - } - - BookSlimefunGuide guide = (BookSlimefunGuide) SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideLayout.BOOK); - guide.showBook(p, profile, lines, true); - } - - @ParametersAreNonnullByDefault - private void showChestMenu(Player p, PlayerProfile profile, SlimefunGuideLayout layout, int page, boolean creativeMode) { - if (!creativeMode) { + private void openGuide(Player p, PlayerProfile profile, SlimefunGuideMode mode, int page) { + if (mode == SlimefunGuideMode.SURVIVAL_MODE) { profile.getGuideHistory().add(this, page); } ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main")); - ChestSlimefunGuide guide = (ChestSlimefunGuide) SlimefunPlugin.getRegistry().getGuideLayout(layout); + SurvivalSlimefunGuide guide = (SurvivalSlimefunGuide) SlimefunPlugin.getRegistry().getSlimefunGuide(mode); menu.setEmptySlotsClickable(false); menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), guide.getSound(), 1, 1)); @@ -121,7 +85,7 @@ public class MultiCategory extends FlexCategory { menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide")))); menu.addMenuClickHandler(1, (pl, s, is, action) -> { - SlimefunGuide.openMainMenu(profile, layout, 1); + SlimefunGuide.openMainMenu(profile, mode, 1); return false; }); @@ -135,7 +99,7 @@ public class MultiCategory extends FlexCategory { SubCategory category = subCategories.get(target); menu.addItem(index, category.getItem(p)); menu.addMenuClickHandler(index, (pl, slot, item, action) -> { - SlimefunGuide.openCategory(profile, category, layout, 1); + SlimefunGuide.openCategory(profile, category, mode, 1); return false; }); @@ -149,7 +113,7 @@ public class MultiCategory extends FlexCategory { int next = page - 1; if (next != page && next > 0) { - showChestMenu(p, profile, layout, next, creativeMode); + openGuide(p, profile, mode, next); } return false; @@ -160,7 +124,7 @@ public class MultiCategory extends FlexCategory { int next = page + 1; if (next != page && next <= pages) { - showChestMenu(p, profile, layout, next, creativeMode); + openGuide(p, profile, mode, next); } return false; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/SubCategory.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/SubCategory.java index 7ca411827..e418e45ec 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/SubCategory.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/categories/SubCategory.java @@ -8,6 +8,7 @@ import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import me.mrCookieSlime.Slimefun.Objects.Category; /** @@ -53,11 +54,11 @@ public class SubCategory extends Category { } @Override - public final void register() { - super.register(); + public final void register(@Nonnull SlimefunAddon addon) { + super.register(addon); if (!multiCategory.isRegistered()) { - multiCategory.register(); + multiCategory.register(addon); } } 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..6e3369de9 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; @@ -76,6 +75,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.EnhancedFurna import io.github.thebusybiscuit.slimefun4.implementation.listeners.ExplosionsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.GadgetsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHookListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.HopperListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemDropListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; @@ -113,6 +113,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 +149,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 +200,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 +226,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 +243,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 +405,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 +416,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 +431,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 +487,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 +568,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" }; @@ -524,6 +626,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new CartographyTableListener(this); new ButcherAndroidListener(this); new NetworkListener(this, networkManager); + new HopperListener(this); // Bees were added in 1.15 if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { @@ -564,6 +667,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 +683,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This loads all of our items. + */ private void loadItems() { try { SlimefunItemSetup.setup(this); @@ -585,6 +694,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This loads our researches. + */ private void loadResearches() { try { ResearchSetup.setupResearches(); @@ -593,6 +705,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 +729,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 +747,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 +845,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 +866,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 +878,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 +890,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 +999,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 +1071,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 11aa23fb1..000000000 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java +++ /dev/null @@ -1,261 +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 javax.annotation.ParametersAreNonnullByDefault; - -import org.apache.commons.lang.Validate; -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; - } - - @ParametersAreNonnullByDefault - public void showBook(Player p, PlayerProfile profile, List lines, boolean backButton) { - Validate.notNull(p, "Player cannot be null"); - Validate.notNull(profile, "Profile cannot be null"); - Validate.notNull(lines, "Lines cannot be null"); - - 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); - } - } - - showBook(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); - } - } - - showBook(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 19eadd1be..4d5353d6a 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 6bac97fdf..09d3557f0 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 @@ -28,6 +28,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; @@ -35,7 +36,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; @@ -52,18 +53,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; @@ -72,7 +72,7 @@ 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)"); } @@ -89,8 +89,8 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { } @Override - public SlimefunGuideLayout getLayout() { - return SlimefunGuideLayout.CHEST; + public SlimefunGuideMode getMode() { + return SlimefunGuideMode.SURVIVAL_MODE; } @Override @@ -98,9 +98,8 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { return item; } - @Override - public boolean isSurvivalMode() { - return true; + protected final boolean isSurvivalMode() { + return getMode() != SlimefunGuideMode.CHEAT_MODE; } /** @@ -117,8 +116,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); + } } } @@ -216,7 +225,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { } if (category instanceof FlexCategory) { - ((FlexCategory) category).open(p, profile, getLayout()); + ((FlexCategory) category).open(p, profile, getMode()); return; } @@ -226,6 +235,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { ChestMenu menu = create(p); createHeader(p, profile, menu); + addBackButton(menu, 1, p, profile); int pages = (category.getItems().size() - 1) / CATEGORY_SIZE + 1; @@ -573,7 +583,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; }); @@ -710,7 +720,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 c741431f5..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; @@ -673,6 +672,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, } } + @ParametersAreNonnullByDefault private void executeInstruction(Instruction instruction, Block b, BlockMenu inv, Config data, int index) { if (getAndroidType().isType(instruction.getRequiredType())) { String rotationData = data.getString("rotation"); @@ -830,14 +830,20 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, preset.addItem(34, getFuelSource().getItem(), ChestMenuUtils.getEmptyClickHandler()); } + @ParametersAreNonnullByDefault public void addItems(Block b, ItemStack... items) { + Validate.notNull(b, "The Block cannot be null."); + BlockMenu inv = BlockStorage.getInventory(b); - for (ItemStack item : items) { - inv.pushItem(item, getOutputSlots()); + if (inv != null) { + for (ItemStack item : items) { + inv.pushItem(item, getOutputSlots()); + } } } + @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 -> { @@ -875,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 6546e4d6b..926ed200f 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,12 +11,12 @@ 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.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; @@ -89,9 +89,9 @@ public class HologramProjector extends SlimefunItem { 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/electric/machines/AutoBrewer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java index 627fe50a9..9dcb2db78 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java @@ -12,12 +12,13 @@ import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionType; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; -import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; /** * @@ -26,7 +27,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; * @author Linox * */ -public class AutoBrewer extends AContainer { +public class AutoBrewer extends AContainer implements NotHopperable { private static final Map potionRecipes = new EnumMap<>(Material.class); private static final Map fermentations = new EnumMap<>(PotionType.class); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDrier.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDrier.java index 9273af6b4..cea222eae 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDrier.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDrier.java @@ -7,6 +7,7 @@ import org.bukkit.Material; import org.bukkit.Tag; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import me.mrCookieSlime.Slimefun.Lists.RecipeType; @@ -22,7 +23,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * @author Linox * */ -public class AutoDrier extends AContainer implements RecipeDisplayItem { +public class AutoDrier extends AContainer implements RecipeDisplayItem, NotHopperable { private List recipeList; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricFurnace.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricFurnace.java index 8d70af663..ba2071cf6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricFurnace.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricFurnace.java @@ -7,12 +7,13 @@ import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.RecipeChoice.MaterialChoice; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; -public class ElectricFurnace extends AContainer { +public class ElectricFurnace extends AContainer implements NotHopperable { public ElectricFurnace(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricIngotPulverizer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricIngotPulverizer.java index 1fe511565..1b9e51673 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricIngotPulverizer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricIngotPulverizer.java @@ -6,6 +6,7 @@ import java.util.List; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import me.mrCookieSlime.Slimefun.Lists.RecipeType; @@ -23,7 +24,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * @see ElectricIngotFactory * */ -public class ElectricIngotPulverizer extends AContainer implements RecipeDisplayItem { +public class ElectricIngotPulverizer extends AContainer implements RecipeDisplayItem, NotHopperable { public ElectricIngotPulverizer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricOreGrinder.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricOreGrinder.java index 50187ea92..2a8675258 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricOreGrinder.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricOreGrinder.java @@ -3,13 +3,14 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; -public class ElectricOreGrinder extends AContainer implements RecipeDisplayItem { +public class ElectricOreGrinder extends AContainer implements RecipeDisplayItem, NotHopperable { public ElectricOreGrinder(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java index 0768c6621..a0ce3cd4d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java @@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; @@ -21,13 +22,13 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenu import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; /** * The {@link ElectricSmeltery} is an electric version of the standard {@link Smeltery}. @@ -35,7 +36,7 @@ import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; * @author TheBusyBiscuit * */ -public class ElectricSmeltery extends AContainer { +public class ElectricSmeltery extends AContainer implements NotHopperable { private static final int[] border = { 4, 5, 6, 7, 8, 13, 31, 40, 41, 42, 43, 44 }; private static final int[] inputBorder = { 0, 1, 2, 3, 9, 12, 18, 21, 27, 30, 36, 37, 38, 39 }; 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..82a322bee 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 @@ -10,6 +10,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -50,7 +51,10 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; */ public class BlockListener implements Listener { + private final SlimefunPlugin plugin; + public BlockListener(@Nonnull SlimefunPlugin plugin) { + this.plugin = plugin; plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -63,18 +67,26 @@ public class BlockListener implements Listener { */ Block block = e.getBlock(); + // Fixes #2636 if (e.getBlockReplacedState().getType().isAir()) { 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); - } - } + /* + * We can move the TickerTask synchronization to an async task to + * avoid blocking the main Thread here. */ - BlockStorage.clearBlockInfo(block); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + if (!SlimefunPlugin.getTickerTask().isDeletedSoon(block.getLocation())) { + for (ItemStack item : sfItem.getDrops()) { + if (item != null && !item.getType().isAir()) { + SlimefunPlugin.runSync(() -> block.getWorld().dropItemNaturally(block.getLocation(), item)); + } + } + + BlockStorage.clearBlockInfo(block); + } + }); } } else if (BlockStorage.hasBlockInfo(e.getBlock())) { e.setCancelled(true); @@ -118,7 +130,7 @@ public class BlockListener implements Listener { int fortune = getBonusDropsWithFortune(item, e.getBlock()); List drops = new ArrayList<>(); - if (item.getType() != Material.AIR) { + if (!item.getType().isAir()) { callToolHandler(e, item, fortune, drops); } @@ -158,9 +170,13 @@ public class BlockListener implements Listener { SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getId()); if (blockHandler != null) { - if (!blockHandler.onBreak(e.getPlayer(), e.getBlock(), sfItem, UnregisterReason.PLAYER_BREAK)) { - e.setCancelled(true); - return; + try { + if (!blockHandler.onBreak(e.getPlayer(), e.getBlock(), sfItem, UnregisterReason.PLAYER_BREAK)) { + e.setCancelled(true); + return; + } + } catch (Exception | LinkageError x) { + sfItem.error("Something went wrong while triggering a BlockHandler", x); } } else { sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onBlockBreak(e, item, fortune, drops)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java index fd4bbd44e..bd3b8f760 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java @@ -94,7 +94,7 @@ public class BlockPhysicsListener implements Listener { Location loc = block.getLocation(); // Fixes #2496 - Make sure it is not a moving block - if (SlimefunPlugin.getTickerTask().isReserved(loc)) { + if (SlimefunPlugin.getTickerTask().isOccupiedSoon(loc)) { e.setCancelled(true); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java index d2db858fc..0a3d4f693 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java @@ -68,7 +68,8 @@ public class ButcherAndroidListener implements Listener { } /** - * Some items are not dropped by default. Wither Skeleton Skulls but for some weird reason + * Some items are not dropped by default. + * Wither Skeleton Skulls but for some weird reason * even Blaze rods... * * @param drops 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 c2d39a904..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 @@ -6,6 +6,7 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Skull; @@ -28,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. @@ -86,14 +86,19 @@ public class DebugFishListener implements Listener { @ParametersAreNonnullByDefault private void onRightClick(Player p, Block b, BlockFace face) { if (p.isSneaking()) { - Block block = b.getRelative(face); - block.setType(Material.PLAYER_HEAD); - SkullBlock.setFromHash(block, HeadTexture.MISSING_TEXTURE.getTexture()); + // Fixes #2655 - Delaying the placement to prevent a new event from being fired + SlimefunPlugin.runSync(() -> { + Block block = b.getRelative(face); + block.setType(Material.PLAYER_HEAD); + SkullBlock.setFromHash(block, HeadTexture.MISSING_TEXTURE.getTexture()); + + p.playSound(block.getLocation(), Sound.BLOCK_BAMBOO_PLACE, 1, 1); + }, 2L); } else if (BlockStorage.hasBlockInfo(b)) { 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/HopperListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/HopperListener.java new file mode 100644 index 000000000..94c07556e --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/HopperListener.java @@ -0,0 +1,38 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import javax.annotation.Nonnull; + +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryType; + +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; +import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; + +/** + * This {@link Listener} prevents item from being transferred to + * and from {@link AContainer} using a hopper. + * + * @author CURVX + * + * @see NotHopperable + * + */ +public class HopperListener implements Listener { + + public HopperListener(@Nonnull SlimefunPlugin plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onHopperInsert(InventoryMoveItemEvent e) { + Location loc = e.getDestination().getLocation(); + if (e.getSource().getType() == InventoryType.HOPPER && loc != null && BlockStorage.check(loc.getBlock()) instanceof NotHopperable) { + e.setCancelled(true); + } + } +} 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/resources/NetherIceResource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/NetherIceResource.java index eef7c7e85..3d7e79608 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/NetherIceResource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/NetherIceResource.java @@ -3,8 +3,16 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources; import org.bukkit.World.Environment; import org.bukkit.block.Biome; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +/** + * A {@link GEOResource} which consists of nether ice. + * It can only be found in the nether. + * + * @author TheBusyBiscuit + * + */ class NetherIceResource extends SlimefunResource { NetherIceResource() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/OilResource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/OilResource.java index 551af133b..c45cc768d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/OilResource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/OilResource.java @@ -3,8 +3,21 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources; import org.bukkit.World.Environment; import org.bukkit.block.Biome; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner; +import io.github.thebusybiscuit.slimefun4.implementation.items.geo.OilPump; +/** + * A {@link GEOResource} which consists of buckets of Oil. + * It cannot be obtained via a {@link GEOMiner} but instead requires + * and {@link OilPump}. + * + * @author TheBusyBiscuit + * + * @see OilPump + * + */ class OilResource extends SlimefunResource { OilResource() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SaltResource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SaltResource.java index a75ad23c5..532bfa339 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SaltResource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SaltResource.java @@ -3,8 +3,15 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources; import org.bukkit.World.Environment; import org.bukkit.block.Biome; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +/** + * A {@link GEOResource} which consists of Salt. + * + * @author TheBusyBiscuit + * + */ class SaltResource extends SlimefunResource { SaltResource() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SlimefunResource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SlimefunResource.java index fd10467fb..03953e0ac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SlimefunResource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SlimefunResource.java @@ -10,6 +10,17 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +/** + * This is an abstract parent class for any {@link GEOResource} + * that is added by Slimefun itself. It is package-private, therefore + * only classes inside this package can access it. + *

+ * It just provides a bit of a convenience for us to reduce redundancies + * in our {@link GEOResource} implementations. + * + * @author TheBusyBiscuit + * + */ abstract class SlimefunResource implements GEOResource { private final NamespacedKey key; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/UraniumResource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/UraniumResource.java index 3b7f3584f..831d8ffdd 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/UraniumResource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/UraniumResource.java @@ -3,8 +3,15 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources; import org.bukkit.World.Environment; import org.bukkit.block.Biome; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +/** + * A {@link GEOResource} which consists of small chunks of Uranium. + * + * @author TheBusyBiscuit + * + */ class UraniumResource extends SlimefunResource { UraniumResource() { 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..aee8512fe 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); @@ -253,10 +252,26 @@ public class TickerTask implements Runnable { * * @return Whether this {@link Location} has been reserved and will be filled upon the next tick */ - public boolean isReserved(@Nonnull Location l) { + public boolean isOccupiedSoon(@Nonnull Location l) { + Validate.notNull(l, "Null is not a valid Location!"); + return movingQueue.containsValue(l); } + /** + * This method checks if a given {@link Location} will be deleted on the next tick. + * + * @param l + * The {@link Location} to check + * + * @return Whether this {@link Location} will be deleted on the next tick + */ + public boolean isDeletedSoon(@Nonnull Location l) { + Validate.notNull(l, "Null is not a valid Location!"); + + return deletionQueue.containsKey(l); + } + /** * This returns the delay between ticks * 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 6d997d8c7..978e39863 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java @@ -20,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; @@ -38,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; @@ -96,12 +99,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}. * @@ -263,7 +283,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..5cca61a0d 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,7 +150,8 @@ public class SlimefunItem implements Placeable { * @param recipeOutput * The result of crafting this item */ - public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { + @ParametersAreNonnullByDefault + public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, @Nullable ItemStack recipeOutput) { Validate.notNull(category, "'category' is not allowed to be null!"); Validate.notNull(item, "'item' is not allowed to be null!"); Validate.notNull(recipeType, "'recipeType' 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!"); @@ -259,10 +263,21 @@ public class SlimefunItem implements Placeable { * @return The linked {@link Research} or null */ @Nullable - public Research getResearch() { + public final Research getResearch() { return research; } + /** + * This returns whether this {@link SlimefunItem} has a {@link Research} + * assigned to it. + * It is equivalent to a null check performed on {@link #getResearch()}. + * + * @return Whether this {@link SlimefunItem} has a {@link Research} + */ + public final boolean hasResearch() { + return research != null; + } + /** * This returns a {@link Set} containing all instances of {@link ItemSetting} for this {@link SlimefunItem}. * @@ -371,7 +386,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 +491,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 author(s) 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 +526,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 +592,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..8870e9534 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; } @@ -673,7 +673,8 @@ public class BlockStorage { @Nullable public static String checkID(@Nonnull Block b) { - if (SlimefunPlugin.getBlockDataService().isTileEntity(b.getType())) { + // Only access the BlockState when on the main thread + if (Bukkit.isPrimaryThread() && SlimefunPlugin.getBlockDataService().isTileEntity(b.getType())) { Optional blockData = SlimefunPlugin.getBlockDataService().getBlockData(b); if (blockData.isPresent()) { @@ -817,7 +818,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