SimpleCronClone
There are two parts to SimpleCronClone: scheduled scripts based on a cron-like syntax, and scripts that are called when certain events occur.
SimpleCronClone
This part of the plugin mimics the behavior of cron (for Windows-Users: Planned Tasks) and allows you to schedule scripts and commands for execution. It uses the awesome cron4j scheduler written by Carlo Pelliccia and it's own very, very, very, very, very basic scripting language.
How does it work? Well, the file plugins/SimpleCronClone/tab.scc is used as crontab-file, but instead of whole commands, it only takes the names of scripts. The tab file is parsed and scheduled, and when according the the cron part, the script is ran.
The CronClone part is to help with automated tasks that every server needs help with. For example:
- sending a message to the console every set amount of time.
- running a series of scripts that are dependent on the server running (eg, backups, off-site backups and more)
- running a series of in-game commands every so often (clearing logs, resetting arenas and much more, depending on your other plugins)
- query OS programs for status or information and use that information inside of the SCC script
EventEngine
New in v1.0, the EventEngine is a extension to the normal SimpleCronClone that calls event scripts (ending in .sce
) when certain events occur.
The idea of this is that now by adding scripts to plugins/SimpleCronClone/tab.sce
you will be able to do certain stats gathering or any other kind of thing based on events that players themselves cause. An example is lets say you have an adventure world, you can set a script to be run saying "do say hey player $1 is now playing in $2 adventure map, go join!" when a world is no longer empty, and when the world is empty again have a script revert it to normal. This is just one of many things that could be done with the EventEngine. See the events page for what events can be scheduled and how.
** Script Format **
See here
** Tab Format **
See here
** Warning about security **
One word of warning: Whatever you'll execute, it will have the same rights as the user from which the server is run. So be careful. Also keep in mind the execution-directory of the script is the server-directory for executables, not the plugin-directory.
@Scorpion_vn
if its two (or more) different event engine scripts (.sce), then you have to copy/paste and have a copy of the same filter configs, EG:
Although at that point would it not be better to join the two .sce files into one?
I am away from my test machine so I can't be 100% sure this is how it works, but should be about right...
Although I have a feeling I might be miss-understanding exactly what you were asking, if thats the case please let me know!
Hi, respect for your hard work. I played around a bit and for me it seems like I cant make event fire two different files - one unconditional and one with filters. Can you give us working example how to call two different files on playerJoin Event.
The examples did not say "famous person Scorpion joined" for example.
Best regards
Just tested SCC with both spigot-1148 and craftbukkit-2924 (early 1.7.2 builds), here is the news from the trenches:
Seems that things work just fine, passing my test suite just the same as it was before. The event "playerFirstJoin" seems to be working reliably now, but not going to close its relevant issue until I can reproduce or explain why it was 10 seconds late once. (most likely my overloaded computer, but better to be safe...)
EDIT: I should mention this test was for my own group of servers, so not my normal regression testing that takes about 5-6 hours against a pile of other plugins that might muck with the task scheduler or changes to the execution environment.
TL;DR: plugin still works fine, but will report again in about a week with much more thorough testing (studying for finals so cant put more than 2 hours into this right now).
As always if there are any issues open a ticket on github or post a comment here and I will reply as soon as I can.
@Tritek
By default, and staying within the SCC/SCE engine: no, there is no included "sleep" command. however there are two other ways to do this if you so wish:
if you are on linux or have the relevant windows server command "execWait" a external program that can wait/sleep for you. EG:
for windows you need a different command in "execwait", see here for some ideas (different versions of windows use different commands...)
The other option (that I personally use for my server) is to have multiple .scc files in the tab.scc scheduled one after another:
for how to do it by seconds and such refer to http://en.wikipedia.org/wiki/Cron#Format (basically num-num%s range)
Because you want only a few seconds I would recommend using "execWait" because that is the simplest.
Hello. Is there a possible to do command:
command "say Restart za 10 sekund"
wait 10 seconds and
command "/restart"
@PYROBITCH123
ok, so a few things to start off with:
thus, modify your backup.scc to be (eg for $HOME==/home/admalledd on my system)
"exec /home/admalledd/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh"
and your command to manually execute would also be:
"simplecronclone exec backup"
now to the *why* of no environment variables: In general doing sub-processes properly in a cross platform way is... complicated to say the least, so the basic stance is "have a path relative script in your server directory, have your native shell now handle env vars". If you have any ideas on how to approach subprocesses better that fork in the background that are a bit better than the normal java API way then let me know and I will take a look into adding support that way. (this includes parsing the different platforms env markings eg %PATH% vs $PATH ect ect...)
editing the script format page to include the note about no environment variables. Sorry for missing documenting that.
Anything else that I can help you with? although note its a bit late at night here now, so I will have to answer any more questions in the morning... sorry again for taking so long to reply, CurseForge dislikes sending me alerts in a timely manner...
I am attempting to execute an external shellscript with SimpleCronClone. In each variation of how I try to run it, either from the console directly or by using a .scc script, it is unable to see the shellscript ("Log" below). In certain cases it fails because it cannot find "save_world.sh.scc" which leads me to believe that it is trying to execute it as if it were a .scc script. I don't know why that would be happening, but I'm sure it's user error on my part. Any help here would be hot. ;)
TRYING TO EXECUTE THE SHELLSCRIPT DIRECTLY
>simplecronclone exec /$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh
23:12:26 [INFO] [SimpleCronClone] Executing: plugins/SimpleCronClone/$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh.scc 23:12:26 [WARNING] [SimpleCronClone] Could not find script: "plugins/SimpleCronClone/$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh.scc" 23:12:26 [INFO] SimpleCronClone: Error while executing "plugins/SimpleCronClone$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh.scc".
>simplecronclone exec /save_world.sh
23:13:12 [INFO] [SimpleCronClone] Executing: plugins/SimpleCronClone/save_world.sh.scc 23:13:12 [WARNING] [SimpleCronClone] Could not find script: "plugins/SimpleCronClone/save_world.sh.scc" 23:13:12 [INFO] SimpleCronClone: Error while executing "plugins/SimpleCronClonesave_world.sh.scc".
USING A .SCC SCRIPT TO EXECUTE THE SHELLSCRIPT
>simplecronclone exec backup.scc
23:17:12 [INFO] [SimpleCronClone] Executing: plugins/SimpleCronClone/backup.scc 23:17:12 [WARNING] [SimpleCronClone] Failed to execute script "plugins/SimpleCronClone/backup.scc" at "/$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh" Cannot run program "/$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh": error=2, No such file or directory 23:17:12 [INFO] SimpleCronClone: Error while executing "plugins/SimpleCronClone/backup.scc".
Contents of backup.scc:
exec /$HOME/Desktop/bukkit/plugins/SimpleCronClone/save_world.sh
@ronfkingswanson
http://dev.bukkit.org/bukkit-plugins/simplecronclone/pages/jsonapi-example/
bah sorry I forgot that I was going to make a example for JSONapi really. darn school work eating my free time. Its a very basic example and if you need anything else made clear just let me know.
But the basic is that: execute not a shell script, but a more in-depth language such as python using ExecWait or some such. pass arguments as appropriate (eg $0 if your program is used for multiple events and needs logic around that)
@admalledd
Can you give an example of a script that would hook into JSONAPI? I've used the API a lot in a PHP environment on our server's website, but have no clue how to make similar API calls from a shell script that simplecronclone might trigger...
Ok, the testbuild passes my internal testing with flying colors. Nice to see it all work so nicely. should show up in the files page/tree in a bit after DBO takes a peek at it. This is version "1.2"
My integration server is still off-line, turns out I need to basically get a new one. Power surge killed it or something. Going to be a heck of a lot slower on updates code wise until I get a new one, please consider donating if you use this plugin (Powerful enough computers to run my integration server are not cheap). </shameless plug>
@Shelmak
Ok, really rough test build of what you want. Note that the event argument structure might change, either adding things or removing things or even shuffling them around. SimpleCronClone_testbuild.jar
here is the basic structure to add to the tab.sce for these events. Like the other events you can also use the file event structure instead or along side the command based structure, refer to the docs or the sample tab.sce in the main download for more info.
Again, note that this is a rough testbuild, I added the event and it works, but no testing against other plugins or such. My integration server is off-line right now due to a lack of funds and I wont have free compute time till thursday really. Let me know if anything doesn't work right or such and ill try to fix it asap. If everything works I'll be releasing the official build update before the end of the weekend.
@Shelmak
Should not be a problem, give me a few days though. Sadly I am in the middle of some school work as well as updating a large amount of my server back-end code so I am out of free time atm. I should have a yay/nay within 72 hours. If yay I will link you directly to the test build and such.
Hi admalledd, I have a request. I like to give a player a object when he dies and respawns, but in tab.sce there is no option to do that. Could you add a new event like "deathrespawn" or similar to do that? Thanks for your attention.
@ronfkingswanson
Sadly that type of logic (fire a cron event if $blah) is out side the scope. however with basic scripting it should be simple to poll the server for the current player count. Either via Rquery or something like JSONapi.
the basic concept would be fire the backup script (you arent executing the commands directly from the .scc right? riiiight?) but inside have it connect and see what things are like.
Another thought is consider your backups in a bit more long term detail, let me use my systems and servers as an example:
here is where I kinda go into more depth what my current backup is as well as linking to my scripts for that end of things.
TL;DR: two ways to think about this. first is "move logic to the backup script" the other is "move to a more dynamic and fluid backup system that handles repeat files"
I've been using the cron functionality to force saves and backups, but wondering if I can make use of the event functionality to have those backups only run when the world is not empty. Right now my backups are getting filled with tons of redundant backups where nothing has changed (because no one has logged on and changed anything), which is pushing out useful backups.
AFAIK, the serverNotEmpty event will fire each time the last person logs off. If I put the backup command here instead of cron, it will also backup too often. So how can I marry the two to have the cron event fire according to its usual schedule, but only on the condition that the server is not empty?
@Shelmak
Tested and confirmed that the timing oddities are somehow related to minecraft 1.6.1 and the java 8 64 bit version I had just had, updating to the latest java 8 (or the latest java 7...) removed the issue and the delay between event firing and script parsing is within 2 ticks now as it was before.
So, if SCE is not as accurate as you want in the HourChange event: update your java JVM. if you still have issues, ping me here in the comments.
I know your situation, I like all works as expected :). Maybe some code has changed... I don't know how bukkit works but I suppose that with all new features some code has changed.
Good luck with this problem. I can't offer more help. :)
@Shelmak
This shows up both with spigot and craftbukkit, as well as with 8 different GC option flags for both (I like test code that automates things, yay). It is not related to a memory leak, its related to creating the threads and the fact that for some reason the delay from spawning a thread to activating it has changed since 1.5.2 (or that the tick scheduler changed internally?). Also, the server still stays at the 19.82 TPS that is considered "base line" (still the same since 1.5.2 even) even when running SCE and SCC full tilt at more than 10 events per tick and 5 cron's per minute. So its not "lag" per se, its that I spawn the thread at say tick 1200, but by the time I reach the script parser code and parse the first line its +- 10 ticks off (.5 seconds).
Anyways, yea it only effects "hourChange" events (and friends, see the docs) nothing else. So if your tab.sce is empty then nothing to worry about. Its just that it bugs me when something doesnt work as expected, I want to know *why* at least.
Umm, if garbage collection is forced it could be a big issue... when garbage collection is executed processor is more used and tick rate could decrease. Lamentably I can't offer you more help.
Are you sure that is your plugin causing this issue and not a memory leak? If you tried with spigot I have no more suggestions.
I don't know if this issue could affect my server because I have the tab.sce empty. I don't use that function... but I wish you good luck finding the problem. Thanks for your awesome work.
@Shelmak
The issue with the SCE timing is actually much more complicated than that, its not that the server itself is lagging(or running out of RAM), its that there seems to be some thread/context switching issues that cause the sub-event (iterating the script parsing loop and firing off a thread per script). The delay resides around this function call (SCE.runEventsFor()), the creation of the threads seems to randomly cause a "stop the world" garbage collection loop witch throws off the timing of the threads now that they are separate from the main event loop.
This is a problem related to multithreading, there is some form of hidden lock contention happening in the background inside the JVM native code when spawning threads that causes some garbage scanning every once in a while. This is why I need to talk to a friend that knows way more about debugging the native JVM than me, debugging when/why a garbage cycle happens is not easy. As well as adding multithreading and contentions in the mix? turns into a nightmare.
Although thanks for the try at giving me some help I do know enough about programming and the JVM to know the command line options to use, as well as I test with 8 other "configurations" each one showing this "drift" in time keeping. (the other configs are all different common GC or RAM options)