├── .github └── workflows │ └── maven.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── pom.xml └── src └── main └── java └── com └── github └── Anon8281 └── universalScheduler ├── UniversalRunnable.java ├── UniversalScheduler.java ├── bukkitScheduler ├── BukkitScheduledTask.java └── BukkitScheduler.java ├── foliaScheduler ├── FoliaScheduledTask.java └── FoliaScheduler.java ├── paperScheduler └── PaperScheduler.java ├── scheduling ├── schedulers │ └── TaskScheduler.java └── tasks │ └── MyScheduledTask.java └── utils └── JavaUtil.java /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Maven Compile 2 | on: [ push, pull_request ] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Set up OpenJDK 8 9 | uses: actions/setup-java@v2 10 | with: 11 | distribution: 'adopt' 12 | java-version: '17' 13 | - name: Compile with Maven 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | run: mvn -B package --file pom.xml 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | 11 | # Compiled class file 12 | *.class 13 | 14 | # Log file 15 | *.log 16 | 17 | # BlueJ files 18 | *.ctxt 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | 32 | *~ 33 | 34 | # temporary files which can be created if a process still has a handle open of a deleted file 35 | .fuse_hidden* 36 | 37 | # KDE directory preferences 38 | .directory 39 | 40 | # Linux trash folder which might appear on any partition or disk 41 | .Trash-* 42 | 43 | # .nfs files are created when an open file is removed but is still being accessed 44 | .nfs* 45 | 46 | # General 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | 51 | # Icon must end with two \r 52 | Icon 53 | 54 | # Thumbnails 55 | ._* 56 | 57 | # Files that might appear in the root of a volume 58 | .DocumentRevisions-V100 59 | .fseventsd 60 | .Spotlight-V100 61 | .TemporaryItems 62 | .Trashes 63 | .VolumeIcon.icns 64 | .com.apple.timemachine.donotpresent 65 | 66 | # Directories potentially created on remote AFP share 67 | .AppleDB 68 | .AppleDesktop 69 | Network Trash Folder 70 | Temporary Items 71 | .apdisk 72 | 73 | # Windows thumbnail cache files 74 | Thumbs.db 75 | Thumbs.db:encryptable 76 | ehthumbs.db 77 | ehthumbs_vista.db 78 | 79 | # Dump file 80 | *.stackdump 81 | 82 | # Folder config file 83 | [Dd]esktop.ini 84 | 85 | # Recycle Bin used on file shares 86 | $RECYCLE.BIN/ 87 | 88 | # Windows Installer files 89 | *.cab 90 | *.msi 91 | *.msix 92 | *.msm 93 | *.msp 94 | 95 | # Windows shortcuts 96 | *.lnk 97 | 98 | target/ 99 | 100 | pom.xml.tag 101 | pom.xml.releaseBackup 102 | pom.xml.versionsBackup 103 | pom.xml.next 104 | 105 | release.properties 106 | dependency-reduced-pom.xml 107 | buildNumber.properties 108 | .mvn/timing.properties 109 | .mvn/wrapper/maven-wrapper.jar 110 | .flattened-pom.xml 111 | 112 | # Common working directory 113 | run/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Sevastjan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Universal Scheduler [![](https://jitpack.io/v/Anon8281/UniversalScheduler.svg)](https://jitpack.io/#Anon8281/UniversalScheduler) 2 | 3 | Is a lib for java minecraft plugins to simplify Folia support implementation 4 | > Just for your information: Folia doesn't support any of `Bukkit.getScheduler().*` and `Bukkit.getServer().getScheduler().*` 5 | > scheduling methods 6 | 7 | ### Java version: 8 or above 8 | 9 | ### Supported: 10 | 11 | - Folia 12 | - Paper 13 | - Spigot 14 | 15 | ## Plugins using UniversalScheduler 16 | 17 | | **Name** | **Link** | 18 | |:----------------------------:|:-------------------------------------------------------------:| 19 | | Brewery (Fork) | [GitHub](https://github.com/Anon8281/Brewery) | 20 | | InventoryRollbackPlus (Fork) | [GitHub](https://github.com/Anon8281/Inventory-Rollback-Plus) | 21 | | CraftBook (Fork) | [GitHub](https://github.com/Anon8281/CraftBook) | 22 | | PlaceholderAPI (Fork) | [GitHub](https://github.com/Anon8281/PlaceholderAPI) | 23 | | ImageOnMap (Fork) | [GitHub](https://github.com/Anon8281/ImageOnMap) | 24 | | BigDoors (Fork) | [GitHub](https://github.com/Anon8281/BigDoors) | 25 | | WorldGuardExtraFlags (Fork) | [GitHub](https://github.com/Anon8281/WorldGuardExtraFlags) | 26 | | HorseTpWithMe (Fork) | [GitHub](https://github.com/Anon8281/HorseTpWithMe) | 27 | | BetterTridents (Fork) | [GitHub](https://github.com/Anon8281/BetterTridents) | 28 | | HolographicDisplays (Fork) | [GitHub](https://github.com/Anon8281/HolographicDisplays) | 29 | | Lucko helper (Fork) | [GitHub](https://github.com/Anon8281/helper) | 30 | | HexNicks | [GitHub](https://github.com/MajekDev/HexNicks) | 31 | | WorldEdit (Unstable Fork) | [GitHub](https://github.com/Anon8281/WorldEdit) | 32 | | SuperVanish (Fork) | [GitHub](https://github.com/ewof/SuperVanish/tree/folia) | 33 | | TownyWaypoints (Fork) | [GitHub](https://github.com/ewof/TownyWaypoints) | 34 | 35 | ## How to use scheduler? 36 | 37 | 1. To your plugin Main add: 38 | 39 | ```java 40 | private static TaskScheduler scheduler; 41 | ``` 42 | 43 | ```java 44 | @Override 45 | public void onEnable() { 46 | //if your already have onEnable() just add next line to it 47 | scheduler = UniversalScheduler.getScheduler(this); 48 | } 49 | ``` 50 | 51 | ```java 52 | public static TaskScheduler getScheduler() { 53 | return scheduler; 54 | } 55 | ``` 56 | 57 | 2. Call it just like 58 | 59 | ```java 60 | Main.getScheduler().runTaskLater(() -> { //Main there is your plugin Main 61 | Bukkit.broadcastMessage("Wow, it was scheduled"); 62 | }); 63 | ``` 64 | 65 | 3. If you need to get the scheduled task for some reason 66 | 67 | ```java 68 | MyScheduledTask task = Main.getScheduler().runTaskLater(() -> { //Main there is your plugin Main 69 | Bukkit.broadcastMessage("Wow, it was scheduled"); 70 | }, 10L); 71 | ``` 72 | 73 | ### Maven information 74 | 75 | ```xml 76 | 77 | jitpack.io 78 | https://jitpack.io 79 | 80 | ``` 81 | 82 | ```xml 83 | 84 | com.github.Anon8281 85 | UniversalScheduler 86 | [VERSION] 87 | compile 88 | 89 | ``` 90 | 91 | Shading: 92 | 93 | ```xml 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-shade-plugin 98 | 3.5.0 99 | 100 | 101 | package 102 | 103 | shade 104 | 105 | 106 | 107 | 108 | com.github.Anon8281:UniversalScheduler 109 | 110 | 111 | 112 | 113 | com.github.Anon8281.universalScheduler 114 | 115 | [YOUR_PLUGIN_PACKAGE].universalScheduler 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | ``` 124 | 125 | ### Gradle information 126 | 127 | ```groovy 128 | repositories { 129 | //... 130 | maven { url 'https://jitpack.io' } 131 | } 132 | ``` 133 | 134 | ```groovy 135 | dependencies { 136 | //... 137 | implementation 'com.github.Anon8281:UniversalScheduler:[VERSION]' 138 | } 139 | ``` 140 | 141 | Shading: 142 | 143 | ```groovy 144 | shadowJar { 145 | //Don't forget to replace 146 | relocate 'com.github.Anon8281.universalScheduler', '[YOUR_PLUGIN_PACKAGE].universalScheduler' 147 | } 148 | ``` 149 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.github.Anon8281 8 | UniversalScheduler 9 | jar 10 | 1.0 11 | 12 | 13 | 8 14 | 8 15 | UTF-8 16 | 17 | 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-compiler-plugin 23 | 3.11.0 24 | 25 | 8 26 | 17 27 | 17 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | papermc 36 | https://repo.papermc.io/repository/maven-public/ 37 | 38 | 39 | 40 | 41 | 42 | dev.folia 43 | folia-api 44 | 1.20.1-R0.1-SNAPSHOT 45 | provided 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/UniversalRunnable.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler; 4 | import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; 5 | import org.bukkit.plugin.Plugin; 6 | 7 | /** Just modified BukkitRunnable */ 8 | public abstract class UniversalRunnable implements Runnable { 9 | MyScheduledTask task; 10 | 11 | public synchronized void cancel() throws IllegalStateException { 12 | checkScheduled(); 13 | task.cancel(); 14 | } 15 | 16 | /** 17 | * Returns true if this task has been cancelled. 18 | * 19 | * @return true if the task has been cancelled 20 | * @throws IllegalStateException if task was not scheduled yet 21 | */ 22 | public synchronized boolean isCancelled() throws IllegalStateException { 23 | checkScheduled(); 24 | return task.isCancelled(); 25 | } 26 | 27 | /** 28 | * Schedules this in the Bukkit scheduler to run on next tick. 29 | * 30 | * @param plugin the reference to the plugin scheduling task 31 | * @return {@link MyScheduledTask} 32 | * @throws IllegalArgumentException if plugin is null 33 | * @throws IllegalStateException if this was already scheduled 34 | * @see TaskScheduler#runTask(Runnable) 35 | */ 36 | 37 | public synchronized MyScheduledTask runTask(Plugin plugin) throws IllegalArgumentException, IllegalStateException { 38 | checkNotYetScheduled(); 39 | return setupTask(UniversalScheduler.getScheduler(plugin).runTask(this)); 40 | } 41 | 42 | /** 43 | * Asynchronous tasks should never access any API in Bukkit. Great care 44 | * should be taken to assure the thread-safety of asynchronous tasks. 45 | *

