1
0
Fork 0
mirror of https://github.com/xHyroM/lighteco.git synced 2024-11-22 15:01:05 +01:00

feat: command manager, better arguments abstraction

This commit is contained in:
Jozef Steinhübl 2024-06-24 18:51:43 +02:00
parent 0108fde1d0
commit 7001c04915
No known key found for this signature in database
GPG key ID: E6BC90C91973B08F
24 changed files with 257 additions and 687 deletions

View file

@ -1,59 +0,0 @@
package dev.xhyrom.lighteco.bukkit.commands;
import dev.jorel.commandapi.CommandAPICommand;
import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
@RequiredArgsConstructor
public class BalanceCommand implements Command {
private final BukkitCommandManager manager;
private final String name;
private final Currency currency;
private final String permissionBase;
@Override
public CommandAPICommand[] multipleBuild() {
return new CommandAPICommand[]{
new CommandAPICommand(name)
.withPermission(permissionBase + "balance.others")
.withArguments(new OfflinePlayerArgument("target"))
.executes((sender, args) -> {
this.handleBalance(sender, args, currency);
}),
new CommandAPICommand(name)
.withPermission(permissionBase + "balance")
.executesPlayer((sender, args) -> {
this.handleBalance(sender, args, currency);
})
};
}
public void handleBalance(CommandSender originalSender, CommandArguments args, Currency currency) {
BukkitCommandSender sender = new BukkitCommandSender(originalSender, this.manager.audienceFactory);
OfflinePlayer target = (OfflinePlayer) args.get("target");
if (target == null) {
this.manager.onBalance(sender, currency);
return;
}
this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAccept(result -> {
String username = result.getUsername() == null ?
target.getName() != null
? target.getName()
: args.getRaw("target")
: result.getUsername();
result.setUsername(username);
this.manager.onBalance(sender, currency, result);
});
}
}

View file

@ -1,13 +0,0 @@
package dev.xhyrom.lighteco.bukkit.commands;
import dev.jorel.commandapi.CommandAPICommand;
public interface Command {
default CommandAPICommand build() {
return null;
}
default CommandAPICommand[] multipleBuild() {
return new CommandAPICommand[0];
}
}

View file

@ -1,54 +0,0 @@
package dev.xhyrom.lighteco.bukkit.commands;
import dev.jorel.commandapi.CommandAPICommand;
import dev.jorel.commandapi.arguments.DoubleArgument;
import dev.jorel.commandapi.arguments.IntegerArgument;
import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.math.BigDecimal;
@RequiredArgsConstructor
public class GiveCommand implements Command {
private final BukkitCommandManager manager;
private final Currency currency;
private final String permissionBase;
@Override
public CommandAPICommand build() {
return new CommandAPICommand("give")
.withPermission(permissionBase + "give")
.withArguments(
new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 1)
: new IntegerArgument("amount", 1)
)
.executes((sender, args) -> {
this.handleGive(sender, args, currency);
});
}
private void handleGive(CommandSender originalSender, CommandArguments args, Currency currency) {
BukkitCommandSender sender = new BukkitCommandSender(originalSender, this.manager.audienceFactory);
OfflinePlayer target = (OfflinePlayer) args.get("target");
BigDecimal amount = BigDecimal.valueOf(Double.parseDouble(args.getRaw("amount")));
if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAccept(result -> {
String name = target.getName() != null ? target.getName() : args.getRaw("target");
result.setUsername(name);
this.manager.onGive(sender, currency, result, amount);
});
}
}

View file

@ -1,57 +0,0 @@
package dev.xhyrom.lighteco.bukkit.commands;
import dev.jorel.commandapi.CommandAPICommand;
import dev.jorel.commandapi.arguments.DoubleArgument;
import dev.jorel.commandapi.arguments.IntegerArgument;
import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.math.BigDecimal;
@RequiredArgsConstructor
public class PayCommand implements Command {
private final BukkitCommandManager manager;
private final Currency currency;
private final String permissionBase;
@Override
public CommandAPICommand build() {
return new CommandAPICommand("pay")
.withPermission(permissionBase + "pay")
.withArguments(
new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 1)
: new IntegerArgument("amount", 1)
)
.executesPlayer((sender, args) -> {
this.handlePay(sender, args, currency);
});
}
private void handlePay(CommandSender originalSender, CommandArguments args, Currency currency) {
BukkitCommandSender sender = new BukkitCommandSender(originalSender, this.manager.audienceFactory);
OfflinePlayer target = (OfflinePlayer) args.get("target");
BigDecimal amount = BigDecimal.valueOf(Double.parseDouble(args.getRaw("amount")));
if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAccept(result -> {
String username = result.getUsername() == null ?
target.getName() != null
? target.getName()
: args.getRaw("target")
: result.getUsername();
result.setUsername(username);
this.manager.onPay(sender, currency, result, amount);
});
}
}

