package emu.grasscutter.task; import emu.grasscutter.Grasscutter; import emu.grasscutter.game.Account; import emu.grasscutter.game.GenshinPlayer; import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import org.quartz.spi.MutableTrigger; import org.reflections.Reflections; import java.util.*; @SuppressWarnings({"UnusedReturnValue", "unused"}) public final class TaskMap { private final Map tasks = new HashMap<>(); private final Map annotations = new HashMap<>(); private final SchedulerFactory schedulerFactory = new StdSchedulerFactory(); public TaskMap() { this(false); } public TaskMap(boolean scan) { if (scan) this.scan(); } public static TaskMap getInstance() { return Grasscutter.getGameServer().getTaskMap(); } public TaskMap registerTask(String taskName, TaskHandler task) { Task annotation = task.getClass().getAnnotation(Task.class); this.annotations.put(taskName, annotation); this.tasks.put(taskName, task); // register task try { Scheduler scheduler = schedulerFactory.getScheduler(); JobDetail job = JobBuilder .newJob(task.getClass()) .withIdentity(taskName) .build(); Trigger convTrigger = TriggerBuilder.newTrigger() .withIdentity(annotation.triggerName()) .withSchedule(CronScheduleBuilder.cronSchedule(annotation.taskCronExpression())) .build(); scheduler.scheduleJob(job, convTrigger); scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } return this; } public List getHandlersAsList() { return new LinkedList<>(this.tasks.values()); } public HashMap getHandlers() { return new LinkedHashMap<>(this.tasks); } public TaskHandler getHandler(String taskName) { return this.tasks.get(taskName); } private void scan() { Reflections reflector = Grasscutter.reflector; Set> classes = reflector.getTypesAnnotatedWith(Task.class); classes.forEach(annotated -> { try { Task taskData = annotated.getAnnotation(Task.class); Object object = annotated.newInstance(); if (object instanceof TaskHandler) this.registerTask(taskData.taskName(), (TaskHandler) object); else Grasscutter.getLogger().error("Class " + annotated.getName() + " is not a TaskHandler!"); } catch (Exception exception) { Grasscutter.getLogger().error("Failed to register task handler for " + annotated.getSimpleName(), exception); } }); } }