46 | * Schedules this in the Bukkit scheduler to run asynchronously. 47 | * 48 | * @param plugin the reference to the plugin scheduling task 49 | * @return {@link MyScheduledTask} 50 | * @throws IllegalArgumentException if plugin is null 51 | * @throws IllegalStateException if this was already scheduled 52 | * @see TaskScheduler#runTaskAsynchronously(Runnable) 53 | */ 54 | 55 | public synchronized MyScheduledTask runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException { 56 | checkNotYetScheduled(); 57 | return setupTask(UniversalScheduler.getScheduler(plugin).runTaskAsynchronously(this)); 58 | } 59 | 60 | /** 61 | * Schedules this to run after the specified number of server ticks. 62 | * 63 | * @param plugin the reference to the plugin scheduling task 64 | * @param delay the ticks to wait before running the task 65 | * @return {@link MyScheduledTask} 66 | * @throws IllegalArgumentException if plugin is null 67 | * @throws IllegalStateException if this was already scheduled 68 | * @see TaskScheduler#runTaskLater(Runnable, long) 69 | */ 70 | 71 | public synchronized MyScheduledTask runTaskLater(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException { 72 | checkNotYetScheduled(); 73 | return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLater(this, delay)); 74 | } 75 | 76 | /** 77 | * Asynchronous tasks should never access any API in Bukkit. Great care 78 | * should be taken to assure the thread-safety of asynchronous tasks. 79 | *

