1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2025-12-19 14:59:20 +00:00

Folia support

Co-Authored-By: Camotoy <20743703+Camotoy@users.noreply.github.com>
This commit is contained in:
Tim203
2023-03-31 13:14:37 -04:00
committed by Camotoy
parent f0a20aa967
commit 3c0e30bff7
9 changed files with 73 additions and 39 deletions

View File

@@ -28,7 +28,7 @@ object Versions {
const val cumulusVersion = "1.1.1" const val cumulusVersion = "1.1.1"
const val eventsVersion = "1.0-SNAPSHOT" const val eventsVersion = "1.0-SNAPSHOT"
const val configUtilsVersion = "1.0-SNAPSHOT" const val configUtilsVersion = "1.0-SNAPSHOT"
const val spigotVersion = "1.13-R0.1-SNAPSHOT" const val spigotVersion = "1.19.4-R0.1-SNAPSHOT"
const val fastutilVersion = "8.5.3" const val fastutilVersion = "8.5.3"
const val guiceVersion = "5.1.0" const val guiceVersion = "5.1.0"
const val nettyVersion = "4.1.49.Final" const val nettyVersion = "4.1.49.Final"

View File

@@ -4,7 +4,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {
// mavenLocal() mavenLocal()
// Geyser, Cumulus etc. // Geyser, Cumulus etc.
maven("https://repo.opencollab.dev/maven-releases") { maven("https://repo.opencollab.dev/maven-releases") {
@@ -21,13 +21,7 @@ dependencyResolutionManagement {
// maven("https://repo.papermc.io/repository/maven-snapshots") { // maven("https://repo.papermc.io/repository/maven-snapshots") {
// mavenContent { snapshotsOnly() } // mavenContent { snapshotsOnly() }
// } // }
maven("https://repo.papermc.io/repository/maven-public") { maven("https://repo.papermc.io/repository/maven-public")
content {
includeGroupByRegex(
"(io\\.papermc\\..*|com\\.destroystokyo\\..*|com\\.velocitypowered)"
)
}
}
// Spigot // Spigot
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") { maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") {
mavenContent { snapshotsOnly() } mavenContent { snapshotsOnly() }

View File

@@ -2,12 +2,26 @@ var authlibVersion = "1.5.21"
var guavaVersion = "21.0" var guavaVersion = "21.0"
var gsonVersion = "2.8.5" var gsonVersion = "2.8.5"
indra {
javaVersions {
// For Folia
target(8)
minimumToolchain(17)
}
}
dependencies { dependencies {
api(projects.core) api(projects.core)
implementation("cloud.commandframework", "cloud-bukkit", Versions.cloudVersion) implementation("cloud.commandframework", "cloud-bukkit", Versions.cloudVersion)
// hack to make pre 1.12 work // hack to make pre 1.12 work
implementation("com.google.guava", "guava", guavaVersion) implementation("com.google.guava", "guava", guavaVersion)
compileOnlyApi("dev.folia", "folia-api", Versions.spigotVersion) {
attributes {
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
}
}
} }
relocate("com.google.inject") relocate("com.google.inject")
@@ -21,7 +35,6 @@ relocate("com.google.guava")
relocate("it.unimi") relocate("it.unimi")
// these dependencies are already present on the platform // these dependencies are already present on the platform
provided("com.destroystokyo.paper", "paper-api", Versions.spigotVersion)
provided("com.mojang", "authlib", authlibVersion) provided("com.mojang", "authlib", authlibVersion)
provided("io.netty", "netty-transport", Versions.nettyVersion) provided("io.netty", "netty-transport", Versions.nettyVersion)
provided("io.netty", "netty-codec", Versions.nettyVersion) provided("io.netty", "netty-codec", Versions.nettyVersion)

View File

@@ -86,7 +86,7 @@ public final class SpigotPlatformModule extends AbstractModule {
SpigotVersionSpecificMethods versionSpecificMethods, SpigotVersionSpecificMethods versionSpecificMethods,
LanguageManager languageManager) { LanguageManager languageManager) {
return new SpigotCommandUtil( return new SpigotCommandUtil(
languageManager, plugin.getServer(), api, versionSpecificMethods, plugin); languageManager, plugin.getServer(), api, versionSpecificMethods);
} }
@Provides @Provides

View File

@@ -33,7 +33,6 @@ import com.mojang.authlib.properties.PropertyMap;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.floodgate.SpigotPlugin;
import org.geysermc.floodgate.api.event.skin.SkinApplyEvent; import org.geysermc.floodgate.api.event.skin.SkinApplyEvent;
import org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData; import org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.api.player.FloodgatePlayer;
@@ -48,7 +47,6 @@ import org.geysermc.floodgate.util.SpigotVersionSpecificMethods;
@Singleton @Singleton
public final class SpigotSkinApplier implements SkinApplier { public final class SpigotSkinApplier implements SkinApplier {
@Inject private SpigotVersionSpecificMethods versionSpecificMethods; @Inject private SpigotVersionSpecificMethods versionSpecificMethods;
@Inject private SpigotPlugin plugin;
@Inject private EventBus eventBus; @Inject private EventBus eventBus;
@Override @Override
@@ -62,8 +60,7 @@ public final class SpigotSkinApplier implements SkinApplier {
// player is probably not logged in yet // player is probably not logged in yet
if (player == null) { if (player == null) {
if (firstTry) { if (firstTry) {
Bukkit.getScheduler().runTaskLater( versionSpecificMethods.schedule(
plugin,
() -> applySkin0(floodgatePlayer, skinData, false), () -> applySkin0(floodgatePlayer, skinData, false),
10 * 20 10 * 20
); );
@@ -94,12 +91,10 @@ public final class SpigotSkinApplier implements SkinApplier {
replaceSkin(properties, event.newSkin()); replaceSkin(properties, event.newSkin());
// By running as a task, we don't run into async issues versionSpecificMethods.maybeSchedule(() -> {
plugin.getServer().getScheduler().runTask(plugin, () -> {
for (Player p : Bukkit.getOnlinePlayers()) { for (Player p : Bukkit.getOnlinePlayers()) {
if (!p.equals(player) && p.canSee(player)) { if (!p.equals(player) && p.canSee(player)) {
versionSpecificMethods.hidePlayer(p, player); versionSpecificMethods.hideAndShowPlayer(p, player);
versionSpecificMethods.showPlayer(p, player);
} }
} }
}); });

View File

@@ -78,6 +78,8 @@ public class ClassNames {
public static final Field BUNGEE; public static final Field BUNGEE;
public static final boolean IS_FOLIA;
static { static {
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
SPIGOT_MAPPING_PREFIX = "net.minecraft.server." + version; SPIGOT_MAPPING_PREFIX = "net.minecraft.server." + version;
@@ -223,6 +225,10 @@ public class ClassNames {
PAPER_VELOCITY_SUPPORT = null; PAPER_VELOCITY_SUPPORT = null;
} }
} }
IS_FOLIA = ReflectionUtils.getClass(
"io.papermc.paper.threadedregions.scheduler.EntityScheduler"
) != null;
} }
private static <T> T checkNotNull(@CheckForNull T toCheck, @CheckForNull String objectName) { private static <T> T checkNotNull(@CheckForNull T toCheck, @CheckForNull String objectName) {

View File

@@ -27,11 +27,9 @@ package org.geysermc.floodgate.util;
import java.util.Collection; import java.util.Collection;
import java.util.UUID; import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.platform.command.CommandUtil;
@@ -42,19 +40,17 @@ import org.geysermc.floodgate.player.UserAudience.PlayerAudience;
public final class SpigotCommandUtil extends CommandUtil { public final class SpigotCommandUtil extends CommandUtil {
private final Server server; private final Server server;
private final SpigotVersionSpecificMethods versionSpecificMethods; private final SpigotVersionSpecificMethods versionSpecificMethods;
private final JavaPlugin plugin;
private UserAudience console; private UserAudience console;
public SpigotCommandUtil( public SpigotCommandUtil(
LanguageManager manager, LanguageManager manager,
Server server, Server server,
FloodgateApi api, FloodgateApi api,
SpigotVersionSpecificMethods versionSpecificMethods, SpigotVersionSpecificMethods versionSpecificMethods
JavaPlugin plugin) { ) {
super(manager, api); super(manager, api);
this.server = server; this.server = server;
this.versionSpecificMethods = versionSpecificMethods; this.versionSpecificMethods = versionSpecificMethods;
this.plugin = plugin;
} }
@Override @Override
@@ -120,7 +116,7 @@ public final class SpigotCommandUtil extends CommandUtil {
public void kickPlayer(Object player, String message) { public void kickPlayer(Object player, String message) {
// can also be console // can also be console
if (player instanceof Player) { if (player instanceof Player) {
Bukkit.getScheduler().runTask(plugin, () -> ((Player) player).kickPlayer(message)); versionSpecificMethods.schedule(() -> ((Player) player).kickPlayer(message), 0);
} }
} }

View File

@@ -25,16 +25,21 @@
package org.geysermc.floodgate.util; package org.geysermc.floodgate.util;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.geysermc.floodgate.SpigotPlugin; import org.geysermc.floodgate.SpigotPlugin;
public final class SpigotVersionSpecificMethods { public final class SpigotVersionSpecificMethods {
private static final boolean NEW_GET_LOCALE; private static final Method GET_SPIGOT;
private static final Method OLD_GET_LOCALE;
private static final boolean NEW_VISIBILITY; private static final boolean NEW_VISIBILITY;
static { static {
NEW_GET_LOCALE = ReflectionUtils.getMethod(Player.class, "getLocale") != null; GET_SPIGOT = ReflectionUtils.getMethod(Player.class, "spigot");
OLD_GET_LOCALE = ReflectionUtils.getMethod(Player.Spigot.class, "getLocale");
NEW_VISIBILITY = null != ReflectionUtils.getMethod( NEW_VISIBILITY = null != ReflectionUtils.getMethod(
Player.class, "hidePlayer", Player.class, "hidePlayer",
Plugin.class, Player.class Plugin.class, Player.class
@@ -48,27 +53,51 @@ public final class SpigotVersionSpecificMethods {
} }
public String getLocale(Player player) { public String getLocale(Player player) {
if (NEW_GET_LOCALE) { if (OLD_GET_LOCALE == null) {
return player.getLocale(); return player.getLocale();
} }
return player.spigot().getLocale(); Object spigot = ReflectionUtils.invoke(player, GET_SPIGOT);
return ReflectionUtils.castedInvoke(spigot, OLD_GET_LOCALE);
}
public void hideAndShowPlayer(Player on, Player target) {
// In Folia we don't have to schedule this as there is no concept of a single main thread.
// Instead, we have to schedule the task per player.
if (ClassNames.IS_FOLIA) {
on.getScheduler().execute(plugin, () -> hideAndShowPlayer0(on, target), null, 0);
return;
}
hideAndShowPlayer0(on, target);
}
public void schedule(Runnable runnable, long delay) {
if (ClassNames.IS_FOLIA) {
plugin.getServer().getAsyncScheduler().runDelayed(
plugin, $ -> runnable.run(), delay * 50, TimeUnit.MILLISECONDS
);
return;
}
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, delay);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void hidePlayer(Player hideFor, Player playerToHide) { private void hideAndShowPlayer0(Player source, Player target) {
if (NEW_VISIBILITY) { if (NEW_VISIBILITY) {
hideFor.hidePlayer(plugin, playerToHide); source.hidePlayer(plugin, target);
source.showPlayer(plugin, target);
return; return;
} }
hideFor.hidePlayer(playerToHide); source.hidePlayer(target);
source.showPlayer(target);
} }
@SuppressWarnings("deprecation") public void maybeSchedule(Runnable runnable) {
public void showPlayer(Player showFor, Player playerToShow) { // In Folia we don't have to schedule this as there is no concept of a single main thread.
if (NEW_VISIBILITY) { // Instead, we have to schedule the task per player.
showFor.showPlayer(plugin, playerToShow); if (ClassNames.IS_FOLIA) {
runnable.run();
return; return;
} }
showFor.showPlayer(playerToShow); plugin.getServer().getScheduler().runTask(plugin, runnable);
} }
} }

View File

@@ -5,3 +5,4 @@ author: ${author}
website: ${url} website: ${url}
main: org.geysermc.floodgate.SpigotPlugin main: org.geysermc.floodgate.SpigotPlugin
api-version: 1.13 api-version: 1.13
folia-supported: true