View file

@ -1,54 +0,0 @@
package dev.xhyrom.lighteco.bukkit.commands;
import dev.jorel.commandapi.CommandAPICommand;
import dev.jorel.commandapi.arguments.DoubleArgument;
import dev.jorel.commandapi.arguments.IntegerArgument;
import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.math.BigDecimal;
@RequiredArgsConstructor
public class SetCommand implements Command {
private final BukkitCommandManager manager;
private final Currency currency;
private final String permissionBase;
@Override
public CommandAPICommand build() {
return new CommandAPICommand("set")
.withPermission(permissionBase + "set")
.withArguments(
new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 0)
: new IntegerArgument("amount", 0)
)
.executes((sender, args) -> {
this.handleSet(sender, args, currency);
});
}
private void handleSet(CommandSender originalSender, CommandArguments args, Currency currency) {
BukkitCommandSender sender = new BukkitCommandSender(originalSender, this.manager.audienceFactory);
OfflinePlayer target = (OfflinePlayer) args.get("target");
BigDecimal amount = BigDecimal.valueOf(Double.parseDouble(args.getRaw("amount")));
if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAccept(result -> {
String name = target.getName() != null ? target.getName() : args.getRaw("target");
result.setUsername(name);
this.manager.onSet(sender, currency, result, amount);
});
}
}

View file

@ -1,54 +0,0 @@
package dev.xhyrom.lighteco.bukkit.commands;
import dev.jorel.commandapi.CommandAPICommand;
import dev.jorel.commandapi.arguments.DoubleArgument;
import dev.jorel.commandapi.arguments.IntegerArgument;
import dev.jorel.commandapi.arguments.OfflinePlayerArgument;
import dev.jorel.commandapi.executors.CommandArguments;
import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.manager.BukkitCommandManager;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import lombok.RequiredArgsConstructor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.math.BigDecimal;
@RequiredArgsConstructor
public class TakeCommand implements Command {
private final BukkitCommandManager manager;
private final Currency currency;
private final String permissionBase;
@Override
public CommandAPICommand build() {
return new CommandAPICommand("take")
.withPermission(permissionBase + "take")
.withArguments(
new OfflinePlayerArgument("target"),
currency.getProxy().fractionalDigits() > 0
? new DoubleArgument("amount", 1)
: new IntegerArgument("amount", 1)
)
.executes((sender, args) -> {
this.handleTake(sender, args, currency);
});
}
private void handleTake(CommandSender originalSender, CommandArguments args, Currency currency) {
BukkitCommandSender sender = new BukkitCommandSender(originalSender, this.manager.audienceFactory);
OfflinePlayer target = (OfflinePlayer) args.get("target");
BigDecimal amount = BigDecimal.valueOf(Double.parseDouble(args.getRaw("amount")));
if (!this.manager.canUse(sender, currency)) return;
this.manager.plugin.getUserManager().loadUser(target.getUniqueId())
.thenAccept(result -> {
String name = target.getName() != null ? target.getName() : args.getRaw("target");
result.setUsername(name);
this.manager.onTake(sender, currency, result, amount);
});
}
}

View file

