Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ItemType Random Safety Improvements #6886

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/main/java/ch/njol/skript/aliases/ItemType.java
Original file line number Diff line number Diff line change
Expand Up @@ -612,15 +612,27 @@ public ItemType clone() {
.collect(Collectors.toList());
if (datas.isEmpty())
return null;
int numItems = datas.size();
int index = random.nextInt(numItems);
ItemStack is = datas.get(index).getStack();
ItemStack is = datas.get(random.nextInt(datas.size())).getStack();
assert is != null; // verified above
is = is.clone();
is.setAmount(getAmount());
return is;
}

/**
* @return One random ItemStack or Material that this ItemType represents.
* A Material may only be returned for ItemStacks containing a Material where {@link Material#isItem()} is false.
*/
public Object getRandomStackOrMaterial() {
ItemData randomData = types.get(random.nextInt(types.size()));
ItemStack stack = randomData.getStack();
if (stack == null)
return randomData.getType();
stack = stack.clone();
stack.setAmount(getAmount());
return stack;
}

/**
* Test whether this ItemType can be put into the given inventory completely.
* <p>
Expand Down Expand Up @@ -1396,8 +1408,11 @@ public void clearItemMeta() {
globalMeta = null;
}

/**
* @return A random Material this ItemType represents.
*/
public Material getMaterial() {
ItemData data = types.get(0);
ItemData data = types.get(random.nextInt(types.size()));
if (data == null)
throw new IllegalStateException("material not found");
return data.getType();
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,10 @@ public ItemStack parse(final String s, final ParseContext context) {
}

final ItemStack i = t.getRandom();
assert i != null;
if (i == null) {
Skript.error("'" + s + "' cannot represent an item");
return null;
}
return i;
}

