Base rewrite with appliance System

This commit is contained in:
2023-10-24 20:49:44 +02:00
parent a8d37b82db
commit bb54482b5e
42 changed files with 1073 additions and 398 deletions

View File

@@ -0,0 +1,82 @@
package eu.mhsl.craftattack.spawn.appliance;
import eu.mhsl.craftattack.spawn.config.Configuration;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Any implementation of this class can be seen as a "sub-plugin" with its own event handlers and commands.
* Appliances can be enabled or disabled independent of other appliances
*/
public abstract class Appliance {
private String localConfigPath;
public Appliance() {
}
/**
* Use this constructor to specify a config sub-path for use with the localConfig() method.
* @param localConfigPath sub path, if not found, the whole config will be used
*/
public Appliance(String localConfigPath) {
this.localConfigPath = localConfigPath;
}
/**
* Provides a list of listeners for the appliance. All listeners will be automatically registered.
* @return List of listeners
*/
@NotNull
protected List<Listener> eventHandlers() {
return new ArrayList<>();
}
/**
* Provides a list of commands for the appliance. All commands will be automatically registered.
* @return List of commands
*/
@NotNull
protected List<ApplianceCommand<?>> commands() {
return new ArrayList<>();
}
/**
* Provides a localized config section. Path can be set in appliance constructor.
* @return Section of configuration for your appliance
*/
@NotNull
public ConfigurationSection localConfig() {
return Optional.ofNullable(Configuration.cfg.getConfigurationSection(localConfigPath)).orElse(Configuration.cfg);
}
public void onEnable() {}
public void onDisable() {}
public void initialize(@NotNull JavaPlugin plugin) {
eventHandlers().forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, plugin));
commands().forEach(command -> setCommandExecutor(plugin, command.commandName, command));
}
public void destruct(@NotNull JavaPlugin plugin) {
eventHandlers().forEach(HandlerList::unregisterAll);
commands().forEach(command -> setCommandExecutor(plugin, command.commandName, null));
}
private void setCommandExecutor(JavaPlugin plugin, String name, ApplianceCommand<?> executor) {
PluginCommand command = plugin.getCommand(name);
if(command != null) {
command.setExecutor(executor);
} else {
Bukkit.getLogger().warning("Command " + name + " is not specified in plugin.yml!");
}
}
}

View File

@@ -0,0 +1,84 @@
package eu.mhsl.craftattack.spawn.appliance;
import eu.mhsl.craftattack.spawn.Main;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
/**
* Utility class which enables command name definition over a constructor.
*/
public abstract class ApplianceCommand<T extends Appliance> implements ApplianceSupplier<T>, CommandExecutor {
public String commandName;
private final T appliance;
protected Component errorMessage = Component.text("Error whilst executing command").color(NamedTextColor.RED);
public ApplianceCommand(String command) {
this.appliance = Main.instance().getAppliance(Main.getApplianceType(getClass()));
this.commandName = command;
}
public ApplianceCommand(String command, Component errorMessage) {
this(command);
this.errorMessage = errorMessage;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
try {
execute(sender, command, label, args);
} catch (Exception e) {
sender.sendMessage(errorMessage);
return false;
}
return true;
}
protected abstract void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args);
@Override
public T getAppliance() {
return appliance;
}
/**
* Utility class for command which can only be used as a Player. You can access the executing player with the getPlayer() method.
*/
public static abstract class PlayerChecked<T extends Appliance> extends ApplianceCommand<T> {
private Player player;
private Component notPlayerMessage = Component.text("This command can only be executed as an Player!").color(NamedTextColor.RED);
protected PlayerChecked(String command) {
super(command);
}
public PlayerChecked(String command, Component errorMessage) {
super(command, errorMessage);
}
protected PlayerChecked(String command, @Nullable Component errorMessage, Component notPlayerMessage) {
super(command);
this.errorMessage = Optional.ofNullable(errorMessage).orElse(this.errorMessage);
this.notPlayerMessage = notPlayerMessage;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!(sender instanceof Player)) {
sender.sendMessage(notPlayerMessage);
return false;
}
this.player = (Player) sender;
return super.onCommand(sender, command, label, args);
}
public Player getPlayer() {
return this.player;
}
}
}

View File

@@ -0,0 +1,21 @@
package eu.mhsl.craftattack.spawn.appliance;
import eu.mhsl.craftattack.spawn.Main;
import org.bukkit.event.Listener;
/**
* Utility class which provides a specific, type save appliance.
* You can access the appliance with the protected 'appliance' field.
* @param <T> the type of your appliance
*/
public abstract class ApplianceListener<T extends Appliance> implements ApplianceSupplier<T>, Listener {
private final T appliance;
protected ApplianceListener() {
this.appliance = Main.instance().getAppliance(Main.getApplianceType(getClass()));
}
@Override
public T getAppliance() {
return appliance;
}
}

View File

@@ -0,0 +1,5 @@
package eu.mhsl.craftattack.spawn.appliance;
public interface ApplianceSupplier<T extends Appliance> {
T getAppliance();
}