@ -1,77 +1,52 @@
package dev.xhyrom.lighteco.bukkit.manager; package dev.xhyrom.lighteco.bukkit.manager;
import dev.jorel.commandapi.CommandAPICommand; import dev.xhyrom.lighteco.bukkit.chat.BukkitCommandSender;
import dev.xhyrom.lighteco.bukkit.commands.*; import dev.xhyrom.lighteco.common.command.CommandManager;
import dev.xhyrom.lighteco.common.manager.command.AbstractCommandManager;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.NotNull;
public class BukkitCommandManager extends AbstractCommandManager { import java.lang.reflect.Field;
public class BukkitCommandManager extends CommandManager {
public final BukkitAudiences audienceFactory; public final BukkitAudiences audienceFactory;
private CommandMap commandMap;
public BukkitCommandManager(LightEcoPlugin plugin) { public BukkitCommandManager(LightEcoPlugin plugin) {
super(plugin); super(plugin);
this.audienceFactory = BukkitAudiences.create((JavaPlugin) this.plugin.getBootstrap().getLoader()); this.audienceFactory = BukkitAudiences.create((JavaPlugin) this.plugin.getBootstrap().getLoader());
}
@Override try {
public void registerCurrencyCommand(@NonNull Currency currency) { Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
registerCommands(currency.getIdentifier(), currency);
for (String alias : currency.getIdentifierAliases()) { field.setAccessible(true);
registerCommands(alias, currency); this.commandMap = (CommandMap) field.get(Bukkit.getServer());
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
} }
} }
@Override @Override
public void registerCurrencyCommand(@NonNull Currency currency, boolean main) { public void register(Currency currency, boolean main) {
if (!main) { super.register(currency, main);
registerCurrencyCommand(currency);
return;
}
String permissionBase = "lighteco.currency." + currency.getIdentifier() + ".command."; commandMap.register(currency.getIdentifier(), new Command(currency.getIdentifier()) {
@Override
// Register main command public boolean execute(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
registerCurrencyCommand(currency); bukkitCommandManagerExecute(new BukkitCommandSender(commandSender, audienceFactory), s, strings);
return true;
// Expose pay as main command }
if (currency.isPayable()) });
new PayCommand(this, currency, permissionBase).build().register();
// Expose balance as main command
for (CommandAPICommand cmd : new BalanceCommand(
this,
"balance",
currency,
permissionBase
).multipleBuild()) {
cmd.register();
}
} }
private void registerCommands(@NonNull String name, @NonNull Currency currency) { private void bukkitCommandManagerExecute(dev.xhyrom.lighteco.common.model.chat.CommandSender sender, String name, String[] args) {
String permissionBase = "lighteco.currency." + currency.getIdentifier() + ".command."; super.execute(sender, name, args);
BalanceCommand balanceCommand = new BalanceCommand(this, "balance", currency, permissionBase);
CommandAPICommand cmd = new CommandAPICommand(name)
.withSubcommand(new SetCommand(this, currency, permissionBase).build())
.withSubcommand(new GiveCommand(this, currency, permissionBase).build())
.withSubcommand(new TakeCommand(this, currency, permissionBase).build())
.withSubcommands(balanceCommand.multipleBuild())
// We want balance to be the default command
.executesPlayer((sender, args) -> {
balanceCommand.handleBalance(sender, args, currency);
});
if (currency.isPayable())
cmd = cmd.withSubcommand(new PayCommand(this, currency, permissionBase).build());
cmd.register();
} }
} }

View file

@ -5,8 +5,8 @@ import dev.xhyrom.lighteco.api.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public class ApiCommandManager extends ApiAbstractManager<dev.xhyrom.lighteco.common.manager.command.CommandManager> implements CommandManager { public class ApiCommandManager extends ApiAbstractManager<dev.xhyrom.lighteco.common.command.CommandManager> implements CommandManager {
public ApiCommandManager(LightEcoPlugin plugin, dev.xhyrom.lighteco.common.manager.command.CommandManager handle) { public ApiCommandManager(LightEcoPlugin plugin, dev.xhyrom.lighteco.common.command.CommandManager handle) {
super(plugin, handle); super(plugin, handle);
} }
@ -15,7 +15,7 @@ public class ApiCommandManager extends ApiAbstractManager<dev.xhyrom.lighteco.co
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.plugin.getCurrencyManager() dev.xhyrom.lighteco.common.model.currency.Currency internal = this.plugin.getCurrencyManager()
.getIfLoaded(currency.getIdentifier()); .getIfLoaded(currency.getIdentifier());
this.handle.registerCurrencyCommand(internal); this.handle.register(internal);
} }
@Override @Override
@ -23,6 +23,6 @@ public class ApiCommandManager extends ApiAbstractManager<dev.xhyrom.lighteco.co
dev.xhyrom.lighteco.common.model.currency.Currency internal = this.plugin.getCurrencyManager() dev.xhyrom.lighteco.common.model.currency.Currency internal = this.plugin.getCurrencyManager()
.getIfLoaded(currency.getIdentifier()); .getIfLoaded(currency.getIdentifier());
this.handle.registerCurrencyCommand(internal, main); this.handle.register(internal, main);
} }
} }

