Add folia support

This commit is contained in:
ceze88 2023-05-17 12:57:40 +02:00
parent e3153653ff
commit 6d46e3311c
25 changed files with 573 additions and 32 deletions

View File

@ -11,7 +11,10 @@ public enum ServerVersion {
private final static ServerVersion serverVersion;
private final static boolean isMocked;
private final static boolean isFolia;
static {
boolean isFolia1;
if (Bukkit.getServer() != null) {
String srvPackage = Bukkit.getServer().getClass().getPackage().getName();
isMocked = srvPackage.equals("be.seeseemelk.mockbukkit");
@ -29,9 +32,21 @@ public enum ServerVersion {
isMocked = false;
}
try {
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
isFolia1 = true;
} catch (ClassNotFoundException e) {
isFolia1 = false;
}
isFolia = isFolia1;
serverVersion = getVersion();
}
public static boolean isFolia() {
return isFolia;
}
private static ServerVersion getVersion() {
for (ServerVersion version : values()) {
if (serverPackageVersion.toUpperCase().startsWith(version.name())) {

View File

@ -84,6 +84,7 @@
<include>org.apache.commons:commons-lang3</include>
<include>org.apache.commons:commons-text</include>
<include>org.yaml:snakeyaml</include>
<include>io.papermc:paperlib</include>
</includes>
</artifactSet>
@ -109,8 +110,8 @@
</relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>com.songoda.core.third_party.org.yaml.snakeyaml</shadedPattern>
<pattern>io.papermc.lib</pattern>
<shadedPattern>com.songoda.core.third_party.io.papermc.lib</shadedPattern>
</relocation>
</relocations>
@ -142,6 +143,13 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
@ -149,6 +157,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-Compatibility</artifactId>
@ -156,6 +171,13 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>Folia</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-NMS</artifactId>

View File

@ -1,5 +1,7 @@
package com.songoda.core;
import com.songoda.SchedulerTask;
import com.songoda.SchedulerUtils;
import com.songoda.core.commands.CommandManager;
import com.songoda.core.compatibility.ClientVersion;
import com.songoda.core.compatibility.CompatibleMaterial;
@ -198,15 +200,14 @@ public class SongodaCore {
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
// we aggressively want to own this command
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () ->
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager),
10 * 60));
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () ->
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager),
20 * 60));
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () ->
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager),
20 * 60 * 2));
tasks.add(SchedulerUtils.runTaskLater(piggybackedPlugin, () ->
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager), 10 * 60));
tasks.add(SchedulerUtils.runTaskLater(piggybackedPlugin, () ->
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager), 20 * 60));
tasks.add(SchedulerUtils.runTaskLater(piggybackedPlugin, () ->
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager), 20 * 60 * 2));
}
/**
@ -216,7 +217,7 @@ public class SongodaCore {
Bukkit.getServicesManager().unregister(SongodaCore.class, INSTANCE);
tasks.stream().filter(Objects::nonNull)
.forEach(task -> Bukkit.getScheduler().cancelTask(task.getTaskId()));
.forEach(SchedulerUtils::cancelTask);
HandlerList.unregisterAll(loginListener);
if (!hasShading()) {
@ -228,7 +229,7 @@ public class SongodaCore {
loginListener = null;
}
private ArrayList<BukkitTask> tasks = new ArrayList<>();
private ArrayList<SchedulerTask> tasks = new ArrayList<>();
private void register(JavaPlugin plugin, int pluginID, String icon, String libraryVersion) {
logger.info(getPrefix() + "Hooked " + plugin.getName() + ".");
@ -237,7 +238,7 @@ public class SongodaCore {
// don't forget to check for language pack updates ;)
info.addModule(new LocaleModule());
registeredPlugins.add(info);
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> update(info), 60L));
tasks.add(SchedulerUtils.runTaskLaterAsynchronously(plugin, () -> update(info), 60L));
}
/**
@ -416,9 +417,10 @@ public class SongodaCore {
// check for updates! ;)
for (PluginInfo plugin : getPlugins()) {
if (plugin.getNotification() != null && plugin.getJavaPlugin().isEnabled())
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin.getJavaPlugin(), () ->
if (plugin.getNotification() != null && plugin.getJavaPlugin().isEnabled()) {
SchedulerUtils.runTaskLaterAsynchronously(plugin.getJavaPlugin(), () ->
player.sendMessage("[" + plugin.getJavaPlugin().getName() + "] " + plugin.getNotification()), 10L);
}
}
}

View File

@ -1,5 +1,6 @@
package com.songoda.core;
import com.songoda.SchedulerUtils;
import com.songoda.core.configuration.Config;
import com.songoda.core.database.DataManagerAbstract;
import com.songoda.core.locale.Locale;
@ -136,7 +137,7 @@ public abstract class SongodaPlugin extends JavaPlugin {
}
// Load Data.
Bukkit.getScheduler().runTaskLater(this, this::onDataLoad, this.dataLoadDelay);
SchedulerUtils.runTaskLater(this, this::onDataLoad, this.dataLoadDelay);
if (this.emergencyStop) {
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

View File

@ -1,5 +1,6 @@
package com.songoda.core.database;
import com.songoda.SchedulerUtils;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
@ -81,7 +82,7 @@ public class DataManagerAbstract {
*/
@Deprecated
public void async(Runnable runnable) {
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, runnable);
SchedulerUtils.runTaskAsynchronously(plugin, runnable);
}
/**
@ -100,7 +101,7 @@ public class DataManagerAbstract {
* @param runnable task to run on the next server tick
*/
public void sync(Runnable runnable) {
Bukkit.getScheduler().runTask(this.plugin, runnable);
SchedulerUtils.runTask(plugin, runnable);
}
public void runAsync(Runnable runnable) {

View File

@ -1,5 +1,6 @@
package com.songoda.core.gui;
import com.songoda.SchedulerUtils;
import com.songoda.core.compatibility.ClientVersion;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
@ -102,7 +103,7 @@ public class GuiManager {
return;
}
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
SchedulerUtils.runTaskAsynchronously(plugin, () -> {
Gui openInv = openInventories.get(player);
if (openInv != null) {
@ -111,7 +112,7 @@ public class GuiManager {
Inventory inv = gui.getOrCreateInventory(this);
Bukkit.getScheduler().runTask(plugin, () -> {
SchedulerUtils.runTask(plugin, () -> {
player.openInventory(inv);
gui.onOpen(this, player);
@ -136,7 +137,7 @@ public class GuiManager {
popup.add();
popup.grant(player);
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
SchedulerUtils.runTaskLaterAsynchronously(plugin, () -> {
popup.revoke(player);
popup.remove();
}, 70);
@ -280,7 +281,7 @@ public class GuiManager {
if (manager.shutdown) {
gui.onClose(manager, player);
} else {
Bukkit.getScheduler().runTaskLater(manager.plugin, () -> gui.onClose(manager, player), 1);
SchedulerUtils.runEntityTask(manager.plugin, player, () -> gui.onClose(manager, player), 1);
}
manager.openInventories.remove(player);

View File

@ -1,5 +1,7 @@
package com.songoda.core.input;
import com.songoda.SchedulerTask;
import com.songoda.SchedulerUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -20,7 +22,7 @@ public class ChatPrompt implements Listener {
private final Plugin plugin;
private final ChatConfirmHandler handler;
private int taskId;
private SchedulerTask taskId;
private OnClose onClose = null;
private OnCancel onCancel = null;
private Listener listener;
@ -67,7 +69,7 @@ public class ChatPrompt implements Listener {
}
public ChatPrompt setTimeOut(Player player, long ticks) {
taskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> {
taskId = SchedulerUtils.scheduleSyncDelayedTask(plugin, () -> {
if (onClose != null) {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () ->
onClose.onClose(), 0L);
@ -108,7 +110,7 @@ public class ChatPrompt implements Listener {
}
HandlerList.unregisterAll(listener);
Bukkit.getScheduler().cancelTask(taskId);
SchedulerUtils.cancelTask(taskId);
}
@EventHandler(priority = EventPriority.LOWEST)
@ -132,7 +134,7 @@ public class ChatPrompt implements Listener {
}
HandlerList.unregisterAll(listener);
Bukkit.getScheduler().cancelTask(taskId);
SchedulerUtils.cancelTask(taskId);
}
};

View File

@ -1,6 +1,7 @@
package com.songoda.core.lootables.loot;
import com.bgsoftware.wildstacker.api.objects.StackedItem;
import com.songoda.SchedulerUtils;
import com.songoda.core.SongodaCore;
import com.songoda.ultimatestacker.UltimateStacker;
import com.songoda.ultimatestacker.settings.Settings;
@ -87,7 +88,7 @@ public class DropUtils {
}
stack.setamount(newAmount);
}
Bukkit.getScheduler().runTask(UltimateStacker.getInstance(), () -> {
SchedulerUtils.runLocationTask(UltimateStacker.getInstance(), event.getEntity().getLocation(), () -> {
for (StackedItem stack : stacks) {
UltimateStacker.spawnStackedItem(stack.getItem(), stack.getAmount(), event.getEntity().getLocation());
}
@ -98,7 +99,7 @@ public class DropUtils {
}
private static void runCommands(LivingEntity entity, List<String> commands) {
Bukkit.getScheduler().runTask(SongodaCore.getHijackedPlugin(), () -> {
SchedulerUtils.runTask(SongodaCore.getHijackedPlugin(), () -> {
for (String command : commands) {
if (entity.getKiller() != null) {
command = command.replace("%player%", entity.getKiller().getName()

View File

@ -1,6 +1,7 @@
package com.songoda.core.nms;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.v1_19_R3.NmsImplementationsImpl;
public class Nms {
protected static NmsImplementations impl;
@ -11,8 +12,17 @@ public class Nms {
public static NmsImplementations getImplementations() throws UnsupportedServerVersionException {
if (impl == null) {
try {
if (ServerVersion.isFolia()) {
impl = new NmsImplementationsImpl();
return impl;
}
switch (ServerVersion.getServerVersionString()) {
case "v1_19_R2":
impl = new com.songoda.core.nms.v1_19_R2.NmsImplementationsImpl();
break;
}
impl = (NmsImplementations) Class.forName("com.songoda.core.nms." + ServerVersion.getServerVersionString() + ".NmsImplementationsImpl").getConstructors()[0].newInstance();
} catch (ReflectiveOperationException ex) {
} catch (Exception ex) {
throw new UnsupportedServerVersionException(ex);
}
}

View File

@ -1,5 +1,6 @@
package com.songoda.core.utils;
import com.songoda.SchedulerUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@ -188,7 +189,7 @@ public class Metrics {
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
Bukkit.getScheduler().runTask(plugin, () -> submitData());
SchedulerUtils.runTask(plugin, () -> submitData());
}
}, 1000 * 60 * 5, 1000 * 60 * 30);
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start

View File

@ -2,12 +2,14 @@ package com.songoda.core.world;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.Nms;
import io.papermc.paper.threadedregions.scheduler.EntityScheduler;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import java.util.List;
import java.util.Map;
public class SWorld {
protected final com.songoda.core.nms.world.SWorld sWorld;
@ -35,6 +37,14 @@ public class SWorld {
return sWorld.getLivingEntities();
}
/**
* For folia servers
* @return EntityScheduler and a list of entities belongs to it
*/
public Map<EntityScheduler, List<LivingEntity>> getRegionizedEntities() {
return sWorld.getRegionizedEntities();
}
public World getWorld() {
return world;
}

49
Folia/pom.xml Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore-Modules</artifactId>
<version>2.6.22</version>
</parent>
<artifactId>Folia</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>SongodaCore-Compatibility</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,24 @@
package com.songoda;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
public class SchedulerTask {
private final Object task;
public SchedulerTask(Object task) {
this.task = task;
}
public Object getTask() {
return task;
}
public ScheduledTask getAsFoliaTask() {
return (ScheduledTask) task;
}
public int getAsBukkitTaskId() {
return (int) task;
}
}

View File

@ -0,0 +1,155 @@
package com.songoda;
import com.songoda.core.compatibility.ServerVersion;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.TimeUnit;
public class SchedulerUtils {
/**
* Run a task on an entity or fallback for Bukkit#runTask
*/
public static SchedulerTask runEntityTask(@NotNull Plugin plugin, @NotNull Entity entity, @NotNull Runnable runnable) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(runEntityTask(plugin, entity, runnable, 1));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
public static SchedulerTask runEntityTask(@NotNull Plugin plugin, @NotNull Entity entity, @NotNull Runnable runnable, long delay) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(entity.getScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), null, delay));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
//location task
public static SchedulerTask runLocationTask(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable runnable) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(runLocationTask(plugin, location, runnable, 1));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
public static SchedulerTask runEntityTask(@NotNull Plugin plugin, @NotNull Entity entity, @NotNull Runnable runnable, long delay, long period) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(entity.getScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), null, delay, period));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
/**
* Run a task on a location or fallback for Bukkit#runTask
* Delay is in ticks
*/
public static SchedulerTask runLocationTask(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable runnable, long delay) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getRegionScheduler().runDelayed(plugin, location, scheduledTask -> runnable.run(), delay));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
public static SchedulerTask runLocationTask(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable runnable, long delay, long period) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getRegionScheduler().runAtFixedRate(plugin, location, scheduledTask -> runnable.run(), delay, period));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
public static SchedulerTask runTask(@NotNull Plugin plugin, @NotNull Runnable runnable) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getGlobalRegionScheduler().run(plugin, scheduledTask -> runnable.run()));
}
return new SchedulerTask(Bukkit.getScheduler().runTask(plugin, runnable));
}
public static SchedulerTask runTaskAsynchronously(@NotNull Plugin plugin, @NotNull Runnable runnable) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getAsyncScheduler().runNow(plugin, scheduledTask -> runnable.run()));
}
return new SchedulerTask(Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable));
}
public static SchedulerTask runTaskLater(@NotNull Plugin plugin, @NotNull Runnable runnable, long delay) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), delay));
}
return new SchedulerTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
}
public static SchedulerTask runTaskLaterAsynchronously(@NotNull Plugin plugin, @NotNull Runnable runnable, long delay) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getAsyncScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), delay, TimeUnit.MILLISECONDS));
}
return new SchedulerTask(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, delay));
}
public static SchedulerTask scheduleSyncDelayedTask(@NotNull Plugin plugin, @NotNull Runnable runnable, long delay) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> runnable.run(), delay));
}
return new SchedulerTask(Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, runnable, delay));
}
public static SchedulerTask scheduleSyncRepeatingTask(@NotNull Plugin plugin, @NotNull Runnable runnable, long delay, long period) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, period));
}
return new SchedulerTask(Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, runnable, delay, period));
}
public static SchedulerTask runTaskTimer(@NotNull Plugin plugin, @NotNull Runnable runnable, long delay, long period) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, period));
}
return new SchedulerTask(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
}
public static SchedulerTask runTaskTimerAsynchronously(@NotNull Plugin plugin, @NotNull Runnable runnable, long delay, long period) {
if (ServerVersion.isFolia()) {
return new SchedulerTask(plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, scheduledTask -> runnable.run(), delay, period, TimeUnit.MILLISECONDS));
}
return new SchedulerTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, period));
}
public static void cancelTask(SchedulerTask task) {
if (ServerVersion.isFolia()) {
task.getAsFoliaTask().cancel();
} else {
Bukkit.getScheduler().cancelTask(task.getAsBukkitTaskId());
}
}
public static void cancelAllTasks(Plugin plugin) {
if (ServerVersion.isFolia()) {
Bukkit.getAsyncScheduler().cancelTasks(plugin);
Bukkit.getGlobalRegionScheduler().cancelTasks(plugin);
} else {
Bukkit.getScheduler().cancelTasks(plugin);
}
}
public static boolean isCurrentlyRunning(SchedulerTask task) {
if (ServerVersion.isFolia()) {
return task.getAsFoliaTask().getExecutionState() == ScheduledTask.ExecutionState.RUNNING;
} else {
return Bukkit.getScheduler().isCurrentlyRunning(task.getAsBukkitTaskId());
}
}
public static boolean isQueued(SchedulerTask task) {
if (ServerVersion.isFolia()) {
return task.getAsFoliaTask().getExecutionState() == ScheduledTask.ExecutionState.RUNNING;
} else {
return Bukkit.getScheduler().isQueued(task.getAsBukkitTaskId());
}
}
}

