1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 03:35:51 +00:00

Merge branch 'Slimefun:master' into master

This commit is contained in:
J3fftw 2022-03-20 14:31:44 +01:00 committed by GitHub
commit b7825a4c95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 194 additions and 85 deletions

View File

@ -27,7 +27,7 @@ jobs:
api: '🔧 API'
compatibility: '🤝 Compatibility'
- uses: thollander/actions-comment-pull-request@v1.0.4
- uses: thollander/actions-comment-pull-request@v1.1.0
name: Leave a comment about the applied label
if: ${{ steps.labeller.outputs.applied != 0 }}
with:
@ -36,7 +36,7 @@ jobs:
Your Pull Request was automatically labelled as: "${{ steps.labeller.outputs.applied }}"
Thank you for contributing to this project! ❤️
- uses: thollander/actions-comment-pull-request@v1.0.4
- uses: thollander/actions-comment-pull-request@v1.1.0
name: Leave a comment about our branch naming convention
if: ${{ steps.labeller.outputs.applied == 0 }}
with:

View File

@ -1,5 +1,6 @@
# Table of contents
- [Release Candidate 31 (TBD)](#release-candidate-31-tbd)
- [Release Candidate 32 (TBD)](#release-candidate-32-tbd)
- [Release Candidate 31 (14 Mar 2022)](#release-candidate-31-14-mar-2022)
- [Release Candidate 30 (31 Dec 2021)](#release-candidate-30-31-dec-2021)
- [Release Candidate 29 (07 Nov 2021)](#release-candidate-29-07-nov-2021)
- [Release Candidate 28 (06 Sep 2021)](#release-candidate-28-06-sep-2021)
@ -31,7 +32,18 @@
- [Release Candidate 2 (29 Sep 2019)](#release-candidate-2-29-sep-2019)
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
## Release Candidate 31 (TBD)
## Release Candidate 32 (TBD)
#### Additions
#### Changes
#### Fixes
* Fixed #3445
## Release Candidate 31 (14 Mar 2022)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#31
#### Additions
* Added Armored Jetpack
@ -49,6 +61,7 @@
* You can now pick up Slimefun blocks in creative mode using the middle mouse button
* `/sf search` no longer shows items in hidden item groups (can be overidden by a config setting)
* Fluid Pumps can now fill bottles with water
* (API) Added Shulker boxes to `ColoredMaterial` enum
#### Changes
* (API) `BiomeMapParser` is now `public`

View File

@ -362,7 +362,7 @@
<dependency>
<groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId>
<version>3.13.6</version>
<version>3.13.7</version>
<scope>compile</scope>
<exclusions>
@ -390,7 +390,7 @@
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.18</artifactId>
<version>1.18.1</version>
<version>1.24.1</version>
<scope>test</scope>
<exclusions>
@ -435,7 +435,7 @@
<dependency>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.209</version>
<version>2.1.211</version>
<scope>provided</scope>
<exclusions>

View File

@ -90,8 +90,7 @@ public class ItemGroup implements Keyed {
}
@Override
@Nonnull
public final NamespacedKey getKey() {
public final @Nonnull NamespacedKey getKey() {
return key;
}
@ -117,6 +116,16 @@ public class ItemGroup implements Keyed {
sortCategoriesByTier();
}
/**
* This method returns whether this {@link ItemGroup} has been registered yet.
* More specifically: Whether {@link #register(SlimefunAddon)} was called or not.
*
* @return Whether this {@link ItemGroup} has been registered
*/
public boolean isRegistered() {
return this.addon != null && Slimefun.getRegistry().getAllItemGroups().contains(this);
}
/**
* Returns the tier of this {@link ItemGroup}.
* The tier determines the position of this {@link ItemGroup} in the {@link SlimefunGuide}.
@ -157,8 +166,7 @@ public class ItemGroup implements Keyed {
*
* @return The {@link SlimefunAddon} or null if unregistered
*/
@Nullable
public final SlimefunAddon getAddon() {
public final @Nullable SlimefunAddon getAddon() {
return addon;
}
@ -176,6 +184,10 @@ public class ItemGroup implements Keyed {
return;
}
if (isRegistered() && !item.getAddon().getName().equals(this.addon.getName())) {
item.warn("This item does not belong into ItemGroup " + this + " as that group belongs to " + this.addon.getName());
}
items.add(item);
}
@ -199,8 +211,7 @@ public class ItemGroup implements Keyed {
*
* @return A localized display item for this {@link ItemGroup}
*/
@Nonnull
public ItemStack getItem(@Nonnull Player p) {
public @Nonnull ItemStack getItem(@Nonnull Player p) {
return new CustomItemStack(item, meta -> {
String name = Slimefun.getLocalization().getItemGroupName(p, getKey());
@ -224,8 +235,7 @@ public class ItemGroup implements Keyed {
*
* @return The unlocalized name of this {@link ItemGroup}
*/
@Nonnull
public String getUnlocalizedName() {
public @Nonnull String getUnlocalizedName() {
return ChatColor.stripColor(item.getItemMeta().getDisplayName());
}
@ -238,8 +248,7 @@ public class ItemGroup implements Keyed {
*
* @return The localized name of this {@link ItemGroup}
*/
@Nonnull
public String getDisplayName(@Nonnull Player p) {
public @Nonnull String getDisplayName(@Nonnull Player p) {
String localized = Slimefun.getLocalization().getItemGroupName(p, getKey());
if (localized != null) {
@ -254,8 +263,7 @@ public class ItemGroup implements Keyed {
*
* @return the list of SlimefunItems bound to this {@link ItemGroup}
*/
@Nonnull
public List<SlimefunItem> getItems() {
public @Nonnull List<SlimefunItem> getItems() {
return items;
}
@ -271,6 +279,52 @@ public class ItemGroup implements Keyed {
return item != null && items.contains(item);
}
/**
* This method returns whether this {@link ItemGroup} can be accessed
* by the given {@link Player}. If an {@link ItemGroup} is not accessible,
* it will not show up in the {@link SlimefunGuide} nor will items from this
* {@link ItemGroup} show up in the guide search.
*
* @param p
* The {@link Player} to check for
*
* @return Whether this {@link ItemGroup} is accessible by the given {@link Player}
*/
public boolean isAccessible(@Nonnull Player p) {
return true;
}
/**
* This method returns whether this {@link ItemGroup} can be viewed
* by the given {@link Player}. Empty {@link ItemGroup ItemGroups} will not
* be visible. This includes {@link ItemGroup ItemGroups} where every {@link SlimefunItem}
* is disabled. If an {@link ItemGroup} is not accessible by the {@link Player},
* see {@link #isAccessible(Player)}, this method will also return false.
*
* @param p
* The {@link Player} to check for
*
* @return Whether this {@link ItemGroup} is visible to the given {@link Player}
*/
public boolean isVisible(@Nonnull Player p) {
if (items.isEmpty() || !isAccessible(p)) {
return false;
}
for (SlimefunItem slimefunItem : getItems()) {
/*
* If any item for this item group is visible,
* the item group itself is also visible.
* Empty item groups are not displayed.
*/
if (!slimefunItem.isHidden() && !slimefunItem.isDisabledIn(p.getWorld())) {
return true;
}
}
return false;
}
@Override
public final boolean equals(Object obj) {
if (obj instanceof ItemGroup) {
@ -301,24 +355,9 @@ public class ItemGroup implements Keyed {
*
* @return Whether this {@link ItemGroup} will be hidden to the given {@link Player}
*/
@Deprecated
public boolean isHidden(@Nonnull Player p) {
for (SlimefunItem slimefunItem : getItems()) {
if (!slimefunItem.isHidden() && !slimefunItem.isDisabledIn(p.getWorld())) {
return false;
}
}
return true;
}
/**
* This method returns whether this {@link ItemGroup} has been registered yet.
* More specifically: Whether {@link #register(SlimefunAddon)} was called or not.
*
* @return Whether this {@link ItemGroup} has been registered
*/
public boolean isRegistered() {
return Slimefun.getRegistry().getAllItemGroups().contains(this);
return !isVisible(p);
}
}

View File

@ -36,6 +36,16 @@ public abstract class FlexItemGroup extends ItemGroup {
super(key, item, tier);
}
@Override
public final boolean isVisible(@Nonnull Player p) {
/*
* We can stop this method right here.
* We provide a custom method with more parameters for this.
* See isVisible(...)
*/
return true;
}
/**
* This method returns whether this {@link FlexItemGroup} is visible under the given context.
* Implementing this method gives full flexibility over who can see the ItemGroup when and where.
@ -66,16 +76,6 @@ public abstract class FlexItemGroup extends ItemGroup {
*/
public abstract void open(Player p, PlayerProfile profile, SlimefunGuideMode layout);
@Override
public final boolean isHidden(@Nonnull Player p) {
/*
* We can stop this method right here.
* We provide a custom method with more parameters for this.
* See isVisible(...)
*/
return false;
}
@Override
public final void add(@Nonnull SlimefunItem item) {
throw new UnsupportedOperationException("You cannot add items to a FlexItemGroup!");

View File

@ -56,12 +56,12 @@ public class SeasonalItemGroup extends ItemGroup {
}
@Override
public boolean isHidden(@Nonnull Player p) {
// Hide this ItemGroup if the month differs
public boolean isAccessible(@Nonnull Player p) {
// Block this ItemGroup if the month differs
if (month != LocalDate.now().getMonth()) {
return true;
return false;
}
return super.isHidden(p);
return super.isAccessible(p);
}
}

View File

@ -40,14 +40,29 @@ public class SubItemGroup extends ItemGroup {
}
@Override
public final boolean isHidden(@Nonnull Player p) {
public final boolean isVisible(@Nonnull Player p) {
/*
* Sub Categories are always hidden,
* they won't show up in the normal guide view.
*/
return false;
}
@Override
public final boolean isAccessible(@Nonnull Player p) {
/*
* Sub Categories are accessible, they are invisible
* but their items are available to the guide search.
*/
return true;
}
/**
* This method returns the parent {@link NestedItemGroup} which this
* {@link SubItemGroup} belongs to.
*
* @return The parent {@link NestedItemGroup}
*/
public final @Nonnull NestedItemGroup getParent() {
return parentItemGroup;
}

View File

@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.core.guide.options;
import java.util.Optional;
import javax.annotation.Nonnull;
import org.bukkit.Keyed;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -24,6 +26,7 @@ public interface SlimefunGuideOption<T> extends Keyed {
*
* @return The registering {@link SlimefunAddon}
*/
@Nonnull
SlimefunAddon getAddon();
Optional<ItemStack> getDisplayItem(Player p, ItemStack guide);

View File

@ -33,7 +33,6 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.items.groups.FlexItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.groups.LockedItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.groups.SubItemGroup;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.api.researches.Research;
@ -361,7 +360,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
break;
}
if (!slimefunItem.isHidden() && !isItemGroupHidden(p, slimefunItem) && isSearchFilterApplicable(slimefunItem, searchTerm)) {
if (!slimefunItem.isHidden() && isItemGroupAccessible(p, slimefunItem) && isSearchFilterApplicable(slimefunItem, searchTerm)) {
ItemStack itemstack = new CustomItemStack(slimefunItem.getItem(), meta -> {
ItemGroup itemGroup = slimefunItem.getItemGroup();
meta.setLore(Arrays.asList("", ChatColor.DARK_GRAY + "\u21E8 " + ChatColor.WHITE + itemGroup.getDisplayName(p)));
@ -391,19 +390,8 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
}
@ParametersAreNonnullByDefault
private boolean isItemGroupHidden(Player p, SlimefunItem slimefunItem) {
if (showHiddenItemGroupsInSearch) {
return false;
}
ItemGroup itemGroup = slimefunItem.getItemGroup();
// Fixes #3487 - SubItemGroups are "pseudo-hidden"
if (itemGroup instanceof SubItemGroup) {
return false;
} else {
return itemGroup.isHidden(p);
}
private boolean isItemGroupAccessible(Player p, SlimefunItem slimefunItem) {
return showHiddenItemGroupsInSearch || slimefunItem.getItemGroup().isAccessible(p);
}
@ParametersAreNonnullByDefault

View File

@ -55,8 +55,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
addItemHandler(onPlace(), onRightClick(), onBreak());
}
@Nonnull
private BlockPlaceHandler onPlace() {
private @Nonnull BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) {
@Override
@ -72,8 +71,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
};
}
@Nonnull
private BlockBreakHandler onBreak() {
private @Nonnull BlockBreakHandler onBreak() {
return new SimpleBlockBreakHandler() {
@Override
@ -83,8 +81,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
};
}
@Nonnull
public BlockUseHandler onRightClick() {
public @Nonnull BlockUseHandler onRightClick() {
return e -> {
e.cancel();
@ -97,15 +94,22 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
};
}
private static void openEditor(@Nonnull Player p, @Nonnull Block projector) {
private void openEditor(@Nonnull Player p, @Nonnull Block projector) {
ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "machines.HOLOGRAM_PROJECTOR.inventory-title"));
menu.addItem(0, new CustomItemStack(Material.NAME_TAG, "&7Text &e(Click to edit)", "", "&r" + ChatColors.color(BlockStorage.getLocationInfo(projector.getLocation(), "text"))));
menu.addItem(0, new CustomItemStack(Material.NAME_TAG, "&7Text &e(Click to edit)", "", "&f" + ChatColors.color(BlockStorage.getLocationInfo(projector.getLocation(), "text"))));
menu.addMenuClickHandler(0, (pl, slot, item, action) -> {
pl.closeInventory();
Slimefun.getLocalization().sendMessage(pl, "machines.HOLOGRAM_PROJECTOR.enter-text", true);
ChatUtils.awaitInput(pl, message -> {
// Fixes #3445 - Make sure the projector is not broken
if (!BlockStorage.check(projector, getId())) {
// Hologram projector no longer exists.
// TODO: Add a chat message informing the player that their message was ignored.
return;
}
ArmorStand hologram = getArmorStand(projector, true);
hologram.setCustomName(ChatColors.color(message));
BlockStorage.addBlockInfo(projector, "text", hologram.getCustomName());
@ -115,7 +119,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
return false;
});
menu.addItem(1, new CustomItemStack(Material.CLOCK, "&7Offset: &e" + NumberUtils.roundDecimalNumber(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + 1.0D), "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1"));
menu.addItem(1, new CustomItemStack(Material.CLOCK, "&7Offset: &e" + NumberUtils.roundDecimalNumber(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + 1.0D), "", "&fLeft Click: &7+0.1", "&fRight Click: &7-0.1"));
menu.addMenuClickHandler(1, (pl, slot, item, action) -> {
double offset = NumberUtils.reparseDouble(Double.valueOf(BlockStorage.getLocationInfo(projector.getLocation(), OFFSET_PARAMETER)) + (action.isRightClicked() ? -0.1F : 0.1F));
ArmorStand hologram = getArmorStand(projector, true);
@ -154,8 +158,7 @@ public class HologramProjector extends SlimefunItem implements HologramOwner {
return hologram;
}
@Nonnull
private static ArmorStand spawnArmorStand(@Nonnull Location l) {
private static @Nonnull ArmorStand spawnArmorStand(@Nonnull Location l) {
ArmorStand armorStand = (ArmorStand) l.getWorld().spawnEntity(l, EntityType.ARMOR_STAND);
armorStand.setVisible(false);
armorStand.setSilent(true);

View File

@ -177,6 +177,50 @@ public enum ColoredMaterial {
Material.GREEN_CONCRETE,
Material.RED_CONCRETE,
Material.BLACK_CONCRETE
}),
/**
* This {@link List} contains all shulker box colors ordered by their appearance ingame.
*/
SHULKER_BOX(new Material[] {
Material.WHITE_SHULKER_BOX,
Material.ORANGE_SHULKER_BOX,
Material.MAGENTA_SHULKER_BOX,
Material.LIGHT_BLUE_SHULKER_BOX,
Material.YELLOW_SHULKER_BOX,
Material.LIME_SHULKER_BOX,
Material.PINK_SHULKER_BOX,
Material.GRAY_SHULKER_BOX,
Material.LIGHT_GRAY_SHULKER_BOX,
Material.CYAN_SHULKER_BOX,
Material.PURPLE_SHULKER_BOX,
Material.BLUE_SHULKER_BOX,
Material.BROWN_SHULKER_BOX,
Material.GREEN_SHULKER_BOX,
Material.RED_SHULKER_BOX,
Material.BLACK_SHULKER_BOX
}),
/**
* This {@link List} contains all candle colors ordered by their appearance ingame.
*/
CANDLE(new Material[] {
Material.WHITE_CANDLE,
Material.ORANGE_CANDLE,
Material.MAGENTA_CANDLE,
Material.LIGHT_BLUE_CANDLE,
Material.YELLOW_CANDLE,
Material.LIME_CANDLE,
Material.PINK_CANDLE,
Material.GRAY_CANDLE,
Material.LIGHT_GRAY_CANDLE,
Material.CYAN_CANDLE,
Material.PURPLE_CANDLE,
Material.BLUE_CANDLE,
Material.BROWN_CANDLE,
Material.GREEN_CANDLE,
Material.RED_CANDLE,
Material.BLACK_CANDLE
});
// @formatter:on

View File

@ -87,7 +87,7 @@ class TestItemGroups {
Player player = server.addPlayer();
// Empty Item Groups are also hidden
Assertions.assertTrue(group.isHidden(player));
Assertions.assertFalse(group.isVisible(player));
SlimefunItem disabledItem = TestUtilities.mockSlimefunItem(plugin, "DISABLED_ITEM_GROUP_ITEM", new CustomItemStack(Material.BEETROOT, "&4Disabled"));
Slimefun.getItemCfg().setValue("DISABLED_ITEM_GROUP_ITEM.enabled", false);
@ -96,7 +96,7 @@ class TestItemGroups {
disabledItem.load();
// A disabled Item should also make the ItemGroup hide
Assertions.assertTrue(group.isHidden(player));
Assertions.assertFalse(group.isVisible(player));
SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "ITEM_GROUP_HIDDEN_TEST", new CustomItemStack(Material.BAMBOO, "&6Test Bamboo"));
item.setItemGroup(group);
@ -105,10 +105,10 @@ class TestItemGroups {
item.load();
// A hidden Item should also make the ItemGroup hide
Assertions.assertTrue(group.isHidden(player));
Assertions.assertFalse(group.isVisible(player));
item.setHidden(false);
Assertions.assertFalse(group.isHidden(player));
Assertions.assertTrue(group.isVisible(player));
}
@Test
@ -201,11 +201,11 @@ class TestItemGroups {
Player player = server.addPlayer();
Assertions.assertEquals(month, group.getMonth());
Assertions.assertFalse(group.isHidden(player));
Assertions.assertTrue(group.isVisible(player));
// ItemGroup with future Month
SeasonalItemGroup itemGroup2 = new SeasonalItemGroup(group.getKey(), month.plus(6), 1, new CustomItemStack(Material.MILK_BUCKET, "&dSeasonal Test"));
Assertions.assertTrue(itemGroup2.isHidden(player));
Assertions.assertFalse(itemGroup2.isVisible(player));
}
@Test
@ -225,7 +225,7 @@ class TestItemGroups {
};
Player player = server.addPlayer();
Assertions.assertFalse(group.isHidden(player));
Assertions.assertTrue(group.isVisible(player));
Assertions.assertThrows(UnsupportedOperationException.class, () -> group.add(null));
Assertions.assertThrows(UnsupportedOperationException.class, () -> group.contains(null));

View File

@ -7,6 +7,7 @@ import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Firework;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
@ -20,10 +21,13 @@ import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.WorldMock;
class TestFireworkUtils {
private static World world;
@BeforeAll
public static void load() {
MockBukkit.mock();
world = new WorldMock();
}
@AfterAll
@ -35,7 +39,7 @@ class TestFireworkUtils {
@MethodSource("getColors")
@DisplayName("Test colored Fireworks")
void testColoredFirework(Color color) {
Location l = new Location(new WorldMock(), 50, 50, 50);
Location l = new Location(world, 50, 50, 50);
Firework firework = FireworkUtils.createFirework(l, color);
Assertions.assertEquals(l, firework.getLocation());