View file

@ -0,0 +1,48 @@
package dev.xhyrom.lighteco.common.command;
import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.command.argument.Arguments;
import dev.xhyrom.lighteco.common.commands.BalanceCommand;
import dev.xhyrom.lighteco.common.commands.BalanceOtherCommand;
import dev.xhyrom.lighteco.common.commands.CurrencyParentCommand;
import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.Component;
import java.util.ArrayList;
import java.util.List;
public class CommandManager {
protected final LightEcoPlugin plugin;
private final List<Command> commands = new ArrayList<>();
public CommandManager(LightEcoPlugin plugin) {
this.plugin = plugin;
}
public void register(Currency currency) {
register(currency, false);
}
public void register(Currency currency, boolean main) {
commands.add(new CurrencyParentCommand(currency));
if (main) {
commands.add(BalanceCommand.create(currency));
commands.add(BalanceOtherCommand.create(currency));
}
}
public void execute(CommandSender sender, String name, String[] args) {
Command command = this.commands.stream()
.filter(cmd -> cmd.getName().equalsIgnoreCase(name) && cmd.getArgs().size() == args.length)
.findFirst().orElse(null);
if (command == null) {
sender.sendMessage(Component.text("Command not found.")); // TODO: change
return;
}
command.execute(this.plugin, sender, new Arguments(List.of(args)));
}
}

View file

@ -2,24 +2,25 @@ package dev.xhyrom.lighteco.common.command.abstraction;
import dev.xhyrom.lighteco.common.command.argument.Argument; import dev.xhyrom.lighteco.common.command.argument.Argument;
import dev.xhyrom.lighteco.common.command.argument.Arguments; import dev.xhyrom.lighteco.common.command.argument.Arguments;
import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin; import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List; import java.util.List;
import java.util.Map;
@Getter
public abstract class Command { public abstract class Command {
@Getter
@NonNull @NonNull
private final String name; private final String name;
@Getter
@Nullable @Nullable
private final String permission; private final String permission;
@Getter
@NonNull @NonNull
private final List<Argument<?>> args; private final List<Argument<?>> args;
@ -30,4 +31,15 @@ public abstract class Command {
} }
public abstract void execute(LightEcoPlugin plugin, CommandSender sender, Arguments args); public abstract void execute(LightEcoPlugin plugin, CommandSender sender, Arguments args);
protected CurrencyMessageConfig getCurrencyMessageConfig(LightEcoPlugin plugin, Currency currency) {
Map<String, CurrencyMessageConfig> config = plugin.getConfig().messages.currency;
CurrencyMessageConfig currencyMessageConfig = config.get(currency.getIdentifier());
if (currencyMessageConfig == null) {
return config.get("default");
}
return currencyMessageConfig;
}
} }

View file

@ -0,0 +1,37 @@
package dev.xhyrom.lighteco.common.command.abstraction;
import dev.xhyrom.lighteco.common.command.argument.Arguments;
import dev.xhyrom.lighteco.common.command.argument.type.StringArgument;
import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Arrays;
@Getter
public class ParentCommand extends Command {
private final Command[] children;
public ParentCommand(@NonNull String name, @Nullable String permission, @NonNull Command... children) {
super(name, permission, new StringArgument("child"));
this.children = children;
}
@Override
public void execute(LightEcoPlugin plugin, CommandSender sender, Arguments args) {
String childName = args.string("child");
Command child = Arrays.stream(getChildren())
.filter(cmd -> cmd.getName().equalsIgnoreCase(childName))
.findFirst()
.orElse(null);
if (child == null) {
return;
}
child.execute(plugin, sender, args.subList(1));
}
}

View file

