().configureEach {
"https://logging.apache.org/log4j/2.x/javadoc/log4j-api/",
"https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3",
)
- options.tags("apiNote:a:API Note:")
+ options.tags(customJavadocTags.map { it.toOptionString() })
inputs.files(apiAndDocs).ignoreEmptyDirectories().withPropertyName(apiAndDocs.name + "-configuration")
val apiAndDocsElements = apiAndDocs.elements
diff --git a/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java b/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java
index 65e36495bd..98d6967f61 100644
--- a/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java
+++ b/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java
@@ -3,17 +3,15 @@ package io.papermc.paper;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.world.damagesource.CombatEntry;
import io.papermc.paper.world.damagesource.FallLocationType;
+import java.util.function.Predicate;
import net.kyori.adventure.util.Services;
import org.bukkit.block.Biome;
import org.bukkit.damage.DamageEffect;
import org.bukkit.damage.DamageSource;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.ApiStatus;
-import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
-import java.util.function.Predicate;
-
/**
* Static bridge to the server internals.
*
@@ -21,7 +19,6 @@ import java.util.function.Predicate;
* cause issues when called under unexpected circumstances.
*/
@ApiStatus.Internal
-@NullMarked
public interface InternalAPIBridge {
/**
@@ -31,6 +28,7 @@ public interface InternalAPIBridge {
*/
static InternalAPIBridge get() {
class Holder {
+
public static final InternalAPIBridge INSTANCE = Services.service(InternalAPIBridge.class).orElseThrow();
}
@@ -49,30 +47,31 @@ public interface InternalAPIBridge {
* Constructs the legacy custom biome instance for the biome enum.
*
* @return the created biome.
+ * @deprecated for removal, legacy custom biome constant isn't supported
*/
@Deprecated(forRemoval = true, since = "1.21.5")
@ApiStatus.ScheduledForRemoval(inVersion = "1.22")
Biome constructLegacyCustomBiome();
-
+
/**
* Creates a new combat entry.
*
* The fall location and fall distance will be calculated from the entity's current state.
*
- * @param entity entity
+ * @param entity entity
* @param damageSource damage source
- * @param damage damage amount
+ * @param damage damage amount
* @return new combat entry
*/
CombatEntry createCombatEntry(LivingEntity entity, DamageSource damageSource, float damage);
/**
- * Creates a new combat entry
+ * Creates a new combat entry.
*
- * @param damageSource damage source
- * @param damage damage amount
+ * @param damageSource damage source
+ * @param damage damage amount
* @param fallLocationType fall location type
- * @param fallDistance fall distance
+ * @param fallDistance fall distance
* @return combat entry
*/
CombatEntry createCombatEntry(DamageSource damageSource, float damage, @Nullable FallLocationType fallLocationType, float fallDistance);
@@ -87,4 +86,3 @@ public interface InternalAPIBridge {
*/
Predicate restricted(Predicate predicate);
}
-
diff --git a/paper-api/src/main/java/io/papermc/paper/ServerBuildInfo.java b/paper-api/src/main/java/io/papermc/paper/ServerBuildInfo.java
index 652ff54e7c..807fc00446 100644
--- a/paper-api/src/main/java/io/papermc/paper/ServerBuildInfo.java
+++ b/paper-api/src/main/java/io/papermc/paper/ServerBuildInfo.java
@@ -6,12 +6,10 @@ import java.util.OptionalInt;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.util.Services;
import org.jetbrains.annotations.ApiStatus;
-import org.jspecify.annotations.NullMarked;
/**
* Information about the current server build.
*/
-@NullMarked
@ApiStatus.NonExtendable
public interface ServerBuildInfo {
/**
@@ -30,6 +28,7 @@ public interface ServerBuildInfo {
static final Optional INSTANCE = Services.service(ServerBuildInfo.class);
}
//
+
return Holder.INSTANCE.orElseThrow();
}
@@ -47,7 +46,7 @@ public interface ServerBuildInfo {
* @return {@code true} if the server supports the specified brand
*/
@ApiStatus.Experimental
- boolean isBrandCompatible(final Key brandId);
+ boolean isBrandCompatible(Key brandId);
/**
* Gets the brand name of the server.
@@ -104,7 +103,7 @@ public interface ServerBuildInfo {
* @param representation the type of representation
* @return a string
*/
- String asString(final StringRepresentation representation);
+ String asString(StringRepresentation representation);
/**
* String representation types.
diff --git a/paper-api/src/main/java/io/papermc/paper/package-info.java b/paper-api/src/main/java/io/papermc/paper/package-info.java
new file mode 100644
index 0000000000..c374169c56
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Root package for the Paper API.
+ */
+@NullMarked
+package io.papermc.paper;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/paper-checkstyle/.checkstyle/checkstyle.xml b/paper-checkstyle/.checkstyle/checkstyle.xml
new file mode 100644
index 0000000000..8a1e4fce56
--- /dev/null
+++ b/paper-checkstyle/.checkstyle/checkstyle.xml
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/paper-checkstyle/build.gradle.kts b/paper-checkstyle/build.gradle.kts
new file mode 100644
index 0000000000..a61e0fe3b0
--- /dev/null
+++ b/paper-checkstyle/build.gradle.kts
@@ -0,0 +1,8 @@
+plugins {
+ java
+}
+
+dependencies {
+ implementation("com.puppycrawl.tools:checkstyle:10.26.1")
+ implementation("org.jspecify:jspecify:1.0.0")
+}
diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/Util.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/Util.java
new file mode 100644
index 0000000000..af4ec85029
--- /dev/null
+++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/Util.java
@@ -0,0 +1,129 @@
+package io.papermc.checkstyle;
+
+import com.puppycrawl.tools.checkstyle.JavaParser;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.DetailNode;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.JavadocUtil;
+import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.function.Predicate;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Utility class containing utility methods for custom checkstyle checks.
+ */
+public final class Util {
+
+ private Util() {
+ }
+
+ /**
+ * Gets the previous sibling of the given node with the given type.
+ *
+ * @param node the node
+ * @param type the type
+ * @return the previous sibling with the given type, or {@code null} if not found
+ */
+ public static @Nullable DetailNode getPreviousSibling(final DetailNode node, final int type) {
+ DetailNode sibling = JavadocUtil.getPreviousSibling(node);
+ while (sibling != null && sibling.getType() != type) {
+ sibling = JavadocUtil.getPreviousSibling(sibling);
+ }
+ return sibling;
+ }
+
+ /**
+ * Gets the next sibling of the given node with the given type.
+ *
+ * @param node the node
+ * @param type the type
+ * @return the next sibling with the given type, or {@code null} if not found
+ */
+ public static @Nullable DetailAST getNextSibling(final DetailAST node, final int type) {
+ DetailAST sibling = node.getNextSibling();
+ while (sibling != null && sibling.getType() != type) {
+ sibling = sibling.getNextSibling();
+ }
+ return sibling;
+ }
+
+ /**
+ * Gets the enclosing type declaration of the given node.
+ *
+ * @param node the node
+ * @return the enclosing type declaration, or {@code null} if not found
+ */
+ public static @Nullable DetailAST getEnclosingTypeDeclaration(final DetailAST node) {
+ DetailAST parent = node.getParent();
+ while (parent != null && !TokenUtil.isTypeDeclaration(parent.getType())) {
+ parent = parent.getParent();
+ }
+ return parent;
+ }
+
+ /**
+ * Gets an iterator over the children of the given node with the given type.
+ *
+ * @param ast the node
+ * @param type the type
+ * @return the iterator
+ */
+ public static Iterable childrenIterator(final DetailAST ast, final int type) {
+ return () -> new Iterator<>() {
+ private @Nullable DetailAST current = TokenUtil.findFirstTokenByPredicate(ast, child -> child.getType() == type).orElse(null);
+
+ @Override
+ public boolean hasNext() {
+ return this.current != null;
+ }
+
+ @Override
+ public DetailAST next() {
+ if (this.current == null) {
+ throw new NoSuchElementException();
+ }
+ final DetailAST result = this.current;
+ this.current = getNextSibling(this.current, type);
+ return result;
+ }
+ };
+ }
+
+ public static @Nullable DetailAST findPackageInfoFor(final Path filePath) {
+ final Path packageInfo = filePath.getParent().resolve("package-info.java");
+ if (Files.notExists(packageInfo)) {
+ return null;
+ }
+ final DetailAST packageInfoAst;
+ try {
+ packageInfoAst = JavaParser.parseFile(packageInfo.toFile(), JavaParser.Options.WITHOUT_COMMENTS);
+ } catch (final IOException | CheckstyleException e) {
+ throw new RuntimeException(e);
+ }
+ return packageInfoAst;
+ }
+
+ public static boolean isPackageInfoAnnotated(final Path filePath, final Predicate annotationPredicate) {
+ final DetailAST packageInfoAst = Util.findPackageInfoFor(filePath);
+ if (packageInfoAst == null) {
+ return false;
+ }
+ final DetailAST firstToken = packageInfoAst.findFirstToken(TokenTypes.PACKAGE_DEF);
+ if (firstToken == null) {
+ return false;
+ }
+ final DetailAST annotations = firstToken.findFirstToken(TokenTypes.ANNOTATIONS);
+ for (final DetailAST annotation : Util.childrenIterator(annotations, TokenTypes.ANNOTATION)) {
+ if (annotationPredicate.test(annotation)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/JavadocAlignParameterDescriptionCheck.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/JavadocAlignParameterDescriptionCheck.java
new file mode 100644
index 0000000000..e5f8efdff9
--- /dev/null
+++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/JavadocAlignParameterDescriptionCheck.java
@@ -0,0 +1,49 @@
+package io.papermc.checkstyle.checks;
+
+import com.puppycrawl.tools.checkstyle.api.DetailNode;
+import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
+import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
+import com.puppycrawl.tools.checkstyle.utils.JavadocUtil;
+import io.papermc.checkstyle.Util;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Checks that parameter descriptions in Javadoc are aligned.
+ */
+public final class JavadocAlignParameterDescriptionCheck extends AbstractJavadocCheck {
+
+ @Override
+ public int[] getDefaultJavadocTokens() {
+ return new int[]{JavadocTokenTypes.JAVADOC};
+ }
+
+ @Override
+ public void visitJavadocToken(final DetailNode detailNode) {
+ final List params = new ArrayList<>();
+ int maxColumn = -1;
+ for (final DetailNode child : detailNode.getChildren()) {
+ final DetailNode paramLiteralNode = JavadocUtil.findFirstToken(child, JavadocTokenTypes.PARAM_LITERAL);
+ if (child.getType() != JavadocTokenTypes.JAVADOC_TAG || paramLiteralNode == null) {
+ continue;
+ }
+ final DetailNode paramDescription = JavadocUtil.getNextSibling(paramLiteralNode, JavadocTokenTypes.DESCRIPTION);
+ maxColumn = Math.max(maxColumn, paramDescription.getColumnNumber());
+ params.add(paramDescription);
+ }
+
+ for (final DetailNode param : params) {
+ if (param.getColumnNumber() != maxColumn) {
+ final DetailNode paramNameNode = Util.getPreviousSibling(param, JavadocTokenTypes.PARAMETER_NAME);
+ if (paramNameNode == null) {
+ continue;
+ }
+ this.log(
+ param.getLineNumber(),
+ param.getColumnNumber() - 1,
+ "Param description for %s should start at column %d".formatted(paramNameNode.getText(), maxColumn)
+ );
+ }
+ }
+ }
+}
diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/NullabilityAnnotationsCheck.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/NullabilityAnnotationsCheck.java
new file mode 100644
index 0000000000..f1d8ea28a8
--- /dev/null
+++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/NullabilityAnnotationsCheck.java
@@ -0,0 +1,116 @@
+package io.papermc.checkstyle.checks;
+
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import io.papermc.checkstyle.Util;
+import java.nio.file.Path;
+import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Checks that nullability annotations are present where required.
+ */
+public final class NullabilityAnnotationsCheck extends AbstractCheck {
+
+ private static final Set NULLABILITY_ANNOTATIONS = Set.of("Nullable", "NonNull");
+
+ @Override
+ public int[] getDefaultTokens() {
+ return this.getRequiredTokens();
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return this.getRequiredTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return new int[]{
+ TokenTypes.METHOD_DEF,
+ TokenTypes.PARAMETER_DEF,
+ TokenTypes.ANNOTATION_FIELD_DEF,
+ TokenTypes.RECORD_COMPONENT_DEF, // annotations are in ANNOTATIONS token block
+ };
+ }
+
+
+ private static boolean hasNoNullabilityAnnotationChildren(final @Nullable DetailAST ast) {
+ if (ast == null) {
+ return true;
+ }
+ for (final DetailAST annotation : Util.childrenIterator(ast, TokenTypes.ANNOTATION)) {
+ if (annotation.getChildCount(TokenTypes.IDENT) != 1) {
+ // skip `.` annotations like ApiStatus.Internal as these aren't nullability annotations
+ continue;
+ }
+ final String ident = annotation.findFirstToken(TokenTypes.IDENT).getText();
+ if (NULLABILITY_ANNOTATIONS.contains(ident)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void visitMethodDefOrParamDef(final DetailAST holderDef, final int baseAnnotationHolderType) {
+ final DetailAST type = holderDef.findFirstToken(TokenTypes.TYPE);
+ final DetailAST arrayTypeStart = type.findFirstToken(TokenTypes.ARRAY_DECLARATOR);
+ if (arrayTypeStart != null) {
+ final DetailAST arrayAnnotations = type.findFirstToken(TokenTypes.ANNOTATIONS);
+ if (hasNoNullabilityAnnotationChildren(arrayAnnotations)) {
+ this.log(arrayTypeStart.getLineNo(), arrayTypeStart.getColumnNo() - 1, "Array is missing nullability annotation");
+ }
+ }
+ final DetailAST dot = type.findFirstToken(TokenTypes.DOT);
+ final DetailAST annotationHolder;
+ final DetailAST identLoc;
+ if (dot != null) {
+ annotationHolder = dot.findFirstToken(TokenTypes.ANNOTATIONS);
+ identLoc = dot.findFirstToken(TokenTypes.IDENT);
+ } else {
+ annotationHolder = holderDef.findFirstToken(baseAnnotationHolderType);
+ identLoc = type;
+ }
+ if (hasNoNullabilityAnnotationChildren(annotationHolder)) {
+ this.log(identLoc.getLineNo(), identLoc.getColumnNo() - 1, "Missing nullability annotation for '" + holderDef.findFirstToken(TokenTypes.IDENT).getText() + "'");
+ }
+ }
+
+ public static boolean isNullMarkedAnnotation(final DetailAST annotation) {
+ if (annotation.getChildCount(TokenTypes.IDENT) != 1) {
+ return false;
+ }
+ final String ident = annotation.findFirstToken(TokenTypes.IDENT).getText();
+ return "NullMarked".equals(ident);
+ }
+
+ public static @Nullable DetailAST getNullMarkedAnnotation(final DetailAST typeDeclaration) {
+ final DetailAST modifiers = typeDeclaration.findFirstToken(TokenTypes.MODIFIERS);
+ if (modifiers == null) {
+ return null;
+ }
+ for (final DetailAST annotation : Util.childrenIterator(modifiers, TokenTypes.ANNOTATION)) {
+ if (isNullMarkedAnnotation(annotation)) {
+ return annotation;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void visitToken(final DetailAST ast) {
+ if (Util.isPackageInfoAnnotated(Path.of(this.getFilePath()), NullabilityAnnotationsCheck::isNullMarkedAnnotation)) {
+ return;
+ }
+ for (DetailAST parentDef = Util.getEnclosingTypeDeclaration(ast); parentDef != null; parentDef = Util.getEnclosingTypeDeclaration(parentDef)) {
+ if (getNullMarkedAnnotation(parentDef) != null) {
+ return;
+ }
+ }
+ switch (ast.getType()) {
+ case TokenTypes.METHOD_DEF, TokenTypes.PARAMETER_DEF, TokenTypes.ANNOTATION_FIELD_DEF -> this.visitMethodDefOrParamDef(ast, TokenTypes.MODIFIERS);
+ case TokenTypes.RECORD_COMPONENT_DEF -> this.visitMethodDefOrParamDef(ast, TokenTypes.ANNOTATIONS);
+ }
+ }
+}
diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java
new file mode 100644
index 0000000000..1ed6c69551
--- /dev/null
+++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java
@@ -0,0 +1,40 @@
+package io.papermc.checkstyle.checks;
+
+import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
+import com.puppycrawl.tools.checkstyle.api.TokenTypes;
+import io.papermc.checkstyle.Util;
+import java.nio.file.Path;
+
+public class RedundantNullabilityCheck extends AbstractCheck {
+
+ @Override
+ public int[] getDefaultTokens() {
+ return this.getRequiredTokens();
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return this.getRequiredTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return new int[]{
+ TokenTypes.CLASS_DEF,
+ TokenTypes.INTERFACE_DEF,
+ TokenTypes.ANNOTATION_DEF,
+ TokenTypes.RECORD_DEF,
+ TokenTypes.ENUM_DEF,
+ };
+ }
+
+ @Override
+ public void visitToken(final DetailAST ast) {
+ final boolean pkgIsNullMarked = Util.isPackageInfoAnnotated(Path.of(this.getFilePath()), NullabilityAnnotationsCheck::isNullMarkedAnnotation);
+ final DetailAST nullMarkedAnnotation = NullabilityAnnotationsCheck.getNullMarkedAnnotation(ast);
+ if (pkgIsNullMarked && nullMarkedAnnotation != null) {
+ this.log(nullMarkedAnnotation.getLineNo(), ast.getColumnNo() - 1, "Redundant NullMarked annotation");
+ }
+ }
+}
diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/package-info.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/package-info.java
new file mode 100644
index 0000000000..f33ebfddfa
--- /dev/null
+++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Custom checkstyle checks for PaperMC projects.
+ */
+@NullMarked
+@SuppressWarnings("unused")
+package io.papermc.checkstyle.checks;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/package-info.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/package-info.java
new file mode 100644
index 0000000000..cea2de0c77
--- /dev/null
+++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * This package contains custom checkstyle rules for PaperMC projects.
+ */
+@NullMarked
+package io.papermc.checkstyle;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/paper-checkstyle/src/main/resources/checkstyle_packages.xml b/paper-checkstyle/src/main/resources/checkstyle_packages.xml
new file mode 100644
index 0000000000..702587110a
--- /dev/null
+++ b/paper-checkstyle/src/main/resources/checkstyle_packages.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/paper-generator/.checkstyle/checkstyle.xml b/paper-generator/.checkstyle/checkstyle.xml
new file mode 100644
index 0000000000..8a1e4fce56
--- /dev/null
+++ b/paper-generator/.checkstyle/checkstyle.xml
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 9289c95a73..947a2e0a7b 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,5 +1,6 @@
pluginManagement {
repositories {
+ mavenLocal()
gradlePluginPortal()
maven("https://repo.papermc.io/repository/maven-public/")
}
@@ -11,17 +12,17 @@ plugins {
if (!file(".git").exists()) {
val errorText = """
-
+
=====================[ ERROR ]=====================
The Paper project directory is not a properly cloned Git repository.
-
+
In order to build Paper from source you must clone
the Paper repository using Git, not download a code
zip from GitHub.
-
+
Built Paper jars are available for download at
https://papermc.io/downloads/paper
-
+
See https://github.com/PaperMC/Paper/blob/main/CONTRIBUTING.md
for further information on building and modifying Paper.
===================================================
@@ -36,6 +37,8 @@ for (name in listOf("paper-api", "paper-server")) {
file(name).mkdirs()
}
+include("paper-checkstyle")
+
optionalInclude("test-plugin")
optionalInclude("paper-generator")