commit 12ada6454224378cd84644c5929eefbed3e5fcfb
Author: MrPowerGamerBR
Date: Sun Oct 22 08:48:25 2023 -0300
First commit! :tada:
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..210d3ca
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,6 @@
+[*.java]
+charset=utf-8
+end_of_line=lf
+insert_final_newline=true
+indent_style=space
+indent_size=4
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..2fb638f
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,7 @@
+* text=auto
+
+*.sh text eol=lf
+gradlew text eol=lf
+*.bat text eol=crlf
+
+*.jar binary
diff --git a/.github/workflows/auto-update.yml b/.github/workflows/auto-update.yml
new file mode 100644
index 0000000..09338aa
--- /dev/null
+++ b/.github/workflows/auto-update.yml
@@ -0,0 +1,44 @@
+name: Automatically update Paper commit hash
+on:
+ workflow_dispatch: {}
+ schedule:
+ - cron: "0 0 * * *"
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout SparklyPaper Repository
+ uses: actions/checkout@v3
+ with:
+ path: 'SparklyPaper'
+ token: ${{ secrets.LORITTA_PAT }}
+
+ - name: Checkout Paper Repository
+ uses: actions/checkout@v3
+ with:
+ path: 'Paper'
+ repository: "PaperMC/Paper"
+ token: ${{ secrets.LORITTA_PAT }}
+
+ - name: Get Paper Latest Commit Hash
+ id: paperRef
+ run: |
+ ls
+ cd Paper
+ echo "::set-output name=paperRef::$(git rev-parse HEAD)"
+ cd ..
+
+ - name: Update paperRef in SparklyPaper
+ run: |
+ sed -i "s/\paperRef=.*/paperRef=$PAPER_REF/" SparklyPaper/gradle.properties
+ env:
+ PAPER_REF: ${{ steps.paperRef.outputs.paperRef }}
+
+ - name: Write to repository
+ run: |
+ cd SparklyPaper
+ git add gradle.properties
+ git config user.name "Loritta Morenitta"
+ git config user.email 47356322+LorittaMorenitta@users.noreply.github.com
+ git commit -m "Updated Upstream (Paper)"
+ git push
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..14dd07b
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,32 @@
+name: Patch and Build
+
+on:
+ push:
+ branches: [ "**" ]
+ pull_request:
+
+jobs:
+ build:
+ # Only run on PRs if the source branch is on someone else's repo
+ if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Git Repository
+ uses: actions/checkout@v3
+ - name: Validate Gradle wrapper
+ uses: gradle/wrapper-validation-action@v1
+ - name: Setup Gradle
+ uses: gradle/gradle-build-action@v2
+ - name: Set up JDK
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ - name: Configure Git User Details
+ run: git config --global user.email "actions@github.com" && git config --global user.name "Github Actions"
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Apply Patches
+ run: ./gradlew applyPatches
+ - name: Build
+ run: ./gradlew build
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..615b683
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,52 @@
+.gradle/
+build/
+
+# Eclipse stuff
+.classpath
+.project
+.settings/
+
+# VSCode stuff
+.vscode/
+
+# netbeans
+nbproject/
+nbactions.xml
+
+# 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/
+out/
+
+# Linux temp files
+*~
+
+# other stuff
+run/
+
+forktest-server
+forktest-api
+
+!gradle/wrapper/gradle-wrapper.jar
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0f23a70
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+
+
+
+
+
+
✨ SparklyPaper ✨
+
+
+SparklyPower's Paper fork, with a mix of weird & crazy patches from other forks!
\ No newline at end of file
diff --git a/build-data/dev-imports.txt b/build-data/dev-imports.txt
new file mode 100644
index 0000000..b818b96
--- /dev/null
+++ b/build-data/dev-imports.txt
@@ -0,0 +1,10 @@
+# You can use this file to import files from minecraft libraries into the project
+# format:
+#
+# both fully qualified and a file based syntax are accepted for :
+# authlib com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
+# datafixerupper com.mojang.datafixers.DataFixerBuilder
+# datafixerupper com/mojang/datafixers/util/Either.java
+# 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/LevelEntityGetter.java
diff --git a/build-data/reobf-mappings-patch.tiny b/build-data/reobf-mappings-patch.tiny
new file mode 100644
index 0000000..e975a3c
--- /dev/null
+++ b/build-data/reobf-mappings-patch.tiny
@@ -0,0 +1,18 @@
+# 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
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..91107fd
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,115 @@
+plugins {
+ java
+ `maven-publish`
+
+ // Nothing special about this, just keep it up to date
+ id("com.github.johnrengelman.shadow") version "8.1.1" apply false
+
+ // In general, keep this version in sync with upstream. Sometimes a newer version than upstream might work, but an older version is extremely likely to break.
+ id("io.papermc.paperweight.patcher") version "1.5.7"
+}
+
+val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
+
+repositories {
+ mavenCentral()
+ maven(paperMavenPublicUrl) {
+ content { onlyForConfigurations(configurations.paperclip.name) }
+ }
+}
+
+dependencies {
+ remapper("net.fabricmc:tiny-remapper:0.8.6:fat") // Must be kept in sync with upstream
+ decompiler("net.minecraftforge:forgeflower:2.0.627.2") // Must be kept in sync with upstream
+ paperclip("io.papermc:paperclip:3.0.3") // You probably want this to be kept in sync with upstream
+}
+
+allprojects {
+ apply(plugin = "java")
+ apply(plugin = "maven-publish")
+
+ java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(17))
+ }
+ }
+}
+
+subprojects {
+ tasks.withType {
+ options.encoding = Charsets.UTF_8.name()
+ options.release.set(17)
+ }
+ tasks.withType {
+ options.encoding = Charsets.UTF_8.name()
+ }
+ tasks.withType {
+ filteringCharset = Charsets.UTF_8.name()
+ }
+
+ repositories {
+ mavenCentral()
+ maven(paperMavenPublicUrl)
+ }
+}
+
+paperweight {
+ serverProject.set(project(":sparklypaper-server"))
+
+ remapRepo.set(paperMavenPublicUrl)
+ decompileRepo.set(paperMavenPublicUrl)
+
+ usePaperUpstream(providers.gradleProperty("paperRef")) {
+ withPaperPatcher {
+ apiPatchDir.set(layout.projectDirectory.dir("patches/api"))
+ apiOutputDir.set(layout.projectDirectory.dir("sparklypaper-api"))
+
+ serverPatchDir.set(layout.projectDirectory.dir("patches/server"))
+ serverOutputDir.set(layout.projectDirectory.dir("sparklypaper-server"))
+ }
+ }
+}
+
+//
+// Everything below here is optional if you don't care about publishing API or dev bundles to your repository
+//
+
+tasks.generateDevelopmentBundle {
+ apiCoordinates.set("net.sparklypower.sparklypaper:sparklypaper-api")
+ mojangApiCoordinates.set("io.papermc.paper:paper-mojangapi")
+ libraryRepositories.set(
+ listOf(
+ "https://repo.maven.apache.org/maven2/",
+ paperMavenPublicUrl,
+ // "https://my.repo/", // This should be a repo hosting your API (in this example, 'net.sparklypower.sparklypaper:sparklypaper-api')
+ )
+ )
+}
+
+allprojects {
+ // Publishing API:
+ // ./gradlew :SparklyPaper-API:publish[ToMavenLocal]
+ publishing {
+ repositories {
+ maven {
+ name = "myRepoSnapshots"
+ url = uri("https://my.repo/")
+ // See Gradle docs for how to provide credentials to PasswordCredentials
+ // https://docs.gradle.org/current/samples/sample_publishing_credentials.html
+ credentials(PasswordCredentials::class)
+ }
+ }
+ }
+}
+
+publishing {
+ // Publishing dev bundle:
+ // ./gradlew publishDevBundlePublicationTo(MavenLocal|MyRepoSnapshotsRepository) -PpublishDevBundle
+ if (project.hasProperty("publishDevBundle")) {
+ publications.create("devBundle") {
+ artifact(tasks.generateDevelopmentBundle) {
+ artifactId = "dev-bundle"
+ }
+ }
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..16203b0
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,11 @@
+group=net.sparklypower.sparklypaper
+version=1.20.2-R0.1-SNAPSHOT
+
+mcVersion=1.20.2
+paperRef=3a5c6f8cee7e1379fff1908e87af9fd5448eda0e
+
+org.gradle.caching=true
+org.gradle.parallel=true
+org.gradle.vfs.watch=false
+
+org.gradle.jvmargs=-Xmx4096M
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7f93135
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..3fa8f86
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..1aa94a4
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..93e3f59
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch b/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch
new file mode 100644
index 0000000..fabfe22
--- /dev/null
+++ b/patches/server/0001-new-fork-who-dis-Rebrand-to-SparklyPaper-and-Build-C.patch
@@ -0,0 +1,124 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: MrPowerGamerBR
+Date: Sat, 12 Jun 2021 16:40:34 +0200
+Subject: [PATCH] new fork who dis - Rebrand to SparklyPaper and Build Changes
+
+
+diff --git a/build.gradle.kts b/build.gradle.kts
+index a79461457ea19339f47572c70705d655ebc55276..768a691649d9146c7c975a3b25258551d0b6df0a 100644
+--- a/build.gradle.kts
++++ b/build.gradle.kts
+@@ -3,6 +3,8 @@ import io.papermc.paperweight.util.*
+ plugins {
+ java
+ `maven-publish`
++ kotlin("jvm") version "1.9.10"
++ kotlin("plugin.serialization") version "1.9.10"
+ id("com.github.johnrengelman.shadow")
+ }
+
+@@ -13,8 +15,14 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) {
+ val alsoShade: Configuration by configurations.creating
+
+ dependencies {
+- implementation(project(":paper-api"))
+- implementation(project(":paper-mojangapi"))
++ // SparklyPaper start
++ implementation(project(":sparklypaper-api"))
++ implementation("io.papermc.paper:paper-mojangapi:1.20.2-R0.1-SNAPSHOT") {
++ exclude("io.papermc.paper", "paper-api")
++ }
++ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
++ implementation("com.charleskorn.kaml:kaml:0.55.0")
++ // SparklyPaper end
+ // Paper start
+ implementation("org.jline:jline-terminal-jansi:3.21.0")
+ implementation("net.minecrell:terminalconsoleappender:1.3.0")
+@@ -70,7 +78,7 @@ tasks.jar {
+ attributes(
+ "Main-Class" to "org.bukkit.craftbukkit.Main",
+ "Implementation-Title" to "CraftBukkit",
+- "Implementation-Version" to "git-Paper-$implementationVersion",
++ "Implementation-Version" to "git-SparklyPaper-$implementationVersion", // ForkTest
+ "Implementation-Vendor" to date, // Paper
+ "Specification-Title" to "Bukkit",
+ "Specification-Version" to project.version,
+@@ -154,7 +162,7 @@ fun TaskContainer.registerRunTask(
+ name: String,
+ block: JavaExec.() -> Unit
+ ): TaskProvider = register(name) {
+- group = "paper"
++ group = "paperweight" // SparklyPaper
+ mainClass.set("org.bukkit.craftbukkit.Main")
+ standardInput = System.`in`
+ workingDir = rootProject.layout.projectDirectory
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index 97745f0bab8d82d397c6c2a5775aed92bca0a034..0dfd9a2f9195ec018ed5069f43908b8c0e09edbd 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -1697,7 +1697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop // Spigot - Spigot > // CraftBukkit - cb > vanilla!
++ return "SparklyPaper"; // SparklyPaper - SparklyPaper > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla!
+ }
+
+ public SystemReport fillSystemReport(SystemReport details) {
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+index b7e7e6ed60f55d2ab5e4fcefb3638ad1768c3b7f..38460bef2c55264b145c3e21b314eeb88b812d41 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+@@ -267,7 +267,7 @@ import javax.annotation.Nullable; // Paper
+ import javax.annotation.Nonnull; // Paper
+
+ public final class CraftServer implements Server {
+- private final String serverName = "Paper"; // Paper
++ private final String serverName = "SparklyPaper"; // SparklyPaper // Paper
+ private final String serverVersion;
+ private final String bukkitVersion = Versioning.getBukkitVersion();
+ private final Logger logger = Logger.getLogger("Minecraft");
+diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+index 774556a62eb240da42e84db4502e2ed43495be17..22e504565de83f976c8b2996f0b2207b48cbec34 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/net.sparklypower.sparklypaper/sparklypaper-api/pom.properties"); // ForkTest
+ Properties properties = new Properties();
+
+ if (stream != null) {
+diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
+index 50c72e5db369a180f425eaaa0411cb8871bc3463..682077870a3607afc7ec66ed6e8dcf8484c63fd0 100644
+--- a/src/main/java/org/spigotmc/WatchdogThread.java
++++ b/src/main/java/org/spigotmc/WatchdogThread.java
+@@ -155,14 +155,14 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
+ if (isLongTimeout) {
+ // Paper end
+ log.log( Level.SEVERE, "------------------------------" );
+- log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
++ log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug. This could be a SparklyPaper bug and, in that case, MrPowerGamerBR probably made a fucky wucky!" ); // SparklyPaper - branding changes // Paper
+ log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
+ log.log( Level.SEVERE, "\t *Especially* if it looks like HTTP or MySQL operations are occurring" );
+ log.log( Level.SEVERE, "If you see a world save or edit, then it means you did far more than your server can handle at once" );
+ log.log( Level.SEVERE, "\t If this is the case, consider increasing timeout-time in spigot.yml but note that this will replace the crash with LARGE lag spikes" );
+- log.log( Level.SEVERE, "If you are unsure or still think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues" );
++ log.log( Level.SEVERE, "If you are unsure or still think this is a SparklyPaper bug, please report this to https://github.com/SparklyPower/SparklyPaper/issues - and if you think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues" );
+ log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" );
+- log.log( Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion() );
++ log.log( Level.SEVERE, "SparklyPaper version: " + Bukkit.getServer().getVersion() ); // SparklyPaper - branding changes
+ //
+ if ( net.minecraft.world.level.Level.lastPhysicsProblem != null )
+ {
+@@ -190,7 +190,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
+ }
+ // Paper end - Different message for short timeout
+ log.log( Level.SEVERE, "------------------------------" );
+- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
++ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to SparklyPaper!):" ); // SparklyPaper - branding changes // Paper
+ io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
+ this.dumpTickingInfo(); // Paper - log detailed tick information
+ WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
diff --git a/patches/server/0002-SparklyPaper-config-files.patch b/patches/server/0002-SparklyPaper-config-files.patch
new file mode 100644
index 0000000..abe5310
--- /dev/null
+++ b/patches/server/0002-SparklyPaper-config-files.patch
@@ -0,0 +1,294 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: MrPowerGamerBR
+Date: Sun, 22 Oct 2023 09:35:07 -0300
+Subject: [PATCH] SparklyPaper config files
+
+
+diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+index dbccbcb9b44e4efacdf53c2d161115cc20b36cff..1d1fb9eb784e52371d7a50446f4d46714875506c 100644
+--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
++++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+@@ -218,6 +218,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+ thread.start(); // Paper - start console thread after MinecraftServer.console & PaperConfig are initialized
+ io.papermc.paper.command.PaperCommands.registerCommands(this);
+ com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics();
++ // SparklyPaper start
++ try {
++ net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.init((java.io.File) options.valueOf("sparklypaper-settings"));
++ } catch (Exception e) {
++ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
++ return false;
++ }
++ net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this);
++ // SparklyPaper end
+ com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
+ io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
+ // Paper end
+diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
+index ea8a0961190e9aafda4fed6fecd85097c141040a..aa9c56fb95d5e438e85aced984631493b84c8556 100644
+--- a/src/main/java/net/minecraft/world/level/Level.java
++++ b/src/main/java/net/minecraft/world/level/Level.java
+@@ -176,6 +176,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ // Paper end
+
+ public final com.destroystokyo.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
++ public net.sparklypower.sparklypaper.configs.SparklyPaperWorldConfig sparklyPaperConfig; // SparklyPaper
+ public final co.aikar.timings.WorldTimingsHandler timings; // Paper
+ public static BlockPos lastPhysicsProblem; // Spigot
+ private org.spigotmc.TickLimiter entityLimiter;
+@@ -213,6 +214,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor
+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
+ this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper
++ this.sparklyPaperConfig = net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.getWorldSettings(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // SparklyPaper
+ this.generator = gen;
+ this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env);
+
+diff --git a/src/main/java/net/sparklypower/sparklypaper/commands/SparklyPaperCommand.java b/src/main/java/net/sparklypower/sparklypaper/commands/SparklyPaperCommand.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..bc0ec96f91f7c9ab9f9a865a50f69707fab8fd27
+--- /dev/null
++++ b/src/main/java/net/sparklypower/sparklypaper/commands/SparklyPaperCommand.java
+@@ -0,0 +1,65 @@
++package net.sparklypower.sparklypaper.commands;
++
++import net.minecraft.server.MinecraftServer;
++import net.minecraft.server.level.ServerLevel;
++import net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils;
++import org.bukkit.ChatColor;
++import org.bukkit.Location;
++import org.bukkit.command.Command;
++import org.bukkit.command.CommandSender;
++
++import java.io.File;
++import java.util.Collections;
++import java.util.List;
++import java.util.stream.Collectors;
++import java.util.stream.Stream;
++
++public class SparklyPaperCommand extends Command {
++ public SparklyPaperCommand(String name) {
++ super(name);
++ this.description = "SparklyPaper related commands";
++ this.usageMessage = "/sparklypaper [reload | version]";
++ this.setPermission("bukkit.command.sparklypaper");
++ }
++
++ @Override
++ public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
++ if (args.length == 1) {
++ return Stream.of("reload", "version")
++ .filter(arg -> arg.startsWith(args[0].toLowerCase()))
++ .collect(Collectors.toList());
++ }
++ return Collections.emptyList();
++ }
++
++ @Override
++ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
++ if (!testPermission(sender)) return true;
++
++ if (args.length != 1) {
++ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
++ return false;
++ }
++
++ if (args[0].equalsIgnoreCase("reload")) {
++ Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
++ Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
++
++ MinecraftServer console = MinecraftServer.getServer();
++ SparklyPaperConfigUtils.INSTANCE.init((File) console.options.valueOf("sparklypaper-settings"));
++ for (ServerLevel level : console.getAllLevels()) {
++ level.sparklyPaperConfig = SparklyPaperConfigUtils.INSTANCE.getWorldSettings(level.serverLevelData.getLevelName());
++ }
++ console.server.reloadCount++;
++
++ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "SparklyPaper config reload complete.");
++ } else if (args[0].equalsIgnoreCase("version")) {
++ Command verCmd = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
++ if (verCmd != null) {
++ return verCmd.execute(sender, commandLabel, new String[0]);
++ }
++ }
++
++ return true;
++ }
++}
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+index 38460bef2c55264b145c3e21b314eeb88b812d41..b2262f35ed18a59b6496d686a7ec9eca1e30e554 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+@@ -117,6 +117,7 @@ import net.minecraft.world.level.storage.WorldData;
+ import net.minecraft.world.level.storage.loot.LootDataManager;
+ import net.minecraft.world.level.validation.ContentValidationException;
+ import net.minecraft.world.phys.Vec3;
++import net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils;
+ import org.bukkit.BanList;
+ import org.bukkit.Bukkit;
+ import org.bukkit.ChatColor;
+@@ -1039,6 +1040,7 @@ public final class CraftServer implements Server {
+
+ org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
+ this.console.paperConfigurations.reloadConfigs(this.console);
++ net.sparklypower.sparklypaper.configs.SparklyPaperConfigUtils.INSTANCE.init((File) console.options.valueOf("sparklypaper-settings")); // SparklyPaper
+ for (ServerLevel world : this.console.getAllLevels()) {
+ // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
+ world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean))
+@@ -1054,6 +1056,7 @@ public final class CraftServer implements Server {
+ }
+ }
+ world.spigotConfig.init(); // Spigot
++ world.sparklyPaperConfig = SparklyPaperConfigUtils.INSTANCE.getWorldSettings(world.serverLevelData.getLevelName()); // SparklyPaper
+ }
+
+ Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
+@@ -1069,6 +1072,7 @@ public final class CraftServer implements Server {
+ this.reloadData();
+ org.spigotmc.SpigotConfig.registerCommands(); // Spigot
+ io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
++ net.sparklypower.sparklypaper.SparklyPaperCommands.INSTANCE.registerCommands(this.console); // SparklyPaper
+ this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
+ this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
+index e4cacb17f56c618bef19e1165c07aac86af61150..86e351daf1bcf33d0a26fd58b930a55a9a3b0ea8 100644
+--- a/src/main/java/org/bukkit/craftbukkit/Main.java
++++ b/src/main/java/org/bukkit/craftbukkit/Main.java
+@@ -173,6 +173,14 @@ public class Main {
+ .describedAs("Jar file");
+ // Paper end
+
++ // SparklyPaper Start
++ acceptsAll(asList("sparklypaper", "sparklypaper-settings"), "File for SparklyPaper settings")
++ .withRequiredArg()
++ .ofType(File.class)
++ .defaultsTo(new File("sparklypaper.yml"))
++ .describedAs("Yml file");
++ // SparklyPaper end
++
+ // Paper start
+ acceptsAll(asList("server-name"), "Name of the server")
+ .withRequiredArg()
+diff --git a/src/main/kotlin/net/sparklypower/sparklypaper/SparklyPaperCommands.kt b/src/main/kotlin/net/sparklypower/sparklypaper/SparklyPaperCommands.kt
+new file mode 100644
+index 0000000000000000000000000000000000000000..614e64ce6bf5bb7fab5758250927a0d3949d0917
+--- /dev/null
++++ b/src/main/kotlin/net/sparklypower/sparklypaper/SparklyPaperCommands.kt
+@@ -0,0 +1,22 @@
++package net.sparklypower.sparklypaper
++
++import net.minecraft.server.MinecraftServer
++import net.sparklypower.sparklypaper.commands.SparklyPaperCommand
++import org.bukkit.command.Command
++import org.checkerframework.checker.nullness.qual.NonNull
++import org.checkerframework.framework.qual.DefaultQualifier
++
++@DefaultQualifier(NonNull::class)
++object SparklyPaperCommands {
++ private val COMMANDS = mapOf(
++ "sparklypaper" to SparklyPaperCommand("sparklypaper")
++ )
++
++ fun registerCommands(server: MinecraftServer) {
++ COMMANDS.forEach { (s: String, command: Command) ->
++ server.server.commandMap.register(
++ s, "SparklyPaper", command
++ )
++ }
++ }
++}
+\ No newline at end of file
+diff --git a/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperConfig.kt b/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperConfig.kt
+new file mode 100644
+index 0000000000000000000000000000000000000000..1965b785204edcb8199bfe8b7ab1c86892c848c0
+--- /dev/null
++++ b/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperConfig.kt
+@@ -0,0 +1,10 @@
++package net.sparklypower.sparklypaper.configs
++
++import kotlinx.serialization.SerialName
++import kotlinx.serialization.Serializable
++
++@Serializable
++class SparklyPaperConfig(
++ @SerialName("world-settings")
++ val worldSettings: Map
++)
+\ No newline at end of file
+diff --git a/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperConfigUtils.kt b/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperConfigUtils.kt
+new file mode 100644
+index 0000000000000000000000000000000000000000..82a29b23429e31d78e09fa23e8c87cec76ba63bd
+--- /dev/null
++++ b/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperConfigUtils.kt
+@@ -0,0 +1,46 @@
++package net.sparklypower.sparklypaper.configs
++
++import com.charleskorn.kaml.Yaml
++import com.google.common.base.Throwables
++import kotlinx.serialization.SerializationException
++import kotlinx.serialization.decodeFromString
++import kotlinx.serialization.encodeToString
++import org.bukkit.Bukkit
++import java.io.File
++import java.util.logging.Level
++
++object SparklyPaperConfigUtils {
++ val yaml = Yaml()
++ lateinit var config: SparklyPaperConfig
++
++ fun init(configFile: File) {
++ // Write default config if the file doesn't exist
++ if (!configFile.exists()) {
++ configFile.writeText(
++ yaml.encodeToString(
++ SparklyPaperConfig(
++ mapOf(
++ "default" to SparklyPaperWorldConfig(
++ SparklyPaperWorldConfig.TickRates(
++ farmWhenMoisturised = 1
++ )
++ )
++ )
++ )
++ )
++ )
++ }
++
++ val loadedConfig = try {
++ yaml.decodeFromString(configFile.readText())
++ } catch (e: SerializationException) {
++ Bukkit.getLogger().log(Level.SEVERE, "Could not load sparklypaper.yml, please correct your syntax errors", e)
++ throw Throwables.propagate(e)
++ }
++ config = loadedConfig
++ }
++
++ fun getWorldSettings(levelName: String): SparklyPaperWorldConfig {
++ return config.worldSettings[levelName] ?: config.worldSettings["default"] ?: error("Missing default world-settings in sparklypaper.yml!")
++ }
++}
+\ No newline at end of file
+diff --git a/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperWorldConfig.kt b/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperWorldConfig.kt
+new file mode 100644
+index 0000000000000000000000000000000000000000..190954d4533e53247f9a4af878a08ce96eee2ebd
+--- /dev/null
++++ b/src/main/kotlin/net/sparklypower/sparklypaper/configs/SparklyPaperWorldConfig.kt
+@@ -0,0 +1,16 @@
++package net.sparklypower.sparklypaper.configs
++
++import kotlinx.serialization.SerialName
++import kotlinx.serialization.Serializable
++
++@Serializable
++class SparklyPaperWorldConfig(
++ @SerialName("tick-rates")
++ val tickRates: TickRates
++) {
++ @Serializable
++ data class TickRates(
++ @SerialName("farm-when-moisturised")
++ val farmWhenMoisturised: Int
++ )
++}
+\ No newline at end of file
diff --git a/patches/server/0003-Configurable-Farm-Land-moisture-tick-rate-when-the-b.patch b/patches/server/0003-Configurable-Farm-Land-moisture-tick-rate-when-the-b.patch
new file mode 100644
index 0000000..c99afc9
--- /dev/null
+++ b/patches/server/0003-Configurable-Farm-Land-moisture-tick-rate-when-the-b.patch
@@ -0,0 +1,20 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: MrPowerGamerBR
+Date: Sun, 22 Oct 2023 10:47:22 -0300
+Subject: [PATCH] Configurable Farm Land moisture tick rate when the block is
+ already moisturised
+
+The isNearWater check is costly, especially if you have a lot of farm lands. If the block is already moistured, we can change the tick rate of it to avoid these expensive isNearWater checks
+
+diff --git a/src/main/java/net/minecraft/world/level/block/FarmBlock.java b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
+index 5946f06f63b5694034bd027984a4925b0831d439..590a573a9b5099d3062031dc54978993cdd912ad 100644
+--- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java
+@@ -85,6 +85,7 @@ public class FarmBlock extends Block {
+ @Override
+ public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
+ int i = (Integer) state.getValue(FarmBlock.MOISTURE);
++ if (i > 0 && world.sparklyPaperConfig.getTickRates().getFarmWhenMoisturised() != 1 && (world.sparklyPaperConfig.getTickRates().getFarmWhenMoisturised() < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.sparklyPaperConfig.getTickRates().getFarmWhenMoisturised() != 0)) { return; } // SparklyPaper
+
+ if (!FarmBlock.isNearWater(world, pos) && !world.isRainingAt(pos.above())) {
+ if (i > 0) {
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..37d6034
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,14 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ maven("https://repo.papermc.io/repository/maven-public/")
+ }
+}
+
+plugins {
+ id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
+}
+
+rootProject.name = "SparklyPaper"
+
+include("sparklypaper-api", "sparklypaper-server")
diff --git a/sparklypaper.png b/sparklypaper.png
new file mode 100644
index 0000000..b3edf82
Binary files /dev/null and b/sparklypaper.png differ