Refactor actions

This commit is contained in:
filoghost 2020-08-07 14:36:43 +02:00
parent a845dbc0ae
commit 294dc05fa3
20 changed files with 173 additions and 99 deletions

View File

@ -16,22 +16,8 @@ package me.filoghost.chestcommands.action;
import org.bukkit.entity.Player;
public abstract class Action {
public interface Action {
private String errorMessage;
protected void disable(String errorMessage) {
this.errorMessage = errorMessage;
}
public final void execute(Player player) {
if (errorMessage != null) {
player.sendMessage(errorMessage);
} else {
execute0(player);
}
}
protected abstract void execute0(Player player);
void execute(Player player);
}

View File

@ -19,7 +19,7 @@ import me.filoghost.chestcommands.util.Colors;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class BroadcastAction extends Action {
public class BroadcastAction implements Action {
private final PlaceholderString message;
@ -28,7 +28,7 @@ public class BroadcastAction extends Action {
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
Bukkit.broadcastMessage(message.getValue(player));
}

View File

@ -18,7 +18,7 @@ import me.filoghost.chestcommands.hook.BungeeCordHook;
import me.filoghost.chestcommands.placeholder.PlaceholderString;
import org.bukkit.entity.Player;
public class ChangeServerAction extends Action {
public class ChangeServerAction implements Action {
private final PlaceholderString targetServer;
@ -27,7 +27,7 @@ public class ChangeServerAction extends Action {
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
BungeeCordHook.connect(player, targetServer.getValue(player));
}

View File

@ -18,7 +18,7 @@ import me.filoghost.chestcommands.placeholder.PlaceholderString;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class ConsoleCommandAction extends Action {
public class ConsoleCommandAction implements Action {
private final PlaceholderString command;
@ -27,7 +27,7 @@ public class ConsoleCommandAction extends Action {
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.getValue(player));
}

View File

@ -0,0 +1,32 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.filoghost.chestcommands.action;
import org.bukkit.entity.Player;
public class DisabledAction implements Action {
private final String errorMessage;
public DisabledAction(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override
public void execute(Player player) {
player.sendMessage(errorMessage);
}
}

View File

@ -15,41 +15,44 @@
package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.hook.BarAPIHook;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.NumberParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.placeholder.PlaceholderString;
import me.filoghost.chestcommands.util.Colors;
import me.filoghost.chestcommands.util.Strings;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class DragonBarAction extends Action {
public class DragonBarAction implements Action {
private PlaceholderString message;
private int seconds;
private final PlaceholderString message;
private final int seconds;
public DragonBarAction(String serialiazedAction) {
seconds = 1;
String message = serialiazedAction;
public DragonBarAction(String serialiazedAction) throws ParseException {
String message;
String[] split = Strings.trimmedSplit(serialiazedAction, "\\|", 2); // Max of 2 pieces
if (split.length > 1) {
try {
seconds = NumberParser.getStrictlyPositiveInteger(split[0]);
message = split[1];
} catch (ParseException ex) {
disable(ChatColor.RED + "Invalid dragon bar time \"" + split[0] + "\": " + ex.getMessage());
return;
} catch (ParseException e) {
throw new ParseException(ErrorMessages.Parsing.invalidBossBarTime(split[0]), e);
}
} else {
seconds = 1;
message = serialiazedAction;
}
this.message = PlaceholderString.of(Colors.addColors(message));
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
if (BarAPIHook.INSTANCE.isEnabled()) {
BarAPIHook.setMessage(player, message.getValue(player), seconds);
} else {
player.sendMessage(ErrorMessages.User.configurationError("BarAPI plugin not found"));
}
}

View File

@ -16,25 +16,20 @@ package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.parsing.ItemStackParser;
import me.filoghost.chestcommands.parsing.ParseException;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class GiveItemAction extends Action {
public class GiveItemAction implements Action {
private ItemStack itemToGive;
private final ItemStack itemToGive;
public GiveItemAction(String serializedAction) {
try {
ItemStackParser reader = new ItemStackParser(serializedAction, true);
itemToGive = reader.createStack();
} catch (ParseException e) {
disable(ChatColor.RED + "Invalid item to give: " + e.getMessage());
}
public GiveItemAction(String serializedAction) throws ParseException {
ItemStackParser reader = new ItemStackParser(serializedAction, true);
itemToGive = reader.createStack();
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
player.getInventory().addItem(itemToGive.clone());
}

View File

@ -15,29 +15,25 @@
package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.hook.VaultEconomyHook;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.NumberParser;
import me.filoghost.chestcommands.parsing.ParseException;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class GiveMoneyAction extends Action {
public class GiveMoneyAction implements Action {
private double moneyToGive;
private final double moneyToGive;
public GiveMoneyAction(String serializedAction) {
try {
moneyToGive = NumberParser.getStrictlyPositiveDouble(serializedAction);
} catch (ParseException e) {
disable(ChatColor.RED + "Invalid money amount \"" + serializedAction + "\": " + e.getMessage());
}
public GiveMoneyAction(String serializedAction) throws ParseException {
moneyToGive = NumberParser.getStrictlyPositiveDouble(serializedAction);
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
if (VaultEconomyHook.INSTANCE.isEnabled()) {
VaultEconomyHook.giveMoney(player, moneyToGive);
} else {
player.sendMessage(ChatColor.RED + "Vault with a compatible economy plugin not found. Please inform the staff.");
player.sendMessage(ErrorMessages.User.configurationError("Vault with a compatible economy plugin not found"));
}
}

View File

@ -17,7 +17,7 @@ package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.placeholder.PlaceholderString;
import org.bukkit.entity.Player;
public class OpCommandAction extends Action {
public class OpCommandAction implements Action {
private final PlaceholderString command;
@ -26,7 +26,7 @@ public class OpCommandAction extends Action {
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
if (player.isOp()) {
player.chat("/" + command.getValue(player));
} else {

View File

@ -15,13 +15,13 @@
package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.placeholder.PlaceholderString;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class OpenMenuAction extends Action {
public class OpenMenuAction implements Action {
private final PlaceholderString targetMenu;
@ -30,8 +30,9 @@ public class OpenMenuAction extends Action {
}
@Override
protected void execute0(final Player player) {
final InternalIconMenu menu = ChestCommands.getMenuManager().getMenuByFileName(targetMenu.getValue(player));
public void execute(final Player player) {
String menuName = targetMenu.getValue(player);
final InternalIconMenu menu = ChestCommands.getMenuManager().getMenuByFileName(menuName);
if (menu != null) {
/*
@ -43,7 +44,7 @@ public class OpenMenuAction extends Action {
});
} else {
player.sendMessage(ChatColor.RED + "Menu not found! Please inform the staff.");
player.sendMessage(ErrorMessages.User.configurationError("couldn't find the menu \"" + menuName + "\""));
}
}

View File

@ -14,54 +14,56 @@
*/
package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.NumberParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.util.Strings;
import me.filoghost.chestcommands.util.collection.Registry;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import java.util.Optional;
public class PlaySoundAction extends Action {
public class PlaySoundAction implements Action {
private static final Registry<Sound> SOUNDS_REGISTRY = Registry.fromEnumValues(Sound.class);
private Sound sound;
private float pitch;
private float volume;
public PlaySoundAction(String serializedAction) {
pitch = 1.0f;
volume = 1.0f;
private final Sound sound;
private final float pitch;
private final float volume;
public PlaySoundAction(String serializedAction) throws ParseException {
String[] split = Strings.trimmedSplit(serializedAction, ",", 3);
Optional<Sound> sound = SOUNDS_REGISTRY.find(split[0]);
if (!sound.isPresent()) {
disable(ChatColor.RED + "Invalid sound \"" + split[0] + "\".");
return;
throw new ParseException(ErrorMessages.Parsing.unknownSound(split[0]));
}
this.sound = sound.get();
if (split.length > 1) {
try {
pitch = Float.parseFloat(split[1]);
} catch (NumberFormatException e) {
// TODO
pitch = NumberParser.getFloat(split[1]);
} catch (ParseException e) {
throw new ParseException(ErrorMessages.Parsing.invalidSoundPitch(split[1]), e);
}
} else {
pitch = 1.0f;
}
if (split.length > 2) {
try {
volume = Float.parseFloat(split[2]);
} catch (NumberFormatException e) {
// TODO
volume = NumberParser.getFloat(split[2]);
} catch (ParseException e) {
throw new ParseException(ErrorMessages.Parsing.invalidSoundVolume(split[2]), e);
}
} else {
volume = 1.0f;
}
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
player.playSound(player.getLocation(), sound, volume, pitch);
}

View File

@ -17,7 +17,7 @@ package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.placeholder.PlaceholderString;
import org.bukkit.entity.Player;
public class PlayerCommandAction extends Action {
public class PlayerCommandAction implements Action {
private final PlaceholderString command;
@ -26,7 +26,7 @@ public class PlayerCommandAction extends Action {
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
player.chat('/' + command.getValue(player));
}

View File

@ -18,7 +18,7 @@ import me.filoghost.chestcommands.placeholder.PlaceholderString;
import me.filoghost.chestcommands.util.Colors;
import org.bukkit.entity.Player;
public class SendMessageAction extends Action {
public class SendMessageAction implements Action {
private final PlaceholderString message;
@ -27,7 +27,7 @@ public class SendMessageAction extends Action {
}
@Override
protected void execute0(Player player) {
public void execute(Player player) {
player.sendMessage(message.getValue(player));
}

View File

@ -16,6 +16,7 @@ package me.filoghost.chestcommands.config;
import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
import me.filoghost.chestcommands.config.framework.mapped.modifier.ChatColors;
import me.filoghost.chestcommands.logging.ErrorMessages;
@ChatColors
public class Lang extends MappedConfig {
@ -25,7 +26,7 @@ public class Lang extends MappedConfig {
public String no_required_item = "&cYou must have &e{amount}x {material} &c(durability: {durability}) for this.";
public String no_money = "&cYou need {money}$ for this.";
public String no_exp = "&cYou need {levels} XP levels for this.";
public String menu_not_found = "&cMenu not found! Please inform the staff.";
public String menu_not_found = "&cMenu not found! " + ErrorMessages.User.notifyStaffRequest;
public String open_menu = "&aOpening the menu \"{menu}\".";
public String open_menu_others = "&aOpening the menu \"{menu}\" to {player}.";
public String any = "any"; // Used in no_required_item when durability is not restrictive

View File

@ -17,7 +17,7 @@ package me.filoghost.chestcommands.icon.requirement;
import com.google.common.base.Preconditions;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.hook.VaultEconomyHook;
import org.bukkit.ChatColor;
import me.filoghost.chestcommands.logging.ErrorMessages;
import org.bukkit.entity.Player;
public class RequiredMoney implements Requirement {
@ -32,7 +32,9 @@ public class RequiredMoney implements Requirement {
@Override
public boolean hasCost(Player player) {
if (!VaultEconomyHook.INSTANCE.isEnabled()) {
player.sendMessage(ChatColor.RED + "This action has a price, but Vault with a compatible economy plugin was not found. For security, the action has been blocked. Please inform the staff.");
player.sendMessage(ErrorMessages.User.configurationError(
"the item has a price, but Vault with a compatible economy plugin was not found. "
+ "For security, the action has been blocked"));
return false;
}
@ -49,7 +51,7 @@ public class RequiredMoney implements Requirement {
boolean success = VaultEconomyHook.takeMoney(player, moneyAmount);
if (!success) {
player.sendMessage(ChatColor.RED + "Error: a money transaction couldn't be executed. Please inform the staff.");
player.sendMessage(ErrorMessages.User.configurationError("a money transaction couldn't be executed"));
}
return success;

View File

@ -20,6 +20,7 @@ import me.filoghost.chestcommands.config.framework.mapped.MappedField;
import me.filoghost.chestcommands.config.framework.mapped.converter.Converter;
import me.filoghost.chestcommands.parsing.icon.AttributeType;
import me.filoghost.chestcommands.parsing.icon.IconSettings;
import org.bukkit.ChatColor;
import java.nio.file.Path;
@ -119,9 +120,9 @@ public class ErrorMessages {
public static class Parsing {
public static final String invalidDouble = "value is not a valid decimal";
public static final String invalidDecimal = "value is not a valid decimal";
public static final String invalidShort = "value is not a valid short integer";
public static final String invalidInteger = "value not a valid integer";
public static final String invalidInteger = "value is not a valid integer";
public static final String strictlyPositive = "value must be greater than zero";
public static final String zeroOrPositive = "value must be zero or greater";
@ -167,6 +168,22 @@ public class ErrorMessages {
return "invalid " + colorName + " color \"" + valueString + "\", value must be between 0 and 255";
}
public static String invalidBossBarTime(String timeString) {
return "invalid dragon bar time \"" + timeString + "\"";
}
public static String invalidSoundPitch(String pitchString) {
return "invalid sound pitch \"" + pitchString + "\"";
}
public static String invalidSoundVolume(String volumeString) {
return "invalid sound volume \"" + volumeString + "\"";
}
public static String unknownSound(String soundString) {
return "unknown sound \"" + soundString + "\"";
}
}
public static class Menu {
@ -183,6 +200,12 @@ public class ErrorMessages {
return menuError(menuFile, "is missing the menu setting section");
}
public static String invalidSettingListElement(Path menuFile, String invalidSetting, String listElement) {
return menuError(menuFile,
"contains an invalid list element (\"" + listElement + "\") "
+ "in the menu setting \"" + invalidSetting + "\"");
}
private static String menuError(Path menuFile, String errorMessage) {
return "the menu \"" + formatPath(menuFile) + "\" " + errorMessage;
}
@ -225,6 +248,15 @@ public class ErrorMessages {
}
}
public static class User {
public static String notifyStaffRequest = "Please inform the staff.";
public static String configurationError(String errorMessage) {
return ChatColor.RED + "Error: " + errorMessage + ". " + ErrorMessages.User.notifyStaffRequest;
}
}
private static String formatPath(Path path) {
if (path.startsWith(ChestCommands.getDataFolderPath())) {

View File

@ -32,7 +32,7 @@ import java.util.regex.Pattern;
public class ActionParser {
public static Action parse(String serializedAction) {
public static Action parse(String serializedAction) throws ParseException {
for (ActionType actionType : ActionType.values()) {
Matcher matcher = actionType.prefixPattern.matcher(serializedAction);
if (matcher.find()) {
@ -72,7 +72,7 @@ public class ActionParser {
@FunctionalInterface
private interface ActionFactory {
Action create(String serializedAction);
Action create(String serializedAction) throws ParseException;
}

View File

@ -28,7 +28,15 @@ public class NumberParser {
try {
return Double.parseDouble(input);
} catch (NumberFormatException ex) {
throw new ParseException(ErrorMessages.Parsing.invalidDouble);
throw new ParseException(ErrorMessages.Parsing.invalidDecimal);
}
}
public static float getFloat(String input) throws ParseException {
try {
return Float.parseFloat(input);
} catch (NumberFormatException ex) {
throw new ParseException(ErrorMessages.Parsing.invalidDecimal);
}
}
@ -65,5 +73,4 @@ public class NumberParser {
throw new ParseException(errorMessage);
}
}
}

View File

@ -15,8 +15,11 @@
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.action.DisabledAction;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ActionParser;
import me.filoghost.chestcommands.parsing.ParseException;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +36,13 @@ public class ActionsAttribute implements ApplicableIconAttribute {
continue; // Skip
}
actions.add(ActionParser.parse(serializedAction));
try {
actions.add(ActionParser.parse(serializedAction));
} catch (ParseException e) {
actions.add(new DisabledAction(ErrorMessages.User.configurationError(
"an action linked to clicking this icon was not executed because it was not valid")));
errorHandler.onListElementError(serializedAction, e);
}
}
}

View File

@ -15,6 +15,7 @@
package me.filoghost.chestcommands.parsing.menu;
import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.action.DisabledAction;
import me.filoghost.chestcommands.config.framework.Config;
import me.filoghost.chestcommands.config.framework.ConfigSection;
import me.filoghost.chestcommands.config.framework.EmptyConfigSection;
@ -136,7 +137,14 @@ public class MenuParser {
for (String serializedAction : serializedOpenActions) {
if (serializedAction != null && !serializedAction.isEmpty()) {
openActions.add(ActionParser.parse(serializedAction));
try {
openActions.add(ActionParser.parse(serializedAction));
} catch (ParseException e) {
errorCollector.add(ErrorMessages.Menu.invalidSettingListElement(
config.getSourceFile(), MenuSettingsNode.OPEN_ACTIONS, serializedAction), e);
openActions.add(new DisabledAction(ErrorMessages.User.configurationError(
"an action linked to opening this menu was not executed because it was not valid")));
}
}
}