Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Folia Support; #2012

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public void onChunkUnload(ChunkUnloadEvent event) {
}
}, plugin);

Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, cache::invalidateAll, CACHE_INVALIDATION_INTERVAL, CACHE_INVALIDATION_INTERVAL);
plugin.getScheduler().runAsyncRate(cache::invalidateAll, CACHE_INVALIDATION_INTERVAL, CACHE_INVALIDATION_INTERVAL);
HarvelsX marked this conversation as resolved.
Show resolved Hide resolved
}

public void shutdown() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.scheduler.FoliaSchedulerAdapter;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.util.profile.resolver.PaperPlayerService;
Expand Down Expand Up @@ -235,7 +236,7 @@ public void stackPlayerInventory(LocalPlayer localPlayer) {
public void addPlatformReports(ReportList report) {
report.add(new ServerReport());
report.add(new PluginReport());
report.add(new SchedulerReport());
if (!FoliaSchedulerAdapter.isSupported()) report.add(new SchedulerReport());
report.add(new ServicesReport());
report.add(new WorldReport());
report.add(new PerformanceReport());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
import com.sk89q.worldguard.bukkit.listener.WorldRulesListener;
import com.sk89q.worldguard.bukkit.scheduler.BukkitSchedulerAdapter;
import com.sk89q.worldguard.bukkit.scheduler.FoliaSchedulerAdapter;
import com.sk89q.worldguard.bukkit.scheduler.SchedulerAdapter;
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
import com.sk89q.worldguard.bukkit.util.ClassSourceValidator;
import com.sk89q.worldguard.bukkit.util.Entities;
Expand Down Expand Up @@ -107,6 +110,8 @@ public class WorldGuardPlugin extends JavaPlugin {
private static WorldGuardPlugin inst;
private static BukkitWorldGuardPlatform platform;
private final CommandsManager<Actor> commands;
private final SchedulerAdapter scheduler = FoliaSchedulerAdapter.isSupported()
? new FoliaSchedulerAdapter(this) : new BukkitSchedulerAdapter(this);
private PlayerMoveListener playerMoveListener;

private static final int BSTATS_PLUGIN_ID = 3283;
Expand Down Expand Up @@ -164,7 +169,7 @@ public void onEnable() {
reg.register(GeneralCommands.class);
}

getServer().getScheduler().scheduleSyncRepeatingTask(this, sessionManager, BukkitSessionManager.RUN_DELAY, BukkitSessionManager.RUN_DELAY);
getScheduler().runAsyncRate(sessionManager, BukkitSessionManager.RUN_DELAY, BukkitSessionManager.RUN_DELAY);

// Register events
getServer().getPluginManager().registerEvents(sessionManager, this);
Expand Down Expand Up @@ -205,12 +210,12 @@ public void onEnable() {
}
worldListener.registerEvents();

Bukkit.getScheduler().runTask(this, () -> {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
getScheduler().executeAtEntity(player, () -> {
ProcessPlayerEvent event = new ProcessPlayerEvent(player);
Events.fire(event);
}
});
});
}

((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
((SimpleDomainRegistry) WorldGuard.getInstance().getDomainRegistry()).setInitialized(true);
Expand Down Expand Up @@ -266,7 +271,7 @@ private void setupCustomCharts(Metrics metrics) {
@Override
public void onDisable() {
WorldGuard.getInstance().disable();
this.getServer().getScheduler().cancelTasks(this);
getScheduler().cancelTasks();
}

@Override
Expand Down Expand Up @@ -526,4 +531,7 @@ public PlayerMoveListener getPlayerMoveListener() {
return playerMoveListener;
}

public SchedulerAdapter getScheduler() {
return scheduler;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -990,8 +990,7 @@ public void onInventoryMoveItem(InventoryMoveItemEvent event) {
handleInventoryHolderUse(event, cause, targetHolder);

if (event.isCancelled() && causeHolder instanceof Hopper && wcfg.breakDeniedHoppers) {
HarvelsX marked this conversation as resolved.
Show resolved Hide resolved
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(),
() -> ((Hopper) causeHolder).getBlock().breakNaturally());
getPlugin().getScheduler().executeAtRegion(((Hopper) causeHolder).getLocation(), () -> ((Hopper) causeHolder).getBlock().breakNaturally());
} else {
entry.setCancelled(event.isCancelled());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import org.bukkit.Bukkit;
import io.papermc.lib.PaperLib;
import org.bukkit.Location;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.Entity;
Expand Down Expand Up @@ -118,16 +118,16 @@ public void onPlayerMove(PlayerMoveEvent event) {
current.eject();
vehicle.setVelocity(new Vector());
if (vehicle instanceof LivingEntity) {
vehicle.teleport(override.clone());
PaperLib.teleportAsync(vehicle, override.clone());
} else {
vehicle.teleport(override.clone().add(0, 1, 0));
PaperLib.teleportAsync(vehicle, override.clone().add(0, 1, 0));
}
current = current.getVehicle();
}

player.teleport(override.clone().add(0, 1, 0));
PaperLib.teleportAsync(player, override.clone().add(0, 1, 0));

Bukkit.getScheduler().runTaskLater(getPlugin(), () -> player.teleport(override.clone().add(0, 1, 0)), 1);
getPlugin().getScheduler().runAtEntityDelayed(player, () -> PaperLib.teleportAsync(player, override.clone().add(0, 1, 0)), 1);
}
}
}
Expand All @@ -141,7 +141,7 @@ public void onPlayerQuit(PlayerQuitEvent event) {
com.sk89q.worldedit.util.Location loc = session.testMoveTo(localPlayer,
BukkitAdapter.adapt(event.getPlayer().getLocation()), MoveType.OTHER_CANCELLABLE); // white lie
if (loc != null) {
player.teleport(BukkitAdapter.adapt(loc));
PaperLib.teleportAsync(player, BukkitAdapter.adapt(loc));
}

session.uninitialize(localPlayer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.util.Locations;
import io.papermc.lib.PaperLib;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
Expand Down Expand Up @@ -66,10 +67,10 @@ public void onVehicleMove(VehicleMoveEvent event) {
if ((lastValid = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer)
.testMoveTo(localPlayer, BukkitAdapter.adapt(event.getTo()), MoveType.RIDE)) != null) {
vehicle.setVelocity(new Vector(0, 0, 0));
vehicle.teleport(event.getFrom());
PaperLib.teleportAsync(vehicle, event.getFrom());
if (Locations.isDifferentBlock(lastValid, BukkitAdapter.adapt(event.getFrom()))) {
Vector dir = player.getLocation().getDirection();
player.teleport(BukkitAdapter.adapt(lastValid).setDirection(dir));
PaperLib.teleportAsync(player, BukkitAdapter.adapt(lastValid).setDirection(dir));
}
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldguard.bukkit.scheduler;

import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;

public class BukkitSchedulerAdapter implements SchedulerAdapter {

private final Plugin plugin;
@SuppressWarnings("deprecation")
private final BukkitScheduler scheduler;

public BukkitSchedulerAdapter(final Plugin plugin) {
this.plugin = plugin;
this.scheduler = plugin.getServer().getScheduler();
}

@Override
public void runAsyncRate(Runnable runnable, long delay, long period) {
scheduler.runTaskTimerAsynchronously(plugin, runnable, delay, period);
}

@Override
public void executeAtEntity(Entity entity, Runnable runnable) {
scheduler.runTask(plugin, runnable);
}

@Override
public void runAtEntityDelayed(final Entity entity, final Runnable runnable, final long delay) {
scheduler.runTaskLater(plugin, runnable, delay);
}

@Override
public void executeAtRegion(Location location, Runnable runnable) {
scheduler.runTask(plugin, runnable);
}

@Override
public void cancelTasks() {
scheduler.cancelTasks(plugin);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldguard.bukkit.scheduler;

import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
import io.papermc.paper.threadedregions.scheduler.RegionScheduler;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;

import java.util.concurrent.TimeUnit;

public class FoliaSchedulerAdapter implements SchedulerAdapter {
private static final boolean SUPPORTED = checkSupport();

private final Plugin plugin;
private final AsyncScheduler asyncScheduler;
private final RegionScheduler regionScheduler;

public FoliaSchedulerAdapter(final Plugin plugin) {
this.plugin = plugin;
this.asyncScheduler = plugin.getServer().getAsyncScheduler();
this.regionScheduler = plugin.getServer().getRegionScheduler();
}

public static boolean isSupported() {
return SUPPORTED;
}

private static boolean checkSupport() {
try {
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

@Override
public void runAsyncRate(final Runnable runnable, final long delay, final long period) {
asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS);
}

@Override
public void executeAtEntity(final Entity entity, final Runnable runnable) {
entity.getScheduler().run(plugin, task -> runnable.run(), null);
}

@Override
public void runAtEntityDelayed(final Entity entity, final Runnable runnable, final long delay) {
entity.getScheduler().execute(plugin, runnable, null, delay);
}

@Override
public void executeAtRegion(final Location location, final Runnable runnable) {
regionScheduler.execute(plugin, location, runnable);
}

@Override
public void cancelTasks() {
asyncScheduler.cancelTasks(plugin);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldguard.bukkit.scheduler;

import org.bukkit.Location;
import org.bukkit.entity.Entity;

public interface SchedulerAdapter {
HarvelsX marked this conversation as resolved.
Show resolved Hide resolved

/**
* Schedules the specified task to be executed asynchronously after the 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 task should be executed.
* @param period The time between task executions after the first execution of the task.
*/
void runAsyncRate(Runnable runnable, long delay, long period);

/**
* Schedules a task. If the task failed to schedule because the scheduler is retired (entity removed),
* then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay,
* or the retired callback will be invoked if the scheduler is retired.
* Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity,
* remove other entities, load chunks, load worlds, modify ticket levels, etc.
*
* <p>
* It is guaranteed that the task and retired callback are invoked on the region which owns the entity.
* </p>
*
* @param entity The entity relative to which the scheduler is obtained.
* @param runnable The task to execute.
*/
void executeAtEntity(Entity entity, Runnable runnable);

/**
* Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity removed),
* then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay,
* or the retired callback will be invoked if the scheduler is retired.
* Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity,
* remove other entities, load chunks, load worlds, modify ticket levels, etc.
*
* <p>
* It is guaranteed that the task and retired callback are invoked on the region which owns the entity.
* </p>
*
* @param entity The entity relative to which the scheduler is obtained.
* @param runnable The task to execute.
* @param delay The time delay to pass before the task should be executed, in ticks.
*/
void runAtEntityDelayed(Entity entity, Runnable runnable, long delay);

/**
* Schedules a task to be executed on the region which owns the location.
*
* @param location The location at which the region executing should own.
* @param runnable The task to execute.
*/
void executeAtRegion(Location location, Runnable runnable);

/**
* Attempts to cancel all tasks scheduled by the plugin.
*/
void cancelTasks();
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ public void resetAllStates() {
@EventHandler
public void onPlayerProcess(ProcessPlayerEvent event) {
// Pre-load a session
LocalPlayer player = WorldGuardPlugin.inst().wrapPlayer(event.getPlayer());
get(player).initialize(player);
get(WorldGuardPlugin.inst().wrapPlayer(event.getPlayer()));
HarvelsX marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
Expand Down
Loading