80 | * Schedules this to run asynchronously after the specified number of 81 | * server ticks. 82 | * 83 | * @param plugin the reference to the plugin scheduling task 84 | * @param delay the ticks to wait before running the task 85 | * @return {@link MyScheduledTask} 86 | * @throws IllegalArgumentException if plugin is null 87 | * @throws IllegalStateException if this was already scheduled 88 | * @see TaskScheduler#runTaskLaterAsynchronously(Runnable, long) 89 | */ 90 | 91 | public synchronized MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException { 92 | checkNotYetScheduled(); 93 | return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLaterAsynchronously(this, delay)); 94 | } 95 | 96 | /** 97 | * Schedules this to repeatedly run until cancelled, starting after the 98 | * specified number of server ticks. 99 | * 100 | * @param plugin the reference to the plugin scheduling task 101 | * @param delay the ticks to wait before running the task 102 | * @param period the ticks to wait between runs 103 | * @return {@link MyScheduledTask} 104 | * @throws IllegalArgumentException if plugin is null 105 | * @throws IllegalStateException if this was already scheduled 106 | * @see TaskScheduler#runTaskTimer(Runnable, long, long) 107 | */ 108 | 109 | public synchronized MyScheduledTask runTaskTimer(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException { 110 | checkNotYetScheduled(); 111 | return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimer(this, delay, period)); 112 | } 113 | 114 | /** 115 | * Asynchronous tasks should never access any API in Bukkit. Great care 116 | * should be taken to assure the thread-safety of asynchronous tasks. 117 | *

