Begin hard fork

This commit is contained in:
Spottedleaf 2025-01-11 05:26:16 -08:00
parent 8af1aef1f1
commit 838465ab24
58 changed files with 7586 additions and 7647 deletions

View File

@ -1,6 +0,0 @@
[*.java]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=4

11
.gitattributes vendored
View File

@ -1,7 +1,12 @@
* text=auto #
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew text eol=lf
*.sh text eol=lf # These are Windows script files and should use crlf
gradlew text eol=lf
*.bat text eol=crlf *.bat text eol=crlf
# Binary files should be left untouched
*.jar binary *.jar binary

View File

@ -13,18 +13,16 @@ jobs:
steps: steps:
- name: Checkout Git Repository - name: Checkout Git Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v4
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '21' java-version: '21'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Configure Git User Details - name: Configure Git User Details
run: git config --global user.email "actions@github.com" && git config --global user.name "Github Actions" run: git config --global user.email "actions@github.com" && git config --global user.name "Github Actions"
- name: Apply Patches - name: Apply Patches
run: ./gradlew applyPatches run: ./gradlew applyAllPatches --stacktrace
- name: Build - name: Build
run: ./gradlew build run: ./gradlew build

59
.gitignore vendored
View File

@ -1,53 +1,16 @@
.gradle/ # Ignore Gradle project-specific cache directory
build/ .gradle
# Eclipse stuff # Ignore Gradle build output directory
.classpath build
.project
.settings/
# VSCode stuff /run
.vscode/
# netbeans /folia-server/build.gradle.kts
nbproject/ /folia-server/src/minecraft
nbactions.xml /paper-server
/folia-api/build.gradle.kts
/paper-api
/paper-api-generator
# we use maven!
build.xml
# maven
target/
dependency-reduced-pom.xml
# vim
.*.sw[a-p]
# various other potential build files
build/
bin/
dist/
manifest.mf
# Mac filesystem dust
.DS_Store/
.DS_Store
# intellij
*.iml
*.ipr
*.iws
.idea/ .idea/
out/
# Linux temp files
*~
# other stuff
run/
Folia-Server
Folia-API
paper-api-generator
!gradle/wrapper/gradle-wrapper.jar

View File

@ -8,3 +8,7 @@
# To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId: # To import classes from the vanilla Minecraft jar use `minecraft` as the artifactId:
# minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter # minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter
# minecraft net/minecraft/world/level/entity/LevelEntityGetter.java # minecraft net/minecraft/world/level/entity/LevelEntityGetter.java
# To import minecraft data files, like the default chat type, use `mc_data` as the prefix:
# mc_data chat_type/chat.json
# mc_data dimension_type/overworld.json
#

3
build-data/fork.at Normal file
View File

@ -0,0 +1,3 @@
# This file is auto generated, any changes may be overridden!
# See CONTRIBUTING.md on how to add access transformers.
public net.minecraft.data.registries.TradeRebalanceRegistries BUILDER

View File

@ -1,18 +0,0 @@
# We would like for paperweight to generate 100% perfect reobf mappings (and deobf mappings for that matter).
# But unfortunately it's not quite there yet - and it may be some time before that happens. Generating perfect mappings
# from Spigot's mappings is extremely difficult due to Spigot's bad tooling and bad mappings. To add insult to injury
# we remap Spigot's _source code_ which is a lot more complex and error-prone than bytecode remapping. So with all that
# said, this file exists to help fill in the gap.
#
# We will continue to improve paperweight and will work on fixing these issues so they don't come up in the first place,
# but these mappings exist to prevent these issues from holding everything else in Paper up while we work through all
# of these issues. Due to the complex nature of mappings generation and the debugging difficulty involved it may take
# a significant amount of time for us to track down every possible issue, so this file will likely be around and in
# use - at least in some capacity - for a long time.
#
# If you are adding mappings patches which are correcting for issues in paperweight's reobf mappings generation,
# unrelated to any changes in your patches, we ask that you PR the mapping to Paper so more users can benefit rather
# than keep the fix for your own fork. If the mappings patch is there to correct reobf for changes made in your patches,
# then obviously it doesn't make any sense to PR them upstream.
tiny 2 0 mojang+yarn spigot

View File

