mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2025-09-05 17:07:06 +02:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f14b081f0b | ||
|
b51fbf4e13 | ||
|
e48b6fe702 | ||
|
984f944daf | ||
|
0575c8cf41 | ||
|
c181d18f5e | ||
|
2e0d9eb846 | ||
|
33d1009d6a | ||
|
b16d62fb75 | ||
|
e019d6370c | ||
|
581b73dbc7 | ||
|
25f7eafe32 | ||
|
ef22d564f3 | ||
|
787a053d98 | ||
|
f31dd2bea9 | ||
|
5c8086150a | ||
|
b838d1c52a | ||
|
0a712e6530 | ||
|
272e2e7904 | ||
|
98082398fc | ||
|
c66806ecf8 | ||
|
c97f5aa5a6 | ||
|
c1487898a9 | ||
|
907ced6d7d | ||
|
ac771207c3 | ||
|
32f3d14682 | ||
|
152105017d | ||
|
be956f52b0 |
@@ -9,6 +9,7 @@
|
||||
[spigot]: https://www.spigotmc.org/resources/6245/
|
||||
[hangar]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[bbb]: https://builtbybit.com/resources/placeholderapi.24306
|
||||
[modrinth]: https://modrinth.com/plugin/placeholderapi
|
||||
[Expansions cloud]: https://api.extendedclip.com/home
|
||||
[placeholder list]: https://helpch.at/placeholders
|
||||
[statistics]: https://bstats.org/plugin/bukkit/PlaceholderAPI
|
||||
@@ -16,7 +17,7 @@
|
||||
[ci]: http://ci.extendedclip.com/job/PlaceholderAPI/
|
||||
[ciImg]: http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI
|
||||
|
||||
[APIversionImg]: https://img.shields.io/nexus/placeholderapi/me.clip/placeholderapi?server=https%3A%2F%2Frepo.extendedclip.com&label=API%20Version
|
||||
[APIversionImg]: https://repo.extendedclip.com/api/badge/latest/releases/me/clip/placeholderapi?name=API%20Version
|
||||
[logo]: https://wiki.placeholderapi.com/assets/img/papi-logo.png
|
||||
|
||||
[contributing]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/.github/CONTRIBUTING.md
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
Support for specific plugins are provided either by the plugin itself or through expansions. The expansions may be downloaded in-game through the PAPI Expansion Cloud. There are currently over 240+ expansions that support a wide variety of plugins, such as Essentials, Factions, LuckPerms, and Vault.
|
||||
|
||||
PlaceholderAPI has been downloaded over 1,000,000 times and has been used concurrently on over 40,000 servers, which makes it a must-have for a server of any type or scale.
|
||||
PlaceholderAPI has been downloaded over 1,700,000 times on Spigot and has been used concurrently on over 45,000 servers, which makes it a must-have for a server of any type or scale.
|
||||
|
||||
## Contribute
|
||||
If you would like to contribute towards PlaceholderAPI should you take a look at our [Contributing file][contributing] for the ins and outs on how you can do that and what you need to keep in mind.
|
||||
@@ -51,4 +52,5 @@ If you would like to create your own Placeholder Expansion for PlaceholderAPI, t
|
||||
- [Spigot Page][spigot]
|
||||
- [Hangar Page][hangar]
|
||||
- [BuiltByBit Page][bbb]
|
||||
- [Modrinth Page][modrinth]
|
||||
- [Plugin Statistics][statistics]
|
||||
|
@@ -4,11 +4,11 @@ plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
id("com.github.hierynomus.license") version "0.16.1"
|
||||
id("com.github.johnrengelman.shadow") version "8.1.0"
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
}
|
||||
|
||||
group = "me.clip"
|
||||
version = "2.11.6"
|
||||
version = "2.11.7-DEV-${System.getProperty("BUILD_NUMBER")}"
|
||||
|
||||
description = "An awesome placeholder provider!"
|
||||
|
||||
@@ -20,13 +20,15 @@ repositories {
|
||||
|
||||
maven("https://repo.codemc.org/repository/maven-public/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.bstats:bstats-bukkit:3.0.1")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.3.2")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.3.3")
|
||||
|
||||
compileOnly("org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT")
|
||||
//compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
|
||||
compileOnly("dev.folia:folia-api:1.20.1-R0.1-SNAPSHOT")
|
||||
compileOnlyApi("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
testImplementation("org.openjdk.jmh:jmh-core:1.32")
|
||||
@@ -43,6 +45,8 @@ java {
|
||||
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
|
||||
disableAutoTargetJvm()
|
||||
}
|
||||
|
||||
license {
|
||||
@@ -71,6 +75,7 @@ tasks {
|
||||
|
||||
withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 8
|
||||
}
|
||||
|
||||
withType<Javadoc> {
|
||||
@@ -107,9 +112,9 @@ tasks {
|
||||
repositories {
|
||||
maven {
|
||||
if ("-DEV" in version.toString()) {
|
||||
url = uri("https://repo.extendedclip.com/content/repositories/dev/")
|
||||
url = uri("https://repo.extendedclip.com/snapshots")
|
||||
} else {
|
||||
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
||||
url = uri("https://repo.extendedclip.com/releases")
|
||||
}
|
||||
|
||||
credentials {
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
28
gradlew
vendored
28
gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright <EFBFBD> 2015-2021 the original authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,10 @@
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
|
||||
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
|
||||
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
|
||||
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -80,10 +80,10 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
@@ -143,12 +143,16 @@ fi
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -205,6 +209,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +25,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
@@ -136,8 +136,8 @@ public final class PlaceholderAPI {
|
||||
* @return String containing all translated placeholders
|
||||
*/
|
||||
@NotNull
|
||||
public static List<String> setBracketPlaceholders(final OfflinePlayer player,
|
||||
@NotNull final List<String> text) {
|
||||
public static List<@NotNull String> setBracketPlaceholders(final OfflinePlayer player,
|
||||
@NotNull final List<@NotNull String> text) {
|
||||
return text.stream().map(line -> setBracketPlaceholders(player, line))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@@ -150,7 +150,8 @@ public final class PlaceholderAPI {
|
||||
* @param text Text to set the placeholder values in
|
||||
* @return String containing all translated placeholders
|
||||
*/
|
||||
public static String setBracketPlaceholders(Player player, String text) {
|
||||
@NotNull
|
||||
public static String setBracketPlaceholders(Player player, @NotNull String text) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, text);
|
||||
}
|
||||
|
||||
@@ -162,7 +163,8 @@ public final class PlaceholderAPI {
|
||||
* @param text List of Strings to set the placeholder values in
|
||||
* @return String containing all translated placeholders
|
||||
*/
|
||||
public static List<String> setBracketPlaceholders(Player player, List<String> text) {
|
||||
@NotNull
|
||||
public static List<String> setBracketPlaceholders(Player player, @NotNull List<String> text) {
|
||||
return setBracketPlaceholders((OfflinePlayer) player, text);
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,8 @@ import me.clip.placeholderapi.expansion.Version;
|
||||
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
|
||||
import me.clip.placeholderapi.expansion.manager.LocalExpansionManager;
|
||||
import me.clip.placeholderapi.listeners.ServerLoadEventListener;
|
||||
import me.clip.placeholderapi.scheduler.UniversalScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.updatechecker.UpdateChecker;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
@@ -86,9 +88,12 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this);
|
||||
@NotNull
|
||||
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this);
|
||||
@NotNull
|
||||
private final TaskScheduler scheduler = UniversalScheduler.getScheduler(this);
|
||||
|
||||
private BukkitAudiences adventure;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
|
||||
* class, this is the main class that extends JavaPlugin. For most API methods, use static methods
|
||||
@@ -174,7 +179,7 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
scheduler.cancelTasks(this);
|
||||
|
||||
adventure.close();
|
||||
adventure = null;
|
||||
@@ -215,6 +220,11 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
return adventure;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TaskScheduler getScheduler() {
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the configuration class for PlaceholderAPI.
|
||||
*
|
||||
@@ -262,8 +272,8 @@ public final class PlaceholderAPIPlugin extends JavaPlugin {
|
||||
Class.forName("org.bukkit.event.server.ServerLoadEvent");
|
||||
new ServerLoadEventListener(this);
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
Bukkit.getScheduler()
|
||||
.runTaskLater(this, () -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
|
||||
scheduler
|
||||
.runTaskLater(() -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,11 @@ public enum NMSVersion {
|
||||
SPIGOT_1_20_R1("v1_20_R1"),
|
||||
SPIGOT_1_20_R2("v1_20_R2"),
|
||||
SPIGOT_1_20_R3("v1_20_R3"),
|
||||
SPIGOT_1_20_R4("v1_20_R4");
|
||||
SPIGOT_1_20_R4("v1_20_R4"),
|
||||
SPIGOT_1_21_R1("v1_21_R1"),
|
||||
SPIGOT_1_21_R2("V1_21_R2"),
|
||||
SPIGOT_1_21_R3("V1_21_R3"),
|
||||
SPIGOT_1_21_R4("V1_21_R4");
|
||||
|
||||
private final String version;
|
||||
|
||||
|
@@ -202,10 +202,8 @@ public final class CloudExpansionManager {
|
||||
|
||||
// loop through what's left on the main thread
|
||||
plugin
|
||||
.getServer()
|
||||
.getScheduler()
|
||||
.runTask(
|
||||
plugin,
|
||||
() -> {
|
||||
try {
|
||||
for (Map.Entry<String, CloudExpansion> entry : values.entrySet()) {
|
||||
|
@@ -34,9 +34,9 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
|
||||
@@ -440,7 +440,8 @@ public final class LocalExpansionManager implements Listener {
|
||||
Msg.severe("Failed to load expansion %s (is a dependency missing?)", e, file.getName());
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
throw new CompletionException(e.getMessage() + " (expansion file: " + file.getAbsolutePath() + ")", e);
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to load expansion file: " + file.getAbsolutePath(), e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/** Just modified BukkitRunnable */
|
||||
public abstract class UniversalRunnable implements Runnable {
|
||||
MyScheduledTask task;
|
||||
|
||||
public synchronized void cancel() throws IllegalStateException {
|
||||
checkScheduled();
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this task has been cancelled.
|
||||
*
|
||||
* @return true if the task has been cancelled
|
||||
* @throws IllegalStateException if task was not scheduled yet
|
||||
*/
|
||||
public synchronized boolean isCancelled() throws IllegalStateException {
|
||||
checkScheduled();
|
||||
return task.isCancelled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules this in the Bukkit scheduler to run on next tick.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTask(Runnable)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTask(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTask(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Schedules this in the Bukkit scheduler to run asynchronously.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskAsynchronously(Runnable)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskAsynchronously(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules this to run after the specified number of server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskLater(Runnable, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskLater(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLater(this, delay));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Schedules this to run asynchronously after the specified number of
|
||||
* server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskLaterAsynchronously(Runnable, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskLaterAsynchronously(this, delay));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules this to repeatedly run until cancelled, starting after the
|
||||
* specified number of server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task
|
||||
* @param period the ticks to wait between runs
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskTimer(Runnable, long, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskTimer(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimer(this, delay, period));
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
|
||||
* should be taken to assure the thread-safety of asynchronous tasks.</b>
|
||||
* <p>
|
||||
* Schedules this to repeatedly run asynchronously until cancelled,
|
||||
* starting after the specified number of server ticks.
|
||||
*
|
||||
* @param plugin the reference to the plugin scheduling task
|
||||
* @param delay the ticks to wait before running the task for the first
|
||||
* time
|
||||
* @param period the ticks to wait between runs
|
||||
* @return {@link MyScheduledTask}
|
||||
* @throws IllegalArgumentException if plugin is null
|
||||
* @throws IllegalStateException if this was already scheduled
|
||||
* @see TaskScheduler#runTaskTimerAsynchronously(Runnable, long, long)
|
||||
*/
|
||||
|
||||
public synchronized MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException {
|
||||
checkNotYetScheduled();
|
||||
return setupTask(UniversalScheduler.getScheduler(plugin).runTaskTimerAsynchronously(this, delay, period));
|
||||
}
|
||||
|
||||
private void checkScheduled() {
|
||||
if (task == null) {
|
||||
throw new IllegalStateException("Not scheduled yet");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNotYetScheduled() {
|
||||
if (task != null) {
|
||||
throw new IllegalStateException("Already scheduled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private MyScheduledTask setupTask(final MyScheduledTask task) {
|
||||
this.task = task;
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.bukkit.BukkitScheduler;
|
||||
import me.clip.placeholderapi.scheduler.folia.FoliaScheduler;
|
||||
import me.clip.placeholderapi.scheduler.paper.PaperScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.utils.JavaUtil;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class UniversalScheduler {
|
||||
private static final boolean IS_FOLIA = JavaUtil.classExists("io.papermc.paper.threadedregions.RegionizedServer");
|
||||
private static final boolean IS_CANVAS = JavaUtil.classExists("io.canvasmc.canvas.server.ThreadedServer");
|
||||
private static final boolean IS_EXPANDED_SCHEDULING_AVAILABLE = JavaUtil.classExists("io.papermc.paper.threadedregions.scheduler.ScheduledTask");
|
||||
|
||||
public static TaskScheduler getScheduler(Plugin plugin) {
|
||||
return IS_FOLIA || IS_CANVAS ? new FoliaScheduler(plugin) : (IS_EXPANDED_SCHEDULING_AVAILABLE ? new PaperScheduler(plugin) : new BukkitScheduler(plugin));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.bukkit;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class BukkitScheduledTask implements MyScheduledTask {
|
||||
|
||||
BukkitTask task;
|
||||
|
||||
boolean isRepeating;
|
||||
|
||||
public BukkitScheduledTask(final BukkitTask task) {
|
||||
this.task = task;
|
||||
this.isRepeating = false;
|
||||
}
|
||||
|
||||
public BukkitScheduledTask(final BukkitTask task, boolean isRepeating) {
|
||||
this.task = task;
|
||||
this.isRepeating = isRepeating;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getOwningPlugin() {
|
||||
return task.getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentlyRunning() {
|
||||
return Bukkit.getServer().getScheduler().isCurrentlyRunning(this.task.getTaskId()); //There's no other way. Fuck bukkit
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRepeatingTask() {
|
||||
return isRepeating;
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.bukkit;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class BukkitScheduler implements TaskScheduler {
|
||||
final Plugin plugin;
|
||||
|
||||
public BukkitScheduler(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlobalThread() {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityThread(Entity entity) {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegionThread(Location location) {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
//Useless? Or...
|
||||
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTask(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return new BukkitScheduledTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks() {
|
||||
Bukkit.getScheduler().cancelTasks(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks(Plugin plugin) {
|
||||
Bukkit.getScheduler().cancelTasks(plugin);
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.folia;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class FoliaScheduledTask implements MyScheduledTask {
|
||||
private final ScheduledTask task;
|
||||
|
||||
public FoliaScheduledTask(final ScheduledTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
this.task.cancel();
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return this.task.isCancelled();
|
||||
}
|
||||
|
||||
public Plugin getOwningPlugin() {
|
||||
return this.task.getOwningPlugin();
|
||||
}
|
||||
|
||||
public boolean isCurrentlyRunning() {
|
||||
final ScheduledTask.ExecutionState state = this.task.getExecutionState();
|
||||
return state == ScheduledTask.ExecutionState.RUNNING || state == ScheduledTask.ExecutionState.CANCELLED_RUNNING;
|
||||
}
|
||||
|
||||
public boolean isRepeatingTask() {
|
||||
return this.task.isRepeatingTask();
|
||||
}
|
||||
}
|
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.folia;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
|
||||
import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler;
|
||||
import io.papermc.paper.threadedregions.scheduler.RegionScheduler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FoliaScheduler implements TaskScheduler {
|
||||
|
||||
final Plugin plugin;
|
||||
|
||||
public FoliaScheduler(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
private final RegionScheduler regionScheduler = Bukkit.getServer().getRegionScheduler();
|
||||
private final GlobalRegionScheduler globalRegionScheduler = Bukkit.getServer().getGlobalRegionScheduler();
|
||||
private final AsyncScheduler asyncScheduler = Bukkit.getServer().getAsyncScheduler();
|
||||
|
||||
@Override
|
||||
public boolean isGlobalThread() {
|
||||
return Bukkit.getServer().isGlobalTickThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTickThread() {
|
||||
return Bukkit.getServer().isPrimaryThread(); // The Paper implementation checks whether this is a tick thread, this method exists to avoid confusion.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityThread(Entity entity) {
|
||||
return Bukkit.getServer().isOwnedByCurrentRegion(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegionThread(Location location) {
|
||||
return Bukkit.getServer().isOwnedByCurrentRegion(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Runnable runnable) {
|
||||
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||
return new FoliaScheduledTask(globalRegionScheduler.run(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(plugin, runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runDelayed(plugin, task -> runnable.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(globalRegionScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Location location, Runnable runnable) {
|
||||
return new FoliaScheduledTask(regionScheduler.run(plugin, location, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(regionScheduler.runDelayed(plugin, location, task -> runnable.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(regionScheduler.runAtFixedRate(plugin, location, task -> runnable.run(), delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTask(Entity entity, Runnable runnable) {
|
||||
return new FoliaScheduledTask(entity.getScheduler().run(plugin, task -> runnable.run(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
if (delay <= 0) {
|
||||
return runTask(entity, runnable);
|
||||
}
|
||||
return new FoliaScheduledTask(entity.getScheduler().runDelayed(plugin, task -> runnable.run(), null, delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(entity.getScheduler().runAtFixedRate(plugin, task -> runnable.run(), null, delay, period));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Runnable runnable) {
|
||||
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period) {
|
||||
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||
return new FoliaScheduledTask(asyncScheduler.runNow(plugin, task -> runnable.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(asyncScheduler.runDelayed(plugin, task -> runnable.run(), delay * 50L, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
//Folia exception: Delay ticks may not be <= 0
|
||||
delay = getOneIfNotPositive(delay);
|
||||
return new FoliaScheduledTask(asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
globalRegionScheduler.execute(plugin, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Location location, Runnable runnable) {
|
||||
regionScheduler.execute(plugin, location, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Entity entity, Runnable runnable) {
|
||||
entity.getScheduler().execute(plugin, runnable, null, 1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks() {
|
||||
globalRegionScheduler.cancelTasks(plugin);
|
||||
asyncScheduler.cancelTasks(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTasks(Plugin plugin) {
|
||||
globalRegionScheduler.cancelTasks(plugin);
|
||||
asyncScheduler.cancelTasks(plugin);
|
||||
}
|
||||
|
||||
private long getOneIfNotPositive(long x) {
|
||||
return x <= 0 ? 1L : x;
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.paper;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.folia.FoliaScheduler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
//Thanks to Towny
|
||||
public class PaperScheduler extends FoliaScheduler {
|
||||
public PaperScheduler(Plugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlobalThread() {
|
||||
// isGlobalThread does not exist on paper, match the bukkit task scheduler's behaviour.
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
}
|
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.scheduling.schedulers;
|
||||
|
||||
import me.clip.placeholderapi.scheduler.scheduling.tasks.MyScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* <b>Folia</b>: Returns whether the current thread is ticking the global region <br>
|
||||
* <b>Paper & Bukkit</b>: Returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*/
|
||||
boolean isGlobalThread();
|
||||
|
||||
/**
|
||||
* @return {@link org.bukkit.Server#isPrimaryThread}
|
||||
*/
|
||||
default boolean isTickThread() {
|
||||
return Bukkit.getServer().isPrimaryThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* being ticked owns the specified entity. Note that this function is the only appropriate method of
|
||||
* checking for ownership of an entity, as retrieving the entity's location is undefined unless the
|
||||
* entity is owned by the current region
|
||||
* <p>
|
||||
* <b>Bukkit</b>: returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*
|
||||
* @param entity Specified entity
|
||||
*/
|
||||
boolean isEntityThread(Entity entity);
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Returns whether the current thread is ticking a region and that the region
|
||||
* being ticked owns the chunk at the specified world and block position as included in the specified location
|
||||
* <p>
|
||||
* <b>Bukkit</b>: returns {@link org.bukkit.Server#isPrimaryThread}
|
||||
*
|
||||
* @param location Specified location, must have a non-null world.
|
||||
*/
|
||||
boolean isRegionThread(Location location);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the next tick <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
MyScheduledTask runTask(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed after the specified delay in ticks <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The delay, in ticks
|
||||
*/
|
||||
MyScheduledTask runTaskLater(Runnable runnable, long delay);
|
||||
|
||||
/**
|
||||
* Schedules a repeating task to be executed after the initial delay with the specified period <br>
|
||||
* <b>Folia & Paper</b>: ...on the global region <br>
|
||||
* <b>Bukkit</b>: ...on the main thread
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The initial delay, in ticks.
|
||||
* @param period The period, in ticks.
|
||||
*/
|
||||
MyScheduledTask runTaskTimer(Runnable runnable, long delay, long period);
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTask(Runnable)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTask(Plugin plugin, Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskLater(Runnable, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskLater(Plugin plugin, Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskTimer(Runnable, long, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location on the next tick
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTask(Runnable)}
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default MyScheduledTask runTask(Location location, Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location after the
|
||||
* specified delay in ticks
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskLater(Runnable, long)}
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The delay, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskLater(Location location, Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a repeating task to be executed on the region which owns the location
|
||||
* after the initial delay with the specified period
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskTimer(Runnable, long, long)}
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The initial delay, in ticks.
|
||||
* @param period The period, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskTimer(Location location, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskLater(Runnable, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #execute(Runnable)} or {@link #runTask(Runnable)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask scheduleSyncDelayedTask(Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskTimer(Runnable, long, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask scheduleSyncRepeatingTask(Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* of given entity on the next tick
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTask(Runnable)}
|
||||
*
|
||||
* @param entity The entity whose location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default MyScheduledTask runTask(Entity entity, Runnable runnable) {
|
||||
return runTask(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a task to be executed on the region which owns the location
|
||||
* of given entity after the specified delay in ticks
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskLater(Runnable, long)}
|
||||
*
|
||||
* @param entity The entity whose location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The delay, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskLater(Entity entity, Runnable runnable, long delay) {
|
||||
return runTaskLater(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Folia & Paper</b>: Schedules a repeating task to be executed on the region which owns the
|
||||
* location of given entity after the initial delay with the specified period
|
||||
* <p>
|
||||
* <b>Bukkit</b>: same as {@link #runTaskTimer(Runnable, long, long)}
|
||||
*
|
||||
* @param entity The entity whose location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
* @param delay The initial delay, in ticks.
|
||||
* @param period The period, in ticks.
|
||||
*/
|
||||
default MyScheduledTask runTaskTimer(Entity entity, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimer(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the specified task to be executed asynchronously immediately
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||
*/
|
||||
MyScheduledTask runTaskAsynchronously(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Schedules the specified task to be executed asynchronously after the time delay has passed
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The time delay to pass before the task should be executed
|
||||
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||
*/
|
||||
MyScheduledTask runTaskLaterAsynchronously(Runnable runnable, long delay);
|
||||
|
||||
/**
|
||||
* Schedules the specified task to be executed asynchronously after the initial delay has passed,
|
||||
* and then periodically executed with the specified period
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
* @param delay The time delay to pass before the first execution of the task, in ticks
|
||||
* @param period The time between task executions after the first execution of the task, in ticks
|
||||
* @return The {@link MyScheduledTask} that represents the scheduled task
|
||||
*/
|
||||
MyScheduledTask runTaskTimerAsynchronously(Runnable runnable, long delay, long period);
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskAsynchronously(Runnable)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskAsynchronously(Plugin plugin, Runnable runnable) {
|
||||
return runTaskAsynchronously(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskLaterAsynchronously(Runnable, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) {
|
||||
return runTaskLaterAsynchronously(runnable, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: use {@link #runTaskTimerAsynchronously(Runnable, long, long)}
|
||||
*/
|
||||
@Deprecated
|
||||
default MyScheduledTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) {
|
||||
return runTaskTimerAsynchronously(runnable, delay, period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a method on the main thread and returns a Future object. This task will be executed
|
||||
* by the main(Bukkit)/global(Folia&Paper) server thread.
|
||||
* <p>
|
||||
* Note: The Future.get() methods must NOT be called from the main thread.
|
||||
* <p>
|
||||
* Note2: There is at least an average of 10ms latency until the isDone() method returns true.
|
||||
*
|
||||
* @param task Task to be executed
|
||||
*/
|
||||
default <T> Future<T> callSyncMethod(final Callable<T> task) {
|
||||
CompletableFuture<T> completableFuture = new CompletableFuture<>();
|
||||
execute(() -> {
|
||||
try {
|
||||
completableFuture.complete(task.call());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the global region
|
||||
*
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
void execute(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the region which owns the location
|
||||
*
|
||||
* @param location The location which the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default void execute(Location location, Runnable runnable) {
|
||||
execute(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed on the region which owns the location of given entity
|
||||
*
|
||||
* @param entity The entity which location the region executing should own
|
||||
* @param runnable The task to execute
|
||||
*/
|
||||
default void execute(Entity entity, Runnable runnable) {
|
||||
execute(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to cancel all tasks scheduled by this plugin
|
||||
*/
|
||||
void cancelTasks();
|
||||
|
||||
/**
|
||||
* Attempts to cancel all tasks scheduled by the specified plugin
|
||||
*
|
||||
* @param plugin specified plugin
|
||||
*/
|
||||
void cancelTasks(Plugin plugin);
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Sevastjan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.clip.placeholderapi.scheduler.scheduling.tasks;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public interface MyScheduledTask {
|
||||
/**
|
||||
* Cancels executing task
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* @return true if task is cancelled, false otherwise
|
||||
*/
|
||||
boolean isCancelled();
|
||||
|
||||
/**
|
||||
* @return The plugin under which the task was scheduled.
|
||||
*/
|
||||
Plugin getOwningPlugin();
|
||||
|
||||
/**
|
||||
* @return true if task is currently executing, false otherwise
|
||||
*/
|
||||
boolean isCurrentlyRunning();
|
||||
|
||||
/**
|
||||
* @return true if task is repeating, false otherwise
|
||||
*/
|
||||
boolean isRepeatingTask();
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package me.clip.placeholderapi.scheduler.utils;
|
||||
|
||||
public class JavaUtil {
|
||||
public static boolean classExists(String className) {
|
||||
try {
|
||||
Class.forName(className);
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -26,6 +26,7 @@ import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -35,15 +36,17 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class UpdateChecker implements Listener {
|
||||
|
||||
private final int RESOURCE_ID = 6245;
|
||||
private static final int RESOURCE_ID = 6245;
|
||||
private final PlaceholderAPIPlugin plugin;
|
||||
private final TaskScheduler scheduler;
|
||||
private final String pluginVersion;
|
||||
private String spigotVersion;
|
||||
private boolean updateAvailable;
|
||||
|
||||
public UpdateChecker(PlaceholderAPIPlugin i) {
|
||||
plugin = i;
|
||||
pluginVersion = i.getDescription().getVersion();
|
||||
public UpdateChecker(PlaceholderAPIPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
scheduler = plugin.getScheduler();
|
||||
pluginVersion = plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
public boolean hasUpdateAvailable() {
|
||||
@@ -55,7 +58,7 @@ public class UpdateChecker implements Listener {
|
||||
}
|
||||
|
||||
public void fetch() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
scheduler.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
||||
@@ -76,7 +79,7 @@ public class UpdateChecker implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
scheduler.runTask(() -> {
|
||||
plugin.getLogger()
|
||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
||||
plugin.getLogger()
|
||||
|
@@ -27,6 +27,8 @@ import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,14 +38,14 @@ public final class Futures {
|
||||
private Futures() {}
|
||||
|
||||
|
||||
public static <T> void onMainThread(@NotNull final Plugin plugin,
|
||||
public static <T> void onMainThread(@NotNull final PlaceholderAPIPlugin plugin,
|
||||
@NotNull final CompletableFuture<T> future,
|
||||
@NotNull final BiConsumer<T, Throwable> consumer) {
|
||||
future.whenComplete((value, exception) -> {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
consumer.accept(value, exception);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(plugin, () -> consumer.accept(value, exception));
|
||||
plugin.getScheduler().runTask(() -> consumer.accept(value, exception));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
name: PlaceholderAPI
|
||||
main: "me.clip.placeholderapi.PlaceholderAPIPlugin"
|
||||
folia-supported: true
|
||||
|
||||
version: ${version}
|
||||
author: HelpChat
|
||||
|
Reference in New Issue
Block a user