@ -1,6 +1,7 @@
package dev.xhyrom.lighteco.common.command.argument; package dev.xhyrom.lighteco.common.command.argument;
public enum ArgumentType { public enum ArgumentType {
STRING,
OFFLINE_USER, OFFLINE_USER,
INTEGER, INTEGER,
DOUBLE; DOUBLE;

View file

@ -2,24 +2,40 @@ package dev.xhyrom.lighteco.common.command.argument;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
import java.util.List;
import java.util.Map; import java.util.Map;
public class Arguments { public class Arguments {
private final Map<String, ?> arguments; private final List<String> arguments;
private final Map<String, ?> mappedArguments;
public Arguments(Map<String, ?> arguments) { public Arguments(List<String> arguments) {
this.arguments = arguments; this.arguments = arguments;
this.mappedArguments = Map.of();
}
public String string(String name) {
return (String) this.mappedArguments.get(name);
} }
public User offlineUser(String name) { public User offlineUser(String name) {
return (User) this.arguments.get(name); return (User) this.mappedArguments.get(name);
} }
public int integer(String name) { public int integer(String name) {
return (int) this.arguments.get(name); return (int) this.mappedArguments.get(name);
} }
public double dbl(String name) { public double dbl(String name) {
return (double) this.arguments.get(name); return (double) this.mappedArguments.get(name);
}
public String raw(int index) {
return (String) this.arguments.get(index);
}
public Arguments subList(int fromIndex) {
return new Arguments(this.arguments.subList(fromIndex, this.arguments.size()));
} }
} }

View file

@ -1,12 +1,10 @@
package dev.xhyrom.lighteco.common.command.argument.type; package dev.xhyrom.lighteco.common.command.argument.type;
import dev.xhyrom.lighteco.common.command.argument.Argument;
import dev.xhyrom.lighteco.common.command.argument.ArgumentType; import dev.xhyrom.lighteco.common.command.argument.ArgumentType;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
public class DoubleArgument extends Argument<Double> { public class DoubleArgument extends NumberArgument<Double> {
protected DoubleArgument(String name) { protected DoubleArgument(String name, Double min, Double max) {
super(name); super(name, min, max);
} }
@Override @Override
@ -20,7 +18,7 @@ public class DoubleArgument extends Argument<Double> {
} }
@Override @Override
public Double parse(LightEcoPlugin plugin, String input) { public Double parse(String input) {
return Double.parseDouble(input); return Double.parseDouble(input);
} }
} }

View file

@ -1,12 +1,10 @@
package dev.xhyrom.lighteco.common.command.argument.type; package dev.xhyrom.lighteco.common.command.argument.type;
import dev.xhyrom.lighteco.common.command.argument.Argument;
import dev.xhyrom.lighteco.common.command.argument.ArgumentType; import dev.xhyrom.lighteco.common.command.argument.ArgumentType;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
public class IntegerArgument extends Argument<Integer> { public class IntegerArgument extends NumberArgument<Integer> {
protected IntegerArgument(String name) { protected IntegerArgument(String name, Integer min, Integer max) {
super(name); super(name, min, max);
} }
@Override @Override
@ -20,7 +18,7 @@ public class IntegerArgument extends Argument<Integer> {
} }
@Override @Override
public Integer parse(LightEcoPlugin plugin, String input) { public Integer parse(String input) {
return Integer.parseInt(input); return Integer.parseInt(input);
} }
} }

View file

@ -0,0 +1,32 @@
package dev.xhyrom.lighteco.common.command.argument.type;
import dev.xhyrom.lighteco.common.command.argument.Argument;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
abstract class NumberArgument<T> extends Argument<T> {
private final T min;
private final T max;
protected NumberArgument(String name, T min, T max) {
super(name);
this.min = min;
this.max = max;
}
public abstract T parse(String input);
@Override
public T parse(LightEcoPlugin plugin, String input) {
T value = parse(input);
if (value == null || (min != null && compare(value, min) < 0) || (max != null && compare(value, max) > 0)) {
return null;
}
return value;
}
private int compare(T a, T b) {
return ((Comparable<T>) a).compareTo(b);
}
}

View file

@ -0,0 +1,29 @@
package dev.xhyrom.lighteco.common.command.argument.type;
import dev.xhyrom.lighteco.common.command.argument.Argument;
import dev.xhyrom.lighteco.common.command.argument.ArgumentType;
import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import java.util.UUID;
public class StringArgument extends Argument<String> {
public StringArgument(String name) {
super(name);
}
@Override
public Class<String> getPrimitiveType() {
return String.class;
}
@Override
public ArgumentType getArgumentType() {
return ArgumentType.STRING;
}
@Override
public String parse(LightEcoPlugin plugin, String input) {
return input;
}
}

View file

