GraalCron is a
cron emulator for GS2. Cronjobs are used to automate tasks over specific time intervals. The crontab syntax has been provided inside the script, for easy reference.
It's highly advised that you do not edit anything outside of onCreated() and getcrontabs().
For example, a cronjob can be used to automate interest in bank scripts. In the sample provided in the script, the function
Bank.accrueInterest() will be called on midnight of each day of the week.
While automation is already possible in your scripts, the centralizing of each automation script should optimize the use of such automation. Instead of 10 timeouts running in 10 different scripts, GraalCron allows you to run a single automation process for all 10 of those scripts.
PHP Code:
function onCreated() {
// Display [cron] messages in RC
this.msgoutput = true;
// Resyching
scheduleevent(1, "CronTick", false);
cronmsg("Syncing with timevar2. Syncing can take up to a minute to complete...");
}
function cronmsg(msg) {
if(this.msgoutput) {
echo("[cron]: " @ msg);
}
}
function getcrontabs() {
/* Crontab format:
.---------------- minute (0 - 59)
| .-------------- hour (0 - 23)
| | .------------ day of month (1 - 31)
| | | .---------- month (0 - 11)
| | | | .-------- day of week (0 - 6)
| | | | |
* * * * * object function params
* - Any value
0 - Individual value
0,5,10... - Multiple values
Examples:
* * * * * - Runs every minute
5 * * * * - Runs on the fifth minute
of every hour
0,5,10... - Runs every 5 minutes
0 0 * * * - Runs at midnight each day
0 0 1 * * - Runs at midnight of the 1st
day of each month
Parameters are treated as STRINGS
E.g. * * * * * MyObj MyFunc timevar2,
"timevar2" will be the parameter
"* * * * * MyObj MyFunc " @ timevar2,
the built-in timevar2 variable will be the parameter
Parameters containing spaces should be \"escaped\"
E.g. * * * * * MyObj MyFunc My Param
Two parameters will be sent: "My" and "Param"
* * * * * MyObj MyFunc \"My Param\"
The parameter sent will be "My Param"
*/
return {
"0 0 * * * Bank accrueInterest",
};
}
function onCronTick(synced) {
cancelevents("CronTick");
if(!temp.synced) {
// Get the current second of timevar2
temp.ct = converttimetostring(timevar2).tokenize();
temp.cs = temp.ct[3].tokenize(":")[2];
// Check if it's the first second of the minute
if(temp.cs == "00") {
cronmsg("Syncing complete.");
// Execute each crontab
temp.crontabs = getcrontabs();
if(temp.crontabs.size() >= 1) {
for(temp.i: temp.crontabs) {
parse(temp.i);
}
}
// Schedule CronTick to run one minute later
scheduleevent(60, "CronTick", true);
}
else {
// Not synced. Schedule CronTick to check in 1 second
scheduleevent(1, "CronTick", false);
}
}
else {
temp.crontabs = getcrontabs();
if(temp.crontabs.size() >= 1) {
for(temp.i: temp.crontabs) {
parse(temp.i);
}
}
scheduleevent(60, "CronTick", true);
}
}
function parse(line) {
temp.toks = explode(" ", temp.line, 8);
temp.exectime = convert_exec_time({
temp.toks[0],temp.toks[1],temp.toks[2],
temp.toks[3],temp.toks[4]
});
// Weapon/Object name
temp.wname = temp.toks[5];
// Function to execute
temp.func = temp.toks[6];
// Parameters to send
temp.p = temp.toks[7];
if(check_time(temp.exectime)) {
makevar(temp.wname @ "." @ temp.func)
(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9]);
}
}
function check_time(input) {
// Current time in crontab format
temp.check = convert_time_to_crontab();
// Check if the current time is equal to crontab exec time
for(temp.i = 0; temp.i < temp.input.size(); temp.i++) {
// Multiple value check
if(temp.input[temp.i].size() > 0) {
if(!(temp.check[temp.i] in temp.input[temp.i])) {
return false;
}
}
// Single value check
else if(temp.input[temp.i] != temp.check[temp.i]) {
return false;
}
}
return true;
}
function convert_exec_time(exectime) {
for(temp.i = 0; temp.i < temp.exectime.size(); temp.i++) {
// Convert wildcards to current time value
if(temp.exectime[temp.i] == "*") {
temp.exectime[temp.i] = convert_time_to_crontab()[temp.i];
}
}
return temp.exectime;
}
function convert_time_to_crontab() {
temp.monidx = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
"Sep","Oct","Nov","Dec"};
temp.dowidx = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
temp.ts = converttimetostring(timevar2).tokenize();
temp.ts_dow = temp.dowidx.index(temp.ts[0]);
temp.ts_mon = temp.monidx.index(temp.ts[1]);
temp.ts_day = temp.ts[2];
temp.ts_hr = temp.ts[3].tokenize(":")[0];
temp.ts_min = temp.ts[3].tokenize(":")[1];
return strip_starting_zeroes({ts_min,ts_hr,ts_day,ts_mon,ts_dow});
}
function strip_starting_zeroes(input) {
for(temp.i = 0; temp.i < temp.input.size(); temp.i++) {
if(temp.input[temp.i].pos("0") == 0) {
temp.input[temp.i] = temp.input[temp.i].substring(1);
}
}
return temp.input;
}
// explode() can be separated and put in a class
// for use in multiple scripts
function explode(delimiter, string, limit) {
temp.tokens = temp.string.tokenize(temp.delimiter);
if(!temp.delimiter || temp.delimiter == "") {
return false;
}
if(!temp.limit || temp.limit == 0) {
return temp.string.tokenize(temp.delimiter);
}
if(temp.limit > temp.tokens.size()) {
temp.limit = temp.tokens.size();
}
if(temp.limit > 0) {
for(temp.i = 0; temp.i <= temp.limit - 1; temp.i ++) {
temp.output.add(temp.tokens[temp.i]);
}
for(temp.i = 0; temp.i < temp.tokens.size() - temp.limit; temp.i ++) {
temp.output[temp.limit - 1] @= temp.delimiter @ temp.tokens[temp.limit + temp.i];
}
}
else {
temp.limit *= -1;
for(temp.i = 0; temp.i <= temp.limit - 1; temp.i ++) {
temp.output.add(temp.tokens[temp.i]);
}
}
return temp.output;
}
Note: This script has been generally tested. However, understandably, not each time interval has been tested extensively. Should you notice that one of your crontabs is not executing correctly, post here or contact me (Dylan) through IRC (#graaldt on freenode), on Valikorlia, or through a forum PM.