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

Implement Folia Support #2682

Draft
wants to merge 26 commits into
base: v3
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a31f2f3
History: Read change positions at once (#2542)
SirYwell Jan 25, 2024
0264ba3
Merge branch 'main' into v3
dordsor21 Mar 15, 2024
472eb19
Allow repeated keys in RandomCollection (#2624)
SirYwell Mar 16, 2024
fb12ff2
refactor: apply final/abstract to various fawe extent classes (#2615)
dordsor21 Mar 16, 2024
fbb8a9b
Merge branch 'main' into v3
dordsor21 Mar 27, 2024
0faaaa5
Initial experimental work on Folia support
SirYwell Mar 7, 2023
00b1339
Improve block tracing performance
SirYwell Mar 8, 2023
c0653d0
Throw exception if player is retired to ensure task always finishes
SirYwell Mar 9, 2023
c9f8a87
Add folia support
TheMeinerLP Mar 30, 2023
7d264aa
Add run folia task
TheMeinerLP Apr 2, 2023
5769912
Add runFolia with snapshot version of run paper
TheMeinerLP Apr 2, 2023
82f3cea
Add multi folia run task support
TheMeinerLP Jun 18, 2023
54a96bc
drop 1.19 folia support
SirYwell Aug 20, 2023
fca4ab4
tmp
SirYwell Aug 21, 2023
441c2d4
Fix compilation
SirYwell Oct 29, 2023
17b7a2c
compact run-task configuration
SirYwell Oct 29, 2023
d64b0d9
Fix some folia incompatibilities
SirYwell Oct 29, 2023
fbe69bd
rebase fixes
SirYwell Dec 11, 2023
c0903e7
align adapters
SirYwell Dec 17, 2023
0bee4a6
fix some bugs/todos
SirYwell Jan 2, 2024
ac83bb5
tmp
SirYwell Jan 6, 2024
4608c8e
mark folia todos
SirYwell Jan 27, 2024
20ff871
resolve some simple todos
SirYwell Jan 27, 2024
8feb6d7
block entity access has to be synchronously
SirYwell Feb 1, 2024
29b0669
fixes
SirYwell Apr 1, 2024
09541db
static handle
SirYwell Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import org.ajoberstar.grgit.Grgit
import org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
import org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED
import org.gradle.configurationcache.extensions.capitalized
import xyz.jpenilla.runpaper.task.RunServer
import java.net.URI
import java.time.format.DateTimeFormatter
import xyz.jpenilla.runpaper.task.RunServer

plugins {
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
Expand Down Expand Up @@ -84,24 +85,33 @@ allprojects {

applyCommonConfiguration()
val supportedVersions = listOf("1.18.2", "1.19.4", "1.20", "1.20.4")
val foliaSupportedVersions = listOf("1.20.4")

tasks {
supportedVersions.forEach {
register<RunServer>("runServer-$it") {
minecraftVersion(it)
pluginJars(*project(":worldedit-bukkit").getTasksByName("shadowJar", false).map { (it as Jar).archiveFile }
fun registerVersion(version: String, software: String, task: RunServer.() -> Unit = {}) {
register<RunServer>("run${software.capitalized()}-$version") {
minecraftVersion(version)
pluginJars(*project(":worldedit-bukkit").getTasksByName("shadowJar", false)
.map { (it as Jar).archiveFile }
.toTypedArray())
jvmArgs("-DPaper.IgnoreJavaVersion=true", "-Dcom.mojang.eula.agree=true")
group = "run paper"
runDirectory.set(file("run-$it"))
group = "run $software"
runDirectory.set(file("run-$software-$version"))
task(this)
}
}
runServer {
minecraftVersion("1.20.4")
pluginJars(*project(":worldedit-bukkit").getTasksByName("shadowJar", false).map { (it as Jar).archiveFile }
.toTypedArray())

registerVersion("1.20.4", "paper")
}
supportedVersions.forEach {
registerVersion(it, "paper")
}
foliaSupportedVersions.forEach {
registerVersion(it, "folia") {
downloadsApiService.set(xyz.jpenilla.runtask.service.DownloadsAPIService.folia(project))
}
}

}

nexusPublishing {
Expand Down
9 changes: 9 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,14 @@ dependencyResolutionManagement {
}
}
}
pluginManagement {
repositories {
gradlePluginPortal()
maven {
name = "jmp repository"
url = uri("https://repo.jpenilla.xyz/snapshots")
}
}
}

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public synchronized net.minecraft.world.level.block.state.BlockState setBlockSta
net.minecraft.world.level.block.state.BlockState blockState
) {
int currentTick = MinecraftServer.currentTick;
if (Fawe.isMainThread()) {
if (Fawe.isTickThread()) {
return levelChunk.setBlockState(blockPos, blockState,
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE)
);
Expand Down Expand Up @@ -250,7 +250,8 @@ public void run(Object value) {
}
}
};
TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal));
// we don't support Folia on that version, we can run this globally
TaskManager.taskManager().async(() -> TaskManager.taskManager().syncGlobal(runnableVal));
}

@Override
Expand All @@ -266,10 +267,11 @@ public void run(Object value) {
}
}
};
if (Fawe.isMainThread()) {
if (Fawe.isTickThread()) {
runnableVal.run();
} else {
TaskManager.taskManager().sync(runnableVal);
// we don't support Folia on that version, we can run this globally
TaskManager.taskManager().syncGlobal(runnableVal);
}
cachedChanges.clear();
cachedChunksToSend.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.fastasyncworldedit.core.util.ReflectionUtils;
import com.fastasyncworldedit.core.util.TaskManager;
import com.mojang.datafixers.util.Either;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
Expand Down Expand Up @@ -246,7 +247,7 @@ public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int c
} catch (TimeoutException e) {
String world = serverLevel.getWorld().getName();
// We've already taken 10 seconds we can afford to wait a little here.
boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null);
boolean loaded = TaskManager.taskManager().syncGlobal(() -> Bukkit.getWorld(world) != null);
if (loaded) {
LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world);
// Retry chunk load
Expand All @@ -260,7 +261,8 @@ public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int c
e.printStackTrace();
}
}
return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ));
return TaskManager.taskManager().syncAt(() -> serverLevel.getChunk(chunkX, chunkZ),
BukkitAdapter.adapt(serverLevel.getWorld()), chunkX, chunkZ);
}

