1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Merge branch 'master' into performance/cobblestone

This commit is contained in:
TheBusyBiscuit 2021-01-14 11:16:39 +01:00 committed by GitHub
commit 43109ab2d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 607 additions and 479 deletions

3
.github/TRIAGE_WORKFLOW.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -1,23 +0,0 @@
name: URL Validator
on:
push:
branches:
- master
jobs:
check:
name: URL Checker
runs-on: ubuntu-latest
steps:
- name: URL-checker
uses: SuperKogito/URLs-checker@0.2.1
with:
git_path: https://github.com/Slimefun/Slimefun4
file_types: .md,.java,.yml
print_all: false
retry_count: 2
## These URLs will always be correct, even if their services may be offline right now
white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349,https://gitlocalize.com/repo/3841

View File

@ -29,11 +29,13 @@
#### Additions #### Additions
#### Changes #### Changes
* Performance Improvements and Optimizations for Cobblestone/Stone/Basalt generators and mining androids
* Androids operating on a Cobblestone/Stone/Basalt generator now work faster
#### Fixes #### Fixes
* Fixed elevator floor order * Fixed elevator floor order
* Performance Improvements and Optimizations for Cobblestone/Stone/Basalt generators and mining androids * Fixed #2449
* Androids operating on a Cobblestone/Stone/Basalt generator now work faster * Fixed #2511
## Release Candidate 19 (11 Jan 2021) ## Release Candidate 19 (11 Jan 2021)

23
pom.xml
View File

@ -9,10 +9,11 @@
<!-- Our default version will be UNOFFICIAL, this will prevent auto updates --> <!-- Our default version will be UNOFFICIAL, this will prevent auto updates -->
<!-- from overriding our local test file --> <!-- from overriding our local test file -->
<version>4.8-UNOFFICIAL</version> <version>4.9-UNOFFICIAL</version>
<inceptionYear>2013</inceptionYear> <inceptionYear>2013</inceptionYear>
<packaging>jar</packaging> <packaging>jar</packaging>
<!-- Project Info -->
<description>Slimefun is a Spigot/Paper plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server.</description> <description>Slimefun is a Spigot/Paper plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server.</description>
<url>https://github.com/Slimefun/Slimefun4</url> <url>https://github.com/Slimefun/Slimefun4</url>
@ -33,11 +34,13 @@
<sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths> <sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
</properties> </properties>
<!-- Bug Tracker -->
<issueManagement> <issueManagement>
<system>GitHub Issues</system> <system>GitHub Issues</system>
<url>https://github.com/Slimefun/Slimefun4/issues</url> <url>https://github.com/Slimefun/Slimefun4/issues</url>
</issueManagement> </issueManagement>
<!-- License -->
<licenses> <licenses>
<license> <license>
<name>GNU General Public License v3.0</name> <name>GNU General Public License v3.0</name>
@ -46,6 +49,7 @@
</license> </license>
</licenses> </licenses>
<!-- The repositories which host our dependencies -->
<repositories> <repositories>
<repository> <repository>
<id>spigot-repo</id> <id>spigot-repo</id>
@ -77,11 +81,13 @@
</repository> </repository>
</repositories> </repositories>
<!-- Build settings -->
<build> <build>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<defaultGoal>clean package</defaultGoal> <defaultGoal>clean package</defaultGoal>
<!-- The name of the final jar -->
<finalName>${project.name} v${project.version}</finalName> <finalName>${project.name} v${project.version}</finalName>
<plugins> <plugins>
@ -104,6 +110,7 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId> <artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version> <version>3.2.1</version>
<executions> <executions>
<execution> <execution>
<id>attach-sources</id> <id>attach-sources</id>
@ -119,6 +126,11 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version> <version>3.0.0-M5</version>
<configuration>
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin> </plugin>
<!-- Sonarcloud Scanner --> <!-- Sonarcloud Scanner -->
@ -137,6 +149,7 @@
<executions> <executions>
<execution> <execution>
<id>prepare</id> <id>prepare</id>
<goals> <goals>
<goal>prepare-agent</goal> <goal>prepare-agent</goal>
</goals> </goals>
@ -145,6 +158,7 @@
<execution> <execution>
<id>report</id> <id>report</id>
<phase>test</phase> <phase>test</phase>
<goals> <goals>
<goal>report</goal> <goal>report</goal>
</goals> </goals>
@ -159,8 +173,7 @@
<version>3.2.4</version> <version>3.2.4</version>
<configuration> <configuration>
<!-- Relocate these to avoid clashes and conflicts -->
<!-- Shade dependencies into the output jar -->
<relocations> <relocations>
<relocation> <relocation>
<pattern>io.github.thebusybiscuit.cscorelib2</pattern> <pattern>io.github.thebusybiscuit.cscorelib2</pattern>
@ -336,7 +349,7 @@
<dependency> <dependency>
<groupId>com.github.TheBusyBiscuit</groupId> <groupId>com.github.TheBusyBiscuit</groupId>
<artifactId>CS-CoreLib2</artifactId> <artifactId>CS-CoreLib2</artifactId>
<version>0.29</version> <version>0.29.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -429,7 +442,7 @@
<dependency> <dependency>
<groupId>com.github.LoneDev6</groupId> <groupId>com.github.LoneDev6</groupId>
<artifactId>itemsadder-api</artifactId> <artifactId>itemsadder-api</artifactId>
<version>0.1.2</version> <version>2.1.25</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>

View File

