> 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 32671d0c8..8bced8798 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 abf17e55d..98dfa4a69 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,11 +14,11 @@ 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;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
-import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* Represents a {@link Category} that cannot be opened until the parent category/categories
@@ -76,8 +76,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 +94,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() });
}
}
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 14c1345b4..000000000
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java
+++ /dev/null
@@ -1,253 +0,0 @@
-package io.github.thebusybiscuit.slimefun4.implementation.guide;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-
-import org.bukkit.ChatColor;
-import org.bukkit.NamespacedKey;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.ItemStack;
-
-import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
-import io.github.thebusybiscuit.cscorelib2.chat.ChatInput;
-import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent;
-import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent;
-import io.github.thebusybiscuit.cscorelib2.chat.json.CustomBookInterface;
-import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent;
-import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
-import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
-import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
-import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory;
-import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
-import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
-import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
-import io.github.thebusybiscuit.slimefun4.core.researching.Research;
-import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
-import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
-import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
-import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem;
-import me.mrCookieSlime.Slimefun.Objects.Category;
-import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
-import me.mrCookieSlime.Slimefun.api.Slimefun;
-
-/**
- * The {@link BookSlimefunGuide} is a {@link SlimefunGuideImplementation} which
- * uses a {@link CustomBookInterface} to display the contents of the {@link SlimefunGuide}.
- * {@link Player Players} have the option to choose this Written Book layout over the
- * standard {@link Inventory} variant.
- *
- * @author TheBusyBiscuit
- *
- * @see SlimefunGuide
- * @see SlimefunGuideImplementation
- * @see ChestSlimefunGuide
- * @see CheatSheetSlimefunGuide
- *
- */
-public class BookSlimefunGuide implements SlimefunGuideImplementation {
-
- private final NamespacedKey guideSearch = new NamespacedKey(SlimefunPlugin.instance(), "search");
- private final ItemStack item;
-
- public BookSlimefunGuide() {
- item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Book GUI)");
- }
-
- @Override
- public SlimefunGuideLayout getLayout() {
- return SlimefunGuideLayout.BOOK;
- }
-
- @Override
- public boolean isSurvivalMode() {
- return true;
- }
-
- @Override
- public ItemStack getItem() {
- return item;
- }
-
- private void openBook(Player p, PlayerProfile profile, List lines, boolean backButton) {
- CustomBookInterface book = new CustomBookInterface(SlimefunPlugin.instance());
- book.setTitle(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main"));
-
- for (int i = 0; i < lines.size(); i = i + 10) {
- ChatComponent page = new ChatComponent("");
- ChatComponent header = new ChatComponent(ChatColors.color("&b&l- " + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main") + " -\n\n"));
- header.setHoverEvent(new HoverEvent(ChestMenuUtils.getSearchButton(p)));
-
- header.setClickEvent(new ClickEvent(guideSearch, player -> SlimefunPlugin.runSync(() -> {
- SlimefunPlugin.getLocalization().sendMessage(player, "guide.search.message");
- ChatInput.waitForPlayer(SlimefunPlugin.instance(), player, msg -> SlimefunGuide.openSearch(profile, msg, true, true));
- }, 1)));
-
- page.append(header);
-
- for (int j = i; j < lines.size() && j < i + 10; j++) {
- page.append(lines.get(j));
- }
-
- page.append(new ChatComponent("\n"));
-
- if (backButton) {
- ChatComponent button = new ChatComponent(ChatColor.DARK_BLUE + "\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"));
- button.setHoverEvent(new HoverEvent(ChatColor.DARK_BLUE + "\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"), "", ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide")));
- button.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance(), "slimefun_guide"), pl -> openMainMenu(profile, 1)));
- page.append(button);
- }
-
- book.addPage(page);
- }
-
- book.open(p);
- }
-
- @Override
- public void openMainMenu(PlayerProfile profile, int page) {
- Player p = profile.getPlayer();
-
- if (p == null) {
- return;
- }
-
- List lines = new LinkedList<>();
- int tier = 0;
-
- for (Category category : SlimefunPlugin.getRegistry().getCategories()) {
- if (!category.isHidden(p) && (!(category instanceof FlexCategory) || ((FlexCategory) category).isVisible(p, profile, getLayout()))) {
- if (tier < category.getTier()) {
- tier = category.getTier();
-
- if (tier > 1) {
- for (int i = 0; i < 10 && lines.size() % 10 != 0; i++) {
- lines.add(new ChatComponent("\n"));
- }
- }
-
- lines.add(new ChatComponent(ChatColor.DARK_GRAY + "\u21E8" + ChatColor.DARK_BLUE + " Tier " + tier + "\n"));
- }
-
- addCategory(p, profile, category, lines);
- }
- }
-
- openBook(p, profile, lines, false);
- }
-
- private void addCategory(Player p, PlayerProfile profile, Category category, List lines) {
- if (category instanceof LockedCategory && !((LockedCategory) category).hasUnlocked(p, profile)) {
- List lore = new LinkedList<>();
- lore.add(ChatColor.DARK_RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked") + " " + ChatColor.GRAY + "- " + ChatColor.RESET + category.getItem(p).getItemMeta().getDisplayName());
- lore.add("");
-
- for (String line : SlimefunPlugin.getLocalization().getMessages(p, "guide.locked-category")) {
- lore.add(ChatColor.RESET + line);
- }
-
- lore.add("");
-
- for (Category parent : ((LockedCategory) category).getParents()) {
- lore.add(parent.getItem(p).getItemMeta().getDisplayName());
- }
-
- ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.RED, ItemUtils.getItemName(category.getItem(p))) + "\n");
- chatComponent.setHoverEvent(new HoverEvent(lore));
- lines.add(chatComponent);
- } else {
- ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, ItemUtils.getItemName(category.getItem(p))) + "\n");
- chatComponent.setHoverEvent(new HoverEvent(ItemUtils.getItemName(category.getItem(p)), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category")));
- chatComponent.setClickEvent(new ClickEvent(category.getKey(), pl -> openCategory(profile, category, 1)));
- lines.add(chatComponent);
- }
- }
-
- @Override
- public void openCategory(PlayerProfile profile, Category category, int page) {
- Player p = profile.getPlayer();
-
- if (p == null) {
- return;
- }
-
- if (category instanceof FlexCategory) {
- ((FlexCategory) category).open(p, profile, getLayout());
- } else if (category.getItems().size() < 250) {
- profile.getGuideHistory().add(category, page);
-
- List items = new LinkedList<>();
-
- for (SlimefunItem slimefunItem : category.getItems()) {
- if (Slimefun.hasPermission(p, slimefunItem, false)) {
- if (Slimefun.isEnabled(p, slimefunItem, false)) {
- addSlimefunItem(category, page, p, profile, slimefunItem, items);
- }
- } else {
- ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_RED, ItemUtils.getItemName(slimefunItem.getItem())) + "\n");
-
- List lore = new ArrayList<>();
- lore.add(ChatColor.DARK_RED + ChatColor.stripColor(ItemUtils.getItemName(slimefunItem.getItem())));
- lore.add("");
-
- for (String line : SlimefunPlugin.getPermissionsService().getLore(slimefunItem)) {
- lore.add(ChatColors.color(line));
- }
-
- component.setHoverEvent(new HoverEvent(lore));
- items.add(component);
- }
- }
-
- openBook(p, profile, items, true);
- } else {
- p.sendMessage(ChatColor.RED + "That Category is too big to open :/");
- }
- }
-
- private void addSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List items) {
- NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getId().toLowerCase(Locale.ROOT));
-
- if (!item.canUse(p, false) && item.hasResearch()) {
- Research research = item.getResearch();
-
- ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.RED, item.getItemName()) + "\n");
- component.setHoverEvent(new HoverEvent(ChatColor.RESET + item.getItemName(), ChatColor.DARK_RED.toString() + ChatColor.BOLD + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", ChatColor.GREEN + "> Click to unlock", "", ChatColor.GRAY + "Cost: " + ChatColor.AQUA.toString() + research.getCost() + " Level(s)"));
- component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> research.unlockFromGuide(this, player, profile, item, category, page))));
-
- items.add(component);
- } else {
- ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, item.getItemName()) + "\n");
-
- List lore = new ArrayList<>();
- lore.add(item.getItemName());
-
- if (item.getItem().hasItemMeta() && item.getItem().getItemMeta().hasLore()) {
- lore.addAll(item.getItem().getItemMeta().getLore());
- }
-
- component.setHoverEvent(new HoverEvent(lore));
- component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> displayItem(profile, item, true))));
- items.add(component);
- }
- }
-
- @Override
- public void openSearch(PlayerProfile profile, String input, boolean addToHistory) {
- // We need to write a book implementation for this at some point
- SlimefunGuide.openSearch(profile, input, true, addToHistory);
- }
-
- @Override
- public void displayItem(PlayerProfile profile, ItemStack item, int index, boolean addToHistory) {
- SlimefunGuide.displayItem(profile, item, addToHistory);
- }
-
- @Override
- public void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) {
- SlimefunGuide.displayItem(profile, item, addToHistory);
- }
-
-}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java
index d02c04c7e..f45f47272 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java
@@ -12,7 +12,7 @@ import org.bukkit.inventory.Recipe;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
-import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
+import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem;
@@ -21,13 +21,13 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
- * This is an admin-variant of the {@link ChestSlimefunGuide} which allows a {@link Player}
+ * This is an admin-variant of the {@link SurvivalSlimefunGuide} which allows a {@link Player}
* to spawn in a {@link SlimefunItem} via click rather than showing their {@link Recipe}.
*
* @author TheBusyBiscuit
*
*/
-public class CheatSheetSlimefunGuide extends ChestSlimefunGuide {
+public class CheatSheetSlimefunGuide extends SurvivalSlimefunGuide {
private final ItemStack item;
@@ -37,11 +37,6 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide {
item = new SlimefunGuideItem(this, "&cSlimefun Guide &4(Cheat Sheet)");
}
- @Override
- public boolean isSurvivalMode() {
- return false;
- }
-
/**
* Returns a {@link List} of visible {@link Category} instances that the {@link SlimefunGuide} would display.
*
@@ -65,11 +60,13 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide {
return categories;
}
+ @Nonnull
@Override
- public SlimefunGuideLayout getLayout() {
- return SlimefunGuideLayout.CHEAT_SHEET;
+ public SlimefunGuideMode getMode() {
+ return SlimefunGuideMode.CHEAT_MODE;
}
+ @Nonnull
@Override
public ItemStack getItem() {
return item;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java
index 51917a37e..acb1b57f9 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/RecipeChoiceTask.java
@@ -21,7 +21,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
* A {@link RecipeChoiceTask} is an asynchronously repeating task that cycles
* through the different variants of {@link Material} that a {@link MaterialChoice} or {@link Tag} can represent.
*
- * It is used in the {@link ChestSlimefunGuide} for any {@link ItemStack} from Minecraft
+ * It is used in the {@link SurvivalSlimefunGuide} for any {@link ItemStack} from Minecraft
* that accepts more than one {@link Material} in its {@link Recipe}.
*
* @author TheBusyBiscuit
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java
similarity index 94%
rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java
rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java
index 23b673c39..c59c7dfb9 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java
@@ -27,6 +27,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatInput;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.recipes.MinecraftRecipe;
+import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
@@ -34,7 +35,7 @@ import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory;
import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
-import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
+import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
@@ -51,18 +52,17 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
- * The {@link ChestSlimefunGuide} is the standard version of our {@link SlimefunGuide}.
+ * The {@link SurvivalSlimefunGuide} is the standard version of our {@link SlimefunGuide}.
* It uses an {@link Inventory} to display {@link SlimefunGuide} contents.
*
* @author TheBusyBiscuit
*
* @see SlimefunGuide
* @see SlimefunGuideImplementation
- * @see BookSlimefunGuide
* @see CheatSheetSlimefunGuide
*
*/
-public class ChestSlimefunGuide implements SlimefunGuideImplementation {
+public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
private static final int CATEGORY_SIZE = 36;
private static final Sound sound = Sound.ITEM_BOOK_PAGE_TURN;
@@ -71,14 +71,14 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
private final ItemStack item;
private final boolean showVanillaRecipes;
- public ChestSlimefunGuide(boolean showVanillaRecipes) {
+ public SurvivalSlimefunGuide(boolean showVanillaRecipes) {
this.showVanillaRecipes = showVanillaRecipes;
item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)");
}
@Override
- public SlimefunGuideLayout getLayout() {
- return SlimefunGuideLayout.CHEST;
+ public SlimefunGuideMode getMode() {
+ return SlimefunGuideMode.SURVIVAL_MODE;
}
@Override
@@ -86,9 +86,8 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
return item;
}
- @Override
- public boolean isSurvivalMode() {
- return true;
+ protected final boolean isSurvivalMode() {
+ return getMode() != SlimefunGuideMode.CHEAT_MODE;
}
/**
@@ -105,8 +104,18 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
List categories = new LinkedList<>();
for (Category category : SlimefunPlugin.getRegistry().getCategories()) {
- if (!category.isHidden(p) && (!(category instanceof FlexCategory) || ((FlexCategory) category).isVisible(p, profile, getLayout()))) {
- categories.add(category);
+ try {
+ if (!category.isHidden(p) && (!(category instanceof FlexCategory) || ((FlexCategory) category).isVisible(p, profile, getMode()))) {
+ categories.add(category);
+ }
+ } catch (Exception | LinkageError x) {
+ SlimefunAddon addon = category.getAddon();
+
+ if (addon != null) {
+ addon.getLogger().log(Level.SEVERE, x, () -> "Could not display Category: " + category);
+ } else {
+ SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "Could not display Category: " + category);
+ }
}
}
@@ -204,7 +213,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
}
if (category instanceof FlexCategory) {
- ((FlexCategory) category).open(p, profile, getLayout());
+ ((FlexCategory) category).open(p, profile, getMode());
return;
}
@@ -561,7 +570,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
pl.closeInventory();
SlimefunPlugin.getLocalization().sendMessage(pl, "guide.search.message");
- ChatInput.waitForPlayer(SlimefunPlugin.instance(), pl, msg -> SlimefunGuide.openSearch(profile, msg, isSurvivalMode(), isSurvivalMode()));
+ ChatInput.waitForPlayer(SlimefunPlugin.instance(), pl, msg -> SlimefunGuide.openSearch(profile, msg, getMode(), isSurvivalMode()));
return false;
});
@@ -698,7 +707,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
private void printErrorMessage(Player p, Throwable x) {
p.sendMessage(ChatColor.DARK_RED + "An internal server error has occurred. Please inform an admin, check the console for further info.");
- Slimefun.getLogger().log(Level.SEVERE, "An error has occurred while trying to open a SlimefunItem in the guide!", x);
+ SlimefunPlugin.logger().log(Level.SEVERE, "An error has occurred while trying to open a SlimefunItem in the guide!", x);
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java
deleted file mode 100644
index 01117440f..000000000
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
-
-import java.util.Optional;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
-import org.bukkit.Effect;
-import org.bukkit.block.Block;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
-import me.mrCookieSlime.Slimefun.Lists.RecipeType;
-import me.mrCookieSlime.Slimefun.Objects.Category;
-import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
-import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
-
-/**
- * The {@link AdvancedFarmerAndroid} is an extension of the {@link FarmerAndroid}.
- * It also allows the {@link Player} to harvest plants from the addon ExoticGarden.
- *
- * @author John000708
- * @author TheBusyBiscuit
- *
- * @see FarmerAndroid
- *
- */
-public class AdvancedFarmerAndroid extends FarmerAndroid {
-
- @ParametersAreNonnullByDefault
- public AdvancedFarmerAndroid(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
- super(category, tier, item, recipeType, recipe);
- }
-
- @Override
- public AndroidType getAndroidType() {
- return AndroidType.ADVANCED_FARMER;
- }
-
- @Override
- protected void exoticFarm(BlockMenu menu, Block block) {
- farm(menu, block);
-
- if (SlimefunPlugin.getIntegrations().isExoticGardenInstalled()) {
- Optional result = SlimefunPlugin.getThirdPartySupportService().harvestExoticGardenPlant(block);
-
- if (result.isPresent()) {
- ItemStack drop = result.get();
- menu.pushItem(drop, getOutputSlots());
- block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
- }
- }
- }
-
-}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java
index 732c998a3..fbbbdb108 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidType.java
@@ -29,7 +29,7 @@ public enum AndroidType {
FARMER,
/**
- * The {@link AdvancedFarmerAndroid} is an extension of the {@link FarmerAndroid},
+ * The Advanced Farmer is an extension of the {@link FarmerAndroid},
* it can also harvest plants from ExoticGarden.
*/
ADVANCED_FARMER,
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java
index e46721c84..44948ab4b 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/FarmerAndroid.java
@@ -3,6 +3,9 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -10,6 +13,7 @@ import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack;
+import io.github.thebusybiscuit.slimefun4.api.events.AndroidFarmEvent;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@@ -17,37 +21,41 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
public class FarmerAndroid extends ProgrammableAndroid {
+ @ParametersAreNonnullByDefault
public FarmerAndroid(Category category, int tier, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, tier, item, recipeType, recipe);
}
@Override
public AndroidType getAndroidType() {
- return AndroidType.FARMER;
- }
-
- private boolean isFullGrown(Block block) {
- BlockData data = block.getBlockData();
-
- if (!(data instanceof Ageable)) {
- return false;
- }
-
- Ageable ageable = (Ageable) data;
- return ageable.getAge() >= ageable.getMaximumAge();
+ return getTier() == 1 ? AndroidType.FARMER : AndroidType.ADVANCED_FARMER;
}
@Override
- protected void farm(BlockMenu menu, Block block) {
- if (isFullGrown(block)) {
- ItemStack drop = getDropFromCrop(block.getType());
+ protected void farm(Block b, BlockMenu menu, Block block, boolean isAdvanced) {
+ Material blockType = block.getType();
+ BlockData data = block.getBlockData();
+ ItemStack drop = null;
- if (drop != null && menu.fits(drop, getOutputSlots())) {
- menu.pushItem(drop, getOutputSlots());
- Ageable ageable = (Ageable) block.getBlockData();
- ageable.setAge(0);
- block.setBlockData(ageable);
- block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
+ if (data instanceof Ageable && ((Ageable) data).getAge() >= ((Ageable) data).getMaximumAge()) {
+ drop = getDropFromCrop(blockType);
+ }
+
+ AndroidInstance instance = new AndroidInstance(this, b);
+
+ AndroidFarmEvent event = new AndroidFarmEvent(block, instance, isAdvanced, drop);
+ Bukkit.getPluginManager().callEvent(event);
+
+ if (!event.isCancelled()) {
+ drop = event.getDrop();
+
+ if (drop != null && menu.pushItem(drop, getOutputSlots()) == null) {
+ block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, blockType);
+
+ if (data instanceof Ageable) {
+ ((Ageable) data).setAge(0);
+ block.setBlockData(data);
+ }
}
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java
index 6c707c979..4f1ffef80 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/Instruction.java
@@ -1,11 +1,12 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Predicate;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Predicate;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
@@ -191,7 +192,7 @@ public enum Instruction {
*/
FARM_FORWARD(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> {
Block target = b.getRelative(face);
- android.farm(inv, target);
+ android.farm(b, inv, target, false);
}),
/**
@@ -200,7 +201,7 @@ public enum Instruction {
*/
FARM_DOWN(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> {
Block target = b.getRelative(BlockFace.DOWN);
- android.farm(inv, target);
+ android.farm(b, inv, target, false);
}),
/**
@@ -211,7 +212,7 @@ public enum Instruction {
*/
FARM_EXOTIC_FORWARD(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> {
Block target = b.getRelative(face);
- android.exoticFarm(inv, target);
+ android.farm(b, inv, target, true);
}),
/**
@@ -222,7 +223,7 @@ public enum Instruction {
*/
FARM_EXOTIC_DOWN(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> {
Block target = b.getRelative(BlockFace.DOWN);
- android.exoticFarm(inv, target);
+ android.farm(b, inv, target, true);
}),
/**
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java
index 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/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 b0741f11b..c0c4a63a1 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);
- // Fixes #2636
- if (sfItem != null && !SlimefunPlugin.getTickerTask().isDeletedSoon(block.getLocation())) {
- for (ItemStack item : sfItem.getDrops()) {
- if (item != null && !item.getType().isAir()) {
- block.getWorld().dropItemNaturally(block.getLocation(), item);
- }
- }
+ if (sfItem != null) {
+ /*
+ * We can move the TickerTask synchronization to an async task to
+ * avoid blocking the main Thread here.
+ */
+ 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);
+ BlockStorage.clearBlockInfo(block);
+ }
+ });
}
} else if (BlockStorage.hasBlockInfo(e.getBlock())) {
e.setCancelled(true);
@@ -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 75b9ea9a9..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,7 +252,7 @@ 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);
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 1e7b76000..c7446de7f 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java
@@ -48,8 +48,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() {}
@@ -111,8 +109,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;
}
}
@@ -143,13 +142,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/me/mrCookieSlime/Slimefun/Objects/Category.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java
index 8c788e94f..cf95721f3 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/Category.java
@@ -7,6 +7,7 @@ import java.util.Comparator;
import java.util.List;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
@@ -19,6 +20,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
+import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory;
import io.github.thebusybiscuit.slimefun4.core.categories.SeasonalCategory;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
@@ -37,6 +39,8 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class Category implements Keyed {
+ private SlimefunAddon addon;
+
protected final List items = new ArrayList<>();
protected final NamespacedKey key;
protected final ItemStack item;
@@ -94,12 +98,29 @@ public class Category implements Keyed {
* Registers this category.
*
* By default, a category is automatically registered when a {@link SlimefunItem} was added to it.
+ *
+ * @param addon
+ * The {@link SlimefunAddon} that wants to register this {@link Category}
*/
- public void register() {
+ public void register(@Nonnull SlimefunAddon addon) {
+ Validate.notNull(addon, "The Addon cannot be null");
+ this.addon = addon;
+
SlimefunPlugin.getRegistry().getCategories().add(this);
Collections.sort(SlimefunPlugin.getRegistry().getCategories(), Comparator.comparingInt(Category::getTier));
}
+ /**
+ * This returns the {@link SlimefunAddon} which has registered this {@link Category}.
+ * Or null if it has not been registered yet.
+ *
+ * @return The {@link SlimefunAddon} or null if unregistered
+ */
+ @Nullable
+ public final SlimefunAddon getAddon() {
+ return addon;
+ }
+
/**
* Adds the given {@link SlimefunItem} to this {@link Category}.
*
@@ -247,7 +268,7 @@ public class Category implements Keyed {
/**
* This method returns whether this {@link Category} has been registered yet.
- * More specifically: Whether {@link #register()} was called or not.
+ * More specifically: Whether {@link #register(SlimefunAddon)} was called or not.
*
* @return Whether this {@link Category} has been registered
*/
diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java
index 09afe8290..d205894db 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;
@@ -133,6 +134,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);
}
@@ -151,7 +153,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!");
@@ -165,6 +168,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!");
@@ -266,6 +270,13 @@ public class SlimefunItem implements Placeable {
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;
}
@@ -378,7 +389,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);
}
@@ -483,12 +494,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);
@@ -508,13 +529,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);
@@ -570,15 +595,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 d47c380c3..de397d152 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java
@@ -1,9 +1,5 @@
package me.mrCookieSlime.Slimefun.api;
-import java.util.logging.Logger;
-
-import javax.annotation.Nonnull;
-
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -23,11 +19,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