Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cjcrafter/foliascheduler
Fully featured scheduler lib for Spigot/Paper/Folia support
https://github.com/cjcrafter/foliascheduler
api folia papermc spigot
Last synced: 3 months ago
JSON representation
Fully featured scheduler lib for Spigot/Paper/Folia support
- Host: GitHub
- URL: https://github.com/cjcrafter/foliascheduler
- Owner: CJCrafter
- Created: 2024-07-28T22:11:22.000Z (5 months ago)
- Default Branch: master
- Last Pushed: 2024-10-08T14:38:56.000Z (3 months ago)
- Last Synced: 2024-10-11T03:40:33.961Z (3 months ago)
- Topics: api, folia, papermc, spigot
- Language: Java
- Homepage:
- Size: 158 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
README
# FoliaScheduler
FoliaScheduler is a fully-featured task scheduler for plugins seeking Spigot/Paper/Folia support. With clean syntax,
you can now schedule tasks on entities, regions, asynchronously, and more!## Features
* Java 1.8+ (but you will need a JDK of 17+ to shade the Folia compatibility classes!)
* Folia 1.20+
* Spigot/Paper 1.12.2+ (and *likely* any older version)
* Task chaining w/ callback values (`CompletableFuture` support)
* Easy task cancellation through both `Consumer>` and return values.
* [`ServerVersions`](https://github.com/CJCrafter/FoliaScheduler/blob/master/src/main/java/com/cjcrafter/foliascheduler/util/ServerVersions.java) and [`MinecraftVersions`](https://github.com/CJCrafter/FoliaScheduler/blob/master/src/main/java/com/cjcrafter/foliascheduler/util/MinecraftVersions.java) utility classes for checking server type and version.
* [`ReflectionUtil`](https://github.com/CJCrafter/FoliaScheduler/blob/master/src/main/java/com/cjcrafter/foliascheduler/util/ReflectionUtil.java) with automatic remapping for Paper remapping compatibility.## How it works
We use Folia's scheduler (included in paper server jars) if it is available. If not, we fallback to
Spigot's scheduler, `BukkitRunnable`. This adds support for practically any server.## Maven
```xmlcom.cjcrafter
foliascheduler
0.6.0```
[Full Maven + Shade example]
```xml
com.cjcrafter
foliascheduler
0.6.0
org.apache.maven.plugins
maven-shade-plugin
3.6.0
package
shade
com.cjcrafter.foliascheduler
com.example.foliascheduler
```
## Gradle
```kotlin
repositories {
mavenCentral()
}dependencies {
implementation("com.cjcrafter:foliascheduler:0.6.0")
}
```[Full Gradle + Shade example]
```kotlin
plugins {
java // or kotlin("jvm") version "..."
//id("com.github.johnrengelman.shadow") version "8.1.1" // for below Java 21... always check for latest
id("io.github.gooler.shadow") version "8.1.7" // for Java 21+... always check for latest
id("net.minecrell.plugin-yml.bukkit") version "0.6.0" // always check for latest
}repositories {
mavenCentral()
}dependencies {
// TODO add your version of Spigot/Paper here
implementation("com.cjcrafter:foliascheduler:0.6.0")
}// See https://github.com/Minecrell/plugin-yml
bukkit {
main = "com.example.MyPlugin"
foliaSupported = true
}tasks.shadowJar {
archiveFileName.set("MyPlugin-${project.version}.jar")
relocate("com.cjcrafter.foliascheduler", "com.example.foliascheduler")
}
```## How do I convert my whole plugin to Folia?
Your plugin is *SO CLOSE* to working on Folia, except you need to change usage of
[`BukkitRunnable`](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/scheduler/BukkitRunnable.html) and
[`Bukkit#getScheduler`](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Bukkit.html#getScheduler()),
and add `folia-supported: true` to your plugin.yml.Not sure where to start? Take a look at these projects that used this library to add Folia:
* [WeaponMechanics](https://github.com/WeaponMechanics/MechanicsMain/pull/433/)
* [VivecraftSpigot](https://github.com/CJCrafter/VivecraftSpigot/pull/5)#### Thread safety tips
* Before modifying any block/entity, you can check if your thread is correct by using:
* `ServerImplementation#isOwnedByCurrentRegion(Entity)`
* `ServerImplementation#isOwnedByCurrentRegion(Block)`
* Typically, you should not use `ServerImplementation#async()` unless you are doing I/O operations or heavy calculations.
* When you use async, you should probably use a sync callback (See examples below)
* It is safe to send packets to players on any thread.## How do I check the server's version?
We provide 2 utility classes:
* `ServerVersions` - Check `isFolia()` and `isPaper()`
* `MinecraftVersions` - Get current `major.minor.patch` version```java
if (!MinecraftVersions.UPDATE_AQUATIC.isAtLeast()) {
getLogger().warning("Uh oh! You're not on 1.13+! This plugin may not work correctly!");
// disable plugin
}
```## Scheduler Examples
#### Modify an entity on the next tick
```java
Plugin plugin = null;
Entity entity = null;// You should re-use this instance
ServerImplementation scheduler = new FoliaCompatibility(plugin).getServerImplementation();
scheduler.entity(entity).run(() -> {
entity.setVelocity(new Vector(0, 1, 0));
});
```#### Execute an async task after 5 seconds
```java
Plugin plugin = null;// You should re-use this instance
ServerImplementation scheduler = new FoliaCompatibility(plugin).getServerImplementation();
scheduler.async().runDelayed(task -> {
plugin.getLogger().info("This is the scheduled task! I'm async! " + task);
}, 5 * 20L);
```#### Doing some I/O operations with a callback
```java
Plugin plugin = null;
File file = null;// You should re-use this instance
ServerImplementation scheduler = new FoliaCompatibility(plugin).getServerImplementation();
TaskImplementation scheduledTask = scheduler.async().runNow(task -> {
String contents = "Read the file";
return contents;
});// Use "thenCompose" to chain many tasks together
CompletableFuture> composed = scheduledTask.asFuture().thenCompose(task -> {
return scheduler.global().run(nextTask -> {
System.out.println("We're back on the global thread: " + scheduledTask.getCallback());
}).asFuture();
});
composed.thenAccept(task -> {
System.out.println("We finished everything now!");
});
```## Using Reflection
Paper and Spigot often "*disagree*" on what to name a class, field, or method. This is a
major problem if you plan on using reflection to access these classes. Like this example:
```java
Class.forName("net.minecraft.world.entity.monster.EntityCreeper"); // Works on Spigot servers
Class.forName("net.minecraft.world.entity.monster.Creeper"); // Works on Paper servers
```To solve this, we provide a utility class called [`ReflectionUtil`](https://github.com/CJCrafter/FoliaScheduler/blob/master/src/main/java/com/cjcrafter/foliascheduler/util/ReflectionUtil.java)
that will automatically remap classes, fields, and methods for you. The example
above can be solved by using the code below:```java
// Always provide a Spigot-mapped class, and we'll remap as needed
Class> entityCreeper = ReflectionUtil.getMinecraftClass("net.minecraft.world.entity.monster.EntityCreeper");
```