/** * BetonQuest - advanced quests for Bukkit * Copyright (C) 2016 Jakub "Co0sh" Sapalski * * 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 <http://www.gnu.org/licenses/>. */ package pl.betoncraft.betonquest; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.scheduler.BukkitRunnable; import pl.betoncraft.betonquest.config.Config; import pl.betoncraft.betonquest.config.ConfigPackage; import pl.betoncraft.betonquest.utils.Debug; /** * StaticEvents contains logic for running events that aren't tied to any player * * @author Jakub Sapalski */ public class StaticEvents { /** * Contains pointers to timers, so they can be canceled if needed */ private static ArrayList<EventTimer> timers = new ArrayList<>(); /** * Creates new instance of a StaticEvents object, scheduling static events * to run at specified times */ public StaticEvents() { Debug.info("Initializing static events"); // old timers need to be deleted in case of reloading the plugin boolean deleted = false; for (EventTimer eventTimer : timers) { eventTimer.cancel(); deleted = true; } if (deleted) { Debug.info("Previous timers has been canceled"); } for (ConfigPackage pack : Config.getPackages().values()) { String packName = pack.getName(); Debug.info("Searching package " + packName); // get those hours and events ConfigurationSection config = pack.getMain().getConfig().getConfigurationSection("static"); if (config == null) { Debug.info("There are no static events defined, skipping"); continue; } // for each hour, create an event timer for (String key : config.getKeys(false)) { String value = config.getString(key); long timeStamp = getTimestamp(key); if (timeStamp < 0) { Debug.error("Incorrect time value in static event declaration (" + key + "), skipping this one"); continue; } Debug.info("Scheduling static event " + value + " at hour " + key + ". Current timestamp: " + new Date().getTime() + ", target timestamp: " + timeStamp); // add the timer to static list, so it can be canceled if needed try { timers.add(new EventTimer(timeStamp, new EventID(pack, value))); } catch (ObjectNotFoundException e) { Debug.error("Could not load static event '" + packName + "." + key + "': " + e.getMessage()); } } } Debug.info("Static events initialization done"); } /** * Cancels all scheduled timers */ public static void stop() { Debug.info("Killing all timers on disable"); for (EventTimer timer : timers) { timer.cancel(); } } /** * Generates a timestamp closest to the specified hour * * @param hour * time of the day * @return timestamp representing next occurence of specified hour */ private long getTimestamp(String hour) { // get the current day and add the given hour to it Date time = new Date(); String timeString = new SimpleDateFormat("dd.MM.yy").format(time) + " " + hour; // convert it into a timestamp long timeStamp = -1; try { timeStamp = new SimpleDateFormat("dd.MM.yy HH:mm").parse(timeString).getTime(); } catch (ParseException e) { Debug.error("Error in time setting in static event declaration: " + hour); } // if the timestamp is too old, add one day to it if (timeStamp < new Date().getTime()) { timeStamp += (24 * 60 * 60 * 1000); } return timeStamp; } /** * EventTimer represents a timer for an event * * @author Jakub Sapalski */ private class EventTimer extends TimerTask { protected final EventID event; /** * Creates and schedules a new timer for specified event, based on given * timeStamp * * @param timeStamp * @param event */ public EventTimer(long timeStamp, EventID eventID) { event = eventID; new Timer().schedule(this, timeStamp - new Date().getTime(), 24 * 60 * 60 * 1000); } @Override public void run() { new BukkitRunnable() { @Override public void run() { // run the event in sync BetonQuest.event(null, event); } }.runTask(BetonQuest.getInstance()); } } }