@ -3,6 +3,7 @@ package dev.xhyrom.lighteco.common.commands;
import dev.xhyrom.lighteco.common.command.abstraction.Command; import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.command.argument.Argument; import dev.xhyrom.lighteco.common.command.argument.Argument;
import dev.xhyrom.lighteco.common.command.argument.Arguments; import dev.xhyrom.lighteco.common.command.argument.Arguments;
import dev.xhyrom.lighteco.common.command.argument.type.OfflineUserArgument;
import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig; import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
@ -19,12 +20,12 @@ import java.util.Map;
public class BalanceCommand extends Command { public class BalanceCommand extends Command {
private final Currency currency; private final Currency currency;
public BalanceCommand(@Nullable String permission, @NonNull Currency currency) { public static BalanceCommand create(@NonNull Currency currency) {
this(permission, currency, new Argument<?>[0]); return new BalanceCommand(currency.getIdentifier() + ".balance", currency);
} }
public BalanceCommand(@Nullable String permission, @NonNull Currency currency, @NonNull Argument<?>... args) { public BalanceCommand(@Nullable String permission, @NonNull Currency currency) {
super("balance", permission + ".balance", args); super("balance", permission, new Argument<?>[0]);
this.currency = currency; this.currency = currency;
} }
@ -36,21 +37,10 @@ public class BalanceCommand extends Command {
sender.sendMessage( sender.sendMessage(
MiniMessage.miniMessage().deserialize( MiniMessage.miniMessage().deserialize(
getConfig(plugin, currency).balance, getCurrencyMessageConfig(plugin, currency).balance,
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("balance", balance.toPlainString()) Placeholder.parsed("balance", balance.toPlainString())
) )
); );
} }
protected CurrencyMessageConfig getConfig(LightEcoPlugin plugin, Currency currency) {
Map<String, CurrencyMessageConfig> config = plugin.getConfig().messages.currency;
CurrencyMessageConfig currencyMessageConfig = config.get(currency.getIdentifier());
if (currencyMessageConfig == null) {
return config.get("default");
}
return currencyMessageConfig;
}
} }

View file

