Skip to content

Commit

Permalink
feat: No more unhandled exception on action execution
Browse files Browse the repository at this point in the history
  • Loading branch information
PeyaPeyaPeyang committed Dec 6, 2024
1 parent e9e2852 commit 6ee60fb
Show file tree
Hide file tree
Showing 48 changed files with 219 additions and 192 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.kunlab.scenamatica.nms.exceptions;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;

/**
* NMS に対応していない操作が行われた際にスローされる例外です。
*/
@Getter
public class UnsupportedNMSOperationException extends UnsupportedOperationException
{
@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.kunlab.scenamatica.bookkeeper.enums.AdmonitionType;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.events.actor.ActorMessageReceiveEvent;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -83,7 +84,7 @@ public class MessageAction extends AbstractScenamaticaAction
public void execute(@NotNull ActionContext ctxt)
{
Player recipient = ctxt.input(IN_RECIPIENT).selectTarget(ctxt.getContext())
.orElseThrow(() -> new IllegalStateException("Cannot select target for this action, please specify target with valid specifier."));
.orElseThrow(() -> new IllegalActionInputException(IN_RECIPIENT, "Cannot select target for this action, please specify target with valid specifier."));
String message = ctxt.input(IN_MESSAGE);

this.makeOutputs(ctxt, recipient, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.kunlab.scenamatica.bookkeeper.enums.AdmonitionType;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.events.actions.server.ServerLogEvent;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -88,7 +89,7 @@ private static String normalizeLevelName(String original)
result = result.toUpperCase();

if (result.equals("OFF") || result.equals("ALL"))
throw new IllegalArgumentException("Illegal log level: " + original + " is not allowed here.");
throw new IllegalActionInputException(IN_LEVEL, "Illegal log level: " + original + " is not allowed here.");

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.commons.utils.Utils;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -83,9 +84,9 @@ protected boolean checkMatchedBlockEvent(@NotNull ActionContext ctxt, @NotNull E
protected Location getBlockLocationWithWorld(@NotNull BlockStructure block, @NotNull ActionContext ctxt)
{
if (block.getLocation() == null)
throw new IllegalStateException("Block location is not specified");
throw new IllegalActionInputException("Block location is not specified");
else if (block.getLocation().getX() == null || block.getLocation().getY() == null || block.getLocation().getZ() == null)
throw new IllegalStateException("Unable to specify block location: " + block.getLocation());
throw new IllegalActionInputException("Unable to specify block location: " + block.getLocation());

return Utils.assignWorldToLocation(block.getLocation().create(), ctxt.getEngine());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.kunlab.scenamatica.bookkeeper.annotations.InputDoc;
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalScenarioStateException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -85,7 +86,7 @@ private void validateBreakable(@NotNull Block block, @NotNull Player player)
World playerWorld = player.getWorld();

if (world != playerWorld) // 同値比較でよい
throw new IllegalArgumentException("The block and the player must be in the same world.");
throw new IllegalScenarioStateException("The block and the player must be in the same world.");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.kunlab.scenamatica.bookkeeper.enums.AdmonitionType;
import org.kunlab.scenamatica.enums.MinecraftVersion;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -126,7 +127,7 @@ public void execute(@NotNull ActionContext ctxt)
NMSHand hand = ctxt.orElseInput(IN_HAND, () -> NMSHand.MAIN_HAND);

Player player = ctxt.input(IN_ACTOR).selectTarget(ctxt.getContext())
.orElseThrow(() -> new IllegalStateException("Cannot find player"));
.orElseThrow(() -> new IllegalActionInputException(IN_ACTOR, "Cannot find player"));
Actor scenarioActor = ctxt.getActorOrThrow(player);
this.makeOutputs(ctxt, location.getBlock(), player);
if (MinecraftVersion.current().isInRange(MinecraftVersion.V1_14, MinecraftVersion.V1_15_2) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.kunlab.scenamatica.bookkeeper.annotations.OutputDocs;
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -78,6 +79,6 @@ public InputBoard getInputBoard(ScenarioType type)
public E selectTarget(@NotNull ActionContext ctxt)
{
return ctxt.input(this.IN_TARGET_ENTITY).selectTarget(ctxt.getContext())
.orElseThrow(() -> new IllegalStateException("Cannot select target for this action, please specify target with valid specifier."));
.orElseThrow(() -> new IllegalActionInputException(this.IN_TARGET_ENTITY, "Cannot select target for this action, please specify target with valid specifier."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.commons.utils.MapUtils;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -125,7 +126,7 @@ public void execute(@NotNull ActionContext ctxt)
Entity target = this.selectTarget(ctxt);

if (!(target instanceof Damageable))
throw new IllegalArgumentException("Target is not damageable");
throw new IllegalActionInputException("Target is not damageable");

this.makeOutputs(ctxt, target, null, ctxt.input(IN_AMOUNT), null);
((Damageable) target).damage(ctxt.input(IN_AMOUNT));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.kunlab.scenamatica.bookkeeper.annotations.OutputDoc;
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -62,10 +63,10 @@ public void execute(@NotNull ActionContext ctxt)
Entity target = this.selectTarget(ctxt);

if (!(target instanceof Damageable))
throw new IllegalArgumentException("Target is not damageable");
throw new IllegalActionInputException("Target is not damageable");

Entity damager = ctxt.input(IN_DAMAGER).selectTarget(ctxt.getContext())
.orElseThrow(() -> new IllegalStateException("Cannot select damager for this action, please specify damager with valid specifier."));
.orElseThrow(() -> new IllegalActionInputException(IN_DAMAGER, "Cannot select damager for this action, please specify damager with valid specifier."));

this.makeOutputs(ctxt, target, damager, null, ctxt.input(IN_AMOUNT), null);
((Damageable) target).damage(ctxt.input(IN_AMOUNT), damager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.kunlab.scenamatica.bookkeeper.annotations.InputDoc;
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.exceptions.scenario.IllegalScenarioStateException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -137,10 +139,10 @@ public void execute(@NotNull ActionContext ctxt)
{
Entity target = this.selectTarget(ctxt);
if (target.isDead())
throw new IllegalStateException("The target entity " + target + " is already dead.");
throw new IllegalScenarioStateException("The target entity " + target + " is already dead.");

if (!(target instanceof LivingEntity))
throw new IllegalStateException("The target entity " + target + " is not a living entity.");
throw new IllegalActionInputException(IN_TARGET_ENTITY, "The target entity " + target + " is not a living entity.");

LivingEntity livingEntity = (LivingEntity) target;
this.makeOutputs(ctxt, livingEntity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.kunlab.scenamatica.bookkeeper.annotations.InputDoc;
import org.kunlab.scenamatica.bookkeeper.annotations.OutputDoc;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -72,7 +73,7 @@ public void execute(@NotNull ActionContext ctxt)
{
Entity target = this.selectTarget(ctxt);
if (!(target instanceof InventoryHolder))
throw new IllegalArgumentException("Target is not inventory holder.");
throw new IllegalActionInputException(IN_TARGET_ENTITY, "Target is not inventory holder.");

EntityItemStructure itemStructure = (EntityItemStructure) ctxt.input(IN_ITEM).getTargetStructure();
ItemStack stack = itemStructure.getItemStack().create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import org.kunlab.scenamatica.bookkeeper.annotations.OutputDoc;
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.exceptions.scenario.IllegalScenarioStateException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -99,17 +101,17 @@ public void execute(@NotNull ActionContext ctxt)
{
Entity target = this.selectTarget(ctxt);
if (!(target instanceof LivingEntity))
throw new IllegalArgumentException("Target is not living entity.");
throw new IllegalActionInputException(IN_TARGET_ENTITY, "Target is not living entity.");

LivingEntity leTarget = (LivingEntity) target;
if (!leTarget.getCanPickupItems())
throw new IllegalStateException("The target cannot pickup items (LivingEntity#getCanPickupItems() is false).");
throw new IllegalActionInputException(IN_TARGET_ENTITY, "The target cannot pickup items (LivingEntity#getCanPickupItems() is false).");

EntitySpecifier<Item> itemSpecifier = ctxt.input(IN_ITEM);
Item item; // TODO: 統一?
if (itemSpecifier.isSelectable())
item = itemSpecifier.selectTarget(ctxt.getContext())
.orElseThrow(() -> new IllegalStateException("Item is not found."));
.orElseThrow(() -> new IllegalActionInputException(IN_ITEM, "Unable to select item."));
else
{
EntityItemStructure itemStructure = (EntityItemStructure) itemSpecifier;
Expand All @@ -126,17 +128,17 @@ public void execute(@NotNull ActionContext ctxt)
boolean canPlayerPickUp = item.getPickupDelay() != Short.MAX_VALUE;

if (isPlayer && !item.canMobPickup())
throw new IllegalStateException("The item cannot be picked up by mobs (Item#canMobPickup() is false).");
throw new IllegalScenarioStateException("The item cannot be picked up by mobs (Item#canMobPickup() is false).");
else if (!isPlayer && !canPlayerPickUp)
throw new IllegalStateException("The item cannot be picked up by players (Item#canPlayerPickup() is false).");
throw new IllegalScenarioStateException("The item cannot be picked up by players (Item#canPlayerPickup() is false).");

int amount = ctxt.orElseInput(IN_REMAINING, () -> item.getItemStack().getAmount() - 1);
// NMS にすら アイテムを拾ったことを検知する API がないので偽造する
EntityPickupItemEvent event = new EntityPickupItemEvent(leTarget, item, amount);
Bukkit.getPluginManager().callEvent(event);

if (event.isCancelled())
throw new IllegalStateException("Item pickup event is cancelled.");
throw new IllegalScenarioStateException("Item pickup event is cancelled.");

int quantity = item.getItemStack().getAmount() - amount;
NMSEntityLiving nmsEntity = NMSProvider.getProvider().wrap(leTarget);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.kunlab.scenamatica.bookkeeper.enums.ActionMethod;
import org.kunlab.scenamatica.bookkeeper.enums.AdmonitionType;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.input.InputToken;
Expand Down Expand Up @@ -179,7 +180,7 @@ public class EntityPlaceAction extends AbstractGeneralEntityAction
PLACEABLE_ENTITIES_MAP = Collections.unmodifiableMap(map);
}

public static boolean isPlaceable(Material material)
private static boolean isPlaceable(Material material)
{
for (Material m : PLACEABLE_ENTITIES_MAP.keySet())
if (m == material)
Expand All @@ -192,12 +193,12 @@ public static EntityType toEntityType(Material material)
return PLACEABLE_ENTITIES_MAP.get(material);
}

public static Material toMaterial(EntityType entityType)
private static Material toMaterial(EntityType entityType)
{
for (Map.Entry<Material, EntityType> entry : PLACEABLE_ENTITIES_MAP.entrySet())
if (entry.getValue() == entityType)
return entry.getKey();
throw new IllegalArgumentException("EntityType" + entityType + " is not placeable.");
throw new IllegalActionInputException(IN_MATERIAL, "EntityType" + entityType + " is not placeable.");
}

private static boolean isNotOnlyLocationAvailable(@Nullable BlockStructure structure)
Expand All @@ -216,7 +217,7 @@ public void execute(@NotNull ActionContext ctxt)
{
Location location = ctxt.input(IN_BLOCK).getLocation().create();
Actor actor = ctxt.getActorOrThrow(ctxt.input(IN_PLAYER).selectTarget(ctxt.getContext())
.orElseThrow(() -> new IllegalArgumentException("Player is not specified."))
.orElseThrow(() -> new IllegalActionInputException(IN_PLAYER, "Player is not specified."))
);
if (location.getWorld() == null)
{
Expand All @@ -230,7 +231,7 @@ public void execute(@NotNull ActionContext ctxt)
Material material = ctxt.input(IN_MATERIAL);

if (!isPlaceable(material))
throw new IllegalArgumentException("Material is not placable.");
throw new IllegalActionInputException(IN_MATERIAL, "Material is not placable.");

this.makeOutputs(ctxt, null, actor.getPlayer(), location.getBlock(), ctxt.input(IN_BLOCK_FACE), material);
actor.placeItem(location, new ItemStack(material), ctxt.input(IN_BLOCK_FACE));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.kunlab.scenamatica.commons.utils.EntityUtils;
import org.kunlab.scenamatica.commons.utils.Utils;
import org.kunlab.scenamatica.enums.ScenarioType;
import org.kunlab.scenamatica.exceptions.scenario.IllegalActionInputException;
import org.kunlab.scenamatica.exceptions.scenario.IllegalScenarioStateException;
import org.kunlab.scenamatica.interfaces.action.ActionContext;
import org.kunlab.scenamatica.interfaces.action.input.InputBoard;
import org.kunlab.scenamatica.interfaces.action.types.Executable;
Expand Down Expand Up @@ -65,12 +67,12 @@ private static Plugin getPlugin()
{
ClassLoader classLoader = MethodHandles.lookup().lookupClass().getClassLoader();
if (!(classLoader instanceof PluginClassLoader))
throw new IllegalArgumentException("ClassLoader is not PluginClassLoader");
throw new IllegalScenarioStateException("ClassLoader is not PluginClassLoader");

PluginClassLoader pluginClassLoader = (PluginClassLoader) classLoader;
Plugin plugin = pluginClassLoader.getPlugin();
if (plugin == null)
throw new IllegalStateException("Can't specify your plugin.");
throw new IllegalScenarioStateException("Can't specify your plugin.");

return plugin;
}
Expand All @@ -84,7 +86,7 @@ private static BlockProjectileSource getBlockProjectileSource(Block block)
case LEGACY_DISPENSER:
return ((Dispenser) block.getState()).getBlockProjectileSource();
default:
throw new IllegalArgumentException("Block must be ProjectileSource");
throw new IllegalScenarioStateException("Block must be ProjectileSource");
}
}

Expand Down Expand Up @@ -153,7 +155,7 @@ private ProjectileSource convertProjectileSource(ProjectileSourceStructure struc
.filter(e -> e instanceof ProjectileSource)
.map(e -> (ProjectileSource) e)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Selector must select ProjectileSource"));
.orElseThrow(() -> new IllegalActionInputException("Selector must select ProjectileSource"));
}
else if (structure instanceof EntityStructure)
{
Expand All @@ -164,12 +166,12 @@ else if (structure instanceof BlockStructure)
{
BlockStructure blockStructure = (BlockStructure) structure;
if (blockStructure.getLocation() == null)
throw new IllegalArgumentException("BlockStructure must have location");
throw new IllegalScenarioStateException("BlockStructure must have location");
Block block = Utils.assignWorldToBlockLocation(blockStructure, ctxt.getEngine()).getBlock();
return getBlockProjectileSource(block);
}
else
throw new IllegalArgumentException("Invalid ProjectileSourceStructure: " + structure);
throw new IllegalActionInputException("Invalid ProjectileSourceStructure: " + structure);
}

@Override
Expand Down
Loading

0 comments on commit 6ee60fb

Please sign in to comment.