This repository has been archived on 2021-07-14. You can view files and clone it, but cannot push or open issues or pull requests.
scriptcraft/src/main/js/modules/at.js

123 lines
3.3 KiB
JavaScript

'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);
});
});