@ -35,6 +35,9 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage;
* an {@link ErrorReport} instead. * an {@link ErrorReport} instead.
* Error reports get saved in the plugin folder. * Error reports get saved in the plugin folder.
* *
* @param <T>
* The type of {@link Throwable} which has spawned this {@link ErrorReport}
*
* @author TheBusyBiscuit * @author TheBusyBiscuit
* *
*/ */
@ -222,6 +225,16 @@ public class ErrorReport<T extends Throwable> {
return newFile; return newFile;
} }
/**
* This helper method wraps the given {@link Runnable} into a try-catch block.
* When an {@link Exception} occurs, a new {@link ErrorReport} will be generated using
* the provided {@link Function}.
*
* @param function
* The {@link Function} to generate a new {@link ErrorReport}
* @param runnable
* The code to execute
*/
public static void tryCatch(@Nonnull Function<Exception, ErrorReport<Exception>> function, @Nonnull Runnable runnable) { public static void tryCatch(@Nonnull Function<Exception, ErrorReport<Exception>> function, @Nonnull Runnable runnable) {
try { try {
runnable.run(); runnable.run();

View File

@ -6,6 +6,7 @@ import org.apache.commons.lang.Validate;
import org.bukkit.Server; import org.bukkit.Server;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.papermc.lib.PaperLib;
/** /**
* This enum holds all versions of Minecraft that we currently support. * 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 * This constant represents Minecraft (Java Edition) Version 1.14
* (The "Village &amp; Pillage" Update) * (The "Village &amp; Pillage" Update)
*/ */
MINECRAFT_1_14("1.14.x"), MINECRAFT_1_14(14, "1.14.x"),
/** /**
* This constant represents Minecraft (Java Edition) Version 1.15 * This constant represents Minecraft (Java Edition) Version 1.15
* (The "Buzzy Bees" Update) * (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 * This constant represents Minecraft (Java Edition) Version 1.16
* (The "Nether Update") * (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 * This constant represents an exceptional state in which we were unable
@ -51,18 +52,22 @@ public enum MinecraftVersion {
private final String name; private final String name;
private final boolean virtual; private final boolean virtual;
private final String prefix; private final int majorVersion;
/** /**
* This constructs a new {@link MinecraftVersion} with the given name. * This constructs a new {@link MinecraftVersion} with the given name.
* This constructor forces the {@link MinecraftVersion} to be real. * This constructor forces the {@link MinecraftVersion} to be real.
* It must be a real version of Minecraft. * It must be a real version of Minecraft.
* *
* @param majorVersion
* The major version of minecraft as an {@link Integer}
* @param name * @param name
* The display name of this {@link MinecraftVersion} * The display name of this {@link MinecraftVersion}
*/ */
MinecraftVersion(@Nonnull String name) { MinecraftVersion(int majorVersion, @Nonnull String name) {
this(name, false); this.name = name;
this.majorVersion = majorVersion;
this.virtual = false;
} }
/** /**
@ -77,8 +82,8 @@ public enum MinecraftVersion {
*/ */
MinecraftVersion(@Nonnull String name, boolean virtual) { MinecraftVersion(@Nonnull String name, boolean virtual) {
this.name = name; this.name = name;
this.majorVersion = 0;
this.virtual = virtual; 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}. * {@link MinecraftVersion}.
* <p>
* You can obtain the version number by doing {@link PaperLib#getMinecraftVersion()}.
* It is equivalent to the "major" version
* <p>
* Example: {@literal "1.13"} returns {@literal 13}
* *
* @param version * @param minecraftVersion
* The version to compare * 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) { public boolean isMinecraftVersion(int minecraftVersion) {
Validate.notNull(version, "The input version must not be null!"); return !isVirtual() && this.majorVersion == minecraftVersion;
return version.startsWith(prefix);
} }
/** /**

View File

@ -1,21 +1,15 @@
package io.github.thebusybiscuit.slimefun4.api; package io.github.thebusybiscuit.slimefun4.api;
import java.util.Collection;
import java.util.Locale;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin; 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; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/** /**
@ -106,16 +100,4 @@ public interface SlimefunAddon {
return description.getDepend().contains(dependency) || description.getSoftDepend().contains(dependency); 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<Category> getCategories() {
String namespace = getJavaPlugin().getName().toLowerCase(Locale.ROOT);
return SlimefunPlugin.getRegistry().getCategories().stream().filter(cat -> cat.getKey().getNamespace().equals(namespace)).collect(Collectors.toList());
}
} }

View File

@ -34,10 +34,10 @@ public class AncientAltarCraftEvent extends PlayerEvent implements Cancellable {
private boolean cancelled; private boolean cancelled;
/** /**
* @param block
* The altar {@link Block}
* @param output * @param output
* The {@link ItemStack} that would be dropped by the ritual * The {@link ItemStack} that would be dropped by the ritual
* @param block
* The altar {@link Block}
* @param player * @param player
* The {@link Player} that started the ritual. * The {@link Player} that started the ritual.
*/ */

View File

@ -16,7 +16,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; 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.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -46,8 +46,8 @@ public class PlayerRightClickEvent extends PlayerEvent {
private final EquipmentSlot hand; private final EquipmentSlot hand;
private final BlockFace face; private final BlockFace face;
private ComputedOptional<SlimefunItem> slimefunItem = ComputedOptional.createNew(); private TriStateOptional<SlimefunItem> slimefunItem = TriStateOptional.createNew();
private ComputedOptional<SlimefunItem> slimefunBlock = ComputedOptional.createNew(); private TriStateOptional<SlimefunItem> slimefunBlock = TriStateOptional.createNew();
private Result itemResult; private Result itemResult;
private Result blockResult; private Result blockResult;
@ -127,7 +127,7 @@ public class PlayerRightClickEvent extends PlayerEvent {
if (itemStack.isPresent()) { if (itemStack.isPresent()) {
slimefunItem.compute(SlimefunItem.getByItem(itemStack.get())); slimefunItem.compute(SlimefunItem.getByItem(itemStack.get()));
} else { } else {
slimefunItem = ComputedOptional.empty(); slimefunItem = TriStateOptional.empty();
} }
} }
@ -140,7 +140,7 @@ public class PlayerRightClickEvent extends PlayerEvent {
if (clickedBlock.isPresent()) { if (clickedBlock.isPresent()) {
slimefunBlock.compute(BlockStorage.check(clickedBlock.get())); slimefunBlock.compute(BlockStorage.check(clickedBlock.get()));
} else { } else {
slimefunBlock = ComputedOptional.empty(); slimefunBlock = TriStateOptional.empty();
} }
} }

View File

@ -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 * This variation of {@link ItemSetting} allows you to allow {@link Enum} constants to be
* used for {@link ItemSetting} validation. * used for {@link ItemSetting} validation.
* *
* @param <T>
* The {@link Enum} type
*
* @author TheBusyBiscuit * @author TheBusyBiscuit
* *
* @see ItemSetting * @see ItemSetting
@ -41,6 +44,7 @@ public class EnumSetting<T extends Enum<T>> extends ItemSetting<String> {
* *
* @return An array of allowed {@link Enum} constants * @return An array of allowed {@link Enum} constants
*/ */
@Nonnull
public T[] getAllowedValues() { public T[] getAllowedValues() {
return enumClass.getEnumConstants(); return enumClass.getEnumConstants();
} }
@ -50,6 +54,7 @@ public class EnumSetting<T extends Enum<T>> extends ItemSetting<String> {
* *
* @return The value as an {@link Enum} constant * @return The value as an {@link Enum} constant
*/ */
@Nonnull
public T getAsEnumConstant() { public T getAsEnumConstant() {
return Enum.valueOf(enumClass, getValue()); return Enum.valueOf(enumClass, getValue());
} }

View File

@ -30,7 +30,6 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
@ -82,7 +81,7 @@ public final class SlimefunRegistry {
private final Map<UUID, PlayerProfile> profiles = new ConcurrentHashMap<>(); private final Map<UUID, PlayerProfile> profiles = new ConcurrentHashMap<>();
private final Map<String, BlockStorage> worlds = new ConcurrentHashMap<>(); private final Map<String, BlockStorage> worlds = new ConcurrentHashMap<>();
private final Map<String, BlockInfoConfig> chunks = new HashMap<>(); private final Map<String, BlockInfoConfig> chunks = new HashMap<>();
private final Map<SlimefunGuideMode, SlimefunGuideImplementation> layouts = new EnumMap<>(SlimefunGuideMode.class); private final Map<SlimefunGuideMode, SlimefunGuideImplementation> guides = new EnumMap<>(SlimefunGuideMode.class);
private final Map<EntityType, Set<ItemStack>> mobDrops = new EnumMap<>(EntityType.class); private final Map<EntityType, Set<ItemStack>> mobDrops = new EnumMap<>(EntityType.class);
private final Map<String, BlockMenuPreset> blockMenuPresets = new HashMap<>(); private final Map<String, BlockMenuPreset> blockMenuPresets = new HashMap<>();
@ -99,8 +98,8 @@ public final class SlimefunRegistry {
guideKey = new NamespacedKey(plugin, "slimefun_guide_mode"); guideKey = new NamespacedKey(plugin, "slimefun_guide_mode");
boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes");
layouts.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide(showVanillaRecipes)); guides.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide(showVanillaRecipes));
layouts.put(SlimefunGuideMode.CHEAT_MODE, new CheatSheetSlimefunGuide()); guides.put(SlimefunGuideMode.CHEAT_MODE, new CheatSheetSlimefunGuide());
researchRanks.addAll(cfg.getStringList("research-ranks")); researchRanks.addAll(cfg.getStringList("research-ranks"));
@ -141,6 +140,7 @@ public final class SlimefunRegistry {
automaticallyLoadItems = mode; automaticallyLoadItems = mode;
} }
@Nonnull
public List<Category> getCategories() { public List<Category> getCategories() {
return categories; return categories;
} }
@ -150,6 +150,7 @@ public final class SlimefunRegistry {
* *
* @return A {@link List} containing every {@link SlimefunItem} * @return A {@link List} containing every {@link SlimefunItem}
*/ */
@Nonnull
public List<SlimefunItem> getAllSlimefunItems() { public List<SlimefunItem> getAllSlimefunItems() {
return slimefunItems; return slimefunItems;
} }
@ -159,18 +160,22 @@ public final class SlimefunRegistry {
* *
* @return A {@link List} containing every enabled {@link SlimefunItem} * @return A {@link List} containing every enabled {@link SlimefunItem}
*/ */
@Nonnull
public List<SlimefunItem> getEnabledSlimefunItems() { public List<SlimefunItem> getEnabledSlimefunItems() {
return enabledItems; return enabledItems;
} }
@Nonnull
public List<Research> getResearches() { public List<Research> getResearches() {
return researches; return researches;
} }
@Nonnull
public Set<UUID> getCurrentlyResearchingPlayers() { public Set<UUID> getCurrentlyResearchingPlayers() {
return researchingPlayers; return researchingPlayers;
} }
@Nonnull
public List<String> getResearchRanks() { public List<String> getResearchRanks() {
return researchRanks; return researchRanks;
} }
@ -195,12 +200,31 @@ public final class SlimefunRegistry {
return researchFireworks; return researchFireworks;
} }
@Nonnull
public List<MultiBlock> getMultiBlocks() { public List<MultiBlock> getMultiBlocks() {
return multiblocks; return multiblocks;
} }
public SlimefunGuideImplementation getGuideLayout(SlimefunGuideMode 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;
} }
/** /**
@ -209,6 +233,7 @@ public final class SlimefunRegistry {
* *
* @return The {@link Map} of custom mob drops * @return The {@link Map} of custom mob drops
*/ */
@Nonnull
public Map<EntityType, Set<ItemStack>> getMobDrops() { public Map<EntityType, Set<ItemStack>> getMobDrops() {
return mobDrops; return mobDrops;
} }
@ -219,50 +244,62 @@ public final class SlimefunRegistry {
* *
* @return A {@link Set} of bartering drops * @return A {@link Set} of bartering drops
*/ */
@Nonnull
public Set<ItemStack> getBarteringDrops() { public Set<ItemStack> getBarteringDrops() {
return barterDrops; return barterDrops;
} }
@Nonnull
public Set<SlimefunItem> getRadioactiveItems() { public Set<SlimefunItem> getRadioactiveItems() {
return radioactive; return radioactive;
} }
@Nonnull
public Set<String> getTickerBlocks() { public Set<String> getTickerBlocks() {
return tickers; return tickers;
} }
@Nonnull
public Map<String, SlimefunItem> getSlimefunItemIds() { public Map<String, SlimefunItem> getSlimefunItemIds() {
return slimefunIds; return slimefunIds;
} }
@Nonnull
public Map<String, BlockMenuPreset> getMenuPresets() { public Map<String, BlockMenuPreset> getMenuPresets() {
return blockMenuPresets; return blockMenuPresets;
} }
@Nonnull
public Map<String, UniversalBlockMenu> getUniversalInventories() { public Map<String, UniversalBlockMenu> getUniversalInventories() {
return universalInventories; return universalInventories;
} }
@Nonnull
public Map<UUID, PlayerProfile> getPlayerProfiles() { public Map<UUID, PlayerProfile> getPlayerProfiles() {
return profiles; return profiles;
} }
@Nonnull
public Map<Class<? extends ItemHandler>, Set<ItemHandler>> getPublicItemHandlers() { public Map<Class<? extends ItemHandler>, Set<ItemHandler>> getPublicItemHandlers() {
return globalItemHandlers; return globalItemHandlers;
} }
@Nonnull
public Map<String, SlimefunBlockHandler> getBlockHandlers() { public Map<String, SlimefunBlockHandler> getBlockHandlers() {
return blockHandlers; return blockHandlers;
} }
@Nonnull
public Map<String, BlockStorage> getWorlds() { public Map<String, BlockStorage> getWorlds() {
return worlds; return worlds;
} }
@Nonnull
public Map<String, BlockInfoConfig> getChunks() { public Map<String, BlockInfoConfig> getChunks() {
return chunks; return chunks;
} }
@Nonnull
public KeyMap<GEOResource> getGEOResources() { public KeyMap<GEOResource> getGEOResources() {
return geoResources; return geoResources;
} }

View File

@ -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 {
}

View File

@ -68,7 +68,7 @@ public abstract class FlexCategory extends Category {
@Override @Override
public final boolean isHidden(@Nonnull Player p) { public final boolean isHidden(@Nonnull Player p) {
/** /*
* We can stop this method right here. * We can stop this method right here.
* We provide a custom method with more parameters for this. * We provide a custom method with more parameters for this.
* See isVisible(...) * See isVisible(...)

View File

@ -149,12 +149,13 @@ public class LockedCategory extends Category {
* The {@link Player} to check * The {@link Player} to check
* @param profile * @param profile
* The {@link PlayerProfile} that belongs to the given {@link Player} * The {@link PlayerProfile} that belongs to the given {@link Player}
*
* @return Whether the {@link Player} has fully completed all parent categories, otherwise false * @return Whether the {@link Player} has fully completed all parent categories, otherwise false
*/ */
public boolean hasUnlocked(@Nonnull Player p, @Nonnull PlayerProfile profile) { public boolean hasUnlocked(@Nonnull Player p, @Nonnull PlayerProfile profile) {
for (Category category : parents) { for (Category category : parents) {
for (SlimefunItem item : category.getItems()) { for (SlimefunItem item : category.getItems()) {
/** /*
* Should probably be replaced with Slimefun.hasUnlocked(...) * Should probably be replaced with Slimefun.hasUnlocked(...)
* However this will result in better performance because we don't * However this will result in better performance because we don't
* request the PlayerProfile everytime * request the PlayerProfile everytime

View File

@ -19,7 +19,7 @@ class GuideCommand extends SubCommand {
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) { if (sender instanceof Player) {
if (sender.hasPermission("slimefun.command.guide")) { if (sender.hasPermission("slimefun.command.guide")) {
SlimefunGuideMode design = SlimefunGuide.getDefaultLayout(); SlimefunGuideMode design = SlimefunGuide.getDefaultMode();
((Player) sender).getInventory().addItem(SlimefunGuide.getItem(design).clone()); ((Player) sender).getInventory().addItem(SlimefunGuide.getItem(design).clone());
} else { } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);

View File

@ -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.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class SearchCommand extends SubCommand { class SearchCommand extends SubCommand {
@ -23,7 +24,7 @@ class SearchCommand extends SubCommand {
if (sender.hasPermission("slimefun.command.search")) { if (sender.hasPermission("slimefun.command.search")) {
if (args.length > 1) { if (args.length > 1) {
String query = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); 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 { } else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search <SearchTerm>")); SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search <SearchTerm>"));
} }

View File

@ -6,6 +6,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -14,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; 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.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -33,7 +35,7 @@ public final class SlimefunGuide {
@Nonnull @Nonnull
public static ItemStack getItem(@Nonnull SlimefunGuideMode design) { public static ItemStack getItem(@Nonnull SlimefunGuideMode design) {
return SlimefunPlugin.getRegistry().getGuideLayout(design).getItem(); return SlimefunPlugin.getRegistry().getSlimefunGuide(design).getItem();
} }
public static void openCheatMenu(@Nonnull Player p) { public static void openCheatMenu(@Nonnull Player p) {
@ -52,7 +54,7 @@ public final class SlimefunGuide {
} }
} }
public static void openGuide(@Nonnull Player p, @Nonnull SlimefunGuideMode layout) { public static void openGuide(@Nonnull Player p, @Nonnull SlimefunGuideMode mode) {
if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) { if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) {
return; return;
} }
@ -61,67 +63,72 @@ public final class SlimefunGuide {
if (optional.isPresent()) { if (optional.isPresent()) {
PlayerProfile profile = optional.get(); PlayerProfile profile = optional.get();
SlimefunGuideImplementation guide = SlimefunPlugin.getRegistry().getGuideLayout(layout); SlimefunGuideImplementation guide = SlimefunPlugin.getRegistry().getSlimefunGuide(mode);
profile.getGuideHistory().openLastEntry(guide); profile.getGuideHistory().openLastEntry(guide);
} else { } else {
openMainMenuAsync(p, layout, 1); openMainMenuAsync(p, mode, 1);
} }
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
private static void openMainMenuAsync(Player player, SlimefunGuideMode layout, int selectedPage) { private static void openMainMenuAsync(Player player, SlimefunGuideMode mode, int selectedPage) {
if (!PlayerProfile.get(player, profile -> SlimefunPlugin.runSync(() -> openMainMenu(profile, layout, selectedPage)))) { if (!PlayerProfile.get(player, profile -> SlimefunPlugin.runSync(() -> openMainMenu(profile, mode, selectedPage)))) {
SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide"); SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide");
} }
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public static void openMainMenu(PlayerProfile profile, SlimefunGuideMode layout, int selectedPage) { public static void openMainMenu(PlayerProfile profile, SlimefunGuideMode mode, int selectedPage) {
SlimefunPlugin.getRegistry().getGuideLayout(layout).openMainMenu(profile, selectedPage); SlimefunPlugin.getRegistry().getSlimefunGuide(mode).openMainMenu(profile, selectedPage);
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public static void openCategory(PlayerProfile profile, Category category, SlimefunGuideMode layout, int selectedPage) { public static void openCategory(PlayerProfile profile, Category category, SlimefunGuideMode mode, int selectedPage) {
SlimefunPlugin.getRegistry().getGuideLayout(layout).openCategory(profile, category, selectedPage); SlimefunPlugin.getRegistry().getSlimefunGuide(mode).openCategory(profile, category, selectedPage);
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public static void openSearch(PlayerProfile profile, String input, boolean survival, boolean addToHistory) { public static void openSearch(PlayerProfile profile, String input, SlimefunGuideMode mode, boolean addToHistory) {
SlimefunGuideImplementation layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideMode.SURVIVAL_MODE); SlimefunGuideImplementation guide = SlimefunPlugin.getRegistry().getSlimefunGuide(mode);
guide.openSearch(profile, input, addToHistory);
if (!survival) {
layout = SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideMode.CHEAT_MODE);
}
layout.openSearch(profile, input, addToHistory);
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public static void displayItem(PlayerProfile profile, ItemStack item, boolean addToHistory) { public static void displayItem(PlayerProfile profile, ItemStack item, boolean addToHistory) {
SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideMode.SURVIVAL_MODE).displayItem(profile, item, 0, addToHistory); SlimefunPlugin.getRegistry().getSlimefunGuide(SlimefunGuideMode.SURVIVAL_MODE).displayItem(profile, item, 0, addToHistory);
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public static void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) { public static void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) {
SlimefunPlugin.getRegistry().getGuideLayout(SlimefunGuideMode.SURVIVAL_MODE).displayItem(profile, item, addToHistory); SlimefunPlugin.getRegistry().getSlimefunGuide(SlimefunGuideMode.SURVIVAL_MODE).displayItem(profile, item, addToHistory);
} }
/**
* 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) { public static boolean isGuideItem(@Nullable ItemStack item) {
if (item == null) { if (item == null || item.getType() != Material.ENCHANTED_BOOK) {
return false; return false;
} else if (item instanceof SlimefunGuideItem) {
return true;
} else { } else {
return SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideMode.SURVIVAL_MODE), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideMode.CHEAT_MODE), true); return SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideMode.SURVIVAL_MODE), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideMode.CHEAT_MODE), true);
} }
} }
/** /**
* Get the default layout for the Slimefun guide. * Get the default mode for the Slimefun guide.
* Currently this is only {@link SlimefunGuideMode#SURVIVAL_MODE}. * Currently this is only {@link SlimefunGuideMode#SURVIVAL_MODE}.
* *
* @return The default {@link SlimefunGuideLayout}. * @return The default {@link SlimefunGuideMode}.
*/ */
@Nonnull @Nonnull
public static SlimefunGuideMode getDefaultLayout() { public static SlimefunGuideMode getDefaultMode() {
return SlimefunGuideMode.SURVIVAL_MODE; return SlimefunGuideMode.SURVIVAL_MODE;
} }
} }

View File

@ -15,7 +15,7 @@ import javax.annotation.Nullable;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor; 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.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
@ -35,7 +35,7 @@ public class Contributor {
private final String profileLink; private final String profileLink;
private final ConcurrentMap<String, Integer> contributions = new ConcurrentHashMap<>(); private final ConcurrentMap<String, Integer> contributions = new ConcurrentHashMap<>();
private final ComputedOptional<String> headTexture = ComputedOptional.createNew(); private final TriStateOptional<String> headTexture = TriStateOptional.createNew();
private Optional<UUID> uuid = Optional.empty(); private Optional<UUID> uuid = Optional.empty();
private boolean immutable = false; private boolean immutable = false;

View File

@ -14,7 +14,7 @@ import javax.annotation.Nullable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import io.github.thebusybiscuit.cscorelib2.players.MinecraftAccount; 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 io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/** /**

View File

@ -21,6 +21,7 @@ import org.bukkit.Server;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.Recipe;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -29,7 +30,6 @@ import org.bukkit.scheduler.BukkitTask;
import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager; 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.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException; import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
@ -75,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.ExplosionsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.GadgetsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.GadgetsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHookListener; 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.ItemDropListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
@ -502,13 +503,13 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
} }
// Now check the actual Version of Minecraft // Now check the actual Version of Minecraft
String currentVersion = ReflectionUtils.getVersion(); int version = PaperLib.getMinecraftVersion();
if (currentVersion.startsWith("v")) { if (version > 0) {
// Check all supported versions of Minecraft // Check all supported versions of Minecraft
for (MinecraftVersion version : MinecraftVersion.valuesCache) { for (MinecraftVersion supportedVersion : MinecraftVersion.valuesCache) {
if (version.matches(currentVersion)) { if (supportedVersion.isMinecraftVersion(version)) {
minecraftVersion = version; minecraftVersion = supportedVersion;
return false; return false;
} }
} }
@ -518,22 +519,22 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
getLogger().log(Level.SEVERE, "### Slimefun was not installed correctly!"); 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, "### You are using the wrong version of Minecraft!");
getLogger().log(Level.SEVERE, "###"); getLogger().log(Level.SEVERE, "###");
getLogger().log(Level.SEVERE, "### You are using Minecraft {0}", currentVersion); 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, "### but Slimefun {0} requires you to be using", getDescription().getVersion());
getLogger().log(Level.SEVERE, "### Minecraft {0}", String.join(" / ", getSupportedVersions())); getLogger().log(Level.SEVERE, "### Minecraft {0}", String.join(" / ", getSupportedVersions()));
getLogger().log(Level.SEVERE, "#############################################"); getLogger().log(Level.SEVERE, "#############################################");
return true; 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;
} }
getLogger().log(Level.WARNING, "We could not determine the version of Minecraft you were using ({0})", currentVersion);
/*
* 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) { } catch (Exception | LinkageError x) {
getLogger().log(Level.SEVERE, x, () -> "Error: Could not determine Environment or version of Minecraft for Slimefun v" + getDescription().getVersion()); getLogger().log(Level.SEVERE, x, () -> "Error: Could not determine Environment or version of Minecraft for Slimefun v" + getDescription().getVersion());
@ -625,6 +626,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new CartographyTableListener(this); new CartographyTableListener(this);
new ButcherAndroidListener(this); new ButcherAndroidListener(this);
new NetworkListener(this, networkManager); new NetworkListener(this, networkManager);
new HopperListener(this);
// Bees were added in 1.15 // Bees were added in 1.15
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
@ -792,6 +794,13 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
return instance.local; return instance.local;
} }
/**
* 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 @Nonnull
public static MinecraftRecipeService getMinecraftRecipeService() { public static MinecraftRecipeService getMinecraftRecipeService() {
validateInstance(); validateInstance();

View File

@ -570,7 +570,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
pl.closeInventory(); pl.closeInventory();
SlimefunPlugin.getLocalization().sendMessage(pl, "guide.search.message"); 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; return false;
}); });

View File

@ -843,6 +843,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
} }
} }
@ParametersAreNonnullByDefault
protected void move(Block b, BlockFace face, Block block) { protected void move(Block b, BlockFace face, Block block) {
if (block.getY() > 0 && block.getY() < block.getWorld().getMaxHeight() && block.isEmpty()) { if (block.getY() > 0 && block.getY() < block.getWorld().getMaxHeight() && block.isEmpty()) {
BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> { BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> {

View File

@ -105,7 +105,6 @@ public class StomperBoots extends SlimefunItem {
* @return If the entity can move. * @return If the entity can move.
*/ */
protected boolean canPush(@Nonnull Player player, @Nonnull LivingEntity entity) { protected boolean canPush(@Nonnull Player player, @Nonnull LivingEntity entity) {
return entity.isValid() && !entity.getUniqueId().equals(player.getUniqueId()) return entity.isValid() && !entity.getUniqueId().equals(player.getUniqueId()) && entity.isCollidable() && entity.hasGravity();
&& entity.isCollidable() && entity.hasGravity();
} }
} }

View File

@ -52,8 +52,7 @@ public class MultiTool extends SlimefunItem implements Rechargeable {
if (index >= modes.size()) { if (index >= modes.size()) {
index = 0; index = 0;
} }
} } while (index != i && !modes.get(index).isEnabled());
while (index != i && !modes.get(index).isEnabled());
return index; return index;
} }

View File

@ -12,12 +12,13 @@ import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType; import org.bukkit.potion.PotionType;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; 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.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; 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.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; 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 * @author Linox
* *
*/ */
public class AutoBrewer extends AContainer { public class AutoBrewer extends AContainer implements NotHopperable {
private static final Map<Material, PotionType> potionRecipes = new EnumMap<>(Material.class); private static final Map<Material, PotionType> potionRecipes = new EnumMap<>(Material.class);
private static final Map<PotionType, PotionType> fermentations = new EnumMap<>(PotionType.class); private static final Map<PotionType, PotionType> fermentations = new EnumMap<>(PotionType.class);

View File

@ -7,6 +7,7 @@ import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack; 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.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -22,7 +23,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @author Linox * @author Linox
* *
*/ */
public class AutoDrier extends AContainer implements RecipeDisplayItem { public class AutoDrier extends AContainer implements RecipeDisplayItem, NotHopperable {
private List<ItemStack> recipeList; private List<ItemStack> recipeList;

View File

@ -7,12 +7,13 @@ import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.RecipeChoice.MaterialChoice; import org.bukkit.inventory.RecipeChoice.MaterialChoice;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; 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.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; 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) { public ElectricFurnace(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -6,6 +6,7 @@ import java.util.List;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; 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.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -23,7 +24,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see ElectricIngotFactory * @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) { public ElectricIngotPulverizer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -3,13 +3,14 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; 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.core.attributes.RecipeDisplayItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; 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) { public ElectricOreGrinder(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; 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.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.Smeltery;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 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.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; 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.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; 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}. * 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 * @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[] 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 }; private static final int[] inputBorder = { 0, 1, 2, 3, 9, 12, 18, 21, 27, 30, 36, 37, 38, 39 };

View File

@ -67,12 +67,13 @@ public class BlockListener implements Listener {
SlimefunItem sfItem = BlockStorage.check(block); SlimefunItem sfItem = BlockStorage.check(block);
if (sfItem != null) { if (sfItem != null) {
/* Temp fix for #2636 /*
for (ItemStack item : sfItem.getDrops()) { * Temp fix for #2636
if (item != null && !item.getType().isAir()) { * for (ItemStack item : sfItem.getDrops()) {
block.getWorld().dropItemNaturally(block.getLocation(), item); * if (item != null && !item.getType().isAir()) {
} * block.getWorld().dropItemNaturally(block.getLocation(), item);
} * }
* }
*/ */
BlockStorage.clearBlockInfo(block); BlockStorage.clearBlockInfo(block);
} }

View File

@ -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);
}
}
}

View File

@ -38,7 +38,7 @@ public class SlimefunGuideListener implements Listener {
return; return;
} }
SlimefunGuideMode type = SlimefunGuide.getDefaultLayout(); SlimefunGuideMode type = SlimefunGuide.getDefaultMode();
p.getInventory().addItem(SlimefunGuide.getItem(type).clone()); p.getInventory().addItem(SlimefunGuide.getItem(type).clone());
} }
} }

View File

@ -114,8 +114,6 @@ public enum HeadTexture {
PIGLIN_HEAD("2882af1294a74023e6919a31d1a027310f2e142afb4667d230d155e7f21dbb41"), PIGLIN_HEAD("2882af1294a74023e6919a31d1a027310f2e142afb4667d230d155e7f21dbb41"),
NECROTIC_SKULL("7953b6c68448e7e6b6bf8fb273d7203acd8e1be19e81481ead51f45de59a8"); NECROTIC_SKULL("7953b6c68448e7e6b6bf8fb273d7203acd8e1be19e81481ead51f45de59a8");
public static final HeadTexture[] valuesCache = values();
private final String texture; private final String texture;
private final UUID uuid; private final UUID uuid;

View File

@ -62,7 +62,7 @@ public enum SlimefunTag implements Tag<Material> {
* All command block variants * All command block variants
*/ */
COMMAND_BLOCKS, COMMAND_BLOCKS,
/** /**
* All variants of Spawn Eggs * All variants of Spawn Eggs
*/ */

View File

@ -110,17 +110,6 @@ public class Category implements Keyed {
Collections.sort(SlimefunPlugin.getRegistry().getCategories(), Comparator.comparingInt(Category::getTier)); Collections.sort(SlimefunPlugin.getRegistry().getCategories(), Comparator.comparingInt(Category::getTier));
} }
/**
* Old way of registering categories, do not call this manually.
*
* @deprecated Please use {@link #register(SlimefunAddon)} instead.
*/
@Deprecated
public void register() {
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}. * This returns the {@link SlimefunAddon} which has registered this {@link Category}.
* Or null if it has not been registered yet. * Or null if it has not been registered yet.
@ -279,7 +268,7 @@ public class Category implements Keyed {
/** /**
* This method returns whether this {@link Category} has been registered yet. * 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 * @return Whether this {@link Category} has been registered
*/ */

View File

@ -12,6 +12,7 @@ import java.util.logging.Logger;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
@ -130,6 +131,7 @@ public class SlimefunItem implements Placeable {
* @param recipe * @param recipe
* An Array representing the recipe of this {@link SlimefunItem} * An Array representing the recipe of this {@link SlimefunItem}
*/ */
@ParametersAreNonnullByDefault
public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
this(category, item, recipeType, recipe, null); this(category, item, recipeType, recipe, null);
} }
@ -148,6 +150,7 @@ public class SlimefunItem implements Placeable {
* @param recipeOutput * @param recipeOutput
* The result of crafting this item * The result of crafting this item
*/ */
@ParametersAreNonnullByDefault
public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
Validate.notNull(category, "'category' is not allowed to be null!"); Validate.notNull(category, "'category' is not allowed to be null!");
Validate.notNull(item, "'item' is not allowed to be null!"); Validate.notNull(item, "'item' is not allowed to be null!");
@ -162,6 +165,7 @@ public class SlimefunItem implements Placeable {
} }
// Previously deprecated constructor, now only for internal purposes // Previously deprecated constructor, now only for internal purposes
@ParametersAreNonnullByDefault
protected SlimefunItem(Category category, ItemStack item, String id, RecipeType recipeType, ItemStack[] recipe) { protected SlimefunItem(Category category, ItemStack item, String id, RecipeType recipeType, ItemStack[] recipe) {
Validate.notNull(category, "'category' is not allowed to be null!"); Validate.notNull(category, "'category' is not allowed to be null!");
Validate.notNull(item, "'item' is not allowed to be null!"); Validate.notNull(item, "'item' is not allowed to be null!");
@ -371,7 +375,7 @@ public class SlimefunItem implements Placeable {
* @return The {@link SlimefunAddon} that registered this {@link SlimefunItem} * @return The {@link SlimefunAddon} that registered this {@link SlimefunItem}
*/ */
@Nonnull @Nonnull
public SlimefunAddon getAddon() { public final SlimefunAddon getAddon() {
if (addon == null) { if (addon == null) {
throw new UnregisteredItemException(this); throw new UnregisteredItemException(this);
} }
@ -482,6 +486,16 @@ public class SlimefunItem implements Placeable {
// Send out deprecation warnings for any classes or interfaces // Send out deprecation warnings for any classes or interfaces
checkForDeprecations(getClass()); checkForDeprecations(getClass());
// Check for an illegal stack size
if (itemStackTemplate.getAmount() != 1) {
// @formatter:off
warn("This item has an illegal stack size: " + itemStackTemplate.getAmount()
+ "An Item size of 1 is recommended. Please inform the autho of " + addon.getName()
+ " to fix this. Crafting Results with amounts of higher should be handled"
+ " via the recipeOutput parameter!");
// @formatter:on
}
// Add it to the list of enabled items // Add it to the list of enabled items
SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(this); SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(this);
@ -501,13 +515,17 @@ public class SlimefunItem implements Placeable {
if (exception.isPresent()) { if (exception.isPresent()) {
throw exception.get(); throw exception.get();
} else { } 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()); 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()) { if (!handler.isPrivate()) {
Set<ItemHandler> handlerset = getPublicItemHandlers(handler.getIdentifier()); Set<ItemHandler> handlerset = getPublicItemHandlers(handler.getIdentifier());
handlerset.add(handler); handlerset.add(handler);
@ -563,15 +581,19 @@ public class SlimefunItem implements Placeable {
*/ */
private void checkForDeprecations(@Nullable Class<?> c) { private void checkForDeprecations(@Nullable Class<?> c) {
if (SlimefunPlugin.getUpdater().getBranch() == SlimefunBranch.DEVELOPMENT) { 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. * This method is currently way too spammy with all the restructuring going on...
// So we fire these only for stable versions, since devs should update then, so * Since DEV builds are anyway under "development", things may be relocated.
// it's the perfect moment to tell them to act. * 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; 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) { if (c != null) {
// Check if this Class is deprecated // Check if this Class is deprecated
if (c.isAnnotationPresent(Deprecated.class)) { if (c.isAnnotationPresent(Deprecated.class)) {

View File

@ -1,12 +1,11 @@
--- ---
commands: commands:
help: 展示此帮助页面 help: 显示此帮助
cheat: 使用作弊模式获取 Slimefun 的物品 cheat: 直接拿取 Slimefun 物品
give: 给某人 Slimefun 物品 give: 给予玩家 Slimefun 物品
guide: 给你自己一本 Slimefun 指南 guide: 获取一本 Slimefun 指南书
timings: 查看关于 Slimefun 的耗能信息 teleporter: 查看其他玩家的公共传送点
teleporter: 查看其他玩家的公开传送点 versions: 显示 Slimefun 运行环境
versions: 列出已安装的扩展插件
search: 搜索 Slimefun 物品 search: 搜索 Slimefun 物品
open_guide: 使用命令打开 Slimefun 指南 open_guide: 使用命令打开 Slimefun 指南
stats: 查看玩家的统计数据 stats: 查看玩家的统计数据
@ -24,9 +23,14 @@ commands:
description: 为你手持的物品充电 description: 为你手持的物品充电
charge-success: 充电完成! charge-success: 充电完成!
not-rechargeable: 这个物品不能充电! not-rechargeable: 这个物品不能充电!
timings:
description: Slimefun 及其附属插件的性能报告
please-wait: "&e请稍等一会...结果马上就来!"
verbose-player: "&4该标记不能对玩家使用!"
unknown-flag: "&4未知标记: &c%flag%"
guide: guide:
search: search:
message: "&b你想要搜索什么?" message: "&b今天要搜些什么?"
name: "&7搜索..." name: "&7搜索..."
tooltip: "&b单击搜索物品" tooltip: "&b单击搜索物品"
inventory: '正在搜索: %item%' inventory: '正在搜索: %item%'
@ -34,28 +38,28 @@ guide:
- "&b你想要搜索什么?" - "&b你想要搜索什么?"
- "&7将要搜索的物品的名字输入在聊天栏上" - "&7将要搜索的物品的名字输入在聊天栏上"
cheat: cheat:
no-multiblocks: "&4你不能在作弊模式下直接获得多方块结构的机器, 你必须自己建造!" no-multiblocks: "&4你不能在作弊模式下获得多方块结构的机器, 必须按书中所示建造!"
languages: languages:
updated: "&a你的语言已设为: &b%lang%" updated: "&a成功修改语言为: &b%lang%"
translations: translations:
name: "&a少了些什么?" name: "&a少了些什么?"
lore: 单击添加你自己的翻译 lore: 单击添加你自己的翻译
select: 单击选中此语言 select: 单击选中此语言
select-default: 单击选中默认语言 select-default: 单击选中默认语言
selected-language: '目前使用的语言:' selected-language: '目前使用的语言:'
change: 单击选择的语言 change: 单击选择要更改的语言
description: description:
- "&7现在你有了修改 Slimefun" - "&7现在你可以修改 Slimefun"
- "&7展示给你的文本语言选项了." - "&7展示的文本消息的语言了."
- "&7物品中的文本" - "&7注意: 物品中的文本"
- "&7还不能够修改." - "&7暂时无法修改."
title: title:
main: Slimefun 指南 main: Slimefun 指南
settings: 设置 & 关于 settings: 设置 & 详情
languages: 选择你想要的语言 languages: 选择你想要更改的语言
credits: Slimefun4 贡献者 credits: Slimefun4 贡献者
wiki: Slimefun4 维基 wiki: Slimefun4 维基
addons: Slimefun4 扩展 addons: Slimefun4 附属插件
bugs: 问题反馈 bugs: 问题反馈
source: 源代码 source: 源代码
versions: 安装的版本 versions: 安装的版本
@ -67,8 +71,8 @@ guide:
wiki: "&3Wiki 编辑者" wiki: "&3Wiki 编辑者"
resourcepack: "&c材质制作者" resourcepack: "&c材质制作者"
translator: "&9翻译者" translator: "&9翻译者"
profile-link: 单击访问TA们的 Github 个人主页 profile-link: 单击访问们的 Github 个人主页
open: 单击查看我们的贡献者 open: 单击查看贡献者名单
description: description:
- "&7Slimefun 是一个开源的项目" - "&7Slimefun 是一个开源的项目"
- "&7并且由玩家社区维护." - "&7并且由玩家社区维护."
@ -84,7 +88,7 @@ guide:
recipes: recipes:
machine: 此机器可用的合成配方 machine: 此机器可用的合成配方
miner: 此采矿机可以获得的资源 miner: 此采矿机可以获得的资源
generator: 可用的燃料 generator: 可用的燃料
gold-pan: 你可以获得的资源 gold-pan: 你可以获得的资源
climbing-pick: 你可以攀爬的平面 climbing-pick: 你可以攀爬的平面
back: back:
@ -96,14 +100,14 @@ guide:
- 为了解锁这一类别 - 为了解锁这一类别
- 你需要先解锁以下 - 你需要先解锁以下
- 类别里的所有物品 - 类别里的所有物品
work-in-progress: 这个功能还没完全做完! work-in-progress: 该功能暂未推出!
messages: messages:
not-researched: "&4你没有足够的学识来理解它" not-researched: "&4你的知识还不足以理解这个物品"
not-enough-xp: "&4你没有足够的经验来解锁这个研究" not-enough-xp: "&4你没有足够的经验来解锁这个研究"
unlocked: '&b成功解锁研究 &7"%research%"' unlocked: '&b成功解锁研究 &7"%research%"'
only-players: "&4这个指令只能在游戏内使用" only-players: "&4这个指令只能在游戏内使用"
unknown-player: "&4未知玩家: &c%player%" unknown-player: "&4未知玩家: &c%player%"
no-permission: "&4你没有足够的权限做这个" no-permission: "&4你没有足够的权限这么做"
usage: "&4用法: &c%usage%" usage: "&4用法: &c%usage%"
not-online: "&4%player% &c不在线" not-online: "&4%player% &c不在线"
given-item: '&b你获得了 &a%amount% &7"%item%&7"' given-item: '&b你获得了 &a%amount% &7"%item%&7"'
@ -123,25 +127,25 @@ messages:
angel: "&a&o你的护身符使你在信仰之跃时不受伤害" angel: "&a&o你的护身符使你在信仰之跃时不受伤害"
fire: "&a&o你的护身符使你免受火焰伤害" fire: "&a&o你的护身符使你免受火焰伤害"
magician: "&a&o你的护身符赠送了你额外的附魔" magician: "&a&o你的护身符赠送了你额外的附魔"
traveller: "&a&o你的护身符让你跑起来更快了" traveller: "&a&o你的护身符让你跑更快了"
warrior: "&a&o你的护身符使你在一段时间内变强了" warrior: "&a&o你的护身符使你变强了"
knight: "&a&o你的护身符给予了你 5 秒的生命恢复" knight: "&a&o你的护身符给予了你 5 秒的生命恢复"
whirlwind: "&a&o你的护身符反弹了所有的弹射物" whirlwind: "&a&o你的护身符反弹了所有射向你的投掷物"
wizard: "&a&o你的护身符使一个附魔的等级提高了, 同时其他附魔等级将会下降" wizard: "&a&o你的护身符随机提高了一个附魔的等级, 但其他的附魔等级将会下降"
caveman: "&a&o你的护身符给予了你急迫效果" caveman: "&a&o你的护身符给予了你急迫效果"
soulbound-rune: soulbound-rune:
fail: "&c一次只能灵魂绑定一个物品." fail: "&c灵魂一次只能绑定一个物品."
success: "&a物品绑定成功! 在你死亡后此物品将不会掉落." success: "&a物品绑定成功! 在你死亡后此物品将不会掉落."
research: research:
start: "&7古老的灵魂正向你诉说神秘的话语!" start: "&7古老的灵魂正向你低语其中的神秘!"
progress: "&7你开始慢慢理解研究 &b%research% &e(%progress%)" progress: "&7你逐渐开始理解研究 &b%research% &e(%progress%)"
fire-extinguish: "&7你灭掉了身上的火" fire-extinguish: "&7你灭掉了身上的火"
cannot-place: "&c你不能在这里放置方块!" cannot-place: "&c你不能在这里放置方块!"
no-pvp: "&c你不能在这里 PVP!" no-pvp: "&c你不能在这里攻击其他玩家!"
radiation: "&4你已经暴露在致命的辐射之下! &c快把辐射物品丢掉或者穿上防化服!" radiation: "&4你已经暴露在致命的辐射之下! &c快把辐射物品丢掉或者穿上防化服!"
opening-guide: "&b正在打开指南书, 请稍等..." opening-guide: "&b正在打开指南书, 请稍等..."
opening-backpack: "&b正在打开背包, 请稍等...." opening-backpack: "&b正在打开背包, 请稍等...."
no-iron-golem-heal: "&c这不是铁锭. 你不能用这个治疗铁傀儡!" no-iron-golem-heal: "&c这不是铁锭. 不能用来治疗铁傀儡!"
link-prompt: "&e单击此处:" link-prompt: "&e单击此处:"
diet-cookie: "&e你感觉变轻了..." diet-cookie: "&e你感觉变轻了..."
fortune-cookie: fortune-cookie:
@ -159,7 +163,7 @@ messages:
- "&7要总是看着生活中光明的一面!" - "&7要总是看着生活中光明的一面!"
- "&7这一块其实是饼干而不是曲奇" - "&7这一块其实是饼干而不是曲奇"
- "&7霓虹灯亮起来了!" - "&7霓虹灯亮起来了!"
piglin-barter: "&4你不能使用 Slimefun 的物品和猪灵以物换物" piglin-barter: "&4你不能使用 Slimefun 的物品和猪灵物"
enchantment-rune: enchantment-rune:
fail: "&c你不能附魔这个物品." fail: "&c你不能附魔这个物品."
no-enchantment: "&c无法找到此物品可用的附魔属性." no-enchantment: "&c无法找到此物品可用的附魔属性."
@ -167,21 +171,21 @@ messages:
tape-measure: tape-measure:
no-anchor: "&c在开始测量之前请先选定测量起点!" no-anchor: "&c在开始测量之前请先选定测量起点!"
wrong-world: "&c你设置的起点似乎在另一个世界!" wrong-world: "&c你设置的起点似乎在另一个世界!"
distance: "&7已测量到距离, &e为: %distance%" distance: "&7距离已测量, &e为: %distance%"
anchor-set: "&a成功在 &e %anchor% &a设置了测量起点" anchor-set: "&a成功在 &e %anchor% &a设置了测量起点"
multi-tool: multi-tool:
mode-change: "&b%device% 的模式已切换为: &9%mode%" mode-change: "&b%device% 的模式已切换为: &9%mode%"
not-shears: "&c多功能工具 (Multi Tool) 不能当成剪刀来用!" not-shears: "&c多功能工具 (Multi Tool) 不能作为剪刀使用!"
climbing-pick: climbing-pick:
dual-wielding: "&4你需要双手拿着攀岩镐才能使用!" dual-wielding: "&4你需要双手拿着攀岩镐才能使用!"
wrong-material: "&c你不能爬上这个平面. 查看指南书了解更多!" wrong-material: "&c你不能爬上这个平面. 查看指南书了解详情!"
invalid-item: "&4%item% &c不是一个有效的物品名!" invalid-item: "&4%item% &c不是一个有效的物品名!"
invalid-amount: "&4%amount% &ci不是一个有效的数字 : 它必须大于 0!" invalid-amount: "&4%amount% &ci不是一个有效的数字 : 它必须大于 0!"
invalid-research: "&4%research% &c不是一个有效的研究名!" invalid-research: "&4%research% &c不是一个有效的研究名!"
bee-suit-slow-fall: "&e你的蜂翅会让你安全且缓慢地回到地面" bee-suit-slow-fall: "&e你的蜂翅将会让你安全缓降"
mode-change: "&b%device% 的模式已切换为: &9%mode%" mode-change: "&b%device% 的模式已切换为: &9%mode%"
machines: machines:
pattern-not-found: "&e抱歉, 你记错合成表了吧. 这不是一个正确的合成配方, 请检查发射器里放置物品的顺序." pattern-not-found: "&e抱歉, 这不是正确的合成配方, 请检查发射器里放置物品的顺序."
unknown-material: "&e抱歉, 我无法识别在发射器里的物品. 请按照合成配方放置物品." unknown-material: "&e抱歉, 我无法识别在发射器里的物品. 请按照合成配方放置物品."
wrong-item: "&e抱歉, 我无法识别你右键的物品. 检查指南书看看哪些物品可以使用." wrong-item: "&e抱歉, 我无法识别你右键的物品. 检查指南书看看哪些物品可以使用."
full-inventory: "&e抱歉, 物品栏已经满了!" full-inventory: "&e抱歉, 物品栏已经满了!"
@ -190,14 +194,14 @@ machines:
ANCIENT_ALTAR: ANCIENT_ALTAR:
not-enough-pedestals: "&4古代基座不足. 目前已摆放的基座数: &c(%pedestals% / 8)" not-enough-pedestals: "&4古代基座不足. 目前已摆放的基座数: &c(%pedestals% / 8)"
unknown-catalyst: "&4无效的催化剂! &c请按照合成配方正确摆放物品!" unknown-catalyst: "&4无效的催化剂! &c请按照合成配方正确摆放物品!"
unknown-recipe: "&4未知合成表! &c请使用正确的合成配方!" unknown-recipe: "&4未知合成表! &c请按照合成配方正确摆放物品!"
ANCIENT_PEDESTAL: ANCIENT_PEDESTAL:
obstructed: "&4基座被挡住了! &c把基座上面的东西移开!" obstructed: "&4基座被挡住了! &c把基座上面的东西移开!"
HOLOGRAM_PROJECTOR: HOLOGRAM_PROJECTOR:
enter-text: "&7请写下想显示在全息文本上的话. &r(支持颜色代码)" enter-text: "&7请写下想显示在全息文本上的话. &r(支持颜色代码)"
inventory-title: 全息图像编辑器 inventory-title: 全息图像编辑器
ELEVATOR: ELEVATOR:
no-destinations: "&4找不到目的地" no-destinations: "&4找不到上下楼"
pick-a-floor: "&3- 选择一个楼层 -" pick-a-floor: "&3- 选择一个楼层 -"
current-floor: "&e你现在所在的楼层:" current-floor: "&e你现在所在的楼层:"
click-to-teleport: "&e单击 &7传送至楼层:" click-to-teleport: "&e单击 &7传送至楼层:"
@ -213,10 +217,10 @@ machines:
tooltip: 单击传送 tooltip: 单击传送
time: 预计时间 time: 预计时间
CARGO_NODES: CARGO_NODES:
must-be-placed: "&4必须放置在箱子或机器上!" must-be-placed: "&4货运节点必须放置在箱子或机器上!"
GPS_CONTROL_PANEL: GPS_CONTROL_PANEL:
title: GPS - 控制面板 title: GPS - 控制面板
transmitters: 信号发射器概览 transmitters: 信号发射机详情
waypoints: 传送点列表 waypoints: 传送点列表
INDUSTRIAL_MINER: INDUSTRIAL_MINER:
no-fuel: "&c你的工业矿机没有燃料了! 将燃料放入它上面的箱子里." no-fuel: "&c你的工业矿机没有燃料了! 将燃料放入它上面的箱子里."
@ -225,7 +229,7 @@ machines:
destroyed: "&c你的工业矿机被拆除了." destroyed: "&c你的工业矿机被拆除了."
already-running: "&c这个工业矿机正在运行!" already-running: "&c这个工业矿机正在运行!"
full-chest: "&c你的工业矿机的箱子已经满了!" full-chest: "&c你的工业矿机的箱子已经满了!"
no-permission: "&4你没有权限在此操作此工业矿机!" no-permission: "&4你没有权限操作这台工业矿机!"
finished: "&e你的工业矿机采矿已完成! 总共开采了 %ores% 个矿石!" finished: "&e你的工业矿机采矿已完成! 总共开采了 %ores% 个矿石!"
anvil: anvil:
not-working: "&4你不能在铁砧里使用 Slimefun 的物品" not-working: "&4你不能在铁砧里使用 Slimefun 的物品"
@ -236,14 +240,14 @@ backpack:
workbench: workbench:
not-enhanced: "&4你不能在普通的工作台上使用 Slimefun 物品" not-enhanced: "&4你不能在普通的工作台上使用 Slimefun 物品"
gps: gps:
deathpoint: "&4死亡点 &7%date%" deathpoint: "&4死亡点 &7%date%"
waypoint: waypoint:
new: "&e给你的路径点起个名字吧 &7(支持彩色代码!)" new: "&e给你的路径点起个名字吧 &7(支持彩色代码!)"
added: "&a成功添加了新的传送点" added: "&a成功添加了新的传送点"
max: "&4你已到达设置传送点个数的最大上限" max: "&4你已到达设置传送点个数的最大上限"
duplicate: "&4你已经创建了一个相同名字的传送点了: &f%waypoint%" duplicate: "&4已经有相同名字的传送点了: &f%waypoint%"
insufficient-complexity: insufficient-complexity:
- "&4GPS网络复杂度不足: &c%complexity%" - "&4GPS 网络复杂度不足: &c%complexity%"
- "&4a) 你还没有设置一个 GPS 网络" - "&4a) 你还没有设置一个 GPS 网络"
- "&4b) 你的 GPS 网络复杂度不够, 多放置几个 GPS 信号发射机" - "&4b) 你的 GPS 网络复杂度不够, 多放置几个 GPS 信号发射机"
geo: geo:
@ -251,10 +255,10 @@ gps:
inventory: inventory:
no-access: "&4你没有权限使用这个方块" no-access: "&4你没有权限使用这个方块"
android: android:
started: "&7你的机器人开始运行脚本" started: "&7机器人正在依照脚本运行"
stopped: "&7你的机器人停运行了脚本" stopped: "&7机器人停止了运行"
scripts: scripts:
already-uploaded: "&4这个脚本已经上传过了." already-uploaded: "&4你已经上传过这个脚本了."
instructions: instructions:
START: "&2运行脚本" START: "&2运行脚本"
REPEAT: "&9重复运行脚本" REPEAT: "&9重复运行脚本"
@ -278,8 +282,8 @@ android:
CATCH_FISH: "&b钓鱼" CATCH_FISH: "&b钓鱼"
FARM_FORWARD: "&b自动采收并补种作物" FARM_FORWARD: "&b自动采收并补种作物"
FARM_DOWN: "&b自动采收并补种下面的作物" FARM_DOWN: "&b自动采收并补种下面的作物"
FARM_EXOTIC_FORWARD: "&b自动采收并补种作物 &7(支持异域花园植物)" FARM_EXOTIC_FORWARD: "&b自动采收并补种所有作物"
FARM_EXOTIC_DOWN: "&b自动采收并补种下面的作物 &7(支持异域花园植物)" FARM_EXOTIC_DOWN: "&b自动采收并补种下面的所有作物"
INTERFACE_ITEMS: "&9将物品栏里的物品放入面前的容器" INTERFACE_ITEMS: "&9将物品栏里的物品放入面前的容器"
INTERFACE_FUEL: "&c从面前的容器中拿出燃料" INTERFACE_FUEL: "&c从面前的容器中拿出燃料"
enter-name: enter-name:
@ -313,7 +317,6 @@ languages:
zh-CN: 简体中文 (中国) zh-CN: 简体中文 (中国)
el: 希腊语 el: 希腊语
he: 希伯来语 he: 希伯来语
pt: 葡萄牙语 (葡萄牙)
ar: 阿拉伯语 ar: 阿拉伯语
af: 南非语 af: 南非语
da: 丹麦语 da: 丹麦语
@ -325,6 +328,7 @@ languages:
fa: 波斯语 fa: 波斯语
th: 泰语 th: 泰语
ro: 罗马尼亚语 ro: 罗马尼亚语
pt: 葡萄牙语 (葡萄牙)
pt-BR: 葡萄牙语 (巴西) pt-BR: 葡萄牙语 (巴西)
bg: 保加利亚语 bg: 保加利亚语
ko: 韩语 ko: 韩语
@ -341,6 +345,6 @@ villagers:
cartography_table: cartography_table:
not-working: "&4你不能在制图台中使用 Slimefun 物品!" not-working: "&4你不能在制图台中使用 Slimefun 物品!"
cauldron: cauldron:
no-discoloring: "&4你不能用炼药锅洗 Slimefun 物品的颜色" no-discoloring: "&4你不能用炼药锅 Slimefun 物品的颜色"
miner: miner:
no-ores: "&e抱歉, 周围找不到矿石了!" no-ores: "&e抱歉, 周围找不到矿石了!"

View File

@ -1,247 +1,247 @@
{ {
"GOLD_PAN" : "Gold-Pan", "GOLD_PAN" : "Gold-Pan",
"SIFTED_ORE" : "Sifted-Ore", "SIFTED_ORE" : "Sifted-Ore",
"SMELTERY" : "Smeltery", "SMELTERY" : "Smeltery",
"DIET_COOKIE" : "Diet-Cookie", "DIET_COOKIE" : "Diet-Cookie",
"ENHANCED_CRAFTING_TABLE" : "Enhanced-Crafting-Table", "ENHANCED_CRAFTING_TABLE" : "Enhanced-Crafting-Table",
"FORTUNE_COOKIE" : "Fortune-Cookie", "FORTUNE_COOKIE" : "Fortune-Cookie",
"TABLE_SAW" : "Table-Saw", "TABLE_SAW" : "Table-Saw",
"APPLE_JUICE" : "Juices", "APPLE_JUICE" : "Juices",
"GOLDEN_APPLE_JUICE" : "Juices", "GOLDEN_APPLE_JUICE" : "Juices",
"CARROT_JUICE" : "Juices", "CARROT_JUICE" : "Juices",
"MELON_JUICE" : "Juices", "MELON_JUICE" : "Juices",
"PUMPKIN_JUICE" : "Juices", "PUMPKIN_JUICE" : "Juices",
"SWEET_BERRY_JUICE" : "Juices", "SWEET_BERRY_JUICE" : "Juices",
"MAGIC_SUGAR" : "Magic-Sugar", "MAGIC_SUGAR" : "Magic-Sugar",
"MONSTER_JERKY" : "Monster-Jerky", "MONSTER_JERKY" : "Monster-Jerky",
"OUTPUT_CHEST" : "Output-Chest", "OUTPUT_CHEST" : "Output-Chest",
"BEEF_JERKY" : "Meat-Jerky", "BEEF_JERKY" : "Meat-Jerky",
"PORK_JERKY" : "Meat-Jerky", "PORK_JERKY" : "Meat-Jerky",
"CHICKEN_JERKY" : "Meat-Jerky", "CHICKEN_JERKY" : "Meat-Jerky",
"MUTTON_JERKY" : "Meat-Jerky", "MUTTON_JERKY" : "Meat-Jerky",
"RABBIT_JERKY" : "Meat-Jerky", "RABBIT_JERKY" : "Meat-Jerky",
"FISH_JERKY" : "Meat-Jerky", "FISH_JERKY" : "Meat-Jerky",
"KELP_COOKIE" : "Kelp-Cookie", "KELP_COOKIE" : "Kelp-Cookie",
"ANCIENT_ALTAR" : "Ancient-Altar", "ANCIENT_ALTAR" : "Ancient-Altar",
"ANCIENT_PEDESTAL" : "Ancient-Pedestal", "ANCIENT_PEDESTAL" : "Ancient-Pedestal",
"BLADE_OF_VAMPIRES" : "Blade-of-Vampires", "BLADE_OF_VAMPIRES" : "Blade-of-Vampires",
"BROKEN_SPAWNER" : "Broken-Spawner", "BROKEN_SPAWNER" : "Broken-Spawner",
"REPAIRED_SPAWNER" : "Reinforced-Spawner", "REPAIRED_SPAWNER" : "Reinforced-Spawner",
"NETHER_GOLD_PAN" : "Nether-Gold-Pan", "NETHER_GOLD_PAN" : "Nether-Gold-Pan",
"PICKAXE_OF_CONTAINMENT" : "Pickaxe-of-Containment", "PICKAXE_OF_CONTAINMENT" : "Pickaxe-of-Containment",
"SEISMIC_AXE" : "Seismic-Axe", "SEISMIC_AXE" : "Seismic-Axe",
"SMELTERS_PICKAXE" : "Smelter's-Pickaxe", "SMELTERS_PICKAXE" : "Smelter's-Pickaxe",
"MAGNET" : "Magnet", "MAGNET" : "Magnet",
"BASIC_CIRCUIT_BOARD" : "Circuit-Boards", "BASIC_CIRCUIT_BOARD" : "Circuit-Boards",
"ADVANCED_CIRCUIT_BOARD" : "Circuit-Boards", "ADVANCED_CIRCUIT_BOARD" : "Circuit-Boards",
"BATTERY" : "Battery", "BATTERY" : "Battery",
"STEEL_THRUSTER" : "Steel-Thruster", "STEEL_THRUSTER" : "Steel-Thruster",
"POWER_CRYSTAL" : "Power-Crystal", "POWER_CRYSTAL" : "Power-Crystal",
"SOLAR_PANEL" : "Solar-Panel", "SOLAR_PANEL" : "Solar-Panel",
"ELECTRO_MAGNET" : "Electromagnet", "ELECTRO_MAGNET" : "Electromagnet",
"ELECTRIC_MOTOR" : "Electric-Motor", "ELECTRIC_MOTOR" : "Electric-Motor",
"HEATING_COIL" : "Heating-Coil", "HEATING_COIL" : "Heating-Coil",
"COPPER_WIRE" : "Copper-Wire", "COPPER_WIRE" : "Copper-Wire",
"HARDENED_GLASS" : "Hardened-Glass", "HARDENED_GLASS" : "Hardened-Glass",
"COOLING_UNIT" : "Cooling-Unit", "COOLING_UNIT" : "Cooling-Unit",
"WITHER_PROOF_OBSIDIAN" : "Wither-Proof-Blocks", "WITHER_PROOF_OBSIDIAN" : "Wither-Proof-Blocks",
"WITHER_PROOF_GLASS" : "Wither-Proof-Blocks", "WITHER_PROOF_GLASS" : "Wither-Proof-Blocks",
"REACTOR_COOLANT_CELL" : "Coolant-Cells", "REACTOR_COOLANT_CELL" : "Coolant-Cells",
"NETHER_ICE_COOLANT_CELL" : "Coolant-Cells", "NETHER_ICE_COOLANT_CELL" : "Coolant-Cells",
"IRON_DUST" : "Iron-Dust", "IRON_DUST" : "Iron-Dust",
"GOLD_DUST" : "Gold-Dust", "GOLD_DUST" : "Gold-Dust",
"GOLD_4K" : "Gold-Ingot", "GOLD_4K" : "Gold-Ingot",
"GOLD_6K" : "Gold-Ingot", "GOLD_6K" : "Gold-Ingot",
"GOLD_8K" : "Gold-Ingot", "GOLD_8K" : "Gold-Ingot",
"GOLD_10K" : "Gold-Ingot", "GOLD_10K" : "Gold-Ingot",
"GOLD_12K" : "Gold-Ingot", "GOLD_12K" : "Gold-Ingot",
"GOLD_14K" : "Gold-Ingot", "GOLD_14K" : "Gold-Ingot",
"GOLD_16K" : "Gold-Ingot", "GOLD_16K" : "Gold-Ingot",
"GOLD_18K" : "Gold-Ingot", "GOLD_18K" : "Gold-Ingot",
"GOLD_20K" : "Gold-Ingot", "GOLD_20K" : "Gold-Ingot",
"GOLD_22K" : "Gold-Ingot", "GOLD_22K" : "Gold-Ingot",
"GOLD_24K" : "Gold-Ingot", "GOLD_24K" : "Gold-Ingot",
"ENERGY_REGULATOR" : "Energy-Regulator", "ENERGY_REGULATOR" : "Energy-Regulator",
"SMALL_CAPACITOR" : "Energy-Capacitors", "SMALL_CAPACITOR" : "Energy-Capacitors",
"MEDIUM_CAPACITOR" : "Energy-Capacitors", "MEDIUM_CAPACITOR" : "Energy-Capacitors",
"BIG_CAPACITOR" : "Energy-Capacitors", "BIG_CAPACITOR" : "Energy-Capacitors",
"LARGE_CAPACITOR" : "Energy-Capacitors", "LARGE_CAPACITOR" : "Energy-Capacitors",
"CARBONADO_EDGED_CAPACITOR" : "Energy-Capacitors", "CARBONADO_EDGED_CAPACITOR" : "Energy-Capacitors",
"SOLAR_GENERATOR" : "Solar-Generator", "SOLAR_GENERATOR" : "Solar-Generator",
"SOLAR_GENERATOR_2" : "Solar-Generator", "SOLAR_GENERATOR_2" : "Solar-Generator",
"SOLAR_GENERATOR_3" : "Solar-Generator", "SOLAR_GENERATOR_3" : "Solar-Generator",
"SOLAR_GENERATOR_4" : "Solar-Generator", "SOLAR_GENERATOR_4" : "Solar-Generator",
"COAL_GENERATOR" : "Coal-Generator", "COAL_GENERATOR" : "Coal-Generator",
"COAL_GENERATOR_2" : "Coal-Generator", "COAL_GENERATOR_2" : "Coal-Generator",
"COBALT_PICKAXE" : "Cobalt-Pickaxe", "COBALT_PICKAXE" : "Cobalt-Pickaxe",
"EXPLOSIVE_PICKAXE" : "Explosive-Pickaxe", "EXPLOSIVE_PICKAXE" : "Explosive-Pickaxe",
"EXPLOSIVE_SHOVEL" : "Explosive-Shovel", "EXPLOSIVE_SHOVEL" : "Explosive-Shovel",
"GRAPPLING_HOOK" : "Grappling-Hook", "GRAPPLING_HOOK" : "Grappling-Hook",
"HERCULES_PICKAXE" : "Hercules'-Pickaxe", "HERCULES_PICKAXE" : "Hercules'-Pickaxe",
"LUMBER_AXE" : "Lumber-Axe", "LUMBER_AXE" : "Lumber-Axe",
"PICKAXE_OF_VEIN_MINING" : "Pickaxe-of-Vein-Mining", "PICKAXE_OF_VEIN_MINING" : "Pickaxe-of-Vein-Mining",
"PICKAXE_OF_THE_SEEKER" : "Pickaxe-of-the-Seeker", "PICKAXE_OF_THE_SEEKER" : "Pickaxe-of-the-Seeker",
"CARGO_OUTPUT_ADVANCED" : "Advanced-Output-Node", "CARGO_OUTPUT_ADVANCED" : "Advanced-Output-Node",
"CARGO_MANAGER" : "Cargo-Manager", "CARGO_MANAGER" : "Cargo-Manager",
"CARGO_MOTOR" : "Cargo-Motor", "CARGO_MOTOR" : "Cargo-Motor",
"CARGO_NODE" : "Connector-Node", "CARGO_NODE" : "Connector-Node",
"CARGO_INPUT" : "Input-Node", "CARGO_INPUT" : "Input-Node",
"CARGO_OUTPUT" : "Output-Node", "CARGO_OUTPUT" : "Output-Node",
"TRASH_CAN" : "Trash-Can", "TRASH_CAN" : "Trash-Can",
"ORE_WASHER" : "Ore-Washer", "ORE_WASHER" : "Ore-Washer",
"SCUBA_HELMET" : "Hazmat-Suit", "SCUBA_HELMET" : "Hazmat-Suit",
"HAZMAT_CHESTPLATE" : "Hazmat-Suit", "HAZMAT_CHESTPLATE" : "Hazmat-Suit",
"HAZMAT_LEGGINGS" : "Hazmat-Suit", "HAZMAT_LEGGINGS" : "Hazmat-Suit",
"RUBBER_BOOTS" : "Hazmat-Suit", "RUBBER_BOOTS" : "Hazmat-Suit",
"ARMOR_FORGE" : "Armor-Forge", "ARMOR_FORGE" : "Armor-Forge",
"AUTOMATED_PANNING_MACHINE" : "Automated-Panning-Machine", "AUTOMATED_PANNING_MACHINE" : "Automated-Panning-Machine",
"COMPRESSOR" : "Compressor", "COMPRESSOR" : "Compressor",
"ORE_CRUSHER" : "Ore-Crusher", "ORE_CRUSHER" : "Ore-Crusher",
"PRESSURE_CHAMBER" : "Pressure-Chamber", "PRESSURE_CHAMBER" : "Pressure-Chamber",
"GRIND_STONE" : "Grind-Stone", "GRIND_STONE" : "Grind-Stone",
"MAGIC_WORKBENCH" : "Magic-Workbench", "MAGIC_WORKBENCH" : "Magic-Workbench",
"PORTABLE_CRAFTER" : "Portable-Crafter", "PORTABLE_CRAFTER" : "Portable-Crafter",
"PORTABLE_DUSTBIN" : "Portable-Dustbin", "PORTABLE_DUSTBIN" : "Portable-Dustbin",
"COOLER" : "Cooler", "COOLER" : "Cooler",
"ALUMINUM_BRASS_INGOT" : "Aluminum-Brass-Ingot", "ALUMINUM_BRASS_INGOT" : "Aluminum-Brass-Ingot",
"ALUMINUM_BRONZE_INGOT" : "Aluminum-Bronze-Ingot", "ALUMINUM_BRONZE_INGOT" : "Aluminum-Bronze-Ingot",
"ALUMINUM_DUST" : "Aluminum-Dust", "ALUMINUM_DUST" : "Aluminum-Dust",
"ALUMINUM_INGOT" : "Aluminum-Ingot", "ALUMINUM_INGOT" : "Aluminum-Ingot",
"GLOWSTONE_HELMET" : "Magical-Armor", "GLOWSTONE_HELMET" : "Magical-Armor",
"GLOWSTONE_CHESTPLATE" : "Magical-Armor", "GLOWSTONE_CHESTPLATE" : "Magical-Armor",
"GLOWSTONE_LEGGINGS" : "Magical-Armor", "GLOWSTONE_LEGGINGS" : "Magical-Armor",
"GLOWSTONE_BOOTS" : "Magical-Armor", "GLOWSTONE_BOOTS" : "Magical-Armor",
"ENDER_HELMET" : "Magical-Armor", "ENDER_HELMET" : "Magical-Armor",
"ENDER_CHESTPLATE" : "Magical-Armor", "ENDER_CHESTPLATE" : "Magical-Armor",
"ENDER_LEGGINGS" : "Magical-Armor", "ENDER_LEGGINGS" : "Magical-Armor",
"ENDER_BOOTS" : "Magical-Armor", "ENDER_BOOTS" : "Magical-Armor",
"SLIME_HELMET" : "Magical-Armor", "SLIME_HELMET" : "Magical-Armor",
"SLIME_CHESTPLATE" : "Magical-Armor", "SLIME_CHESTPLATE" : "Magical-Armor",
"SLIME_LEGGINGS" : "Magical-Armor", "SLIME_LEGGINGS" : "Magical-Armor",
"SLIME_BOOTS" : "Magical-Armor", "SLIME_BOOTS" : "Magical-Armor",
"CACTUS_HELMET" : "Armor", "CACTUS_HELMET" : "Armor",
"CACTUS_CHESTPLATE" : "Armor", "CACTUS_CHESTPLATE" : "Armor",
"CACTUS_LEGGINGS" : "Armor", "CACTUS_LEGGINGS" : "Armor",
"CACTUS_BOOTS" : "Armor", "CACTUS_BOOTS" : "Armor",
"DAMASCUS_STEEL_HELMET" : "Armor", "DAMASCUS_STEEL_HELMET" : "Armor",
"DAMASCUS_STEEL_CHESTPLATE" : "Armor", "DAMASCUS_STEEL_CHESTPLATE" : "Armor",
"DAMASCUS_STEEL_LEGGINGS" : "Armor", "DAMASCUS_STEEL_LEGGINGS" : "Armor",
"DAMASCUS_STEEL_BOOTS" : "Armor", "DAMASCUS_STEEL_BOOTS" : "Armor",
"REINFORCED_ALLOY_HELMET" : "Armor", "REINFORCED_ALLOY_HELMET" : "Armor",
"REINFORCED_ALLOY_CHESTPLATE" : "Armor", "REINFORCED_ALLOY_CHESTPLATE" : "Armor",
"REINFORCED_ALLOY_LEGGINGS" : "Armor", "REINFORCED_ALLOY_LEGGINGS" : "Armor",
"REINFORCED_ALLOY_BOOTS" : "Armor", "REINFORCED_ALLOY_BOOTS" : "Armor",
"GILDED_IRON_HELMET" : "Armor", "GILDED_IRON_HELMET" : "Armor",
"GILDED_IRON_CHESTPLATE" : "Armor", "GILDED_IRON_CHESTPLATE" : "Armor",
"GILDED_IRON_LEGGINGS" : "Armor", "GILDED_IRON_LEGGINGS" : "Armor",
"GILDED_IRON_BOOTS" : "Armor", "GILDED_IRON_BOOTS" : "Armor",
"GOLD_12K_HELMET" : "Armor", "GOLD_12K_HELMET" : "Armor",
"GOLD_12K_CHESTPLATE" : "Armor", "GOLD_12K_CHESTPLATE" : "Armor",
"GOLD_12K_LEGGINGS" : "Armor", "GOLD_12K_LEGGINGS" : "Armor",
"GOLD_12K_BOOTS" : "Armor", "GOLD_12K_BOOTS" : "Armor",
"SLIME_STEEL_HELMET" : "Magical-Armor", "SLIME_STEEL_HELMET" : "Magical-Armor",
"SLIME_STEEL_CHESTPLATE" : "Magical-Armor", "SLIME_STEEL_CHESTPLATE" : "Magical-Armor",
"SLIME_STEEL_LEGGINGS" : "Magical-Armor", "SLIME_STEEL_LEGGINGS" : "Magical-Armor",
"SLIME_STEEL_BOOTS" : "Magical-Armor", "SLIME_STEEL_BOOTS" : "Magical-Armor",
"BILLON_INGOT" : "Billon-Ingot", "BILLON_INGOT" : "Billon-Ingot",
"BLOCK_PLACER" : "Block-Placer", "BLOCK_PLACER" : "Block-Placer",
"EXPLOSIVE_BOW" : "Bows", "EXPLOSIVE_BOW" : "Bows",
"ICY_BOW" : "Bows", "ICY_BOW" : "Bows",
"BRASS_INGOT" : "Brass-Ingot", "BRASS_INGOT" : "Brass-Ingot",
"BRONZE_INGOT" : "Bronze-Ingot", "BRONZE_INGOT" : "Bronze-Ingot",
"CHRISTMAS_MILK" : "Christmas-Items", "CHRISTMAS_MILK" : "Christmas-Items",
"CHRISTMAS_CHOCOLATE_MILK" : "Christmas-Items", "CHRISTMAS_CHOCOLATE_MILK" : "Christmas-Items",
"CHRISTMAS_EGG_NOG" : "Christmas-Items", "CHRISTMAS_EGG_NOG" : "Christmas-Items",
"CHRISTMAS_APPLE_CIDER" : "Christmas-Items", "CHRISTMAS_APPLE_CIDER" : "Christmas-Items",
"CHRISTMAS_COOKIE" : "Christmas-Items", "CHRISTMAS_COOKIE" : "Christmas-Items",
"CHRISTMAS_FRUIT_CAKE" : "Christmas-Items", "CHRISTMAS_FRUIT_CAKE" : "Christmas-Items",
"CHRISTMAS_APPLE_PIE" : "Christmas-Items", "CHRISTMAS_APPLE_PIE" : "Christmas-Items",
"CHRISTMAS_HOT_CHOCOLATE" : "Christmas-Items", "CHRISTMAS_HOT_CHOCOLATE" : "Christmas-Items",
"CHRISTMAS_CAKE" : "Christmas-Items", "CHRISTMAS_CAKE" : "Christmas-Items",
"CHRISTMAS_CARAMEL" : "Christmas-Items", "CHRISTMAS_CARAMEL" : "Christmas-Items",
"CHRISTMAS_CARAMEL_APPLE" : "Christmas-Items", "CHRISTMAS_CARAMEL_APPLE" : "Christmas-Items",
"CHRISTMAS_CHOCOLATE_APPLE" : "Christmas-Items", "CHRISTMAS_CHOCOLATE_APPLE" : "Christmas-Items",
"CHRISTMAS_PRESENT" : "Christmas-Items", "CHRISTMAS_PRESENT" : "Christmas-Items",
"RAINBOW_WOOL_XMAS" : "Christmas-Seasonal-Category", "RAINBOW_WOOL_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_GLASS_XMAS" : "Christmas-Seasonal-Category", "RAINBOW_GLASS_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_CLAY_XMAS" : "Christmas-Seasonal-Category", "RAINBOW_CLAY_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_GLASS_PANE_XMAS" : "Christmas-Seasonal-Category", "RAINBOW_GLASS_PANE_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_CONCRETE_XMAS" : "Christmas-Seasonal-Category", "RAINBOW_CONCRETE_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_GLAZED_TERRACOTTA_XMAS" : "Christmas-Seasonal-Category", "RAINBOW_GLAZED_TERRACOTTA_XMAS" : "Christmas-Seasonal-Category",
"COBALT_INGOT" : "Cobalt-Ingot", "COBALT_INGOT" : "Cobalt-Ingot",
"COPPER_DUST" : "Copper-Dust", "COPPER_DUST" : "Copper-Dust",
"COPPER_INGOT" : "Copper-Ingot", "COPPER_INGOT" : "Copper-Ingot",
"CORINTHIAN_BRONZE_INGOT" : "Corinthian-Bronze-Ingot", "CORINTHIAN_BRONZE_INGOT" : "Corinthian-Bronze-Ingot",
"DAMASCUS_STEEL_INGOT" : "Damascus-Steel-Ingot", "DAMASCUS_STEEL_INGOT" : "Damascus-Steel-Ingot",
"DURALUMIN_INGOT" : "Duralumin-Ingot", "DURALUMIN_INGOT" : "Duralumin-Ingot",
"ELEVATOR_PLATE" : "Elevator-Plate", "ELEVATOR_PLATE" : "Elevator-Plate",
"ELYTRA_SCALE" : "Elytras", "ELYTRA_SCALE" : "Elytras",
"INFUSED_ELYTRA" : "Elytras", "INFUSED_ELYTRA" : "Elytras",
"SOULBOUND_ELYTRA" : "Elytras", "SOULBOUND_ELYTRA" : "Elytras",
"ENHANCED_FURNACE" : "Enhanced-Furnaces", "ENHANCED_FURNACE" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_2" : "Enhanced-Furnaces", "ENHANCED_FURNACE_2" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_3" : "Enhanced-Furnaces", "ENHANCED_FURNACE_3" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_4" : "Enhanced-Furnaces", "ENHANCED_FURNACE_4" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_5" : "Enhanced-Furnaces", "ENHANCED_FURNACE_5" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_6" : "Enhanced-Furnaces", "ENHANCED_FURNACE_6" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_7" : "Enhanced-Furnaces", "ENHANCED_FURNACE_7" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_8" : "Enhanced-Furnaces", "ENHANCED_FURNACE_8" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_9" : "Enhanced-Furnaces", "ENHANCED_FURNACE_9" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_10" : "Enhanced-Furnaces", "ENHANCED_FURNACE_10" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_11" : "Enhanced-Furnaces", "ENHANCED_FURNACE_11" : "Enhanced-Furnaces",
"REINFORCED_FURNACE" : "Enhanced-Furnaces", "REINFORCED_FURNACE" : "Enhanced-Furnaces",
"CARBONADO_EDGED_FURNACE" : "Enhanced-Furnaces", "CARBONADO_EDGED_FURNACE" : "Enhanced-Furnaces",
"FERROSILICON" : "Ferrosilicon", "FERROSILICON" : "Ferrosilicon",
"GEO_MINER" : "GEO-Miner", "GEO_MINER" : "GEO-Miner",
"GPS_ACTIVATION_DEVICE_SHARED" : "GPS-Activation-Device", "GPS_ACTIVATION_DEVICE_SHARED" : "GPS-Activation-Device",
"GPS_ACTIVATION_DEVICE_PERSONAL" : "GPS-Activation-Device", "GPS_ACTIVATION_DEVICE_PERSONAL" : "GPS-Activation-Device",
"GPS_CONTROL_PANEL" : "GPS-Control-Panel", "GPS_CONTROL_PANEL" : "GPS-Control-Panel",
"GPS_EMERGENCY_TRANSMITTER" : "GPS-Emergency-Transmitter", "GPS_EMERGENCY_TRANSMITTER" : "GPS-Emergency-Transmitter",
"GPS_GEO_SCANNER" : "GPS-Geo-Scanner", "GPS_GEO_SCANNER" : "GPS-Geo-Scanner",
"GPS_MARKER_TOOL" : "GPS-Marker-Tool", "GPS_MARKER_TOOL" : "GPS-Marker-Tool",
"GPS_TELEPORTATION_MATRIX" : "GPS-Teleporter-Matrix", "GPS_TELEPORTATION_MATRIX" : "GPS-Teleporter-Matrix",
"GPS_TELEPORTER_PYLON" : "GPS-Teleporter-Pylon", "GPS_TELEPORTER_PYLON" : "GPS-Teleporter-Pylon",
"GPS_TRANSMITTER" : "GPS-Transmitter", "GPS_TRANSMITTER" : "GPS-Transmitter",
"GILDED_IRON" : "Gilded-Iron", "GILDED_IRON" : "Gilded-Iron",
"HARDENED_METAL_INGOT" : "Hardened-Metal", "HARDENED_METAL_INGOT" : "Hardened-Metal",
"LEAD_DUST" : "Lead-Dust", "LEAD_DUST" : "Lead-Dust",
"LEAD_INGOT" : "Lead-Ingot", "LEAD_INGOT" : "Lead-Ingot",
"MAGNESIUM_DUST" : "Magnesium-Dust", "MAGNESIUM_DUST" : "Magnesium-Dust",
"MAGNESIUM_INGOT" : "Magnesium-Ingot", "MAGNESIUM_INGOT" : "Magnesium-Ingot",
"NICKEL_INGOT" : "Nickel-Ingot", "NICKEL_INGOT" : "Nickel-Ingot",
"OIL_PUMP" : "Oil-Pump", "OIL_PUMP" : "Oil-Pump",
"PORTABLE_GEO_SCANNER" : "Portable-Geo-Scanner", "PORTABLE_GEO_SCANNER" : "Portable-Geo-Scanner",
"RAINBOW_WOOL" : "Rainbow-Blocks", "RAINBOW_WOOL" : "Rainbow-Blocks",
"RAINBOW_GLASS" : "Rainbow-Blocks", "RAINBOW_GLASS" : "Rainbow-Blocks",
"RAINBOW_CLAY" : "Rainbow-Blocks", "RAINBOW_CLAY" : "Rainbow-Blocks",
"RAINBOW_GLASS_PANE" : "Rainbow-Blocks", "RAINBOW_GLASS_PANE" : "Rainbow-Blocks",
"RAINBOW_CONCRETE" : "Rainbow-Blocks", "RAINBOW_CONCRETE" : "Rainbow-Blocks",
"RAINBOW_GLAZED_TERRACOTTA" : "Rainbow-Blocks", "RAINBOW_GLAZED_TERRACOTTA" : "Rainbow-Blocks",
"REDSTONE_ALLOY" : "Redstone-Alloy-Ingot", "REDSTONE_ALLOY" : "Redstone-Alloy-Ingot",
"REINFORCED_ALLOY_INGOT" : "Reinforced-Alloy-Ingot", "REINFORCED_ALLOY_INGOT" : "Reinforced-Alloy-Ingot",
"SILVER_DUST" : "Silver-Dust", "SILVER_DUST" : "Silver-Dust",
"SILVER_INGOT" : "Silver-Ingot", "SILVER_INGOT" : "Silver-Ingot",
"SOLDER_INGOT" : "Solder-Ingot", "SOLDER_INGOT" : "Solder-Ingot",
"SOULBOUND_HELMET" : "Soulbound-Armor", "SOULBOUND_HELMET" : "Soulbound-Armor",
"SOULBOUND_CHESTPLATE" : "Soulbound-Armor", "SOULBOUND_CHESTPLATE" : "Soulbound-Armor",
"SOULBOUND_LEGGINGS" : "Soulbound-Armor", "SOULBOUND_LEGGINGS" : "Soulbound-Armor",
"SOULBOUND_BOOTS" : "Soulbound-Armor", "SOULBOUND_BOOTS" : "Soulbound-Armor",
"ANCIENT_RUNE_SOULBOUND" : "Soulbound-Rune", "ANCIENT_RUNE_SOULBOUND" : "Soulbound-Rune",
"SOULBOUND_SWORD" : "Soulbound-Weapons", "SOULBOUND_SWORD" : "Soulbound-Weapons",
"SOULBOUND_BOW" : "Soulbound-Weapons", "SOULBOUND_BOW" : "Soulbound-Weapons",
"SOULBOUND_PICKAXE" : "Soulbound-Weapons", "SOULBOUND_PICKAXE" : "Soulbound-Weapons",
"SOULBOUND_AXE" : "Soulbound-Weapons", "SOULBOUND_AXE" : "Soulbound-Weapons",
"SOULBOUND_SHOVEL" : "Soulbound-Weapons", "SOULBOUND_SHOVEL" : "Soulbound-Weapons",
"SOULBOUND_HOE" : "Soulbound-Weapons", "SOULBOUND_HOE" : "Soulbound-Weapons",
"SOULBOUND_TRIDENT" : "Soulbound-Weapons", "SOULBOUND_TRIDENT" : "Soulbound-Weapons",
"STEEL_INGOT" : "Steel-Ingot", "STEEL_INGOT" : "Steel-Ingot",
"SWORD_OF_BEHEADING" : "Sword-of-Beheading", "SWORD_OF_BEHEADING" : "Sword-of-Beheading",
"COMMON_TALISMAN" : "Talismans", "COMMON_TALISMAN" : "Talismans",
"ENDER_TALISMAN" : "Talismans", "ENDER_TALISMAN" : "Talismans",
"TIN_DUST" : "Tin-Dust", "TIN_DUST" : "Tin-Dust",
"TIN_INGOT" : "Tin-Ingot", "TIN_INGOT" : "Tin-Ingot",
"GRANDMAS_WALKING_STICK" : "Walking-Sticks", "GRANDMAS_WALKING_STICK" : "Walking-Sticks",
"GRANDPAS_WALKING_STICK" : "Walking-Sticks", "GRANDPAS_WALKING_STICK" : "Walking-Sticks",
"ZINC_DUST" : "Zinc-Dust", "ZINC_DUST" : "Zinc-Dust",
"ZINC_INGOT" : "Zinc-Ingot" "ZINC_INGOT" : "Zinc-Ingot"
} }

View File

@ -51,7 +51,7 @@ class TestSlimefunGuideListener {
PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide"); PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide");
listener.onJoin(event); listener.onJoin(event);
ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultLayout()); ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultMode());
Assertions.assertEquals(!hasPlayedBefore && giveSlimefunGuide, hasSlimefunGuide(player, guide)); Assertions.assertEquals(!hasPlayedBefore && giveSlimefunGuide, hasSlimefunGuide(player, guide));
} }

View File

@ -16,7 +16,7 @@ class TestHeadTextures {
void testForDuplicates() { void testForDuplicates() {
Set<String> textures = new HashSet<>(); Set<String> textures = new HashSet<>();
for (HeadTexture head : HeadTexture.valuesCache) { for (HeadTexture head : HeadTexture.values()) {
String texture = head.getTexture(); String texture = head.getTexture();
Assertions.assertNotNull(texture); Assertions.assertNotNull(texture);

View File

@ -11,12 +11,11 @@ class TestMinecraftVersion {
@Test @Test
@DisplayName("Test if Minecraft versions match themselves") @DisplayName("Test if Minecraft versions match themselves")
void testMatches() { void testMatches() {
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.matches("v1_14_R2")); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.isMinecraftVersion(14));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.matches("v1_15_R1")); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.isMinecraftVersion(15));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.matches("v1_14_R2")); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.isMinecraftVersion(14));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_14.matches("1.14.x")); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_14.isMinecraftVersion(0));
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.MINECRAFT_1_14.matches(null));
} }
@Test @Test