ShowControl/src/main/java/tech/sbdevelopment/showcontrol/api/SCAPI.java
2023-09-21 17:34:48 +02:00

140 lines
6.1 KiB
Java

package tech.sbdevelopment.showcontrol.api;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import tech.sbdevelopment.showcontrol.ShowControlPlugin;
import tech.sbdevelopment.showcontrol.api.exceptions.InvalidTriggerException;
import tech.sbdevelopment.showcontrol.api.exceptions.TooFewArgumentsException;
import tech.sbdevelopment.showcontrol.api.points.ShowCuePoint;
import tech.sbdevelopment.showcontrol.api.triggers.Trigger;
import tech.sbdevelopment.showcontrol.api.triggers.TriggerIdentifier;
import tech.sbdevelopment.showcontrol.data.DataStorage;
import tech.sbdevelopment.showcontrol.utils.YamlFile;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SCAPI {
@Getter
private static final Map<String, Trigger> defaultTriggers = new HashMap<>(); //DO NOT USE, just for tab complete!
@Getter
private static final Map<String, Class<? extends Trigger>> triggers = new HashMap<>();
@Getter
private static final HashMap<String, List<ShowCuePoint>> showsMap = new HashMap<>();
private static final HashMap<String, ScheduledExecutorService> showTimers = new HashMap<>();
public static void index(Class<?> clazz, String... packages) {
ShowControlPlugin.getInstance().getLogger().info("Indexing triggers for starting point " + clazz.getSimpleName() + "...");
FilterBuilder filterBuilder = new FilterBuilder();
for (String p : packages) filterBuilder.includePackage(p);
ConfigurationBuilder config = new ConfigurationBuilder()
.setScanners(Scanners.SubTypes.filterResultsBy(new FilterBuilder().includePattern(Trigger.class.getName())), Scanners.TypesAnnotated)
.setUrls(ClasspathHelper.forClass(clazz))
.filterInputsBy(filterBuilder);
Reflections reflections = new Reflections(config);
Set<Class<?>> trig = reflections.getTypesAnnotatedWith(TriggerIdentifier.class);
for (Class<?> trigger : trig) {
ShowControlPlugin.getInstance().getLogger().info("Found trigger " + trigger.getSimpleName() + ".");
TriggerIdentifier identifier = trigger.getAnnotation(TriggerIdentifier.class);
triggers.put(identifier.value(), (Class<? extends Trigger>) trigger);
try {
defaultTriggers.put(identifier.value(), (Trigger) trigger.getDeclaredConstructor().newInstance());
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException |
IllegalAccessException ex) {
throw new RuntimeException("Could not find default constructor for trigger " + trigger.getSimpleName() + "! Tab complete will not work for this trigger.", ex);
}
}
}
public static List<String> getTabComplete(String triggerType, Player player, int index, String arg) {
if (!defaultTriggers.containsKey(triggerType)) return new ArrayList<>();
return defaultTriggers.get(triggerType).getArgumentTabComplete(player, index, arg);
}
public static <T extends Trigger> T getTrigger(String data) throws ReflectiveOperationException, InvalidTriggerException, TooFewArgumentsException, IllegalArgumentException {
String[] dataSplitter = data.split(" ");
String[] dataSplitterNew = Arrays.copyOfRange(dataSplitter, 1, dataSplitter.length);
String triggerType = dataSplitter[0];
if (!triggers.containsKey(triggerType))
throw new InvalidTriggerException("Provided trigger " + triggerType + " does not exists!");
Constructor<T> ctor = (Constructor<T>) triggers.get(triggerType).getConstructor(String[].class);
TriggerIdentifier identifier = triggers.get(triggerType).getAnnotation(TriggerIdentifier.class);
if (dataSplitter.length < identifier.minArgs() + 1)
throw new TooFewArgumentsException(identifier.argDesc());
return ctor.newInstance(new Object[]{dataSplitterNew});
}
public static void create(String name) {
showsMap.put(name, new ArrayList<>());
DataStorage.save();
}
public static void delete(String name) {
showsMap.remove(name);
File data = new File(ShowControlPlugin.getInstance().getDataFolder(), "data/" + name + ".yml");
data.delete();
}
public static boolean exists(String name) {
return showsMap.containsKey(name);
}
public static List<ShowCuePoint> getPoints(String name) {
if (!exists(name)) return new ArrayList<>();
return showsMap.get(name);
}
public static void addPoint(String name, Long time, Trigger data) {
if (!exists(name)) return;
getPoints(name).add(new ShowCuePoint(time, data));
DataStorage.save();
}
public static void removePoint(String name, ShowCuePoint point) {
if (!exists(name)) return;
point.getData().remove();
showsMap.get(name).remove(point);
YamlFile data = DataStorage.getFiles().get(name);
data.getFile().set(point.getCueID().toString(), null);
data.saveFile();
}
public static void startShow(String name) {
if (!exists(name)) return;
ScheduledExecutorService showTimer = Executors.newSingleThreadScheduledExecutor();
for (ShowCuePoint point : getPoints(name)) {
showTimer.schedule(() -> Bukkit.getScheduler().runTask(ShowControlPlugin.getInstance(), () -> point.getData().trigger()), point.getTime(), TimeUnit.MILLISECONDS);
}
showTimers.put(name, showTimer);
}
public static void cancelShow(String name) {
if (!exists(name)) return;
if (!showTimers.containsKey(name)) return;
ScheduledExecutorService showTimer = showTimers.get(name);
showTimer.shutdownNow();
}
}