@ -1,41 +1,68 @@
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import io.papermc.paperweight.tasks.RebuildGitPatches import io.papermc.paperweight.tasks.RebuildGitPatches
plugins { plugins {
java java // TODO java launcher tasks
`maven-publish` id("io.papermc.paperweight.patcher") version "2.0.0-beta.13"
id("io.papermc.paperweight.patcher") version "1.7.7" }
paperweight {
upstreams.paper {
ref = providers.gradleProperty("paperRef")
patchFile {
path = "paper-server/build.gradle.kts"
outputFile = file("folia-server/build.gradle.kts")
patchFile = file("folia-server/build.gradle.kts.patch")
}
patchFile {
path = "paper-api/build.gradle.kts"
outputFile = file("folia-api/build.gradle.kts")
patchFile = file("folia-api/build.gradle.kts.patch")
}
patchDir("paperApi") {
upstreamPath = "paper-api"
excludes = setOf("build.gradle.kts")
patchesDir = file("folia-api/paper-patches")
outputDir = file("paper-api")
}
patchDir("paperApiGenerator") {
upstreamPath = "paper-api-generator"
patchesDir = file("folia-api-generator/paper-patches")
outputDir = file("paper-api-generator")
}
}
} }
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
subprojects {
apply(plugin = "java-library")
apply(plugin = "maven-publish")
extensions.configure<JavaPluginExtension> {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories { repositories {
mavenCentral() mavenCentral()
maven(paperMavenPublicUrl) { maven(paperMavenPublicUrl)
content { onlyForConfigurations(configurations.paperclip.name) }
}
} }
dependencies { dependencies {
remapper("net.fabricmc:tiny-remapper:0.10.3:fat") "testRuntimeOnly"("org.junit.platform:junit-platform-launcher")
decompiler("org.vineflower:vineflower:1.10.1")
paperclip("io.papermc:paperclip:3.0.3")
} }
allprojects { tasks.withType<AbstractArchiveTask>().configureEach {
apply(plugin = "java") isPreserveFileTimestamps = false
apply(plugin = "maven-publish") isReproducibleFileOrder = true
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
} }
}
}
subprojects {
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
options.encoding = Charsets.UTF_8.name() options.encoding = Charsets.UTF_8.name()
options.release.set(21) options.release = 21
options.isFork = true options.isFork = true
} }
tasks.withType<Javadoc> { tasks.withType<Javadoc> {
@ -44,61 +71,22 @@ subprojects {
tasks.withType<ProcessResources> { tasks.withType<ProcessResources> {
filteringCharset = Charsets.UTF_8.name() filteringCharset = Charsets.UTF_8.name()
} }
tasks.withType<Test> {
testLogging {
showStackTraces = true
exceptionFormat = TestExceptionFormat.FULL
events(TestLogEvent.STANDARD_OUT)
}
}
extensions.configure<PublishingExtension> {
repositories { repositories {
mavenCentral() /*
maven(paperMavenPublicUrl)
}
}
paperweight {
serverProject.set(project(":folia-server"))
remapRepo.set(paperMavenPublicUrl)
decompileRepo.set(paperMavenPublicUrl)
usePaperUpstream(providers.gradleProperty("paperRef")) {
withPaperPatcher {
apiPatchDir.set(layout.projectDirectory.dir("patches/api"))
apiOutputDir.set(layout.projectDirectory.dir("Folia-API"))
serverPatchDir.set(layout.projectDirectory.dir("patches/server"))
serverOutputDir.set(layout.projectDirectory.dir("Folia-Server"))
}
patchTasks.register("generatedApi") {
isBareDirectory = true
upstreamDirPath = "paper-api-generator/generated"
patchDir = layout.projectDirectory.dir("patches/generatedApi")
outputDir = layout.projectDirectory.dir("paper-api-generator/generated")
}
}
}
tasks.generateDevelopmentBundle {
apiCoordinates.set("dev.folia:folia-api")
libraryRepositories.addAll(
"https://repo.maven.apache.org/maven2/",
paperMavenPublicUrl,
)
}
allprojects {
publishing {
repositories {
maven("https://repo.papermc.io/repository/maven-snapshots/") { maven("https://repo.papermc.io/repository/maven-snapshots/") {
name = "paperSnapshots" name = "paperSnapshots"
credentials(PasswordCredentials::class) credentials(PasswordCredentials::class)
} }
} */
}
}
publishing {
if (project.hasProperty("publishDevBundle")) {
publications.create<MavenPublication>("devBundle") {
artifact(tasks.generateDevelopmentBundle) {
artifactId = "dev-bundle"
}
} }
} }
} }

View File

@ -0,0 +1,44 @@
--- a/paper-api/build.gradle.kts
+++ b/paper-api/build.gradle.kts
@@ -103,6 +_,18 @@
main {
java {
srcDir(generatedApiPath)
+ srcDir(file("../paper-api/src/main/java"))
+ }
+ resources {
+ srcDir(file("../paper-api/src/main/resources"))
+ }
+ }
+ test {
+ java {
+ srcDir(file("../paper-api/src/test/java"))
+ }
+ resources {
+ srcDir(file("../paper-api/src/test/resources"))
}
}
}
@@ -169,7 +_,7 @@
tasks.withType<Javadoc> {
val options = options as StandardJavadocDocletOptions
- options.overview = "src/main/javadoc/overview.html"
+ options.overview = "../paper-api/src/main/javadoc/overview.html"
options.use()
options.isDocFilesSubDirs = true
options.links(
@@ -202,11 +_,11 @@
}
// workaround for https://github.com/gradle/gradle/issues/4046
- inputs.dir("src/main/javadoc").withPropertyName("javadoc-sourceset")
+ inputs.dir("../paper-api/src/main/javadoc").withPropertyName("javadoc-sourceset")
val fsOps = services.fileSystemOperations
doLast {
fsOps.copy {
- from("src/main/javadoc") {
+ from("../paper-api/src/main/javadoc") {
include("**/doc-files/**")
}
into("build/docs/javadoc")

View File

@ -0,0 +1,26 @@
package io.papermc.paper.threadedregions;
import org.bukkit.event.HandlerList;
import org.bukkit.event.server.ServerEvent;
import org.jetbrains.annotations.NotNull;
/**
* This event is called after the server is initialised but <b>before</b> the server begins ticking regions in parallel.
* Plugins may use this as a hook to run post initialisation logic without worrying about the possibility that
* regions are ticking in parallel.
*/
public class RegionizedServerInitEvent extends ServerEvent {
private static final HandlerList handlers = new HandlerList();
@NotNull
@Override
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,73 @@
--- a/paper-server/build.gradle.kts
+++ b/paper-server/build.gradle.kts
@@ -21,8 +_,19 @@
// macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java")
// gitFilePatches = true
+ val fork = forks.register("folia") {
+ upstream.patchDir("paperServer") {
+ upstreamPath = "paper-server"
+ excludes = setOf("src/minecraft", "patches", "build.gradle.kts")
+ patchesDir = rootDirectory.dir("folia-server/paper-patches")
+ outputDir = rootDirectory.dir("paper-server")
+ }
+ }
+
+ activeFork = fork
+
paper {
- reobfMappingsPatch = layout.projectDirectory.file("../build-data/reobf-mappings-patch.tiny")
+ paperServerDir = upstreamsDirectory().map { it.dir("paper/paper-server") }
}
spigot {
@@ -105,7 +_,20 @@
}
}
-val log4jPlugins = sourceSets.create("log4jPlugins")
+sourceSets {
+ main {
+ java { srcDir("../paper-server/src/main/java") }
+ resources { srcDir("../paper-server/src/main/resources") }
+ }
+ test {
+ java { srcDir("../paper-server/src/test/java") }
+ resources { srcDir("../paper-server/src/test/resources") }
+ }
+}
+
+val log4jPlugins = sourceSets.create("log4jPlugins") {
+ java { srcDir("../paper-server/src/log4jPlugins/java") }
+}
configurations.named(log4jPlugins.compileClasspathConfigurationName) {
extendsFrom(configurations.compileClasspath.get())
}
@@ -123,7 +_,7 @@
}
dependencies {
- implementation(project(":paper-api"))
+ implementation(project(":folia-api"))
implementation("ca.spottedleaf:concurrentutil:0.0.2")
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
@@ -192,14 +_,14 @@
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
- "Implementation-Title" to "Paper",
+ "Implementation-Title" to "Folia", // Folia
"Implementation-Version" to implementationVersion,
"Implementation-Vendor" to date,
- "Specification-Title" to "Paper",
+ "Specification-Title" to "Folia", // Folia
"Specification-Version" to project.version,
"Specification-Vendor" to "Paper Team",
- "Brand-Id" to "papermc:paper",
- "Brand-Name" to "Paper",
+ "Brand-Id" to "papermc:folia", // Folia
+ "Brand-Name" to "Folia", // Folia
"Build-Number" to (build ?: ""),
"Build-Time" to buildTime.toString(),
"Git-Branch" to gitBranch,

View File

@ -5,24 +5,24 @@ Subject: [PATCH] Max pending logins
Should help the floodgates on launch Should help the floodgates on launch
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 7fdb9304de7cf1979d57e3fac32415d7c674609d..227d62a69a453d49c28568ecb41ecef85a35405b 100644 index 6173f704b0d093813ec67eb231c75be49a462e7d..159f2f169d26b436a70006f7bc9bdc481315dd32 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java --- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -117,7 +117,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -117,7 +117,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
if (this.server.getPlayerList().pushPendingJoin(name, uniqueId, this.connection)) { if (this.server.getPlayerList().pushPendingJoin(name, uniqueId, this.connection)) {
// Folia end - region threading - rewrite login process // Folia end - region threading - rewrite login process
this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile)); this.verifyLoginAndFinishConnectionSetup(Objects.requireNonNull(this.authenticatedProfile));
- } // Paper - prevent logins to be processed even though disconnect was called - } // Paper - prevent logins to be processed even though disconnect was called
+ } else { --this.tick; } // Paper - prevent logins to be processed even though disconnect was called // Folia - max concurrent logins + } else { --this.tick; } // Paper - prevent logins to be processed even though disconnect was called // Folia - max concurrent logins
} }
// CraftBukkit start // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index b449de44b1911e2ff0701956bfba53fb5d2ed44e..c1574cdea90731dec4d24b15979209cce0c581af 100644 index 65835fa09cdcd3bb158025f7d8b3cb29ac8b2549..bcfe3af0b0df25d4b308b11a64c361da1ab3eeca 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java
@@ -175,6 +175,17 @@ public abstract class PlayerList { @@ -151,6 +151,17 @@ public abstract class PlayerList {
conflictingId = this.connectionById.get(byId); conflictingId = this.connectionById.get(byId);
if (conflictingName == null && conflictingId == null) { if (conflictingName == null && conflictingId == null) {

View File

@ -4,10 +4,10 @@ Date: Fri, 10 Mar 2023 00:16:26 -0800
Subject: [PATCH] Add chunk system throughput counters to /tps Subject: [PATCH] Add chunk system throughput counters to /tps
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java
index 6ab353b0d2465c3680bb3c8d0852ba0f65c00fd2..4ad647a9f98cf1c11c45f85edcba3c29e343c236 100644 index 6ab353b0d2465c3680bb3c8d0852ba0f65c00fd2..4ad647a9f98cf1c11c45f85edcba3c29e343c236 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java
@@ -30,6 +30,9 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl @@ -30,6 +30,9 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl
private final ChunkAccess fromChunk; private final ChunkAccess fromChunk;
private final PrioritisedExecutor.PrioritisedTask convertToFullTask; private final PrioritisedExecutor.PrioritisedTask convertToFullTask;
@ -57,10 +57,10 @@ index 6ab353b0d2465c3680bb3c8d0852ba0f65c00fd2..4ad647a9f98cf1c11c45f85edcba3c29
if (this.fromChunk instanceof ImposterProtoChunk wrappedFull) { if (this.fromChunk instanceof ImposterProtoChunk wrappedFull) {
chunk = wrappedFull.getWrapped(); chunk = wrappedFull.getWrapped();
} else { } else {
diff --git a/src/main/java/io/papermc/paper/threadedregions/commands/CommandServerHealth.java b/src/main/java/io/papermc/paper/threadedregions/commands/CommandServerHealth.java diff --git a/io/papermc/paper/threadedregions/commands/CommandServerHealth.java b/io/papermc/paper/threadedregions/commands/CommandServerHealth.java
index 3bcb1dc98c61e025874cc9e008faa722581a530c..012d3a7da7fe483393a0888c823bd2e78f5c3908 100644 index 3bcb1dc98c61e025874cc9e008faa722581a530c..012d3a7da7fe483393a0888c823bd2e78f5c3908 100644
--- a/src/main/java/io/papermc/paper/threadedregions/commands/CommandServerHealth.java --- a/io/papermc/paper/threadedregions/commands/CommandServerHealth.java
+++ b/src/main/java/io/papermc/paper/threadedregions/commands/CommandServerHealth.java +++ b/io/papermc/paper/threadedregions/commands/CommandServerHealth.java
@@ -170,6 +170,9 @@ public final class CommandServerHealth extends Command { @@ -170,6 +170,9 @@ public final class CommandServerHealth extends Command {
totalUtil += (report == null ? 0.0 : report.utilisation()); totalUtil += (report == null ? 0.0 : report.utilisation());
} }

View File

@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 19 Mar 2023 14:35:46 -0700
Subject: [PATCH] Make CraftEntity#getHandle and overrides perform thread
checks
While these checks are painful, it should assist in debugging
threading issues for plugins.
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index dbe049c164657ae352f4dadfa673a07dbef2054d..7d5368330870aca9d14ff43296d64c8db6a3e89b 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -3050,6 +3050,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
if (force || this.canRide(vehicle) && vehicle.canAddPassenger(this)) {
+ if (this.valid) { // Folia - region threading - suppress entire event logic during worldgen
// CraftBukkit start
if (vehicle.getBukkitEntity() instanceof org.bukkit.entity.Vehicle && this.getBukkitEntity() instanceof org.bukkit.entity.LivingEntity) {
org.bukkit.event.vehicle.VehicleEnterEvent event = new org.bukkit.event.vehicle.VehicleEnterEvent((org.bukkit.entity.Vehicle) vehicle.getBukkitEntity(), this.getBukkitEntity());
@@ -3071,6 +3072,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return false;
}
// CraftBukkit end
+ } // Folia - region threading - suppress entire event logic during worldgen
if (this.isPassenger()) {
this.stopRiding();
}
@@ -3152,6 +3154,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
} else {
// CraftBukkit start
+ if (this.valid) { // Folia - region threading - suppress entire event logic during worldgen
org.bukkit.craftbukkit.entity.CraftEntity craft = (org.bukkit.craftbukkit.entity.CraftEntity) passenger.getBukkitEntity().getVehicle();
Entity orig = craft == null ? null : craft.getHandle();
if (this.getBukkitEntity() instanceof org.bukkit.entity.Vehicle && passenger.getBukkitEntity() instanceof org.bukkit.entity.LivingEntity) {
@@ -3179,6 +3182,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return false;
}
// CraftBukkit end
+ } // Folia - region threading - suppress entire event logic during worldgen
if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) {
this.passengers = ImmutableList.of();
} else {

View File

@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 17 Apr 2023 19:47:57 -0700
Subject: [PATCH] Prevent block updates in non-loaded or non-owned chunks
This is to prevent block physics from tripping thread checks by
far exceeding the bounds of the current region. While this does
add explicit block update suppression techniques, it's better
than the server crashing.
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index d36b5ad7b386391e617895a33b919e29266220e2..e16a824488d2b43c430f12b8416fdeb590e66d28 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -2053,7 +2053,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public void updateNeighbourForOutputSignal(BlockPos pos, Block block) {
for (Direction direction : Direction.Plane.HORIZONTAL) {
BlockPos blockPos = pos.relative(direction);
- if (this.hasChunkAt(blockPos)) {
+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this, blockPos, 16) && this.hasChunkAt(blockPos)) { // Folia - block updates in unloaded chunks
BlockState blockState = this.getBlockState(blockPos);
if (blockState.is(Blocks.COMPARATOR)) {
this.neighborChanged(blockState, blockPos, block, null, false);
diff --git a/net/minecraft/world/level/block/DetectorRailBlock.java b/net/minecraft/world/level/block/DetectorRailBlock.java
index 8f0217f25a2faf23833be10c85c5febc896ae292..6994a95e846a19525da1360c33f858ed29b64193 100644
--- a/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -133,8 +133,8 @@ public class DetectorRailBlock extends BaseRailBlock {
RailState railState = new RailState(level, pos, state);
for (BlockPos blockPos : railState.getConnections()) {
- BlockState blockState = level.getBlockState(blockPos);
- level.neighborChanged(blockState, blockPos, blockState.getBlock(), null, false);
+ BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, blockPos, 16) ? null : level.getBlockState(blockPos); // Folia - block updates in unloaded chunks
+ if (blockState != null) level.neighborChanged(blockState, blockPos, blockState.getBlock(), null, false); // Folia - block updates in unloaded chunks
}
}
diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java
index f33b53257a231dccf16740f1e78a3cdfa6e70726..f87f59ea29bd288cd6b7ff877c517dc6d9cdefea 100644
--- a/net/minecraft/world/level/block/PoweredRailBlock.java
+++ b/net/minecraft/world/level/block/PoweredRailBlock.java
@@ -108,8 +108,8 @@ public class PoweredRailBlock extends BaseRailBlock {
}
protected boolean isSameRailWithPower(Level level, BlockPos state, boolean searchForward, int recursionCount, RailShape shape) {
- BlockState blockState = level.getBlockState(state);
- if (!blockState.is(this)) {
+ BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, state, 16) ? null : level.getBlockState(state); // Folia - block updates in unloaded chunks
+ if (blockState == null || !blockState.is(this)) { // Folia - block updates in unloaded chunks
return false;
} else {
RailShape railShape = blockState.getValue(SHAPE);
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
index 6ba86c5e55d09fd99e81e40db4614ef14246bdc3..996e8d5b4e4aac7a0c0f846dd765711a2dfb5682 100644
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -236,8 +236,9 @@ public class RedStoneWireBlock extends Block {
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
for (Direction direction : Direction.Plane.HORIZONTAL) {
+ BlockState currState; mutableBlockPos.setWithOffset(pos, direction); // Folia - block updates in unloaded chunks
RedstoneSide redstoneSide = state.getValue(PROPERTY_BY_DIRECTION.get(direction));
- if (redstoneSide != RedstoneSide.NONE && !level.getBlockState(mutableBlockPos.setWithOffset(pos, direction)).is(this)) {
+ if (redstoneSide != RedstoneSide.NONE && (currState = (level instanceof net.minecraft.server.level.ServerLevel serverLevel && !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(serverLevel, pos, 16) ? null : level.getBlockStateIfLoaded(mutableBlockPos.setWithOffset(pos, direction)))) != null && !currState.is(this)) { // Folia - block updates in unloaded chunks
mutableBlockPos.move(Direction.DOWN);
BlockState blockState = level.getBlockState(mutableBlockPos);
if (blockState.is(this)) {
diff --git a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
index e7ea9df8f404a6176435204a91edeefab8070c89..285fa83ee583595274f228e5981a67f67012d410 100644
--- a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
+++ b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
@@ -122,7 +122,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
public boolean runNext(Level level) {
Direction direction = NeighborUpdater.UPDATE_ORDER[this.idx++];
BlockPos blockPos = this.sourcePos.relative(direction);
- BlockState blockState = level.getBlockState(blockPos);
+ BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, blockPos, 16) ? null : level.getBlockState(blockPos); // Folia - block updates in unloaded chunks
+ if (blockState != null) { // Folia - block updates in unloaded chunks
Orientation orientation = null;
if (level.enabledFeatures().contains(FeatureFlags.REDSTONE_EXPERIMENTS)) {
if (this.orientation == null) {
@@ -135,6 +136,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
}
NeighborUpdater.executeUpdate(level, blockState, blockPos, this.sourceBlock, orientation, false, this.sourcePos); // Paper - Add source block to BlockPhysicsEvent
+ } // Folia - block updates in unloaded chunks
if (this.idx < NeighborUpdater.UPDATE_ORDER.length && NeighborUpdater.UPDATE_ORDER[this.idx] == this.skipDirection) {
this.idx++;
}
@@ -151,7 +153,9 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
implements CollectingNeighborUpdater.NeighborUpdates {
@Override
public boolean runNext(Level level) {
+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, this.pos, 16) && level.getChunkIfLoaded(this.pos) != null) { // Folia - block updates in unloaded chunks
NeighborUpdater.executeShapeUpdate(level, this.direction, this.pos, this.neighborPos, this.neighborState, this.updateFlags, this.updateLimit);
+ } // Folia - block updates in unloaded chunks
return false;
}
}
@@ -159,8 +163,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
record SimpleNeighborUpdate(BlockPos pos, Block block, @Nullable Orientation orientation) implements CollectingNeighborUpdater.NeighborUpdates {
@Override
public boolean runNext(Level level) {
- BlockState blockState = level.getBlockState(this.pos);
- NeighborUpdater.executeUpdate(level, blockState, this.pos, this.block, this.orientation, false);
+ BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(level, this.pos, 16) ? null : level.getBlockStateIfLoaded(this.pos); // Folia - block updates in unloaded chunks
+ if (blockState != null) NeighborUpdater.executeUpdate(level, blockState, this.pos, this.block, this.orientation, false);
return false;
}
}

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Block reading in-world tile entities on worldgen threads
The returned TE may be in the world, in which case it is unsafe The returned TE may be in the world, in which case it is unsafe
for the current thread to modify or access its contents. for the current thread to modify or access its contents.
diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java diff --git a/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
index 1eb8022f3e31603322e6c56516304afc9a11bbec..87ddae289972b8e0dd0b48a07e23c627b598bae3 100644 index 41856c98d97e7eb0782f8e441b9a269a47ed1914..606b07ae06166f954b6aaa39d56f024c7ad8611f 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java --- a/net/minecraft/world/level/chunk/ImposterProtoChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +++ b/net/minecraft/world/level/chunk/ImposterProtoChunk.java
@@ -91,6 +91,11 @@ public class ImposterProtoChunk extends ProtoChunk implements ca.spottedleaf.moo @@ -91,6 +91,11 @@ public class ImposterProtoChunk extends ProtoChunk implements ca.spottedleaf.moo
@Nullable @Nullable
@Override @Override

View File

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 23 Apr 2023 07:38:50 -0700
Subject: [PATCH] Skip worldstate access when waking players up during data
deserialization
In general, worldstate read/write is unacceptable during
data deserialization and is racey even in Vanilla. But in Folia,
some accesses may throw and as such we need to fix this directly.
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index ab85c5acc63abc07a55ff7c5e207527bb18d50b2..df0c10880c5aea110a4eade57d257d3a46e8c180 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -674,7 +674,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.getBukkitEntity().readExtraData(compound); // CraftBukkit
if (this.isSleeping()) {
- this.stopSleeping();
+ this.stopSleepingRaw(); // Folia - do not modify or read worldstate during data deserialization
}
// CraftBukkit start
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 8f9e64590400039566ee5c9628d82a0eb9e56be1..5ba06cf6b26baa5acae9d64111ee3f61533e7867 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -4333,6 +4333,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.setXRot(0.0F);
}
});
+ // Folia start - separate out
+ this.stopSleepingRaw();
+ }
+ public void stopSleepingRaw() {
+ // Folia end - separate out
Vec3 vec3 = this.position();
this.setPose(Pose.STANDING);
this.setPos(vec3.x, vec3.y, vec3.z);

View File

@ -8,18 +8,18 @@ the lodestone block, as that is at least safe enough for the light
engine compared to the POI access. This should make it safe for engine compared to the POI access. This should make it safe for
off-region access. off-region access.
diff --git a/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java b/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java diff --git a/net/minecraft/world/item/component/LodestoneTracker.java b/net/minecraft/world/item/component/LodestoneTracker.java
index cdd1f6939ce33e62f6609f7eb3a5dff59bf12675..5d92251dc5a53eb6b2f5ecfef1261ad6edd0e2a9 100644 index 0c00c23743a4978e8dceed5bbee8ca44b0e0c8d6..b6de5d017bed5c71125f26881b95383386aa1a79 100644
--- a/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java --- a/net/minecraft/world/item/component/LodestoneTracker.java
+++ b/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java +++ b/net/minecraft/world/item/component/LodestoneTracker.java
@@ -29,7 +29,10 @@ public record LodestoneTracker(Optional<GlobalPos> target, boolean tracked) { @@ -29,7 +29,10 @@ public record LodestoneTracker(Optional<GlobalPos> target, boolean tracked) {
return this; return this;
} else { } else {
BlockPos blockPos = this.target.get().pos(); BlockPos blockPos = this.target.get().pos();
- return world.isInWorldBounds(blockPos) && (!world.hasChunkAt(blockPos) || world.getPoiManager().existsAtPosition(PoiTypes.LODESTONE, blockPos)) // Paper - Prevent compass from loading chunks - return level.isInWorldBounds(blockPos) && (!level.hasChunkAt(blockPos) || level.getPoiManager().existsAtPosition(PoiTypes.LODESTONE, blockPos)) // Paper - Prevent compass from loading chunks
+ // Folia start - do not access the POI data off-region + // Folia start - do not access the POI data off-region
+ net.minecraft.world.level.chunk.LevelChunk chunk = world.getChunkIfLoaded(blockPos); + net.minecraft.world.level.chunk.LevelChunk chunk = level.getChunkIfLoaded(blockPos);
+ return world.isInWorldBounds(blockPos) && (chunk == null || chunk.getBlockState(blockPos).getBlock() == net.minecraft.world.level.block.Blocks.LODESTONE) // Paper - Prevent compass from loading chunks + return level.isInWorldBounds(blockPos) && (chunk == null || chunk.getBlockState(blockPos).getBlock() == net.minecraft.world.level.block.Blocks.LODESTONE) // Paper - Prevent compass from loading chunks
+ // Folia end - do not access the POI data off-region + // Folia end - do not access the POI data off-region
? this ? this
: new LodestoneTracker(Optional.empty(), true); : new LodestoneTracker(Optional.empty(), true);

View File

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: WillQi <williamqipizza@gmail.com>
Date: Mon, 15 May 2023 23:45:09 -0600
Subject: [PATCH] Fix off region raid heroes
This patch aims to solve a potential incorrect thread call when completing a raid.
If a player is a hero of the village but proceeds to leave the region of the
raid before it's completion, it would throw an exception due to not being on the
same region thread anymore.
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
index b7045b2d4665c72d0c4849c711be4e44f7d17ad3..58ea6738dd9a04831197b850850720d5a775a131 100644
--- a/net/minecraft/world/entity/raid/Raid.java
+++ b/net/minecraft/world/entity/raid/Raid.java
@@ -391,14 +391,21 @@ public class Raid {
if (entity instanceof LivingEntity) {
LivingEntity livingEntity = (LivingEntity)entity;
if (!entity.isSpectator()) {
- livingEntity.addEffect(
- new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.raidOmenLevel - 1, false, false, true)
- );
+ //livingEntity.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.raidOmenLevel - 1, false, false, true)); // Folia start - Fix off region raid heroes - moved down
if (livingEntity instanceof ServerPlayer serverPlayer) {
- serverPlayer.awardStat(Stats.RAID_WIN);
- CriteriaTriggers.RAID_WIN.trigger(serverPlayer);
+ //serverPlayer.awardStat(Stats.RAID_WIN); // Folia start - Fix off region raid heroes - moved down
+ //CriteriaTriggers.RAID_WIN.trigger(serverPlayer); // Folia start - Fix off region raid heroes - moved down
winners.add(serverPlayer.getBukkitEntity()); // CraftBukkit
}
+ // Folia start - Fix off region raid heroes
+ livingEntity.getBukkitEntity().taskScheduler.schedule((LivingEntity lv) -> {
+ lv.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.raidOmenLevel - 1, false, false, true));
+ if (lv instanceof ServerPlayer serverPlayer) {
+ serverPlayer.awardStat(Stats.RAID_WIN);
+ CriteriaTriggers.RAID_WIN.trigger(serverPlayer);
+ }
+ }, null, 1L);
+ // Folia end - Fix off region raid heroes
}
}
}

View File

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 25 Jun 2023 13:57:30 -0700
Subject: [PATCH] Sync vehicle position to player position on player data load
This allows the player to be re-positioned before logging into
the world without causing thread checks to trip on Folia.
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index df0c10880c5aea110a4eade57d257d3a46e8c180..ca3770e9f77e583dfa6cef8ca884eaf6a43f5ffa 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -775,8 +775,18 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public void loadAndSpawnParentVehicle(Optional<CompoundTag> tag) {
if (tag.isPresent() && tag.get().contains("RootVehicle", 10) && this.level() instanceof ServerLevel serverLevel) {
CompoundTag compound = tag.get().getCompound("RootVehicle");
+ Vec3 playerPos = this.position(); // Paper - force sync root vehicle to player position
Entity entity = EntityType.loadEntityRecursive(
- compound.getCompound("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity2 // Paper - Entity#getEntitySpawnReason
+ // Paper start - force sync root vehicle to player position
+ compound.getCompound("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> {
+ // Paper start - force sync root vehicle to player position
+ if (entity2.distanceToSqr(ServerPlayer.this) > (5.0 * 5.0)) {
+ entity2.setPosRaw(playerPos.x, playerPos.y, playerPos.z, true);
+ }
+ // Paper end - force sync root vehicle to player position
+ return !serverLevel.addWithUUID(entity2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity2; // Paper - Entity#getEntitySpawnReason
+ }
+ // Paper end - force sync root vehicle to player position
);
if (entity == null) {
return;

View File

@ -76,11 +76,11 @@ The X is the average number of times the counter is invoked
relative to the parent, exactly similar to the D field of Timers, relative to the parent, exactly similar to the D field of Timers,
where Y is the total number of times the counter is invoked. where Y is the total number of times the counter is invoked.
diff --git a/src/main/java/ca/spottedleaf/leafprofiler/LProfileGraph.java b/src/main/java/ca/spottedleaf/leafprofiler/LProfileGraph.java diff --git a/ca/spottedleaf/leafprofiler/LProfileGraph.java b/ca/spottedleaf/leafprofiler/LProfileGraph.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..19c13bd372711bce978a463f85130f1e10202da9 index 0000000000000000000000000000000000000000..19c13bd372711bce978a463f85130f1e10202da9
--- /dev/null --- /dev/null
+++ b/src/main/java/ca/spottedleaf/leafprofiler/LProfileGraph.java +++ b/ca/spottedleaf/leafprofiler/LProfileGraph.java
@@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
+package ca.spottedleaf.leafprofiler; +package ca.spottedleaf.leafprofiler;
+ +
@ -188,11 +188,11 @@ index 0000000000000000000000000000000000000000..19c13bd372711bce978a463f85130f1e
+ return this.createNode(parent, timerId); + return this.createNode(parent, timerId);
+ } + }
+} +}
diff --git a/src/main/java/ca/spottedleaf/leafprofiler/LProfilerRegistry.java b/src/main/java/ca/spottedleaf/leafprofiler/LProfilerRegistry.java diff --git a/ca/spottedleaf/leafprofiler/LProfilerRegistry.java b/ca/spottedleaf/leafprofiler/LProfilerRegistry.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..cf81748afe993e486ce27ae65e0148071b029423 index 0000000000000000000000000000000000000000..cf81748afe993e486ce27ae65e0148071b029423
--- /dev/null --- /dev/null
+++ b/src/main/java/ca/spottedleaf/leafprofiler/LProfilerRegistry.java +++ b/ca/spottedleaf/leafprofiler/LProfilerRegistry.java
@@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
+package ca.spottedleaf.leafprofiler; +package ca.spottedleaf.leafprofiler;
+ +
@ -312,11 +312,11 @@ index 0000000000000000000000000000000000000000..cf81748afe993e486ce27ae65e014807
+ public static final int TILE_ENTITY_PENDING = GLOBAL_REGISTRY.createType(ProfileType.TIMER, "Tile Entity Handle Pending"); + public static final int TILE_ENTITY_PENDING = GLOBAL_REGISTRY.createType(ProfileType.TIMER, "Tile Entity Handle Pending");
+ public static final int TILE_ENTITY_TICK = GLOBAL_REGISTRY.createType(ProfileType.TIMER, "Tile Entity Tick"); + public static final int TILE_ENTITY_TICK = GLOBAL_REGISTRY.createType(ProfileType.TIMER, "Tile Entity Tick");
+} +}
diff --git a/src/main/java/ca/spottedleaf/leafprofiler/LeafProfiler.java b/src/main/java/ca/spottedleaf/leafprofiler/LeafProfiler.java diff --git a/ca/spottedleaf/leafprofiler/LeafProfiler.java b/ca/spottedleaf/leafprofiler/LeafProfiler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..d1d259fbf6633ea38799b1519bca6deb623704a3 index 0000000000000000000000000000000000000000..d1d259fbf6633ea38799b1519bca6deb623704a3
--- /dev/null --- /dev/null
+++ b/src/main/java/ca/spottedleaf/leafprofiler/LeafProfiler.java +++ b/ca/spottedleaf/leafprofiler/LeafProfiler.java
@@ -0,0 +1,413 @@ @@ -0,0 +1,413 @@
+package ca.spottedleaf.leafprofiler; +package ca.spottedleaf.leafprofiler;
+ +
@ -731,11 +731,11 @@ index 0000000000000000000000000000000000000000..d1d259fbf6633ea38799b1519bca6deb
+ } + }
+ */ + */
+} +}
diff --git a/src/main/java/ca/spottedleaf/leafprofiler/RegionizedProfiler.java b/src/main/java/ca/spottedleaf/leafprofiler/RegionizedProfiler.java diff --git a/ca/spottedleaf/leafprofiler/RegionizedProfiler.java b/ca/spottedleaf/leafprofiler/RegionizedProfiler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..6e9b04613c5c867a74fa4f266a8ae8e60416cb6d index 0000000000000000000000000000000000000000..6e9b04613c5c867a74fa4f266a8ae8e60416cb6d
--- /dev/null --- /dev/null
+++ b/src/main/java/ca/spottedleaf/leafprofiler/RegionizedProfiler.java +++ b/ca/spottedleaf/leafprofiler/RegionizedProfiler.java
@@ -0,0 +1,277 @@ @@ -0,0 +1,277 @@
+package ca.spottedleaf.leafprofiler; +package ca.spottedleaf.leafprofiler;
+ +
@ -1014,11 +1014,11 @@ index 0000000000000000000000000000000000000000..6e9b04613c5c867a74fa4f266a8ae8e6
+ TickData tickData + TickData tickData
+ ) {} + ) {}
+} +}
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
index dbb5b6ee36a54d6682b2a6d9389aee721b95d506..811479551bad422123ad1b09329e6fc8e12c7c4e 100644 index aae97116a22a87cffd4756d566da3acd96ce2ae0..5a59099c4dd375f5f163751655d774d70c42699f 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
@@ -1461,7 +1461,9 @@ public final class ChunkHolderManager { @@ -1460,7 +1460,9 @@ public final class ChunkHolderManager {
} }
public boolean processTicketUpdates() { public boolean processTicketUpdates() {
@ -1028,11 +1028,11 @@ index dbb5b6ee36a54d6682b2a6d9389aee721b95d506..811479551bad422123ad1b09329e6fc8
} }
private static final ThreadLocal<List<ChunkProgressionTask>> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>(); private static final ThreadLocal<List<ChunkProgressionTask>> CURRENT_TICKET_UPDATE_SCHEDULING = new ThreadLocal<>();
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
index 9e7e10fe46dbbd03d690a65af6ae719d1665bc6a..6edbe46c5c2eb74bca7e437474a6e992f45a04f8 100644 index 601ed36413bbbf9c17e530b42906986e441237fd..6ae7d646c1173c4835fa235c7cee21ec463dbab2 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
@@ -1680,6 +1680,8 @@ public final class NewChunkHolder { @@ -1679,6 +1679,8 @@ public final class NewChunkHolder {
public SaveStat save(final boolean shutdown) { public SaveStat save(final boolean shutdown) {
TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main"); TickThread.ensureTickThread(this.world, this.chunkX, this.chunkZ, "Cannot save data off-main");
@ -1041,7 +1041,7 @@ index 9e7e10fe46dbbd03d690a65af6ae719d1665bc6a..6edbe46c5c2eb74bca7e437474a6e992
ChunkAccess chunk = this.getCurrentChunk(); ChunkAccess chunk = this.getCurrentChunk();
PoiChunk poi = this.getPoiChunk(); PoiChunk poi = this.getPoiChunk();
@@ -1738,6 +1740,7 @@ public final class NewChunkHolder { @@ -1737,6 +1739,7 @@ public final class NewChunkHolder {
canSavePOI | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.POI_DATA.ordinal()] canSavePOI | executedUnloadTasks[MoonriseRegionFileIO.RegionFileType.POI_DATA.ordinal()]
) )
: null; : null;
@ -1049,22 +1049,10 @@ index 9e7e10fe46dbbd03d690a65af6ae719d1665bc6a..6edbe46c5c2eb74bca7e437474a6e992
} }
private boolean saveChunk(final ChunkAccess chunk, final boolean unloading) { private boolean saveChunk(final ChunkAccess chunk, final boolean unloading) {
diff --git a/src/main/java/io/papermc/paper/command/PaperCommands.java b/src/main/java/io/papermc/paper/command/PaperCommands.java diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
index a587d83b78af4efc484f939529acf70834f60d7e..45f76aaaa7dedb77a83b4a2c87905bf9a099a93c 100644
--- a/src/main/java/io/papermc/paper/command/PaperCommands.java
+++ b/src/main/java/io/papermc/paper/command/PaperCommands.java
@@ -20,6 +20,7 @@ public final class PaperCommands {
COMMANDS.put("callback", new CallbackCommand("callback"));
COMMANDS.put("mspt", new MSPTCommand("mspt"));
COMMANDS.put("tps", new io.papermc.paper.threadedregions.commands.CommandServerHealth()); // Folia - region threading
+ COMMANDS.put("profiler", new io.papermc.paper.threadedregions.commands.CommandProfiler()); // Folia - region threading - profiler
}
public static void registerCommands(final MinecraftServer server) {
diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java
index 4471285a4358e51da9912ed791a824527f1a2e8e..a18da3f3f245031f0547efe9b52a1f2a219ef04a 100644 index 4471285a4358e51da9912ed791a824527f1a2e8e..a18da3f3f245031f0547efe9b52a1f2a219ef04a 100644
--- a/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java --- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java +++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
@@ -67,8 +67,13 @@ public final class TickRegionScheduler { @@ -67,8 +67,13 @@ public final class TickRegionScheduler {
tickThreadRunner.currentTickingRegion = region; tickThreadRunner.currentTickingRegion = region;
if (region != null) { if (region != null) {
@ -1107,10 +1095,10 @@ index 4471285a4358e51da9912ed791a824527f1a2e8e..a18da3f3f245031f0547efe9b52a1f2a
public TickThreadRunner(final Runnable run, final String name) { public TickThreadRunner(final Runnable run, final String name) {
super(run, name); super(run, name);
diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
index df15b1139e71dfe10b8f24ec6d235b99f6d5006a..b1c07e582dbf0a203cf734fdbcd8387a422af3a6 100644 index df15b1139e71dfe10b8f24ec6d235b99f6d5006a..b1c07e582dbf0a203cf734fdbcd8387a422af3a6 100644
--- a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java --- a/io/papermc/paper/threadedregions/TickRegions.java
+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java +++ b/io/papermc/paper/threadedregions/TickRegions.java
@@ -81,6 +81,11 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic @@ -81,6 +81,11 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
@Override @Override
public void onRegionDestroy(final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> region) { public void onRegionDestroy(final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> region) {
@ -1196,11 +1184,11 @@ index df15b1139e71dfe10b8f24ec6d235b99f6d5006a..b1c07e582dbf0a203cf734fdbcd8387a
} }
@Override @Override
diff --git a/src/main/java/io/papermc/paper/threadedregions/commands/CommandProfiler.java b/src/main/java/io/papermc/paper/threadedregions/commands/CommandProfiler.java diff --git a/io/papermc/paper/threadedregions/commands/CommandProfiler.java b/io/papermc/paper/threadedregions/commands/CommandProfiler.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..dbc6ffd8fec4570de4abdb3aa0a16d0e0cc09353 index 0000000000000000000000000000000000000000..dbc6ffd8fec4570de4abdb3aa0a16d0e0cc09353
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/commands/CommandProfiler.java +++ b/io/papermc/paper/threadedregions/commands/CommandProfiler.java
@@ -0,0 +1,245 @@ @@ -0,0 +1,245 @@
+package io.papermc.paper.threadedregions.commands; +package io.papermc.paper.threadedregions.commands;
+ +
@ -1447,42 +1435,42 @@ index 0000000000000000000000000000000000000000..dbc6ffd8fec4570de4abdb3aa0a16d0e
+ return new ArrayList<>(); + return new ArrayList<>();
+ } + }
+} +}
diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java diff --git a/net/minecraft/network/protocol/PacketUtils.java b/net/minecraft/network/protocol/PacketUtils.java
index d6eb8f495688a1b65a4c419aa3ee655cd8eb322a..f338b273613840ed366ab13b528373e7091631e8 100644 index b28ff2f18ab7e0e3a61e37ee46048ab5cb7ab45d..c7214f0457641b5550b98dbd2863c1d637faeaa5 100644
--- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java --- a/net/minecraft/network/protocol/PacketUtils.java
+++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/net/minecraft/network/protocol/PacketUtils.java
@@ -52,7 +52,10 @@ public class PacketUtils { @@ -26,7 +26,10 @@ public class PacketUtils {
if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players if (processor instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // Paper - Don't handle sync packets for kicked players
if (listener.shouldHandleMessage(packet)) { if (processor.shouldHandleMessage(packet)) {
try { try {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
+ final int packetTimerId = profiler.getOrCreateTimerAndStart(() -> "Packet Handler: ".concat(io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(packet.getClass().getName()))); try { // Folia - profiler + final int packetTimerId = profiler.getOrCreateTimerAndStart(() -> "Packet Handler: ".concat(io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(packet.getClass().getName()))); try { // Folia - profiler
packet.handle(listener); packet.handle(processor);
+ } finally { profiler.stopTimer(packetTimerId); } // Folia - profiler + } finally { profiler.stopTimer(packetTimerId); } // Folia - profiler
} catch (Exception exception) { } catch (Exception var4) {
if (exception instanceof ReportedException) { if (var4 instanceof ReportedException reportedException && reportedException.getCause() instanceof OutOfMemoryError) {
ReportedException reportedexception = (ReportedException) exception; throw makeReportedException(var4, packet, processor);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 25b4b0d531f0698338ffeac686013a4631d60c00..1676c4abb3f6f71bb7b25351aa58b4e127786fca 100644 index 9c9de462eb7187d6cc3562c796e3bcf69fb20783..faf72dd6dff74296c73cb058aaabd1f9f475a072 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -1713,6 +1713,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1579,6 +1579,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia start - region threading // Folia start - region threading
public void tickServer(long startTime, long scheduledEnd, long targetBuffer, public void tickServer(long startTime, long scheduledEnd, long targetBuffer,
io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { io.papermc.paper.threadedregions.TickRegions.TickRegionData region) {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
// Folia end - region threading // Folia end - region threading
org.spigotmc.WatchdogThread.tick(); // Spigot org.spigotmc.WatchdogThread.tick(); // Spigot
long i = startTime; // Folia - region threading long nanos = startTime; // Folia - region threading
@@ -1751,6 +1752,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1616,6 +1617,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
} }
+ +
// Folia start - region threading // Folia start - region threading
if (region != null) {
region.world.getCurrentWorldData().updateTickData(); region.world.getCurrentWorldData().updateTickData();
@@ -1774,10 +1776,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa if (region.world.checkInitialised.get() != ServerLevel.WORLD_INIT_CHECKED) {
@@ -1637,10 +1639,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper - Server Tick Events // Folia - region threading new com.destroystokyo.paper.event.server.ServerTickStartEvent((int)region.getCurrentTick()).callEvent(); // Paper - Server Tick Events // Folia - region threading
// Folia start - region threading // Folia start - region threading
if (region != null) { if (region != null) {
@ -1490,16 +1478,16 @@ index 25b4b0d531f0698338ffeac686013a4631d60c00..1676c4abb3f6f71bb7b25351aa58b4e1
region.getTaskQueueData().drainTasks(); region.getTaskQueueData().drainTasks();
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.INTERNAL_TICK_TASKS); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.INTERNAL_TICK_TASKS); } // Folia - profiler
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLUGIN_TICK_TASKS); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLUGIN_TICK_TASKS); try { // Folia - profiler
((io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler)Bukkit.getRegionScheduler()).tick(); ((io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler)org.bukkit.Bukkit.getRegionScheduler()).tick();
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLUGIN_TICK_TASKS); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLUGIN_TICK_TASKS); } // Folia - profiler
// now run all the entity schedulers // now run all the entity schedulers
// TODO there has got to be a more efficient variant of this crap // TODO there has got to be a more efficient variant of this crap
+ long tickedEntitySchedulers = 0L; // Folia - profiler + long tickedEntitySchedulers = 0L; // Folia - profiler
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_SCHEDULER_TICK); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_SCHEDULER_TICK); try { // Folia - profiler
for (Entity entity : region.world.getCurrentWorldData().getLocalEntitiesCopy()) { for (net.minecraft.world.entity.Entity entity : region.world.getCurrentWorldData().getLocalEntitiesCopy()) {
if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(entity) || entity.isRemoved()) { if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(entity) || entity.isRemoved()) {
continue; continue;
@@ -1785,8 +1793,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1648,8 +1656,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw(); org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw();
if (bukkit != null) { if (bukkit != null) {
bukkit.taskScheduler.executeTick(); bukkit.taskScheduler.executeTick();
@ -1510,8 +1498,8 @@ index 25b4b0d531f0698338ffeac686013a4631d60c00..1676c4abb3f6f71bb7b25351aa58b4e1
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_SCHEDULER_TICK); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_SCHEDULER_TICK); } // Folia - profiler
} }
// Folia end - region threading // Folia end - region threading
if (region == null) this.tickRateManager.tick(); // Folia - region threading //this.tickCount++; // Folia - region threading
@@ -1805,6 +1816,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1669,6 +1680,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
profiler.push("save"); profiler.push("save");
final boolean fullSave = autosavePeriod > 0 && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % autosavePeriod == 0; // Folia - region threading final boolean fullSave = autosavePeriod > 0 && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % autosavePeriod == 0; // Folia - region threading
@ -1519,7 +1507,7 @@ index 25b4b0d531f0698338ffeac686013a4631d60c00..1676c4abb3f6f71bb7b25351aa58b4e1
try { try {
this.isSaving = true; this.isSaving = true;
if (playerSaveInterval > 0) { if (playerSaveInterval > 0) {
@@ -1818,6 +1830,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1682,6 +1694,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} finally { } finally {
this.isSaving = false; this.isSaving = false;
} }
@ -1527,59 +1515,57 @@ index 25b4b0d531f0698338ffeac686013a4631d60c00..1676c4abb3f6f71bb7b25351aa58b4e1
profiler.pop(); profiler.pop();
// Paper end - Incremental chunk and player saving // Paper end - Incremental chunk and player saving
@@ -1900,6 +1913,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1761,6 +1774,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
protected void tickChildren(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - region threading protected void tickChildren(BooleanSupplier hasTimeLeft, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - region threading
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionizedWorldData(); // Folia - regionised ticking final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegionizedWorldData(); // Folia - regionised ticking
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
//this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing()); // Folia - region threading
@@ -1964,7 +1978,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1815,7 +1829,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
gameprofilerfiller.push("tick"); profilerFiller.push("tick");
try { try {
+ profiler.startTimer(worldserver.tickTimerId); try { // Folia - profiler + profiler.startTimer(serverLevel.tickTimerId); try { // Folia - profiler
worldserver.tick(shouldKeepTicking, region); // Folia - region threading serverLevel.tick(hasTimeLeft, region); // Folia - region threading
+ } finally { profiler.stopTimer(worldserver.tickTimerId); } // Folia - profiler + } finally { profiler.stopTimer(serverLevel.tickTimerId); } // Folia - profiler
} catch (Throwable throwable) { } catch (Throwable var7) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world"); CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
serverLevel.fillReportDetails(crashReport);
@@ -1829,7 +1845,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked // Folia - region threading
@@ -1979,8 +1995,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa profilerFiller.popPush("connection");
if (region == null) this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked // Folia - region threading
gameprofilerfiller.popPush("connection");
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CONNECTION_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CONNECTION_TICK); try { // Folia - profiler
if (region == null) this.tickConnection(); // Folia - region threading regionizedWorldData.tickConnections(); // Folia - region threading
if (region != null) regionizedWorldData.tickConnections(); // Folia - region threading
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CONNECTION_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CONNECTION_TICK); } // Folia - profiler
gameprofilerfiller.popPush("players"); profilerFiller.popPush("players");
if (false) this.playerList.tick(); // Folia - region threading //this.playerList.tick(); // Folia - region threading
if (SharedConstants.IS_RUNNING_IN_IDE && this.tickRateManager.runsNormally()) { if (SharedConstants.IS_RUNNING_IN_IDE && this.tickRateManager.runsNormally()) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 1668011de11a5ed513815fa1b547ff3a7636cc13..74cd86aea1a82f169cb50dac14a8973c97cca88d 100644 index 06cc9d69220b09667db30a5c1e161333d2563b23..65b9a49e84d9bde75c249651e974d57bc1a43277 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java
@@ -406,13 +406,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -410,12 +410,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
protected void tick(BooleanSupplier shouldKeepTicking) { protected void tick(BooleanSupplier hasMoreTime) {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("poi");
gameprofilerfiller.push("poi");
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.POI_MANAGER_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.POI_MANAGER_TICK); try { // Folia - profiler
this.poiManager.tick(shouldKeepTicking); this.poiManager.tick(hasMoreTime);
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.POI_MANAGER_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.POI_MANAGER_TICK); } // Folia - profiler
gameprofilerfiller.popPush("chunk_unload"); profilerFiller.popPush("chunk_unload");
if (!this.level.noSave()) { if (!this.level.noSave()) {
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PROCESS_UNLOADS); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PROCESS_UNLOADS); try { // Folia - profiler
this.processUnloads(shouldKeepTicking); this.processUnloads(hasMoreTime);
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PROCESS_UNLOADS); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PROCESS_UNLOADS); } // Folia - profiler
} }
gameprofilerfiller.pop(); profilerFiller.pop();
@@ -941,12 +946,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -937,12 +942,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - optimise entity tracker // Paper start - optimise entity tracker
private void newTrackerTick() { private void newTrackerTick() {
@ -1598,7 +1584,7 @@ index 1668011de11a5ed513815fa1b547ff3a7636cc13..74cd86aea1a82f169cb50dac14a8973c
final Entity entity = trackerEntitiesRaw[i]; final Entity entity = trackerEntitiesRaw[i];
final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity(); final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity();
if (tracker == null) { if (tracker == null) {
@@ -958,6 +968,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -954,6 +964,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
tracker.serverEntity.sendChanges(); tracker.serverEntity.sendChanges();
} }
} }
@ -1607,18 +1593,17 @@ index 1668011de11a5ed513815fa1b547ff3a7636cc13..74cd86aea1a82f169cb50dac14a8973c
} }
// Paper end - optimise entity tracker // Paper end - optimise entity tracker
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 1a43c6fba5eea514dd6cf406f600dc254282da35..ca47a512452ae425160e30dc7c4a79f40aa97a26 100644 index c340d537749c49d83f50f6cec84ac75e1ace2bbd..089e694753e3c1b61902255442b26a3a6cbdf9af 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -462,18 +462,25 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -483,17 +483,24 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
@Override @Override
public void tick(BooleanSupplier shouldKeepTicking, boolean tickChunks) { public void tick(BooleanSupplier hasTimeLeft, boolean tickChunks) {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("purge");
gameprofilerfiller.push("purge");
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_HOLDER_MANAGER_TICK); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_HOLDER_MANAGER_TICK); try { // Folia - profiler
if (this.level.tickRateManager().runsNormally() || !tickChunks || this.level.spigotConfig.unloadFrozenChunks) { // Spigot if (this.level.tickRateManager().runsNormally() || !tickChunks || this.level.spigotConfig.unloadFrozenChunks) { // Spigot
this.distanceManager.purgeStaleTickets(); this.distanceManager.purgeStaleTickets();
@ -1626,7 +1611,7 @@ index 1a43c6fba5eea514dd6cf406f600dc254282da35..ca47a512452ae425160e30dc7c4a79f4
this.runDistanceManagerUpdates(); this.runDistanceManagerUpdates();
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_HOLDER_MANAGER_TICK); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_HOLDER_MANAGER_TICK); } // Folia - profiler
gameprofilerfiller.popPush("chunks"); profilerFiller.popPush("chunks");
if (tickChunks) { if (tickChunks) {
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLAYER_CHUNK_LOADER_TICK); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLAYER_CHUNK_LOADER_TICK); try { // Folia - profiler
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getPlayerChunkLoader().tick(); // Paper - rewrite chunk system
@ -1637,68 +1622,73 @@ index 1a43c6fba5eea514dd6cf406f600dc254282da35..ca47a512452ae425160e30dc7c4a79f4
this.chunkMap.tick(); this.chunkMap.tick();
} }
@@ -485,6 +492,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -505,6 +512,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
private void tickChunks() { private void tickChunks() {
io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData(); // Folia - region threading io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData(); // Folia - region threading
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
//long i = this.level.getGameTime(); // Folia - region threading //long gameTime = this.level.getGameTime(); // Folia - region threading
long j = 1L; // Folia - region threading long l = 1L; // Folia - region threading
//this.lastInhabitedUpdate = gameTime; // Folia - region threading
@@ -498,7 +506,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -516,7 +524,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
try { try {
gameprofilerfiller.push("filteringTickingChunks"); profilerFiller.push("filteringTickingChunks");
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_TICK_COLLECT_CHUNKS); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_TICK_COLLECT_CHUNKS); try { // Folia - profiler
this.collectTickingChunks(list); this.collectTickingChunks(list);
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_TICK_COLLECT_CHUNKS); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_TICK_COLLECT_CHUNKS); } // Folia - profiler
gameprofilerfiller.popPush("shuffleChunks"); profilerFiller.popPush("shuffleChunks");
// Paper start - chunk tick iteration optimisation // Paper start - chunk tick iteration optimisation
this.shuffleRandom.setSeed(this.level.random.nextLong()); this.shuffleRandom.setSeed(this.level.random.nextLong());
@@ -511,7 +521,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -529,7 +539,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
} }
} }
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BROADCAST_BLOCK_CHANGES); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BROADCAST_BLOCK_CHANGES); try { // Folia - profiler
this.broadcastChangedChunks(gameprofilerfiller); this.broadcastChangedChunks(profilerFiller);
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BROADCAST_BLOCK_CHANGES); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BROADCAST_BLOCK_CHANGES); } // Folia - profiler
gameprofilerfiller.pop(); profilerFiller.pop();
} }
} }
@@ -559,11 +571,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -574,10 +586,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
private void tickChunks(ProfilerFiller profiler, long timeDelta, List<LevelChunk> chunks) { private void tickChunks(ProfilerFiller profiler, long timeInhabited, List<LevelChunk> chunks) {
io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData(); // Folia - region threading io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.level.getCurrentWorldData(); // Folia - region threading
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
profiler.popPush("naturalSpawnCount"); profiler.popPush("naturalSpawnCount");
int j = this.distanceManager.getNaturalSpawnChunkCount(); int naturalSpawnChunkCount = this.distanceManager.getNaturalSpawnChunkCount();
// Paper start - Optional per player mob spawns // Paper start - Optional per player mob spawns
final int naturalSpawnChunkCount = j; NaturalSpawner.SpawnState spawnState;
NaturalSpawner.SpawnState spawnercreature_d; // moved down
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); try { // Folia - profiler
if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled
// re-set mob counts // re-set mob counts
for (ServerPlayer player : this.level.getLocalPlayers()) { // Folia - region threading for (ServerPlayer player : this.level.getLocalPlayers()) { // Folia - region threading
@@ -583,6 +597,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -597,6 +611,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
} else { } else {
spawnercreature_d = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false); // Folia - region threading - note: function only cares about loaded entities, doesn't need all
} }
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MOB_SPAWN_ENTITY_COUNT); } // Folia - profiler
// Paper end - Optional per player mob spawns // Paper end - Optional per player mob spawns
regionizedWorldData.lastSpawnState = spawnState; // Folia - region threading
regionizedWorldData.lastSpawnState = spawnercreature_d; // Folia - region threading profiler.popPush("spawnAndTick");
@@ -609,6 +624,9 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -618,21 +633,31 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
filteredSpawningCategories = List.of();
Iterator iterator = chunks.iterator(); }
+ long spawnChunkCount = 0L; // Folia - profiler + long spawnChunkCount = 0L; // Folia - profiler
+ long randomChunkCount = 0L; // Folia - profiler + long randomChunkCount = 0L; // Folia - profiler
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.SPAWN_AND_RANDOM_TICK); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.SPAWN_AND_RANDOM_TICK); try { // Folia - profiler
while (iterator.hasNext()) { for (LevelChunk levelChunk : chunks) {
LevelChunk chunk = (LevelChunk) iterator.next(); ChunkPos pos = levelChunk.getPos();
ChunkPos chunkcoordintpair = chunk.getPos(); levelChunk.incrementInhabitedTime(timeInhabited);
@@ -622,10 +640,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && this.chunkMap.anyPlayerCloseEnoughForSpawning(pos, true)) { // Spigot
this.level.tickChunk(chunk, k); + ++spawnChunkCount; // Folia - profiler
NaturalSpawner.spawnForChunk(this.level, levelChunk, spawnState, filteredSpawningCategories);
}
if (true) { // Paper - rewrite chunk system
+ ++randomChunkCount; // Folia - profiler
this.level.tickChunk(levelChunk, _int);
} }
} }
+ foliaProfiler.addCounter(ca.spottedleaf.leafprofiler.LProfilerRegistry.SPAWN_CHUNK_COUNT, spawnChunkCount); // Folia - profiler + foliaProfiler.addCounter(ca.spottedleaf.leafprofiler.LProfilerRegistry.SPAWN_CHUNK_COUNT, spawnChunkCount); // Folia - profiler
@ -1706,67 +1696,67 @@ index 1a43c6fba5eea514dd6cf406f600dc254282da35..ca47a512452ae425160e30dc7c4a79f4
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.SPAWN_AND_RANDOM_TICK); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.SPAWN_AND_RANDOM_TICK); } // Folia - profiler
profiler.popPush("customSpawners"); profiler.popPush("customSpawners");
if (flag) { if (_boolean) {
+ foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MISC_MOB_SPAWN_TICK); try { // Folia - profiler + foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MISC_MOB_SPAWN_TICK); try { // Folia - profiler
this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies); this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
+ } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MISC_MOB_SPAWN_TICK); } // Folia - profiler + } finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.MISC_MOB_SPAWN_TICK); } // Folia - profiler
} }
} }
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index e0ad5a7715949c281a94f000e2df5cb2a0a99dff..07037eb601f9dcae2cad5f3e3d5f9a0ac142b68a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -726,6 +726,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public void tick(BooleanSupplier shouldKeepTicking, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index c09099070117483054f438b2bb77ff48a81610f0..a4aec91811cd986333cf6a818f70956d59bb3240 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -729,6 +729,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public void tick(BooleanSupplier hasTimeLeft, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking
final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
regionizedWorldData.setHandlingTick(true); // Folia - regionised ticking regionizedWorldData.setHandlingTick(true); // Folia - regionised ticking
@@ -754,22 +755,32 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe TickRateManager tickRateManager = this.tickRateManager();
if (!this.isDebug() && flag) { @@ -752,22 +753,32 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
j = regionizedWorldData.getRedstoneGameTime(); // Folia - region threading if (!this.isDebug() && runsNormally) {
gameprofilerfiller.push("blockTicks"); long l = regionizedWorldData.getRedstoneGameTime(); // Folia - region threading
profilerFiller.push("blockTicks");
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_TICK); try { // Folia - profiler
regionizedWorldData.getBlockLevelTicks().tick(j, paperConfig().environment.maxBlockTicks, this::tickBlock); // Paper - configurable max block ticks // Folia - region ticking regionizedWorldData.getBlockLevelTicks().tick(l, paperConfig().environment.maxBlockTicks, this::tickBlock); // Paper - configurable max block ticks // Folia - region ticking
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_TICK); } // Folia - profiler
gameprofilerfiller.popPush("fluidTicks"); profilerFiller.popPush("fluidTicks");
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.FLUID_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.FLUID_TICK); try { // Folia - profiler
regionizedWorldData.getFluidLevelTicks().tick(j, paperConfig().environment.maxFluidTicks, this::tickFluid); // Paper - configurable max fluid ticks // Folia - region ticking regionizedWorldData.getFluidLevelTicks().tick(l, paperConfig().environment.maxFluidTicks, this::tickFluid); // Paper - configurable max fluid ticks // Folia - region ticking
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.FLUID_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.FLUID_TICK); } // Folia - profiler
gameprofilerfiller.pop(); profilerFiller.pop();
} }
gameprofilerfiller.popPush("raid"); profilerFiller.popPush("raid");
if (flag) { if (runsNormally) {
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); try { // Folia - profiler
this.raids.tick(); this.raids.tick();
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.RAIDS_TICK); } // Folia - profiler
} }
gameprofilerfiller.popPush("chunkSource"); profilerFiller.popPush("chunkSource");
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_PROVIDER_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_PROVIDER_TICK); try { // Folia - profiler
this.getChunkSource().tick(shouldKeepTicking, true); this.getChunkSource().tick(hasTimeLeft, true);
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_PROVIDER_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.CHUNK_PROVIDER_TICK); } // Folia - profiler
gameprofilerfiller.popPush("blockEvents"); profilerFiller.popPush("blockEvents");
if (flag) { if (runsNormally) {
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); try { // Folia - profiler
this.runBlockEvents(); this.runBlockEvents();
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.BLOCK_EVENT_TICK); } // Folia - profiler
} }
regionizedWorldData.setHandlingTick(false); // Folia - regionised ticking regionizedWorldData.setHandlingTick(false); // Folia - regionised ticking
@@ -783,6 +794,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -780,6 +791,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (flag1 || this.emptyTime++ < 300) { if (flag || this.emptyTime++ < 300) {
gameprofilerfiller.push("entities"); profilerFiller.push("entities");
if (this.dragonFight != null && flag) { if (this.dragonFight != null && runsNormally) {
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.DRAGON_FIGHT_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.DRAGON_FIGHT_TICK); try { // Folia - profiler
if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this, this.dragonFight.origin)) { // Folia - region threading if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this, this.dragonFight.origin)) { // Folia - region threading
gameprofilerfiller.push("dragonFight"); profilerFiller.push("dragonFight");
this.dragonFight.tick(); this.dragonFight.tick();
@@ -795,9 +807,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -792,9 +804,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
fightCenter fightCenter
); );
} // Folia end - region threading } // Folia end - region threading
@ -1774,44 +1764,40 @@ index e0ad5a7715949c281a94f000e2df5cb2a0a99dff..07037eb601f9dcae2cad5f3e3d5f9a0a
} }
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); try { // Folia - profiler
org.spigotmc.ActivationRange.activateEntities(this); // Spigot io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); } // Folia - profiler
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler
regionizedWorldData.forEachTickingEntity((entity) -> { // Folia - regionised ticking regionizedWorldData // Folia - regionised ticking
if (!entity.isRemoved()) { .forEachTickingEntity( // Folia - regionised ticking
if (!tickratemanager.isEntityFrozen(entity)) { entity -> {
@@ -823,8 +839,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -822,8 +838,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
} }
} }
}); );
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); } // Folia - profiler
gameprofilerfiller.pop(); profilerFiller.pop();
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY); try { // Folia - profiler
this.tickBlockEntities(); this.tickBlockEntities();
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY); } // Folia - profiler
} }
gameprofilerfiller.push("entityManagement"); profilerFiller.push("entityManagement");
@@ -886,12 +905,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -888,8 +907,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
} }
public void tickCustomSpawners(boolean spawnMonsters, boolean spawnAnimals) { public void tickCustomSpawners(boolean spawnEnemies, boolean spawnFriendlies) {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
Iterator iterator = this.customSpawners.iterator(); for (CustomSpawner customSpawner : this.customSpawners) {
+ final int customSpawnerTimer = profiler.getOrCreateTimerAndStart(() -> "Misc Spawner: ".concat(io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(customSpawner.getClass().getName()))); try { // Folia - profiler
while (iterator.hasNext()) { customSpawner.tick(this, spawnEnemies, spawnFriendlies);
CustomSpawner mobspawner = (CustomSpawner) iterator.next();
+ final int customSpawnerTimer = profiler.getOrCreateTimerAndStart(() -> "Misc Spawner: ".concat(io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(mobspawner.getClass().getName()))); try { // Folia - profiler
mobspawner.tick(this, spawnMonsters, spawnAnimals);
+ } finally { profiler.stopTimer(customSpawnerTimer); } // Folia - profiler + } finally { profiler.stopTimer(customSpawnerTimer); } // Folia - profiler
} }
} }
@@ -1346,6 +1368,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}); @@ -1312,6 +1334,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
gameprofilerfiller.incrementCounter("tickNonPassenger"); profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString());
final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); // Paper - EAR 2 profilerFiller.incrementCounter("tickNonPassenger");
final boolean isActive = io.papermc.paper.entity.activation.ActivationRange.checkIfActive(entity); // Paper - EAR 2
+ // Folia start - profiler + // Folia start - profiler
+ final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId; + final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
@ -1821,66 +1807,65 @@ index e0ad5a7715949c281a94f000e2df5cb2a0a99dff..07037eb601f9dcae2cad5f3e3d5f9a0a
if (isActive) { // Paper - EAR 2 if (isActive) { // Paper - EAR 2
entity.tick(); entity.tick();
// Folia start - region threading // Folia start - region threading
@@ -1360,6 +1388,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1326,6 +1354,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Folia end - region threading // Folia end - region threading
} else {entity.inactiveTick();} // Paper - EAR 2 } else {entity.inactiveTick();} // Paper - EAR 2
gameprofilerfiller.pop(); profilerFiller.pop();
+ } finally { profiler.stopTimer(timerId); } // Folia - timer + } finally { profiler.stopTimer(timerId); } // Folia - profiler
Iterator iterator = entity.getPassengers().iterator();
while (iterator.hasNext()) { for (Entity entity1 : entity.getPassengers()) {
@@ -1378,6 +1407,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2 @@ -1341,6 +1370,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
if (!passenger.isRemoved() && passenger.getVehicle() == vehicle) { if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) {
if (passenger instanceof Player || this.getCurrentWorldData().hasEntityTickingEntity(passenger)) { // Folia - region threading passengerEntity.stopRiding();
} else if (passengerEntity instanceof Player || this.getCurrentWorldData().hasEntityTickingEntity(passengerEntity)) { // Folia - region threading
+ // Folia start - profiler + // Folia start - profiler
+ final int timerId = isActive ? passenger.getType().tickTimerId : passenger.getType().inactiveTickTimerId; + final int timerId = isActive ? passengerEntity.getType().tickTimerId : passengerEntity.getType().inactiveTickTimerId;
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
+ profiler.startTimer(timerId); + profiler.startTimer(timerId);
+ try { + try {
+ // Folia end - profiler + // Folia end - profiler
passenger.setOldPosAndRot(); passengerEntity.setOldPosAndRot();
++passenger.tickCount; passengerEntity.tickCount++;
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
@@ -1415,6 +1450,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1371,6 +1406,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.tickPassenger(passenger, entity2, isActive); // Paper - EAR 2 for (Entity entity : passengerEntity.getPassengers()) {
this.tickPassenger(passengerEntity, entity, isActive); // Paper - EAR 2
} }
+ } finally { profiler.stopTimer(timerId); } // Folia - profiler + } finally { profiler.stopTimer(timerId); } // Folia - profiler
} }
} else { }
passenger.stopRiding();
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index c1574cdea90731dec4d24b15979209cce0c581af..a809622f43a45fd77bbb07a24f21c841a90dc07a 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -1258,6 +1258,7 @@ public abstract class PlayerList {
public void saveAll(int interval) { diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index bcfe3af0b0df25d4b308b11a64c361da1ab3eeca..422e4cd1606a612056ae335d92786d8a5c46fa1d 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1163,6 +1163,7 @@ public abstract class PlayerList {
public void saveAll(final int interval) {
io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
int numSaved = 0; int numSaved = 0;
long now = System.nanoTime(); // Folia - region threading final long now = System.nanoTime(); // Folia - region threading
long timeInterval = (long)interval * io.papermc.paper.threadedregions.TickRegionScheduler.TIME_BETWEEN_TICKS; // Folia - region threading long timeInterval = (long)interval * io.papermc.paper.threadedregions.TickRegionScheduler.TIME_BETWEEN_TICKS; // Folia - region threading
@@ -1268,7 +1269,9 @@ public abstract class PlayerList { @@ -1173,7 +1174,9 @@ public abstract class PlayerList {
} }
// Folia end - region threading // Folia end - region threading
if (interval == -1 || now - player.lastSave >= timeInterval) { // Folia - region threading if (interval == -1 || now - player.lastSave >= timeInterval) { // Folia - region threading
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLAYER_SAVE); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLAYER_SAVE); try { // Folia - profiler
this.save(player); this.save(player);
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLAYER_SAVE); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PLAYER_SAVE); } // Folia - profiler
if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) { break; } if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) {
break;
} }
// Paper end - Incremental chunk and player saving diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java index 49201d6664656ebe34c84c1c84b5ea4878729062..d9cc1d7e56c37d5ce92544edc10e89dbc89dd15d 100644
index d23914a3ab3723d532ae867db6b954c843030f75..635c9c7a8c8307c2bc845a8e1f24aacb526a3c92 100644 --- a/net/minecraft/world/entity/EntityType.java
--- a/src/main/java/net/minecraft/world/entity/EntityType.java +++ b/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java @@ -1091,6 +1091,13 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
@@ -412,7 +412,20 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(key));
return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(id));
} }
- public EntityType(EntityType.EntityFactory<T> factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet<Block> canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional<ResourceKey<LootTable>> lootTable, FeatureFlagSet requiredFeatures) {
+ // Folia start - profiler + // Folia start - profiler
+ public final int tickTimerId; + public final int tickTimerId;
+ public final int inactiveTickTimerId; + public final int inactiveTickTimerId;
@ -1888,30 +1873,40 @@ index d23914a3ab3723d532ae867db6b954c843030f75..635c9c7a8c8307c2bc845a8e1f24aacb
+ public final int passengerInactiveTickTimerId; + public final int passengerInactiveTickTimerId;
+ // Folia end - profiler + // Folia end - profiler
+ +
+ // Folia start - profiler public EntityType(
+ public EntityType(EntityType.EntityFactory<T> factory, MobCategory spawnGroup, boolean saveable, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet<Block> canSpawnInside, EntityDimensions dimensions, float spawnBoxScale, int maxTrackDistance, int trackTickInterval, String translationKey, Optional<ResourceKey<LootTable>> lootTable, FeatureFlagSet requiredFeatures, String id) { EntityType.EntityFactory<T> factory,
MobCategory category,
@@ -1105,8 +1112,14 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
int updateInterval,
String descriptionId,
Optional<ResourceKey<LootTable>> lootTable,
- FeatureFlagSet requiredFeatures
+ FeatureFlagSet requiredFeatures, // Folia start - profiler
+ String id
) {
+ this.tickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Entity Tick: " + id); + this.tickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Entity Tick: " + id);
+ this.inactiveTickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Inactive Entity Tick: " + id); + this.inactiveTickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Inactive Entity Tick: " + id);
+ this.passengerTickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Passenger Entity Tick: " + id); + this.passengerTickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Passenger Entity Tick: " + id);
+ this.passengerInactiveTickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Passenger Inactive Entity Tick: " + id); + this.passengerInactiveTickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Passenger Inactive Entity Tick: " + id);
+ // Folia end - profiler + // Folia end - profiler
this.builtInRegistryHolder = BuiltInRegistries.ENTITY_TYPE.createIntrusiveHolder(this);
this.factory = factory; this.factory = factory;
this.category = spawnGroup; this.category = category;
@@ -977,7 +990,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT this.canSpawnFarFromPlayer = canSpawnFarFromPlayer;
Util.fetchChoiceType(References.ENTITY_TREE, registryKey.location().toString()); @@ -1680,7 +1693,8 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
} this.updateInterval,
this.descriptionId.get(entityType),
- return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, (String) this.descriptionId.get(registryKey), (Optional) this.lootTable.get(registryKey), this.requiredFeatures); this.lootTable.get(entityType),
+ return new EntityType<>(this.factory, this.category, this.serialize, this.summon, this.fireImmune, this.canSpawnFarFromPlayer, this.immuneTo, this.dimensions.withAttachments(this.attachments), this.spawnDimensionsScale, this.clientTrackingRange, this.updateInterval, (String) this.descriptionId.get(registryKey), (Optional) this.lootTable.get(registryKey), this.requiredFeatures, registryKey.toString()); // Folia - profiler - this.requiredFeatures
+ this.requiredFeatures, // Folia - profiler
+ entityType.toString()// Folia - profiler
);
} }
} }
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index 7ad7b3b964939f5e389d968aa812d74ba96c9681..a7ca4fef8c97f19425fc0d05f5b32d357ceda5db 100644
index 7c18c298e26b2920ea588fc6a16c0baaea9f6fe5..456f15e44e41d65338c0346594be2b0042b84005 100644 --- a/net/minecraft/world/level/Level.java
--- a/src/main/java/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java @@ -200,6 +200,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -205,6 +205,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup moonrise$getEntityLookup() { public final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup moonrise$getEntityLookup() {
return this.entityLookup; return this.entityLookup;
} }
@ -1921,24 +1916,23 @@ index 7c18c298e26b2920ea588fc6a16c0baaea9f6fe5..456f15e44e41d65338c0346594be2b00
@Override @Override
public final void moonrise$setEntityLookup(final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup) { public final void moonrise$setEntityLookup(final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup entityLookup) {
@@ -937,6 +940,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -947,6 +950,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime);
this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new io.papermc.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : io.papermc.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system this.entityLookup = new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.dfl.DefaultEntityLookup(this); // Paper - rewrite chunk system
+ // Folia start - profiler + // Folia start - profiler
+ this.tickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Tick World: " + resourcekey.location().toString()); + this.tickTimerId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Tick World: " + dimension.location().toString());
+ // Folia end - profiler + // Folia end - profiler
} }
// Paper start - Cancel hit for vanished players // Paper start - Cancel hit for vanished players
@@ -1481,14 +1487,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -1498,13 +1504,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
} }
protected void tickBlockEntities() { protected void tickBlockEntities() {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push("blockEntities");
gameprofilerfiller.push("blockEntities");
final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking final io.papermc.paper.threadedregions.RegionizedWorldData regionizedWorldData = this.getCurrentWorldData(); // Folia - regionised ticking
regionizedWorldData.seTtickingBlockEntities(true); // Folia - regionised ticking regionizedWorldData.seTtickingBlockEntities(true); // Folia - regionised ticking
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_PENDING); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_PENDING); try { // Folia - profiler
@ -1948,70 +1942,67 @@ index 7c18c298e26b2920ea588fc6a16c0baaea9f6fe5..456f15e44e41d65338c0346594be2b00
+ profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_TICK); try { // Folia - profiler + profiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_TICK); try { // Folia - profiler
// Spigot start // Spigot start
// Iterator<TickingBlockEntity> iterator = this.blockEntityTickers.iterator(); boolean runsNormally = this.tickRateManager().runsNormally();
boolean flag = this.tickRateManager().runsNormally();
@@ -1517,6 +1527,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -1526,6 +1536,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
} }
} }
blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 // Folia - regionised ticking blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 // Folia - regionised ticking
+ } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_TICK); } // Folia - profiler + } finally { profiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.TILE_ENTITY_TICK); } // Folia - profiler
regionizedWorldData.seTtickingBlockEntities(false); // Folia - regionised ticking regionizedWorldData.seTtickingBlockEntities(false); // Folia - regionised ticking
gameprofilerfiller.pop(); profilerFiller.pop();
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java diff --git a/net/minecraft/world/level/block/entity/BlockEntityType.java b/net/minecraft/world/level/block/entity/BlockEntityType.java
index 63c5bc786010d96dc121ee14dbac99253b3c8168..47e9a10c8d1f12dff335cda787ce720357bdd969 100644 index a2a674f18d7f2c2e50a6b25f9ac3bf4534275976..ace04a8904338a622bdcdf9140b0dec44d3c7790 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java --- a/net/minecraft/world/level/block/entity/BlockEntityType.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntityType.java +++ b/net/minecraft/world/level/block/entity/BlockEntityType.java
@@ -81,11 +81,14 @@ public class BlockEntityType<T extends BlockEntity> { @@ -246,10 +246,14 @@ public class BlockEntityType<T extends BlockEntity> {
BlockEntityType.LOGGER.warn("Block entity type {} requires at least one valid block to be defined!", id);
} }
- Util.fetchChoiceType(References.BLOCK_ENTITY, id); Util.fetchChoiceType(References.BLOCK_ENTITY, name);
- return (BlockEntityType) Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, id, new BlockEntityType<>(factory, Set.of(blocks))); - return Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, name, new BlockEntityType<>(factory, Set.of(validBlocks)));
- } + return Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, name, new BlockEntityType<>(factory, Set.of(validBlocks), name)); // Folia - profiler
}
- private BlockEntityType(BlockEntityType.BlockEntitySupplier<? extends T> factory, Set<Block> blocks) { - private BlockEntityType(BlockEntityType.BlockEntitySupplier<? extends T> factory, Set<Block> validBlocks) {
+ return (BlockEntityType) Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, id, new BlockEntityType<>(factory, Set.of(blocks), id)); // Folia - profiler
+ }
+ // Folia start - profiler + // Folia start - profiler
+ public final int tileEntityTimingId; + public final int tileEntityTimingId;
+ private BlockEntityType(BlockEntityType.BlockEntitySupplier<? extends T> factory, Set<Block> blocks, String id) { + private BlockEntityType(BlockEntityType.BlockEntitySupplier<? extends T> factory, Set<Block> validBlocks, String id) {
+ this.tileEntityTimingId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Tile Entity Tick: " + id); + this.tileEntityTimingId = ca.spottedleaf.leafprofiler.LProfilerRegistry.GLOBAL_REGISTRY.getOrCreateTimer("Tile Entity Tick: " + id);
+ // Folia end - profiler + // Folia end - profiler
this.builtInRegistryHolder = BuiltInRegistries.BLOCK_ENTITY_TYPE.createIntrusiveHolder(this);
this.factory = factory; this.factory = factory;
this.validBlocks = blocks; this.validBlocks = validBlocks;
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java }
index 2c421ddb759eae4fbf2f2420d3b8cab22e854b85..6003e3495e61073c39928918b9d9f4c2e20f3a49 100644 diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java index f83cfa85678d288ece2348aae41d315660095ad8..78211c68bf52c0cd402fee7bcdde223130d49b5c 100644
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java --- a/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1079,10 +1079,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +++ b/net/minecraft/world/level/chunk/LevelChunk.java
BlockPos blockposition = this.blockEntity.getBlockPos(); @@ -921,9 +921,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
if (!this.blockEntity.isRemoved() && this.blockEntity.hasLevel()) {
if (LevelChunk.this.isTicking(blockposition)) { BlockPos blockPos = this.blockEntity.getBlockPos();
if (LevelChunk.this.isTicking(blockPos)) {
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler + final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
+ final int timerId = this.blockEntity.getType().tileEntityTimingId; // Folia - profiler + final int timerId = this.blockEntity.getType().tileEntityTimingId; // Folia - profiler
try { try {
ProfilerFiller gameprofilerfiller = Profiler.get(); ProfilerFiller profilerFiller = Profiler.get();
profilerFiller.push(this::getType);
gameprofilerfiller.push(this::getType);
+ profiler.startTimer(timerId); try { // Folia - profiler + profiler.startTimer(timerId); try { // Folia - profiler
BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); BlockState blockState = LevelChunk.this.getBlockState(blockPos);
if (this.blockEntity.getType().isValid(blockState)) {
if (this.blockEntity.getType().isValid(iblockdata)) { this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
@@ -1097,6 +1100,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -937,6 +940,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
} }
// Paper end - Remove the Block Entity if it's invalid // Paper end - Remove the Block Entity if it's invalid
} }
+ } finally { profiler.stopTimer(timerId); } // Folia - profiler + } finally { profiler.stopTimer(timerId); } // Folia - profiler
gameprofilerfiller.pop(); profilerFiller.pop();
} catch (Throwable throwable) { } catch (Throwable var5) {
diff --git a/src/main/java/net/minecraft/world/ticks/LevelTicks.java b/src/main/java/net/minecraft/world/ticks/LevelTicks.java diff --git a/net/minecraft/world/ticks/LevelTicks.java b/net/minecraft/world/ticks/LevelTicks.java
index 3fc6b4f93885fe447ed068bc5e0784daad655696..7d3067a7df48171f6c8cda12d5da6d721c085a60 100644 index 2caedf1c12e5a388f7b14989310a2137bc1117c3..07e0258e8c2c0c0788e76822e2477fb6f5bc4447 100644
--- a/src/main/java/net/minecraft/world/ticks/LevelTicks.java --- a/net/minecraft/world/ticks/LevelTicks.java
+++ b/src/main/java/net/minecraft/world/ticks/LevelTicks.java +++ b/net/minecraft/world/ticks/LevelTicks.java
@@ -248,6 +248,12 @@ public class LevelTicks<T> implements LevelTickAccess<T> { @@ -247,6 +247,12 @@ public class LevelTicks<T> implements LevelTickAccess<T> {
} }
private void runCollectedTicks(BiConsumer<BlockPos, T> ticker) { private void runCollectedTicks(BiConsumer<BlockPos, T> ticker) {

View File

@ -6,11 +6,11 @@ Subject: [PATCH] Add watchdog thread
When regions take too long, having the server print the stacktrace When regions take too long, having the server print the stacktrace
of the ticking region should help debug the cause. of the ticking region should help debug the cause.
diff --git a/src/main/java/io/papermc/paper/threadedregions/FoliaWatchdogThread.java b/src/main/java/io/papermc/paper/threadedregions/FoliaWatchdogThread.java diff --git a/io/papermc/paper/threadedregions/FoliaWatchdogThread.java b/io/papermc/paper/threadedregions/FoliaWatchdogThread.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..258d82ab2c78482e1561343e8e1f81fc33f1895e index 0000000000000000000000000000000000000000..258d82ab2c78482e1561343e8e1f81fc33f1895e
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/FoliaWatchdogThread.java +++ b/io/papermc/paper/threadedregions/FoliaWatchdogThread.java
@@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
+package io.papermc.paper.threadedregions; +package io.papermc.paper.threadedregions;
+ +
@ -116,10 +116,10 @@ index 0000000000000000000000000000000000000000..258d82ab2c78482e1561343e8e1f81fc
+ } + }
+ } + }
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
index a18da3f3f245031f0547efe9b52a1f2a219ef04a..056fb1ca7b07d5e713dcbd951830b14fc9025f4c 100644 index a18da3f3f245031f0547efe9b52a1f2a219ef04a..056fb1ca7b07d5e713dcbd951830b14fc9025f4c 100644
--- a/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java --- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegionScheduler.java +++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
@@ -34,6 +34,13 @@ public final class TickRegionScheduler { @@ -34,6 +34,13 @@ public final class TickRegionScheduler {
public static final int TICK_RATE = 20; public static final int TICK_RATE = 20;
public static final long TIME_BETWEEN_TICKS = 1_000_000_000L / TICK_RATE; // ns public static final long TIME_BETWEEN_TICKS = 1_000_000_000L / TICK_RATE; // ns
@ -168,10 +168,10 @@ index a18da3f3f245031f0547efe9b52a1f2a219ef04a..056fb1ca7b07d5e713dcbd951830b14f
final long tickEnd = System.nanoTime(); final long tickEnd = System.nanoTime();
final long cpuEnd = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L; final long cpuEnd = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L;
diff --git a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
index b1c07e582dbf0a203cf734fdbcd8387a422af3a6..988fe74578065c9464f5639e5cc6af79619edef5 100644 index b1c07e582dbf0a203cf734fdbcd8387a422af3a6..988fe74578065c9464f5639e5cc6af79619edef5 100644
--- a/src/main/java/io/papermc/paper/threadedregions/TickRegions.java --- a/io/papermc/paper/threadedregions/TickRegions.java
+++ b/src/main/java/io/papermc/paper/threadedregions/TickRegions.java +++ b/io/papermc/paper/threadedregions/TickRegions.java
@@ -330,9 +330,9 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic @@ -330,9 +330,9 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
} }
} }
@ -184,16 +184,3 @@ index b1c07e582dbf0a203cf734fdbcd8387a422af3a6..988fe74578065c9464f5639e5cc6af79
private ConcreteRegionTickHandle(final TickRegionData region, final long start) { private ConcreteRegionTickHandle(final TickRegionData region, final long start) {
super(region, start); super(region, start);
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index f7a4fee9bb25ff256dc2e5ea26bfbceca6a49167..64e0acf28fc241b16a7bc8d3807062fd7758ed7f 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -245,7 +245,7 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
}
}
- private static void dumpThread(ThreadInfo thread, Logger log)
+ public static void dumpThread(ThreadInfo thread, Logger log) // Folia - watchdog
{
log.log( Level.SEVERE, "------------------------------" );
//

View File

@ -1,133 +1,14 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com> From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 23 Feb 2023 07:56:29 -0800 Date: Fri, 20 Dec 2024 12:41:13 -0800
Subject: [PATCH] Build changes Subject: [PATCH] Update Logo
diff --git a/build.gradle.kts b/build.gradle.kts
index 2da91ed6363c0851e4c459188f5e8ef5475e0c97..8d2b5fec6fe27dca3ce01ba1ce50506179fc3b4d 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -25,7 +25,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider {
// Paper end - configure mockito agent that is needed in newer java versions
dependencies {
- implementation(project(":paper-api"))
+ implementation(project(":folia-api")) // Folia
implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency
// Paper start
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
@@ -100,14 +100,14 @@ tasks.jar {
val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
- "Implementation-Title" to "Paper",
+ "Implementation-Title" to "Folia", // Folia
"Implementation-Version" to implementationVersion,
"Implementation-Vendor" to date, // Paper
- "Specification-Title" to "Paper",
+ "Specification-Title" to "Folia", // Folia
"Specification-Version" to project.version,
"Specification-Vendor" to "Paper Team",
- "Brand-Id" to "papermc:paper",
- "Brand-Name" to "Paper",
+ "Brand-Id" to "papermc:folia", // Folia
+ "Brand-Name" to "Folia", // Folia
"Build-Number" to (build ?: ""),
"Build-Time" to Instant.now().toString(),
"Git-Branch" to gitBranch, // Paper
@@ -173,7 +173,7 @@ fun TaskContainer.registerRunTask(
name: String,
block: JavaExec.() -> Unit
): TaskProvider<JavaExec> = register<JavaExec>(name) {
- group = "paper"
+ group = "paperweight" // Folia
mainClass.set("org.bukkit.craftbukkit.Main")
standardInput = System.`in`
workingDir = rootProject.layout.projectDirectory
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 8f62879582195d8ae4f64bd23f752fa133b1c973..f5ff71e31516327be71924926938f1c9f0e503df 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -592,7 +592,7 @@ public class Metrics {
boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
// Only start Metrics, if it's enabled in the config
if (config.getBoolean("enabled", true)) {
- Metrics metrics = new Metrics("Paper", serverUUID, logFailedRequests, Bukkit.getLogger());
+ Metrics metrics = new Metrics("Folia", serverUUID, logFailedRequests, Bukkit.getLogger()); // Folia - we have our own bstats page
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
String minecraftVersion = Bukkit.getVersion();
@@ -606,11 +606,11 @@ public class Metrics {
final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion();
if (implVersion != null) {
final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1);
- paperVersion = "git-Paper-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash);
+ paperVersion = "git-Folia-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Folia - we have our own bstats page
} else {
paperVersion = "unknown";
}
- metrics.addCustomChart(new Metrics.SimplePie("paper_version", () -> paperVersion));
+ metrics.addCustomChart(new Metrics.SimplePie("folia_version", () -> paperVersion)); // Folia - we have our own bstats page
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>();
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..29bd788ae8bc61c1e62a4f84b9e259931a7041ce 100644
--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
@@ -49,7 +49,7 @@ public class PaperVersionFetcher implements VersionFetcher {
if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) {
updateMessage = text("You are running a development version without access to version information", color(0xFF5300));
} else {
- updateMessage = getUpdateStatusMessage("PaperMC/Paper", build);
+ updateMessage = getUpdateStatusMessage("PaperMC/Folia", build); // Folia
}
final @Nullable Component history = this.getHistory();
@@ -86,7 +86,7 @@ public class PaperVersionFetcher implements VersionFetcher {
private static int fetchDistanceFromSiteApi(final ServerBuildInfo build, final int jenkinsBuild) {
try {
try (final BufferedReader reader = Resources.asCharSource(
- URI.create("https://api.papermc.io/v2/projects/paper/versions/" + build.minecraftVersionId()).toURL(),
+ URI.create("https://api.papermc.io/v2/projects/folia/versions/" + build.minecraftVersionId()).toURL(), // Folia
Charsets.UTF_8
).openBufferedStream()) {
final JsonObject json = new Gson().fromJson(reader, JsonObject.class);
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
index 790bad0494454ca12ee152e3de6da3da634d9b20..e741201fdbea0dbbc0e42313ebd33368014c9dc4 100644
--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
@@ -42,9 +42,9 @@ public record ServerBuildInfoImpl(
this(
getManifestAttribute(manifest, ATTRIBUTE_BRAND_ID)
.map(Key::key)
- .orElse(BRAND_PAPER_ID),
+ .orElse(Key.key("papermc", "folia")), // Folia
getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME)
- .orElse(BRAND_PAPER_NAME),
+ .orElse("Folia"), // Folia
SharedConstants.getCurrentVersion().getId(),
SharedConstants.getCurrentVersion().getName(),
getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER)
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 774556a62eb240da42e84db4502e2ed43495be17..e9b6ca3aa25e140467ae866d572483050ea3fa0e 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning {
public static String getBukkitVersion() {
String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties");
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/dev.folia/folia-api/pom.properties"); // Folia
Properties properties = new Properties();
if (stream != null) {
diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png
index 8b924977b7886df9ab8790b1e4ff9b1c04a2af45..c06126b92e36566c93b901637926703bbfcc42ff 100644 index 8b924977b7886df9ab8790b1e4ff9b1c04a2af45..c06126b92e36566c93b901637926703bbfcc42ff 100644
GIT binary patch GIT binary patch
literal 36428 literal 36428
zcmV(&K;gfMP)<h;3K|Lk000e1NJLTq0077U0077c1^@s6tyr#}0052?Nkl<ZcwX$; zcmV)lK%c*fP)<h;3K|Lk000e1NJLTq0077U0077c1^@s6tyr#}0052?Nkl<ZcwX$;
ze`u9e9LMp`_nh-Qce~qdxtz{Y5;X~l%2LdP2>;WtinuKj$t4c@tAY?f!f62s6;MC~ ze`u9e9LMp`_nh-Qce~qdxtz{Y5;X~l%2LdP2>;WtinuKj$t4c@tAY?f!f62s6;MC~
znNkH6{%4hvv=wF*(`jJlm}#XowOPBrp69ve$2S>_KnR2`;q?1DZ~)Hv_k9kBgUgr@ znNkH6{%4hvv=wF*(`jJlm}#XowOPBrp69ve$2S>_KnR2`;q?1DZ~)Hv_k9kBgUgr@
zLI@#*5JCtcgb+dqAw+LqufauxkTAGcZ9Bes^|l{36fjN*fpz<f?JpdDddIVS9<LQ& zLI@#*5JCtcgb+dqAw+LqufauxkTAGcZ9Bes^|l{36fjN*fpz<f?JpdDddIVS9<LQ&
@ -442,9 +323,9 @@ zT(qC@{D5JGoRLx{lq5l+FfARkGGqS09xlD=3XZ+$jr`4%9;SDE=Zo07VmtX64_12S
z6G)GEFzNjBupQg6#RXzCfMIJ&37Z?h+A7W55YG}h3otVS5^~2<!U$my3emKPiU+tE z6G)GEFzNjBupQg6#RXzCfMIJ&37Z?h+A7W55YG}h3otVS5^~2<!U$my3emKPiU+tE
znrtx4L;9nqZ!fpq{k8n_oeAVAkD2?#<mfti-1ht<wk^-C%r;Nk+HHr?cmS4=M34wo znrtx4L;9nqZ!fpq{k8n_oeAVAkD2?#<mfti-1ht<wk^-C%r;Nk+HHr?cmS4=M34wo
zLx2~PdL$t^ghPaQAQs4W`GfZH>p%39^xH2qSzrj^@(84$Mh|k<Pxs8Gg+y@PzGX_k zLx2~PdL$t^ghPaQAQs4W`GfZH>p%39^xH2qSzrj^@(84$Mh|k<Pxs8Gg+y@PzGX_k
zZcT2@noMdEAyI2Z4iRAz5LoGZ&OLvbTW(roZaiQ(NNSpfL6aE`8UPDG^uOD?G~k+B zZcT2@noMdEAyI2Z4iRAz5LoGZ&OLvbTW(roZaiQ(NNSpfL6aE`8r!=x;F?<|Ja#$R
zCOmdI*}4XFAsopFkkN;jd1C5`)tcBWGq#SyTc5XP|LsRl+h0HGyI8*bJcf&7asy4% zx(0M19LWff(TA9MV(N+2n%FEewvNMFpSNcJ?MF}BUq9-*Sibx`hKplz15MLlsWBrc
zV5u=9D1&Op%LW_Gn6odrgwfiRPk!Z#^*3MhrEJ9QjK1g@HupJ?Wpd~+!<CCI(?BxF zgKEbB%0M;0%LW_Gn6odrgwfiRPk!Z#^*3MhrEJ9QjK1g@HupJ?Wpd~+!<CCI(?BxF
zC=7%Ez=R11uw?Wnj*-U$OHu8C5QwNC!`#6d%cYPci&_Z`B}3jLN9D+|6JK!I<yQha zC=7%Ez=R11uw?Wnj*-U$OHu8C5QwNC!`#6d%cYPci&_Z`B}3jLN9D+|6JK!I<yQha
z6UaZ)C;sBgU*e~a?QHUp)Yy=J#Gt7UN-mc7?V!8wFph&I@B#{fkUIeoj(H$CiZB#J z6UaZ)C;sBgU*e~a?QHUp)Yy=J#Gt7UN-mc7?V!8wFph&I@B#{fkUIeoj(H$CiZB#J
zIPOkgrwk%U!!bEJi9q2b2}K}>>J_NC;Ly=6UHXuVu#<N}N~l)6I!S?<VN^1bMPNy+ zIPOkgrwk%U!!bEJi9q2b2}K}>>J_NC;Ly=6UHXuVu#<N}N~l)6I!S?<VN^1bMPNy+
@ -758,12 +639,12 @@ z-fU;u>{b~ZpbpNVj?N;6dr)2k8$xa|%aRh3kV2sV3By2uK*GRK02oHHq(lgrGT}3F
z0%EAZQFI~=3`Pv{P_%rW<#>r@j?;Cw@gK{XKmaa(<Ry>pbHzMC5~hR+GYb+81tH8F z0%EAZQFI~=3`Pv{P_%rW<#>r@j?;Cw@gK{XKmaa(<Ry>pbHzMC5~hR+GYb+81tH8F
zanGqu``%|>&eAAz{v`+PiLd)h&OYx;S=o6&jb(BUEsS<@>dud{J}Xw{_8<=wLV~0U zanGqu``%|>&eAAz{v`+PiLd)h&OYx;S=o6&jb(BUEsS<@>dud{J}Xw{_8<=wLV~0U
zav|Y}2;oX#EkXn$<Oo?Ph)AFTFgDa;DwZ{YdW!5PjdB?EcSCoNqB}~|bt!t}Jw!Ed zav|Y}2;oX#EkXn$<Oo?Ph)AFTFgDa;DwZ{YdW!5PjdB?EcSCoNqB}~|bt!t}Jw!Ed
zNRXSBrWs+@0s$iq-0>##KW%^uhyWY`;1&q85yd;2WCjgwJ2Ll5QHSM$<!0Vp@ySxQ zNRXSBrWs+@0w(l7ZGa1i02~3}76`Ku#XFj01`TaHGWSYRhvk9gX5L-#$x^m{6A=IL
zeiIP?@tg_d10VRnbbi;tud;E2IV2NCQZvkiRXiL6?pfXBWsf+Ei*~l`KW~9o{@}aO zoC)LuANas@e%HaTvT=hsBojtbGt7ilJRAe=S>5Dik2s5qcDC$4Z-H0-;JeYv=drZo
z%IC4P<3f@(CWMhJWmsI?#nGGJ#@5D!I)64Lum}hxP%@Vj;fioP99hDZksO7nDk=&< zLXtHmgpn*|SX|u2(VO4K*2aW7e>Nqs2nZ!mGM5wKif}v}S;Cc(9EGSVDhfb^SA-)B
zgja+k47W`2N|+N7NQTISvSFD}80G+wgdvdQUd??<@fi`alrxfKfCv;$lZ+Hj^`NU& zw@mR$m=h65hRB4nVVO`E<^Yg{A&}!<&3#Jo84<FSGm>P02oz3}j1*4wpsQ7VH^p;e
zeK*B(V%V;*uyhu?cAd-o;sLhryo{B(^B6B~ce(z&_G@3rKkAHz{{U{k=jvaZ8}9ms z*sid!bQZgIoy+{<0k-eFjFq|b7%y&jx&FNNYhTDe>Wqf}0B*nM>R+21?)rvBOApR!
zMN1FPYG|moJeZ?~z>LjOxp?=yo_@s++rDQ`AHMmt{ly*IIOoELGa9sDAdK)p3K_DM zXsEV4n4<wA4c+pFz>LjOxp?=yo_@s++rDQ`AHMmt{ly*IIOoELGa9sDAdK)p3K_DM
z<pbP$>)&YqSx>QrZRcYrZ$yHSLx>b^9swb$J1(b5W4X2ng-L;jfFPm}?n1@PhVtqr z<pbP$>)&YqSx>QrZRcYrZ$yHSLx>b^9swb$J1(b5W4X2ng-L;jfFPm}?n1@PhVtqr
ziI5W^03s?6Ocf=$2>=&_nJQ9{%?MRyUB{rw7Ct4Hj%@@F-`;cX0Ci2r`g+)%jJYd@ ziI5W^03s?6Ocf=$2>=&_nJQ9{%?MRyUB{rw7Ct4Hj%@@F-`;cX0Ci2r`g+)%jJYd@
zY|M;}%|o~sk<5mJv5GeO$%(a>!}JaO-#Wwi4`T0y58YMoIdTkw>dr&YU*U@`-OKmA zY|M;}%|o~sk<5mJv5GeO$%(a>!}JaO-#Wwi4`T0y58YMoIdTkw>dr&YU*U@`-OKmA
@ -830,328 +711,327 @@ zBq)Y_UrzM}lhm^PIRFB#2ma}vTKd{uO*4J<v*R!7ct=^;PH_YP&Km2{@s6tIv8N6D
w|1kyt000000000000000000000001h-~8pj()Vetm;e9(07*qoM6N<$f(agZz5oCK w|1kyt000000000000000000000001h-~8pj()Vetm;e9(07*qoM6N<$f(agZz5oCK
literal 16900 literal 16900
zcmaf)RZtymu&!}kXmDLfg1h^|-QC?ixG&s2I0Sch5AG1$U4m<HKb8ON+PC{+s^+4r zcmaicV|1Ng^k&Q(Hn!T>_Kj`Zc4OO48rwD-G<MS1Mq@Vi-2P_Pf6b?v4@vGy-W=|C
zXQu0|uKD_XI#NkN5(S9>2?7EFMOsQs1p)$M^xuU52LS<5tyS|A0z!B~T1;5Y)8HZp zpS_>w*(Xv_UIGaL4*?7e3`t5-R2lSh^xqd84Cs4}W^FDQn9zijsF13M{zVR~<`0dB
zUh9YE!*I`C!>au1!lt}?^7%)ymXa9F0E8%U6cA@Hs@r2|t2YjT?MMEK&sF!xR;P(1 z;hww3Rk_uLO*yyZ^N(arMN#SjFcHEi60E_fZug<B-Z(hc9|bGkSKT99oyHP$K-u|n
zJxFf8OgT_&`%_^18f74-j~9B>_v*F_4QG7P$=~I&{g0k-!dKZ;dhG_Yv84aKQ7`JU zr9jc`PyX#|q=B419>`IjtJ^LVtno=lKj+Jze{_WszRIN1X*HUTCH>C_wc;+D)6YYT
zJ^ehid=1+b=_P#o97{5v??~H!^zyIS&U_=f-+Z&XS28Q#IuJUNE}ApzE+z8$<M**` z*RWmTUi`Puu_Uwkj<o$pPrusj%r}Dj%{SY7MbnC{1HmJy;yKgqG6L^Ez8~9WV_rtC
zKIU!g_So>!_(s%I3_!)=jTdGmXzz2p&3&czvSwVkj_PR|SM`xDjT-m<)@wFKtJ!fY zkBu))Zv;Ih0AviFcp(<NpM4Iud9PHSRtyW*Q9aG$D&A6MQR80UdQHb@G&*iYdL;l6
z+A9f&c$RQF&Z%Ui9@S9nRjlxMs@)Z5_OxNu^|5JS^tNFPeEv!Mp+fj^Yc}Scf482J z&*F~9IaLf)qv{I13YG3pb-Q9r9@Z>6-qwu_Ue*kO&$%=o%J?6*rej_Ock3znkGIb6
z_jv2_UYgabd?1AMePOH(|ApkUIjM`|sON7?4||4r>}#l#)Nj}LPNV67U-a5cAqgk9 zWm&yS2Z9LS7slFgUx+?ilDgQBdj7`ruw|IVzJ@wV{&tD)G@SPTMW@9Wl5lcsuU~6`
z4hA)b1i?G`_{?Is2NgH3=G*Y_oV4G*#y>w?4I7fSpx2h|vD&hsqdFVmofnVkNpM8o z7raw|%Or|@P<iuewhar*LG$fv{PV-rumN!^YF+sriw!F(vXddsdC8crID6#HGQV_Y
zEDOkF7WVse0CrXXeH^X&Y+X5Ugeg(@8XVq_7ng<WSLc%Q<*-QIhnsE4;ZV;$Me+D- zQNMQwU{~ee<Y?4p>nlh`7!!rA1H$`p;<B)P>zz}+92Tp2bFmKDAL`nrC>)<{qBHso
z6O+kzkagG!u1}sMYVY^UJljV<@ZpQ$9%*p>H%kQ4q8to@(w`VD%+t{VjBlZzMA{89 zvJ6|o^vMxL?frh4XZ`3WdH7<mM;zSn%>s_NI0p@{EElbnX*!yp;Vtx&K&w$&to`sW
z;%$e2aiD==VT$}%!%lBb<H%>Y3xicyog$jB!Djxd7vpR6bXArR{Oqv(5MfWsJg3Yy z79>enm;xWhu;ZKKIN}-h!eBK<r?3Weu&JNQ#rPT>ZM6j$9~*Q(SlE*i_bHS0o#tPY
zcUpf<i*XRQ-u8j=yfnTAd<;#}0(9p_Mh7gx&!`jRA8$wFN#<^|FB1MW+fs1Cf@q-! z5-j+ww|x>h9%`RLUixM!e%f<G!vp5vXXFX8kGG@oBs1697je+0Nx}#TpoAWD*|IYb
zU3MIdBzL_H_z&sj^8+k=#YiQ^+$Ny8yzr0AeUGmYlYGdR`w9gb2Lx)?IbkwW&1DO6 z-Ssx&KBQO74>0qVAe5GH83X6?!#^_j-M@lO@*-aD%NMF2;Hg^Wgh@}elrPA3o_&(-
zooAoqd!IA{afAE)J$MNE8EDL($_Qb7^jY-Tsb5DMjT&SWxeu;&{9Cq-;QIVXkZ5c- zeNyws4es~%;K1o+pfG(Z!G-nFWzl7)ejRNxY?M~uI=I&MYuz@4>GLH*ptjlQJ`LYr
zx=+LR*Y)a+RPIfjC{LhfzZvst38Sh@J6SdEVEDi(KywY$Y+}Jl1d*UV+;mz*KDAhz z*KIIVzBhKHIDwe`X2hc@gsdjzXxX%b<_#kc$vIHFi2)-XM1=fs(`g?0)M{lcJXwp<
zh)mX?^+*da+?k?h8~OJJ8$%paIkEkT+36F4*KVjH2cBc6;=dfslN%vAZH(Uy{cQfN zBgIdDXM&n-=+_%;1a?sE$oeN{r%w=8tFfAl<Qy{<_vK)o%n;sjWBhI?x8=90Lxkg`
z<{05LX(3vHPxFA6xPb50ypE5TCZA6YBZ}<-$vEI%pfjQkh!CS-P8y7_5rEIXH{0%v zxkx20^#e}g0<LSzIxbF{Tmco72&OwY!+=|%_J|fBLX?~-X)wN)AGYA$bh|T>QopAk
zq%!E~hwvPQHvUZ?Ef@P@;F%J@*kGou23nY?0$xpm+NOfZ`fm2Ene6n`CX^hNmZavr z%wrVN=r>)oZ0w7^M~Xi~qp6lEaABgF<Z2SwJ{3&bce8KBXsfF_q3EEvBsuR{Xk!fV
z3T#cF-q`UEca4lZhb{Zv1|e5Gbiv~cN!HZn5QX1Ea4!8`@;BL;2G8GnVZc<^iZrFL z#)f;iYiQ^(Y|-yJ2)^R36EIGnWJP5LR`fjt>(ck7V3Un;@cg|ODuD7@fw~OZ;^TQV
zmLJcfN#-n&{j#vj3m1P~7JF`tq<;B|g<?0_V4;>*M1f-z9ik)<Z3n&ko3>^?H|-}` z$&4AiUj}-4;o`6JV$Y4C<S!r5P|PN44CIQ+sDKy+`zUdEn?bMs=B=5}O}j~Et~>2G
zxbJl0Xc<(adaW`;Xc^eA&$kJ4EZWH)dOO+mFzw;MBfNjA5<1ZP>E3RWzD|&L1WdK! z8hVweUdzl78hW<t^KJYb^Pi*-y`5~j=yosxBRqeq6FN})Y2R*>zD|&J_)oRr2JdJP
z2k&T-AdM3|);yD$reQ{x9G{_#6R5f}9%tdjf-W#_wS$qa(*X;ot*Gkja`g1Q_eN^= zA&lca);^P(q@hQb9-kqN<EgkX9B1Lg0x!^RwSp0@(*X;oZOCftvUGI4_lBx=xUhLb
z`0%;Ho3r-6zU-m(+)f%v8KxzXfn20UBXua$j&hd^L+a{0lv^F@IS92I<OY%c!ol*K zo3nPmzU-m&+)f%w8l)wW0-YsCBels@kMfp_Lh9??mD=nZ*zvU*Wd{-d!a#GMo*nMA
zo*nMA<@|~EJJV<8>L#!_sffCl2&zHVp_~j(J1np!W5n69+~xPAJ6}_zBa%4jtFt9W z=lqHGJ=0_2?8Y-csf@Z852{7hrkD&)J1n#!Wx(38*yZz}JzrCxB@jR9tG6LU{M;p+
z{@f*=wRJ|ZitBopGm<ha<ogQz0D}_=VefQ-dFzyrIj$n~KD=LR3L`)v>@A{J`xa&M zwQ)kSjO%)r1@%(I`<3J)ARrMR`c8)=f1Lt6$3>XVo9An7Q3NoAtyRQw-@JUDD$o<f
z)PY`TF0^X2?f!}827nOWNuI-<r$5<TE%a{e3k373M9lQ%RHs%RSr)PVP<kxBXcZnm znMRf7r(dF(J|Ki=lKXJy=}$IiE1fIb0^Ym|0TW#X<*B86mU(PHgf6oWN~L>luryjE
zgJm!x;g~C$@#FI_>}Ne-gU_A_rT89Qjihq3d_{Ugx}ge|kRq}v@?<-}sM1htR5<=} z3{zzbZhStP-K;xw@Yxf-B=4h(p=4f`k8p2DH$>qQLPR!szD!2|vJ}J`C6=EoRwG^+
zI1L1)$lG(bP|&c#@>`Np6h0xGHe-S%SWq_<x4Dzlch(EG5BQ%Qqe)*6^zW6~@M``# z;`ZDv1SGVO+?IqSxpxSM^_V~@2E+~dZQdl+oz;TP1MX+XXwugMy?Z5AoZ7#R33Y@T
zCDamY8s8Jaa~2g;DZ|q6lDf*tg~lJ!!^4{=$Wcp@h{Rq-YeCkqfsMBv=tV{(jCL{| zM)w4;9L0szO3>6i#4fV3q49@wu&`zcvQ!d8!m*dpn&7pp0Y=;QbiyOzhC7)Ki7tDt
z6J7V*FaUy2Q)|?Xlq6r!8)bWEQlPx2ux5Cg5uzT>O*_rH`M&)M5xj9Un#*HS!PqE5 zXaIqysWqx53ZgHlO)|YRDG**$7&F{0a8VEECY`3;yx)F>2;4Xr&gC;Iqiqx;orWkF
zISo-XF(NX8c$<8iK|uH&>qt?Q&-b}D+Tgr7t>MFp&WJTZFnPZ1>|RTVqu7iauEwTX z8xk0Ty-mK&z`^~Fbs#S;;Qd@1ZFJh4R`+H>Wx$xgn>^oka;w9~QfR>rS7lYHG?D#o
zVJi3CHpH3>2eq__Ox+k#@Bzl=K|7STdhX7MT{c8Ce71~q9Y&PXH}*iaRuCUgMZj4H z6Jo`Qg<Muls%8W(@Bn4~pcP6}Gk0gmCKDnOK3h(_4kg0j6MLXiCxDBi%<rTP>_-DP
z)Q<sa+KPzRqz0O{-kXtzDagS<&%r}abao`SSO`yF|Lj?rpGDNntoJVWe}|8U>yHub zX@kdURs~L5?afF*73QF!=HQ?vIysP;FNCMBfA*}*&%$eDHh5L|y~D=C^v8(wdtcYZ
z_qnc(rzc$MCNk878`Sofx_>n{BwDNL?TS=$RO_S6!R*Ey=`(aG@LbB{HGQ+@MqP=h z)8Q|56BuZ~3~KpF-oKg|5Uf@Ac15Z>sP<9hpm(E>^cgr8dMxGhn7mnWA+JPK+EGR;
zu&0VvO0ab!36xlai&*>Xc+6_xPmdSo9TasQ3?*TY!)%lYzD(AZ0HWie+au=#fiLo& zCfK+V1&Xi1M6CUFIA+oJqr(aF3W_=ph7h;IVlqq&xJ=d(CqczQwL>f*A$gJW_|iZw
zU+O6Y`-6UchQAZ*C2TI_f~f(2hrMt6KE)jP36+(ZZfle23Dx>Inkk_7xY0&pkp)+N z&>!^cGyI)UH(_%jFMta0ci8K;?^D#C4_`@%@wP6R4qvs8y@ecdj|*ia7Exg3*BpG4
z%^^0b-mA7bkD<)a8%J{cvSRJ2S;}#v9g(doR}TQ3QGy%7T$YWkQuW{|T0eu$!D%Gg z%Dqav(-_hWolzv04-3Ygs)Z~U$`R?hQq2Is2`RWS%z4?!GF2CryzMjCEFg_Y%K+yz
zhIpru$xwR_h!F-%c~|@zigH-C2m<JnIbRGUJ`o+s{0B$0h@KfxTQq^K(h!%+wnmUZ zG8tm;0X{;XG5?BBT|pMZ296(fGUtoF_$Ryrso&s;Cc!g3a;pYOn-tjPvW+1)iAQ)I
z&+uH(<{{~AZ3;c1s&I>=8{D8VNnCdFPc6Rfz(8f#dDmuUW@`u=TQn?l6ex-ha;(`` zaPyG(wl0MZUqz_Z!4+oEh$t>QIaiZ+J1|fQdfugliOCAg+6D!~3<-k#gA8N#Rk3@5
zrS1uS-(@|j8cS+#fW*WdM9k{Fbp6f|!@JL%Gh}@yEWnT<?~y(gdk!gF4iLczhzP8A z&u3Yevetsi3m`sm2Ntt>FV(PfME~wR=LFu+2@Noy&wr###hgP3mjy&H03re#97OQ%
z6eYZ;NxgqYm0WAz^WFy?M1rvTjaYzkZ-k9O0o`V+34a3+%6{bTw=UzMuGx9|_wc1E zsZ;NtktNoC?s@G44<dmW{f5jWvTyiJLH^yQs|kPo;mUvH?YAxCAg|ea`1SCn%9nW+
zlzJB;CAmRbWieMfkz)5Lx6QlXVJsZCW2NX66{xtNY`ok_u9t5`tiF2O8sRN|iIjwm zAtbqiTV^rUI1*#_DYehL-JvZU|HMeqE-qAdM%s9}lUT3VidcPhzcs{J{1Pbv9kWhq
zStm2P{thW%Q3u7>jE-<YhsXZGBt`Inuklb3vv0q7ty;K7T}G$@6MPS5K4N^c{Wc-- zc>Num-@G1zw*?jMf)<DEgHaOi16Tc_GG^ay^ID~7jj9}99V+-ffa!?g&F0&L_z(A~
z!(-|(z>DYfVpx0s5?hF9Qzi@Lf>~6Pm?DX{;HP^Q242(r1D1_=jrbppWF;PQk_!Ls zM}JT5(~DuP{Yy+if=%fxqzfhy4MOrHp2A$WEHs?v`3DSZv0AY|>dA`SWJHyI-Lp=m
zS?3Zy6SOYNhA^`C9Gr`$aM+kF+PqIpNc~b)YOTag^;@K{!LHyR#-D?kKh>QZn&JHs zyv8V97L8$~?>Sf(&Ee27TQvEf=-_%~EL56_n`*ZRVS`=4Ka4&HGjr9P8e3rf;8BK&
z(S}LQ;l-T8IWrlT$vDeig`Pf3fs);`cyZgTesw;vUk*#=1ZlB5zS``R@)U;`I^|DW z&0s~H!Z|V-mPt9vUj?5&%Sa@;XK~`TS$ylgW4|1h&I!<9c6_zoDdR2)FLErHw%Sow
z?`Wu5^KI6hZo2(M-a~zF#>3kiX?zjyY=f@)xk3s24jF8WN!RqnV5qMC{5IS-?p~l` zwc_2ZKizcAMchMvZ^6OY8)<qG>uiUt&RwA(`3@dzgihQ1MSrNi;ruq-C+?oVa@U0x
z*Od<2Atam`NRWyKlq2%T>WdXRFci|p)_QD!{us*BG6#&@1J>-ygf`d(+Yt%AR?$|m z(>^4ei3Bedg+!LX52G(u@W4P&3sdv45%OawU(*aQat~OuEf?Hi6Zi>__qCd)nw0_j
zG2&h}ZNhe<x)?3<qMqjG%(&Ex)~h>;3iL&t-&Bo~bSQvwc_uqFF*q*u<%r&3Io&Jc zvUwA_6WQ5tnFsl_AZNz8L8L*=L4?0A>inj9l&C`<n8!WYp@GJJsV7VD2F>AC71u=H
z8X3Bs8jXqH@NHmV7BRmCYCHHs=Nrep*-}>qojz9eD&96O%Es8n$%gaSnOL~VE%6i@ z?bu{Q_=al@1+|F&El|te2eQB@?#+g(D(LjFx>w=0X;CJ|CQc@tuin_)Rd$KH$Y9P9
z&N;!@pfy%G7dw?+2y1|uMDE?45uzNTNB_7>aX);UvtG>N2^CK4jXJOIypMJdF8LKU z${MAq+Ns2`>_SLAfKm9~%?U2bK6><zn<Ur6w>hiDEbdUD#NMd$hR*wFx8TxWVY3Za
zTYqIdp7&|wl19M2-A~xsFLDE9e-nocdK3)_YdtcQ)W%k7bx|ihJbIc=Z5ZyZ^yh9L zM&tRPhR$htT-*KlZT-SGBy4YD;6aZfAz^Jt1`=ABifztn#D_;u)2WTa-Bo^EKL;=o
zz(%H87tSJzNkw!4yq5hajBkYU#kO&cksLk7!K-`GO(iyvT=U{|HBlNQU1VB|)w$-~ zDc6Ov2x3y<odK`qKZ@d;Abc>bU1B6gkFjv-UvyFl^(EFkIb4ht2Z<LM*J8D=dG^q^
z!`vE~Br`P8J<1%ly9{1OIZc%XlCTOPAdcit!jhpR;%=Zn+J^5sT)?#vtC4a+pY5iB zMkYxOjCGDOM{O^I*O5+BWk`rv1mWOE@+P54krJ^tP#<l=ckM4=+6h&OIU&z>(*io4
zJDz5Ru-Z>~+fH$VWPdd~FVQ(AT}O25HPC_wANYArttZij2ISLx>m75xSQO6+R*;0g zW(6^Rp7OMxVh73mYH?bkbxgXB=+<qd2^f6f<36>TL>U^8OY>=P$oXPkGAmF?6#80T
zmeuq!90F_}HX%kFZpuj4@q)SDa3k?+Bb2PrSZjTt%acFjLT3$4HPduPZ4Sfv?#~)_ z+e?24uzuJC8?nCu`7)ef&Nu8x+`0%wOB9wmZ^(+|&$!T80~3uj?NRH)aNhf~#vN9e
z*x>rvxpNnXh2P;_1YzBnVcqa9VK{mn1MhEaK>}|FhPXm?dB28(cqh2<aQ(E5eBk$f zem1VW#bKd$SZ4ufS0-pzoJ%P7UWdT@8yg`1+kpYLV153t;UJy~P8@7sO+#<ky&oE2
zXhOu5zd5gn#=c+vTG>Ag&XIAnbGh%w38mufD688Vg0{`stk3i+PA1e~X7W%o(N09G zaTRY)D<ZM)m%mo_4}){09c-QN`>{ePIXcSgw}v2XayA<>Jxh}D)tMOGRgJY0QEJs`
z(V+dK5Ra`6>fQc$6V4g$Mc;jTrbmt|ZcfPDi&luFxnBGk{2GGnMACo~C5VWy9A^BK z{>aB;ssVeqKi-6L#(PnBpPuOu<4Rf*GWVk8BdM<!bAw+)5FLpck)j0P;g-XUo>Cd}
z%9O|VK>O{=o7e@%H==p}Gh9?4J3)S(^K@|@-bpGMlMM#a6u}N>;hDZ{$m0w+?{P+i zc^_!LU3n2YWBEk1?0<%f@MkB;t#h0%&cixNCZn@Lft$eDVl6z=l@Ga}k<7cF5n!!o
zv!bb`WN0Gnx5bB0s;!iJeK(?<LJ-dXRu>O@&xo_Yr==8dbs9N^gw0u(XK<y5w?dyc zXet^Q3;AyG!j)+$=3U>7D5c<q^S#x_L*FxCE%0h8`d^(!P9b1&)aUD8>Ef)=<q!3`
z)a$+g&xyOCWn;D<z-4)I7QKFvmV)ZQ@wBYI#3q%m)W*lhSISyiCsazEGS1p8lE1)# zEx>YMZ)jSZ?)!6EoSa3kU!<iV+p|9{t1Yog7AUs!^759kl+_ECQKgKtv<Me0u){xU
z_^8FfD5K8oA3|kPpdN8v1L{mwC|fV!*`NrE)?hzJDcwO>a5#%g4gLt%5d9^x&bUp+ zvNK4lG5Lj18W*ZXoYw+7Q{~Io3%NJQ!=lyM&XLM?;1=x9;!=Y@!qr8739mD3ld??W
zI*CuQXb^F)LGcsTq00ke&-aZbA7<pGjOF(_S|Pt5M)lu5W;92@!*xG|2lh*QeQxy~ zk}v8<+^du4Lfdz_gYEgeF&99Myp%KlUPme7^F^!q+sB0B0C>3W2Xn`K`Pq<Ha|d)N
z$g!BuyQ8D9vma$My_5FGv532J!R?oH!Re~vD^o8a1UK~>b?Ow}kNZFJJuWYsoo#JJ z;q~h1DC+D-+Dz}H`Ee}lrc`+QC0$^;y5!2lQxMKotyYaHh3Dh`k6e%Q%VuYLdoeFJ
zd^|iHd;0^2Lk8)L=de&2-C9OWIvMMW>WH|w6pe<w(C{@#n$-IGNY&KruO7Hu)T8vC zH~ZfHz~PX7I>R|ML`Ju!A)|K2`l1><Ha2;a0S_c>ErJG>o*qIC72B&jHYe36od@P!
z*muol#eb?iAulS}{q(0Y{Ez0Ya)G=5Wyw?cgMz+VY-tLjPQJb|z9k2(@WFTc)Ok2) zi)qQ9Y7g*>N;Y4;sSLlPxvM;q-Tzw2m;Zx=x>{mk0;Ed5zA?Hb1FrDGc6-;m+iSFU
zwsm$+w2;kT>Ak$qJ4MH%Wu;|h=~A6+4h{@J3knK0*pJ@vag9^60=vvWcI&Lb_(VX2 zc22aC&R^-iyw5vE$D?GWWo7A5o@@>d3_uD92sGM_-tlsdQ?ZbAnF4LsSxDj&0TFgO
zy)N7VOA=(g{REg_f)&_ekDo9i1vl8j0R0zl47}1}4kDqz)m%np1-97YCtx<!sT41J zFbB*@;0<;Y0es>tB&~M12_up)gRS(Ce{seFR$9$~MC8~S%gCTV+2AIiH`gndEW2~H
zaJTs_DdiJUL7Q}@LegMCL2ZF9>X^_8E<IMcJZHX3{+Yv$8*d!QPI)Zy<6{N3SZ2Y( z`z|RK5KuxIccy|<V?aP`0WazqQSmO_S2;aqzDxX>!;Bkm8puw0EcWFE{ij71G*o4(
zRHQnRbDzsDSYt-;?hd4D7AO=(Pd?VXhDTW<-~l7PGp?<CgEsMLp#f=K2gL1M^CDQY z0~y!3%z_nq1kdh3x<;XVQS{_v?Q3|H1so1Z#CL|Zm2Z&7-mTO?&1?U-oogOAE4Cm{
z2YE5P`rx>b1U&2>fjdHvFw8)9n=P<XR)vYwTQ}=fjxb9Dv{WAW=&PJ?Qd0Xk00<jz z`d4o(XCnWH-J^hx&?7X^xHns&B`u2*skUy`s~w=0252bVaZy(}U?e5?u>fG!UbYaS
zJE+ilN7%&?0!w`K)fPCZi))*i)-kTY{*@khj$U3|wErJ%b?gHGck`onT`i&xz~QEN z4Gz$YBX|~|U$??YUR+zxw2g5F_OJB7viI^}qx|ouEswnc0o{D4T~~|912EVr9)4P&
z`fI}tw%DtJ6F{2I8G-#PUVX+U6p;UNz)MLLE_qH4(ZTki+;mr_0Y;Hc9334!y}Tkx zS=*@uBmgy>GC)sz_8A$Iga2y-R#LKP$zyVe7P=4Vrn@Q)Fp6mG;Nall=^07<{OPT~
zpFe#J)=7Z*@<ezrJ%5$(vUJwZmBzt8JY<a)%2nYRbX&xN;ZW#NBQGE^aULLpcYtW2 zPDD~5M}Py>^H&ikOMCrXaXjFMyNuyNg$gXaPOE4z3=$o3<OMi7)&qF(4hc$VL&fJj
z_2r-Qj9iZR3E%CYD7d-t_J?B!#*(RS&T4!1-kxvq*sT)8$?63_#~NxKPqP5Lq;lys z1E&LS!gpH;axN~M{o&Ywv1H1dv$~$Wx93|NHp>Jt(guFuvAQbA?*MR;Dx}r~+zsgJ
zK@UUv+ON<mTXIHE&(Haaxq>T=mS{*wNJdpIN5Au>lfU5v4<160<tyx?ddd-t5JQ-Q zzCtQ*$r?UAKNl$E39K|(pdcV17*;zU{VtG7{)QDicnC&XAit07AxkJs2xbNxkEh-l
z#^Y&r#;SFi`y0$BoL(O;OpK&no{w^8i)C@Sd3Yk3Z?=!D?X$oO4toeT!H#f%v4wA{ ztI=-hZ#0{5e0{huHk5pMKFXUdk-_HT=8j~#**>ze%L-Vq--ELbc7OqlEqqgfDL$7|
za7E|xN}k@{1^(|ZQu6ZR?(Uq^Vl4XY-(h!mcgxhuF^PzYbNP~2D1qypy#5)QwS8VB z^zia3^m~7il#>&4bK{s6W!C%o9eQ_nw_LRXoq&)qk2e`~Carh!_+@C+^?4E@nB?8v
zNT#`WcWJf>teocH-d>QHxOk-7@IW}47m1u$uA~w=(B0jA`kk+l2DCPaOxmP~ndvI$ zrP(B~aF_-3_5wx4#3EgX2f|T2iDX6dBot9e+}zxz-+7y;fop?^#LWumnJ%(ER<|F>
zYkm8H%IFn;s^>pUrvz6NLyr<`Ro3Korg8A+&kfO!G6vn2h>XJTf5yvnnk!b`Vn06= z44(0)x_-m7iZI17bV#w5<;|{V>IZ-R+z|XI2d!L0M$z{_<K@~dl`C(tpC1Y)Szw}R
zO|u}x(#U)>eRZq|c{Ep6$&^P+2{n)IUvm+$hJWpRp@dc$Pc5;};;;?#x;>0!Q&lV! zq&}HG+Lrj-8Y`=$N~2}?8b|l9dGHv+zjnS*Kq`-?mfB^p+k|=E9!9dNC=>~PzI|b}
z`h5GsX89Y7O)`a6U8!1!!`XBAGrQC|6pr$y?Yi~{n@H;dTYvsSV}Guzrbl=`^4UoI z_>I9TkwT-USfkDE<T3o2UFH-DLvho7UH5}kxNU*8zhI%MKhH(OJ-i?BY$W~-^|55)
z8~S7M#L3iCl4D&LZY7p{pxhZgK`flMwzluNP~zogXL!BoNYnrwRFOn1!FLoBg%hgK zWa=r&p}q^d3PUbX_6!#<7Dh`;%jaA$@p7{>yuoB7YJe7^SUeW*JCd>d31w)Viag>w
zT2%$)cYHjmbW$l?<>3q586J5ELJKn1OZfwK6zZEGypC8YxWSi_nBA+Z_&{j*y_tMb zE)Hcnu_U(A@CEh^w;UM0IVsDf+yNUB)lCpiM=a>2dMS<By}F7IgoNFjDG)Kn@=#YA
z6C6(s<>8a1YQkTymwXrrI?Xm2Z(XHsp-_~6s;*Hc@MZxKw?mh=jIMvB--jM9zQDT5 zK3S^4|Mhywi<Y3>Vx95URpuHBLGh>h8fgM&77%eeba~6*@>lA8=;7iEw2QP4d^IvP
z_##%J(qN!>z*rOmA{Oc8*IOL7NzRt42R1uBo;?F>^ndx{qY!eko1xoqPknBbx`jeg z8fpiWc?lq5kxp*C)nS|HY^i2ov(x?A!{1u(mk%xyJ_nmAsx{Zt=LV=Ta0-O}2|y4O
zBK1!If?!CHwgxmCjWr7V)0^wAxV{-lm1HGp@U)MCwN_MeX3LZ*<Z=axg+87rNROr| z5yIAhMw5|xp<jAS{T1goL&?&tBz5keV*#2g$~m*;O60P60)&DePvpc$(-fJzJYIL@
zGk1Bt@5+qfq9O9P@jq{KmxjSJf5d$^x|QZ~Fy8QBT0N;L=b3Ha98v{T?!a<*H!Oco zMljJ}1>3lvw|Ps$0W*KZd^Wlj=W@{AaG=^es3_){Y~Jis`IYYiWN~ho|DLil1qRD5
zIhX^3<(4C7)s0wzsf{-e=xaD8((gATq$_pC!Q52^`1G=JH%YOOh)Awkup!<3Bb&&D zN6xAlvXG=U-8`VKVHr!k-;5Bi)EfnJRTtvY$;jR$#e%~lxMV?xboY;JA{IT_^y}D0
zPqzKKb`i}X@B=H-Bd~YbHMOEI@}9^-?1=1qlLdT_OT6u-ZGcf1-8B+SeEi66pT|r) zw1mJ8tVoSO-(}a<iGU($L_s!qHr~lX-p3`LpC;{qQD>bsB6M8b$Zqe)Ok0$OkaA#I
zwEB=TP-zV1l#zO^!F#)9-6$r|HF`OsuObU}`MndmLi2gW$9S+oiWz#B5iP79o{6bK z48@e8TAlv;PmB6dbP|{7<%qt@Ea>I;PRL4)=M`_G!A40Y$Xy1Mum)I0#!3<77H4)u
z6t&rf0~tYIu6;`z?!b$F5x-iubvO!}PG*C|1o8c0-4Tz?B1YV@ZWIor_al#w4Eg(_ zI6c{)TUsy&o^*@2H9Bp>QJA#S8$`zN?+@z^IIQL|VxYEQfVw~Oc}Wq!FS`G2T=aDu
z$KQrUKc~@M4#5WlgcH^f4=o(+5mB;?FztPJgyXV#w8m61e_JT{jLWsH<2^Fyzkt-! z-DMYe(1$x=331oN(i#yV%?Q)lcY`}FpGRp*74@@$fX%pE+dAGOh5QRhJ&mcaXOhk4
zn7TS<xomEX_V#vPeqA-SfVb-bwBxnrN@KWa9OUPbdwNDVsU`%3zb*?Nw~g=NK-v3m zLi_pirw^Zws;d9n^#IE8T1ypZDX|crNABquU?iL2;Ql%<xZgIthm*+Me<Sv144IQh
zqybDJa|+12fG~a%)UilOSl3+gJO)Aw>jEL+Um3h1ahneA%41;uV#JudJYWnF4<<f7 z+y#X35h0I(f?Jn7vV3}cbE`r@p<fw1A#t1bZc1YTd?oNP`S~O<1l*vNz*T7GKk&TY
zzG9QWf!F;`AGBVZlQ7I&5}VcmCIs2hpQ8%N-OLGH-?tPW>o}yV;v9^YzeZ9DJPbxV z>4Vg5cNBt}OJdbLKnEi|`g2q%v70%e<MWo{Z54-bRg#0&`qxlWo}1oq$2e7Jg~<kZ
zCaJ<J%(kHO^{0C0gfV8icm-@)esj>z8JMuzS|;y@^GISocc73^ZoFw_q)lcpJX%zS zzW&tUlrY9b8!wMZ!)FG}oq-Cgt7G(fIFBUcbt4fJ%!@avinPuQhDC|WkXbV}j>M&7
z?3#&5BtAW>(BMlU0{VA<|F{5pf0gcm5u<ioLW^c2W~^(c1nYDT?@BPLUBn{Kt~rr? z5gdFef<yi8=NIQs=cn8~Fk<)<8{fRekO|}3F~KUG-K#19**0R4d)JJ>u8Ix3n54MC
zB|BshuqfYiwi_^7$beF+(_|Gm6pb6*46=?!a@CQozXRZ`;wAJY%541p%ki81znPfy zW40SGT11ajrrm5AI24T?-2$|VMsU%VX}AMmt>Pr~B}#An{>%QG>_1FQYV^)CExzx2
z=$%(ueBbx#JD2|Oa?8+7exd?=;MxFGhrEe)2ufq>eT^9u0&(YN^<63?O&=!S{pn(` z&7E_9c!fpiCLci|F3H*eM2DQQRtQp4>V2&#1RP=KX3ZVw#OXuFxj$VDmM<G<u~~j<
zLg_%W?ebF_1IK2E8}fXKJRN7Sd1NEd3=zE}{Ff-5<hkKhjL-603?!M*=!CN3Ajdtt zr)S^na7COim80bdHj8W`F@;C%2>&HQD{*dc7301976VQyI69%EFvxxn>qC&L<E!j`
zFHx$lpNhxfi2h+m%}kE>5EeRtg*n1;E66aMQp_*vt;2W-BHy(2b;Flg4sLL8j`MDJ zIHGshQ9G04HH3kRXKn^}+y*oVrx5jxdh0M60xK|Sd)@G1l7$%@oa4CL9SGkajQnDZ
zAbfu?@{0+Il12eRII46kiNKmt05><cmKj{M9Y888Rc2DYHcpi<g&%kjUiB@*`KV)i zq^Mqq7mh3yOT@pX=+DK)rD+NiZ3~dhN|m0JtBX_NP2nRs2(SK@;dIooJ>o-`%ImvM
z#Fsvm&u^Vx_(p$zP`;Tr_Q_@N@e?y#jURaDNWq0<H65l6ZTcCMOR&h8Do(;m>iU=h zCv>AXKPcD26Z_;m`1pw)uF6Mp=RnShU^yM81!?jbl!v#-kSa#RLhSOG0?yp1YB6Jr
z$<m-^Ib(-mPuCOhDM(sd%(&JmzB)m`re%hRt{Dmi$-qm&$ODM}woZ0d2QRdc)U|VI zW=GrO|0zIRSHiH?DYiO+$EpdMkwz#4I6V(J12-W0+dAo4J*?nDQrFI<*}a92Y%1bU
zesAe3mx|o3@cdkhnrPdhY4g*wTICkTcbOhTK3P<LCjlZ-2$(0!%T_5G*XqoLZ$W&2 z`RC_4<V2ee4eMNw8s%FkpJh5UxnvQ!odmE*L6UqK9@Z+6xHczFTyw(v>tyg7>R(8{
zoeX(H^9#lA<L$Z4c^{6n)cji}fZON6t{$Hr7TMy1hrjYG=tm8sQ*?wxW60O^^z$fe zA8*g?PWv##WoF+p0bJe>whg#+(1_+A+<aAEfj?>)9HS$|n?k;(r=Le*vR;57rn)2&
zwu_s6>)Irsw!hHw5wf7*gjxln_O`c8!(m4}pSsbqKLIVrd=!}5jW}+WPlzQ;+_e-& zEkD8KBSZm#3Drt?t!*#s#>0+yUNysIKRg=t`KSOcSHieiUP0z8F_$tZ(ciPnq_o~@
z?Dy<48J&+h3*<q_`1T<r8T08<b#zDwj5C{&*BATm8$AI5_4xE$TwKXVH&vW)g90Yp z%-{zh<J*Veq)ewvHPIm<P)@9do?q;~Z}j;4gSzD8<V-%gspfzg<TvK(YEGM>bs{i7
zT}^2-bk0N;#}&r&dzo!1C#EDxcK2(q%kRGq_L~;|B={e5pvha9PCrco6sNv2OYQJK zt~8q8%WO|MF(FE_y<dA>e*bl_-@NcA!S9$IMb6x0`e_oNF!hy5a)<B9TQy2D<cFAc
z`KU!nh5QiLDT2-HCCe24(ww?TW|yAA|3*r^bDA*!6OvQ6=nEbsBqScI8A2Qpk4lN# zF?41xX{OMZmefU3+w>H^H)5)t(}ek4a1Nc~FF4@f;5aO%aB&3O%B8NuMWWCzYb`d>
zaG@CN%UZK-^psJ#8g25?Z51b+*lZma|2I8w&jZXbWo!TW589RPVSJC;OstCn<nM2- zQ-&3)G|5M|pzcLy>pA(p=?3&XKn+v0^`HNsS?M0eb+60BxF|&Y{?>MI^x``)Vp}1V
z2S+b{6C-xz(kY(1hP3h}VS&z)XyIEV^+!tGw?v{i%6E7{&OU<dW8`;_h(55cGGCZI z;<0N$BUc(0=p=y>zD3k<q}Y8+AcCcIhZE%FEx<NLcJ~PH4f57sm^|KipT6?7YhrO<
z-}s)s^0#T>@LUmFxqzh_g>rb^`iEl)hiDf5($dZZJpaL!%i&d@Buf3+M~(|w0IKfQ z5n4J2NHz)P@VNF5$KnrBFZ`vUnel)AgDsoGqc%y9n%hT)4PFSW=~V|s-Gnq#m>_I~
za3X0Srk%nLvE~Ab9|gBtt2_H<(fw_Zha@}t^K>=dbE+8{uYX2|#N=bmI)Wc;T*rwV zMC>T|r<IzMPZsUpMmccM`~7q^-gBxE8n1Uoi@@k@#WI2$Y*f#I7`5xI_*1MgU2N2@
zwd<qQF5ZwXK5Ad`lnx=HAV`+CET<7}W!P7~L^1@?exSN;0g-qLIHlq6d9Y)-9`7sz z^eG)oSYCiMe_2*N+|r=0Vu@%7?B{{Xx;a?lDd3cv9kkEP*W;ZaA8JRpl=-jMJ%r^M
zmD<xUW&V5W9@6p*v)UCq_9aWHcDBC6$RNAiJdaUdkxiRt@8+A5?3EuZ&nbZ~g04Qv zCe<r8%uD7nt!zE<kwG@ud2YkLV(WH~-pw~fnJZrqo`&ZGr=v%-HmRL^lg5w%)?Xdf
z+N93Un>5A@i2kamPB6hHF1AG?W!pUo_~vz+3wdlN<%QSGe!5}^qJ59h?#udS@qUf7 z8GyHmjcJ}p(SA=9aPzv&i8wZs^1@?kH(d$pau473%lc-?eyx*})9B>n!T!wN%lqT@
zv-9ZW<iY;T-pl*r_RYMakia7+7VXT5XUz=&=YC)>cl%ZgYEV62Ov?klP4Ypq+COVB z&Afsj|04$m&CH2M?F|6yeqb+e`&JWTP^~~z(;c>5;z6RuFKe)%3j|YzeZB9c)5E08
zzbpQbKJ4p#FTFlCeU?M~M)FWg!L^__)A~q8ym6&0c0f4_^d1Qsf;q;YQPHwFTKQaY zvX9?L9%?PT7Vu(RAIXR}s*=I<uRwy_BSL{QL;Eu-Qa(o`mnTNne9Sa30EPPEJt+@<
z@}^_vfdLrw7oSN5$O~22BEUP<N7?!egjAd%LV+GFBk%{yaT{IpneWzqjUui0h+&Vv zp#ohDc&Gd*U!MV!j5B~M)TLn{`N4eLPTO+kv$bEVK;t!H(BsE%ztuJNxvUZm<n?`V
zfWubT*yplpG>Fgd#kF2FBsIH_Toz2Nw=v^=tZBu!NT|Lp7qp(fZ&&7q@7C0rFJD6; zX;2AC&F&+U382#5nDIK+u;g9D2ceKb>*@Qp<*vA{&7B2uwdBH$_I`33U5di9weG|3
z(%|4PztN>6GF#&@{I1tbNIIaALQ8ulFL8_Y1vGk-QMPKSZe0HpMtxgqkoct%kuq`w zx-Iy`1L`R>G-q<+w-{f5qc<7ls}^cT4Y^Qi+meHXFIDgqkt0wpdBZGY?LB+q9&o`T
z#x-}Cb*!ytPr?%+STtAMUu{{K-N%@g062$UWI7UOQm3=mc9wknbhD2q<j>Ej-!b^P zd18L5%R+44Ml^UNbEw58BXP#{+I#J1$;VGO`#6Grd<=RWgP+T+ktE6H^>C;%(}szj
z%oYhuwx~lumz_3B^a7bYyyq-71@Fw*7ULPhNJocwr5CvLRsE<~sh>maF=R1p!hO** zK;wt^oW<tgof(@F90Mq+=n&8JLg&8fAC)T&bMQR|%m&TaFS`11YvCXVKCa{ZL8~Bl
zh+7MfH?17kb@`xEls`270@5OICG>$(UstdYt%lJ^wwiJK8I1@$5SE2?UF-^CtL8@; zX!HfBiRXgv4WYI!Z!S^;rJig#<C+@{PjVn61MRZd6~tP@hcr-a@OEY_3Jo#X{yUxB
zs4{#zGZBM@8f^QW&S9I{2Bl9>kdJkdQs6??R6c{5q%l*?6D-aNSM(>Zc4);q<1&7n zCbb<x53jHQ<07TdnY6iL20clAriMFMj02|lPk!CdidDvC{5bvm4$t3wF6Em!UD54g
zVSb1AZyvYG&77Xtb`dpP1hGZw+U_-uc%-;be&gSUcbi*hJ9V!?LnI5O4d&1TOrlrE zDwqgD^Rl(wYb>!yG4Fz=zm4zKw@$Wdo`VJm=879kp$F&$uMP_qiKSB4L@SV)<o?t!
z1<S+|>1&b|=uC<L8aTvvuX9dFVpk|m*IEmR0}GHqjEWingb*`V#YU;@E+Z@ZMRRAl z@b8}I9N>g55F9Rb=3ocrK>iqIRR9n!X0Do*Ldi{9M&^sg&T_TZz~>`tbXc$p%%BI%
zN_*h*ku5qb*cEQj6K-N_YpZ}w>!5&O5GB^zm!T#ncJ-bmy8|`YuXV_zy3)jPFmR0m z#MahUA?U0t#2ZA4_41*w&52#TXU^_G4)$#uGOnpIb{Gs?Bge_xP|beH;cUSBec^gk
zFLy&N`z42~p5XU|+fn|GAIE2AfPi3JbxB>QXQ+7$3m_ug7v}~qfMAh#5*_)0mSKO^ zu;a`And#3j5LZ)LAL<cm7Q+mP2=~Fd!STmi<e5Z8e4wG<pEWU}FV0~dCjlgckVACH
z)R>_thix1PNC=^T>X5@o5Ik^s!>_0nb%0+Qu?l@fMu||fRMI8(eq@a06~$a6goXp4 zq9q6%IKSam)`{4|E{#}*z9J$;s9GrM5PCf_#PW!sFXBVO08lMbOJy_uZixMCC|@VD
zTc(!CW&GU`Z?7*~C%0!|`Po;Y-B>bq8(=^Pt<rP<iQcM7$|SG7sZ1jRpJv=SL@y#* zV`k3ntJG>L9lQ0{$A?tzx&K6M(;#M))7n&`7KTkT>KvjI7O4?mTa;X`81yn7WAir6
zEwQ#JwOl^vZ8pa4W0vb_HmmSKCN$E@LOP+5th*N)ua+rG_zVzH1RvJYNm52?iwQI# z^Dv#2{~#3{X=5gyP*2v`3yoLJl)--n2rC2}*3n8(L~4ohHzT6QbyEu{!K3q#&p9Lp
zW5#vU2r46D@>0w>CW3cOKf|^OmN3o|I)zb~mlpR!VZ<ufcwLW;>RWgf3r$DjB6U@% z?3#RrZR0JWoh5V%Au%m2?uSB&R<iQA92+*Y@+cI6j44t_h023EBCpi<I5`60E*hIL
zJ!v9xOZ<+LBarT*ahaknq^miC#W^ANPQ%<$&RHDpEBCU_M(sbvsugC-mYh-fO{Sw9 z>O!i99khjDd#7P;NaxJ<_f>mYXQOtXqBZif<x5V;e8$sJ4ucprdS6=76OH3DIx00;
z2eEARzci;On#5;xRA{kHL-zc9^rxh(B6&XXZ*i0bo|+5(tR}B*i$>CjH@i(J`<5N< zr@?!2AN?pOs)?RY{8}AkNKVZJa%;%y+M^NF<4tc9%D-iY`=)tTYcBWKE<%Yiw9%%D
zm*!QawcKB`2qVVWN|!2bmCj+qMz_>lyQe41<ecu-<Bn%yzzizlEp*-=HX&5VRA7)- zS*EjFv(hfL)a~iYFgm5X_PF5~>oWn1d5WC&hmG;&Gv(>!l)|)selJ-m-pz9Og@*rA
z4%2D>Uc6GYo8|ZmgRouOWH<`fPtitAzEwsVe{gYe@!;OmfY1hA^J^GP2Zh7jc0#tW z%Xl~n+gHI_Rjy513U_dEaq-~ZLm%H7RpV<IR0p~J+;&2?kV82msqT8fkP1sSj2%4`
zV;K{f-a2?ll{FjAo&kmu**_ByBXvrN+H7%pUgwrk*v>}T<%nfg$(O1#f`vAf;$Wwj z1)^UjAV%_(0=dQf^t|3Rqv$6qMVAAHX%%m(_6P>bREoW=Zu*D?n%JFyy6(v}{RCOy
zK4OU>ekZ7*cXG`zK^{1Jk?6U1Z!$nXMaDUqNo}Oc<%5yn3pWZ=j1+|nlh9DXMmgJp z>_wu--o5bv-4rRuWG0oN3a2+(f)C6nR0%>9HdI1mB`d{jE6Q4vSf>>{@~N-bGMc6~
zw$>=#X^n__>L<R8p{2vFMsa-tMZAw+b!4w*{~Hs?ILY$MKb`ll%OHuFsPn@iLGzz& zn=1MB2?XIjZuOC!s@-pN5{60UUw-L4f1L-3Ohud?4)I$4Y&#w^A*ij(1$$3|Vskv}
zr(<R$^>z7RpGg`FbOM{jMF-I&Mx~Gtq{nwcJ*VwE0OFOdSNksknPO9!AjUy9a^u}; z#YKCOBnHKh5QN8fd|k)wI{^HZj_1!`{L&>R(m@P^tYk*J)5>eCrio9{j>kWLDCGrM
zl{GfA#HVPd<MtoQxnP@W)7b#^ViRq#kuCg}NnB>@8C*|vf;gcdLXrJL?MukrGr%c^ z*O<)utCbjQiH>aHzD!~>S<PU3pyI^|2H^|uA8K8K@16lp(bU!op*y#_y`x#B*bbDc
z`dR^O=T^5*G@CU0fpX=d2?dv}l#Z}rvrURI+yrK9#ndWZg69>4-LW#tEa5!`s{Zgq z7LCa{Z6vjY3|g#Hj9@0vV=JdXah1mvnC-C=(k%WxIkMjH1PFK%C1_nf?QEs`jYDCF
z8R@zhQOojaXAAXjJW6}a5>uV1LhgG$u5JQ_EBF0C=A-S5S2BuoH^CBy68!ST^VMKp zUTUHpRm64A3!+5iuiW+nnU1zIUP;N%T?I<%OK~d}&sT$agrSxf=YC~O3^hi4ze58t
z5t!x0xnCI*Lk$t%?=aM?bAC5Sk&8&Qiu@hZj7DiJ;6#WZd1Z764c#+#;>O(U9%lfW zYrh*M$%Mt*g#V6dL?bm7a==9py)xK`hVB_Ta-nZ_kJFQw=~*NkZ)SVx&6coZl;7FQ
z>suxqZ)SVz&lYoFmEAcgM7u2vPU$2e-Hjzv>AJy1PeOk$DMk`K`~^i^seLl#HX2s@ zN4qWzPH870+<`J%9aos>NyzV|B?uyizaR*!v`(g6N5ks=aSqWHk#wzbQOx2Ehc(>s
z&vS?_kECyji(-+eKdk1750r)$2U(RhTgkZT@l<$kC`GSck-TzG(h{pKG1aJhxkqgZ zfl`oSK+EzLOKDeK?n<u>#pu;5qF1g-8bXyN##%K`x2R14CxOh8w&P-kz4U}>3Q=A&
zItykNw;mTU?xiP8Q;PAKW4yNPGkd;&0<^_8y4rHh6AzZ1@<X}MHxR~1w*H_dG}N$B zwAa>sCXe?|fR^Y+S9_jW;=!_GK`1Bc2HY6Y)*s}A##+#}239~LV&Q~wL&4n_6^@vW
z&IXplBIDqN@xUP57Z!||jp5Tt&pmdz9L2TW`!AF!hrJB^PxZJR12(Mif-n#R#NUkl z;nGUYJ$5-C#kJr2EtD&Ty$t-H)#GyT->}39LWB1gdo%LwqR8{YbRBL*-FCEc5iY{;
zx+rtKvE7DS(6^neT}2A9{BXuZ>@Og1z$t3+RoVK`LOEWpvj)dqZ+bn-ZI_R@g2TDm z#TpZ~y8yolNKuWi&enqz%<*)Y)j#ff)9q1ezkI|N7|zr3<o?*+;JRvZ-Y?YN3nrDc
zUOXS$8{AioF8c*Kd%<K<R-Azr*inn*=YgH^e2AUys)JPOj=rj?w9#>YqEKoqkyqA= z<Onp!j9Mf+5A2NRh3|Az8KhKm@KH&niH`ddg;Z;SxUyCP16j;Grz-FV0d?P3g)Le|
z;h>9H=F|lLAffO3sj^3_YLHV~t7o60Afgf+&g?fx9El~tAP}$YS=MFe<j5P)$*$lf zos7y#E&CJ+9vSa&X1`JVNHhrwj&NnqqCPt(M^2wsW(6k!Uf|=Y$zG%w@JT7|R|gxi
zAPRmwH9CkE0Y0fD{A=Muw)Eg@o^ck}2J2opVQXezQM5xOn5HmOO_CJGfU}lKQ?fR@ zr3+j8jJ3EnSpUKST|4`Vq!l90IE9{SoFqR+GHa1EC1bt2R5F5fF*>b=T|b>+m?)d%
zOT{BN7o*eaxOLMRMu~Ds9z(B{K}7c!FZs)gKE}_J1be~x@F^v?Vr}mBH~BchgVsA1 zKJ;1@L~w8ZQn0MxZS*{ew-;Ohn^Jl!+U{m|QvgB~tai**t#d>0E=CMjN*SZ+36QnO
zYBoPZ2rfp9R!W$n8HiA|DU42gKOx-uSytz3^&m|2EPpKhDo+x7&9!omIz@pJU9%AM z4NrSN!Cd>9SLf?=!Hjh+ek}c}ND_U`vvi9(MS>7nGZ*l<Hmq_}pg^NoxPAelAVczK
zyf&(ISER(CT)2K&C|4a)z|b-MrvQ;;u1X&@@z1X>#gI{HMPF+3A4XgD2y6V7pZ8*{ z+9v-jKscGR%3D?J^Xp3qcvM>Pm%4(7(bhfuTHod8y%;N{YO_KMV}N<7D)x5snD;XG
zm8;APEKL9wC2F|aO=CXGJo^TSmQpb}X_X3Im%nsfn-Yr)Ip(;&N*#Ay_m3?ila&Xh zzCOH#WK2$4mAvQWFCCZW#F8TRInJ+=$6eR`V~dES6+!6-=6lkVCHyCW^Bb-$@=b%3
zA6V?kP!$WD1kP``H7hg@QY|w7?54~1UuB*oXqD_ePJg`i3GPV0EM`;%joWPh;8C{7 zi%hxQwAp^EOp|zR61~UikJsM89qE@P3@X5J>+K)hO6K`Z$80UqhLV&|mVt3wQ#G4H
zYdmIemNAl|da??P+nTE06i%eXK303w@_~!CLz4QEZFdnUm~0^2U*Dh4GePdBsTQhV zi4>T}s*jr9pkN+B@=LbuMW8^kzEFQde*yOdnXiUws9u#OD8dYzm?0F`qCm7pBCNNz
zsihVr6*e(LETK(_Y=c5vXJenfn3=4BLe-LG|E6?ccR#tlx)pG=|6cC;SaBt^!li5R zOJB@PR!5?2&9Zw_Jg~i=TwmStKiYq<aCxk}5?tZbG5<T2QE@w{`v9b{e*GpE>1_@$
zcPgX&c2MsDL}~N-O+3=a0$|oiwZm$c)<&SyI4_0A<srpSW;AoK?9|@QWZ?t*0}=T4 zZKB*^u}y2o({7rV#Nl+8<Rdkl0a@$MpN!_-&_Ccw-kxLT);QIY%C|Au!%Igfx^3nY
z95c7ZrJhu_jm;5WGD6vHJD(60#@Pgv(k^DF#6E7aA6jG6GBX94bT68~J@fG6iGF*7 zqQW?uNhGyO*g%79wi{Xl<pL%^<L*Ucm}hQ29FcEt&?fH3+ltiY=y5&ppGG-@oEz4J
zHT5{&R-&=MjO#)CG|n01+OQ$E>@|JEcP=7FY3^?#Of0zNSfD^&A$%$p{mSW|9&i*6 z7QH5KxK71nNG<)%_=$zL><i?GEBH?(B40WD(*2LZ1LB`N{Ao5PmAglN&FZpl>$2T5
zj(_qDpxvBQ=^ptttH-vj$9~Va*80<33lpe5w3*6)d5BABGb>2&T7!J8KM%t$O}n*W zthMF3X`+*;4Q-~<qaR}9Th9vMz1AXL>&-*4NzrU=7>#}h=jB}<^tsAch7Ac~Vq;V7
zJo+7yk8gR<_bN{XJ|u{lon5UfZc>HMFjulERk&KL*jqG{qadfz)xhuQcg|aymb_Y? ziknpCHOP}_P8F&VE%6e`WG~EVa?$ra`knKZrYWbIZ_w@4vO+{B!(Pb&!YhY8pCfe=
zVYhel3JJX|M+K*)DQMX1IZ`*_*vfscZkpLiT)9gL=cKs}uA(KzRP<4d8#RxOLcE#D zjxF8x>Zh3;#gw`fu})grVJcf=Ohg_<xsdZ&$;Db2&61EKPttRh=b4(sN_y`B$-^iU
zJP9@OB>kt#JaeOXaqm4Kc^GYiehxcy4(-(f*^`-a9<3OAl0lXjMU<hs234e~Ga6{D zbaR-Yb11Loh#pK7^C%^llk_r#NFww#waCKFozWylT7w{l+sUF-C2bd{Wnaa2cZe^u
zJ?J(F>1<h|nzoDAyszrFJH(&a%{NK>hK=(Co4O{$8%UM|E#&*;l(B?QsiT<hhRy3Q zn|G4%4HN4LI(1E&Cy+D;QqbqgF=GjrLR+E06_dwL=4wv4Tj*+|*(R0fY_3G+nX##|
zdo`!hEqt}nWSdHIHdieB%+y#>24bqlr*B{Z7V`VuFjMMHlGAysOT^==1z=5qZQ_2R z9LQLMOV`Lu0>Xc9m?(57$!NXQ#N%;Q{V}EjtmA$m<@Ie2(h2j9T2Xq=0<2R#daW&$
z<o0b2(u?qoT2pz=0&G$}du^;#nCdx8xE!J;?vZWx4u|^LC|6ILAHTl|9+|#ph|70a z85=lCIqjn+?h$SF4u|?#DOOKg9>2c{9GSdlh{<(WR;Mb+bxH>u95roevUiqSmcdG*
zRi!G*cglbdjvBYLI6BL$O5vr@7Os2u*>-1qLb)#p6A6j}B#jg`CWg~=F5uJg4=mk4 zEL`{Qv+mA#hjLxuC*l?ROBgDsPYkDNU%;m09$2^ni=SVA=kS_<QrbUz1Y8%cg`w>)
zMbEFlbNEc>OXUCT5piF*6@<3E+@D1YQ`=LOmdxBa$alJ^s;X9Vnwl%91RCi4CyD~~ z_h->URCbhQr89T-a-Gg9Dk?P`CT8-=f%@A28AYMmma&Ks#DNDsr^|eI%nHBQ0Nps*
zEfY~;r~^+zF4y_)m=yu>0s3+B%|pI?8RS^ct^$kP#XRzE>S#R+#~GhIc~p)Cii4cW z<{@u^G-9krSD|^{Vm?_nRkW_T!;E*n95To#4sxn;9FH2W%&T043S^Vg_Bk^^&J9*H
z9H*m(D~n23;e5HIw0*7&$Qv-cSkS?#GB%E4^9a4Zdg>n0VB=s|P>wkUFR@1Py;++p z=-^Zd6GYUG(CMkA?hy<&4Tc5fn4$3ys+ZiGw!07qHH1zPDzAJY;{8Oj#B1-LTAZ>D
zX;6LW6tT+67ZSct6f1(Z{;9<&8!$Q%dsr@?heJCLyu$kE{QNwMcpba!S7M2R5q^_F zKqX)c%j0#o|H%z2zdkxYKaV6<&nEMgP`q%2&v+2dsa++rFeWoOnf$VkCAY6|8|kw{
z1m`x@%z~KA<YbD=KGvUo1=}c}9XjK~V8HD)rtTajaKXxH=c$#&F7^XOeVqIzd^^zc zdwe(maC?oeGlx#HVClH?)W&QZ`+=l3PIeQ%9cb~nWxJ9)YD|MPt`v?0-3bMcbZ<2Z
zbIWe!=coxS%D8ek3T!6~BFeq>D3f^-kF`7BW3BU>kYEeLw+hLBNDUxD$O}Z7ySX3c zG7xSnH{QoOr#C@?R{C$168|JMfCxcPAVuEhewgQpYO@AfbP3Fw+|Vi7h~L@$6ydj5
zb)wd!i4k24w<bSyiZSAUc0Wb@?Uf)*n?=`9#OzE)13Dy(y2(Mw;6+{;LZx1wLEPH1 zyf7_h9Rp$0Gii0mkT9xddqw>hIVCXV203~$D~swIj_)TV=zX)@-tK6Hb66mM;EywH
z>W1_C2@tbyw%f-8qhJmP`&caiZ`w$^LAjZS5Sn#m^9yX>OCkC~g$Cc7>RooBAs^cU zsMV;{!i^8fva<OFy6>e3b)iz7_f6$4yU2i-b%Bh|o@eU2$RD^G(AtWlyl0^8dxd<9
zIlTk#)OXQ82-Til1rliQ85sNCA>X3OzZ4b&8XPSua_&2S?i?lbG}vKCBGdB|nXS>g zCi_xU0%&wFugtmc%-uOk=xMY?lR%{7BQRZ~b8}1<=DQI)v2*#3|70VNVV*?SK4O}0
zJ0*+o--w^syM8BpvQ@ycNTP2WG0U^*#8-MC0N=cB;m&`}!LXiv%vI8XM1O%D865l( z-HEICfCoyTwy@{F=Ac>4KISQEgQLDcj|>j}h<?bSz+1B0{-w9kD!eM3*<Z37%?4E*
z{g6XRuw=jeOMjz9WK|@yzj!yA9i}KA0|SHG<q+`sr<i<Pi`^JhieTLjCMhhg(V-g~ zkA{ZE<$MVE{8K_UuE}NuEQ7P^4<ITksnw<(11+kf3MpfIy*u6n*}`3yO2>zn(*RSn
z1_PW_$(Y*eJP0Pp7w)=LJ3hRf2biP%Vg#-kH(u|)=qji?<Oh@6prwi5!B<IqYZl^Q zZw&u6!^Z2~7ae&u`+{IHYm_vxJJ@RRZ!LoCjQ2ecK6E;Aqey<dg6j^l0`!YnxYi9$
zy6<`LrPq}oMe*koT6dHaWLV6?x2bm~X<_g%6J^i<7ORO)4?2sRit)0sdJ<9yVGvuC zM6LAhrXuv}BqgdM(}PZ8CZas7EFSpef@p;1<$!_e)*`_#yxN-Rs6oNz6|Hvb!y~|q
z0S2mC3WdJ#>1bi12L)S{x7e=_kAN~FN)m7xbSP^arS9Rd{|t-bdQUEl`8{54zNMvQ zh|&aXdTokY2g!RF%s;~-*j|$hW4@1<n{R1pndLxAptQ|@z=;7T$_-oy6r5g`(6WW7
zmVu~1GPeH>P7JxwZV*CX5cIQzmo3E{siDMziZ<Dq{2I|y#mgkKMnYVM8W2_`T`s}4 z0~Lg5P%%i9;@gCpDpoF$H4@@H)CjjK;d~ijGr8!04az5G=lEzh!m;dMSOO20Zv`}Y
zlZye@&UWgvbNqB0;W!R2tbqs1w}M)H)52AfR>%<cunA#0ca#-wneg$WQgYl+Tt&IK zr-iB|ED^!%pcBHh?<gu=GhyRLC1tsuIE(YJXUH?a_pCjE<xhHzrjd&pxx`;jQzh5;
zGZYz+dp2I6vM2opv&cowpQK+;Q>E7Tl9Q4KN4`#}D9_*vX?k}pO!=)gn7_4Bb4bJT zl9Q4KN4`!eE6v~vYIt=mO!=-hn!UAAu}eYoAW6h3plLh*H$37JSU(h+uGkpx@7+$Q
zqDaOnV(7U1_j;to@cwADU9mBc-@BdBUmAHSzyI{7YGVPi_y~b*r-e;$%CQnDe?9;8 zFHJlY-*f#a+nGt2y#)horiF~LDlif$em(#7hPWT7k)?Nq{j<MPS$NS8i1>JZxfuAC
zfw~{4mSb>(|FgeRQE<@@i1>JZxfuACaFBgBIQO3(xsqo~Se?tnEhWOPgi|!6k69%H zaFBgBIQO4DawgA~vN)BCS%`;S38kn@9kWOTMq)$V$+z&4nDQvH*{(1#N58$C)v2#;
zBXMEw6q@;gX1q%5b}P&*(QhwjwHm7%kJPg>aV1XSsKm6t<)rE6*j;x$hUQ|hu`kT) zJW|ch#FaXRBNNj6mX)HNV{_ScADWB7#Jn(Th}B15lvrI|-2<dL5!1=&wWue31zOTq
zV+}ADC0AEh_W-HRr1Y}-%^FExK~@Y^t(ANZuuEJ`p#^k<`-MWnN77L2@X=9jV+>R; zw^i}lLoabQhZfQf?iUFP9Z5m3!A3{9j?q)ToPigJcwL-KMw|?59r7;lq=EA1Xyn|3
zXOQ`#-WMm65hugihkOgXY4OID(WpNU{=B$ZDs8X^hCKKCdranviTkKK>$2J_;-Ga6 zKQFEpiW@9}A<zAO?vr_<V%};_IxKbySSVeCdLh1TCD(W}kZUFmMeb{5>fj-=SL1AY
z>WBEX7GD$0K(CoP7J96eYCwj_U5&HrOXJSWm=N0MQ^#7X5>(8zV6XiWLH3_Zh<aeV zQrI&y#`tyxRIyenc$G7)m}|d;5&h;8q8?ap1~7v{vEXIAhojO|^XI$6=K!f+>;5yx
z8Ndz-#X*$y8IDR*%bV{Gp97?Rt^H4qcV^AUv0!gF&}cM84>nV9@qF1Eb95#jw+CTK zJJXiq*Z?mW;Ak{?4<=)9$$a@6Q*<UTmpguGcnDIPC0WEYN#Q;#Yxy$|D3``2G%7BN
zcnC_X6?w!ouwb8!t?ZeXbU*`_*tn=L1`tKaPq~o#XH-LT(pdaeEr(+5o7_BF^YP^9 z0Yu^RQ7okX8CBPqG!lDN%^_d=COePPay&UYI#6#@B{KaL`8fF_auJMF1vvL@@Ng<C
z=s=xqrRelm)Z^rj$VCV;RnXkG!NaMn=)gAL=kN77LMYwzIqFtY;-;Q!9U{UKkl*Z; zI<Vd6`Flf-AW}D7j+&*Un2E<)hp>=1_%}Nx&bGA3oqS%{I)k3y{#DALAzrPw)h(FU
zxmwdAck=k)YYlsT2UM!0spVa*x7IFL)Qt{<T{YYOnY`lQI^(7M2P9V+PsDdz9D4(H zj}8a8Xte($dBp<ijg|@?5L~1^;NP*a?DW~(Zh!0u1DnIboQI)1jmk@=vdiYoethVK
z_uC&kBA}+QFqdK2PUEuTsqE4@^B*7j;oxh`V9FrWk=ulg?!EAw%IrbyYD#^ur<#gk z2VA2EQv@N8+$L;v?}g`7We;lAQ0N7Cs45%8&+P5um4~~FV_#?}YNMf!&GB+#_IG>T
z{LJ1iL0Pzm1nz~Vk`4y?*c=}hc7M0`eSeX3@*qVqdyY+Hm54oWxpS6AC3d*SaOK{i z_ZLeg50aO#<yc2n3)}HjIAy6<VTQX8SM42|2g1dr((CMP{B(Y6qxk|d#EXAUaxXkM
zMIb_4DueFcM!U;fEA1C)Sl)|&O>!?hIJJcZxQPc`eiw~~Oj@Tz_oM0xtx3Lb{5kxu zwUwD<6NhB^T_hSjX`KSqm$ECgHu=6Ocle)oFKYFN8Tma6BWbCWiB;waOh;6`(c*u4
zyBD?uz>WN#g_E*U&crG80;MCX-DnFuJuz_nIeOw6$6c?&s+F|L2zU?5G!ekeS!llo zqG$he^u#%iy<Uw`Ct;c4{~nZS%#WV4@bfxg(X2g|KN3$5q}$mfwzscUhZSWBB*Pr~
zFPgW-3Pcj<t6*$wk~%olXuylH29jeB{WFT%ocHUz?`>`}O?5W?ab_h%Gy97f=v~(o zM-+k3z<RHH>zhmy?M*+dS#c4NyP>CZSyS+OOi>@2;)lr;&A$)(OEO;kV+bz6O57by
zy&qFFhNcAIGR5-l!~O!ti+&6tBv?y$VCZ!G*COZC^Rd=v3DD{<mn-8DDFj7)a(=aD zyW>9>Ij2^Du|A83(r~$46%S7?Ancv<t1a_}DOz@l5HE6yFlo?8Jw?4@@8O%XR>(6R
z-Y`eYO%W4BP7x;!8f&Czl<z%!bI}fYCg336HEmrGi|zPZZj1{*hK6sTB{)Db@Ahz< zJK?TL+k$9p$KMJgY}hdrTzyS}0it==hvU?8YM**7M}l@-<ok|B?D9J>W{&s26~NM6
zT1Mkrr|m@4hL3vR(STca2f@Pm{<j=dva8hN|ITbW45+Uwv0kNGEfo(G4`o1Ew-Ule z#U8(RCX-=6Lw%{$D&=aKSfE%aJ<__RASP1DaZcJPva<-yi3NH#t$OuNk6wlp&CD~1
zDL&3gJ4JO7r9H94%%;<*+Ue2Hkfxn^#;2DxXx2!Ig*@qp$PYUl1}EU&y$jvc$e#Wl zanJ|7AhF;l{a^)Qhr<C0*mv)OH?=aSzsFD-;L^+K4SEaqsYLqhx9tkX_6ia?J#83$
zL#szfFJmz5&EKaM?Q__+&mY^%Pvr8lW%BDEaVV#`$}|M|w*-7clRhNl6*UQG&ylf% z`$z06sIM{&fPSt1-%z9uNqIz!!`X7AZNbDv=pR>_9Bo;2ZG8=}0whx#r7zZ6W`Fs5
zkPu~fTxoQ&W7V_sGsFQ)r8dZ1tToU6^7C;{W7^ylj>VK&YZV`0rM0q-=5@nOTtcx@ zJEbvhZVJVsORu$w4Y1HyT1E4?Vka&kS*mSpBuKM>OAT~3W;g7KLGzfQWF~QJ1)H6S
z-`GfyVTF_)=xoTY-xG)BHAl-#;@k>0Kap5G)B~X77JGh`U;(W#+Xleny2|+?3X~v9 zFCOXwP_auqzKSygLBPB}EH;Q1gXb@Wm*lZWfM<8NWGZM_*$8Ze)0+^IpqCyco5T+P
z@j4(Oa(GxV=hv@n1U4Y(PY6pg$c&Ot;)efq)~zTw>;uHy`pS!hYaNUHxEYhbgRg4R z>!edzc-RMsx%H6~4%a*u{&6!V2Xf)f8oOKEEtBAhvI#TkSv+Ago-TMSQ(2q}=S0FP
z+}+}7o`g)4OPEQ|;tiYeawTA$%HmQyClOH{QqjoI$3uxnpv;6|Hoy*8NC^3e-^$N* zL(1v}1vp6Ya1@zfO!}Dq3ke|~@mmFXu2dHEQWpO$6X$;c8V@V*w>NACSkmSKF-THX
zqqby_w*0S5T>t%`@v?z_`@m;FByBE`COSJ7m_~uq^-Bim*HTzq_chCA9jeHpXN(2n zXc85Wu2(uhx0b@}vaeA-YhO(oJ!8ZlugSxzOn{tnI7h@dCB`UVE~EEY_ww_|qDlb|
zwRqW7h)`1w=SY~Q#F+#wWc43wU)ql>D-{W#MMi*+Rc<(sqj$1IsI?*Vo~~JX4iGFY zQh0>qvDy{uar91x0J$!N&ch{3*B*?y730`NAZJT0IXU?T1Oo1Zc+QnB&!+ZYLh%_v
zSjVn{Ia}(<$;mhGkK6li&$laGUX5+PgyS=U#yks+rN3QUeb1{R0P)Mr;duDNP0Yns zV;)6DQs1sEzvoxu0r{lou-yG%CgwotYzFK>vqr!e>KRehvaz@y)fTge`_wgV2*|2H
zOl80yG--mz(9cLJmrW%6skc}}J*KYlL*%B2MMfm>8W3{uoeA1tCC<ou*r+;3^qV%^ zVl|vbxEx$3ymn~uGqN65%FYqJ<_)*Uqs49;KY2h*(Xa?Tk7AFfl-xf>irJoUyL*;0
zACDHhZT%GhF@?jT47^G`Uefaah!pcZkv5Mk6-LNJdXye&)fqvWHFMeba%$acLKIon z19&1GQV*5Ni~#kTnaq0ymCiLjk_=0q&=&|cG{r57n*6NwV6zJl<AE{?uiy^?^PFEl
zKH)D=>=;U0l+}4z>%rz1`1Gu3qlk(DUqGWSub-M#qTbUB+d9M0<eVN_uP7C*u^78~ zHL69trWdxghat&0+%;d3D%)bwcJp!RtqFvYL{}8g0Q6YuQRDUcg4GskLUHlFezjgb
z_zX5gA}C@jN@oBD9F3^)Is>69OLgJ6ct8Id?;aM)g-r9s^V6BrQ}Q;SCiP`udh7DC z%oGcmW{c;iGpDCy?cU95%R+Qk73F1uDmg--Py0a;zrr32XFHuef2iiC4FRw~6D^mv
zQX$nG;n1i3pom{#4@R?{E?z&>^3sL?I2rH<Wis|q@F<NBuC69-5#ZnDFFs7q#yC7D zgMdY9dT?<uc8v)5UGd`0_-us5eL?}U1d|_P=m;QXl76{#yY>5K*ED&DsZy8iEL_rr
zlpG#bra#0nk!-|k49aBMY~DA!rYSnil)LO^5t1e()wKAhNCbSmBV(ftVL(5Zu#AL- zgsLXr6cN9-S7dCo0TeKI3ByoGNNBIG{4b4m4=LB^FstU0B?!6TBZ1v~zn%e*Xk=B)
zh4=c({?h97ka3R=vuQ0^soDSL2f}Z@U(W!5npx$ud><%HigVl9la73e4N^TR>PE}F z@_rySE6i<YPde}>HcIxSfbe^sRAkjZKFfR!7A5uNa|Q%HSV{);)`X_I$=Rz#g9)RV
zsi<mye3$v_EsN{Q<_w8^ag+@iY>3VDlCxI}2NOm!ndIQSbW~gNZ4rN(jki^a>Fbq! zjIuDE+A6IDHt@No<L%X=db;Hw`M7lZ{F)`q!D5Htt7nHrf@-5e-`j-vV+h{^xhA8s
z<l)or3uqOy1dAU+uAUth3aO6@e{U5Qh#`It<erSmrigfqxCSSjXavqUPoep)0*hU1 z$s-;kt^*QI)B|UnrciuVNlIMmjGIErd$4j48G;5;lAAA$Ev}+q;LPGdoNB5SegP#K
zO&UYWdT?@(8G{DVlAA6~EU%*A5X|H2O-E9#3G=Bi7{1TBx@%AV8+f|Ybl;aE@qnl+ z{r5Q+H?7HkfTtUE_k9@xH;}4o67QOQ?Hl585(7w&`EOai?w1T9lK$xN+LxkuSRGel
zCkd`O*1jPhCouv)!2infb-#EBne0c8_r5gc!|J#)6BUR=Pt)|q^$ICN*h)UM<!6Fb zqy!S_YM9)(Tp?r#S;~dB<|bI?1gcloG<=?UibWT`0kG_<eKrPzOC}*3Hy088)4@Z+
zPM}6bb^Yg=mw0r+8vw_?%6DThxOft}VRI2VARRI!Oq-8ySp+^+c$5N}Q18|W>qTN5 zv_SccFl?&OC^;g&?yV!ni}*NhUvPXkw)lcuC^*Zf0?cUPiE6Ma9gu1!C^&e?-3+~^
zzb`nx8&_h%Jrt7lQxR^o;6yE0jUGfj6BHag<YA6kT{yFf)v+ARIMlT8QG1l)3YU}H zXl50oV>y^%sCnU|?kL3tCMU12QN7688MFeYr;%^{CT)BqX<4rY8gFNo(^2<+x6~@>
z*Pu~o<8lbOdU_i9)^FO%4@}E?&DVT8vzm^&_rIl4O$Qr0t>GKnEIbC?*Yeh-mN_p6 z0Y;8%xJK3sk3si!JoTyNPRqf>i>%mkw_b{g-~}-aAljQww_S1L53kdn=uMD<c17D#
zlP<F1%HMh`B|_%M)VrN&(Cf7+ZT#VL-V?hCQq(DLU8>omN>R(3=k&0Ki-xElR=54S z?H*+c=osa2w*s-S4Z~_SUsrKZwWYR;6)|&Y4rFt<B;x%HbWu)tqyir54O=xC@8VBz
ziifTvy<Mb)okM#dm%}X??{BDwcET$SeyB5Q(PFxbKfw?BLh8Zv1L7W@BHWWc4|fy? zgT4^EGyVX(hb0g9pv%V|#R4Op=lH^tCrs~K9#Hm6!z@M3QY`N@z7d4`-v-z^-t=yw
zf^44i3vaFngI^iA^p~c2in^6}?rD5OW*_-2*v{#ucM}uBON)w#4bGqDC)&v<zr`6v zgL!IF60pMfQRkwZjPjYEk%wzZ^3xZK3Q^@$Emwcl&{&RZg@DVEDLYS0N>ZM5$#ndk
zxVDr4Ly?#;bx!4S)mKf;<+v6ogdEw@^Tebil}Xo3r{CE;Cew^-9|k(wp*7kRpeKBK z&22o*u=b&^trc3UMGkzzrL*~$;t?gd{w8WCC+z$)6{fY`v4CL%;?|JZtR3}&oLz8*
z+kZzqk_5NkByAMLoqwjnwAVWpux!x@EKt~Oob-cST=7NR1P=|U+uPgS8oq*#f1yDI zT?G#HsX)xAYvWho@h=pJpzsjcWp0%LD4s08onG)Nb4)MY=8K^XfVvcKVvP||0{idF
zg@?#3^QaEM@Mih%^g>ozV0-H|T?}miG^F_wtBpw#IDTI~O&zZ=pp6zI7~U;(eX9v~ zr>Wx=dX&);ID@-|u5Y#BAa0c8rW_t)Xfo<vlc#AAL?V;xK!(VoUOQfwYKLZS&i<-9
z%_Rrklp$gbO-9{o@iq>QY$8+WLWjtqUprlw=!9l&&i<-B;;B?gDuUYF04x={Q|PYo z;;vFoDu&qH04x=`k?XASkyK@GT+_OrFRio<oEjgbKi&<{<pem1Bh|_{rd}3b6M_~k
z11qyPuIW6^msVN_PE8KdAMXa}bHL6LC^fQ9sh369#H1cfF?JZ}v`b#V$&6F1HA?9- z#ug2gX33LeGUF6ujY8^-+NBC3N3Fo!SH?DlQ(x%FqF&l0I?|LVAq9|-_ZAzs`MtE0
z8rMp!9QAw;KUupJE(75s%Q_j;=twh?gcLwR?pti!=J%3LhEmj*cmxEL#xOjNHpVeK zz6|*#9u5wvDGZ0bong!tha)Mz6I;9$ZWQF+WC+Z02hfO#<HL~fql9E=*Ih)@0t$FV
zJkF%}PF#r=gweO>TUjCt`~eJ7()chG!YE-`x^-8vG;ltjSQ*{>Exm{gthe@Wqr_;) z%W2<l>4c@By|jKCCPsr7DjJ6t;eTIrmF;CpM`~(ysWB=S@seY-cC;IYp7eGp3%$l}
z0wt5sLc;HhZgRcM=_rjYuGPk6qTcdMHcs}#u#-NnrJ>ijEn2POpi%bVAyH$%NC@JW z)oc?3j<N+0i5LM!Lg2p)9=a<RaaY_xwy2ck^!-q?ggIYnFfpFqE!+Gptg``+3UZ&B
z!9x#~LZ0#)=w{X8oW39GR&eJl^`<7%yQQ1IMRYe1(f#2jGXHCzX6=QT%WeN8>DptC z|G7`opGD})?f*>DrN<0qs>+yfj#><OZl7$l^xn+cudeRjEGbCoGdi+?_*DlwButhM
zHdSdtJVzrAI(JAmUV3k0>(|f-Xp$15@*N%7K>n%=8xkhRkB3QAUtf=ah{(e3zoSSq z2c4jyp#csao|(;WM}d0ov1}Oihu(2H(;^$M+d1l4WRg4(PiAdTKH$e65RXehqGcYp
z_gFfN{zLz`jCqlr&;1<zEHX&}L?FAirvU!(2Y|Cm1k|>O+r(+F_Z0oUu;MXftO1`Y ziS@I=L*)Cyiu;g}I&7*~m`bn>o^%eHp8`K^wUK{qUM_Xl#K;;VHK+>&$DqLQV1~<L
z9;O;>OCXbj;jbt_S7jVfllzmVYhq*#nMM~j1j#8VFg%#?vdErxSYKI2XR#z#^jrF| zJDOoVC28%&(mauG>BoxLuBrt&0}DAhEKn_^ER<H!yx{%QhA9tM0kEdHkOyS`=c%lV
z60VzCe$K!`P7W(fGZ`zDbu=Gj|Fluc!xb3b3?KS{Jm5T)ZILV)F5q8zrZN3x1!?Fl zq{%S;|CVPO-A_h<n$FyCVaW`RarknRGNlHhU*Qp*V8JL9k4MsRCTKGmV-lT;?XB>`
zj24#65txQAH>pypq52gcF^Lw8LkW1LoMwVHld&c-soCEOJ`7#g5|?z#rkMgkK7BD? zz-29QNvC|8F%an87xNYKcn*LCu89T8nVkc&?~&O83)5GbY)slt*#=)i7s;A<N)hyx
zv5)5fIFMR6Y+7b6;Ou);_P~PlRc2e$)>HPum(WG>M&1%61LbYx=>T1OuOHP=A_2Ml zwh^cOb?iKU)IbRP=ka+qf+JT_=N|faOQrq_JH^K1`TFgfF^F{DYfaT@vyY6ISleTm
zUJa0_6*NB&eSM@;e}$dm67YWg_RVCo!)>o6Rkzh4GG20Rk8#RK+5<zUQ@NQZ3;N(k zGL!<vL!F>_C=2r7N7+fk`X1KngTDCyUEafq@X5m_z1=DeiD@Q38P{+Ou8AdwgrjC5
z=}G<i9?t87fyDrQ?!$@5$-^dt{VFZcEK`7-dpHK))QVHmNvnXg##tkOmFbjLy3w); zajlbj!7Ae^jZ~9GGnmvF%|dV*Siz7~1$lG}zFHP5%BV8TD09lQN!w79WRZ;`=PM(z
zLi&t$Avg^pe@MEVBD$GSJ&O%(R0VF7CFR+)b*NFQ&{m1-m5EdlTcHJjaKBrCPsyt# z0;YT`0PcRb5SM~SQ_OKjwTc~?W_G_IPe||U$;Um2U%fe+7X>%Nvy!xcXUbbT1miw0
z?lhxT$$?5cyPuyctpD}o<31z==H_T#4APvyTFMfUId|z0g6BNHXY!VX5o9&+;>)kj z=$X7_W&m0ay!h~`ae>C68mu@al*ia7R0saqO=sn$tE@ww372nWLhU^>%{WE>Eoln8
zy-EvI3s#yE&SmNou7&*UrnmOiQ_-c!M98x?rSX}WW}0I7mNW&~u)Vo_w^FUmMKUp> zaeH(5Zly+xlW1Z@B{Z2HqS52V*oh`BC}k&quf19RS}N6$l#0qGWzl9DQkZ@85<PA+
z8k)=i)!=z!;!K+sl(Lhz*Vd$PEuCsaMon#-vS>REEy6K+i5a(<$=x(75fa)xG@=%o zldE}FJS4PxXhbzMsRmrwaRz~V3QLN=WqdEEvulNbgjbr&&1P5w4PCwA3{?jrWGCM~
zR1GQOG=s!5g(EG{JieFH*|kCh<dflcw;k5Rz|^QeL)V20*~xQ=nQNl8Co89(e%7`} zX0DmWj<kYm`dP~kIl-=0KWu`Jc;838I{cbhtw0szBJu5{7M^n&!<`QEsTb#X9`$lT
zO|Y*q2%F$1-S^d~3cqGi&sR%?%qO&$UU<%F2zNfrqgkBeeboPHkD9=Mq<A2J4`k2c z57Hwj9Ps0kuw}6a#aAGdM8Uyjl-gC)G1hP^b}DQCDLs;KR8(o5(@&tS<A5C%$Hu%&
z2#PO9Dvm-x$SAQduVt#{QR-CD`BQQv>7=CEGG~xLSIY@MDuIiAnc`G2Ge{P@B(m6G zajcvfB#m7XUTidGKu@9pZHG2y*-%G$Ih9jXO6!k#h<t!VB52|u)nv~y!>(#UMH4E)
z!ibqfOA9p9!7d%@C@Z6Oj!J3yF%OjokW8F{Y}gut?pbEsRm(4LL??RqN~(!1fsK#O z!&hPrOmR$HRF*}2C{e3A#U3h9d)gN68^|>O9=TO4Ga~u#5kl0}_*QP9IxEl~Ce;Vj
zx=08kW?ie)L(K_4s$=P~flB)?<W{NF82DcZG5TtJ3lB(x4deiq>RT~0m>*m4)K<a# zS3zvyQ+p-TKYiV8z>J$akDBH=i$W7}&)8|aN%_17$7$H|;eKWRKgAtrMwoyE;#kJp
zkFUE0&$xT=s%xFIDmJ3_jGe}tmd$%|o`x+S?pO5xBkt@`6R-gZq_Ir5RrAMWx3z#M z>iJ{R+d4p$2q2;Y5EBQ7>@E&mk*MzVW>!EDsQ9Pd1Icl|=0d^U2HU!hP6MLe0bwp2
zQ9wjFASMn0)k6ZbB3aez!=i{JSpJXQ8wSsO{Rx9`8*Jw`It_?=2ZXtDhS&@UE{Sb+ zA=U!|OQM?{{^8dU?o^&w|I~Y5fw~zw)IT&*mzBRUy1Ljo^-=Z`fvN|N_J<BBAdS~k
z1cYBhc~E=d{G<22g7h+UX?|#?E~|WFa&xtJ?xX4@5tiRN+8;Wkgf>}Eg&^ysOF8lN z!ALu4Q%-z*R{oO&4hJxm{nHfwfAoO3sOznOQIr1~0QZdfH=zHAn6N<6r7+IV)Vf=N
zUHK0Q90oI&{$mRN4;~O7eZ2)RYWiOSNUxax118K@axIASH?!$hWN<QDk2~>TeE-m< z-qCbD?!=wp{X>gxG~k*Hc%03VftQZkoi*AD{-11-bt2%}_=-R;7ZY`jOzsFyAEWb!
z9|d2NgO0N~GYHc0yR$}HApgS_*(Si(CRarIKe5r*$mNd^46r(X7=_aLFxEIYsbgvH zVJNLPL#@4|8iv-c@m4Lu!^Uc7?VOsDWty>@T6^QN67|~9P?w&boWVpR2)d)gI@s*$
znrzh|J#4IY*379ZTcw$}tG6{QE7PnE4Rz`3%NtHKG_U~aaSk@Sx>k@6ej8+~c|Yc1 zT0uPct)H#x^_Y(_q2El&g2<(pF8niAzCde(;c)XAp3awn@Z)3{qMO$l1?#O_cXL+a
zO&By$u_ANpr;D`5D&%W#Fdl9`BhvdZ5`UZwLv{1Hpy9lA>ut_To&@^KV8eBInUrO5 zB+yS96Q;w{xIBw9%-h2xp$%a(D0`Noi$$31BbukCM_lu$4sG_+rWsH9U`eD0eY3t3
zh52}zCbS}L24&AucCm_(e?;?E_ef|R)nd$k+BOlW94v|UU~blRLjQ0ZP-4r2%|3Mn z@`vkyB5OW$_NhyNPE(&_JPvYO1XVd%SiaJPVza|ZguGogD*p`OzJ!Odk4wR7o=G7;
z>o)c|#p9v2Mo^cLhvg|xC^b2rL@3y2qYKOs?@M}`_`2q==9(4=kTk_PZBIhX-PBrZ zQFEN*_9WQcO`Vliy5G@VCnZ;Qb~fJ44e1$o^Tw=L_lA;Z-8Dw0CC}X_m5Q_J*xP61
zr~4n>by9I>XJ-@K+>o8|G;Pd^cW)?r)m~#|TJhd}QmeX{jlF$FjtCHM4zkU<60>Zs z2tVQGAnU9PA@k;{9QL{c=-~c_joC`W*8qxTI)7}foE-)SU;g6SD;S1P5oGCta0DrC
z%Hys(I^Fbs!^Li)<*(mdMDF~twQ_bC9DMnUdoO<&F-3^A3(9GW4<SRa*?EWyZ`Gfy zGXz?khB$Fn{Ycwuk%t&RTyJ!Mz8mnC0U+AYu}PkaA-t-gE*25%;RVKNKyWz!scpu6
ztp;_7>BH?t7v#5rXa(*RMsaFXpk@rOtgnql#(8*wa~=>H&U<Q|@mQPKi>=;wN0Q<% zZDKFBX5S4#lCQK!Ip%UxMsP%cC4T!8d`;mo#M{(B)h;Ilk3UVA`-O^+JuQDuUnt-K
z=~0Qf+>{j>5oC?u{)Ajpd<^k1GgPzB2_X<j6XAKG=I2Pun==pwKj6K56E|&82n<!N z=jEH2NuzvVs7mGT0rJ;Nz54;;pVk-{O`o<8h5~yAG9cx)%sJ+#d0-B8j!9{+{>1@9
z*gZh~dZ~XuK-zADh1K|J_h2NrXDF+Utt5Mn{b>=HLz81#(ra*Wz}OO-za_H(wqrv+ zYiz-m^g@6wE8^*umZD0JhIN!|&Ok-?2XhJ@B|oI&FfS^$rs90JhlZBoJW`e5b9j^-
zz0y`v?a{P}lFJz=@BUy(A)pd~b{ghG$JJ7r@AlNxR+>kt6nYMil7}v99Ja?<@UZ3T zWO>uD9oB-o4QKEBn$akVeT1MeUX-s%#m~lP<b&9IWGgbi$*OIzpK_3n^}!I)WVooa
zeP1&kMRSM{5+R84Gc9j#ct$;ly+^es_n)lXhG>_EcB%`8iYCWLpCv8)3~8MaxHrGc z#6_PWZ8QA$W_OwNhR51iZ{AQ8gp5IC_qMYoKTO<wW7Lxu951+0Q*<Z_wU3?^MX!Qs
zWH36`!Flt6p(JJsBEPqrE&gHZ?iZtxyx?@fgPx*GS)g<DtR!|7O#4C3-<&26BCuWt zKFIi5(!_vxR?8&ce&YV47mZ8#83_LZ{o>XZR!_h7SU~%Y_rx{QlrO<RbvccdJya54
zerw17XD^zR2rv@=1^LIVEv%k??XiUQAMc54pe<X1gXwY}D}AUS!dY+~%?)~iLq63N zEx3&41--x^p6UqQ4-K0v<iu-hD(5Xrz}`FaganW<;qBVLd$lhu5Wn*9nE3U4nha#d
zz8@MkUC4>o(Nf7>mW01|;SB);nF)3s-o4wF7D!)tc}@L$K1~NQ<I#C`<^M5#IaG+p zqjK-c{nPa2P{JRx8UPnyz`s1eOA2Taz`!T`m}fLvc<|5nl(qw*BvH~+UyPRhKzyrh
zY=)o(ILI##h*E;uL~w`+KjxW?7ajugykzXTJqV*@roI?2`+v(0w+pxF_kxqaQOlgT zxOKlLj5wBR=EU`4w)nCr{hTY!q<lpX5(s|w3QJ3;mfaaus{2>`$o+{oUb!PIS+x5N
zUd)zQ7Gs!mqn%VJ4?;n<-SZAhOQ(_B8C9<RxBSTSNibfqBO+C}`wi089v4cu?tLqd z+{O+YLa6?IE1#&A?RMZ&J}!O!vj>Os^y>J_BMi^Cu8;>FP)!5eagStg`4k8`f<9)s
zq=x-=;8Gzjeg3ltkL&d6_{$?4@3*dy2VO}1QiS6ksot_FD0X<*W7a!#r)8YzfwCVl zLv>uniXJHc5tD}2a*xO+UycHT8lGykAS#<PAVxm$cbPxfCa|;$;o~~iE+XVlgHCw7
zX&BA-$m|MbXd}O8pK7$BDw;B&Mm`94Sw7e&aI^~$<2u$ZA{0)8PI!GLrK_X#D|4>b zC#7nl^r~{M*TsmN95D{cIk!IhJ_X-wC?{Y<`4dUpmRY}yVmTSPk&p-vIF$+M=~`b#
z#Yr2Tunx+&wm$nlh2CtbCg8*b5`pf^Y+pukoQ>UqK#>9GQek~Po6Bh899xq^a4oaN z6Xw_$9|qJhncu-46MlAh5ITV>tq7H&?$Q|yXO#aH{77;M;}%#Rn*u_i#Q#=kFoCjB
z9sDuzXNM=T^ExFYu?oyxI-}8y%D;slDQ*$`e5+$KKq!pF-*Qc6*L_WdXk^K$IEown zxM)O)sW@_wx=K{lJ|iyESH0iv9Nr111eP3eEA!SenTb%U12{RS*7qj0=;%^Kd#QiJ
zc`-GIjJQlcjeh%cL}$EWcnajL%v-BuW@70M(BzzY-<$NJlWQg2rNIpwvZO(rx6c;G ziYTEU=jFY{zWsSqmqmw<7L@5T1o7NxWhht`9gu$(b|QZnjVAE)D;lyC=><hR)|0rK
z_UBD)7Cj+GP^Rw?)N_Nikx*qcIPWa%MBy?TL-6TWG;|5d3z|f%7il*;Ac9f={o<JQ z4G=-Wk9u*;^2!F@ZPDmuT=Fj`zK22q4P|a@naT2k6OIr&5bt7mM+Zi{1dh<!#Q+MV
zl^wF%vccP=_}`iM9tJHGMq+Mknc3=s3xOCnkl<o?M;A__7=hTv)ez>-sOWXfH2ow& zNV$%grklh|8>~hv=8piE3T9#-QVKCSaq-q&xr*zuRbfKtru+;Kkp5Si5+<6{tz}rp
z+F%t%kw65bbTBi=kaCFWiK~y^%2iyKohma@H`Ql2SmxhqN|;zqx3*C&8_FG(8wPqn zigZWmiiYYR#xdxCbhhJz=wN$k9zPcR8H;AJErv2><3*Bm51h&CEJlpT9yo<pH&s}f
z80VlP%Gr)DvZLLlMf_OsXDo*4wm909tv4{~9yF8NS%e&sJ#dPsVWzk;(a?)XK|KjU zXzYb2r<w#K%?wiq#0>5`<Zq9U!x1gwEv^qA_gUtKoaUH|F#B+-I$;m;h@imuPKwTl
zmKml2h#A~>%-bFxM<7`wSX>`I?z8$Ca++fy%HqqV=8QYYD~bl^Hz_tBVxFF`f!?T6 zn58Fdpf)L2vT#)zU+}?#P)g7lir`yLqN5l4uSh3fGa;S@>1`w{pnaAJ%0k=ISmg0E
z!OC4>a={OOkbTFV#ew8k2GrG${kNo(r<D-Tit;v+1#X*VhOyM~G7)_|P3Jyv5sQ5# zo$J6^H1-w0!^WV5w|yx36dtal`WN}DGpD-gqYjDTfjIaLtR}xxCDSo6v=}KHRM^9@
z?65T~=4%^@K1D?6sQN|m>cXXA_NWUqI*@?8f!7jnu3$bUg%u}bhY5Q));;cCAc0gS z&T;nw5x5ee(K3%Z3QQF%sMId_cIRpr&3g$f><9ZoX7X_c7g4f{y)mf(?;`TLI@jLv
zHeTk{K!dAfJ6}@_zTLUn#qe2z2>ZdYkePg(!A+9v>R>`9$hU~PuED*xe7hANwC~xc z?N)ryzDJ)LsBZU+VnRH0X1E}KJ!}%#n_-<YL8nvAJG1pi@pQ)DNORI)b_#$>hEY9w
zzMc7YMmZr7Iy0P~w;nbL>dml8nV{FL;+xs}qjWkGV5~K1I6DPEC&#K9z5E?@9vBT9 z`8(=7Fd9^wGY;{_ggJK@ZR?yW!1!^^d;F^x%}=DG(7K8XMm$L~K*Np|t>vZmA5%Y|
zvo#L&#*9687;Wd0D#-M4&3F8(7sFq)qrj$;8%`og3#@6+hSB^|^UtXtP#SOBvdY^G zINrWxnZFq_J7&ksTGEluekfNRCX$8u^xk+?w8Q1iII^7LA8Wc=uh=>E34C14fN(+~
znH{rdVJq%P=QxzF3KPx3etK`XD%|1rVH#OZ35YdYtyAh8`vg5MW<WWkk;SsEjw~)f zjb&LKSzG|ur8^cG=n*d|U)DK;5`-D7c>o{;1qb8{cYdL5^ll*Y29ag^ZWs(}{Dq?&
z>d_yI4)jPAmo4j_!3e<(RzCocf`Y+$BAs988hq->eMY}S?z>|#t_c*3a#|wBAi{r! z7Vt6fu%BVSoqvD;RYW!I!KS^e-kCz_2@FvAByt<`2mpv<fkZr|^`JQiBI_`lhGk(!
z{dW0rO)!J3t~1!Um(@E{ATxo*eW!!k$}$1~;aQ@PPH8`A%_SDxVmA)U!Hw)$KXA7$ z_N*Sb+Ln<Xn})Qgi4eM-7qPD_UOjLAm9k+61#g=VRLjj+Bq9RB{*-?aNH;_9hvInV
zqdYbaY15D(b-OI$URl0+-TYf+!wm}Fwiu|ApRr6t288`7`y!ZbjuZgH`OF0cwYAez z1PSqXdP+6AuCc1VrYiH#W?-)Rn#1F?YJ)<4bv{8UexqS@(f!Bn_=kD5>xlE{aWp)%
zqS<wgQ~5PjMPN1qd)3bZ5wArDbnc+RFC;BsJd7!}|JWV>Ft2_caUMO6L4Xk>1Be-C z7->KZs4&!M+Z9|_;(Qr<M|^-9J`VLlA0T%cdqRyI>bPRGNC2zLU&;bq*v@zaDlNR7
zNHX4bgVd8eU&h^$7@$FnL%%Qp$e+fZ(4dAotr#y7!RrZ>u)-F!F&*jOE8kA5rqU|| zR!OB(0w7?XvMI3w1tc_A&fY$=RO&K>9q)K{?KeL9#X2nl`k!ouFF)XFC@Tui*%L4~
zkg!kLmDxaol3FWgZ=YGJwHYE#cf7j}8z24RotEJKC)?r64}@x}^89m-1nf<nRE9gF zwNvTu3}=K5TH;uDS!^k3d+!l_hx$f?(hkYU(6NBYx@mz*Y6dZ7D@JF^5^p{aiT5zv
z84<(gIJR9@J1V-~dt|?%zR{qxLvnIV98j`eTA;GJVNB_Y@tKO`o9{#7JseMXJL>0~ z;Xjc--#|sw407DGZz<4^FBXBq5F)zwTQ|65$~FTfyft2wOiY&QG(ydKoz#wa?YKny
z*_bz@JP+Ml3hd*HWuOR@sNVh74L-Sw?LaYKwKo+rvy}#|aFc!~jT1o|KFR)cI+)Bn z)9C@EX0c#XN}}K5dNFdMNo^+Os>0sS^c;E5Ky4zm)q;>J{J+z3sdUj)7tN@@gZSf7
z7Gg?S>|0zfR!%gT?WBBV*!!8j6W>|lJse7F&5>m#;ooWbRQhP@izf8nK?3n;AClTI zJ|wiD$oI`e{Xe-gDV9P_(x}i7AaPVJn&m~NMi(84-RGbXy6@{lY?h66ze7!6Ee=i!
z6#M340iQgXluMzeY19}<(0FQ=O$wq@ql-?Y9&<2A-S>4Nw#z1Z-(e<j76&JVo#?Yw zInre-6PCHrI9+8v4+)Zge*esLVEy0*)t)o|)801Zf98hgQ=EZH2bpZ=)5NN_2yjw#
zh)dmRov$*VhlD6Tzkg;rvVHK3C7HAQV{hy8K7WSiQJ%3H_%qwhr-@f?5#goio+=fN zP8Ewr(5WN{8DJpt*e!|G(gvZ5Pxywag$Agdns%%4+I<chK&;6@52mh48>H>|FMw9b
zU{XsGGr~dTa#)e7rwzgso$wD;2@lXXH||yuwD}&?-@{=a^kD0$wnE#T{{m<i|Krq= zKb<-v)*Cb*Ao~hb;B*`Ee&trZYBi`{$ru%gmKbuXcPNb3lD3H3Jimki7;BEFp{bxX
zao%A00ohlLP`<Yz?^o_stJZ@W6--fq7>OaL`iCMI&1sAHP4i1wfU%}{TH10ti=qYU zFJ7Rk<~$d5(AGs1%w=$DDrj&3=?C4wX`U{m8^^=Z8R3YTB_A>ZA<nn`Er>OkmldWl
zDz0-eM;$$6p`VP-jrsMCM}MB&A!(m3WE#f9F_{oZS)?8^0-?^g11w23S(X*2v9^k* zwo0ZyTNCB`dfUZA+chm*()HWtA2!JQ3>g${<ZEUqmU&IH*$?ZzOs2IhHpYEix|NPQ
zKU)$N`g+?WLff<~UDFNP<{vgF`ivNrY!#|!D3|%nvN;axyiKQdEH}n|UAvW!JH2@P zJ-Pi715VXGJVDjN><!w*tid~hXaqgXjMCinP(wu6AN~G*C5MrlRjoO?J1hQ>8%Vr%
z6TzqIA6}zL<{b4pMQp)4ffz(REKD*y3@}3^xF7ui{>6upo0Tm&dOIrt&>JXx_VQrn zasf==&095e)fG}M%iIsk{PaQ>2|D59ppz^2pExvb9Ou9EI^`kN!0aXr*u3p0ex0b4
z?-nhZdK!u;m!%$urT+S%i$tA>aj?l1`%j#jH%{|kdYyAos^NAM25jH<6TePW$nes= z=AnHH#@v>`#o*LjN-yB0^^l)H2Nm=yD3|>1aNigv$f`s680kxF8B%d>SUG)YF0R~W
z1!HeZ;$v}XEv4u4(RnINU~U}<DXJ9z?(o<cCd#Ts`xxm<Y#vf|sb4vLXez4MX3R3~ z$TI5rvll2~&q4RSwu3})*@1!~z4l}@NsY#MwV(2<h@*@k1>Y=hbLZh-ce*Eq3<#rZ
z`Lh=&>A*?<y`}>wwCqU9m|k--nxsx^vf5AeRn$pVh?0Mnuc`C!uLu2;Vg{7)wfw`U zxra}au9h@`-JaCDeW|)St?N40z`g~4rjZ?xu=?#W;cJyHNPXCV2DuxD%N1A2hAlFH
zX;*Wa;BHUq-TwcZ=lb=LAJ!W;9=uX-aQwln)6svvPf%SQ<1JdhQIPpzpQJ_KDid+% zwTJm(6XPn#dA&{dq>&yd{5Lp=pa<%$*em=~TdQ%rn_v#5`><qe0k3yPzhk;_7^Ch6
z!(xv_|7G`-+M9p4uk#~(Mx)cG<|di_EPs|%wf~Qb+;nQM%q9N4&z7FNB6Z+G+^+MR z``4jh8^vb#=_?9Hh_)q6T)5{?KdaF@G)h>I!IS>M^uNpl#N|wC@HMBcRTMT#SL;d7
zj)|=QD8BER{dSeRdtd$LH*1N?VC!qI+*y}-;)|d<d&<cw#iye6@8<LL%{>!tvt|0N z<(&BuA6dLkkx|8fWw@PXzCeCBgDx@HJs@)L+j8y~gZ<df6K`wk{>)7)${p-|O7{G?
zm5Vlct%>!zH1~C#{PXnRXO%R17-p8ep7o3QUvcWms)tYH$`9TvKIF>&@BVzZ?VI=h z&|M6FI|A*^d_U+Of-3`+w(c~-YsQby|NH)g|G7xv|Nek^|Jex)g~z+)I0xPC0460S
zpErH+ydwvGOs@R*Hs)&kpXVngrCvTXb;0-d@xj~oPM7_l|L;HY`3dlY6p$IBU;poR LFIp>X81%mY^Bg|U
XXyugpZ1#qMfq}u()z4*}Q$iB}^Bg|U

View File

@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Fri, 10 Jan 2025 22:35:07 -0800
Subject: [PATCH] Build changes
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 8f62879582195d8ae4f64bd23f752fa133b1c973..f5ff71e31516327be71924926938f1c9f0e503df 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -592,7 +592,7 @@ public class Metrics {
boolean logFailedRequests = config.getBoolean("logFailedRequests", false);
// Only start Metrics, if it's enabled in the config
if (config.getBoolean("enabled", true)) {
- Metrics metrics = new Metrics("Paper", serverUUID, logFailedRequests, Bukkit.getLogger());
+ Metrics metrics = new Metrics("Folia", serverUUID, logFailedRequests, Bukkit.getLogger()); // Folia - we have our own bstats page
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
String minecraftVersion = Bukkit.getVersion();
@@ -606,11 +606,11 @@ public class Metrics {
final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion();
if (implVersion != null) {
final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1);
- paperVersion = "git-Paper-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash);
+ paperVersion = "git-Folia-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Folia - we have our own bstats page
} else {
paperVersion = "unknown";
}
- metrics.addCustomChart(new Metrics.SimplePie("paper_version", () -> paperVersion));
+ metrics.addCustomChart(new Metrics.SimplePie("folia_version", () -> paperVersion)); // Folia - we have our own bstats page
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>();
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..29bd788ae8bc61c1e62a4f84b9e259931a7041ce 100644
--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
@@ -49,7 +49,7 @@ public class PaperVersionFetcher implements VersionFetcher {
if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) {
updateMessage = text("You are running a development version without access to version information", color(0xFF5300));
} else {
- updateMessage = getUpdateStatusMessage("PaperMC/Paper", build);
+ updateMessage = getUpdateStatusMessage("PaperMC/Folia", build); // Folia
}
final @Nullable Component history = this.getHistory();
@@ -86,7 +86,7 @@ public class PaperVersionFetcher implements VersionFetcher {
private static int fetchDistanceFromSiteApi(final ServerBuildInfo build, final int jenkinsBuild) {
try {
try (final BufferedReader reader = Resources.asCharSource(
- URI.create("https://api.papermc.io/v2/projects/paper/versions/" + build.minecraftVersionId()).toURL(),
+ URI.create("https://api.papermc.io/v2/projects/folia/versions/" + build.minecraftVersionId()).toURL(), // Folia
Charsets.UTF_8
).openBufferedStream()) {
final JsonObject json = new Gson().fromJson(reader, JsonObject.class);
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
index 790bad0494454ca12ee152e3de6da3da634d9b20..e741201fdbea0dbbc0e42313ebd33368014c9dc4 100644
--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
@@ -42,9 +42,9 @@ public record ServerBuildInfoImpl(
this(
getManifestAttribute(manifest, ATTRIBUTE_BRAND_ID)
.map(Key::key)
- .orElse(BRAND_PAPER_ID),
+ .orElse(Key.key("papermc", "folia")), // Folia
getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME)
- .orElse(BRAND_PAPER_NAME),
+ .orElse("Folia"), // Folia
SharedConstants.getCurrentVersion().getId(),
SharedConstants.getCurrentVersion().getName(),
getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER)
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 774556a62eb240da42e84db4502e2ed43495be17..e9b6ca3aa25e140467ae866d572483050ea3fa0e 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning {
public static String getBukkitVersion() {
String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties");
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/dev.folia/folia-api/pom.properties"); // Folia
Properties properties = new Properties();
if (stream != null) {

File diff suppressed because it is too large Load Diff

View File

@ -28,44 +28,8 @@ index 41bf71d116ffc5431586ce54abba7f8def6c1dcf..1cf9a7677449ab8f03fb23d835e3fadc
return (AbstractSchoolingFish) super.getHandle(); return (AbstractSchoolingFish) super.getHandle();
} }
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 35ff983cd84cb610b70e193220a97a3a5406252f..94f2610e1f2cce41d998bb9c92abbb38d9811f56 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3244,6 +3244,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
return false;
} else {
+ if (this.valid) { // Folia - region threading - suppress entire event logic during worldgen
// CraftBukkit start
if (entity.getBukkitEntity() instanceof Vehicle && this.getBukkitEntity() instanceof LivingEntity) {
VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) entity.getBukkitEntity(), this.getBukkitEntity());
@@ -3265,6 +3266,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return false;
}
// CraftBukkit end
+ } // Folia - region threading - suppress entire event logic during worldgen
if (this.isPassenger()) {
this.stopRiding();
}
@@ -3348,6 +3350,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
} else {
// CraftBukkit start
+ if (this.valid) { // Folia - region threading - suppress entire event logic during worldgen
CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle();
Entity orig = craft == null ? null : craft.getHandle();
if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
@@ -3375,6 +3378,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return false;
}
// CraftBukkit end
+ } // Folia - region threading - suppress entire event logic during worldgen
if (this.passengers.size() == 1 && this.passengers.get(0) == entity) {
this.passengers = ImmutableList.of();
} else {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
index 591af9d0d2fdc9953415979fc97a4a00afd85885..4a0fd1e3203342b7a5ffde579947057fe84a0d80 100644 index e8d82054d17ef1859eb57f3871043b3fe3de22b9..6fae4697512e6e1ded15938d4cdce93e7e2eef39 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java --- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
@@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
@ -88,7 +52,7 @@ index 591af9d0d2fdc9953415979fc97a4a00afd85885..4a0fd1e3203342b7a5ffde579947057f
+ +
@Override @Override
public boolean canHitEntity(org.bukkit.entity.Entity entity) { public boolean canHitEntity(org.bukkit.entity.Entity entity) {
return this.getHandle().canHitEntity(((CraftEntity) entity).getHandle()); return this.getHandle().canHitEntityPublic(((CraftEntity) entity).getHandle());
@@ -55,6 +63,7 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti @@ -55,6 +63,7 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
@Override @Override
@ -98,7 +62,7 @@ index 591af9d0d2fdc9953415979fc97a4a00afd85885..4a0fd1e3203342b7a5ffde579947057f
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
index d0c30fd12aa9866900fe72b97d10c257479cf010..46d8cbe8d09cf43b489d0358498e937454d96e7b 100644 index af2c1ad8cd878f0048f326699ac4462b86e7a4be..866456bda1bebb75ee4be77466d02f951060b693 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
@@ -133,6 +133,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr @@ -133,6 +133,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
@ -895,7 +859,7 @@ index 676dd5331bec75407a74aea2a89e78ab72d69724..4f876511b116dd6e7704f1f047af6fab
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
index 7b7b89e67d53ed70efae714192c5fa32977f3d9c..747907123b9a9b2b7cae4a20f77455ea48bc04e9 100644 index 1ef0ec7ed3b13c25d76c03c7013c8e2eaba4d66a..9f37334ba0e2358f583df5a6d3e347909cfe681e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
@@ -30,8 +30,16 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem @@ -30,8 +30,16 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem
@ -1021,10 +985,10 @@ index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..399ef60ab5f1bf02b638c8c46a72d297
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 5168cf0d58013aecfd80d37fb698014f38f8e08d..982778c4828e79bc7a55745418beb04f9c56cc78 100644 index e0ed7e9501bcf95c9bf7480f766738ed694295b0..fd6449e015289a0079e363ec6ca605cd0c8d7c27 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -514,6 +514,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @@ -538,6 +538,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
} }
public Entity getHandle() { public Entity getHandle() {
@ -1474,10 +1438,10 @@ index 9b6ff0f64966c78a3233860bb0840182b52f01bc..fb34651a9e4ed0cb05721d15524a26f8
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index e345cdbfab44a0f5da80d738798dbb4424b7ab5c..2a4ed66335e4fd88aefabb063ec04fe803bc728e 100644 index a1f42f860f080227a2223ec48d218e91d8f65977..9ce7dba9cfae9c34185a4edcfc2e3c1cc215ccea 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -298,8 +298,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -303,8 +303,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
this.mode = mode; this.mode = mode;
} }
@ -1579,7 +1543,7 @@ index 63cae1a2e95d8da17c45c4404a8dd0ca6a413c39..e417ff87b047dcffa6121835af6f4e71
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
index 30d62ee4d5cd2ddacb8783b5bbbf475d592b3e02..3985b6bea750341f5336babb237aab8874a4cbd9 100644 index 7a3d982b133f8cdaeb936cf40f92565f0f7f6dd0..9216543d8f9c25221abb510b35c6bd504e2ccfeb 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
@@ -18,8 +18,16 @@ public class CraftItem extends CraftEntity implements Item { @@ -18,8 +18,16 @@ public class CraftItem extends CraftEntity implements Item {
@ -2078,7 +2042,7 @@ index ecdac2cf74e99f0d69e053dece11ab891973dc2b..fa365c38c9e0f671df1481c8b36bc993
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
index b1b139b773b37e6ec2afea85c500387d6ba9800e..38c1eb97de420cd7dea6a9f76ef644ecdf8c30b8 100644 index bcac1359c667ef1ee46384f9c7a5adf4010d2b08..e740abd53d99f549acb5048d748241560dfeddd1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
@@ -50,8 +50,16 @@ public class CraftPainting extends CraftHanging implements Painting { @@ -50,8 +50,16 @@ public class CraftPainting extends CraftHanging implements Painting {
@ -2141,7 +2105,7 @@ index 04d6cf6a1f3ae8316e3b2862c2d1b04e84a3b20a..4ed79610b50be635a7a7c8a8f7d7af8f
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
index 83e77c6d287d8e239d2f55f3e9f19ef74946be7c..10e385066d29834eb3d8c9d539bb8655407cabb5 100644 index 429200b0b06cc0f71db03924228240b8b5f22a55..634a95a5d89821d3464e2ae8bd86b3b574f0ef17 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
@@ -9,8 +9,16 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy { @@ -9,8 +9,16 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
@ -2162,7 +2126,7 @@ index 83e77c6d287d8e239d2f55f3e9f19ef74946be7c..10e385066d29834eb3d8c9d539bb8655
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java
index 8016c810aeaf6ee953bca549bc1e7f9a85f860fc..e96e58fa4fb2a73e3e44c5213c73f332df4daa97 100644 index fd4f13e8ea000eb38efd77bfb197855db8816744..7f049e504cf7af7c5c5ee247bccb4f6e01b80121 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java
@@ -55,8 +55,16 @@ public class CraftPig extends CraftAnimals implements Pig { @@ -55,8 +55,16 @@ public class CraftPig extends CraftAnimals implements Pig {
@ -2288,10 +2252,10 @@ index 2638c341bc02f201f7ab17fdebcdbdf3a7ec05bf..074b2919be2b5544b0a46e6cd32f6c57
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index f2a847e590c72eee91a053cecdc691c53751ca3a..b0e93050839ce00b057e3a9bf3bdf8dd5e0662cf 100644 index 89633d88be288e8caba846c49c6267e45fcadc06..5aa9fcb697a758da10a9e1f839dd5502a446c076 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -683,7 +683,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -684,7 +684,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override @Override
public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) { public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
@ -2300,7 +2264,7 @@ index f2a847e590c72eee91a053cecdc691c53751ca3a..b0e93050839ce00b057e3a9bf3bdf8dd
final ServerGamePacketListenerImpl connection = this.getHandle().connection; final ServerGamePacketListenerImpl connection = this.getHandle().connection;
if (connection != null) { if (connection != null) {
connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause); connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause);
@@ -2336,9 +2336,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -2318,9 +2318,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return this; return this;
} }
@ -2803,7 +2767,7 @@ index 067a95ea50418601acfb8b9453d1291161bb706a..3a41ef5fdecee262f3e8899deec360c3
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java
index 9472a6f9c9584048abf1f8d11ab6254b7c7a287d..de8f656818192f35cca228724db3d17ede40b556 100644 index 74fac97231d4d89d1b941a1b5295afc2dafc6007..27992471bb7727a17f5fee61046cc0718994403a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java
@@ -65,8 +65,16 @@ public class CraftStrider extends CraftAnimals implements Strider { @@ -65,8 +65,16 @@ public class CraftStrider extends CraftAnimals implements Strider {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Throw UnsupportedOperationException() for broken APIs
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 26e1584557c8ba7b6bdf4a5ca7fc801d2f33fbdf..567e12e24ece2cd823b73e7337b10eb89995da21 100644 index 82e4b25fbfb27d4a2a96a0785daf2168c60584aa..62a9bb77078522c3a98806083a4995251e036138 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1320,6 +1320,7 @@ public final class CraftServer implements Server { @@ -1320,6 +1320,7 @@ public final class CraftServer implements Server {
@ -16,7 +16,7 @@ index 26e1584557c8ba7b6bdf4a5ca7fc801d2f33fbdf..567e12e24ece2cd823b73e7337b10eb8
Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP"); Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP");
//Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes. //Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes.
Preconditions.checkArgument(creator != null, "WorldCreator cannot be null"); Preconditions.checkArgument(creator != null, "WorldCreator cannot be null");
@@ -1498,6 +1499,7 @@ public final class CraftServer implements Server { @@ -1517,6 +1518,7 @@ public final class CraftServer implements Server {
@Override @Override
public boolean unloadWorld(World world, boolean save) { public boolean unloadWorld(World world, boolean save) {

View File

@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 3 Oct 2023 06:03:34 -0700
Subject: [PATCH] Region profiler
Profiling for a region starts with the /profiler command.
The usage for /profiler:
/profiler <world> <block x> <block z> <time in s> [radius, default 100 blocks]
Any region within the radius of the specified block coordinates
will be profiled. The profiling will stop after the specified
time has passed.
Once the profiler finishes, it will place a report in
the directory ./profiler/<id>.
Since regions can split into smaller regions, or merge into
other regions, the profiler will track this information. If
a profiled region splits, then all of the regions it splits
into are attached to the same profiler instance. If a profiled
region merges into another region, then the merged region is
profiled. This information is tracked and logged into the
"journal.txt" file contained in the report directory. The
journal tracks the region ids for the merge/split operations.
Region profiling is placed into the "region-X.txt" file where
X is the region id inside the profile directory. The header
of the file describes some stats about the region, namely
total profiling duration, ticks, utilisation, TPS, and MSPT.
Then, the timing tree is follows. The format is as specified:
There are two types of data recorded: Timers and Counters.
Timers are specified as follows:
<indent><name> X% total, Y% parent, self A% total, self B% children, avg D sum E, Fms raw sum
The above specifies the format for a named timer.
The <indent> specifies the number of parent timers.
"X" represents the percentage of time the timer took relative
to the entire profiling instance.
"Y" represents the percentage of time the timer took relative
to its _parents_ timer. For example:
```
Full Tick 100.000% total, 100.000% parent, self 0.889% total, self 0.889% children, avg 200.000 sum 200, 401.300ms raw sum
|+++Tick World: minecraft:overworld 81.409% total, 81.409% parent, self 1.873% total, self 2.301% children, avg 1.000 sum 200, 326.694ms raw sum
|---|---Entity Tick 56.784% total, 69.751% parent, self 6.049% total, self 10.652% children, avg 1.000 sum 200, 227.874ms raw sum
```
"Entity Tick" measured 69.751% of the time for the "Tick World: minecraft:overworld" timer.
"A" represents the self time relative to the entire profiling instance.
The self time is the amount of time for a timer that is _not_ measured
by a child timer.
"B" represents the self time relative to its _parents_ timer.
"D" represents the average number of times the timer is invoked relative to
its parent.
For example:
```
|---|---|---Entity Tick: bat 2.642% total, 7.343% parent, self 2.642% total, self 100.000% children, avg 14.975 sum 2,995, 23.127ms raw sum
```
In this case, an average of 14.975 bats were ticked for every
time the "Entity Tick" timer was invoked.
"E" represents the total number of times the timer is invoked.
"F" represents the total raw time accumulated by the timer.
Counters are specified as follows:
<indent>#<name> avg X sum Y
The X is the average number of times the counter is invoked
relative to the parent, exactly similar to the D field of Timers,
where Y is the total number of times the counter is invoked.
diff --git a/src/main/java/io/papermc/paper/command/PaperCommands.java b/src/main/java/io/papermc/paper/command/PaperCommands.java
index a587d83b78af4efc484f939529acf70834f60d7e..45f76aaaa7dedb77a83b4a2c87905bf9a099a93c 100644
--- a/src/main/java/io/papermc/paper/command/PaperCommands.java
+++ b/src/main/java/io/papermc/paper/command/PaperCommands.java
@@ -20,6 +20,7 @@ public final class PaperCommands {
COMMANDS.put("callback", new CallbackCommand("callback"));
COMMANDS.put("mspt", new MSPTCommand("mspt"));
COMMANDS.put("tps", new io.papermc.paper.threadedregions.commands.CommandServerHealth()); // Folia - region threading
+ COMMANDS.put("profiler", new io.papermc.paper.threadedregions.commands.CommandProfiler()); // Folia - region threading - profiler
}
public static void registerCommands(final MinecraftServer server) {

View File

@ -0,0 +1,21 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Fri, 30 Aug 2024 18:34:32 -0700
Subject: [PATCH] Add watchdog thread
When regions take too long, having the server print the stacktrace
of the ticking region should help debug the cause.
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index a9339f59f81dff307317ae4afdff0dc296febcc9..75b698c2bcbbf487200b29083671332a6cc222ed 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -159,7 +159,7 @@ public class WatchdogThread extends Thread {
}
}
- private static void dumpThread(ThreadInfo thread, Logger log) {
+ public static void dumpThread(ThreadInfo thread, Logger log) { // Folia - watchdog
log.log(Level.SEVERE, "------------------------------");
log.log(Level.SEVERE, "Current Thread: " + thread.getThreadName());

View File

@ -0,0 +1,3 @@
--- a/src/main/resources/data/.paperassetsroot
+++ b/src/main/resources/data/.paperassetsroot
@@ -1,0 +_,0 @@

View File

@ -2,10 +2,9 @@ group=dev.folia
version=1.21.4-R0.1-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT
mcVersion=1.21.4 mcVersion=1.21.4
paperRef=b746d9df0b6b7765478b2a72c2d963b6e668fa35 paperRef=3d9ecc4e085d9cfb6c97fd7efe877b3468c6b4fb
org.gradle.configuration-cache=true
org.gradle.caching=true org.gradle.caching=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.vfs.watch=false org.gradle.vfs.watch=false
org.gradle.jvmargs=-Xmx2G

View File

@ -0,0 +1,2 @@
# This file was generated by the Gradle 'init' task.
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

3
gradlew vendored
View File

@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum

0
gradlew.bat vendored Executable file → Normal file
View File

View File

@ -1 +0,0 @@
./gradlew publishToMavenLocal

View File

@ -1 +0,0 @@
./gradlew createMojmapPaperclipJar

2
notes.txt Normal file
View File

@ -0,0 +1,2 @@
change dragonParts to use concurrent map and look at getEntities usage

View File

@ -1 +0,0 @@
./gradlew applypatches

1
patch.sh Executable file
View File

@ -0,0 +1 @@
./gradlew applyAllPatches

View File

@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 7 Mar 2023 12:58:48 -0800
Subject: [PATCH] Add RegionizedServerInitEvent
This event allows plugins to perform synchronous operations before
any region will tick. Plugins will not have to worry about the
possibility of a region ticking in parallel while listening
to the event.
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedServerInitEvent.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedServerInitEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7be944c5638cb6650624bd622b2ad9d52c5c31d
--- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedServerInitEvent.java
@@ -0,0 +1,26 @@
+package io.papermc.paper.threadedregions;
+
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.server.ServerEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * This event is called after the server is initialised but <b>before</b> the server begins ticking regions in parallel.
+ * Plugins may use this as a hook to run post initialisation logic without worrying about the possibility that
+ * regions are ticking in parallel.
+ */
+public class RegionizedServerInitEvent extends ServerEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}

View File

@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Fri, 31 Mar 2023 20:40:28 -0700
Subject: [PATCH] MC-Dev fixes
diff --git a/src/main/java/net/minecraft/world/entity/ai/Brain.java b/src/main/java/net/minecraft/world/entity/ai/Brain.java
index afbb027021acfbe25d534a84f1750e420bbde6e0..af6f91c66e9cc7e0d491e6efed992a140947155e 100644
--- a/src/main/java/net/minecraft/world/entity/ai/Brain.java
+++ b/src/main/java/net/minecraft/world/entity/ai/Brain.java
@@ -79,7 +79,7 @@ public class Brain<E extends LivingEntity> {
}
public <T> DataResult<Brain<E>> decode(DynamicOps<T> dynamicOps, MapLike<T> mapLike) {
- MutableObject<DataResult<Builder<Brain.MemoryValue<?>>>> mutableObject = new MutableObject<>(
+ MutableObject<DataResult<Builder<Brain.MemoryValue<?>>>> mutableObject2 = new MutableObject<>( // Folia - decompile fix
DataResult.success(ImmutableList.builder())
);
mapLike.entries()
@@ -91,10 +91,10 @@ public class Brain<E extends LivingEntity> {
DataResult<? extends Brain.MemoryValue<?>> dataResult2 = dataResult.flatMap(
memoryType -> this.captureRead((MemoryModuleType<T>)memoryType, dynamicOps, (T)pair.getSecond())
);
- mutableObject.setValue(mutableObject.getValue().apply2(Builder::add, dataResult2));
+ mutableObject2.setValue(mutableObject2.getValue().apply2(Builder::add, dataResult2)); // Folia - decompile fix
}
);
- ImmutableList<Brain.MemoryValue<?>> immutableList = mutableObject.getValue()
+ ImmutableList<Brain.MemoryValue<?>> immutableList = mutableObject2.getValue() // Folia - decompile fix
.resultOrPartial(Brain.LOGGER::error)
.map(Builder::build)
.orElseGet(ImmutableList::of);
@@ -194,14 +194,14 @@ public class Brain<E extends LivingEntity> {
if (optional == null) {
throw new IllegalStateException("Unregistered memory fetched: " + type);
} else {
- return optional.map(ExpirableValue::getValue);
+ return (Optional<U>)optional.map(ExpirableValue::getValue); // Folia - decompile fix
}
}
@Nullable
public <U> Optional<U> getMemoryInternal(MemoryModuleType<U> type) {
Optional<? extends ExpirableValue<?>> optional = this.memories.get(type);
- return optional == null ? null : optional.map(ExpirableValue::getValue);
+ return optional == null ? null : (Optional<U>)optional.map(ExpirableValue::getValue); // Folia - decompile fix
}
public <U> long getTimeUntilExpiry(MemoryModuleType<U> type) {

View File

@ -1,112 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 17 Apr 2023 19:47:57 -0700
Subject: [PATCH] Prevent block updates in non-loaded or non-owned chunks
This is to prevent block physics from tripping thread checks by
far exceeding the bounds of the current region. While this does
add explicit block update suppression techniques, it's better
than the server crashing.
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index fc180c3f68a40e909f7e357a6fcd06858b870e97..7c18c298e26b2920ea588fc6a16c0baaea9f6fe5 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1969,7 +1969,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
Direction enumdirection = (Direction) iterator.next();
BlockPos blockposition1 = pos.relative(enumdirection);
- if (this.hasChunkAt(blockposition1)) {
+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((ServerLevel)this, blockposition1) && this.hasChunkAt(blockposition1)) { // Folia - block updates in unloaded chunks
BlockState iblockdata = this.getBlockState(blockposition1);
if (iblockdata.is(Blocks.COMPARATOR)) {
diff --git a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
index fa1c4defd0d4e4cd888eb26eed131539d0ed573f..afd09a54ee3962943cdf4150a41817fdb0da6615 100644
--- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -135,9 +135,9 @@ public class DetectorRailBlock extends BaseRailBlock {
while (iterator.hasNext()) {
BlockPos blockposition1 = (BlockPos) iterator.next();
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+ BlockState iblockdata1 = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((ServerLevel)world, blockposition1) ? null : world.getBlockStateIfLoaded(blockposition1); // Folia - block updates in unloaded chunks
- world.neighborChanged(iblockdata1, blockposition1, iblockdata1.getBlock(), (Orientation) null, false);
+ if (iblockdata1 != null) world.neighborChanged(iblockdata1, blockposition1, iblockdata1.getBlock(), (Orientation) null, false); // Folia - block updates in unloaded chunks
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
index b763361a8f0f1b46093d5dd9afe8dba0cadf9c78..78c6fc0755b149515a98163cb7c68589595c365c 100644
--- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
@@ -104,9 +104,9 @@ public class PoweredRailBlock extends BaseRailBlock {
}
protected boolean isSameRailWithPower(Level world, BlockPos pos, boolean flag, int distance, RailShape shape) {
- BlockState iblockdata = world.getBlockState(pos);
+ BlockState iblockdata = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, pos) ? null : world.getBlockStateIfLoaded(pos); // Folia - block updates in unloaded chunks
- if (!iblockdata.is((Block) this)) {
+ if (iblockdata == null || !iblockdata.is((Block) this)) { // Folia - block updates in unloaded chunks
return false;
} else {
RailShape blockpropertytrackposition1 = (RailShape) iblockdata.getValue(PoweredRailBlock.SHAPE);
diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
index 0020e7bb7b19179a898cd8835d12cfa37eccdcc2..cf3307a3e30c08e741e25ef5757d6597089f6919 100644
--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -237,7 +237,8 @@ public class RedStoneWireBlock extends Block {
for (Direction direction : Direction.Plane.HORIZONTAL) {
RedstoneSide redstoneSide = state.getValue(PROPERTY_BY_DIRECTION.get(direction));
- if (redstoneSide != RedstoneSide.NONE && !world.getBlockState(mutableBlockPos.setWithOffset(pos, direction)).is(this)) {
+ BlockState currState; mutableBlockPos.setWithOffset(pos, direction); // Folia - block updates in unloaded chunks
+ if (redstoneSide != RedstoneSide.NONE && (currState = (world instanceof net.minecraft.server.level.ServerLevel serverLevel && !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(serverLevel, pos) ? null : world.getBlockStateIfLoaded(mutableBlockPos.setWithOffset(pos, direction)))) != null && !currState.is(this)) { // Folia - block updates in unloaded chunks
mutableBlockPos.move(Direction.DOWN);
BlockState blockState = world.getBlockState(mutableBlockPos);
if (blockState.is(this)) {
diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
index 63b12dcb1b86e15607ebbaa157d7a330c089862d..d1d8360f1ae931b22e1712b498ae66b7649be90d 100644
--- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
+++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
@@ -124,7 +124,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
public boolean runNext(Level world) {
Direction direction = NeighborUpdater.UPDATE_ORDER[this.idx++];
BlockPos blockPos = this.sourcePos.relative(direction);
- BlockState blockState = world.getBlockState(blockPos);
+ BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, blockPos) ? null : world.getBlockStateIfLoaded(blockPos); // Folia - block updates in unloaded chunks
+ if (blockState != null) { // Folia - block updates in unloaded chunks
Orientation orientation = null;
if (world.enabledFeatures().contains(FeatureFlags.REDSTONE_EXPERIMENTS)) {
if (this.orientation == null) {
@@ -137,6 +138,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
}
NeighborUpdater.executeUpdate(world, blockState, blockPos, this.sourceBlock, orientation, false, this.sourcePos); // Paper - Add source block to BlockPhysicsEvent
+ } // Folia - block updates in unloaded chunks
if (this.idx < NeighborUpdater.UPDATE_ORDER.length && NeighborUpdater.UPDATE_ORDER[this.idx] == this.skipDirection) {
this.idx++;
}
@@ -153,7 +155,9 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
implements CollectingNeighborUpdater.NeighborUpdates {
@Override
public boolean runNext(Level world) {
+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, this.pos) && world.getChunkIfLoaded(this.pos) != null) { // Folia - block updates in unloaded chunks
NeighborUpdater.executeShapeUpdate(world, this.direction, this.pos, this.neighborPos, this.neighborState, this.updateFlags, this.updateLimit);
+ } // Folia - block updates in unloaded chunks
return false;
}
}
@@ -161,8 +165,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
static record SimpleNeighborUpdate(BlockPos pos, Block block, @Nullable Orientation orientation) implements CollectingNeighborUpdater.NeighborUpdates {
@Override
public boolean runNext(Level world) {
- BlockState blockState = world.getBlockState(this.pos);
- NeighborUpdater.executeUpdate(world, blockState, this.pos, this.block, this.orientation, false);
+ BlockState blockState = !ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor((net.minecraft.server.level.ServerLevel)world, this.pos) ? null : world.getBlockStateIfLoaded(this.pos); // Folia - block updates in unloaded chunks
+ if (blockState != null) NeighborUpdater.executeUpdate(world, blockState, this.pos, this.block, this.orientation, false); // Folia - block updates in unloaded chunks
return false;
}
}

View File

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 23 Apr 2023 07:38:50 -0700
Subject: [PATCH] Skip worldstate access when waking players up during data
deserialization
In general, worldstate read/write is unacceptable during
data deserialization and is racey even in Vanilla. But in Folia,
some accesses may throw and as such we need to fix this directly.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 130643b97fdab3bf89fc87afd6d4e0b922dac538..54c610bb14f8af6026c91179e402ebc66ffbf49c 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -794,7 +794,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
this.getBukkitEntity().readExtraData(nbt); // CraftBukkit
if (this.isSleeping()) {
- this.stopSleeping();
+ this.stopSleepingRaw(); // Folia - do not modify or read worldstate during data deserialization
}
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index e6871fb4b58910043e88ea45564363aa854eb0ca..73af15d18180b4df3fa0614b323f2397f5543db5 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -4612,6 +4612,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
});
+ // Folia start - separate out
+ this.stopSleepingRaw();
+ }
+ public void stopSleepingRaw() {
+ // Folia end - separate out
Vec3 vec3d = this.position();
this.setPose(Pose.STANDING);

View File

@ -1,40 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: WillQi <williamqipizza@gmail.com>
Date: Mon, 15 May 2023 23:45:09 -0600
Subject: [PATCH] Fix off region raid heroes
This patch aims to solve a potential incorrect thread call when completing a raid.
If a player is a hero of the village but proceeds to leave the region of the
raid before it's completion, it would throw an exception due to not being on the
same region thread anymore.
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
index 5ff4a4af7f166f5f977efe41263ca487fe1b270b..1df579db8286113f8412fe678259fb53098e57ed 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
@@ -423,14 +423,22 @@ public class Raid {
LivingEntity entityliving = (LivingEntity) entity;
if (!entity.isSpectator()) {
- entityliving.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.raidOmenLevel - 1, false, false, true));
+ //entityliving.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.raidOmenLevel - 1, false, false, true)); // Folia - Fix off region raid heroes - move down
if (entityliving instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entityliving;
- entityplayer.awardStat(Stats.RAID_WIN);
- CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ // Folia start - Fix off region raid heroes - moved down
winners.add(entityplayer.getBukkitEntity()); // CraftBukkit
}
+ // Folia start - Fix off region raid heroes
+ entityliving.getBukkitEntity().taskScheduler.schedule((LivingEntity lv) -> {
+ lv.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.raidOmenLevel - 1, false, false, true));
+ if (lv instanceof ServerPlayer entityplayer) {
+ entityplayer.awardStat(Stats.RAID_WIN);
+ CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ }
+ }, null, 1L);
+ // Folia end - Fix off region raid heroes
}
}
}

View File

@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 25 Jun 2023 13:57:30 -0700
Subject: [PATCH] Sync vehicle position to player position on player data load
This allows the player to be re-positioned before logging into
the world without causing thread checks to trip on Folia.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 54c610bb14f8af6026c91179e402ebc66ffbf49c..23f852ede94bce4d000c8fcaa8fba5d4800b533c 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -920,7 +920,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
if (world instanceof ServerLevel) {
ServerLevel worldserver = (ServerLevel) world;
CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle");
+ Vec3 playerPos = this.position(); // Paper - force sync root vehicle to player position
Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver, EntitySpawnReason.LOAD, (entity1) -> {
+ // Paper start - force sync root vehicle to player position
+ if (entity1.distanceToSqr(ServerPlayer.this) > (5.0 * 5.0)) {
+ entity1.setPosRaw(playerPos.x, playerPos.y, playerPos.z, true);
+ }
+ // Paper end - force sync root vehicle to player position
return !worldserver.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // CraftBukkit - decompile error // Paper - Entity#getEntitySpawnReason
});

1
rb.bat
View File

@ -1 +0,0 @@
./gradlew rebuildpatches

3
rb.sh Executable file
View File

@ -0,0 +1,3 @@
./gradlew rebuildPaperPatches
./gradlew rebuildServerPatches
./gradlew rebuildMinecraftPatches

View File

@ -1,33 +0,0 @@
Get done after test:
- global autosave queue
- game time / day time tick comparison (== is now invalid due to desync of global / region tick)
- scoreboards
- vanish api
- watchdog stuff
- Spectator teleporting / camera
- Conversable...
- sync load info
- net.minecraft.commands.Commands
- are the race conditions in the weather tick (advanceWeatherCycle) ok?
- make scheduler load chunks better? this requires additional work to:
-> reduce scheduler overhead (i.e at 5000 regions, on 16 threads -> overhead is 10%)
-> unsure how to reduce scheduler overhead, may need to rewrite it so that the queues
are per tick thread and thus it increases parallelism
-> reduce chunk system overhead (i.e at 20 workers, ~100 unique concurrent regions, overhead -> 10-30% on both workers AND tick threads (at tick threads ->8)
-> the only way out of the chunk system overhead is to make the scheduling more parallel - it requires scheduling lock and ticket lock
- redstone wire accross regions
Delayed and hopefully will not forget:
- api for really a lot of shit
- needs: true async events (i.e fire then complete later)
- needs: region determination, craft scheduler per region, craft scheduler
per entity
- needs: world creation/unload (good god)
- needs: more???
- Projectile#getOwner ...
Ideas:
Issues:
To check:

View File

@ -1,38 +1,16 @@
import java.util.Locale
pluginManagement { pluginManagement {
repositories { repositories {
gradlePluginPortal() gradlePluginPortal()
mavenLocal()
maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.papermc.io/repository/maven-public/")
} }
} }
plugins { plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}
if (!file(".git").exists()) {
val errorText = """
=====================[ ERROR ]=====================
The Folia project directory is not a properly cloned Git repository.
In order to build Folia from source you must clone
the Folia repository using Git, not download a code
zip from GitHub.
See https://github.com/PaperMC/Paper/blob/master/CONTRIBUTING.md
for further information on building and modifying Paper and Forks.
===================================================
""".trimIndent()
error(errorText)
} }
rootProject.name = "folia" rootProject.name = "folia"
for (name in listOf("Folia-API", "Folia-Server")) { include("folia-api")
val projName = name.lowercase(Locale.ENGLISH) include("folia-server")
include(projName)
file(name).mkdirs()
findProject(":$projName")!!.projectDir = file(name)
}