View File

@ -13,6 +13,13 @@
<artifactId>SongodaCore-NMS-API</artifactId>
<dependencies>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--suppress VulnerableLibrariesLocal -->
<dependency>
<groupId>org.spigotmc</groupId>

View File

@ -1,9 +1,13 @@
package com.songoda.core.nms.world;
import io.papermc.paper.threadedregions.scheduler.EntityScheduler;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import java.util.List;
import java.util.Map;
public interface SWorld {
List<LivingEntity> getLivingEntities();
@ -17,4 +21,8 @@ public interface SWorld {
// TODO: Check if FabledSkyBlock *really* needs this method and if it can be removed.
// Would make thinks less complicated and I kinda cannot imagine it being *that* much faster to be worth it?
void setBlockFast(int x, int y, int z, Material material);
default Map<EntityScheduler, List<LivingEntity>> getRegionizedEntities() {
throw new UnsupportedOperationException("This server version does not support threaded regions. Not a Folia server.");
}
}

View File

@ -0,0 +1,56 @@
package com.songoda.core.nms.v1_19_R2;
import com.songoda.core.nms.NmsImplementations;
import com.songoda.core.nms.anvil.AnvilCore;
import com.songoda.core.nms.entity.NMSPlayer;
import com.songoda.core.nms.nbt.NBTCore;
import com.songoda.core.nms.v1_19_R2.entity.NMSPlayerImpl;
import com.songoda.core.nms.v1_19_R2.nbt.NBTCoreImpl;
import com.songoda.core.nms.v1_19_R2.world.NmsWorldBorderImpl;
import com.songoda.core.nms.v1_19_R2.world.WorldCoreImpl;
import com.songoda.core.nms.world.NmsWorldBorder;
import com.songoda.core.nms.world.WorldCore;
import org.bukkit.craftbukkit.v1_19_R2.util.CraftMagicNumbers;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class NmsImplementationsImpl implements NmsImplementations {
private final NMSPlayer player;
private final WorldCore world;
private final NmsWorldBorder worldBorder;
private final AnvilCore anvil;
private final NBTCore nbt;
public NmsImplementationsImpl() {
this.player = new NMSPlayerImpl();
this.world = new WorldCoreImpl();
this.worldBorder = new NmsWorldBorderImpl();
this.anvil = new com.songoda.core.nms.v1_19_R2.anvil.AnvilCore();
this.nbt = new NBTCoreImpl();
}
@Override
public @NotNull NMSPlayer getPlayer() {
return this.player;
}
@Override
public @NotNull WorldCore getWorld() {
return this.world;
}
@Override
public @NotNull NmsWorldBorder getWorldBorder() {
return this.worldBorder;
}
@Override
public @NotNull AnvilCore getAnvil() {
return this.anvil;
}
@Override
public @NotNull NBTCore getNbt() {
return this.nbt;
}
}

View File

@ -0,0 +1,35 @@
package com.songoda.core.nms.v1_19_R2.world;
import com.songoda.core.nms.world.NmsWorldBorder;
import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket;
import net.minecraft.world.level.border.WorldBorder;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class NmsWorldBorderImpl implements NmsWorldBorder {
@Override
public void send(Player player, BorderColor color, double size, @NotNull Location center) {
Objects.requireNonNull(center.getWorld());
WorldBorder worldBorder = new WorldBorder();
worldBorder.world = ((CraftWorld) center.getWorld()).getHandle();
worldBorder.setCenter(center.getX(), center.getZ());
worldBorder.setSize(size);
worldBorder.setWarningTime(0);
worldBorder.setWarningBlocks(0);
if (color == BorderColor.GREEN) {
worldBorder.lerpSizeBetween(size - 0.1D, size, Long.MAX_VALUE);
} else if (color == BorderColor.RED) {
worldBorder.lerpSizeBetween(size, size - 1.0D, Long.MAX_VALUE);
}
((CraftPlayer) player).getHandle().connection.send(new ClientboundInitializeBorderPacket(worldBorder));
}
}

View File

@ -62,6 +62,13 @@
</build>
<dependencies>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--suppress VulnerableLibrariesLocal -->
<dependency>
<groupId>org.spigotmc</groupId>
@ -84,5 +91,12 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.7</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,56 @@
package com.songoda.core.nms.v1_19_R3;
import com.songoda.core.nms.NmsImplementations;
import com.songoda.core.nms.anvil.AnvilCore;
import com.songoda.core.nms.entity.NMSPlayer;
import com.songoda.core.nms.nbt.NBTCore;
import com.songoda.core.nms.v1_19_R3.entity.NMSPlayerImpl;
import com.songoda.core.nms.v1_19_R3.nbt.NBTCoreImpl;
import com.songoda.core.nms.v1_19_R3.world.NmsWorldBorderImpl;
import com.songoda.core.nms.v1_19_R3.world.WorldCoreImpl;
import com.songoda.core.nms.world.NmsWorldBorder;
import com.songoda.core.nms.world.WorldCore;
import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class NmsImplementationsImpl implements NmsImplementations {
private final NMSPlayer player;
private final WorldCore world;
private final NmsWorldBorder worldBorder;
private final AnvilCore anvil;
private final NBTCore nbt;
public NmsImplementationsImpl() {
this.player = new NMSPlayerImpl();
this.world = new WorldCoreImpl();
this.worldBorder = new NmsWorldBorderImpl();
this.anvil = new com.songoda.core.nms.v1_19_R3.anvil.AnvilCore();
this.nbt = new NBTCoreImpl();
}
@Override
public @NotNull NMSPlayer getPlayer() {
return this.player;
}
@Override
public @NotNull WorldCore getWorld() {
return this.world;
}
@Override
public @NotNull NmsWorldBorder getWorldBorder() {
return this.worldBorder;
}
@Override
public @NotNull AnvilCore getAnvil() {
return this.anvil;
}
@Override
public @NotNull NBTCore getNbt() {
return this.nbt;
}
}

View File

@ -0,0 +1,35 @@
package com.songoda.core.nms.v1_19_R3.world;
import com.songoda.core.nms.world.NmsWorldBorder;
import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket;
import net.minecraft.world.level.border.WorldBorder;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class NmsWorldBorderImpl implements NmsWorldBorder {
@Override
public void send(Player player, BorderColor color, double size, @NotNull Location center) {
Objects.requireNonNull(center.getWorld());
WorldBorder worldBorder = new WorldBorder();
worldBorder.world = ((CraftWorld) center.getWorld()).getHandle();
worldBorder.setCenter(center.getX(), center.getZ());
worldBorder.setSize(size);
worldBorder.setWarningTime(0);
worldBorder.setWarningBlocks(0);
if (color == BorderColor.GREEN) {
worldBorder.lerpSizeBetween(size - 0.1D, size, Long.MAX_VALUE);
} else if (color == BorderColor.RED) {
worldBorder.lerpSizeBetween(size, size - 1.0D, Long.MAX_VALUE);
}
((CraftPlayer) player).getHandle().connection.send(new ClientboundInitializeBorderPacket(worldBorder));
}
}

View File

@ -4,6 +4,7 @@ import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.CompatibleParticleHandler;
import com.songoda.core.nms.world.SSpawner;
import com.songoda.core.nms.world.SpawnedEntity;
import io.papermc.lib.PaperLib;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
@ -92,7 +93,7 @@ public class SSpawnerImpl implements SSpawner {
world.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER);
spot.setYaw(random.nextFloat() * 360.0F);
craftEntity.teleport(spot);
PaperLib.teleportAsync(craftEntity, spot);
return craftEntity;
}

