Compare commits

..
22 Commits
Author SHA1 Message Date
NotAlexNoyle bbe60a1bf4 Exclude CODEOWNERS from language statistics 2026-10-27 08:25:12 -04:00
NotAlexNoyle 06aca10e5d Add CODEOWNERS (one staff approval) 2026-10-27 08:25:12 -04:00
NotAlexNoyle 625bb0c6a9 Use live TrueOG Network config file 2026-05-27 11:22:19 -04:00
NotAlexNoyle bb8fe0f528 Fix user list on luckperms web by normalizing version number format to upstream 2026-04-24 16:01:18 -04:00
NotAlexNoyle 863d10273c Disable Vault integration 2026-04-24 15:24:29 -04:00
NotAlexNoyle a57ba166ff Merge branch 'LuckPerms:master' into master 2025-09-22 07:10:41 -04:00
蒟蒻 0b91732cd3 Prevent handleDisconnect after stopped server on Fabric (#4160) 2025-09-21 11:04:58 +01:00
An5w1r a087f14aa2 Fix classExists checks to handle NoClassDefFoundError (#4136) 2025-09-21 11:03:07 +01:00
Luck d666a2a798 Fix command rate limit for command blocks (#4094) 2025-09-21 10:58:24 +01:00
NotAlexNoyle c27cfcb10b Update shadow 2025-09-03 14:22:27 -04:00
NotAlexNoyle 52464c6bec Simplify gradle build, support java 17 2025-09-03 13:39:23 -04:00
Luck 65c42b9b09 Micro-optimize temporary node audit (#4155) 2025-08-23 15:39:49 +01:00
Luck 73d710a89e Update to Minecraft 1.21.8 2025-07-21 22:08:21 +01:00
Luck ed863b275d Update to Minecraft 1.21.7 2025-06-30 19:41:56 +01:00
Luck c20776d6aa Remove Forge capability attachment 2025-06-19 19:53:09 +01:00
Luck 3aca721f96 Rollback bytebuddy dependency version upgrade 2025-06-19 19:35:04 +01:00
Luck 8d9c5bf401 Add workaround for Forge eventbus limitation 2025-06-19 19:09:40 +01:00
Luck 0af1038d81 Update to Minecraft 1.21.6 2025-06-19 18:48:44 +01:00
Luck 51fe574a51 Move config load earlier in startup process (#4083) 2025-06-14 09:31:56 +01:00
Max Barrass bac0edd90e Fix missing closing brackets in .conf files (#4109) 2025-06-14 09:24:52 +01:00
Luck 8ab9910ef8 Downgrade jedis and h2 2025-06-01 19:32:26 +01:00
Luck 9538cb9dad Upgrade dependencies and require Java 11 2025-06-01 16:41:39 +01:00
94 changed files with 1039 additions and 3210 deletions

No files matched your search

+1
View File
@@ -3,3 +3,4 @@
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
-2
View File
@@ -1,2 +0,0 @@
github: lucko
patreon: luckdev
-63
View File
@@ -1,63 +0,0 @@
name: 🐛 ​ Bug report
description: Report an issue or problem with the way LuckPerms is functioning.
labels: ["type: issue"]
body:
- type: markdown
attributes:
value: "Before going any further, please check to see if your problem is fixed by updating to a newer version. The latest development builds can be obtained from https://luckperms.net/download"
- type: textarea
id: description
attributes:
label: Description
description: Please provide a short description of the issue in the space below.
placeholder: Description goes here!
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: Reproduction Steps
description: Please provide a clear list of steps we should follow in order to reproduce your issue in the space below.
placeholder: List reproduction steps here, please!
validations:
required: true
- type: textarea
id: expected-behaviour
attributes:
label: Expected Behaviour
description: Please provide a description of what you expected to happen.
placeholder: Describe what you expected to happen here.
validations:
required: true
- type: input
id: server-info
attributes:
label: Server Details
description: Please provide a description of the server details, including type and specific version number.
placeholder: 'git-Paper-124 (MC: 1.17.1)'
validations:
required: true
- type: input
id: luckperms-version
attributes:
label: LuckPerms Version
description: Please provide the specific, precise version number of LuckPerms you are using to reproduce this bug.
placeholder: v5.3.70
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs and Configs
description: If you think it would be helpful, please also include a pastebin of any relevant config files or log output. You should use https://gist.github.com/ to upload, then include the link below.
placeholder: https://gist.github.com/HelpfulBugReporter/ThisIsAVeryUsefulLogOutput
validations:
required: false
- type: textarea
id: extra-info
attributes:
label: Extra Details
description: Please include any other relevant details in the space below.
placeholder: I was able to reproduce this only at the end of a rainbow.
validations:
required: false
-5
View File
@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: 💬 ​ Ask a question
url: https://discord.gg/luckperms
about: We use Discord to provide support for the project. If you have a question, need help, or aren't sure if you've found a bug or not, please come and talk to us there!
-31
View File
@@ -1,31 +0,0 @@
name: 💡 ​ Suggestion
description: Suggest an idea for an improvement or change to LuckPerms.
labels: ["type: suggestion"]
body:
- type: markdown
attributes:
value: "Before going any further, please check to see if your suggestion has already been added by checking the [wiki](https://luckperms.net/wiki/Home). The latest development builds can be obtained from https://luckperms.net/download"
- type: textarea
id: description
attributes:
label: Description
description: Please provide a short description of your suggestion in the space below.
placeholder: Hello, perhaps you should...
validations:
required: true
- type: textarea
id: proposed-behaviour
attributes:
label: Proposed Behaviour
description: Please provide a short explanation of how the feature should work / be changed, and how this will affect the project.
placeholder: It would...
validations:
required: true
- type: textarea
id: extra-info
attributes:
label: Extra Details
description: Please include any other relevant details in the space below.
placeholder: I think this should only function at the end of a rainbow.
validations:
required: false
-128
View File
@@ -1,128 +0,0 @@
name: Build Gradle and Publish Docker image
on:
push:
branches:
- 'master'
tags:
- 'v*'
pull_request:
branches:
- 'master'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-gradle:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Run build and tests with Gradle wrapper
run: ./gradlew test build -PdockerTests
- name: Publish test report
uses: mikepenz/action-junit-report@v5
if: success() || failure()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
annotate_notice: true
detailed_summary: true
- name: Upload all artifacts
uses: actions/upload-artifact@v4
with:
name: jars
path: |
bukkit/loader/build/libs/LuckPerms-Bukkit-*.jar
bukkit-legacy/loader/build/libs/LuckPerms-Bukkit-Legacy-*.jar
bungee/loader/build/libs/LuckPerms-Bungee-*.jar
sponge/loader/build/libs/LuckPerms-Sponge-*.jar
nukkit/loader/build/libs/LuckPerms-Nukkit-*.jar
velocity/build/libs/LuckPerms-Velocity-*.jar
fabric/build/libs/LuckPerms-Fabric-*.jar
forge/loader/build/libs/LuckPerms-Forge-*.jar
standalone/loader/build/libs/LuckPerms-Standalone-*.jar
- name: Upload standalone artifact
uses: actions/upload-artifact@v4
with:
name: standalone-binary
path: standalone/loader/build/libs/LuckPerms-Standalone-*.jar
build-docker:
needs: build-gradle
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Retrieve saved standalone jar artifact
uses: actions/download-artifact@v4
with:
name: standalone-binary
path: standalone/docker/
- name: Remove version number from jar artifact name
run: mv standalone/docker/LuckPerms-Standalone-*.jar standalone/docker/luckperms-standalone.jar
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Determine the LuckPerms version
run: |
echo "luckperms_version=$(git describe --tags | awk -F "-" '{print $1 "." $2}')" >> "$GITHUB_ENV"
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=${{ github.ref == 'refs/heads/master' }}
tags: |
type=schedule
type=ref,event=branch
type=ref,event=tag
type=ref,event=pr
type=raw,enable=${{ github.ref == 'refs/heads/master' }},value=${{ env.luckperms_version }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: standalone/docker/
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
-26
View File
@@ -1,26 +0,0 @@
### :speech_balloon: Looking for support?
Details about support for the project can be found [here, on the Wiki Homepage](https://luckperms.net/wiki/Home#support).
### :bug: Reporting bugs?
Before reporting a bug or issue, please make sure that the issue is actually being caused by or related to LuckPerms. We get a lot of reports which are caused by other software - please double check!
If you're unsure, feel free to ask using the above resources BEFORE making a report.
Bugs or issues should be reported using the [GitHub Issues tab](https://github.com/LuckPerms/LuckPerms/issues).
### :pencil: Want to contribute code?
#### Pull Requests
If you make any changes or improvements to the plugin which you think would be beneficial to others, please consider making a pull request to merge your changes back into the upstream project. (especially if your changes are bug fixes!)
LuckPerms loosely follows the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html). Generally, try to copy the style of code found in the class you're editing.
If you're considering submitting a substantial pull request, please open an issue so we can discuss the change before starting work on the contribution. Most pull requests are happily accepted, but larger changes may have an impact on the maintainability of the project, and require more consideration.
#### Project Layout
The project is split up into a few separate modules.
* **API** - The public, semantically versioned API used by other plugins wishing to integrate with and retrieve data from LuckPerms. This module (for the most part) does not contain any implementation itself, and is provided by the plugin.
* **Common** - The common module contains most of the code which implements the respective LuckPerms plugins. This abstract module reduces duplicated code throughout the project.
* **Bukkit, BungeeCord, Fabric, Forge, Nukkit, Sponge & Velocity** - Each use the common module to implement plugins on the respective server platforms.
-106
View File
@@ -1,106 +0,0 @@
group = 'net.luckperms'
project.version = '5.5'
jar {
manifest {
attributes('Automatic-Module-Name': 'net.luckperms.api')
}
}
dependencies {
compileOnly 'org.checkerframework:checker-qual:3.49.3'
compileOnly 'org.jetbrains:annotations:26.0.2'
}
// Only used occasionally for deployment - not needed for normal builds.
/*
if (project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword')) {
apply plugin: 'signing'
javadoc {
title = 'LuckPerms API (v' + project.ext.apiVersion + ')'
options.overview = 'javadoc/overview.html'
options.encoding = 'UTF-8'
options.charSet = 'UTF-8'
options.links(
'https://checkerframework.org/api/',
'https://javadoc.io/static/org.jetbrains/annotations/26.0.2/'
)
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('-since', '5.0,5.1,5.2,5.3,5.4,5.5')
if (JavaVersion.current() > JavaVersion.VERSION_1_8) {
options.links.add('https://docs.oracle.com/en/java/javase/21/docs/api/')
} else {
options.links.add('https://docs.oracle.com/javase/8/docs/api/')
}
}
java {
withJavadocJar()
withSourcesJar()
}
publishing {
repositories {
maven {
def releasesRepoUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
def snapshotsRepoUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username sonatypeUsername
password sonatypePassword
}
}
}
publications {
mavenJava(MavenPublication) {
artifactId = 'api'
from components.java
pom {
name = 'LuckPerms API'
description = 'A permissions manager for Minecraft servers.'
url = 'https://luckperms.net'
licenses {
license {
name = 'MIT'
url = 'https://opensource.org/licenses/MIT'
}
}
developers {
developer {
id = 'lucko'
name = 'Luck'
url = 'https://lucko.me'
email = 'git@lucko.me'
}
}
scm {
connection = 'scm:git:https://github.com/LuckPerms/LuckPerms.git'
developerConnection = 'scm:git:git@github.com:LuckPerms/LuckPerms.git'
url = 'https://github.com/LuckPerms/LuckPerms'
}
issueManagement {
system = 'GitHub'
url = 'https://github.com/LuckPerms/LuckPerms/issues'
}
}
}
}
}
signing {
useGpgCmd()
sign publishing.publications.mavenJava
required = true
}
}
*/
-83
View File
@@ -1,83 +0,0 @@
plugins {
alias(libs.plugins.licenser) apply false
}
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
defaultTasks 'licenseFormat', 'build'
subprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'org.cadixdev.licenser'
group = 'me.lucko.luckperms'
version = '5.5-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
tasks.withType(Test).configureEach {
testLogging {
events = [TestLogEvent.PASSED, TestLogEvent.FAILED, TestLogEvent.SKIPPED]
exceptionFormat = TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
}
}
jar {
from '../LICENSE.txt'
}
def determinePatchVersion = {
// get the name of the last tag
def tagInfo = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = tagInfo
}
tagInfo = tagInfo.toString()
if (!tagInfo.contains('-')) {
return 0
}
return tagInfo.split("-")[1]
}
project.ext.majorVersion = '5'
project.ext.minorVersion = '5'
project.ext.patchVersion = determinePatchVersion()
project.ext.apiVersion = project.ext.majorVersion + '.' + project.ext.minorVersion
project.ext.fullVersion = project.ext.apiVersion + '.' + project.ext.patchVersion
license {
header = rootProject.file('HEADER.txt')
include '**/*.java'
newLine = true
}
repositories {
// Fix issue with lwjgl-freetype not being found on macOS / ForgeGradle issue
//
// Could not resolve all files for configuration ':_compileJava_1'.
// Could not find lwjgl-freetype-3.3.3-natives-macos-patch.jar (org.lwjgl:lwjgl-freetype:3.3.3).
maven {
url "https://libraries.minecraft.net"
content {
includeModule("org.lwjgl", "lwjgl-freetype")
}
}
mavenCentral()
maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'https://repo.lucko.me/' }
maven { url 'https://libraries.minecraft.net/' }
}
}
+348
View File
@@ -0,0 +1,348 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.kotlin.dsl.provideDelegate
/* ------------------------------ Plugins ------------------------------ */
plugins {
id("java") // Import Java plugin.
id("java-library") // Import Java Library plugin.
id("com.diffplug.spotless") version "7.0.4" // Import Spotless plugin.
id("com.gradleup.shadow") version "8.3.8" // Import Shadow plugin.
id("checkstyle") // Import Checkstyle plugin.
eclipse // Import Eclipse plugin.
kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin.
}
extra["kotlinAttribute"] = Attribute.of("kotlin-tag", Boolean::class.javaObjectType)
val kotlinAttribute: Attribute<Boolean> by rootProject.extra
/* --------------------------- JDK / Kotlin ---------------------------- */
java {
sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility.
toolchain { // Select Java toolchain.
languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17.
vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE.
}
}
kotlin { jvmToolchain(17) }
/* ----------------------------- Metadata ------------------------------ */
group = "me.lucko.luckperms" // Declare bundle identifier.
version = "5.5.0-SNAPSHOT" // Declare plugin version (will be in .jar).
val apiVersion = "1.19" // Declare minecraft server target version.
/* ----------------------------- Resources ----------------------------- */
tasks.named<ProcessResources>("processResources") {
val props = mapOf("version" to version, "apiVersion" to apiVersion)
inputs.properties(props) // Indicates to rerun if version changes.
filesMatching("plugin.yml") { expand(props) }
from("LICENSE") { into("/") } // Bundle licenses into jarfiles.
}
/* ---------------------------- Repos ---------------------------------- */
repositories {
// Fix issue with lwjgl-freetype not being found on macOS / ForgeGradle issue
maven("https://libraries.minecraft.net") { content { includeModule("org.lwjgl", "lwjgl-freetype") } }
mavenCentral()
maven { url = uri("https://repo.lucko.me/") }
maven { url = uri("https://libraries.minecraft.net/") }
maven { url = uri("https://repo.papermc.io/repository/maven-public/") }
maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") }
System.getProperty("SELF_MAVEN_LOCAL_REPO")?.let {
val dir = file(it)
if (dir.isDirectory) {
println("Using SELF_MAVEN_LOCAL_REPO at: $it")
maven { url = uri("file://${dir.absolutePath}") }
} else {
mavenLocal()
}
}
}
/* ---------------------- Java project deps ---------------------------- */
dependencies {
// Root project carries no direct compile deps; subprojects declare their own.
}
/* ---------------------- Reproducible jars ---------------------------- */
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
/* ----------------------------- Shadow -------------------------------- */
tasks.shadowJar {
archiveClassifier.set("") // Use empty string instead of null.
minimize()
}
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
tasks.build { dependsOn(tasks.spotlessApply) } // Build depends on spotless and shadow.
/* --------------------------- Javac opts ------------------------------- */
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters") // Enable reflection for java code.
options.isFork = true // Run javac in its own process.
options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages.
options.encoding = "UTF-8" // Use UTF-8 file encoding.
}
/* ----------------------------- Auto Formatting ------------------------ */
spotless {
java {
eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting.
leadingTabsToSpaces() // Convert leftover leading tabs to spaces.
removeUnusedImports() // Remove imports that aren't being called.
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting.
target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format.
}
}
checkstyle {
toolVersion = "10.18.1" // Declare checkstyle version to use.
configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file.
isIgnoreFailures = true // Don't fail the build if checkstyle does not pass.
isShowViolations = true // Show the violations in any IDE with the checkstyle plugin.
}
tasks.named("compileJava") {
dependsOn("spotlessApply") // Run spotless before compiling with the JDK.
}
tasks.named("spotlessCheck") {
dependsOn("spotlessApply") // Run spotless before checking if spotless ran.
}
/* --------------------------- LuckPerms modules ------------------------ */
subprojects {
apply(plugin = "java-library")
apply(plugin = "eclipse")
group = "me.lucko.luckperms"
version = rootProject.version
repositories {
maven("https://libraries.minecraft.net") { content { includeModule("org.lwjgl", "lwjgl-freetype") } }
mavenCentral()
maven { url = uri("https://repo.lucko.me/") }
maven { url = uri("https://libraries.minecraft.net/") }
maven { url = uri("https://repo.papermc.io/repository/maven-public/") }
maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") }
System.getProperty("SELF_MAVEN_LOCAL_REPO")?.let {
val dir = file(it)
if (dir.isDirectory) {
println("Using SELF_MAVEN_LOCAL_REPO at: $it")
maven { url = uri("file://${dir.absolutePath}") }
} else {
mavenLocal()
}
}
}
tasks.withType<Test>().configureEach {
testLogging {
events("PASSED", "FAILED", "SKIPPED")
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
}
useJUnitPlatform()
}
tasks.withType<JavaCompile>().configureEach { options.encoding = "UTF-8" }
tasks.withType<Jar>().configureEach { from(rootProject.file("LICENSE.txt")) }
}
/* :api */
project(":api") {
dependencies {
compileOnly("org.checkerframework:checker-qual:3.49.3")
compileOnly("org.jetbrains:annotations:26.0.2")
}
tasks.jar { manifest { attributes(mapOf("Automatic-Module-Name" to "net.luckperms.api")) } }
}
/* :common */
project(":common") {
apply(plugin = "jacoco")
val patchedDir = layout.buildDirectory.dir("patchedSrc/commonMain/java")
val patchCommonForJ17 =
tasks.register<Copy>("patchCommonForJ17") {
from("src/main/java")
into(patchedDir)
filteringCharset = "UTF-8"
filesMatching("**/*.java") {
filter { line ->
if (
line.contains(".reversed()") &&
!line.contains("Comparator") &&
!line.contains("comparing") &&
!line.contains("thenComparing") &&
!line.contains("INSTANCE") &&
!line.contains("normal()")
) {
line.replace(
".reversed()",
".stream().collect(java.util.stream.Collectors.collectingAndThen(" +
"java.util.stream.Collectors.toList(), l -> { java.util.Collections.reverse(l); return l; }))",
)
} else line
}
}
}
sourceSets.named("main") {
java.setSrcDirs(emptyList<Any>())
java.srcDir(patchedDir)
}
tasks.named<JavaCompile>("compileJava") { dependsOn(patchCommonForJ17) }
dependencies {
testImplementation("org.slf4j:slf4j-simple:1.7.36")
testImplementation("org.junit.jupiter:junit-jupiter:5.13.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.testcontainers:junit-jupiter:1.21.1")
testImplementation("org.mockito:mockito-core:5.18.0")
testImplementation("org.mockito:mockito-junit-jupiter:5.18.0")
testImplementation("com.h2database:h2:2.1.214")
testImplementation("org.mongodb:mongodb-driver-legacy:5.5.0")
testImplementation("org.spongepowered:configurate-yaml:3.7.3")
testImplementation("org.spongepowered:configurate-hocon:3.7.3")
testImplementation("me.lucko.configurate:configurate-toml:3.7")
testImplementation("net.luckperms:rest-api-java-client:0.1")
api(project(":api"))
api("org.checkerframework:checker-qual:3.12.0")
compileOnly(project(":common:loader-utils"))
compileOnly("com.mojang:brigadier:1.0.18")
compileOnly("org.slf4j:slf4j-api:1.7.30")
compileOnly("org.apache.logging.log4j:log4j-api:2.14.0")
api("net.kyori:adventure-api:4.21.0") {
exclude(module = "adventure-bom")
exclude(module = "checker-qual")
exclude(module = "annotations")
}
api("net.kyori:adventure-text-serializer-gson:4.21.0") {
exclude(module = "adventure-bom")
exclude(module = "adventure-api")
exclude(module = "gson")
}
api("net.kyori:adventure-text-serializer-legacy:4.21.0") {
exclude(module = "adventure-bom")
exclude(module = "adventure-api")
}
api("net.kyori:adventure-text-serializer-plain:4.21.0") {
exclude(module = "adventure-bom")
exclude(module = "adventure-api")
}
api("net.kyori:adventure-text-minimessage:4.21.0") {
exclude(module = "adventure-bom")
exclude(module = "adventure-api")
}
api("net.kyori:event-api:3.0.0") {
exclude(module = "checker-qual")
exclude(module = "guava")
}
api("com.google.code.gson:gson:2.7")
api("com.google.guava:guava:19.0")
api("com.github.ben-manes.caffeine:caffeine:3.2.0")
api("com.squareup.okhttp3:okhttp:3.14.9")
api("com.squareup.okio:okio:1.17.6")
api("net.bytebuddy:byte-buddy:1.15.11")
api("org.spongepowered:configurate-core:3.7.3") { isTransitive = false }
api("org.spongepowered:configurate-yaml:3.7.3") { isTransitive = false }
api("org.spongepowered:configurate-gson:3.7.3") { isTransitive = false }
api("org.spongepowered:configurate-hocon:3.7.3") { isTransitive = false }
api("me.lucko.configurate:configurate-toml:3.7") { isTransitive = false }
compileOnly("com.zaxxer:HikariCP:6.3.0")
compileOnly("redis.clients:jedis:5.2.0")
compileOnly("io.nats:jnats:2.21.1")
compileOnly("com.rabbitmq:amqp-client:5.25.0")
compileOnly("org.mongodb:mongodb-driver-legacy:5.5.0")
compileOnly("org.postgresql:postgresql:42.7.6")
compileOnly("org.yaml:snakeyaml:1.33")
compileOnly("net.luckperms:rest-api-java-client:0.1")
}
}
/* :common:loader-utils */
project(":common:loader-utils") {
// nothing special
}
/* :bukkit */
project(":bukkit") {
apply(plugin = "com.gradleup.shadow")
dependencies {
implementation(project(":common"))
compileOnly(project(":common:loader-utils"))
compileOnly("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT")
compileOnly("net.kyori:adventure-platform-bukkit:4.4.0") {
exclude(module = "adventure-bom")
exclude(module = "adventure-api")
exclude(module = "adventure-nbt")
}
compileOnly("me.lucko:commodore:2.0")
compileOnly("net.milkbowl.vault:VaultAPI:1.7") { exclude(module = "bukkit") }
compileOnly("lilypad.client.connect:api:0.0.1-SNAPSHOT")
}
tasks.named<ShadowJar>("shadowJar") {
archiveFileName.set("luckperms-bukkit.jarinjar")
dependencies { include(dependency("me.lucko.luckperms:.*")) }
relocate("net.kyori.adventure", "me.lucko.luckperms.lib.adventure")
relocate("net.kyori.event", "me.lucko.luckperms.lib.eventbus")
relocate("com.github.benmanes.caffeine", "me.lucko.luckperms.lib.caffeine")
relocate("okio", "me.lucko.luckperms.lib.okio")
relocate("okhttp3", "me.lucko.luckperms.lib.okhttp3")
relocate("net.bytebuddy", "me.lucko.luckperms.lib.bytebuddy")
relocate("me.lucko.commodore", "me.lucko.luckperms.lib.commodore")
relocate("org.mariadb.jdbc", "me.lucko.luckperms.lib.mariadb")
relocate("com.mysql", "me.lucko.luckperms.lib.mysql")
relocate("org.postgresql", "me.lucko.luckperms.lib.postgresql")
relocate("com.zaxxer.hikari", "me.lucko.luckperms.lib.hikari")
relocate("com.mongodb", "me.lucko.luckperms.lib.mongodb")
relocate("org.bson", "me.lucko.luckperms.lib.bson")
relocate("redis.clients.jedis", "me.lucko.luckperms.lib.jedis")
relocate("io.nats.client", "me.lucko.luckperms.lib.nats")
relocate("com.rabbitmq", "me.lucko.luckperms.lib.rabbitmq")
relocate("org.apache.commons.pool2", "me.lucko.luckperms.lib.commonspool2")
relocate("ninja.leaping.configurate", "me.lucko.luckperms.lib.configurate")
}
}
/* :bukkit:loader */
project(":bukkit:loader") {
apply(plugin = "com.gradleup.shadow")
dependencies {
compileOnly("com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT")
implementation(project(":api"))
implementation(project(":common:loader-utils"))
}
tasks.processResources {
filesMatching("plugin.yml") { expand(mapOf("pluginVersion" to rootProject.version.toString())) }
}
tasks.named<ShadowJar>("shadowJar") {
archiveFileName.set("LuckPerms-${rootProject.version}.jar")
from(project(":bukkit").tasks.named<ShadowJar>("shadowJar").flatMap { it.archiveFile })
manifest { attributes(mapOf("paperweight-mappings-namespace" to "mojang")) }
destinationDirectory.set(rootProject.layout.buildDirectory.dir("libs"))
}
}
/* Build root produces the server jar */
tasks.named("build") { dependsOn(project(":bukkit:loader").tasks.named("shadowJar")) }
-45
View File
@@ -1,45 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
dependencies {
implementation project(':bukkit')
implementation 'com.google.code.gson:gson:2.7'
implementation 'com.google.guava:guava:19.0'
}
shadowJar {
archiveFileName = 'luckperms-bukkitlegacy.jarinjar'
dependencies {
include(dependency('me.lucko.luckperms:.*'))
include(dependency('com.google.guava:guava:.*'))
include(dependency('com.google.code.gson:gson:.*'))
}
relocate 'com.google.common', 'me.lucko.luckperms.lib.guava'
relocate 'com.google.gson', 'me.lucko.luckperms.lib.gson'
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
}
artifacts {
archives shadowJar
}
-32
View File
@@ -1,32 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
dependencies {
compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT'
implementation project(':api')
implementation project(':common:loader-utils')
}
processResources {
filesMatching('plugin.yml') {
expand 'pluginVersion': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-Bukkit-Legacy-${project.ext.fullVersion}.jar"
from {
project(':bukkit-legacy').tasks.shadowJar.archiveFile
}
}
artifacts {
archives shadowJar
}
-55
View File
@@ -1,55 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
dependencies {
implementation project(':common')
compileOnly project(':common:loader-utils')
compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT'
compileOnly('net.kyori:adventure-platform-bukkit:4.4.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
exclude(module: 'adventure-nbt')
}
compileOnly 'me.lucko:commodore:2.0'
compileOnly('net.milkbowl.vault:VaultAPI:1.7') {
exclude(module: 'bukkit')
}
compileOnly 'lilypad.client.connect:api:0.0.1-SNAPSHOT'
}
shadowJar {
archiveFileName = 'luckperms-bukkit.jarinjar'
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
}
artifacts {
archives shadowJar
}
-36
View File
@@ -1,36 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
dependencies {
compileOnly 'com.destroystokyo.paper:paper-api:1.15.2-R0.1-SNAPSHOT'
implementation project(':api')
implementation project(':common:loader-utils')
}
processResources {
filesMatching('plugin.yml') {
expand 'pluginVersion': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-Bukkit-${project.ext.fullVersion}.jar"
from {
project(':bukkit').tasks.shadowJar.archiveFile
}
manifest {
attributes(["paperweight-mappings-namespace": "mojang"])
}
}
artifacts {
archives shadowJar
}
@@ -307,7 +307,7 @@ public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap, B
try {
Class.forName("com.google.gson.JsonElement");
return false;
} catch (ClassNotFoundException e) {
} catch (Exception e) {
return true;
}
}
@@ -221,10 +221,12 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
* - https://hub.spigotmc.org/jira/browse/SPIGOT-5546
* - https://github.com/PaperMC/Paper/pull/3509
*/
PluginManagerUtil.injectDependency(this.bootstrap.getServer().getPluginManager(), this.bootstrap.getLoader().getName(), "Vault");
if (getConfiguration().get(ConfigKeys.VAULT_ENABLED)) {
PluginManagerUtil.injectDependency(this.bootstrap.getServer().getPluginManager(), this.bootstrap.getLoader().getName(), "Vault");
// Provide vault support
tryVaultHook(false);
// Provide vault support
tryVaultHook(false);
}
}
@Override
@@ -237,6 +239,10 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
return; // already hooked
}
if (!getConfiguration().get(ConfigKeys.VAULT_ENABLED)) {
return; // disabled in config
}
try {
if (force || this.bootstrap.getServer().getPluginManager().isPluginEnabled("Vault")) {
this.vaultHookManager = new VaultHookManager(this);
@@ -347,7 +353,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
} catch (Exception e) {
return false;
}
}
@@ -94,6 +94,10 @@ public class BukkitPlatformListener implements Listener {
@EventHandler
public void onPluginEnable(PluginEnableEvent e) {
if (!this.plugin.getConfiguration().get(ConfigKeys.VAULT_ENABLED)) {
return;
}
Plugin p = e.getPlugin();
boolean shouldHook = p.getName().equalsIgnoreCase("Vault") ||
(PLUGIN_DESCRIPTION_FILE_PROVIDES_SUPPORTED && p.getDescription().getProvides().contains("Vault"));
+31 -20
View File
@@ -41,7 +41,7 @@ server: global
# - To get around this, you can use a player's uuid directly in the command, or enable this option.
# - When this is set to 'true', the server facility is used. This may use a number of methods,
# including checking the servers local cache, or making a request to the Mojang API.
use-server-uuid-cache: false
use-server-uuid-cache: true
@@ -83,7 +83,7 @@ use-server-uuid-cache: false
#
# - A H2 database is the default option.
# - If you want to edit data manually in "traditional" storage files, we suggest using YAML.
storage-method: h2
storage-method: postgresql
# The following block defines the settings for remote database storage methods.
#
@@ -99,11 +99,11 @@ data:
# The name of the database to store LuckPerms data in.
# - This must be created already. Don't worry about this setting if you're using MongoDB.
database: minecraft
database: luckperms
# Credentials for the database.
username: root
password: ''
username: '^{POSTGRES_USER}'
password: '^{POSTGRES_PASSWORD}'
# These settings apply to the MySQL connection pool.
# - The default values will be suitable for the majority of users.
@@ -132,11 +132,11 @@ data:
# from being timed out by the database or network infrastructure, measured in milliseconds.
# - The value should be less than maximum-lifetime and greater than 30000 (30 seconds).
# - Setting the value to zero will disable the keepalive functionality.
keepalive-time: 0
keepalive-time: 120000
# This setting controls the maximum number of milliseconds that the plugin will wait for a
# connection from the pool, before timing out.
connection-timeout: 5000 # 5 seconds
connection-timeout: 10000 # 10 seconds
# This setting allows you to define extra properties for connections.
#
@@ -216,7 +216,7 @@ sync-minutes: -1
# - When using a file-based storage type, LuckPerms can monitor the data files for changes, and
# automatically update when changes are detected.
# - If you don't want this feature to be active, set this option to false.
watch-files: true
watch-files: false
# Define which messaging service should be used by the plugin.
#
@@ -258,16 +258,16 @@ push-log-entries: true
# - If you have LuckPerms installed on your backend servers as well as a BungeeCord proxy, you
# should set this option to false on either your backends or your proxies, to avoid players being
# messaged twice about log entries.
broadcast-received-log-entries: true
broadcast-received-log-entries: false
# Settings for Redis.
# Settings for Keydb.
# Port 6379 is used by default; set address to "host:port" if differs
# Multiple Redis nodes can be specified in the same format as a string list under the name "addresses".
# Multiple Keydb nodes can be specified in the same format as a string list under the name "addresses".
redis:
enabled: false
enabled: true
address: localhost
username: ''
password: ''
username: 'default'
password: 'bookchin'
# Settings for Nats.
# Port 4222 is used by default; set address to "host:port" if differs
@@ -335,7 +335,7 @@ argument-based-command-permissions: false
# If the plugin should check whether senders are a member of a given group before they're able to
# edit the groups data or add/remove other users to/from it.
# Note: these limitations do not apply to the web editor!
require-sender-group-membership-to-modify: false
require-sender-group-membership-to-modify: true
# If the plugin should send log notifications to users whenever permissions are modified.
#
@@ -408,14 +408,14 @@ meta-formatting:
duplicates: first-only
start-spacer: ""
middle-spacer: " "
end-spacer: ""
end-spacer: " "
suffix:
format:
- "highest"
duplicates: first-only
start-spacer: ""
start-spacer: " "
middle-spacer: " "
end-spacer: ""
end-spacer: " "
@@ -627,8 +627,19 @@ commands-allow-op: true
# +----------------------------------------------------------------------------------------------+ #
# | Vault integration settings | #
# | | #
# | Disabled by default (vault-enabled: false). The remaining vault-* settings below only take | #
# | effect when vault-enabled is set to true. | #
# +----------------------------------------------------------------------------------------------+ #
# If the Vault API bridge should be registered.
#
# - When false (default), LuckPerms will not hook into Vault at all. Vault-dependent plugins will
# fall back to SuperPerms and will not see LuckPerms groups, prefixes, or meta.
# - When true, LuckPerms will register Vault permission and chat providers if the Vault plugin is
# installed. Required for any plugin that reads groups/prefix/suffix via the Vault API.
vault-enabled: false
# If Vault lookups for offline players on the main server thread should be enabled.
#
# LuckPerms has a "catch" for plugins attempting to perform unsafe offline player data lookups
@@ -730,7 +741,7 @@ resolve-command-selectors: false
#
# Note: This does not affect interactions with LuckPerms via the API.
commands-read-only-mode:
players: false
players: true
console: false
# If LuckPerms commands should be disabled. When true, this will prevent all LP commands from being
@@ -747,5 +758,5 @@ commands-read-only-mode:
#
# Note: This does not affect interactions with LuckPerms via the API.
disable-luckperms-commands:
players: false
players: true
console: false
-47
View File
@@ -1,47 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
dependencies {
implementation project(':common')
compileOnly project(':common:loader-utils')
compileOnly 'net.md-5:bungeecord-api:1.16-R0.4'
compileOnly('net.kyori:adventure-platform-bungeecord:4.4.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
exclude(module: 'adventure-nbt')
}
compileOnly 'com.imaginarycode.minecraft:RedisBungee:0.4'
}
shadowJar {
archiveFileName = 'luckperms-bungee.jarinjar'
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
}
artifacts {
archives shadowJar
}
-28
View File
@@ -1,28 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
dependencies {
compileOnly 'net.md-5:bungeecord-api:1.15-SNAPSHOT'
implementation project(':api')
implementation project(':common:loader-utils')
}
processResources {
filesMatching('plugin.yml') {
expand 'pluginVersion': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-Bungee-${project.ext.fullVersion}.jar"
from {
project(':bungee').tasks.shadowJar.archiveFile
}
}
artifacts {
archives shadowJar
}
@@ -302,7 +302,7 @@ public class LPBungeeBootstrap implements LuckPermsBootstrap, LoaderBootstrap, B
try {
Class.forName("com.google.gson.internal.bind.TreeTypeAdapter");
return false;
} catch (ClassNotFoundException e) {
} catch (Exception e) {
return true;
}
}
-105
View File
@@ -1,105 +0,0 @@
plugins {
id("java-library")
id("jacoco")
}
test {
useJUnitPlatform {
if (!project.hasProperty('dockerTests')) {
excludeTags 'docker'
}
}
}
jacocoTestReport {
dependsOn test
}
dependencies {
testImplementation 'org.slf4j:slf4j-simple:1.7.36'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1'
testImplementation 'org.testcontainers:junit-jupiter:1.20.4'
testImplementation 'org.mockito:mockito-core:5.11.0'
testImplementation 'org.mockito:mockito-junit-jupiter:5.11.0'
testImplementation 'com.h2database:h2:2.1.214'
testImplementation 'org.mongodb:mongodb-driver-legacy:4.5.0'
testImplementation 'org.spongepowered:configurate-yaml:3.7.2'
testImplementation 'org.spongepowered:configurate-hocon:3.7.2'
testImplementation 'me.lucko.configurate:configurate-toml:3.7'
testImplementation 'net.luckperms:rest-api-java-client:0.1-SNAPSHOT'
api project(':api')
api 'org.checkerframework:checker-qual:3.12.0'
compileOnly project(':common:loader-utils')
compileOnly 'com.mojang:brigadier:1.0.18'
compileOnly 'org.slf4j:slf4j-api:1.7.30'
compileOnly 'org.apache.logging.log4j:log4j-api:2.14.0'
api('net.kyori:adventure-api:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'checker-qual')
exclude(module: 'annotations')
}
api('net.kyori:adventure-text-serializer-gson:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
exclude(module: 'gson')
}
api('net.kyori:adventure-text-serializer-legacy:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
api('net.kyori:adventure-text-serializer-plain:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
api("net.kyori:adventure-text-minimessage:4.21.0") {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
api('net.kyori:event-api:3.0.0') {
exclude(module: 'checker-qual')
exclude(module: 'guava')
}
api 'com.google.code.gson:gson:2.7'
api 'com.google.guava:guava:19.0'
api 'com.github.ben-manes.caffeine:caffeine:2.9.0'
api 'com.squareup.okhttp3:okhttp:3.14.9'
api 'com.squareup.okio:okio:1.17.5'
api 'net.bytebuddy:byte-buddy:1.10.22'
api('org.spongepowered:configurate-core:3.7.2') {
transitive = false
}
api('org.spongepowered:configurate-yaml:3.7.2') {
transitive = false
}
api('org.spongepowered:configurate-gson:3.7.2') {
transitive = false
}
api('org.spongepowered:configurate-hocon:3.7.2') {
transitive = false
}
api('me.lucko.configurate:configurate-toml:3.7') {
transitive = false
}
compileOnly 'com.zaxxer:HikariCP:4.0.3'
compileOnly 'redis.clients:jedis:4.4.3'
compileOnly 'io.nats:jnats:2.16.4'
compileOnly 'com.rabbitmq:amqp-client:5.12.0'
compileOnly 'org.mongodb:mongodb-driver-legacy:4.5.0'
compileOnly 'org.postgresql:postgresql:42.6.0'
compileOnly 'org.yaml:snakeyaml:1.28'
compileOnly 'net.luckperms:rest-api-java-client:0.1-SNAPSHOT'
}
-1
View File
@@ -1 +0,0 @@
// nothing special to do here (yet)!
@@ -155,7 +155,7 @@ public class CommandManager {
public CompletableFuture<Void> executeCommand(Sender sender, String label, List<String> args) {
UUID uniqueId = sender.getUniqueId();
if (this.plugin.getConfiguration().get(ConfigKeys.COMMANDS_RATE_LIMIT) && !sender.isConsole() && !this.playerRateLimit.add(uniqueId)) {
if (this.plugin.getConfiguration().get(ConfigKeys.COMMANDS_RATE_LIMIT) && !sender.isConsole() && !Sender.CONSOLE_UUID.equals(uniqueId) && !this.playerRateLimit.add(uniqueId)) {
this.plugin.getLogger().warn("Player '" + uniqueId + "' is spamming LuckPerms commands. Ignoring further inputs.");
return CompletableFuture.completedFuture(null);
}
@@ -493,6 +493,12 @@ public final class ConfigKeys {
*/
public static final ConfigKey<Boolean> COMMANDS_RATE_LIMIT = booleanKey("commands-rate-limit", true);
/**
* If the Vault API bridge should be registered on platforms that support it (Bukkit).
* Disabled by default; the remaining vault-* keys below only take effect when this is true.
*/
public static final ConfigKey<Boolean> VAULT_ENABLED = booleanKey("vault-enabled", false);
/**
* If Vault lookups for offline players on the main server thread should be enabled
*/
@@ -44,14 +44,14 @@ public enum Dependency {
ASM(
"org.ow2.asm",
"asm",
"9.1",
"zaTeRV+rSP8Ly3xItGOUR9TehZp6/DCglKmG8JNr66I="
"9.8",
"h26raoPa7K1cpn65/KuwY8l7WuuM8fynqYns3hdSIFE="
),
ASM_COMMONS(
"org.ow2.asm",
"asm-commons",
"9.1",
"r8sm3B/BLAxKma2mcJCN2C4Y38SIyvXuklRplrRwwAw="
"9.8",
"MwGhwctMWfzFKSZI2sHXxa7UwPBn376IhzuM3+d0BPQ="
),
JAR_RELOCATOR(
"me.lucko",
@@ -97,15 +97,15 @@ public enum Dependency {
CAFFEINE(
"com{}github{}ben-manes{}caffeine",
"caffeine",
"2.9.0",
"VFMotEO3XLbTHfRKfL3m36GlN72E/dzRFH9B5BJiX2o=",
"3.2.0",
"7EEd/fDAPyUhhkjOiYYWMLcWgOWFippyeOusjlXKs9c=",
Relocation.of("caffeine", "com{}github{}benmanes{}caffeine")
),
OKIO(
"com{}squareup{}" + RelocationHelper.OKIO_STRING,
RelocationHelper.OKIO_STRING,
"1.17.5",
"Gaf/SNhtPPRJf38lD78pX0MME6Uo3Vt7ID+CGAK4hq0=",
"1.17.6",
"joiwVVI8yAYT37hE1Zh0DhCtpi9L2YMEzdFAxYVMw7Y=",
Relocation.of(RelocationHelper.OKIO_STRING, RelocationHelper.OKIO_STRING)
),
OKHTTP(
@@ -119,8 +119,8 @@ public enum Dependency {
BYTEBUDDY(
"net{}bytebuddy",
"byte-buddy",
"1.10.22",
"+TGtxDkxd6+lJExHJXqDlV4n/gR8QJN4xu2gkPsHSoQ=",
"1.15.11",
"+giZiq4ee9roO94HEsUOhETXHA4MGWuyJHrejUrQ65A=",
Relocation.of("bytebuddy", "net{}bytebuddy")
),
COMMODORE(
@@ -140,22 +140,22 @@ public enum Dependency {
MARIADB_DRIVER(
"org{}mariadb{}jdbc",
"mariadb-java-client",
"3.1.3",
"ESl+5lYkJsScgTh8hgFTy8ExxMPQQkktT20tl6s6HKU=",
"3.5.2",
"8vPDwaO9rKad0dThzYrtB1JC/HKuQUY924LjZ7OI9q0=",
Relocation.of("mariadb", "org{}mariadb{}jdbc")
),
MYSQL_DRIVER(
"mysql",
"mysql-connector-java",
"8.0.23",
"/31bQCr9OcEnh0cVBaM6MEEDsjjsG3pE6JNtMynadTU=",
"com{}mysql",
"mysql-connector-j",
"9.3.0",
"bI5mkrUhN22JvFYYwWzer4xhhUMp9PolZ37Qh3bFu3Y=",
Relocation.of("mysql", "com{}mysql")
),
POSTGRESQL_DRIVER(
"org{}postgresql",
"postgresql",
"42.6.0",
"uBfGekDJQkn9WdTmhuMyftDT0/rkJrINoPHnVlLPxGE=",
"42.7.6",
"8qHMA1LdXlxvZdut/ye+4Awy5DLGrQMNB0R/ilmDxCo=",
Relocation.of("postgresql", "org{}postgresql")
),
H2_DRIVER_LEGACY(
@@ -179,124 +179,124 @@ public enum Dependency {
SQLITE_DRIVER(
"org.xerial",
"sqlite-jdbc",
"3.28.0",
"k3hOVtv1RiXgbJks+D9w6cG93Vxq0dPwEwjIex2WG2A="
"3.49.1.0",
"XIYJ0so0HeuMb3F3iXS1ukmVx9MtfHyJ2TkqPnLDkpE="
// we don't apply relocations to sqlite - it gets loaded via
// an isolated classloader
),
HIKARI(
"com{}zaxxer",
"HikariCP",
"4.0.3",
"fAJK7/HBBjV210RTUT+d5kR9jmJNF/jifzCi6XaIxsk=",
"6.3.0",
"B8Y0QFmvMKE1FEIJx8i9ZmuIIxJEIuyFmGTSCdSrfKE=",
Relocation.of("hikari", "com{}zaxxer{}hikari")
),
SLF4J_SIMPLE(
"org.slf4j",
"slf4j-simple",
"1.7.30",
"i5J5y/9rn4hZTvrjzwIDm2mVAw7sAj7UOSh0jEFnD+4="
"1.7.36",
"Lzm+2UPWJN+o9BAtBXEoOhCHC2qjbxl6ilBvFHAQwQ8="
),
SLF4J_API(
"org.slf4j",
"slf4j-api",
"1.7.30",
"zboHlk0btAoHYUhcax6ML4/Z6x0ZxTkorA1/lRAQXFc="
"1.7.36",
"0+9XXj5JeWeNwBvx3M5RAhSTtNEft/G+itmCh3wWocA="
),
MONGODB_DRIVER_CORE(
"org.mongodb",
"mongodb-driver-core",
"4.5.0",
"awqoW0ImUcrCTA2d1rDCjDLEjLMCrOjKWIcC7E+zLGA=",
"5.5.0",
"69tQuKep52lbYvX2YM+J6GGlYkNySXkMBDuk6BqtsJE=",
Relocation.of("mongodb", "com{}mongodb"),
Relocation.of("bson", "org{}bson")
),
MONGODB_DRIVER_LEGACY(
"org.mongodb",
"mongodb-driver-legacy",
"4.5.0",
"77KZGIr3KZmzBpN69rGOLXmnlJIBCXRl/U4gEIdlFhY=",
"5.5.0",
"yo/0wEdLw0/Md1xqgEd/iqiKV+t0AqAcdnS1TNAaygM=",
Relocation.of("mongodb", "com{}mongodb"),
Relocation.of("bson", "org{}bson")
),
MONGODB_DRIVER_SYNC(
"org.mongodb",
"mongodb-driver-sync",
"4.5.0",
"q9XDSGJjlo/Ek6jHoCbqWnaK/dghB8y9aDM0hCLiSvk=",
"5.5.0",
"nFECiREXgMc5Ikamvmnzaxumhz75NKG+ajIhAW/ioPI=",
Relocation.of("mongodb", "com{}mongodb"),
Relocation.of("bson", "org{}bson")
),
MONGODB_DRIVER_BSON(
"org.mongodb",
"bson",
"4.5.0",
"6CFyEzxbdeiBEXdDBmcgqWs5dvicgFkBLU3MlQUIqRA=",
"5.5.0",
"hQx5w0v/DuQvASpnGXkLuWxkhXhewDTTAmrifPWbBJQ=",
Relocation.of("mongodb", "com{}mongodb"),
Relocation.of("bson", "org{}bson")
),
JEDIS(
"redis.clients",
"jedis",
"4.4.3",
"wwwoCDPCywcfoNwpvwP95kXYusXSTtXhuVrB31sxE0k=",
"5.2.0",
"3U+9osED8xmrSVrbK8GQYTmEB0bP1MZrJ3ENGvmDgtQ=",
Relocation.of("jedis", "redis{}clients{}jedis"),
Relocation.of("commonspool2", "org{}apache{}commons{}pool2")
),
NATS(
"io.nats",
"jnats",
"2.16.4",
"/WZgFi9iJToRGIiGoShlwE5aHwstOuNGZyr4UaBRilM=",
"2.21.1",
"QHUHUCnCCy/oRSwoqhy0245SrvD4lwCfc+ZVmemHXLg=",
Relocation.of("nats", "io{}nats{}client")
),
RABBITMQ(
"com{}rabbitmq",
"amqp-client",
"5.12.0",
"CxliwVWAnPKi5BwxCu1S1SGzx5fbhTk5JCKdBS27P2c=",
"5.25.0",
"WqlvAFCEE56xB32UtV3GQo7KfafizFPqtEp3M5H4qo8=",
Relocation.of("rabbitmq", "com{}rabbitmq")
),
COMMONS_POOL_2(
"org.apache.commons",
"commons-pool2",
"2.9.0",
"vJGbQmv6+zHsxF1mUqnxN0YkZdhJ+zhz142Qw/jTWwE=",
"2.12.1",
"UnPIvIwNyiIRF1wNJ++9cijvrplomqwAGo4e+Ohy6e8=",
Relocation.of("commonspool2", "org{}apache{}commons{}pool2")
),
CONFIGURATE_CORE(
"org{}spongepowered",
"configurate-core",
"3.7.2",
"XF2LzWLkSV0wyQRDt33I+gDlf3t2WzxH1h8JCZZgPp4=",
"3.7.3",
"06R3WDViB84WtSkHTudV8TSPxF1eQyCyfab8L7Pvo2M=",
Relocation.of("configurate", "ninja{}leaping{}configurate")
),
CONFIGURATE_GSON(
"org{}spongepowered",
"configurate-gson",
"3.7.2",
"9S/mp3Ig9De7NNd6+2kX+L4R90bHnAosSNVbFjrl7sM=",
"3.7.3",
"QM+bGrgrzfwT9nvIvTHtR2TUEpun+RwlXIO/a9BU0Mc=",
Relocation.of("configurate", "ninja{}leaping{}configurate")
),
CONFIGURATE_YAML(
"org{}spongepowered",
"configurate-yaml",
"3.7.2",
"OBfYn4nSMGZfVf2DoZhZq+G9TF1mODX/C5OOz/mkPmc=",
"3.7.3",
"a04vRkLhigIqiG/gdVvK7c1YiBQJ7k1q/kBNsS9OVDs=",
Relocation.of("configurate", "ninja{}leaping{}configurate")
),
SNAKEYAML(
"org.yaml",
"snakeyaml",
"1.28",
"NURqFCFDXUXkxqwN47U3hSfVzCRGwHGD4kRHcwzh//o=",
"1.33",
"Ef9Fl4jwoteB9WpKhtfmkgLOus0Cc9UmnErp8C8/2PA=",
Relocation.of("yaml", "org{}yaml{}snakeyaml")
),
CONFIGURATE_HOCON(
"org{}spongepowered",
"configurate-hocon",
"3.7.2",
"GOORZlK1FKLzdIm7dKyyXtBdvk7Z89HARAd2H6NiWSY=",
"3.7.3",
"e/UDpbIrWdJNB6yMFXtrOnnNn3nptmSv/J8n46uQPNs=",
Relocation.of("configurate", "ninja{}leaping{}configurate"),
Relocation.of("hocon", "com{}typesafe{}config")
),
@@ -143,7 +143,7 @@ public class DependencyRegistry {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
} catch (Exception e) {
return false;
}
}
@@ -231,11 +231,11 @@ public final class EventDispatcher {
}
public void dispatchNodeChanges(PermissionHolder target, DataType dataType, Difference<Node> changes) {
if (!this.eventBus.shouldPost(NodeAddEvent.class) && !this.eventBus.shouldPost(NodeRemoveEvent.class)) {
if (changes.isEmpty()) {
return;
}
if (changes.isEmpty()) {
if (!this.eventBus.shouldPost(NodeAddEvent.class) && !this.eventBus.shouldPost(NodeRemoveEvent.class)) {
return;
}
@@ -27,7 +27,6 @@ package me.lucko.luckperms.common.extension;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.plugin.classpath.URLClassLoaderAccess;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.extension.Extension;
@@ -40,7 +39,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
@@ -115,7 +113,6 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
}
String className;
boolean useParentClassLoader = false;
try (JarFile jar = new JarFile(path.toFile())) {
JarEntry extensionJarEntry = jar.getJarEntry("extension.json");
if (extensionJarEntry == null) {
@@ -128,8 +125,14 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
JsonObject parsed = GsonProvider.parser().parse(reader).getAsJsonObject();
className = parsed.get("class").getAsString();
// check for deprecated flags
if (parsed.has("useParentClassLoader")) {
useParentClassLoader = parsed.get("useParentClassLoader").getAsBoolean();
boolean useParentClassLoader = parsed.get("useParentClassLoader").getAsBoolean();
if (useParentClassLoader) {
this.plugin.getLogger().warn("Extension '" + className + "' specifies the 'useParentClassLoader' extension flag, which has been deprecated/removed. " +
"The extension will be loaded using the classloader of the LuckPerms plugin, and not the classloader of the platform, which may break functionality.");
}
}
}
}
@@ -139,15 +142,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
throw new IllegalArgumentException("class is null");
}
if (useParentClassLoader && isJarInJar()) {
try {
addJarToParentClasspath(path);
} catch (Throwable e) {
throw new RuntimeException("Exception whilst classloading extension", e);
}
} else {
this.plugin.getBootstrap().getClassPathAppender().addJarToClasspath(path);
}
this.plugin.getBootstrap().getClassPathAppender().addJarToClasspath(path);
Class<? extends Extension> extensionClass;
try {
@@ -191,21 +186,6 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
return this.extensions.stream().map(e -> e.instance).collect(Collectors.toSet());
}
private static boolean isJarInJar() {
String thisClassLoaderName = SimpleExtensionManager.class.getClassLoader().getClass().getName();
return thisClassLoaderName.equals("me.lucko.luckperms.common.loader.JarInJarClassLoader");
}
@Deprecated
private static void addJarToParentClasspath(Path path) throws Exception {
ClassLoader parentClassLoader = SimpleExtensionManager.class.getClassLoader().getParent();
if (!(parentClassLoader instanceof URLClassLoader)) {
throw new RuntimeException("useParentClassLoader is true but parent is not a URLClassLoader");
}
URLClassLoaderAccess.create(((URLClassLoader) parentClassLoader)).addURL(path.toUri().toURL());
}
private static final class LoadedExtension {
private final Extension instance;
private final Path path;
@@ -431,8 +431,8 @@ public abstract class PermissionHolder {
Difference<Node> result = getData(dataType).removeIf(Node::hasExpired);
if (!result.isEmpty()) {
invalidateCache();
this.plugin.getEventDispatcher().dispatchNodeChanges(this, dataType, result);
}
this.plugin.getEventDispatcher().dispatchNodeChanges(this, dataType, result);
return !result.isEmpty();
}
@@ -132,6 +132,16 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
// load some utilities early
this.permissionRegistry = new AsyncPermissionRegistry(getBootstrap().getScheduler());
this.verboseHandler = new VerboseHandler(getBootstrap().getScheduler());
// load configuration
getLogger().info("Loading configuration...");
ConfigurationAdapter configFileAdapter = provideConfigurationAdapter();
this.configuration = new LuckPermsConfiguration(this, new MultiConfigurationAdapter(this,
new FileSecretConfigAdapter(this),
new SystemPropertyConfigAdapter(this),
new EnvironmentVariableConfigAdapter(this),
configFileAdapter
));
}
public final void enable() {
@@ -144,16 +154,6 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
// setup log dispatcher instance early
this.logDispatcher = new LogDispatcher(this);
// load configuration
getLogger().info("Loading configuration...");
ConfigurationAdapter configFileAdapter = provideConfigurationAdapter();
this.configuration = new LuckPermsConfiguration(this, new MultiConfigurationAdapter(this,
new FileSecretConfigAdapter(this),
new SystemPropertyConfigAdapter(this),
new EnvironmentVariableConfigAdapter(this),
configFileAdapter
));
// setup a bytebin instance
this.httpClient = new OkHttpClient.Builder()
.callTimeout(15, TimeUnit.SECONDS)
@@ -1,58 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.plugin.classpath;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import java.net.MalformedURLException;
import java.net.URLClassLoader;
import java.nio.file.Path;
public class ReflectionClassPathAppender implements ClassPathAppender {
private final URLClassLoaderAccess classLoaderAccess;
public ReflectionClassPathAppender(ClassLoader classLoader) throws IllegalStateException {
if (classLoader instanceof URLClassLoader) {
this.classLoaderAccess = URLClassLoaderAccess.create((URLClassLoader) classLoader);
} else {
throw new IllegalStateException("ClassLoader is not instance of URLClassLoader");
}
}
public ReflectionClassPathAppender(LuckPermsBootstrap bootstrap) throws IllegalStateException {
this(bootstrap.getClass().getClassLoader());
}
@Override
public void addJarToClasspath(Path file) {
try {
this.classLoaderAccess.addURL(file.toUri().toURL());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
}
@@ -1,190 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.plugin.classpath;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
/**
* Provides access to {@link URLClassLoader}#addURL.
*/
public abstract class URLClassLoaderAccess {
/**
* Creates a {@link URLClassLoaderAccess} for the given class loader.
*
* @param classLoader the class loader
* @return the access object
*/
public static URLClassLoaderAccess create(URLClassLoader classLoader) {
if (Reflection.isSupported()) {
return new Reflection(classLoader);
} else if (Unsafe.isSupported()) {
return new Unsafe(classLoader);
} else {
return Noop.INSTANCE;
}
}
private final URLClassLoader classLoader;
protected URLClassLoaderAccess(URLClassLoader classLoader) {
this.classLoader = classLoader;
}
/**
* Adds the given URL to the class loader.
*
* @param url the URL to add
*/
public abstract void addURL(@NonNull URL url);
private static void throwError(Throwable cause) throws UnsupportedOperationException {
throw new UnsupportedOperationException("LuckPerms is unable to inject into the plugin URLClassLoader.\n" +
"You may be able to fix this problem by adding the following command-line argument " +
"directly after the 'java' command in your start script: \n'--add-opens java.base/java.lang=ALL-UNNAMED'", cause);
}
/**
* Accesses using reflection, not supported on Java 9+.
*/
private static class Reflection extends URLClassLoaderAccess {
private static final Method ADD_URL_METHOD;
static {
Method addUrlMethod;
try {
addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addUrlMethod.setAccessible(true);
} catch (Exception e) {
addUrlMethod = null;
}
ADD_URL_METHOD = addUrlMethod;
}
private static boolean isSupported() {
return ADD_URL_METHOD != null;
}
Reflection(URLClassLoader classLoader) {
super(classLoader);
}
@Override
public void addURL(@NonNull URL url) {
try {
ADD_URL_METHOD.invoke(super.classLoader, url);
} catch (ReflectiveOperationException e) {
URLClassLoaderAccess.throwError(e);
}
}
}
/**
* Accesses using sun.misc.Unsafe, supported on Java 9+.
*
* @author Vaishnav Anil (https://github.com/slimjar/slimjar)
*/
private static class Unsafe extends URLClassLoaderAccess {
private static final sun.misc.Unsafe UNSAFE;
static {
sun.misc.Unsafe unsafe;
try {
Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
unsafe = (sun.misc.Unsafe) unsafeField.get(null);
} catch (Throwable t) {
unsafe = null;
}
UNSAFE = unsafe;
}
private static boolean isSupported() {
return UNSAFE != null;
}
private final Collection<URL> unopenedURLs;
private final Collection<URL> pathURLs;
@SuppressWarnings("unchecked")
Unsafe(URLClassLoader classLoader) {
super(classLoader);
Collection<URL> unopenedURLs;
Collection<URL> pathURLs;
try {
Object ucp = fetchField(URLClassLoader.class, classLoader, "ucp");
unopenedURLs = (Collection<URL>) fetchField(ucp.getClass(), ucp, "unopenedUrls");
pathURLs = (Collection<URL>) fetchField(ucp.getClass(), ucp, "path");
} catch (Throwable e) {
unopenedURLs = null;
pathURLs = null;
}
this.unopenedURLs = unopenedURLs;
this.pathURLs = pathURLs;
}
private static Object fetchField(final Class<?> clazz, final Object object, final String name) throws NoSuchFieldException {
Field field = clazz.getDeclaredField(name);
long offset = UNSAFE.objectFieldOffset(field);
return UNSAFE.getObject(object, offset);
}
@Override
public void addURL(@NonNull URL url) {
if (this.unopenedURLs == null || this.pathURLs == null) {
URLClassLoaderAccess.throwError(new NullPointerException("unopenedURLs or pathURLs"));
}
synchronized (this.unopenedURLs) {
this.unopenedURLs.add(url);
this.pathURLs.add(url);
}
}
}
private static class Noop extends URLClassLoaderAccess {
private static final Noop INSTANCE = new Noop();
private Noop() {
super(null);
}
@Override
public void addURL(@NonNull URL url) {
URLClassLoaderAccess.throwError(null);
}
}
}
@@ -28,7 +28,6 @@ package me.lucko.luckperms.common.sender;
import com.google.common.collect.Iterables;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.generic.key.ConfigKey;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
@@ -1,298 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.locale;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.actionlog.LoggedAction;
import me.lucko.luckperms.common.command.spec.Argument;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.extension.SimpleExtensionManager;
import me.lucko.luckperms.common.model.HolderType;
import me.lucko.luckperms.common.model.InheritanceOrigin;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.PermissionHolderIdentifier;
import me.lucko.luckperms.common.node.types.Inheritance;
import me.lucko.luckperms.common.node.types.Meta;
import me.lucko.luckperms.common.node.types.Permission;
import me.lucko.luckperms.common.node.types.Prefix;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap;
import me.lucko.luckperms.common.storage.Storage;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentIteratorFlag;
import net.kyori.adventure.text.ComponentIteratorType;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.translation.TranslationRegistry;
import net.kyori.adventure.util.UTF8ResourceBundleControl;
import net.luckperms.api.actionlog.Action;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.model.data.DataType;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import net.luckperms.api.node.types.ChatMetaNode;
import net.luckperms.api.node.types.InheritanceNode;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.platform.Platform;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Answers;
import org.mockito.junit.jupiter.MockitoExtension;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.MessageFormat;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
public class MessageTest {
private static final Set<Class<?>> MESSAGE_CLASSES = ImmutableSet.of(
Message.Args0.class,
Message.Args1.class,
Message.Args2.class,
Message.Args3.class,
Message.Args4.class,
Message.Args5.class,
Message.Args6.class
);
private static final Set<String> IGNORED_MISSING_TRANSLATION_KEYS = ImmutableSet.of(
"luckperms.command.misc.invalid-input-empty-stub"
);
private static TranslationRegistry registry;
private static Set<String> translationKeys;
@BeforeAll
public static void setupRenderer() {
registry = TranslationRegistry.create(Key.key("luckperms", "test"));
ResourceBundle bundle = ResourceBundle.getBundle("luckperms", Locale.ENGLISH, UTF8ResourceBundleControl.get());
translationKeys = ImmutableSet.copyOf(bundle.keySet());
registry.registerAll(Locale.ENGLISH, bundle, false);
}
private static Stream<Field> getMessageFields() {
return Arrays.stream(Message.class.getDeclaredFields())
.filter(f -> Modifier.isStatic(f.getModifiers()))
.filter(f -> MESSAGE_CLASSES.contains(f.getType()));
}
@ParameterizedTest
@MethodSource("getMessageFields")
public void testMessage(Field field) {
Component baseComponent = buildMessage(field);
for (Component part : getNestedComponents(baseComponent)) {
if (part instanceof TranslatableComponent) {
TranslatableComponent component = (TranslatableComponent) part;
assertTranslatableComponentValid(component);
}
}
}
@ParameterizedTest
@EnumSource
public void testCommandUsageMessages(CommandSpec commandSpec) {
assertTranslatableComponentValid(commandSpec.description());
List<Argument> args = commandSpec.args();
if (args != null) {
for (Argument arg : args) {
assertTranslatableComponentValid(arg.getDescription());
}
}
}
private static void assertTranslatableComponentValid(TranslatableComponent component) {
String key = component.key();
if (IGNORED_MISSING_TRANSLATION_KEYS.contains(key)) {
return;
}
assertTrue(translationKeys.contains(key), "unknown translation key: " + key);
List<Component> args = component.args();
MessageFormat fmt = registry.translate(key, Locale.ENGLISH);
assertNotNull(fmt);
assertEquals(fmt.getFormats().length, args.size(), "number of formats in translation for " + key + " does not match number of arguments");
}
private static Iterable<Component> getNestedComponents(Component component) {
return component.iterable(
ComponentIteratorType.BREADTH_FIRST,
ImmutableSet.of(ComponentIteratorFlag.INCLUDE_TRANSLATABLE_COMPONENT_ARGUMENTS, ComponentIteratorFlag.INCLUDE_HOVER_SHOW_TEXT_COMPONENT)
);
}
private static Component buildMessage(Field field) {
Class<?> type = field.getType();
List<Method> buildMethods = Arrays.stream(type.getDeclaredMethods())
.filter(method -> method.getName().equals("build"))
.collect(Collectors.toList());
if (buildMethods.size() != 1) {
throw new IllegalStateException("Expected exactly one build() method - " + buildMethods);
}
Method buildMethod = buildMethods.get(0);
Object[] parameters = new Object[buildMethod.getParameterCount()];
if (buildMethod.getParameterCount() != 0) {
Type genericType = field.getGenericType();
Type[] typeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
for (int i = 0; i < typeArguments.length; i++) {
Type typeArgument = typeArguments[i];
parameters[i] = mockArgument(typeArgument);
}
}
try {
Object builder = field.get(null);
return (Component) buildMethod.invoke(builder, parameters);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
private static Object mockArgument(Type type) {
if (type instanceof ParameterizedType) {
return mockArgument(((ParameterizedType) type).getRawType());
}
Class<?> clazz = (Class<?>) type;
if (clazz == String.class) {
return "stub";
} else if (clazz == Integer.class) {
return 0;
} else if (clazz == Boolean.class) {
return false;
} else if (clazz == Double.class) {
return 0d;
} else if (clazz == LoggedAction.class) {
return LoggedAction.build()
.source(UUID.randomUUID())
.sourceName("stub")
.targetType(Action.Target.Type.GROUP)
.targetName("stub")
.description("stub")
.build();
} else if (clazz == Node.class) {
return Permission.builder().permission("stub").expiry(1, TimeUnit.MINUTES).build();
} else if (clazz == InheritanceNode.class) {
return Inheritance.builder().group("stub").expiry(1, TimeUnit.MINUTES).build();
} else if (clazz == MetaNode.class) {
return Meta.builder("stub", "stub")
.withMetadata(InheritanceOriginMetadata.KEY, new InheritanceOrigin(
new PermissionHolderIdentifier(HolderType.GROUP, "stub"),
DataType.NORMAL
))
.build();
} else if (clazz == ChatMetaNode.class) {
return Prefix.builder("stub", 1)
.withMetadata(InheritanceOriginMetadata.KEY, new InheritanceOrigin(
new PermissionHolderIdentifier(HolderType.GROUP, "stub"),
DataType.NORMAL
))
.build();
} else if (clazz == ContextSet.class) {
return ImmutableContextSetImpl.of("stub", "stub");
} else if (clazz == Component.class) {
return Component.text("stub");
} else if (clazz == List.class) {
return ImmutableList.of();
} else if (clazz == Collection.class) {
return ImmutableList.of();
}
Object mock;
if (clazz == LuckPermsPlugin.class) {
mock = mock(clazz, Answers.RETURNS_DEEP_STUBS);
} else {
mock = mock(clazz, Answers.RETURNS_SMART_NULLS);
}
if (mock instanceof LuckPermsBootstrap) {
LuckPermsBootstrap bootstrap = (LuckPermsBootstrap) mock;
lenient().when(bootstrap.getType()).thenReturn(Platform.Type.BUKKIT);
lenient().when(bootstrap.getStartupTime()).thenReturn(Instant.now());
} else if (mock instanceof LuckPermsPlugin) {
LuckPermsPlugin plugin = (LuckPermsPlugin) mock;
LuckPermsBootstrap bootstrap = (LuckPermsBootstrap) mockArgument(LuckPermsBootstrap.class);
lenient().when(plugin.getBootstrap()).thenReturn(bootstrap);
Storage storage = (Storage) mockArgument(Storage.class);
lenient().when(plugin.getStorage()).thenReturn(storage);
SimpleExtensionManager extManager = (SimpleExtensionManager) mockArgument(SimpleExtensionManager.class);
lenient().when(plugin.getExtensionManager()).thenReturn(extManager);
lenient().when(plugin.getMessagingService()).thenReturn(Optional.empty());
} else if (mock instanceof PermissionHolder) {
PermissionHolder holder = (PermissionHolder) mock;
LuckPermsPlugin plugin = (LuckPermsPlugin) mockArgument(LuckPermsPlugin.class);
lenient().when(holder.getPlugin()).thenReturn(plugin);
lenient().when(holder.getFormattedDisplayName()).thenReturn(Component.text("stub"));
} else if (mock instanceof SimpleExtensionManager) {
SimpleExtensionManager manager = (SimpleExtensionManager) mock;
lenient().when(manager.getLoadedExtensions()).thenReturn(ImmutableList.of());
}
return mock;
}
}
@@ -25,9 +25,9 @@
package me.lucko.luckperms.common.sender;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.locale.Message;
import net.kyori.adventure.text.Component;
import com.google.common.collect.ImmutableList;
import org.junit.jupiter.api.Test;
import java.util.List;
@@ -1,61 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.storage;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
import me.lucko.luckperms.common.storage.implementation.mongodb.MongoStorage;
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
import org.junit.jupiter.api.Tag;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
@Tag("docker")
public class MongoStorageTest extends AbstractStorageTest {
private final GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("mongo"))
.withExposedPorts(27017);
@Override
protected StorageImplementation makeStorage(LuckPermsPlugin plugin) throws Exception {
this.container.start();
String host = this.container.getHost();
Integer port = this.container.getFirstMappedPort();
StorageCredentials credentials = new StorageCredentials(
host + ":" + port,
"minecraft",
"",
""
);
return new MongoStorage(plugin, credentials, "", "");
}
@Override
protected void cleanupResources() {
this.container.stop();
}
}
@@ -1,63 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.storage;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
import me.lucko.luckperms.common.storage.implementation.rest.RestStorage;
import org.junit.jupiter.api.Tag;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.containers.wait.strategy.WaitAllStrategy;
import org.testcontainers.utility.DockerImageName;
@Tag("docker")
public class RestStorageTest extends AbstractStorageTest {
private final GenericContainer<?> container = new GenericContainer<>(DockerImageName.parse("ghcr.io/luckperms/rest-api"))
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger(RestStorageTest.class)))
.withExposedPorts(8080)
.waitingFor(new WaitAllStrategy()
.withStrategy(Wait.forListeningPort())
.withStrategy(Wait.forLogMessage(".*Successfully enabled.*", 1))
);
@Override
protected StorageImplementation makeStorage(LuckPermsPlugin plugin) throws Exception {
this.container.start();
String host = this.container.getHost();
Integer port = this.container.getFirstMappedPort();
return new RestStorage(plugin, "http://" + host + ":" + port + "/", null);
}
@Override
protected void cleanupResources() {
this.container.stop();
}
}
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="TreeWalker">
<module name="FinalLocalVariable"/>
<module name="AvoidStarImport"/>
<module name="Indentation">
<property name="severity" value="ignore"/>
</module>
</module>
<module name="RegexpSingleline">
<property name="format" value="\borg\.junit\.jupiter\.api\.Assertions\.fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="ignoreCase" value="true"/>
<property name="severity" value="warning"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="(?&lt;!\w)fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="severity" value="warning"/>
</module>
</module>
+404
View File
@@ -0,0 +1,404 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="23">
<profile kind="CodeFormatterProfile" name="TrueOG Network Formatting" version="23">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
-88
View File
@@ -1,88 +0,0 @@
import net.fabricmc.loom.task.RemapJarTask
plugins {
alias(libs.plugins.shadow)
alias(libs.plugins.loom)
}
archivesBaseName = 'luckperms'
repositories {
maven { url 'https://maven.fabricmc.net/' }
}
dependencies {
// https://modmuss50.me/fabric.html
minecraft 'com.mojang:minecraft:1.21.5'
mappings 'net.fabricmc:yarn:1.21.5+build.1:v2'
modImplementation 'net.fabricmc:fabric-loader:0.16.14'
Set<String> apiModules = [
'fabric-api-base',
'fabric-command-api-v2',
'fabric-lifecycle-events-v1',
'fabric-networking-api-v1',
'fabric-entity-events-v1'
]
apiModules.forEach {
modImplementation(fabricApi.module(it, '0.123.0+1.21.5'))
}
include(modImplementation('me.lucko:fabric-permissions-api:0.3.3'))
implementation project(':common')
}
processResources {
inputs.property 'version', project.ext.fullVersion
filesMatching('**/fabric.mod.json') {
expand 'version': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "luckpermsfabric-${project.ext.fullVersion}-dev.jar"
dependencies {
exclude('net.fabricmc:.*')
include(dependency('net.luckperms:.*'))
include(dependency('me.lucko.luckperms:.*'))
// We don't want to include the mappings in the jar do we?
exclude '/mappings/*'
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
relocate 'org.yaml.snakeyaml', 'me.lucko.luckperms.lib.yaml'
}
task remappedShadowJar(type: RemapJarTask) {
dependsOn tasks.shadowJar
input = tasks.shadowJar.archiveFile
addNestedDependencies = true
archiveFileName = "LuckPerms-Fabric-${project.ext.fullVersion}.jar"
}
tasks.assemble.dependsOn tasks.remappedShadowJar
artifacts {
archives remappedShadowJar
shadow shadowJar
}
@@ -25,6 +25,7 @@
package me.lucko.luckperms.fabric;
import com.mojang.serialization.JsonOps;
import me.lucko.fabric.api.permissions.v0.Permissions;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.sender.Sender;
@@ -39,6 +40,7 @@ import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.rcon.RconCommandOutput;
import net.minecraft.text.Text;
import net.minecraft.text.TextCodecs;
import java.util.Locale;
import java.util.UUID;
@@ -118,6 +120,9 @@ public class FabricSenderFactory extends SenderFactory<LPFabricPlugin, ServerCom
}
public static Text toNativeText(Component component) {
return Text.Serialization.fromJsonTree(GsonComponentSerializer.gson().serializeToTree(component), DynamicRegistryManager.EMPTY);
return TextCodecs.CODEC.decode(
DynamicRegistryManager.EMPTY.getOps(JsonOps.INSTANCE),
GsonComponentSerializer.gson().serializeToTree(component)
).getOrThrow(IllegalArgumentException::new).getFirst();
}
}
@@ -78,7 +78,7 @@ public class FabricPlayerCalculator implements ContextCalculator<ServerPlayerEnt
}
// TODO: figure out dimension type context too
ServerWorld world = target.getServerWorld();
ServerWorld world = target.getWorld();
if (this.world) {
this.plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).rewriteAndSubmit(getContextKey(world.getRegistryKey().getValue()), consumer);
}
@@ -131,7 +131,9 @@ public class FabricConnectionListener extends AbstractConnectionListener {
}
private void onDisconnect(ServerPlayNetworkHandler netHandler, MinecraftServer server) {
handleDisconnect(netHandler.player.getUuid());
if (!server.isStopped()) {
handleDisconnect(netHandler.player.getUuid());
}
}
}
@@ -35,9 +35,7 @@ import me.lucko.luckperms.fabric.model.MixinUser;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -63,9 +61,6 @@ public abstract class ServerPlayerEntityMixin implements MixinUser {
@Unique
private QueryOptionsSupplier luckperms$queryOptions;
// Used by PlayerChangeWorldCallback hook below.
@Shadow public abstract ServerWorld getServerWorld();
@Override
public User luckperms$getUser() {
return this.luckperms$user;
+1 -1
View File
@@ -663,7 +663,7 @@ resolve-command-selectors = false
commands-read-only-mode {
players = false
console = false
}
# If LuckPerms commands should be disabled. When true, this will prevent all LP commands from being
# executed. In a sense this is a more extreme version of read-only mode (see above).
-56
View File
@@ -1,56 +0,0 @@
plugins {
alias(libs.plugins.blossom)
alias(libs.plugins.shadow)
alias(libs.plugins.forgegradle)
}
sourceCompatibility = 17
targetCompatibility = 21
blossom {
replaceTokenIn 'src/main/java/me/lucko/luckperms/forge/LPForgeBootstrap.java'
replaceToken '@version@', project.ext.fullVersion
}
minecraft {
mappings channel: 'official', version: minecraftVersion
}
dependencies {
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
implementation project(':common')
compileOnly project(':common:loader-utils')
compileOnly project(':forge:forge-api')
}
shadowJar {
archiveFileName = "luckperms-forge.jarinjar"
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
relocate 'org.yaml.snakeyaml', 'me.lucko.luckperms.lib.yaml'
}
artifacts {
archives shadowJar
}
-15
View File
@@ -1,15 +0,0 @@
plugins {
alias(libs.plugins.forgegradle)
}
sourceCompatibility = 17
targetCompatibility = 21
minecraft {
mappings channel: 'official', version: minecraftVersion
}
dependencies {
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
implementation project(':api')
}
@@ -1,85 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.forge.capabilities;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken;
/**
* A Forge {@link Capability} that attaches LuckPerms functionality onto {@link ServerPlayer}s.
*/
public interface UserCapability {
/**
* The identifier used for the capability
*/
ResourceLocation IDENTIFIER = ResourceLocation.fromNamespaceAndPath("luckperms", "user");
/**
* The capability instance.
*/
Capability<UserCapability> CAPABILITY = CapabilityManager.get(new CapabilityToken<UserCapability>(){});
/**
* Checks for a permission.
*
* @param permission the permission
* @return the result
*/
default boolean hasPermission(String permission) {
return checkPermission(permission).asBoolean();
}
/**
* Runs a permission check.
*
* @param permission the permission
* @return the result
*/
Tristate checkPermission(String permission);
/**
* Runs a permission check.
*
* @param permission the permission
* @param queryOptions the query options
* @return the result
*/
Tristate checkPermission(String permission, QueryOptions queryOptions);
/**
* Gets the user's currently query options.
*
* @return the current query options for the user
*/
QueryOptions getQueryOptions();
}
+2 -2
View File
@@ -1,2 +1,2 @@
minecraftVersion=1.21.5
forgeVersion=55.0.12
minecraftVersion=1.21.8
forgeVersion=58.0.0
-61
View File
@@ -1,61 +0,0 @@
plugins {
alias(libs.plugins.shadow)
alias(libs.plugins.forgegradle)
id("java-library")
}
sourceCompatibility = 17
targetCompatibility = 21
minecraft {
mappings channel: 'official', version: minecraftVersion
}
dependencies {
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
implementation project(':api')
implementation project(':common:loader-utils')
implementation project(':forge:forge-api')
}
build {
dependsOn(":forge:build")
dependsOn(":forge:forge-api:build")
}
jar {
manifest {
attributes(
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'Implementation-Title': 'LuckPerms',
'Implementation-Vendor': 'LuckPerms',
'Implementation-Version': project.ext.fullVersion,
'Specification-Title': 'luckperms',
'Specification-Vendor': 'LuckPerms',
'Specification-Version': '1'
)
}
}
processResources {
filesMatching('META-INF/mods.toml') {
expand 'version': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-Forge-${project.ext.fullVersion}.jar"
from {
project(':forge').tasks.shadowJar.archiveFile
}
dependencies {
include(dependency('net.luckperms:.*'))
include(dependency('me.lucko.luckperms:.*'))
}
}
artifacts {
archives shadowJar
}
@@ -29,16 +29,14 @@ import me.lucko.luckperms.common.loader.JarInJarClassLoader;
import me.lucko.luckperms.common.loader.LoaderBootstrap;
import net.minecraftforge.fml.IExtensionPoint;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
import net.minecraftforge.fml.loading.FMLEnvironment;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.lang.reflect.InvocationTargetException;
import java.util.function.Supplier;
@Mod(value = "luckperms")
@@ -48,15 +46,14 @@ public class ForgeLoaderPlugin implements Supplier<ModContainer> {
private static final String JAR_NAME = "luckperms-forge.jarinjar";
private static final String BOOTSTRAP_CLASS = "me.lucko.luckperms.forge.LPForgeBootstrap";
private final ModContainer container;
private final FMLModContainer container;
private JarInJarClassLoader loader;
private LoaderBootstrap plugin;
public ForgeLoaderPlugin() {
this.container = ModList.get().getModContainerByObject(this).orElse(null);
markAsNotRequiredClientSide();
public ForgeLoaderPlugin(FMLJavaModLoadingContext ctx) {
this.container = ctx.getContainer();
ctx.registerDisplayTest(IExtensionPoint.DisplayTest.IGNORE_SERVER_VERSION);
if (FMLEnvironment.dist.isClient()) {
LOGGER.info("Skipping LuckPerms init (not supported on the client!)");
@@ -64,7 +61,7 @@ public class ForgeLoaderPlugin implements Supplier<ModContainer> {
}
this.loader = new JarInJarClassLoader(getClass().getClassLoader(), JAR_NAME);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onCommonSetup);
FMLCommonSetupEvent.getBus(ctx.getModBusGroup()).addListener(this::onCommonSetup);
}
@Override
@@ -77,21 +74,4 @@ public class ForgeLoaderPlugin implements Supplier<ModContainer> {
this.plugin.onLoad();
}
private static void markAsNotRequiredClientSide() {
try {
// workaround as we don't compile against java 17
ModLoadingContext.class.getDeclaredMethod("registerExtensionPoint", Class.class, Supplier.class)
.invoke(
ModLoadingContext.get(),
IExtensionPoint.DisplayTest.class,
(Supplier<?>) () -> new IExtensionPoint.DisplayTest(
() -> IExtensionPoint.DisplayTest.IGNORESERVERONLY,
(a, b) -> true
)
);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new IllegalStateException(e);
}
}
}
@@ -37,7 +37,8 @@ import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import java.util.List;
import java.util.ListIterator;
@@ -65,6 +66,12 @@ public class ForgeCommandExecutor extends BrigadierCommandExecutor<CommandSource
}
}
// not used - workaround for the idiotic Forge limitation that requires listeners using the @SubscribeEvent annotation to have at least two listener methods
@SubscribeEvent
public void onServerStarted(ServerStartedEvent event) {
}
@Override
public Sender getSender(CommandSourceStack source) {
return this.plugin.getSenderFactory().wrap(source);
@@ -26,22 +26,23 @@
package me.lucko.luckperms.forge;
import com.mojang.brigadier.ParseResults;
import com.mojang.serialization.JsonOps;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.sender.SenderFactory;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.forge.capabilities.UserCapability;
import me.lucko.luckperms.forge.capabilities.UserCapabilityImpl;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.chat.Component.Serializer;
import net.minecraft.network.chat.ComponentSerialization;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.rcon.RconConsoleSource;
import net.minecraft.world.entity.player.Player;
@@ -72,24 +73,22 @@ public class ForgeSenderFactory extends SenderFactory<LPForgePlugin, CommandSour
@Override
protected void sendMessage(CommandSourceStack sender, Component message) {
Locale locale;
if (sender.getEntity() instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) sender.getEntity();
UserCapabilityImpl user = UserCapabilityImpl.get(player);
locale = user.getLocale(player);
} else {
locale = null;
}
Locale locale = sender.getEntity() instanceof ServerPlayer player
? TranslationManager.parseLocale(player.getLanguage())
: null;
sender.sendSuccess(() -> toNativeText(TranslationManager.render(message, locale)), false);
}
@Override
protected Tristate getPermissionValue(CommandSourceStack commandSource, String node) {
if (commandSource.getEntity() instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) commandSource.getEntity();
UserCapability user = UserCapabilityImpl.get(player);
return user.checkPermission(node);
if (commandSource.getEntity() instanceof ServerPlayer player) {
User user = getPlugin().getUserManager().getIfLoaded(player.getUUID());
if (user == null) {
return Tristate.UNDEFINED;
}
QueryOptions queryOptions = getPlugin().getContextManager().getQueryOptions(player);
return user.getCachedData().getPermissionData(queryOptions).checkPermission(node, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
}
VerboseCheckTarget target = VerboseCheckTarget.internal(commandSource.getTextName());
@@ -118,7 +117,10 @@ public class ForgeSenderFactory extends SenderFactory<LPForgePlugin, CommandSour
}
public static net.minecraft.network.chat.Component toNativeText(Component component) {
return Serializer.fromJson(GsonComponentSerializer.gson().serializeToTree(component), RegistryAccess.EMPTY);
return ComponentSerialization.CODEC.decode(
RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE),
GsonComponentSerializer.gson().serializeToTree(component)
).getOrThrow(IllegalArgumentException::new).getFirst();
}
}
@@ -34,15 +34,16 @@ import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender;
import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger;
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
import me.lucko.luckperms.forge.util.ForgeEventBusFacade;
import net.luckperms.api.platform.Platform;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.PlayerList;
import net.minecraftforge.event.server.ServerAboutToStartEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.bus.BusGroup;
import net.minecraftforge.eventbus.api.listener.EventListener;
import net.minecraftforge.eventbus.api.listener.Priority;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLPaths;
@@ -50,6 +51,7 @@ import net.minecraftforge.forgespi.language.IModInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import java.lang.invoke.MethodHandles;
import java.nio.file.Path;
import java.time.Instant;
import java.util.ArrayList;
@@ -88,9 +90,9 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
private final ClassPathAppender classPathAppender;
/**
* A facade for the forge event bus, compatible with LP's jar-in-jar packaging
* A list of all event listerners registered by the plugin.
*/
private final ForgeEventBusFacade forgeEventBus;
private final List<EventListener> listeners = new ArrayList<>();
/**
* The plugin instance
@@ -116,7 +118,6 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
this.logger = new Log4jPluginLogger(LogManager.getLogger(LPForgeBootstrap.ID));
this.schedulerAdapter = new ForgeSchedulerAdapter(this);
this.classPathAppender = new JarInJarClassPathAppender(getClass().getClassLoader());
this.forgeEventBus = new ForgeEventBusFacade();
this.plugin = new LPForgePlugin(this);
}
@@ -143,7 +144,16 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
}
public void registerListeners(Object target) {
this.forgeEventBus.register(target);
Collection<EventListener> listeners = BusGroup.DEFAULT.register(MethodHandles.lookup(), target);
this.listeners.addAll(listeners);
}
public void unregisterListeners() {
if (this.listeners.isEmpty()) {
return;
}
BusGroup.DEFAULT.unregister(this.listeners);
this.listeners.clear();
}
// lifecycle
@@ -157,11 +167,11 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
this.loadLatch.countDown();
}
this.forgeEventBus.register(this);
registerListeners(this);
this.plugin.registerEarlyListeners();
}
@SubscribeEvent(priority = EventPriority.HIGHEST)
@SubscribeEvent(priority = Priority.HIGHEST)
public void onServerAboutToStart(ServerAboutToStartEvent event) {
this.server = event.getServer();
try {
@@ -171,10 +181,10 @@ public final class LPForgeBootstrap implements LuckPermsBootstrap, LoaderBootstr
}
}
@SubscribeEvent(priority = EventPriority.LOWEST)
@SubscribeEvent(priority = Priority.LOWEST)
public void onServerStopping(ServerStoppingEvent event) {
this.plugin.disable();
this.forgeEventBus.unregisterAll();
unregisterListeners();
this.server = null;
}
@@ -41,7 +41,6 @@ import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
import me.lucko.luckperms.common.sender.DummyConsoleSender;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.forge.calculator.ForgeCalculatorFactory;
import me.lucko.luckperms.forge.capabilities.UserCapabilityListener;
import me.lucko.luckperms.forge.context.ForgeContextManager;
import me.lucko.luckperms.forge.context.ForgePlayerCalculator;
import me.lucko.luckperms.forge.listeners.ForgeAutoOpListener;
@@ -93,9 +92,6 @@ public class LPForgePlugin extends AbstractLuckPermsPlugin {
ForgePlatformListener platformListener = new ForgePlatformListener(this);
this.bootstrap.registerListeners(platformListener);
UserCapabilityListener userCapabilityListener = new UserCapabilityListener(this);
this.bootstrap.registerListeners(userCapabilityListener);
ForgePermissionHandlerListener permissionHandlerListener = new ForgePermissionHandlerListener(this);
this.bootstrap.registerListeners(permissionHandlerListener);
@@ -1,158 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.forge.capabilities;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.forge.LPForgePlugin;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.util.LazyOptional;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
public class UserCapabilityImpl implements UserCapability {
private static LazyOptional<UserCapability> getCapability(Player player) {
LazyOptional<UserCapability> optional = player.getCapability(CAPABILITY);
if (optional.isPresent()) {
return optional;
}
// if capability is missing, try to restore them before trying again
player.reviveCaps();
return player.getCapability(CAPABILITY);
}
/**
* Gets a {@link UserCapability} for a given {@link ServerPlayer}.
*
* @param player the player
* @return the capability
*/
public static @NotNull UserCapabilityImpl get(@NotNull Player player) {
return (UserCapabilityImpl) getCapability(player).orElseThrow(() -> new IllegalStateException("Capability missing for " + player.getUUID()));
}
/**
* Gets a {@link UserCapability} for a given {@link ServerPlayer}.
*
* @param player the player
* @return the capability, or null
*/
public static @Nullable UserCapabilityImpl getNullable(@NotNull Player player) {
return (UserCapabilityImpl) getCapability(player).resolve().orElse(null);
}
private boolean initialised = false;
private User user;
private QueryOptionsSupplier queryOptionsSupplier;
private String language;
private Locale locale;
public UserCapabilityImpl() {
}
public void initialise(UserCapabilityImpl previous, ServerPlayer player, LPForgePlugin plugin) {
this.user = previous.user;
this.queryOptionsSupplier = plugin.getContextManager().createQueryOptionsSupplier(player);
this.language = previous.language;
this.locale = previous.locale;
this.initialised = true;
}
public void initialise(User user, ServerPlayer player, LPForgePlugin plugin) {
this.user = user;
this.queryOptionsSupplier = plugin.getContextManager().createQueryOptionsSupplier(player);
this.initialised = true;
}
private void assertInitialised() {
if (!this.initialised) {
throw new IllegalStateException("Capability has not been initialised");
}
}
@Override
public Tristate checkPermission(String permission) {
assertInitialised();
if (permission == null) {
throw new NullPointerException("permission");
}
return checkPermission(permission, this.queryOptionsSupplier.getQueryOptions());
}
@Override
public Tristate checkPermission(String permission, QueryOptions queryOptions) {
assertInitialised();
if (permission == null) {
throw new NullPointerException("permission");
}
if (queryOptions == null) {
throw new NullPointerException("queryOptions");
}
PermissionCache cache = this.user.getCachedData().getPermissionData(queryOptions);
return cache.checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
}
public User getUser() {
assertInitialised();
return this.user;
}
@Override
public QueryOptions getQueryOptions() {
return getQueryOptionsSupplier().getQueryOptions();
}
public QueryOptionsSupplier getQueryOptionsSupplier() {
assertInitialised();
return this.queryOptionsSupplier;
}
public Locale getLocale(ServerPlayer player) {
if (this.language == null || !this.language.equals(player.getLanguage())) {
this.language = player.getLanguage();
this.locale = TranslationManager.parseLocale(this.language);
}
return this.locale;
}
}
@@ -1,107 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.forge.capabilities;
import me.lucko.luckperms.forge.LPForgePlugin;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class UserCapabilityListener {
private final LPForgePlugin plugin;
public UserCapabilityListener(LPForgePlugin plugin) {
this.plugin = plugin;
}
@SubscribeEvent
public void onRegisterCapabilities(RegisterCapabilitiesEvent event) {
event.register(UserCapabilityImpl.class);
}
@SubscribeEvent
public void onAttachCapabilities(AttachCapabilitiesEvent<Entity> event) {
if (!(event.getObject() instanceof ServerPlayer)) {
return;
}
event.addCapability(UserCapability.IDENTIFIER, new UserCapabilityProvider(new UserCapabilityImpl()));
}
@SubscribeEvent
public void onPlayerClone(PlayerEvent.Clone event) {
Player previousPlayer = event.getOriginal();
Player currentPlayer = event.getEntity();
if (!(currentPlayer instanceof ServerPlayer)) {
return;
}
previousPlayer.reviveCaps();
try {
UserCapabilityImpl previous = UserCapabilityImpl.get(previousPlayer);
UserCapabilityImpl current = UserCapabilityImpl.get(currentPlayer);
current.initialise(previous, ((ServerPlayer) currentPlayer), this.plugin);
current.getQueryOptionsSupplier().invalidateCache();
} catch (IllegalStateException e) {
// continue on if we cannot copy original data
} finally {
previousPlayer.invalidateCaps();
}
}
private static final class UserCapabilityProvider implements ICapabilityProvider {
private final UserCapabilityImpl userCapability;
private UserCapabilityProvider(UserCapabilityImpl userCapability) {
this.userCapability = userCapability;
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
if (cap != UserCapability.CAPABILITY) {
return LazyOptional.empty();
}
return LazyOptional.of(() -> (T) this.userCapability);
}
}
}
@@ -25,19 +25,15 @@
package me.lucko.luckperms.forge.context;
import me.lucko.luckperms.common.context.manager.DetachedContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.SimpleContextManager;
import me.lucko.luckperms.forge.LPForgePlugin;
import me.lucko.luckperms.forge.capabilities.UserCapabilityImpl;
import net.luckperms.api.query.OptionKey;
import net.luckperms.api.query.QueryOptions;
import net.minecraft.server.level.ServerPlayer;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Objects;
import java.util.UUID;
public class ForgeContextManager extends DetachedContextManager<ServerPlayer, ServerPlayer> {
public class ForgeContextManager extends SimpleContextManager<ServerPlayer, ServerPlayer> {
public static final OptionKey<Boolean> INTEGRATED_SERVER_OWNER = OptionKey.of("integrated_server_owner", Boolean.class);
public ForgeContextManager(LPForgePlugin plugin) {
@@ -49,16 +45,6 @@ public class ForgeContextManager extends DetachedContextManager<ServerPlayer, Se
return player.getUUID();
}
@Override
public @Nullable QueryOptionsSupplier getQueryOptionsSupplier(ServerPlayer subject) {
Objects.requireNonNull(subject, "subject");
UserCapabilityImpl capability = UserCapabilityImpl.getNullable(subject);
if (capability != null) {
return capability.getQueryOptionsSupplier();
}
return null;
}
@Override
public void customizeQueryOptions(ServerPlayer subject, QueryOptions.Builder builder) {
if (subject.getServer() != null && subject.getServer().isSingleplayerOwner(subject.getGameProfile())) {
@@ -42,7 +42,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Set;
@@ -68,7 +68,7 @@ public class ForgePlayerCalculator implements ContextCalculator<ServerPlayer> {
@Override
public void calculate(@NonNull ServerPlayer target, @NonNull ContextConsumer consumer) {
ServerLevel level = target.serverLevel();
ServerLevel level = target.level();
if (this.dimensionType) {
consumer.accept(DefaultContextKeys.DIMENSION_TYPE_KEY, getContextKey(level.dimension().location()));
}
@@ -33,7 +33,6 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener;
import me.lucko.luckperms.forge.ForgeSenderFactory;
import me.lucko.luckperms.forge.LPForgePlugin;
import me.lucko.luckperms.forge.capabilities.UserCapabilityImpl;
import me.lucko.luckperms.forge.util.AsyncConfigurationTask;
import net.kyori.adventure.text.Component;
import net.minecraft.network.Connection;
@@ -45,8 +44,8 @@ import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent;
import net.minecraftforge.event.network.GatherLoginConfigurationTasksEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.listener.Priority;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import java.util.UUID;
@@ -117,7 +116,7 @@ public class ForgeConnectionListener extends AbstractConnectionListener {
}
}
@SubscribeEvent(priority = EventPriority.HIGHEST)
@SubscribeEvent(priority = Priority.HIGHEST)
public void onPlayerLoggedIn(PlayerLoggedInEvent event) {
ServerPlayer player = (ServerPlayer) event.getEntity();
GameProfile profile = player.getGameProfile();
@@ -146,13 +145,10 @@ public class ForgeConnectionListener extends AbstractConnectionListener {
}
}
// initialise capability
UserCapabilityImpl userCapability = UserCapabilityImpl.get(player);
userCapability.initialise(user, player, this.plugin);
this.plugin.getContextManager().signalContextUpdate(player);
}
@SubscribeEvent(priority = EventPriority.LOWEST)
@SubscribeEvent(priority = Priority.LOWEST)
public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) {
ServerPlayer player = (ServerPlayer) event.getEntity();
handleDisconnect(player.getGameProfile().getId());
@@ -38,7 +38,7 @@ import net.minecraft.server.players.ServerOpList;
import net.minecraftforge.event.AddReloadListenerEvent;
import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import java.io.IOException;
import java.util.Locale;
@@ -51,7 +51,7 @@ public class ForgePlatformListener {
}
@SubscribeEvent
public void onCommand(CommandEvent event) {
public boolean onCommand(CommandEvent event) {
CommandContextBuilder<CommandSourceStack> context = event.getParseResults().getContext();
if (!this.plugin.getConfiguration().get(ConfigKeys.OPS_ENABLED)) {
@@ -63,11 +63,12 @@ public class ForgePlatformListener {
String name = node.getNode().getName().toLowerCase(Locale.ROOT);
if (name.equals("op") || name.equals("deop")) {
Message.OP_DISABLED.send(this.plugin.getSenderFactory().wrap(context.getSource()));
event.setCanceled(true);
return;
return true; // cancel
}
}
}
return false; // don't cancel
}
@SubscribeEvent
@@ -32,7 +32,6 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.forge.LPForgeBootstrap;
import me.lucko.luckperms.forge.LPForgePlugin;
import me.lucko.luckperms.forge.capabilities.UserCapabilityImpl;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryMode;
import net.luckperms.api.query.QueryOptions;
@@ -78,12 +77,9 @@ public class ForgePermissionHandler implements IPermissionHandler {
@Override
public <T> T getPermission(ServerPlayer player, PermissionNode<T> node, PermissionDynamicContext<?>... context) {
UserCapabilityImpl capability = UserCapabilityImpl.getNullable(player);
if (capability != null) {
User user = capability.getUser();
QueryOptions queryOptions = capability.getQueryOptionsSupplier().getQueryOptions();
User user = this.plugin.getUserManager().getIfLoaded(player.getUUID());
if (user != null) {
QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player);
T value = getPermissionValue(user, queryOptions, node, context);
if (value != null) {
return value;
@@ -29,7 +29,7 @@ import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.forge.LPForgePlugin;
import net.minecraftforge.common.ForgeConfig;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
import net.minecraftforge.server.permission.events.PermissionGatherEvent;
import net.minecraftforge.server.permission.handler.DefaultPermissionHandler;
import net.minecraftforge.server.permission.nodes.PermissionNode;
@@ -32,8 +32,7 @@ import me.lucko.luckperms.common.graph.Graph;
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.forge.LPForgePlugin;
import me.lucko.luckperms.forge.capabilities.UserCapability;
import me.lucko.luckperms.forge.capabilities.UserCapabilityImpl;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerPlayer;
@@ -140,22 +139,15 @@ public final class BrigadierInjector {
@Override
public boolean test(CommandSourceStack source) {
if (source.getEntity() instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) source.getEntity();
Tristate state = Tristate.UNDEFINED;
// If player is still connecting and has not been added to world then check LP user directly
if (!player.isAddedToWorld()) {
User user = this.plugin.getUserManager().getIfLoaded(player.getUUID());
if (user == null) {
// Should never happen but just in case...
return false;
}
state = user.getCachedData().getPermissionData().checkPermission(permission);
} else {
UserCapability user = UserCapabilityImpl.get(player);
state = user.checkPermission(this.permission);
if (source.getEntity() instanceof ServerPlayer player) {
User user = this.plugin.getUserManager().getIfLoaded(player.getUUID());
if (user == null) {
return false;
}
QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player);
Tristate state = user.getCachedData().getPermissionData(queryOptions).checkPermission(this.permission);
if (state != Tristate.UNDEFINED) {
return state.asBoolean() && this.delegate.test(source.withPermission(4));
}
@@ -1,264 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.forge.util;
import me.lucko.luckperms.common.loader.JarInJarClassLoader;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.GenericEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.IGenericEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import java.lang.invoke.CallSite;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* A utility for registering Forge listeners for methods in a jar-in-jar.
*
* <p>This differs from {@link IEventBus#register} as reflection is used for invoking the registered listeners
* instead of ASM, which is incompatible with {@link JarInJarClassLoader}</p>
*/
public class ForgeEventBusFacade {
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
private final List<ListenerRegistration> listeners = new ArrayList<>();
/**
* Register listeners for all methods annotated with {@link SubscribeEvent} on the target object.
*/
public void register(Object target) {
for (Method method : target.getClass().getMethods()) {
// Ignore static methods, Support for these could be added, but they are not used in LuckPerms
if (Modifier.isStatic(method.getModifiers())) {
continue;
}
// Methods require a SubscribeEvent annotation in order to be registered
SubscribeEvent subscribeEvent = method.getAnnotation(SubscribeEvent.class);
if (subscribeEvent == null) {
continue;
}
EventType type = determineListenerType(method);
Consumer<?> invoker = createInvokerFunction(method, target, type);
// Determine the 'IEventBus' that this eventType should be registered to.
IEventBus eventBus;
if (IModBusEvent.class.isAssignableFrom(type.eventType)) {
eventBus = FMLJavaModLoadingContext.get().getModEventBus();
} else {
eventBus = MinecraftForge.EVENT_BUS;
}
if (IGenericEvent.class.isAssignableFrom(type.eventType)) {
addGenericListener(eventBus, type.genericType, subscribeEvent, type.eventType, invoker);
} else {
addListener(eventBus, subscribeEvent, type.eventType, invoker);
}
this.listeners.add(new ListenerRegistration(invoker, eventBus, target));
}
}
/**
* Unregister previously registered listeners on the target object.
*
* @param target the target listener
*/
public void unregister(Object target) {
this.listeners.removeIf(listener -> {
if (listener.target == target) {
listener.close();
return true;
} else {
return false;
}
});
}
/**
* Unregister all listeners created through this interface.
*/
public void unregisterAll() {
for (ListenerRegistration listener : this.listeners) {
listener.close();
}
this.listeners.clear();
}
/**
* A listener registration.
*/
private static final class ListenerRegistration implements AutoCloseable {
/** The lambda invoker function */
private final Consumer<?> invoker;
/** The event bus that the invoker was registered to */
private final IEventBus eventBus;
/** The target listener class */
private final Object target;
private ListenerRegistration(Consumer<?> invoker, IEventBus eventBus, Object target) {
this.invoker = invoker;
this.eventBus = eventBus;
this.target = target;
}
@Override
public void close() {
this.eventBus.unregister(this.invoker);
}
}
private static Consumer<?> createInvokerFunction(Method method, Object target, EventType type) {
// Use the 'LambdaMetafactory' to generate a consumer which can be passed directly to an 'IEventBus'
// when registering a listener, this reduces the overhead involved when reflectively invoking methods.
try {
MethodHandle methodHandle = LOOKUP.unreflect(method);
CallSite callSite = LambdaMetafactory.metafactory(
LOOKUP,
"accept",
MethodType.methodType(Consumer.class, target.getClass()),
MethodType.methodType(void.class, Object.class),
methodHandle,
MethodType.methodType(void.class, type.eventType)
);
return (Consumer<?>) callSite.getTarget().bindTo(target).invokeExact();
} catch (Throwable t) {
throw new RuntimeException("Error whilst registering " + method, t);
}
}
public static EventType determineListenerType(Method method) {
// Get the parameter types, this includes generic information which is required for GenericEvent
Type[] parameterTypes = method.getGenericParameterTypes();
if (parameterTypes.length != 1) {
throw new IllegalArgumentException(""
+ "Method " + method + " has @SubscribeEvent annotation. "
+ "It has " + parameterTypes.length + " arguments, "
+ "but event handler methods require a single argument only."
);
}
Type parameterType = parameterTypes[0];
Class<?> eventType;
Class<?> genericType;
if (parameterType instanceof Class) { // Non-generic event
eventType = (Class<?>) parameterType;
genericType = null;
} else if (parameterType instanceof ParameterizedType) { // Generic event
ParameterizedType parameterizedType = (ParameterizedType) parameterType;
// Get the event class
Type rawType = parameterizedType.getRawType();
if (rawType instanceof Class) {
eventType = (Class<?>) rawType;
} else {
throw new UnsupportedOperationException("Raw Type " + rawType.getClass() + " is not supported");
}
// Find the type of 'T' in 'GenericEvent<T>'
Type[] typeArguments = parameterizedType.getActualTypeArguments();
if (typeArguments.length != 1) {
throw new IllegalArgumentException(""
+ "Method " + method + " has @SubscribeEvent annotation. "
+ "It has a " + eventType + " argument, "
+ "but generic events require a single type argument only."
);
}
// Get the generic class
Type typeArgument = typeArguments[0];
if (typeArgument instanceof Class<?>) {
genericType = (Class<?>) typeArgument;
} else {
throw new UnsupportedOperationException("Type Argument " + typeArgument.getClass() + " is not supported");
}
} else {
throw new UnsupportedOperationException("Parameter Type " + parameterType.getClass() + " is not supported");
}
// Ensure 'genericType' is set if 'eventType' is a generic event
if (GenericEvent.class.isAssignableFrom(eventType) && genericType == null) {
throw new IllegalArgumentException(""
+ "Method " + method + " has @SubscribeEvent annotation, "
+ "but the generic argument type cannot be determined for "
+ "for the GenericEvent subtype: " + eventType
);
}
// Ensure 'eventType' is a subclass of event
if (!Event.class.isAssignableFrom(eventType)) {
throw new IllegalArgumentException(""
+ "Method " + method + " has @SubscribeEvent annotation, "
+ "but takes an argument that is not an Event subtype: " + eventType
);
}
return new EventType(eventType, genericType);
}
private static final class EventType {
private final Class<?> eventType;
private final Class<?> genericType;
private EventType(Class<?> eventType, Class<?> genericType) {
this.eventType = eventType;
this.genericType = genericType;
}
}
/**
* Handles casting generics for {@link IEventBus#addGenericListener}.
*/
@SuppressWarnings("unchecked")
private static <T extends GenericEvent<? extends F>, F> void addGenericListener(IEventBus eventBus, Class<?> genericClassFilter, SubscribeEvent annotation, Class<?> eventType, Consumer<?> consumer) {
eventBus.addGenericListener((Class<F>) genericClassFilter, annotation.priority(), annotation.receiveCanceled(), (Class<T>) eventType, (Consumer<T>) consumer);
}
/**
* Handles casting generics for {@link IEventBus#addListener}.
*/
@SuppressWarnings("unchecked")
private static <T extends Event> void addListener(IEventBus eventBus, SubscribeEvent annotation, Class<?> eventType, Consumer<?> consumer) {
eventBus.addListener(annotation.priority(), annotation.receiveCanceled(), (Class<T>) eventType, (Consumer<T>) consumer);
}
}
+1 -1
View File
@@ -652,7 +652,7 @@ resolve-command-selectors = false
commands-read-only-mode {
players = false
console = false
}
# If LuckPerms commands should be disabled. When true, this will prevent all LP commands from being
# executed. In a sense this is a more extreme version of read-only mode (see above).
+3 -3
View File
@@ -1,9 +1,9 @@
[versions]
shadow = "8.3.0"
shadow = "8.3.8"
blossom = "1.3.1"
moddevgradle = "2.0.78"
moddevgradle = "2.0.103"
forgegradle = "[6.0,6.2)"
loom = "1.10-SNAPSHOT"
loom = "1.11-SNAPSHOT"
licenser = "0.6.1"
[plugins]
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+3 -3
View File
@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -205,7 +205,7 @@ fi
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,
# * DEFAULT_JVM_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.
@@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
Vendored
+2 -2
View File
@@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
-62
View File
@@ -1,62 +0,0 @@
plugins {
alias(libs.plugins.blossom)
alias(libs.plugins.shadow)
alias(libs.plugins.moddevgradle)
}
sourceCompatibility = 17
targetCompatibility = 21
Configuration shade = configurations.create('shade')
configurations.implementation {
extendsFrom configurations.shade
}
blossom {
replaceTokenIn 'src/main/java/me/lucko/luckperms/neoforge/LPNeoForgeBootstrap.java'
replaceToken '@version@', project.ext.fullVersion
}
neoForge {
version = project.neoForgeVersion
validateAccessTransformers = true
}
dependencies {
add('shade', project(':common'))
compileOnly project(':common:loader-utils')
}
shadowJar {
archiveFileName = "luckperms-neoforge.jarinjar"
configurations = [shade]
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
relocate 'org.yaml.snakeyaml', 'me.lucko.luckperms.lib.yaml'
}
artifacts {
archives shadowJar
}
+2 -2
View File
@@ -1,2 +1,2 @@
minecraftVersion=1.21.5
neoForgeVersion=21.5.63-beta
minecraftVersion=1.21.8
neoForgeVersion=21.8.4-beta
-92
View File
@@ -1,92 +0,0 @@
import net.neoforged.moddevgradle.internal.RunGameTask
import java.nio.file.Files
import java.nio.file.StandardCopyOption
plugins {
alias(libs.plugins.shadow)
alias(libs.plugins.moddevgradle)
id("java-library")
}
sourceCompatibility = 17
targetCompatibility = 21
neoForge {
version = project.neoForgeVersion
validateAccessTransformers = true
runs {
client {
client()
//mods.set(new HashSet()) // Work around classpath issues by using the production jar for dev runs
}
server {
server()
//mods.set(new HashSet()) // Work around classpath issues by using the production jar for dev runs
}
}
}
// Work around classpath issues by using the production jar for dev runs
tasks.withType(RunGameTask).configureEach {
dependsOn(tasks.shadowJar)
doFirst {
File jar = file("run/mods/main.jar")
jar.parentFile.mkdirs()
Files.copy(tasks.shadowJar.archiveFile.get().asFile.toPath(), jar.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
}
Configuration shade = configurations.create('shade')
configurations.implementation {
extendsFrom configurations.shade
}
dependencies {
add('shade', project(':api'))
add('shade', project(':common:loader-utils'))
}
build {
dependsOn(":neoforge:build")
}
jar {
manifest {
attributes(
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'Implementation-Title': 'LuckPerms',
'Implementation-Vendor': 'LuckPerms',
'Implementation-Version': project.ext.fullVersion,
'Specification-Title': 'luckperms',
'Specification-Vendor': 'LuckPerms',
'Specification-Version': '1'
)
}
}
processResources {
filesMatching('META-INF/neoforge.mods.toml') {
expand 'version': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-NeoForge-${project.ext.fullVersion}.jar"
configurations = [shade]
from {
project(':neoforge').tasks.shadowJar.archiveFile
}
dependencies {
include(dependency('net.luckperms:.*'))
include(dependency('me.lucko.luckperms:.*'))
}
}
artifacts {
archives shadowJar
}
@@ -26,6 +26,7 @@
package me.lucko.luckperms.neoforge;
import com.mojang.brigadier.ParseResults;
import com.mojang.serialization.JsonOps;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
@@ -41,7 +42,7 @@ import net.luckperms.api.util.Tristate;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.chat.Component.Serializer;
import net.minecraft.network.chat.ComponentSerialization;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.rcon.RconConsoleSource;
import net.minecraft.world.entity.player.Player;
@@ -116,7 +117,10 @@ public class NeoForgeSenderFactory extends SenderFactory<LPNeoForgePlugin, Comma
}
public static net.minecraft.network.chat.Component toNativeText(Component component) {
return Serializer.fromJson(GsonComponentSerializer.gson().serializeToTree(component), RegistryAccess.EMPTY);
return ComponentSerialization.CODEC.decode(
RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE),
GsonComponentSerializer.gson().serializeToTree(component)
).getOrThrow(IllegalArgumentException::new).getFirst();
}
}
@@ -68,7 +68,7 @@ public class NeoForgePlayerCalculator implements ContextCalculator<ServerPlayer>
@Override
public void calculate(@NonNull ServerPlayer target, @NonNull ContextConsumer consumer) {
ServerLevel level = target.serverLevel();
ServerLevel level = target.level();
if (this.dimensionType) {
consumer.accept(DefaultContextKeys.DIMENSION_TYPE_KEY, getContextKey(level.dimension().location()));
}
+1 -1
View File
@@ -652,7 +652,7 @@ resolve-command-selectors = false
commands-read-only-mode {
players = false
console = false
}
# If LuckPerms commands should be disabled. When true, this will prevent all LP commands from being
# executed. In a sense this is a more extreme version of read-only mode (see above).
-45
View File
@@ -1,45 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
repositories {
maven { url 'https://repo.opencollab.dev/main/' }
}
dependencies {
implementation project(':common')
compileOnly project(':common:loader-utils')
compileOnly 'cn.nukkit:nukkit:1.0-SNAPSHOT'
}
shadowJar {
archiveFileName = 'luckperms-nukkit.jarinjar'
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
}
artifacts {
archives shadowJar
}
-32
View File
@@ -1,32 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
repositories {
maven { url 'https://repo.opencollab.dev/main/' }
}
dependencies {
compileOnly 'cn.nukkit:nukkit:1.0-SNAPSHOT'
implementation project(':api')
implementation project(':common:loader-utils')
}
processResources {
filesMatching('plugin.yml') {
expand 'pluginVersion': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-Nukkit-${project.ext.fullVersion}.jar"
from {
project(':nukkit').tasks.shadowJar.archiveFile
}
}
artifacts {
archives shadowJar
}
-46
View File
@@ -1,46 +0,0 @@
pluginManagement {
repositories {
gradlePluginPortal()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
maven {
name = 'Forge'
url = 'https://maven.minecraftforge.net/'
}
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0")
}
rootProject.name = 'luckperms'
include (
'api',
'common',
'common:loader-utils',
'bukkit',
'bukkit:loader',
'bukkit-legacy',
'bukkit-legacy:loader',
'bungee',
'bungee:loader',
'fabric',
'neoforge',
'neoforge:loader',
'forge',
'forge:loader',
'forge:forge-api',
'nukkit',
'nukkit:loader',
'sponge',
'sponge:loader',
'sponge:sponge-service',
'sponge:sponge-service-proxy',
'velocity',
'standalone',
'standalone:loader',
'standalone:app'
)
+7
View File
@@ -0,0 +1,7 @@
rootProject.name = "LuckPerms-OG"
include(":api", ":common", ":common:loader-utils", ":bukkit", ":bukkit:loader")
project(":common:loader-utils").projectDir = file("common/loader-utils")
project(":bukkit:loader").projectDir = file("bukkit/loader")
-62
View File
@@ -1,62 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
sourceCompatibility = 17
targetCompatibility = 21
repositories {
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}
dependencies {
implementation project(':common')
implementation project(':sponge:sponge-service')
implementation project(':sponge:sponge-service-proxy')
compileOnly project(':common:loader-utils')
compileOnly('org.spongepowered:spongeapi:12.0.0') {
exclude(module: 'configurate-core')
exclude(module: 'configurate-hocon')
exclude(module: 'configurate-gson')
exclude(module: 'configurate-yaml')
}
compileOnly 'com.google.guava:guava:33.3.1-jre'
}
processResources {
filesMatching('META-INF/sponge_plugins.json') {
expand 'pluginVersion': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = 'luckperms-sponge.jarinjar'
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
//relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
}
artifacts {
archives shadowJar
}
-35
View File
@@ -1,35 +0,0 @@
plugins {
alias(libs.plugins.shadow)
}
sourceCompatibility = 17
targetCompatibility = 21
repositories {
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}
dependencies {
compileOnly 'org.spongepowered:spongeapi:12.0.0'
implementation project(':api')
implementation project(':common:loader-utils')
}
processResources {
filesMatching('META-INF/sponge_plugins.json') {
expand 'pluginVersion': project.ext.fullVersion
}
}
shadowJar {
archiveFileName = "LuckPerms-Sponge-${project.ext.fullVersion}.jar"
from {
project(':sponge').tasks.shadowJar.archiveFile
}
}
artifacts {
archives shadowJar
}
-18
View File
@@ -1,18 +0,0 @@
repositories {
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}
sourceCompatibility = 17
targetCompatibility = 21
dependencies {
implementation project(':common')
implementation project(':sponge:sponge-service')
compileOnly('org.spongepowered:spongeapi:12.0.0') {
exclude(module: 'configurate-core')
exclude(module: 'configurate-hocon')
exclude(module: 'configurate-gson')
exclude(module: 'configurate-yaml')
}
}
-18
View File
@@ -1,18 +0,0 @@
repositories {
maven { url 'https://repo.spongepowered.org/repository/maven-public/' }
}
sourceCompatibility = 17
targetCompatibility = 21
dependencies {
implementation project(':common')
compileOnly('org.spongepowered:spongeapi:12.0.0') {
exclude(module: 'configurate-core')
exclude(module: 'configurate-hocon')
exclude(module: 'configurate-gson')
exclude(module: 'configurate-yaml')
}
}
@@ -31,16 +31,13 @@ import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.filter.IsCancelled;
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
import org.spongepowered.api.profile.GameProfile;
import org.spongepowered.api.util.Identifiable;
import org.spongepowered.api.util.Tristate;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
@@ -31,12 +31,8 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
import net.luckperms.api.messenger.IncomingMessageConsumer;
import net.luckperms.api.messenger.Messenger;
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.Server;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.network.EngineConnectionSide;
import org.spongepowered.api.network.EngineConnectionState;
import org.spongepowered.api.network.ServerConnectionState;
import org.spongepowered.api.network.ServerSideConnection;
import org.spongepowered.api.network.channel.ChannelBuf;
import org.spongepowered.api.network.channel.raw.RawDataChannel;
import org.spongepowered.api.network.channel.raw.play.RawPlayDataHandler;
+1 -1
View File
@@ -650,7 +650,7 @@ resolve-command-selectors = false
commands-read-only-mode {
players = false
console = false
}
# If LuckPerms commands should be disabled. When true, this will prevent all LP commands from being
# executed. In a sense this is a more extreme version of read-only mode (see above).
-56
View File
@@ -1,56 +0,0 @@
plugins {
alias(libs.plugins.blossom)
id("java-library")
}
sourceCompatibility = 17
targetCompatibility = 17
dependencies {
implementation project(':api')
api 'org.apache.logging.log4j:log4j-core:2.17.2'
api 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.2'
api 'net.minecrell:terminalconsoleappender:1.3.0'
api 'org.jline:jline-terminal-jansi:3.20.0'
api 'com.google.code.gson:gson:2.9.0'
api 'com.google.guava:guava:31.1-jre'
api 'io.netty:netty-all:4.1.93.Final'
api('net.kyori:adventure-api:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'checker-qual')
exclude(module: 'annotations')
}
api('net.kyori:adventure-text-serializer-gson:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
exclude(module: 'gson')
}
api('net.kyori:adventure-text-serializer-legacy:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
api('net.kyori:adventure-text-serializer-plain:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
api('net.kyori:adventure-text-minimessage:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
}
api('net.kyori:adventure-text-serializer-ansi:4.21.0') {
exclude(module: 'adventure-bom')
exclude(module: 'adventure-api')
exclude(module: 'annotations')
}
api('net.kyori:ansi:1.1.1') {
exclude(module: 'annotations')
}
}
blossom {
replaceTokenIn('src/main/java/me/lucko/luckperms/standalone/app/LuckPermsApplication.java')
replaceToken '@version@', project.ext.fullVersion
}
-86
View File
@@ -1,86 +0,0 @@
plugins {
alias(libs.plugins.shadow)
id("jacoco")
id("jacoco-report-aggregation")
}
sourceCompatibility = 17
targetCompatibility = 17
test {
useJUnitPlatform {
if (!project.hasProperty('dockerTests')) {
excludeTags 'docker'
}
}
systemProperty('net.kyori.ansi.colorLevel', 'indexed16')
}
jacocoTestReport {
dependsOn test
}
dependencies {
implementation project(':common')
compileOnly project(':common:loader-utils')
compileOnly project(':standalone:app')
compileOnly 'org.spongepowered:configurate-yaml:3.7.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1'
testImplementation "org.testcontainers:junit-jupiter:1.18.3"
testImplementation 'org.mockito:mockito-core:4.11.0'
testImplementation 'org.mockito:mockito-junit-jupiter:4.11.0'
testImplementation 'org.awaitility:awaitility:4.2.0'
testImplementation 'com.zaxxer:HikariCP:4.0.3'
testImplementation 'redis.clients:jedis:4.4.3'
testImplementation 'io.nats:jnats:2.16.4'
testImplementation 'com.rabbitmq:amqp-client:5.12.0'
testImplementation 'org.postgresql:postgresql:42.6.0'
testImplementation 'com.h2database:h2:2.1.214'
testImplementation 'org.xerial:sqlite-jdbc:3.42.0.0'
testImplementation 'mysql:mysql-connector-java:8.0.23'
testImplementation 'org.mariadb.jdbc:mariadb-java-client:3.1.3'
testImplementation 'org.mongodb:mongodb-driver-legacy:4.5.0'
testImplementation 'me.lucko.configurate:configurate-toml:3.7'
testImplementation 'org.spongepowered:configurate-hocon:3.7.2'
testImplementation 'org.yaml:snakeyaml:1.28'
testImplementation 'net.luckperms:rest-api-java-client:0.1-SNAPSHOT'
testImplementation project(':standalone:app')
testImplementation project(':common:loader-utils')
}
shadowJar {
archiveFileName = 'luckperms-standalone.jarinjar'
dependencies {
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
relocate 'org.yaml.snakeyaml', 'me.lucko.luckperms.lib.yaml'
}
artifacts {
archives shadowJar
}
-37
View File
@@ -1,37 +0,0 @@
import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
plugins {
alias(libs.plugins.shadow)
id("application")
}
dependencies {
implementation project(':api')
implementation project(':common:loader-utils')
implementation project(':standalone:app')
}
sourceCompatibility = 17
targetCompatibility = 17
application {
mainClass = 'me.lucko.luckperms.standalone.loader.StandaloneLoader'
}
processResources {
include '*.xml'
}
shadowJar {
archiveFileName = "LuckPerms-Standalone-${project.ext.fullVersion}.jar"
from {
project(':standalone').tasks.shadowJar.archiveFile
}
transform(Log4j2PluginsCacheFileTransformer)
}
artifacts {
archives shadowJar
}
-53
View File
@@ -1,53 +0,0 @@
plugins {
alias(libs.plugins.blossom)
alias(libs.plugins.shadow)
}
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
dependencies {
implementation project(':common')
compileOnly 'com.velocitypowered:velocity-api:3.1.1'
annotationProcessor 'com.velocitypowered:velocity-api:3.1.1'
}
blossom {
replaceTokenIn('src/main/java/me/lucko/luckperms/velocity/LPVelocityBootstrap.java')
replaceToken '@version@', project.ext.fullVersion
}
shadowJar {
archiveFileName = "LuckPerms-Velocity-${project.ext.fullVersion}.jar"
dependencies {
include(dependency('net.luckperms:.*'))
include(dependency('me.lucko.luckperms:.*'))
}
relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure'
relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus'
relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine'
relocate 'okio', 'me.lucko.luckperms.lib.okio'
relocate 'okhttp3', 'me.lucko.luckperms.lib.okhttp3'
relocate 'net.bytebuddy', 'me.lucko.luckperms.lib.bytebuddy'
relocate 'me.lucko.commodore', 'me.lucko.luckperms.lib.commodore'
relocate 'org.mariadb.jdbc', 'me.lucko.luckperms.lib.mariadb'
relocate 'com.mysql', 'me.lucko.luckperms.lib.mysql'
relocate 'org.postgresql', 'me.lucko.luckperms.lib.postgresql'
relocate 'com.zaxxer.hikari', 'me.lucko.luckperms.lib.hikari'
relocate 'com.mongodb', 'me.lucko.luckperms.lib.mongodb'
relocate 'org.bson', 'me.lucko.luckperms.lib.bson'
relocate 'redis.clients.jedis', 'me.lucko.luckperms.lib.jedis'
relocate 'io.nats.client', 'me.lucko.luckperms.lib.nats'
relocate 'com.rabbitmq', 'me.lucko.luckperms.lib.rabbitmq'
relocate 'org.apache.commons.pool2', 'me.lucko.luckperms.lib.commonspool2'
relocate 'ninja.leaping.configurate', 'me.lucko.luckperms.lib.configurate'
relocate 'org.yaml.snakeyaml', 'me.lucko.luckperms.lib.yaml'
}
artifacts {
archives shadowJar
}