private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) {
Expand Down Expand Up @@ -300,7 +302,7 @@ public static void sendChunk(ServerLevel nmsWorld, int chunkX, int chunkZ, boole
return;
}
LevelChunk levelChunk = optional.get();
TaskManager.taskManager().task(() -> {
PaperweightPlatformAdapter.task(() -> {
ClientboundLevelChunkWithLightPacket packet;
if (PaperLib.isPaper()) {
packet = new ClientboundLevelChunkWithLightPacket(
Expand All @@ -322,7 +324,7 @@ public static void sendChunk(ServerLevel nmsWorld, int chunkX, int chunkZ, boole
);
}
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
});
}, nmsWorld, chunkX, chunkZ);
}

private static List<ServerPlayer> nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) {
Expand Down Expand Up @@ -625,6 +627,10 @@ public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTa
}
}

public static void task(Runnable task, ServerLevel level, int chunkX, int chunkZ) {
TaskManager.taskManager().task(task, BukkitAdapter.adapt(level.getWorld()), chunkX, chunkZ);
}

record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@ protected void invokeRelight(
protected void postProcessChunks(Set<ChunkPos> coords) {
boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING;
for (ChunkPos pos : coords) {
int x = pos.x;
int z = pos.z;
if (delay) { // we still need to send the block changes of that chunk
PaperweightPlatformAdapter.sendChunk(serverLevel, x, z, false);
}
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
PaperweightPlatformAdapter.task(
() -> {
int x = pos.x;
int z = pos.z;
if (delay) { // we still need to send the block changes of that chunk
PaperweightPlatformAdapter.sendChunk(serverLevel, x, z, false);
}
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
},
serverLevel,
pos.x,
pos.z
);

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Lifecycle;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightGetBlocks;
Expand Down Expand Up @@ -411,7 +412,12 @@ protected List<BlockPopulator> getBlockPopulators() {
@Override
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
// BlockPopulator#populate has to be called synchronously for TileEntity access
TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()));
TaskManager.taskManager().task(
() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()),
BukkitAdapter.adapt(originalBukkitWorld),
levelChunk.getPos().x,
levelChunk.getPos().z
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public synchronized net.minecraft.world.level.block.state.BlockState setBlockSta
net.minecraft.world.level.block.state.BlockState blockState
) {
int currentTick = MinecraftServer.currentTick;
if (Fawe.isMainThread()) {
if (Fawe.isTickThread()) {
return levelChunk.setBlockState(blockPos, blockState,
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE)
);
Expand Down Expand Up @@ -250,7 +250,8 @@ public void run(Object value) {
}
}
};
TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal));
// we don't support Folia on that version, we can run this globally
TaskManager.taskManager().async(() -> TaskManager.taskManager().syncGlobal(runnableVal));
}