@ -1,7 +1,9 @@
package dev.xhyrom.lighteco.common.commands; package dev.xhyrom.lighteco.common.commands;
import dev.xhyrom.lighteco.common.command.abstraction.Command;
import dev.xhyrom.lighteco.common.command.argument.Arguments; import dev.xhyrom.lighteco.common.command.argument.Arguments;
import dev.xhyrom.lighteco.common.command.argument.type.OfflineUserArgument; import dev.xhyrom.lighteco.common.command.argument.type.OfflineUserArgument;
import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig;
import dev.xhyrom.lighteco.common.model.chat.CommandSender; import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency; import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User; import dev.xhyrom.lighteco.common.model.user.User;
@ -12,12 +14,17 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Map;
public class BalanceOtherCommand extends BalanceCommand { public class BalanceOtherCommand extends Command {
private final Currency currency; private final Currency currency;
public static BalanceOtherCommand create(@NonNull Currency currency) {
return new BalanceOtherCommand(currency.getIdentifier() + ".balance.others", currency);
}
public BalanceOtherCommand(@Nullable String permission, @NonNull Currency currency) { public BalanceOtherCommand(@Nullable String permission, @NonNull Currency currency) {
super(permission + ".balance.others", currency, new OfflineUserArgument("target")); super("balance", permission, new OfflineUserArgument("target"));
this.currency = currency; this.currency = currency;
} }
@ -29,7 +36,7 @@ public class BalanceOtherCommand extends BalanceCommand {
sender.sendMessage( sender.sendMessage(
MiniMessage.miniMessage().deserialize( MiniMessage.miniMessage().deserialize(
getConfig(plugin, currency).balanceOthers, getCurrencyMessageConfig(plugin, currency).balanceOthers,
Placeholder.parsed("currency", currency.getIdentifier()), Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("target", target.getUsername()), Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("balance", balance.toPlainString()) Placeholder.parsed("balance", balance.toPlainString())

View file

@ -0,0 +1,16 @@
package dev.xhyrom.lighteco.common.commands;
import dev.xhyrom.lighteco.common.command.abstraction.ParentCommand;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import org.checkerframework.checker.nullness.qual.NonNull;
public class CurrencyParentCommand extends ParentCommand {
public CurrencyParentCommand(@NonNull Currency currency) {
super(
currency.getIdentifier(),
currency.getIdentifier(),
BalanceCommand.create(currency),
BalanceOtherCommand.create(currency)
);
}
}

View file

@ -1,275 +0,0 @@
package dev.xhyrom.lighteco.common.manager.command;
import dev.xhyrom.lighteco.api.exception.CannotBeGreaterThan;
import dev.xhyrom.lighteco.common.config.message.CurrencyMessageConfig;
import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User;
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
public abstract class AbstractCommandManager implements CommandManager {
public final LightEcoPlugin plugin;
private final MiniMessage miniMessage = MiniMessage.miniMessage();
private final Map<String, CurrencyMessageConfig> config;
private final ArrayList<UUID> mustWait = new ArrayList<>();
protected AbstractCommandManager(LightEcoPlugin plugin) {
this.plugin = plugin;
this.config = this.plugin.getConfig().messages.currency;
}
@Override
public boolean canUse(CommandSender sender, Currency currency) {
// Console doesn't need to wait
if (sender.getUniqueId() == null) return true;
if (mustWait.contains(sender.getUniqueId())) {
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).wait
)
);
return false;
}
return true;
}
private void addToMustWait(UUID ...uuids) {
for (UUID uuid : uuids) {
if (uuid != null)
mustWait.add(uuid);
}
}
private void removeFromMustWait(UUID ...uuids) {
for (UUID uuid : uuids) {
if (uuid != null)
mustWait.remove(uuid);
}
}
private CurrencyMessageConfig getConfig(Currency currency) {
CurrencyMessageConfig currencyMessageConfig = this.config.get(currency.getIdentifier());
if (currencyMessageConfig == null) {
return this.config.get("default");
}
return currencyMessageConfig;
}
@Override
public void onBalance(CommandSender sender, Currency currency) {
User user = this.plugin.getUserManager().getIfLoaded(sender.getUniqueId());
BigDecimal balance = user.getBalance(currency);
sender.sendMessage(
miniMessage.deserialize(
getConfig(currency).balance,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("balance", balance.toPlainString())
)
);
}
@Override
public void onBalance(CommandSender sender, Currency currency, User target) {
BigDecimal balance = target.getBalance(currency);
sender.sendMessage(
miniMessage.deserialize(
getConfig(currency).balanceOthers,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("balance", balance.toPlainString())
)
);
}
@Override
public void onSet(CommandSender sender, Currency currency, User target, BigDecimal amount) {
addToMustWait(sender.getUniqueId(), target.getUniqueId());
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
try {
target.setBalance(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).set,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("amount", amount.toPlainString())
)
);
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
}
@Override
public void onGive(CommandSender sender, Currency currency, User target, BigDecimal amount) {
addToMustWait(sender.getUniqueId(), target.getUniqueId());
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
try {
target.deposit(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).give,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("amount", amount.toPlainString()),
Placeholder.parsed("balance", target.getBalance(currency).toPlainString())
)
);
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
}
@Override
public void onTake(CommandSender sender, Currency currency, User target, BigDecimal amount) {
addToMustWait(sender.getUniqueId(), target.getUniqueId());
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
try {
target.withdraw(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).take,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("amount", amount.toPlainString()),
Placeholder.parsed("balance", target.getBalance(currency).toPlainString())
)
);
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
}
@Override
public void onPay(CommandSender sender, Currency currency, User target, BigDecimal amount) {
if (sender.getUniqueId() != null && (sender.getUniqueId() == target.getUniqueId())) {
sender.sendMessage(
miniMessage.deserialize(this.getConfig(currency).cannotPaySelf)
);
return;
}
amount = amount.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
User user = this.plugin.getUserManager().getIfLoaded(sender.getUniqueId());
if (user.getBalance(currency).compareTo(amount) < 0) {
sender.sendMessage(
miniMessage.deserialize(this.getConfig(currency).notEnoughMoney)
);
return;
}
addToMustWait(sender.getUniqueId(), target.getUniqueId());
// calculate tax using Currency#calculateTax
BigDecimal tax = currency.getProxy().calculateTax(user.getProxy(), amount);
tax = tax.setScale(currency.getProxy().fractionalDigits(), RoundingMode.DOWN);
// subtract tax from amount
BigDecimal taxedAmount = amount.subtract(tax);
try {
target.deposit(currency, taxedAmount);
user.withdraw(currency, amount);
} catch (CannotBeGreaterThan e) {
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
sender.sendMessage(
miniMessage.deserialize(
this.getConfig(currency).cannotBeGreaterThan,
Placeholder.parsed("max", this.plugin.getConfig().maximumBalance.toPlainString())
)
);
return;
}
String template = tax.compareTo(BigDecimal.ZERO) > 0
? this.getConfig(currency).payWithTax
: this.getConfig(currency).pay;
String templateReceived = tax.compareTo(BigDecimal.ZERO) > 0
? this.getConfig(currency).payReceivedWithTax
: this.getConfig(currency).payReceived;
sender.sendMessage(
miniMessage.deserialize(
template,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("target", target.getUsername()),
Placeholder.parsed("amount", amount.toPlainString()),
Placeholder.parsed("taxed_amount", taxedAmount.toPlainString()),
Placeholder.parsed("sender_balance", user.getBalance(currency).toPlainString()),
Placeholder.parsed("receiver_balance", target.getBalance(currency).toPlainString())
)
);
target.sendMessage(
miniMessage.deserialize(
templateReceived,
Placeholder.parsed("currency", currency.getIdentifier()),
Placeholder.parsed("sender", user.getUsername()),
Placeholder.parsed("amount", amount.toPlainString()),
Placeholder.parsed("taxed_amount", taxedAmount.toPlainString()),
Placeholder.parsed("sender_balance", user.getBalance(currency).toPlainString()),
Placeholder.parsed("receiver_balance", target.getBalance(currency).toPlainString())
)
);
removeFromMustWait(target.getUniqueId(), sender.getUniqueId());
}
}

View file

@ -1,23 +0,0 @@
package dev.xhyrom.lighteco.common.manager.command;
import dev.xhyrom.lighteco.common.model.chat.CommandSender;
import dev.xhyrom.lighteco.common.model.currency.Currency;
import dev.xhyrom.lighteco.common.model.user.User;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.math.BigDecimal;
public interface CommandManager {
void registerCurrencyCommand(@NonNull Currency currency);
void registerCurrencyCommand(@NonNull Currency currency, boolean main);
boolean canUse(CommandSender sender, Currency currency);
void onBalance(CommandSender sender, Currency currency);
void onBalance(CommandSender sender, Currency currency, User target);
void onSet(CommandSender sender, Currency currency, User target, BigDecimal amount);
void onGive(CommandSender sender, Currency currency, User target, BigDecimal amount);
void onTake(CommandSender sender, Currency currency, User target, BigDecimal amount);
void onPay(CommandSender sender, Currency currency, User target, BigDecimal amount);
}

View file

@ -2,9 +2,9 @@ package dev.xhyrom.lighteco.common.plugin;
import dev.xhyrom.lighteco.api.manager.ContextManager; import dev.xhyrom.lighteco.api.manager.ContextManager;
import dev.xhyrom.lighteco.api.platform.Platform; import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.common.command.CommandManager;
import dev.xhyrom.lighteco.common.config.Config; import dev.xhyrom.lighteco.common.config.Config;
import dev.xhyrom.lighteco.common.dependencies.DependencyManager; import dev.xhyrom.lighteco.common.dependencies.DependencyManager;
import dev.xhyrom.lighteco.common.manager.command.CommandManager;
import dev.xhyrom.lighteco.common.manager.currency.CurrencyManager; import dev.xhyrom.lighteco.common.manager.currency.CurrencyManager;
import dev.xhyrom.lighteco.common.manager.user.UserManager; import dev.xhyrom.lighteco.common.manager.user.UserManager;
import dev.xhyrom.lighteco.common.messaging.InternalMessagingService; import dev.xhyrom.lighteco.common.messaging.InternalMessagingService;

View file

@ -3,7 +3,7 @@ package dev.xhyrom.lighteco.sponge;
import dev.xhyrom.lighteco.api.LightEco; import dev.xhyrom.lighteco.api.LightEco;
import dev.xhyrom.lighteco.api.manager.ContextManager; import dev.xhyrom.lighteco.api.manager.ContextManager;
import dev.xhyrom.lighteco.api.platform.Platform; import dev.xhyrom.lighteco.api.platform.Platform;
import dev.xhyrom.lighteco.common.manager.command.CommandManager; import dev.xhyrom.lighteco.common.command.CommandManager;
import dev.xhyrom.lighteco.common.manager.currency.StandardCurrencyManager; import dev.xhyrom.lighteco.common.manager.currency.StandardCurrencyManager;
import dev.xhyrom.lighteco.common.manager.user.StandardUserManager; import dev.xhyrom.lighteco.common.manager.user.StandardUserManager;
import dev.xhyrom.lighteco.common.messaging.MessagingFactory; import dev.xhyrom.lighteco.common.messaging.MessagingFactory;