Expand Down
13 changes: 7 additions & 6 deletions src/main/java/ch/njol/skript/conditions/CondIsPreferredTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,14 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
public boolean check(Event event) {
return blocks.check(event, block ->
items.check(event, item -> {
if (block instanceof Block) {
return ((Block) block).isPreferredTool(item.getRandom());
} else if (block instanceof BlockData) {
return ((BlockData) block).isPreferredTool(item.getRandom());
} else {
return false;
ItemStack stack = item.getRandom();
if (stack != null) {
if (block instanceof Block)
return ((Block) block).isPreferredTool(stack);
if (block instanceof BlockData)
return ((BlockData) block).isPreferredTool(stack);
}
return false;
}), isNegated());
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/ch/njol/skript/effects/EffOpenBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ protected void execute(final Event e) {
ItemType itemType = book.getSingle(e);
if (itemType != null) {
ItemStack itemStack = itemType.getRandom();
if (itemStack.getType() == Material.WRITTEN_BOOK) {
if (itemStack != null && itemStack.getType() == Material.WRITTEN_BOOK) {
for (Player player : players.getArray(e)) {
player.openBook(itemStack);
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/ch/njol/skript/effects/EffReplace.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,10 @@ private void replace(Event event, Object[] needles, Expression<?> haystackExpr)

if (new ItemType(itemStack).isSimilar(needle)) {
ItemStack newItemStack = ((ItemType) replacement).getRandom();
newItemStack.setAmount(itemStack.getAmount());

inv.setItem(slot, newItemStack);
if (newItemStack != null) {
newItemStack.setAmount(itemStack.getAmount());
inv.setItem(slot, newItemStack);
}
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/ch/njol/skript/entity/BoatChestData.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ public boolean isSupertypeOf(EntityData<?> e) {
public boolean isOfItemType(ItemType itemType) {
int ordinal = -1;

ItemStack stack = itemType.getRandom();
Material type = stack.getType();
Material type = itemType.getMaterial();
if (type == Material.OAK_CHEST_BOAT)
ordinal = 0;
else if (type == Material.SPRUCE_CHEST_BOAT)
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/ch/njol/skript/entity/BoatData.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,8 @@ public boolean isSupertypeOf(EntityData<?> e) {

public boolean isOfItemType(ItemType i){
int ordinal = -1;

ItemStack stack = i.getRandom();
Material type = stack.getType();

Material type = i.getMaterial();
if (type == Material.OAK_BOAT)
ordinal = 0;
else if (type == Material.SPRUCE_BOAT)
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/ch/njol/skript/entity/DroppedItemData.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,15 @@ public DroppedItemData(ItemType @Nullable [] types) {

@Override
protected boolean init(Literal<?>[] expressions, int matchedPattern, ParseResult parseResult) {
if (expressions.length > 0 && expressions[0] != null)
if (expressions.length > 0 && expressions[0] != null) {
types = (ItemType[]) expressions[0].getAll();
for (ItemType type : types) {
if (!type.getMaterial().isItem()) {
Skript.error("'" + type + "' cannot represent a dropped item");
return false;
}
}
}
return true;
}

Expand Down Expand Up @@ -97,6 +104,7 @@ public void set(final Item entity) {
final ItemType t = CollectionUtils.getRandom(types);
assert t != null;
ItemStack stack = t.getItem().getRandom();
assert stack != null; // should be true by init checks
entity.setItemStack(stack);
}

Expand Down Expand Up @@ -159,6 +167,7 @@ public boolean canSpawn(@Nullable World world) {
final ItemType itemType = CollectionUtils.getRandom(types);
assert itemType != null;
ItemStack stack = itemType.getItem().getRandom();
assert stack != null; // should be true by init checks

Item item;
if (consumer == null) {
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/ch/njol/skript/expressions/ExprMaxStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

/**
* @author joeuguce99
Expand All @@ -40,8 +42,11 @@ public class ExprMaxStack extends SimplePropertyExpression<ItemType, Long> {

@SuppressWarnings("null")
@Override
public Long convert(final ItemType i) {
return (long) i.getRandom().getMaxStackSize();
public Long convert(ItemType itemType) {
Object random = itemType.getRandomStackOrMaterial();
if (random instanceof Material)
return (long) ((Material) random).getMaxStackSize();
return (long) ((ItemStack) random).getMaxStackSize();
}

@Override
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/ch/njol/skript/expressions/ExprPlain.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import ch.njol.util.Kleenean;

import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.Nullable;

@Name("Plain Item")
Expand Down Expand Up @@ -61,7 +62,7 @@ protected ItemType[] get(Event e) {
ItemType itemType = item.getSingle(e);
if (itemType == null)
return new ItemType[0];
ItemData data = new ItemData(itemType.getRandom().getType());
ItemData data = new ItemData(itemType.getMaterial());
data.setPlain(true);
ItemType plain = new ItemType(data);
return new ItemType[]{plain};
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/ch/njol/skript/util/visual/VisualEffects.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,11 @@ private static void registerDataSupplier(String id, BiFunction<Object, Location,
}
if (raw == null)
return Bukkit.createBlockData(Material.AIR);
if (raw instanceof ItemType)
return Bukkit.createBlockData(((ItemType) raw).getRandom().getType());
if (raw instanceof ItemType) {
ItemType type = (ItemType) raw;
ItemStack random = type.getRandom();
return Bukkit.createBlockData(random != null ? random.getType() : type.getMaterial());
}
return raw;
};
registerDataSupplier("Particle.BLOCK", blockDataSupplier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void test() {
ContextlessEvent event = ContextlessEvent.get();
Variables.setVariable("item", itemType, event, true);

EasyMock.expect(itemType.getRandom()).andReturn(new ItemStack(Material.STONE)).atLeastOnce();
EasyMock.expect(itemType.getMaterial()).andReturn(Material.STONE).atLeastOnce();
EasyMock.replay(itemType);
TriggerItem.walk(getPlainRandomItemEffect, event);
EasyMock.verify(itemType);
Expand Down