'use strict'; /*global events, module, require, __plugin, setInterval, clearInterval, setTimeout, addUnloadHandler*/ var utils = require('utils'); /************************************************************************ ## The at Module The at module provides a single function `at()` which can be used to schedule repeating (or non-repeating) tasks to be done at a particular time. ### at() function The utils.at() function will perform a given task at a given time in the (minecraft) day. #### Parameters * time24hr : The time in 24hr form - e.g. 9:30 in the morning is '09:30' while 9:30 pm is '21:30', midnight is '00:00' and midday is '12:00' * callback : A javascript function which will be invoked at the given time. * worlds : (optional) An array of worlds. Each world has its own clock. If no array of worlds is specified, all the server's worlds are used. * repeat : (optional) true or false, default is true (repeat the task every day) #### Example To warn players when night is approaching: ```javascript var utils = require('utils'), at = require('at'); function warning(){ utils.players(function( player ) { echo( player, 'The night is dark and full of terrors!' ); }); } at('19:00', warning); ``` To run a task only once at the next given time: ```javascript var utils = require('utils'), at = require('at'); function wakeup(){ utils.players(function( player ) { echo( player, "Wake Up Folks!" ); }); } at('06:00', wakeup, null, false); ``` ***/ function at(time24hr, callback, pWorlds, repeat) { var timeParts = time24hr.split( ':' ); var timeMins = (timeParts[0] * 60) + (timeParts[1] * 1); if (!pWorlds || typeof pWorlds == 'undefined' ) { pWorlds = utils.worlds(); } if (repeat === undefined){ repeat = true; } utils.foreach( pWorlds, function ( world ) { atAddTask( timeMins, callback, world, repeat); }); }; var atTasks = {}; /* constructs a function which will be called every x ticks to track the schedule for a given world */ function atMonitorFactory(world){ var worldName = ''+ world.name; var lastRun = null; return function(){ var timeMins = utils.getTime24(world); if (timeMins === lastRun){ return; } lastRun = timeMins; var worldSchedule = atTasks[worldName]; if (!worldSchedule){ return; } var tasks = worldSchedule[timeMins]; if (!tasks){ return; } utils.foreach(tasks, function(task, i){ if (!task){ return; } setTimeout(task.callback.bind(null, timeMins, world), 1); if (!task.repeat){ tasks[i] = null; } }); }; } function atAddTask( timeMins, callback, world, repeat){ var worldName = ''+world.name; if (!atTasks[worldName]){ atTasks[worldName] = {}; } if (!atTasks[worldName][timeMins]){ atTasks[worldName][timeMins] = []; } atTasks[worldName][timeMins].push({callback: callback, repeat: repeat}); } var atMonitors = []; function onLoadStartMonitor(event){ var monitor = setInterval( atMonitorFactory(event.world), 900); atMonitors.push( monitor ); } if (__plugin.canary){ events.loadWorld( onLoadStartMonitor ); } if (__plugin.bukkit){ events.worldLoad( onLoadStartMonitor ); } addUnloadHandler(function(){ utils.foreach(atMonitors, function(atInterval){ clearInterval(atInterval); }); });