@Override
Expand All @@ -266,10 +267,11 @@ public void run(Object value) {
}
}
};
if (Fawe.isMainThread()) {
if (Fawe.isTickThread()) {
runnableVal.run();
} else {
TaskManager.taskManager().sync(runnableVal);
// we don't support Folia on that version, we can run this globally
TaskManager.taskManager().syncGlobal(runnableVal);
}
cachedChanges.clear();
cachedChunksToSend.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.fastasyncworldedit.core.util.ReflectionUtils;
import com.fastasyncworldedit.core.util.TaskManager;
import com.mojang.datafixers.util.Either;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
Expand Down Expand Up @@ -59,7 +60,6 @@
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_19_R3.CraftChunk;
import sun.misc.Unsafe;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -283,7 +283,7 @@ public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int c
} catch (TimeoutException e) {
String world = serverLevel.getWorld().getName();
// We've already taken 10 seconds we can afford to wait a little here.
boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null);
boolean loaded = TaskManager.taskManager().syncGlobal(() -> Bukkit.getWorld(world) != null);
if (loaded) {
LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world);
// Retry chunk load
Expand All @@ -298,7 +298,12 @@ public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int c
e.printStackTrace();
}
}
return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ));
return TaskManager.taskManager().syncAt(
() -> serverLevel.getChunk(chunkX, chunkZ),
BukkitAdapter.adapt(serverLevel.getWorld()),
chunkX,
chunkZ
);
}

private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) {
Expand Down Expand Up @@ -361,7 +366,7 @@ public static void sendChunk(ServerLevel nmsWorld, int chunkX, int chunkZ, boole
);
}
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
});
}, BukkitAdapter.adapt(nmsWorld.getWorld()), chunkX, chunkZ);
}

private static List<ServerPlayer> nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) {
Expand Down Expand Up @@ -687,6 +692,10 @@ public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTa
}
}

public static void task(Runnable task, ServerLevel level, int chunkX, int chunkZ) {
TaskManager.taskManager().task(task, BukkitAdapter.adapt(level.getWorld()), chunkX, chunkZ);
}

record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@ protected void invokeRelight(
protected void postProcessChunks(Set<ChunkPos> coords) {
boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING;
for (ChunkPos pos : coords) {
int x = pos.x;
int z = pos.z;
if (delay) { // we still need to send the block changes of that chunk
PaperweightPlatformAdapter.sendChunk(serverLevel, x, z, false);
}
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
PaperweightPlatformAdapter.task(
() -> {
int x = pos.x;
int z = pos.z;
if (delay) { // we still need to send the block changes of that chunk
PaperweightPlatformAdapter.sendChunk(serverLevel, x, z, false);
}
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
},
serverLevel,
pos.x,
pos.z
);

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Lifecycle;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.PaperweightGetBlocks;
Expand Down Expand Up @@ -442,7 +443,7 @@ protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blo
final CraftWorld world = freshWorld.getWorld();
final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ);
blockPopulator.populate(world, random, chunk);
});
}, BukkitAdapter.adapt(originalBukkitWorld), levelChunk.getPos().x, levelChunk.getPos().z);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
import com.fastasyncworldedit.core.queue.IBatchProcessor;
import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket;
import com.fastasyncworldedit.core.util.NbtUtils;
import com.fastasyncworldedit.core.util.TaskManager;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand Down
Loading
Loading