
# yl_scheduler

## Purpose

This mod allows you to tie the execution of tasks to real life utc time.

## Download

Get it from https://gitea.your-land.de/your-land/yl_scheduler

## Installation

1. Copy the "yl_scheduler" folder to your mod directory.
2. Enable the mod in your world.mt file.

## Configuration

```
yl_scheduler.debug = false
```
Set to true to enable debug mode

```
yl_scheduler.execution_interval = 1.0
```
Set this to a higher value for less lag but also less precision.

```
yl_scheduler.maximum_timeframe = 104w
```
Set this to how much time into the future you want to allow tasks created.

Understands m for minute, d for day, w for week. You cannot mix those.

```
yl_scheduler.save_path
```
Set this to where in the worldfolder you want the JSON files stored.

```
yl_scheduler.taskadd_privs
yl_scheduler.taskremove_privs
yl_scheduler.tasklist_privs
yl_scheduler.taskclean_privs
```
Set those to the list of privs you want to allow the execution of the corresponding commands

## Usage

This mod targets servers, but should work in singleplayer, too. It comes with no direct content but exposes functions you can use in your mod.

### Chatcommands

```
/scheduler_add time$function$param1, param2, param3, ...$mask1, mask2, mask3, ...$notes
```
Adds a new task that executes a function with params at the given time and optionally adds notes

time: At best a utc timestamp, in a future update some natural time. See [Supported Time formats](#supported-time-formats)

function: Name of a public function

parameter list: Please note parameters handed over this way are all strings, the mask needs to typecast them or you need to write a wrapper.

If a stringparameter has a true comma(,) in it, you need to escape it. Example: `/scheduler_add 123$minetest.chat_send_all$Attention\\, everyone!!`

mask list: List of types of there parameter list. Choose from number, boolean, string and nil. Default is string

notes: Optionally add notes to that task, so you don't have to guess what it is about

```
/scheduler_remove <UUID>
```
Removes the given UUID from the task list.

Example: `/scheduler_remove 8d3f379f-3c13-4c2e-bb72-16f8326b636d`

```
/scheduler_list <UUID|key=aaa>
```
Without parameters, lists ALL tasks - be careful, that may be a lot. Example: `/scheduler_list`

With parameter it lists all tasks where the UUID contains the parameter. Example: `/scheduler_list 379f`

With parameter `key=mystring` it returns all tasks where the given key contains "mystring". Example: `/scheduler_list notes=changes the spawnpoint`

```
/scheduler_clean [past|done]
```
Without parameter, cleans up both past and done tasks.

With parameter `done` it only cleans up tasks that were already executed.

With parameter `past` it only cleans up tasks where the scheduled execution time is in the past.

Cleaned up tasks are permanently deleted.

### Modmakers

Use the following public functions to get, set, list, remove and clean tasks

```
yl_scheduler.get_task(UUID)
```
Returns a table with the values of this UUID or nil, if it does not exist

```
yl_scheduler.set_task(at, func, params, owner, notes)
```
Adds this task to the list and returns `true, UUID` if accepted, `false, "errormessage"` if not.

```
yl_scheduler.list_all_tasks()
```
Returns `true, {"UUID1", "UUID2", ...}` if one or more tasks were found, `false, {}` if none were found.

```
yl_scheduler.find_ids(part of UUID)
```
Returns `true, {"UUID1", "UUID2", ...}` if one or more tasks were found, `false, {}` if none were found.

```
yl_scheduler.find_task(part of UUID)
```
Returns `true, {{task1}, {task1}, ...}` if one or more tasks were found, `false, {}` if none were found.

```
yl_scheduler.remove_task(UUID)
```
Returns `true, {task}` if one task was successfully removed, `false, "errormessage"` otherwise.

```
yl_scheduler.clean_past_tasks()
```
Removes all tasks of which the intended execution date is in the past.

Returns `true, amount_deleted, amount_remaining` if one or more tasks were successfully cleaned up, `false, "errormessage"` otherwise.

```
yl_scheduler.clean_executed_tasks()
```
Removes all tasks which were already executed. This 

Returns `true, amount_deleted, amount_remaining` if one or more tasks were successfully cleaned up, `false, "errormessage"` otherwise.

```
yl_scheduler.execute_task(UUID)
```
Executes the task with UUID and sets the done value to the current timestamp

Returns `true, {task}` AFTER the done value was set if the execution was started or `false, "errormessage"` if for some reason it was not.

A successful execution does NOT mean the called function achieved what it was supposed to - only that it was found, fed the parameters and executed without immediate crash.

### Supported Time formats {#supported-time-formats}

* utc timestamp. Example: 1712045385

Some future update:

* natural time. Examples: "00:00", "09:45:00", "18" without date, "2.4.2024 18:00" or "02.04.2024 18:00"
* professional time. Examples: "2400", "0945", "1800" without date, "20240402_1800" with date
* YYYY-MM-DDTHH:MM:SS Examples: "2024-04-02T13:45:30"

What you leave out will be assumed. If given without seconds or minutes, both values will be 00, if given without date, it will be assumed you mean "today"

The mod will try to determine what you mean and refuse to create a task if it doesn't understand

## Limitations

Some of those limitations may be addressed in a future update

* UTC is the only supported timezone
* No catchup scheduling! Means if multiple tasks would have fired while the server was down, they will ALL fire at the next available step!
* Your responsibility to load the mapblocks you want to work in and similar
* The parameter list of the `/scheduler_add` should support various time formats
* The parameter params of the `/scheduler_add` Does not yet support tables
* There is no setting to execute the function in a safe manner via pcall
* There is no setting to automatically cleanup
* functions that are executed in the same second/serverstep have no guaranteed execution order
* More performant solution: Moving target execution time

## Alternatives

No direct alternatives, but somewhat related:

* Snippets (Allows you to execute code at server start)
* minetest.after (Allows you to periodically execute functions)

## Supported versions

If you run yl_scheduler, but something is wrong, please [file a bug](https://gitea.your-land.de/your-land/yl_scheduler/issues/new). PRs also welcome.

There is no reason to believe it doesn't work anywhere, but you never know.

## Allied projects

If you know a project that uses this mod tell us and we will add it to the list.

## Uninstall

Remove it from your mod folder or deactivate it in your world.mt

Mods that depend on it will cease to work, if the mod is removed without proper replacement.

## License

See [LICENSE.md](./LICENSE.md)

* Code MIT AliasAlreadyTaken
* Screenshot CC0 Styxcolor

## Thank you

* Styxcolor