118 | * Schedules this to repeatedly run asynchronously until cancelled, 119 | * starting after the specified number of server ticks. 120 | * 121 | * @param plugin the reference to the plugin scheduling task 122 | * @param delay the ticks to wait before running the task for the first 123 | * time 124 | * @param period the ticks to wait between runs 125 | * @return {@link MyScheduledTask} 126 | * @throws IllegalArgumentException if plugin is null 127 | * @throws IllegalStateException if this was already scheduled 128 | * @see TaskScheduler#runTaskTimerAsynchronously(Runnable, long, long) 129 | */ 130 | 131 | public synchronized MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException { 132 | checkNotYetScheduled(); 133 | return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimerAsynchronously(this, delay, period)); 134 | } 135 | 136 | private void checkScheduled() { 137 | if (task == null) { 138 | throw new IllegalStateException("Not scheduled yet"); 139 | } 140 | } 141 | 142 | private void checkNotYetScheduled() { 143 | if (task != null) { 144 | throw new IllegalStateException("Already scheduled"); 145 | } 146 | } 147 | 148 | 149 | private MyScheduledTask setupTask(final MyScheduledTask task) { 150 | this.task = task; 151 | return task; 152 | } 153 | 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/UniversalScheduler.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.bukkitScheduler.BukkitScheduler; 4 | import com.github.Anon8281.universalScheduler.foliaScheduler.FoliaScheduler; 5 | import com.github.Anon8281.universalScheduler.paperScheduler.PaperScheduler; 6 | import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler; 7 | import com.github.Anon8281.universalScheduler.utils.JavaUtil; 8 | import org.bukkit.plugin.Plugin; 9 | 10 | public class UniversalScheduler { 11 | public static final boolean isFolia = JavaUtil.classExists("io.papermc.paper.threadedregions.RegionizedServer"); 12 | public static final boolean isExpandedSchedulingAvailable = JavaUtil.classExists("io.papermc.paper.threadedregions.scheduler.ScheduledTask"); 13 | 14 | public static TaskScheduler getScheduler(Plugin plugin) { 15 | return isFolia ? new FoliaScheduler(plugin) : (isExpandedSchedulingAvailable ? new PaperScheduler(plugin) : new BukkitScheduler(plugin)); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/bukkitScheduler/BukkitScheduledTask.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.bukkitScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.plugin.Plugin; 6 | import org.bukkit.scheduler.BukkitTask; 7 | 8 | public class BukkitScheduledTask implements MyScheduledTask { 9 | 10 | BukkitTask task; 11 | 12 | boolean isRepeating; 13 | 14 | public BukkitScheduledTask(final BukkitTask task) { 15 | this.task = task; 16 | this.isRepeating = false; 17 | } 18 | 19 | public BukkitScheduledTask(final BukkitTask task, boolean isRepeating) { 20 | this.task = task; 21 | this.isRepeating = isRepeating; 22 | } 23 | 24 | @Override 25 | public void cancel() { 26 | task.cancel(); 27 | } 28 | 29 | @Override 30 | public boolean isCancelled() { 31 | return task.isCancelled(); 32 | } 33 | 34 | @Override 35 | public Plugin getOwningPlugin() { 36 | return task.getOwner(); 37 | } 38 | 39 | @Override 40 | public boolean isCurrentlyRunning() { 41 | return Bukkit.getServer().getScheduler().isCurrentlyRunning(this.task.getTaskId()); //There's no other way. Fuck bukkit 42 | } 43 | 44 | @Override 45 | public boolean isRepeatingTask() { 46 | return isRepeating; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/bukkitScheduler/BukkitScheduler.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.bukkitScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler; 4 | import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.Location; 7 | import org.bukkit.entity.Entity; 8 | import org.bukkit.plugin.Plugin; 9 | 10 | public class BukkitScheduler implements TaskScheduler { 11 | final Plugin plugin; 12 | 13 | public BukkitScheduler(Plugin plugin) { 14 | this.plugin = plugin; 15 | } 16 | 17 | @Override 18 | public boolean isGlobalThread() { 19 | return Bukkit.getServer().isPrimaryThread(); 20 | } 21 | 22 | @Override 23 | public boolean isEntityThread(Entity entity) { 24 | return Bukkit.getServer().isPrimaryThread(); 25 | } 26 | 27 | @Override 28 | public boolean isRegionThread(Location location) { 29 | return Bukkit.getServer().isPrimaryThread(); 30 | } 31 | 32 | @Override 33 | public MyScheduledTask runTask(Runnable runnable) { 34 | return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable)); 35 | } 36 | 37 | @Override 38 | public MyScheduledTask runTaskLater(Runnable runnable, long delay) { 39 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay)); 40 | } 41 | 42 | @Override 43 | public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) { 44 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period)); 45 | } 46 | 47 | @Override 48 | public MyScheduledTask runTaskAsynchronously(Runnable runnable) { 49 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable)); 50 | } 51 | 52 | @Override 53 | public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) { 54 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay)); 55 | } 56 | 57 | @Override 58 | public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) { 59 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period)); 60 | } 61 | 62 | //Useless? Or... 63 | public MyScheduledTask runTask(Plugin plugin, Runnable runnable) { 64 | return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable)); 65 | } 66 | 67 | @Override 68 | public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) { 69 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay)); 70 | } 71 | 72 | @Override 73 | public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) { 74 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period)); 75 | } 76 | 77 | @Override 78 | public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) { 79 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable)); 80 | } 81 | 82 | @Override 83 | public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) { 84 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay)); 85 | } 86 | 87 | @Override 88 | public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) { 89 | return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period)); 90 | } 91 | 92 | @Override 93 | public void execute(Runnable runnable) { 94 | Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, runnable); 95 | } 96 | 97 | @Override 98 | public void cancelTasks() { 99 | Bukkit.getScheduler().cancelTasks(plugin); 100 | } 101 | 102 | @Override 103 | public void cancelTasks(Plugin plugin) { 104 | Bukkit.getScheduler().cancelTasks(plugin); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/foliaScheduler/FoliaScheduledTask.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.foliaScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; 4 | import io.papermc.paper.threadedregions.scheduler.ScheduledTask; 5 | import org.bukkit.plugin.Plugin; 6 | 7 | public class FoliaScheduledTask implements MyScheduledTask { 8 | private final ScheduledTask task; 9 | 10 | public FoliaScheduledTask(final ScheduledTask task) { 11 | this.task = task; 12 | } 13 | 14 | public void cancel() { 15 | this.task.cancel(); 16 | } 17 | 18 | public boolean isCancelled() { 19 | return this.task.isCancelled(); 20 | } 21 | 22 | public Plugin getOwningPlugin() { 23 | return this.task.getOwningPlugin(); 24 | } 25 | 26 | public boolean isCurrentlyRunning() { 27 | final ScheduledTask.ExecutionState state = this.task.getExecutionState(); 28 | return state == ScheduledTask.ExecutionState.RUNNING || state == ScheduledTask.ExecutionState.CANCELLED_RUNNING; 29 | } 30 | 31 | public boolean isRepeatingTask() { 32 | return this.task.isRepeatingTask(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/foliaScheduler/FoliaScheduler.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.foliaScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler; 4 | import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; 5 | import io.papermc.paper.threadedregions.scheduler.AsyncScheduler; 6 | import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler; 7 | import io.papermc.paper.threadedregions.scheduler.RegionScheduler; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.Location; 10 | import org.bukkit.entity.Entity; 11 | import org.bukkit.plugin.Plugin; 12 | 13 | import java.util.concurrent.TimeUnit; 14 | 15 | public class FoliaScheduler implements TaskScheduler { 16 | 17 | final Plugin plugin; 18 | 19 | public FoliaScheduler(Plugin plugin) { 20 | this.plugin = plugin; 21 | } 22 | 23 | private final RegionScheduler regionScheduler = Bukkit.getServer().getRegionScheduler(); 24 | private final GlobalRegionScheduler globalRegionScheduler = Bukkit.getServer().getGlobalRegionScheduler(); 25 | private final AsyncScheduler asyncScheduler = Bukkit.getServer().getAsyncScheduler(); 26 | 27 | @Override 28 | public boolean isGlobalThread() { 29 | return Bukkit.getServer().isGlobalTickThread(); 30 | } 31 | 32 | @Override 33 | public boolean isTickThread() { 34 | return Bukkit.getServer().isPrimaryThread(); // The Paper implementation checks whether this is a tick thread, this method exists to avoid confusion. 35 | } 36 | 37 | @Override 38 | public boolean isEntityThread(Entity entity) { 39 | return Bukkit.getServer().isOwnedByCurrentRegion(entity); 40 | } 41 | 42 | @Override 43 | public boolean isRegionThread(Location location) { 44 | return Bukkit.getServer().isOwnedByCurrentRegion(location); 45 | } 46 | 47 | @Override 48 | public MyScheduledTask runTask(Runnable runnable) { 49 | return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run())); 50 | } 51 | 52 | @Override 53 | public MyScheduledTask runTaskLater(Runnable runnable, long delay) { 54 | //Folia exception: Delay ticks may not be <= 0 55 | if (delay <= 0) { 56 | return runTask(runnable); 57 | } 58 | return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay)); 59 | } 60 | 61 | @Override 62 | public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) { 63 | //Folia exception: Delay ticks may not be <= 0 64 | delay = getOneIfNotPositive(delay); 65 | return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period)); 66 | } 67 | 68 | @Override 69 | public MyScheduledTask runTask(Plugin plugin, Runnable runnable) { 70 | return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run())); 71 | } 72 | 73 | @Override 74 | public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) { 75 | //Folia exception: Delay ticks may not be <= 0 76 | if (delay <= 0) { 77 | return runTask(plugin, runnable); 78 | } 79 | return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay)); 80 | } 81 | 82 | @Override 83 | public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) { 84 | //Folia exception: Delay ticks may not be <= 0 85 | delay = getOneIfNotPositive(delay); 86 | return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period)); 87 | } 88 | 89 | @Override 90 | public MyScheduledTask runTask(Location location, Runnable runnable) { 91 | return new FoliaScheduledTask(regionScheduler.run(plugin, location, task -> runnable.run())); 92 | } 93 | 94 | @Override 95 | public MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) { 96 | //Folia exception: Delay ticks may not be <= 0 97 | if (delay <= 0) { 98 | return runTask(runnable); 99 | } 100 | return new FoliaScheduledTask(regionScheduler.runDelayed(plugin, location, task -> runnable.run(), delay)); 101 | } 102 | 103 | @Override 104 | public MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) { 105 | //Folia exception: Delay ticks may not be <= 0 106 | delay = getOneIfNotPositive(delay); 107 | return new FoliaScheduledTask(regionScheduler.runAtFixedRate(plugin, location, task -> runnable.run(), delay, period)); 108 | } 109 | 110 | @Override 111 | public MyScheduledTask runTask(Entity entity, Runnable runnable) { 112 | return new FoliaScheduledTask(entity.getScheduler().run(plugin, task -> runnable.run(), null)); 113 | } 114 | 115 | @Override 116 | public MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) { 117 | //Folia exception: Delay ticks may not be <= 0 118 | if (delay <= 0) { 119 | return runTask(entity, runnable); 120 | } 121 | return new FoliaScheduledTask(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), null, delay)); 122 | } 123 | 124 | @Override 125 | public MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) { 126 | //Folia exception: Delay ticks may not be <= 0 127 | delay = getOneIfNotPositive(delay); 128 | return new FoliaScheduledTask(entity.getScheduler().runAtFixedRate(plugin, task -> runnable.run(), null, delay, period)); 129 | } 130 | 131 | @Override 132 | public MyScheduledTask runTaskAsynchronously(Runnable runnable) { 133 | return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run())); 134 | } 135 | 136 | @Override 137 | public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) { 138 | //Folia exception: Delay ticks may not be <= 0 139 | delay = getOneIfNotPositive(delay); 140 | return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS)); 141 | } 142 | 143 | @Override 144 | public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) { 145 | return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS)); 146 | } 147 | 148 | @Override 149 | public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) { 150 | return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run())); 151 | } 152 | 153 | @Override 154 | public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) { 155 | //Folia exception: Delay ticks may not be <= 0 156 | delay = getOneIfNotPositive(delay); 157 | return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS)); 158 | } 159 | 160 | @Override 161 | public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) { 162 | //Folia exception: Delay ticks may not be <= 0 163 | delay = getOneIfNotPositive(delay); 164 | return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS)); 165 | } 166 | 167 | @Override 168 | public void execute(Runnable runnable) { 169 | globalRegionScheduler.execute(plugin, runnable); 170 | } 171 | 172 | @Override 173 | public void execute(Location location, Runnable runnable) { 174 | regionScheduler.execute(plugin, location, runnable); 175 | } 176 | 177 | @Override 178 | public void execute(Entity entity, Runnable runnable) { 179 | entity.getScheduler().execute(plugin, runnable, null, 1L); 180 | } 181 | 182 | @Override 183 | public void cancelTasks() { 184 | globalRegionScheduler.cancelTasks(plugin); 185 | asyncScheduler.cancelTasks(plugin); 186 | } 187 | 188 | @Override 189 | public void cancelTasks(Plugin plugin) { 190 | globalRegionScheduler.cancelTasks(plugin); 191 | asyncScheduler.cancelTasks(plugin); 192 | } 193 | 194 | private long getOneIfNotPositive(long x) { 195 | return x <= 0 ? 1L : x; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/paperScheduler/PaperScheduler.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.paperScheduler; 2 | 3 | import com.github.Anon8281.universalScheduler.foliaScheduler.FoliaScheduler; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.plugin.Plugin; 6 | 7 | //Thanks to Towny 8 | public class PaperScheduler extends FoliaScheduler { 9 | public PaperScheduler(Plugin plugin) { 10 | super(plugin); 11 | } 12 | 13 | @Override 14 | public boolean isGlobalThread() { 15 | // isGlobalThread does not exist on paper, match the bukkit task scheduler's behaviour. 16 | return Bukkit.getServer().isPrimaryThread(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/scheduling/schedulers/TaskScheduler.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.scheduling.schedulers; 2 | 3 | import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.Location; 6 | import org.bukkit.entity.Entity; 7 | import org.bukkit.plugin.Plugin; 8 | 9 | import java.util.concurrent.Callable; 10 | import java.util.concurrent.CompletableFuture; 11 | import java.util.concurrent.Future; 12 | 13 | public interface TaskScheduler { 14 | 15 | /** 16 | * Folia: Returns whether the current thread is ticking the global region
17 | * Paper & Bukkit: Returns {@link org.bukkit.Server#isPrimaryThread} 18 | */ 19 | boolean isGlobalThread(); 20 | 21 | /** 22 | * @return {@link org.bukkit.Server#isPrimaryThread} 23 | */ 24 | default boolean isTickThread() { 25 | return Bukkit.getServer().isPrimaryThread(); 26 | } 27 | 28 | /** 29 | * Folia & Paper: Returns whether the current thread is ticking a region and that the region 30 | * being ticked owns the specified entity. Note that this function is the only appropriate method of 31 | * checking for ownership of an entity, as retrieving the entity's location is undefined unless the 32 | * entity is owned by the current region 33 | *

34 | * Bukkit: returns {@link org.bukkit.Server#isPrimaryThread} 35 | * 36 | * @param entity Specified entity 37 | */ 38 | boolean isEntityThread(Entity entity); 39 | 40 | /** 41 | * Folia & Paper: Returns whether the current thread is ticking a region and that the region 42 | * being ticked owns the chunk at the specified world and block position as included in the specified location 43 | *

44 | * Bukkit: returns {@link org.bukkit.Server#isPrimaryThread} 45 | * 46 | * @param location Specified location, must have a non-null world. 47 | */ 48 | boolean isRegionThread(Location location); 49 | 50 | /** 51 | * Schedules a task to be executed on the next tick
52 | * Folia & Paper: ...on the global region
53 | * Bukkit: ...on the main thread 54 | * 55 | * @param runnable The task to execute 56 | */ 57 | MyScheduledTask runTask(Runnable runnable); 58 | 59 | /** 60 | * Schedules a task to be executed after the specified delay in ticks
61 | * Folia & Paper: ...on the global region
62 | * Bukkit: ...on the main thread 63 | * 64 | * @param runnable The task to execute 65 | * @param delay The delay, in ticks 66 | */ 67 | MyScheduledTask runTaskLater(Runnable runnable, long delay); 68 | 69 | /** 70 | * Schedules a repeating task to be executed after the initial delay with the specified period
71 | * Folia & Paper: ...on the global region
72 | * Bukkit: ...on the main thread 73 | * 74 | * @param runnable The task to execute 75 | * @param delay The initial delay, in ticks. 76 | * @param period The period, in ticks. 77 | */ 78 | MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period); 79 | 80 | /** 81 | * Deprecated: use {@link #runTask(Runnable)} 82 | */ 83 | @Deprecated 84 | default MyScheduledTask runTask(Plugin plugin, Runnable runnable) { 85 | return runTask(runnable); 86 | } 87 | 88 | /** 89 | * Deprecated: use {@link #runTaskLater(Runnable, long)} 90 | */ 91 | @Deprecated 92 | default MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) { 93 | return runTaskLater(runnable, delay); 94 | } 95 | 96 | /** 97 | * Deprecated: use {@link #runTaskTimer(Runnable, long, long)} 98 | */ 99 | @Deprecated 100 | default MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) { 101 | return runTaskTimer(runnable, delay, period); 102 | } 103 | 104 | /** 105 | * Folia & Paper: Schedules a task to be executed on the region which owns the location on the next tick 106 | *

107 | * Bukkit: same as {@link #runTask(Runnable)} 108 | * 109 | * @param location The location which the region executing should own 110 | * @param runnable The task to execute 111 | */ 112 | default MyScheduledTask runTask(Location location, Runnable runnable) { 113 | return runTask(runnable); 114 | } 115 | 116 | /** 117 | * Folia & Paper: Schedules a task to be executed on the region which owns the location after the 118 | * specified delay in ticks 119 | *

120 | * Bukkit: same as {@link #runTaskLater(Runnable, long)} 121 | * 122 | * @param location The location which the region executing should own 123 | * @param runnable The task to execute 124 | * @param delay The delay, in ticks. 125 | */ 126 | default MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) { 127 | return runTaskLater(runnable, delay); 128 | } 129 | 130 | /** 131 | * Folia & Paper: Schedules a repeating task to be executed on the region which owns the location 132 | * after the initial delay with the specified period 133 | *

134 | * Bukkit: same as {@link #runTaskTimer(Runnable, long, long)} 135 | * 136 | * @param location The location which the region executing should own 137 | * @param runnable The task to execute 138 | * @param delay The initial delay, in ticks. 139 | * @param period The period, in ticks. 140 | */ 141 | default MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) { 142 | return runTaskTimer(runnable, delay, period); 143 | } 144 | 145 | /** 146 | * Deprecated: use {@link #runTaskLater(Runnable, long)} 147 | */ 148 | @Deprecated 149 | default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable, long delay) { 150 | return runTaskLater(runnable, delay); 151 | } 152 | 153 | /** 154 | * Deprecated: use {@link #execute(Runnable)} or {@link #runTask(Runnable)} 155 | */ 156 | @Deprecated 157 | default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable) { 158 | return runTask(runnable); 159 | } 160 | 161 | /** 162 | * Deprecated: use {@link #runTaskTimer(Runnable, long, long)} 163 | */ 164 | @Deprecated 165 | default MyScheduledTask scheduleSyncRepeatingTask(Runnable runnable, long delay, long period) { 166 | return runTaskTimer(runnable, delay, period); 167 | } 168 | 169 | /** 170 | * Folia & Paper: Schedules a task to be executed on the region which owns the location 171 | * of given entity on the next tick 172 | *

173 | * Bukkit: same as {@link #runTask(Runnable)} 174 | * 175 | * @param entity The entity whose location the region executing should own 176 | * @param runnable The task to execute 177 | */ 178 | default MyScheduledTask runTask(Entity entity, Runnable runnable) { 179 | return runTask(runnable); 180 | } 181 | 182 | /** 183 | * Folia & Paper: Schedules a task to be executed on the region which owns the location 184 | * of given entity after the specified delay in ticks 185 | *

186 | * Bukkit: same as {@link #runTaskLater(Runnable, long)} 187 | * 188 | * @param entity The entity whose location the region executing should own 189 | * @param runnable The task to execute 190 | * @param delay The delay, in ticks. 191 | */ 192 | default MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) { 193 | return runTaskLater(runnable, delay); 194 | } 195 | 196 | /** 197 | * Folia & Paper: Schedules a repeating task to be executed on the region which owns the 198 | * location of given entity after the initial delay with the specified period 199 | *

200 | * Bukkit: same as {@link #runTaskTimer(Runnable, long, long)} 201 | * 202 | * @param entity The entity whose location the region executing should own 203 | * @param runnable The task to execute 204 | * @param delay The initial delay, in ticks. 205 | * @param period The period, in ticks. 206 | */ 207 | default MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) { 208 | return runTaskTimer(runnable, delay, period); 209 | } 210 | 211 | /** 212 | * Schedules the specified task to be executed asynchronously immediately 213 | * 214 | * @param runnable The task to execute 215 | * @return The {@link MyScheduledTask} that represents the scheduled task 216 | */ 217 | MyScheduledTask runTaskAsynchronously(Runnable runnable); 218 | 219 | /** 220 | * Schedules the specified task to be executed asynchronously after the time delay has passed 221 | * 222 | * @param runnable The task to execute 223 | * @param delay The time delay to pass before the task should be executed 224 | * @return The {@link MyScheduledTask} that represents the scheduled task 225 | */ 226 | MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay); 227 | 228 | /** 229 | * Schedules the specified task to be executed asynchronously after the initial delay has passed, 230 | * and then periodically executed with the specified period 231 | * 232 | * @param runnable The task to execute 233 | * @param delay The time delay to pass before the first execution of the task, in ticks 234 | * @param period The time between task executions after the first execution of the task, in ticks 235 | * @return The {@link MyScheduledTask} that represents the scheduled task 236 | */ 237 | MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period); 238 | 239 | /** 240 | * Deprecated: use {@link #runTaskAsynchronously(Runnable)} 241 | */ 242 | @Deprecated 243 | default MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) { 244 | return runTaskAsynchronously(runnable); 245 | } 246 | 247 | /** 248 | * Deprecated: use {@link #runTaskLaterAsynchronously(Runnable, long)} 249 | */ 250 | @Deprecated 251 | default MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) { 252 | return runTaskLaterAsynchronously(runnable, delay); 253 | } 254 | 255 | /** 256 | * Deprecated: use {@link #runTaskTimerAsynchronously(Runnable, long, long)} 257 | */ 258 | @Deprecated 259 | default MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) { 260 | return runTaskTimerAsynchronously(runnable, delay, period); 261 | } 262 | 263 | /** 264 | * Calls a method on the main thread and returns a Future object. This task will be executed 265 | * by the main(Bukkit)/global(Folia&Paper) server thread. 266 | *

267 | * Note: The Future.get() methods must NOT be called from the main thread. 268 | *

269 | * Note2: There is at least an average of 10ms latency until the isDone() method returns true. 270 | * 271 | * @param task Task to be executed 272 | */ 273 | default Future callSyncMethod(final Callable task) { 274 | CompletableFuture completableFuture = new CompletableFuture<>(); 275 | execute(() -> { 276 | try { 277 | completableFuture.complete(task.call()); 278 | } catch (Exception e) { 279 | throw new RuntimeException(e); 280 | } 281 | }); 282 | return completableFuture; 283 | } 284 | 285 | /** 286 | * Schedules a task to be executed on the global region 287 | * 288 | * @param runnable The task to execute 289 | */ 290 | void execute(Runnable runnable); 291 | 292 | /** 293 | * Schedules a task to be executed on the region which owns the location 294 | * 295 | * @param location The location which the region executing should own 296 | * @param runnable The task to execute 297 | */ 298 | default void execute(Location location, Runnable runnable) { 299 | execute(runnable); 300 | } 301 | 302 | /** 303 | * Schedules a task to be executed on the region which owns the location of given entity 304 | * 305 | * @param entity The entity which location the region executing should own 306 | * @param runnable The task to execute 307 | */ 308 | default void execute(Entity entity, Runnable runnable) { 309 | execute(runnable); 310 | } 311 | 312 | /** 313 | * Attempts to cancel all tasks scheduled by this plugin 314 | */ 315 | void cancelTasks(); 316 | 317 | /** 318 | * Attempts to cancel all tasks scheduled by the specified plugin 319 | * 320 | * @param plugin specified plugin 321 | */ 322 | void cancelTasks(Plugin plugin); 323 | } 324 | -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/scheduling/tasks/MyScheduledTask.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.scheduling.tasks; 2 | 3 | import org.bukkit.plugin.Plugin; 4 | 5 | public interface MyScheduledTask { 6 | /** 7 | * Cancels executing task 8 | */ 9 | void cancel(); 10 | 11 | /** 12 | * @return true if task is cancelled, false otherwise 13 | */ 14 | boolean isCancelled(); 15 | 16 | /** 17 | * @return The plugin under which the task was scheduled. 18 | */ 19 | Plugin getOwningPlugin(); 20 | 21 | /** 22 | * @return true if task is currently executing, false otherwise 23 | */ 24 | boolean isCurrentlyRunning(); 25 | 26 | /** 27 | * @return true if task is repeating, false otherwise 28 | */ 29 | boolean isRepeatingTask(); 30 | } -------------------------------------------------------------------------------- /src/main/java/com/github/Anon8281/universalScheduler/utils/JavaUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.Anon8281.universalScheduler.utils; 2 | 3 | public class JavaUtil { 4 | public static boolean classExists(String className) { 5 | try { 6 | Class.forName(className); 7 | return true; 8 | } catch (ClassNotFoundException e) { 9 | return false; 10 | } 11 | } 12 | } 13 | --------------------------------------------------------------------------------