View File

@ -1,20 +1,28 @@
package com.songoda.core.nms.v1_19_R3.world;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.world.SWorld;
import io.papermc.paper.threadedregions.scheduler.EntityScheduler;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.entity.LevelEntityGetter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData;
import org.bukkit.entity.LivingEntity;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SWorldImpl implements SWorld {
private final World world;
@ -49,4 +57,24 @@ public class SWorldImpl implements SWorld {
levelChunk.setBlockState(new BlockPos(x & 0xF, y, z & 0xF), blockState, true);
}
@Override
public Map<EntityScheduler, List<LivingEntity>> getRegionizedEntities() {
if (!ServerVersion.isFolia()) {
SWorld.super.getRegionizedEntities();
}
Map<EntityScheduler, List<LivingEntity>> result = new HashMap<>();
for (LivingEntity entity : getLivingEntities()) {
EntityScheduler scheduler = entity.getScheduler();
if (!result.containsKey(scheduler)) {
result.computeIfAbsent(scheduler, k -> new ArrayList<>(List.of(entity)));
}
result.get(scheduler).add(entity);
}
return result;
}
}

View File

@ -141,5 +141,11 @@
<groupId>${project.groupId}</groupId>
<scope>compile</scope>
</dependency>
<dependency>
<version>${project.version}</version>
<artifactId>SongodaCore-NMS-v1_19_R3</artifactId>
<groupId>${project.groupId}</groupId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -48,6 +48,7 @@
<module>NMS/NMS-v1_19_R1</module>
<module>NMS/NMS-v1_19_R2</module>
<module>NMS/NMS-v1_19_R3</module>
<module>Folia</module>
</modules>
<issueManagement>