Maven -> Gradle 8.14.3

This commit is contained in:
NotAlexNoyle committed 2025-08-30 13:32:23 -04:00
1 parent dbcc843a90
commit 95132bf66e
42 files changed
+2683 -895

No files matched your search

+4 -13
View File
@@ -1,19 +1,10 @@
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://maven.apache.org/wrapper/#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# Gradle
build/
.gradle/
# Eclipse m2e generated files
# Eclipse Core
.project
.settings/
# JDT-specific (Eclipse Java Development Tools)
.classpath
-19
View File
@@ -1,19 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
-94
View File
@@ -1,94 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vanillage.libs</groupId>
<artifactId>libs</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Libs</name>
<description>Libs.</description>
<properties>
<minecraftVersion>1.19.4</minecraftVersion>
<paperVersion>${minecraftVersion}-R0.1-SNAPSHOT</paperVersion>
</properties>
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>unpack</id>
<phase>initialize</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>io.papermc.paper</groupId>
<artifactId>dev-bundle</artifactId>
<version>${paperVersion}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>exec</id>
<phase>initialize</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Dpaperclip.patchonly=true</argument>
<argument>-jar</argument>
<argument>${project.build.directory}/data/paperclip-mojang+yarn.jar</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>install-file</id>
<phase>initialize</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>${basedir}/versions/${minecraftVersion}/paper-${minecraftVersion}.jar</file>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-server</artifactId>
<version>${paperVersion}</version>
<classifier>mojang-mapped</classifier>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
-148
View File
@@ -1,148 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vanillage.raytraceantixray</groupId>
<artifactId>raytraceantixray-parent</artifactId>
<version>1.10.8</version>
</parent>
<artifactId>RayTraceAntiXray</artifactId>
<name>RayTraceAntiXray</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>minecraft-libraries</id>
<url>https://libraries.minecraft.net/</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>Fabric</id>
<url>https://maven.fabricmc.net/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>${paperVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-mojangapi</artifactId>
<version>${paperVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-server</artifactId>
<version>${paperVersion}</version>
<classifier>mojang-mapped</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>datafixerupper</artifactId>
<version>6.0.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.87.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<classifier>mojang-mapped</classifier>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>java</id>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>net.fabricmc</groupId>
<artifactId>tiny-remapper</artifactId>
</executableDependency>
<mainClass>net.fabricmc.tinyremapper.Main</mainClass>
<arguments>
<argument>${project.build.directory}/${project.build.finalName}-mojang-mapped.jar</argument>
<argument>${project.build.directory}/${project.build.finalName}.jar</argument>
<argument>${basedir}/../Libs/target/data/mojang+yarn-spigot-reobf.tiny</argument>
<argument>mojang+yarn</argument>
<argument>spigot</argument>
<argument>${basedir}/../Libs/versions/${minecraftVersion}/paper-${minecraftVersion}.jar</argument>
</arguments>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>net.fabricmc</groupId>
<artifactId>tiny-remapper</artifactId>
<version>0.8.6</version>
<classifier>fat</classifier>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<copy
file="target/RayTraceAntiXray-${project.version}.jar"
todir="../target"
overwrite="true"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
+200
View File
@@ -0,0 +1,200 @@
/* This is free and unencumbered software released into the public domain */
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.6" // Import Shadow plugin.
id("checkstyle") // Import Checkstyle plugin.
eclipse // Import Eclipse plugin.
kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin.
id("maven-publish")
}
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 = "com.vanillage.raytraceantixray" // Declare bundle identifier.
version = "1.10.8" // Declare plugin version (will be in .jar).
val apiVersion = "1.19" // Declare minecraft server target version.
val minecraftVersion = "1.19.4"
val paperVersion = "${minecraftVersion}-R0.1-SNAPSHOT"
/* ----------------------------- 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 {
mavenCentral() // Import the Maven Central Maven Repository.
gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository.
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
maven { url = uri("https://repo.papermc.io/repository/maven-public/") }
maven { url = uri("https://libraries.minecraft.net/") }
maven { url = uri("https://repo.dmulloy2.net/repository/public/") }
maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") }
System.getProperty("SELF_MAVEN_LOCAL_REPO")?.let { // TrueOG Bootstrap mavenLocal().
val dir = file(it)
if (dir.isDirectory) {
println("Using SELF_MAVEN_LOCAL_REPO at: $it")
maven { url = uri("file://${dir.absolutePath}") }
} else {
logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()")
mavenLocal()
}
} ?: logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()")
}
/* ---------------------- Dev-bundle prepare --------------------------- */
val devBundle by configurations.creating
dependencies { add("devBundle", "io.papermc.paper:dev-bundle:${paperVersion}@zip") }
val devBundleDir = layout.buildDirectory.dir("paper-dev-bundle")
val unpackDevBundle by
tasks.registering(Copy::class) {
from({ zipTree(devBundle.singleFile) })
into(devBundleDir)
}
val patchPaper by
tasks.registering(Exec::class) {
dependsOn(unpackDevBundle)
doFirst {
workingDir = devBundleDir.get().asFile
commandLine(
"java",
"-Dpaperclip.patchonly=true",
"-jar",
devBundleDir.get().file("data/paperclip-mojang+yarn.jar").asFile.absolutePath,
)
}
}
val mojangMappedPaperJar = devBundleDir.map { it.file("versions/${minecraftVersion}/paper-${minecraftVersion}.jar") }
/* ---------------------- Java project deps ---------------------------- */
dependencies {
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
compileOnly("io.papermc.paper:paper-api:${paperVersion}")
compileOnly("io.papermc.paper:paper-mojangapi:${paperVersion}")
add("compileOnly", files(mojangMappedPaperJar).builtBy(patchPaper))
compileOnly("com.mojang:datafixerupper:6.0.6")
compileOnly("io.netty:netty-all:4.1.87.Final")
compileOnly(files("libs/ProtocolLib-5.0.jar")) // Import Legacy ProtocolLib API.
}
/* ---------------------- Reproducible jars ---------------------------- */
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
/* ----------------------------- Shadow -------------------------------- */
tasks.shadowJar {
exclude("io.github.miniplaceholders.*") // Exclude the MiniPlaceholders package from being shadowed.
archiveClassifier.set("shadow") // Use empty string instead of null.
minimize()
}
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
/* --------------------------- Tiny Remapper --------------------------- */
val tinyRemapper by configurations.creating
dependencies { add("tinyRemapper", "net.fabricmc:tiny-remapper:0.8.6:fat") }
val mojangMappedJar by
tasks.registering(Jar::class) {
dependsOn(patchPaper)
from(sourceSets.main.get().output)
archiveClassifier.set("mojang-mapped")
}
val remappedJar = layout.buildDirectory.file("libs/${project.name}-${project.version}.jar")
val tinyRemapJar by
tasks.registering(JavaExec::class) {
dependsOn(mojangMappedJar, patchPaper)
mainClass.set("net.fabricmc.tinyremapper.Main")
classpath = tinyRemapper
val input = mojangMappedJar.flatMap { it.archiveFile }
val mappings = devBundleDir.map { it.file("data/mojang+yarn-spigot-reobf.tiny") }
val paperJar = mojangMappedPaperJar
args(
input.get().asFile.absolutePath,
remappedJar.get().asFile.absolutePath,
mappings.get().asFile.absolutePath,
"mojang+yarn",
"spigot",
paperJar.get().asFile.absolutePath,
)
}
val copyJarToTarget by
tasks.registering(Copy::class) {
dependsOn(tinyRemapJar)
from(remappedJar)
into(layout.projectDirectory.dir("target"))
}
/* --------------------------- Build wiring ---------------------------- */
tasks.build { dependsOn(tasks.spotlessApply, tinyRemapJar, copyJarToTarget) } // 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.
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach { dependsOn(patchPaper) }
/* ----------------------------- 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.
}
-3
View File
@@ -1,3 +0,0 @@
cd "%~dp0"
call mvn clean package
PAUSE
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
cd "${0%/*}"
mvn clean package
read -n1 -r -p 'Press any key to continue . . . ' key
-3
View File
@@ -1,3 +0,0 @@
cd "%~dp0"
call mvnw.cmd clean package
PAUSE
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
cd "${0%/*}"
./mvnw clean package
read -n1 -r -p 'Press any key to continue . . . ' key
+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>
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+251
View File
@@ -0,0 +1,251 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+94
View File
@@ -0,0 +1,94 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%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
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
Binary file not shown.
Vendored
-259
View File
@@ -1,259 +0,0 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"
Vendored
-149
View File
@@ -1,149 +0,0 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.2
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
if ($env:MAVEN_USER_HOME) {
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
}
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
-17
View File
@@ -1,17 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vanillage.raytraceantixray</groupId>
<artifactId>raytraceantixray-parent</artifactId>
<version>1.10.8</version>
<packaging>pom</packaging>
<name>RayTraceAntiXray-Parent</name>
<description>Paper plugin for server-side async multithreaded ray tracing to hide ores that are exposed to air using Paper Anti-Xray engine-mode 1.</description>
<modules>
<module>Libs</module>
<module>RayTraceAntiXray</module>
</modules>
<properties>
<minecraftVersion>1.19.4</minecraftVersion>
<paperVersion>${minecraftVersion}-R0.1-SNAPSHOT</paperVersion>
</properties>
</project>
+1
View File
@@ -0,0 +1 @@
rootProject.name = "RayTraceAntiXray"
@@ -38,17 +38,22 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
public final class RayTraceAntiXray extends JavaPlugin {
private volatile boolean running = false;
private volatile boolean timingsEnabled = false;
private final Map<ClientboundLevelChunkWithLightPacket, ChunkBlocks> packetChunkBlocksCache = new MapMaker().weakKeys().makeMap();
private final Map<ClientboundLevelChunkWithLightPacket, ChunkBlocks> packetChunkBlocksCache = new MapMaker()
.weakKeys().makeMap();
private final Map<UUID, PlayerData> playerData = new ConcurrentHashMap<>();
private ExecutorService executorService;
private Timer timer;
@Override
public void onEnable() {
if (!new File(getDataFolder(), "README.txt").exists()) {
saveResource("README.txt", false);
}
saveDefaultConfig();
@@ -56,10 +61,13 @@ public final class RayTraceAntiXray extends JavaPlugin {
// saveConfig();
// Initialize stuff.
running = true;
executorService = Executors.newFixedThreadPool(Math.max(getConfig().getInt("settings.anti-xray.ray-trace-threads"), 1));
executorService = Executors
.newFixedThreadPool(Math.max(getConfig().getInt("settings.anti-xray.ray-trace-threads"), 1));
timer = new Timer(true);
timer.schedule(new RayTraceTimerTask(this), 0L, Math.max(getConfig().getLong("settings.anti-xray.ms-per-ray-trace-tick"), 1L));
new UpdateBukkitRunnable(this).runTaskTimer(this, 0L, Math.max(getConfig().getLong("settings.anti-xray.update-ticks"), 1L));
timer.schedule(new RayTraceTimerTask(this), 0L,
Math.max(getConfig().getLong("settings.anti-xray.ms-per-ray-trace-tick"), 1L));
new UpdateBukkitRunnable(this).runTaskTimer(this, 0L,
Math.max(getConfig().getLong("settings.anti-xray.update-ticks"), 1L));
// Register events.
getServer().getPluginManager().registerEvents(new WorldListener(this), this);
getServer().getPluginManager().registerEvents(new PlayerListener(this), this);
@@ -67,10 +75,12 @@ public final class RayTraceAntiXray extends JavaPlugin {
// registerCommands();
getCommand("raytraceantixray").setExecutor(new RayTraceAntiXrayTabExecutor(this));
getLogger().info(getDescription().getFullName() + " enabled");
}
@Override
public void onDisable() {
// unregisterCommands();
// Cleanup stuff.
ProtocolLibrary.getProtocolManager().removePacketListeners(this);
@@ -79,79 +89,111 @@ public final class RayTraceAntiXray extends JavaPlugin {
executorService.shutdownNow();
try {
executorService.awaitTermination(1000L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
packetChunkBlocksCache.clear();
playerData.clear();
getLogger().info(getDescription().getFullName() + " disabled");
}
/* public void onReload() {
// Cleanup stuff.
saveDefaultConfig();
reloadConfig();
getConfig().options().copyDefaults(true);
// saveConfig();
// Initialize stuff.
getLogger().info(getDescription().getFullName() + " reloaded");
} */
/*
* public void onReload() { // Cleanup stuff. saveDefaultConfig();
* reloadConfig(); getConfig().options().copyDefaults(true); // saveConfig(); //
* Initialize stuff. getLogger().info(getDescription().getFullName() +
* " reloaded"); }
*/
public boolean isRunning() {
return running;
}
public boolean isTimingsEnabled() {
return timingsEnabled;
}
public void setTimingsEnabled(boolean timingsEnabled) {
this.timingsEnabled = timingsEnabled;
}
public Map<ClientboundLevelChunkWithLightPacket, ChunkBlocks> getPacketChunkBlocksCache() {
return packetChunkBlocksCache;
}
public Map<UUID, PlayerData> getPlayerData() {
return playerData;
}
public ExecutorService getExecutorService() {
return executorService;
}
public boolean isEnabled(World world) {
return ((CraftWorld) world).getHandle().paperConfig().anticheat.antiXray.enabled && ((CraftWorld) world).getHandle().paperConfig().anticheat.antiXray.engineMode == EngineMode.HIDE && getConfig().getBoolean("world-settings." + world.getName() + ".anti-xray.ray-trace", getConfig().getBoolean("world-settings.default.anti-xray.ray-trace"));
return ((CraftWorld) world).getHandle().paperConfig().anticheat.antiXray.enabled
&& ((CraftWorld) world).getHandle().paperConfig().anticheat.antiXray.engineMode == EngineMode.HIDE
&& getConfig().getBoolean("world-settings." + world.getName() + ".anti-xray.ray-trace",
getConfig().getBoolean("world-settings.default.anti-xray.ray-trace"));
}
public VectorialLocation[] getLocations(Entity entity, VectorialLocation location) {
ChunkPacketBlockController chunkPacketBlockController = ((CraftWorld) location.getWorld()).getHandle().chunkPacketBlockController;
if (chunkPacketBlockController instanceof ChunkPacketBlockControllerAntiXray && ((ChunkPacketBlockControllerAntiXray) chunkPacketBlockController).rayTraceThirdPerson) {
VectorialLocation thirdPersonBackLocation = new VectorialLocation(location.getWorld(), location.getVector().clone(), location.getDirection());
ChunkPacketBlockController chunkPacketBlockController = ((CraftWorld) location.getWorld())
.getHandle().chunkPacketBlockController;
if (chunkPacketBlockController instanceof ChunkPacketBlockControllerAntiXray
&& ((ChunkPacketBlockControllerAntiXray) chunkPacketBlockController).rayTraceThirdPerson)
{
VectorialLocation thirdPersonBackLocation = new VectorialLocation(location.getWorld(),
location.getVector().clone(), location.getDirection());
VectorialLocation thirdPersonFrontLocation = new VectorialLocation(location);
thirdPersonFrontLocation.getDirection().multiply(-1.);
return new VectorialLocation[] { location, move(entity, thirdPersonBackLocation), move(entity, thirdPersonFrontLocation) };
return new VectorialLocation[] { location, move(entity, thirdPersonBackLocation),
move(entity, thirdPersonFrontLocation) };
}
return new VectorialLocation[] { location };
}
private VectorialLocation move(Entity entity, VectorialLocation location) {
location.getVector().subtract(location.getDirection().clone().multiply(getMaxZoom(entity, location, 4.)));
return location;
}
private double getMaxZoom(Entity entity, VectorialLocation location, double maxZoom) {
Vector vector = location.getVector();
Vector direction = location.getDirection();
Vec3 position = new Vec3(vector.getX(), vector.getY(), vector.getZ());
for (int i = 0; i < 8; i++) {
float edgeX = (float) ((i & 1) * 2 - 1);
float edgeY = (float) ((i >> 1 & 1) * 2 - 1);
float edgeZ = (float) ((i >> 2 & 1) * 2 - 1);
@@ -159,18 +201,28 @@ public final class RayTraceAntiXray extends JavaPlugin {
edgeY *= 0.1f;
edgeZ *= 0.1f;
Vec3 edge = position.add(edgeX, edgeY, edgeZ);
Vec3 edgeMoved = new Vec3(position.x - direction.getX() * maxZoom + (double) edgeX, position.y - direction.getY() * maxZoom + (double) edgeY, position.z - direction.getZ() * maxZoom + (double) edgeZ);
BlockHitResult result = ((CraftWorld) location.getWorld()).getHandle().clip(new ClipContext(edge, edgeMoved, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, ((CraftEntity) entity).getHandle()));
Vec3 edgeMoved = new Vec3(position.x - direction.getX() * maxZoom + (double) edgeX,
position.y - direction.getY() * maxZoom + (double) edgeY,
position.z - direction.getZ() * maxZoom + (double) edgeZ);
BlockHitResult result = ((CraftWorld) location.getWorld()).getHandle().clip(new ClipContext(edge, edgeMoved,
ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, ((CraftEntity) entity).getHandle()));
if (result.getType() != HitResult.Type.MISS) {
double zoom = result.getLocation().distanceTo(position);
if (zoom < maxZoom) {
maxZoom = zoom;
}
}
}
return maxZoom;
}
}
@@ -11,21 +11,32 @@ public final class ChunkPacketInfoAntiXray extends ChunkPacketInfo<BlockState> i
private final ChunkPacketBlockControllerAntiXray chunkPacketBlockControllerAntiXray;
private LevelChunk[] nearbyChunks;
public ChunkPacketInfoAntiXray(ClientboundLevelChunkWithLightPacket chunkPacket, LevelChunk chunk, ChunkPacketBlockControllerAntiXray chunkPacketBlockControllerAntiXray) {
public ChunkPacketInfoAntiXray(ClientboundLevelChunkWithLightPacket chunkPacket, LevelChunk chunk,
ChunkPacketBlockControllerAntiXray chunkPacketBlockControllerAntiXray)
{
super(chunkPacket, chunk);
this.chunkPacketBlockControllerAntiXray = chunkPacketBlockControllerAntiXray;
}
public LevelChunk[] getNearbyChunks() {
return nearbyChunks;
}
public void setNearbyChunks(LevelChunk... nearbyChunks) {
this.nearbyChunks = nearbyChunks;
}
@Override
public void run() {
chunkPacketBlockControllerAntiXray.obfuscate(this);
}
}
@@ -12,94 +12,160 @@ import org.bukkit.command.TabExecutor;
import com.vanillage.raytraceantixray.RayTraceAntiXray;
public final class RayTraceAntiXrayTabExecutor implements TabExecutor {
private final RayTraceAntiXray plugin;
public RayTraceAntiXrayTabExecutor(RayTraceAntiXray plugin) {
this.plugin = plugin;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
List<String> completions = new LinkedList<>();
if (args.length == 0) {
if ("raytraceantixray".startsWith(label.toLowerCase(Locale.ROOT))) {
completions.add("raytraceantixray");
}
} else if (command.getName().toLowerCase(Locale.ROOT).equals("raytraceantixray")) {
if (args.length == 1) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings") && "timings".startsWith(args[0].toLowerCase(Locale.ROOT))) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings")
&& "timings".startsWith(args[0].toLowerCase(Locale.ROOT)))
{
completions.add("timings");
}
} else if (args[0].toLowerCase(Locale.ROOT).equals("timings")) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings")) {
if (args.length == 2) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.on") && "on".startsWith(args[1].toLowerCase(Locale.ROOT))) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.on")
&& "on".startsWith(args[1].toLowerCase(Locale.ROOT)))
{
completions.add("on");
}
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.off") && "off".startsWith(args[1].toLowerCase(Locale.ROOT))) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.off")
&& "off".startsWith(args[1].toLowerCase(Locale.ROOT)))
{
completions.add("off");
}
} else if (args[1].toLowerCase(Locale.ROOT).equals("on")) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.on")) {
if (args.length == 3) {
}
}
} else if (args[1].toLowerCase(Locale.ROOT).equals("off")) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.off")) {
if (args.length == 3) {
}
}
}
}
}
}
return completions;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (command.getName().toLowerCase(Locale.ROOT).equals("raytraceantixray")) {
if (args.length == 0) {
} else if (args[0].toLowerCase(Locale.ROOT).equals("timings")) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings")) {
if (args.length == 1) {
} else if (args[1].toLowerCase(Locale.ROOT).equals("on")) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.on")) {
if (args.length == 2) {
plugin.setTimingsEnabled(true);
sender.sendMessage("Timings turned on.");
return true;
}
} else {
sender.sendMessage(ChatColor.RED + "You don't have permissions.");
return true;
}
} else if (args[1].toLowerCase(Locale.ROOT).equals("off")) {
if (sender.hasPermission("raytraceantixray.command.raytraceantixray.timings.off")) {
if (args.length == 2) {
plugin.setTimingsEnabled(false);
sender.sendMessage("Timings turned off.");
return true;
}
} else {
sender.sendMessage(ChatColor.RED + "You don't have permissions.");
return true;
}
}
} else {
sender.sendMessage(ChatColor.RED + "You don't have permissions.");
return true;
}
}
}
return false;
}
}
@@ -8,25 +8,35 @@ import net.minecraft.core.BlockPos;
import net.minecraft.world.level.chunk.LevelChunk;
public final class ChunkBlocks {
private final Reference<LevelChunk> chunk;
private final LongWrapper key;
private final Map<BlockPos, Boolean> blocks;
public ChunkBlocks(LevelChunk chunk, Map<BlockPos, Boolean> blocks) {
this.chunk = new WeakReference<>(chunk);
key = new LongWrapper(chunk.getPos().toLong());
this.blocks = blocks;
}
public LevelChunk getChunk() {
return chunk.get();
}
public LongWrapper getKey() {
return key;
}
public Map<BlockPos, Boolean> getBlocks() {
return blocks;
}
}
@@ -1,23 +1,33 @@
package com.vanillage.raytraceantixray.data;
public class LongWrapper {
protected long value;
public LongWrapper(long value) {
this.value = value;
}
public final long getValue() {
return value;
}
@Override
public final boolean equals(Object obj) {
return this == obj || obj instanceof LongWrapper && value == ((LongWrapper) obj).value;
}
@Override
public final int hashCode() {
return Long.hashCode(value);
}
}
@@ -1,11 +1,17 @@
package com.vanillage.raytraceantixray.data;
public final class MutableLongWrapper extends LongWrapper {
public MutableLongWrapper(long value) {
super(value);
}
public void setValue(long value) {
this.value = value;
}
}
@@ -7,41 +7,59 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public final class PlayerData implements Callable<Object> {
private volatile VectorialLocation[] locations;
private final Map<LongWrapper, ChunkBlocks> chunks = new ConcurrentHashMap<>();
private final Queue<Result> results = new ConcurrentLinkedQueue<>();
private Callable<?> callable;
public PlayerData(VectorialLocation[] locations) {
this.locations = locations;
}
public VectorialLocation[] getLocations() {
return locations;
}
public void setLocations(VectorialLocation[] locations) {
this.locations = locations;
}
public Map<LongWrapper, ChunkBlocks> getChunks() {
return chunks;
}
public Queue<Result> getResults() {
return results;
}
public Callable<?> getCallable() {
return callable;
}
public void setCallable(Callable<?> callable) {
this.callable = callable;
}
@Override
public Object call() throws Exception {
return callable.call();
}
}
@@ -3,25 +3,35 @@ package com.vanillage.raytraceantixray.data;
import net.minecraft.core.BlockPos;
public final class Result {
private final ChunkBlocks chunkBlocks;
private final BlockPos block;
private final boolean visible;
public Result(ChunkBlocks chunkBlocks, BlockPos block, boolean visible) {
this.chunkBlocks = chunkBlocks;
this.block = block;
this.visible = visible;
}
public ChunkBlocks getChunkBlocks() {
return chunkBlocks;
}
public BlockPos getBlock() {
return block;
}
public boolean isVisible() {
return visible;
}
}
@@ -8,37 +8,51 @@ import org.bukkit.World;
import org.bukkit.util.Vector;
public final class VectorialLocation {
private final Reference<World> world;
private final Vector vector;
private final Vector direction;
public VectorialLocation(World world, Vector vector, Vector direction) {
this.world = new WeakReference<>(world);
this.vector = vector;
this.direction = direction;
}
public VectorialLocation(VectorialLocation location) {
world = location.world;
vector = location.getVector().clone();
direction = location.getDirection().clone();
}
public VectorialLocation(Location location) {
world = new WeakReference<>(location.getWorld());
vector = location.toVector();
direction = location.getDirection();
}
public World getWorld() {
return world.get();
}
public Vector getVector() {
return vector;
}
public Vector getDirection() {
return direction;
}
}
@@ -20,19 +20,28 @@ import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.LevelChunk;
public final class PacketListener extends PacketAdapter {
private final RayTraceAntiXray plugin;
public PacketListener(RayTraceAntiXray plugin) {
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK, PacketType.Play.Server.UNLOAD_CHUNK, PacketType.Play.Server.RESPAWN);
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK, PacketType.Play.Server.UNLOAD_CHUNK,
PacketType.Play.Server.RESPAWN);
this.plugin = plugin;
}
@Override
public void onPacketSending(PacketEvent event) {
if (event.getPacketType() == PacketType.Play.Server.MAP_CHUNK) {
// A player data instance is always bound to a world and defines what is to be calculated.
// Apart from the join and quit event, this is the only place that defines the world of a player by renewing the player data instance.
// In principle, we could (additionally) renew the player data instance anywhere else if we detect a world change (e.g. move event, changed world event, ...).
// A player data instance is always bound to a world and defines what is to be
// calculated.
// Apart from the join and quit event, this is the only place that defines the
// world of a player by renewing the player data instance.
// In principle, we could (additionally) renew the player data instance anywhere
// else if we detect a world change (e.g. move event, changed world event, ...).
// However, Anti-Xray specifies what is to be calculated via the chunk packet.
// Since Anti-Xray is async, chunk packets can be delayed.
// (The packet order of all packets is still being preserved and consistent.)
@@ -41,51 +50,67 @@ public final class PacketListener extends PacketAdapter {
// (2) Changed world event from world A to B.
// (3) Chunk packet event of world A.
// (4) Chunk packet event of world B.
// This would lead to unnecessarily renewing the player data instance multiple times in the worst case.
// This would lead to unnecessarily renewing the player data instance multiple
// times in the worst case.
// Therefore, we only renew the player data instance here.
// For similar reasons, we also handle chunk unloads via packet events below.
// Everywhere else we have to check if the player's world still matches the world of the player data instance before we use it.
// Everywhere else we have to check if the player's world still matches the
// world of the player data instance before we use it.
// (See for example the move event.)
PlayerData playerData = plugin.getPlayerData().get(event.getPlayer().getUniqueId());
// Get the result from Anti-Xray for the current chunk packet.
// We can't remove the entry because the same chunk packet can be sent to multiple players.
// The garbage collector will remove the entry later since we're using a weak key map.
// We can't remove the entry because the same chunk packet can be sent to
// multiple players.
// The garbage collector will remove the entry later since we're using a weak
// key map.
ChunkBlocks chunkBlocks = plugin.getPacketChunkBlocksCache().get(event.getPacket().getHandle());
if (chunkBlocks == null) {
// RayTraceAntiXray is probably not enabled in this world (or other plugins bypass Anti-Xray).
// RayTraceAntiXray is probably not enabled in this world (or other plugins
// bypass Anti-Xray).
// We can't determine the world from the chunk packet in this case.
// Thus we use the player's current (more up to date) world instead.
Location location = event.getPlayer().getEyeLocation();
if (!location.getWorld().equals(playerData.getLocations()[0].getWorld())) {
// Detected a world change.
// In the event order listing above, this corresponds to (4) when RayTraceAntiXray is disabled in world B.
// In the event order listing above, this corresponds to (4) when
// RayTraceAntiXray is disabled in world B.
// The player's current world is world B since (2).
playerData = new PlayerData(plugin.getLocations(event.getPlayer(), new VectorialLocation(location)));
playerData = new PlayerData(
plugin.getLocations(event.getPlayer(), new VectorialLocation(location)));
playerData.setCallable(new RayTraceCallable(playerData));
plugin.getPlayerData().put(event.getPlayer().getUniqueId(), playerData);
}
return;
}
// Get chunk from weak reference.
LevelChunk chunk = chunkBlocks.getChunk();
if (chunk == null) {
// The chunk has already been unloaded and garbage collected.
// A chunk unload packet will probably follow.
// We can ignore this chunk packet.
return;
}
if (!chunk.getLevel().getWorld().equals(playerData.getLocations()[0].getWorld())) {
// Detected a world change.
// We need the player's current location to construct a new player data instance.
// We need the player's current location to construct a new player data
// instance.
Location location = event.getPlayer().getEyeLocation();
if (!chunk.getLevel().getWorld().equals(location.getWorld())) {
// The player has changed the world again since this chunk packet was sent.
// (As described above, packets can be delayed.)
// Example event order for this case:
@@ -95,33 +120,49 @@ public final class PacketListener extends PacketAdapter {
// (4) Chunk packet event of world B.
// (5) Chunk packet event of world C.
// The previous chunk packet was from world A in (1).
// The current chunk packet is from world B in (4) but the player is already in world C.
// We can ignore this chunk packet and wait until we get a chunk packet from world C in (5).
// The current chunk packet is from world B in (4) but the player is already in
// world C.
// We can ignore this chunk packet and wait until we get a chunk packet from
// world C in (5).
return;
}
// Renew the player data instance.
playerData = new PlayerData(plugin.getLocations(event.getPlayer(), new VectorialLocation(location)));
playerData.setCallable(new RayTraceCallable(playerData));
plugin.getPlayerData().put(event.getPlayer().getUniqueId(), playerData);
}
// We need to copy the chunk blocks because the same chunk packet could have been sent to multiple players.
// We need to copy the chunk blocks because the same chunk packet could have
// been sent to multiple players.
chunkBlocks = new ChunkBlocks(chunk, new HashMap<>(chunkBlocks.getBlocks()));
playerData.getChunks().put(chunkBlocks.getKey(), chunkBlocks);
} else if (event.getPacketType() == PacketType.Play.Server.UNLOAD_CHUNK) {
// Note that chunk unload packets aren't sent on world change and on respawn.
// World changes are already handled above.
// Technically removing chunks isn't necessary since we're using a weak reference to the chunk.
// Technically removing chunks isn't necessary since we're using a weak
// reference to the chunk.
StructureModifier<Integer> integers = event.getPacket().getIntegers();
plugin.getPlayerData().get(event.getPlayer().getUniqueId()).getChunks().remove(new LongWrapper(ChunkPos.asLong(integers.read(0), integers.read(1))));
plugin.getPlayerData().get(event.getPlayer().getUniqueId()).getChunks()
.remove(new LongWrapper(ChunkPos.asLong(integers.read(0), integers.read(1))));
} else if (event.getPacketType() == PacketType.Play.Server.RESPAWN) {
// As with world changes, chunk unload packets aren't sent on respawn.
// All required chunks are (re)sent afterwards.
// Thus we clear the chunks.
// Technically this isn't necessary since we're using a weak reference to the chunk.
// If respawning involves a world change, it will be handled in the next chunk packet event.
// Technically this isn't necessary since we're using a weak reference to the
// chunk.
// If respawning involves a world change, it will be handled in the next chunk
// packet event.
plugin.getPlayerData().get(event.getPlayer().getUniqueId()).getChunks().clear();
}
}
}
@@ -14,33 +14,46 @@ import com.vanillage.raytraceantixray.data.VectorialLocation;
import com.vanillage.raytraceantixray.tasks.RayTraceCallable;
public final class PlayerListener implements Listener {
private final RayTraceAntiXray plugin;
public PlayerListener(RayTraceAntiXray plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
PlayerData playerData = new PlayerData(plugin.getLocations(event.getPlayer(), new VectorialLocation(event.getPlayer().getEyeLocation())));
PlayerData playerData = new PlayerData(
plugin.getLocations(event.getPlayer(), new VectorialLocation(event.getPlayer().getEyeLocation())));
playerData.setCallable(new RayTraceCallable(playerData));
plugin.getPlayerData().put(event.getPlayer().getUniqueId(), playerData);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
plugin.getPlayerData().remove(event.getPlayer().getUniqueId());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent event) {
PlayerData playerData = plugin.getPlayerData().get(event.getPlayer().getUniqueId());
Location to = event.getTo();
if (to.getWorld().equals(playerData.getLocations()[0].getWorld())) {
VectorialLocation location = new VectorialLocation(to);
location.getVector().setY(location.getVector().getY() + event.getPlayer().getEyeHeight());
playerData.setLocations(plugin.getLocations(event.getPlayer(), location));
}
}
}
@@ -18,34 +18,58 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.Level;
public final class WorldListener implements Listener {
private final RayTraceAntiXray plugin;
public WorldListener(RayTraceAntiXray plugin) {
this.plugin = plugin;
}
@EventHandler
public void onWorldInit(WorldInitEvent event) {
World world = event.getWorld();
if (plugin.isEnabled(world)) {
ConfigurationSection config = plugin.getConfig();
String worldName = world.getName();
boolean rayTraceThirdPerson = config.getBoolean("world-settings." + worldName + ".anti-xray.ray-trace-third-person", config.getBoolean("world-settings.default.anti-xray.ray-trace-third-person"));
double rayTraceDistance = Math.max(config.getDouble("world-settings." + worldName + ".anti-xray.ray-trace-distance", config.getDouble("world-settings.default.anti-xray.ray-trace-distance")), 0.);
int maxRayTraceBlockCountPerChunk = Math.max(config.getInt("world-settings." + worldName + ".anti-xray.max-ray-trace-block-count-per-chunk", config.getInt("world-settings.default.anti-xray.max-ray-trace-block-count-per-chunk")), 0);
boolean rehideBlocks = config.getBoolean("world-settings." + worldName + ".anti-xray.rehide-blocks", config.getBoolean("world-settings.default.anti-xray.rehide-blocks"));
List<String> rayTraceBlocks = config.getList("world-settings." + worldName + ".anti-xray.ray-trace-blocks", config.getList("world-settings.default.anti-xray.ray-trace-blocks")).stream().filter(o -> o != null).map(String::valueOf).collect(Collectors.toList());
boolean rayTraceThirdPerson = config.getBoolean(
"world-settings." + worldName + ".anti-xray.ray-trace-third-person",
config.getBoolean("world-settings.default.anti-xray.ray-trace-third-person"));
double rayTraceDistance = Math
.max(config.getDouble("world-settings." + worldName + ".anti-xray.ray-trace-distance",
config.getDouble("world-settings.default.anti-xray.ray-trace-distance")), 0.);
int maxRayTraceBlockCountPerChunk = Math
.max(config.getInt("world-settings." + worldName + ".anti-xray.max-ray-trace-block-count-per-chunk",
config.getInt("world-settings.default.anti-xray.max-ray-trace-block-count-per-chunk")), 0);
boolean rehideBlocks = config.getBoolean("world-settings." + worldName + ".anti-xray.rehide-blocks",
config.getBoolean("world-settings.default.anti-xray.rehide-blocks"));
List<String> rayTraceBlocks = config
.getList("world-settings." + worldName + ".anti-xray.ray-trace-blocks",
config.getList("world-settings.default.anti-xray.ray-trace-blocks"))
.stream().filter(o -> o != null).map(String::valueOf).collect(Collectors.toList());
Level level = ((CraftWorld) world).getHandle();
Object controller = new ChunkPacketBlockControllerAntiXray(plugin, rayTraceThirdPerson, rayTraceDistance, maxRayTraceBlockCountPerChunk, rehideBlocks, rayTraceBlocks.isEmpty() ? null : rayTraceBlocks, level, MinecraftServer.getServer().executor);
Object controller = new ChunkPacketBlockControllerAntiXray(plugin, rayTraceThirdPerson, rayTraceDistance,
maxRayTraceBlockCountPerChunk, rehideBlocks, rayTraceBlocks.isEmpty() ? null : rayTraceBlocks,
level, MinecraftServer.getServer().executor);
try {
Field field = Level.class.getDeclaredField("chunkPacketBlockController");
field.setAccessible(true);
field.set(level, controller);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
@@ -30,6 +30,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.MissingPaletteEntryException;
public final class RayTraceCallable implements Callable<Void> {
private static final BlockState AIR = Blocks.AIR.defaultBlockState();
private final PlayerData playerData;
private final CachedSectionBlockOcclusionGetter cachedSectionBlockOcclusionGetter;
@@ -40,9 +41,12 @@ public final class RayTraceCallable implements Callable<Void> {
private final boolean rehideBlocks;
public RayTraceCallable(PlayerData playerData) {
ChunkPacketBlockController chunkPacketBlockController = ((CraftWorld) playerData.getLocations()[0].getWorld()).getHandle().chunkPacketBlockController;
ChunkPacketBlockController chunkPacketBlockController = ((CraftWorld) playerData.getLocations()[0].getWorld())
.getHandle().chunkPacketBlockController;
if (!(chunkPacketBlockController instanceof ChunkPacketBlockControllerAntiXray)) {
this.playerData = null;
cachedSectionBlockOcclusionGetter = null;
blockOcclusionCulling = null;
@@ -51,6 +55,7 @@ public final class RayTraceCallable implements Callable<Void> {
rayTraceDistanceSquared = 0.;
rehideBlocks = false;
return;
}
this.playerData = playerData;
@@ -60,6 +65,7 @@ public final class RayTraceCallable implements Callable<Void> {
boolean[] solidGlobal = chunkPacketBlockControllerAntiXray.solidGlobal;
MutableLongWrapper mutableLongWrapper = new MutableLongWrapper(0L);
cachedSectionBlockOcclusionGetter = new CachedSectionBlockOcclusionGetter() {
private static final boolean UNLOADED_OCCLUDING = true;
private LevelChunk chunk;
private LevelChunkSection section;
@@ -69,62 +75,95 @@ public final class RayTraceCallable implements Callable<Void> {
@Override
public boolean isOccluding(int x, int y, int z) {
int chunkX = x >> 4;
int chunkZ = z >> 4;
if (this.chunkX != chunkX || this.chunkZ != chunkZ) {
mutableLongWrapper.setValue(ChunkPos.asLong(chunkX, chunkZ));
ChunkBlocks chunkBlocks = chunks.get(mutableLongWrapper);
if (chunkBlocks == null) {
return UNLOADED_OCCLUDING;
}
LevelChunk chunk = chunkBlocks.getChunk();
if (chunk == null) {
return UNLOADED_OCCLUDING;
}
int sectionY = y >> 4;
if (sectionY < chunk.getMinSection() || sectionY >= chunk.getMaxSection()) {
return false;
}
LevelChunkSection section = chunk.getSections()[sectionY - chunk.getMinSection()];
return section != null && !section.hasOnlyAir() && solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE.idFor(getBlockState(section, x, y, z))]; // Sections aren't null anymore. Unfortunately, LevelChunkSection#recalcBlockCounts() temporarily resets #nonEmptyBlockCount to 0 due to a Paper optimization.
return section != null && !section.hasOnlyAir()
&& solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE
.idFor(getBlockState(section, x, y, z))]; // Sections aren't null anymore.
// Unfortunately,
// LevelChunkSection#recalcBlockCounts()
// temporarily resets #nonEmptyBlockCount
// to 0 due to a Paper optimization.
}
int sectionY = y >> 4;
if (this.sectionY != sectionY) {
if (chunk == null) {
return UNLOADED_OCCLUDING;
}
if (sectionY < chunk.getMinSection() || sectionY >= chunk.getMaxSection()) {
return false;
}
LevelChunkSection section = chunk.getSections()[sectionY - chunk.getMinSection()];
return section != null && !section.hasOnlyAir() && solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE.idFor(getBlockState(section, x, y, z))]; // Sections aren't null anymore. Unfortunately, LevelChunkSection#recalcBlockCounts() temporarily resets #nonEmptyBlockCount to 0 due to a Paper optimization.
return section != null && !section.hasOnlyAir()
&& solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE
.idFor(getBlockState(section, x, y, z))]; // Sections aren't null anymore.
// Unfortunately,
// LevelChunkSection#recalcBlockCounts()
// temporarily resets #nonEmptyBlockCount
// to 0 due to a Paper optimization.
}
if (section == null) {
return chunk == null && UNLOADED_OCCLUDING;
}
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE.idFor(getBlockState(section, x, y, z))];
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE
.idFor(getBlockState(section, x, y, z))];
}
@Override
public boolean isOccludingRay(int x, int y, int z) {
int chunkX = x >> 4;
int sectionY = y >> 4;
int chunkZ = z >> 4;
if (this.chunkX != chunkX || this.chunkZ != chunkZ) {
this.chunkX = chunkX;
this.sectionY = sectionY;
this.chunkZ = chunkZ;
@@ -132,108 +171,153 @@ public final class RayTraceCallable implements Callable<Void> {
ChunkBlocks chunkBlocks = chunks.get(mutableLongWrapper);
if (chunkBlocks == null) {
chunk = null;
section = null;
return UNLOADED_OCCLUDING;
}
chunk = chunkBlocks.getChunk();
if (chunk == null) {
section = null;
return UNLOADED_OCCLUDING;
}
if (sectionY < chunk.getMinSection() || sectionY >= chunk.getMaxSection()) {
section = null;
return false;
}
section = chunk.getSections()[sectionY - chunk.getMinSection()];
if (section == null) { // Sections aren't null anymore.
return false;
}
if (section.hasOnlyAir()) { // Unfortunately, LevelChunkSection#recalcBlockCounts() temporarily resets #nonEmptyBlockCount to 0 due to a Paper optimization.
if (section.hasOnlyAir()) { // Unfortunately, LevelChunkSection#recalcBlockCounts() temporarily
// resets #nonEmptyBlockCount to 0 due to a Paper optimization.
section = null;
return false;
}
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE.idFor(getBlockState(section, x, y, z))];
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE
.idFor(getBlockState(section, x, y, z))];
}
if (this.sectionY != sectionY) {
this.sectionY = sectionY;
if (chunk == null) {
// section = null;
return UNLOADED_OCCLUDING;
}
if (sectionY < chunk.getMinSection() || sectionY >= chunk.getMaxSection()) {
section = null;
return false;
}
section = chunk.getSections()[sectionY - chunk.getMinSection()];
if (section == null) { // Sections aren't null anymore.
return false;
}
if (section.hasOnlyAir()) { // Unfortunately, LevelChunkSection#recalcBlockCounts() temporarily resets #nonEmptyBlockCount to 0 due to a Paper optimization.
if (section.hasOnlyAir()) { // Unfortunately, LevelChunkSection#recalcBlockCounts() temporarily
// resets #nonEmptyBlockCount to 0 due to a Paper optimization.
section = null;
return false;
}
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE.idFor(getBlockState(section, x, y, z))];
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE
.idFor(getBlockState(section, x, y, z))];
}
if (section == null) {
return chunk == null && UNLOADED_OCCLUDING;
}
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE.idFor(getBlockState(section, x, y, z))];
return solidGlobal[ChunkPacketBlockControllerAntiXray.GLOBAL_BLOCKSTATE_PALETTE
.idFor(getBlockState(section, x, y, z))];
}
@Override
public void initializeCache(LevelChunk chunk, int chunkX, int sectionY, int chunkZ) {
this.chunk = chunk;
section = chunk.getSections()[sectionY - chunk.getMinSection()];
this.chunkX = chunkX;
this.sectionY = sectionY;
this.chunkZ = chunkZ;
}
@Override
public void clearCache() {
chunk = null;
section = null;
}
};
blockOcclusionCulling = new BlockOcclusionCulling(blockIterator::initializeNormalized, cachedSectionBlockOcclusionGetter, true);
blockOcclusionCulling = new BlockOcclusionCulling(blockIterator::initializeNormalized,
cachedSectionBlockOcclusionGetter, true);
this.chunks = chunks.values();
rayTraceDistance = chunkPacketBlockControllerAntiXray.rayTraceDistance;
rayTraceDistanceSquared = rayTraceDistance * rayTraceDistance;
rehideBlocks = chunkPacketBlockControllerAntiXray.rehideBlocks;
}
@Override
public Void call() {
try {
rayTrace();
} catch (Throwable t) {
t.printStackTrace();
throw t;
}
return null;
}
private void rayTrace() {
if (blockOcclusionCulling == null) {
return;
}
VectorialLocation[] locations = playerData.getLocations();
@@ -253,23 +337,29 @@ public final class RayTraceCallable implements Callable<Void> {
playerVector.setZ(playerZ);
for (ChunkBlocks chunkBlocks : chunks) {
LevelChunk chunk = chunkBlocks.getChunk();
if (chunk == null) {
playerData.getChunks().remove(chunkBlocks.getKey(), chunkBlocks);
continue;
}
int chunkX = chunk.getPos().x;
int chunkZ = chunk.getPos().z;
if (chunkX < chunkXMin || chunkX > chunkXMax || chunkZ < chunkZMin || chunkZ > chunkZMax) {
continue;
}
Iterator<Entry<BlockPos, Boolean>> iterator = chunkBlocks.getBlocks().entrySet().iterator();
while (iterator.hasNext()) {
Entry<BlockPos, Boolean> blockHidden = iterator.next();
BlockPos block = blockHidden.getKey();
int x = block.getX();
@@ -281,68 +371,107 @@ public final class RayTraceCallable implements Callable<Void> {
double differenceX = playerX - centerX;
double differenceY = playerY - centerY;
double differenceZ = playerZ - centerZ;
double distanceSquared = differenceX * differenceX + differenceY * differenceY + differenceZ * differenceZ;
double distanceSquared = differenceX * differenceX + differenceY * differenceY
+ differenceZ * differenceZ;
if (!(distanceSquared <= rayTraceDistanceSquared)) {
continue;
}
int sectionY = y >> 4;
boolean visible = false;
for (int i = 0; i < locations.length; i++) {
VectorialLocation location = locations[i];
Vector direction = location.getDirection();
cachedSectionBlockOcclusionGetter.initializeCache(chunk, chunkX, sectionY, chunkZ);
if (i == 0) {
if (blockOcclusionCulling.isVisible(x, y, z, centerX, centerY, centerZ, differenceX, differenceY, differenceZ, distanceSquared, direction.getX(), direction.getY(), direction.getZ())) {
if (blockOcclusionCulling.isVisible(x, y, z, centerX, centerY, centerZ, differenceX,
differenceY, differenceZ, distanceSquared, direction.getX(), direction.getY(),
direction.getZ()))
{
visible = true;
break;
}
} else {
Vector vector = location.getVector();
double vectorDifferenceX = vector.getX() - centerX;
double vectorDifferenceY = vector.getY() - centerY;
double vectorDifferenceZ = vector.getZ() - centerZ;
double vectorDistanceSquared = vectorDifferenceX * vectorDifferenceX + vectorDifferenceY * vectorDifferenceY + vectorDifferenceZ * vectorDifferenceZ;
double vectorDistanceSquared = vectorDifferenceX * vectorDifferenceX
+ vectorDifferenceY * vectorDifferenceY + vectorDifferenceZ * vectorDifferenceZ;
if (blockOcclusionCulling.isVisible(x, y, z, centerX, centerY, centerZ, vectorDifferenceX,
vectorDifferenceY, vectorDifferenceZ, vectorDistanceSquared, direction.getX(),
direction.getY(), direction.getZ()))
{
if (blockOcclusionCulling.isVisible(x, y, z, centerX, centerY, centerZ, vectorDifferenceX, vectorDifferenceY, vectorDifferenceZ, vectorDistanceSquared, direction.getX(), direction.getY(), direction.getZ())) {
visible = true;
break;
}
}
}
if (visible) {
if (blockHidden.getValue()) {
playerData.getResults().add(new Result(chunkBlocks, block, true));
if (rehideBlocks) {
blockHidden.setValue(false);
} else {
iterator.remove();
}
}
} else if (!blockHidden.getValue()) {
playerData.getResults().add(new Result(chunkBlocks, block, false));
blockHidden.setValue(true);
}
}
}
cachedSectionBlockOcclusionGetter.clearCache();
}
private static BlockState getBlockState(LevelChunkSection section, int x, int y, int z) {
// synchronized (section.getStates()) {
// try {
// section.getStates().acquire();
try {
return section.getBlockState(x & 15, y & 15, z & 15);
} catch (MissingPaletteEntryException e) {
return AIR;
}
// } finally {
// section.getStates().release();
// }
@@ -350,8 +479,11 @@ public final class RayTraceCallable implements Callable<Void> {
}
private interface CachedSectionBlockOcclusionGetter extends BlockOcclusionGetter {
void initializeCache(LevelChunk chunk, int chunkX, int sectionY, int chunkZ);
void clearCache();
}
}
@@ -6,28 +6,40 @@ import java.util.concurrent.RejectedExecutionException;
import com.vanillage.raytraceantixray.RayTraceAntiXray;
public final class RayTraceTimerTask extends TimerTask {
private final RayTraceAntiXray plugin;
public RayTraceTimerTask(RayTraceAntiXray plugin) {
this.plugin = plugin;
}
@Override
public void run() {
boolean timingsEnabled = plugin.isTimingsEnabled();
long start = timingsEnabled ? System.currentTimeMillis() : 0L;
try {
plugin.getExecutorService().invokeAll(plugin.getPlayerData().values());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (RejectedExecutionException e) {
}
if (timingsEnabled) {
long stop = System.currentTimeMillis();
plugin.getLogger().info((stop - start) + "ms per ray trace tick.");
}
}
}
@@ -23,93 +23,138 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
public final class UpdateBukkitRunnable extends BukkitRunnable {
private final RayTraceAntiXray plugin;
public UpdateBukkitRunnable(RayTraceAntiXray plugin) {
this.plugin = plugin;
}
@Override
public void run() {
plugin.getServer().getOnlinePlayers().forEach(p -> {
PlayerData playerData = plugin.getPlayerData().get(p.getUniqueId());
World world = playerData.getLocations()[0].getWorld();
if (!p.getWorld().equals(world)) {
return;
}
Queue<Result> results = playerData.getResults();
for (Result result = results.poll(); result != null; result = results.poll()) {
ChunkBlocks chunkBlocks = result.getChunkBlocks();
// Check if the client still has the chunk loaded and if it wasn't resent in the meantime.
// Note that even if this check passes, the server could have already unloaded or resent the chunk but the corresponding packet is still in the packet queue.
// Technically the null check isn't necessary but we don't need to send an update packet because the client will unload the chunk.
// Check if the client still has the chunk loaded and if it wasn't resent in the
// meantime.
// Note that even if this check passes, the server could have already unloaded
// or resent the chunk but the corresponding packet is still in the packet
// queue.
// Technically the null check isn't necessary but we don't need to send an
// update packet because the client will unload the chunk.
if (chunkBlocks.getChunk() == null || playerData.getChunks().get(chunkBlocks.getKey()) != chunkBlocks) {
continue;
}
BlockPos block = result.getBlock();
// Similar to the null check above, this check isn't actually necessary.
// However, we don't need to send an update packet because the client will unload the chunk.
// However, we don't need to send an update packet because the client will
// unload the chunk.
// Thus we can avoid loading the chunk just for the update packet.
if (!world.isChunkLoaded(block.getX() >> 4, block.getZ() >> 4)) {
continue;
}
BlockState blockState;
BlockEntity blockEntity = null;
if (result.isVisible()) {
blockState = ((CraftWorld) world).getHandle().getBlockState(block);
if (blockState.hasBlockEntity()) {
blockEntity = ((CraftWorld) world).getHandle().getBlockEntity(block);
}
} else if (world.getEnvironment() == Environment.NETHER) {
blockState = Blocks.NETHERRACK.defaultBlockState();
} else if (world.getEnvironment() == Environment.THE_END) {
blockState = Blocks.END_STONE.defaultBlockState();
} else if (block.getY() < 0) {
blockState = Blocks.DEEPSLATE.defaultBlockState();
} else {
blockState = Blocks.STONE.defaultBlockState();
}
// We can't send the packet normally (through the packet queue).
// We bypass the packet queue since our calculations are based on the packet state (not the server state) as seen by the packet listener.
// As described above, the packet queue could for example already contain a chunk unload packet.
// We bypass the packet queue since our calculations are based on the packet
// state (not the server state) as seen by the packet listener.
// As described above, the packet queue could for example already contain a
// chunk unload packet.
// Thus we send our packet immediately before that.
sendPacketImmediately(p, new ClientboundBlockUpdatePacket(block, blockState));
if (blockEntity != null) {
Object packet = blockEntity.getUpdatePacket();
if (packet != null) {
sendPacketImmediately(p, packet);
}
}
}
});
}
private static boolean sendPacketImmediately(Player player, Object packet) {
ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection;
if (connection == null || connection.processedDisconnect) {
return false;
}
Channel channel = connection.connection.channel;
if (channel == null || !channel.isOpen()) {
return false;
}
channel.writeAndFlush(packet);
return true;
}
}
@@ -5,6 +5,7 @@ import java.util.NoSuchElementException;
// Amanatides, J., & Woo, A. A Fast Voxel Traversal Algorithm for Ray Tracing. http://www.cse.yorku.ca/~amana/research/grid.pdf.
public final class BlockIterator implements Iterator<int[]> {
private int x;
private int y;
private int z;
@@ -18,47 +19,85 @@ public final class BlockIterator implements Iterator<int[]> {
private double tDeltaX;
private double tDeltaY;
private double tDeltaZ;
private int[] ref = new int[3]; // This implementation always returns ref or refSwap to avoid garbage. Can easily be changed if needed.
private int[] ref = new int[3]; // This implementation always returns ref or refSwap to avoid garbage. Can
// easily be changed if needed.
private int[] refSwap = new int[3];
private int[] next;
public BlockIterator(double startX, double startY, double startZ, double endX, double endY, double endZ) {
initialize(startX, startY, startZ, endX, endY, endZ);
}
public BlockIterator(int x, int y, int z, double startX, double startY, double startZ, double endX, double endY, double endZ) {
public BlockIterator(int x, int y, int z, double startX, double startY, double startZ, double endX, double endY,
double endZ)
{
initialize(x, y, z, startX, startY, startZ, endX, endY, endZ);
}
public BlockIterator(double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance) {
public BlockIterator(double startX, double startY, double startZ, double directionX, double directionY,
double directionZ, double distance)
{
initialize(startX, startY, startZ, directionX, directionY, directionZ, distance);
}
public BlockIterator(int x, int y, int z, double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance) {
public BlockIterator(int x, int y, int z, double startX, double startY, double startZ, double directionX,
double directionY, double directionZ, double distance)
{
initialize(x, y, z, startX, startY, startZ, directionX, directionY, directionZ, distance);
}
public BlockIterator(double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance, boolean normalized) {
public BlockIterator(double startX, double startY, double startZ, double directionX, double directionY,
double directionZ, double distance, boolean normalized)
{
if (normalized) {
initializeNormalized(startX, startY, startZ, directionX, directionY, directionZ, distance);
} else {
initialize(startX, startY, startZ, directionX, directionY, directionZ, distance);
}
}
public BlockIterator(int x, int y, int z, double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance, boolean normalized) {
}
public BlockIterator(int x, int y, int z, double startX, double startY, double startZ, double directionX,
double directionY, double directionZ, double distance, boolean normalized)
{
if (normalized) {
initializeNormalized(x, y, z, startX, startY, startZ, directionX, directionY, directionZ, distance);
} else {
initialize(x, y, z, startX, startY, startZ, directionX, directionY, directionZ, distance);
}
}
public BlockIterator initialize(double startX, double startY, double startZ, double endX, double endY, double endZ) {
}
public BlockIterator initialize(double startX, double startY, double startZ, double endX, double endY,
double endZ)
{
return initialize(floor(startX), floor(startY), floor(startZ), startX, startY, startZ, endX, endY, endZ);
}
public BlockIterator initialize(int x, int y, int z, double startX, double startY, double startZ, double endX, double endY, double endZ) {
public BlockIterator initialize(int x, int y, int z, double startX, double startY, double startZ, double endX,
double endY, double endZ)
{
double directionX = endX - startX;
double directionY = endY - startY;
double directionZ = endZ - startZ;
@@ -68,13 +107,22 @@ public final class BlockIterator implements Iterator<int[]> {
directionY /= fixedDistance;
directionZ /= fixedDistance;
return initializeNormalized(x, y, z, startX, startY, startZ, directionX, directionY, directionZ, distance);
}
public BlockIterator initialize(double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance) {
return initialize(floor(startX), floor(startY), floor(startZ), startX, startY, startZ, directionX, directionY, directionZ, distance);
public BlockIterator initialize(double startX, double startY, double startZ, double directionX, double directionY,
double directionZ, double distance)
{
return initialize(floor(startX), floor(startY), floor(startZ), startX, startY, startZ, directionX, directionY,
directionZ, distance);
}
public BlockIterator initialize(int x, int y, int z, double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance) {
public BlockIterator initialize(int x, int y, int z, double startX, double startY, double startZ, double directionX,
double directionY, double directionZ, double distance)
{
double signum = Math.signum(distance);
directionX *= signum;
directionY *= signum;
@@ -82,20 +130,32 @@ public final class BlockIterator implements Iterator<int[]> {
double length = Math.sqrt(directionX * directionX + directionY * directionY + directionZ * directionZ);
if (length == 0.) {
length = Double.NaN;
}
directionX /= length;
directionY /= length;
directionZ /= length;
return initializeNormalized(x, y, z, startX, startY, startZ, directionX, directionY, directionZ, Math.abs(distance));
return initializeNormalized(x, y, z, startX, startY, startZ, directionX, directionY, directionZ,
Math.abs(distance));
}
public BlockIterator initializeNormalized(double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance) {
return initializeNormalized(floor(startX), floor(startY), floor(startZ), startX, startY, startZ, directionX, directionY, directionZ, Math.abs(distance));
public BlockIterator initializeNormalized(double startX, double startY, double startZ, double directionX,
double directionY, double directionZ, double distance)
{
return initializeNormalized(floor(startX), floor(startY), floor(startZ), startX, startY, startZ, directionX,
directionY, directionZ, Math.abs(distance));
}
public BlockIterator initializeNormalized(int x, int y, int z, double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance) {
public BlockIterator initializeNormalized(int x, int y, int z, double startX, double startY, double startZ,
double directionX, double directionY, double directionZ, double distance)
{
this.x = x;
this.y = y;
this.z = z;
@@ -114,26 +174,39 @@ public final class BlockIterator implements Iterator<int[]> {
ref[1] = y;
ref[2] = z;
return this;
}
public int[] calculateNext() {
if (tMaxX < tMaxY) {
if (tMaxZ < tMaxX) {
if (tMaxZ <= tMax) {
z += stepZ;
// next = new int[] { x, y, z };
ref[0] = x;
ref[1] = y;
ref[2] = z;
tMaxZ += tDeltaZ;
} else {
next = null;
}
} else {
if (tMaxX <= tMax) {
if (tMaxZ == tMaxX) {
z += stepZ;
tMaxZ += tDeltaZ;
}
x += stepX;
@@ -142,15 +215,24 @@ public final class BlockIterator implements Iterator<int[]> {
ref[1] = y;
ref[2] = z;
tMaxX += tDeltaX;
} else {
next = null;
}
}
} else if (tMaxY < tMaxZ) {
if (tMaxY <= tMax) {
if (tMaxX == tMaxY) {
x += stepX;
tMaxX += tDeltaX;
}
y += stepY;
@@ -159,19 +241,29 @@ public final class BlockIterator implements Iterator<int[]> {
ref[1] = y;
ref[2] = z;
tMaxY += tDeltaY;
} else {
next = null;
}
} else {
if (tMaxZ <= tMax) {
if (tMaxX == tMaxZ) {
x += stepX;
tMaxX += tDeltaX;
}
if (tMaxY == tMaxZ) {
y += stepY;
tMaxY += tDeltaY;
}
z += stepZ;
@@ -180,25 +272,35 @@ public final class BlockIterator implements Iterator<int[]> {
ref[1] = y;
ref[2] = z;
tMaxZ += tDeltaZ;
} else {
next = null;
}
}
return next;
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public int[] next() {
int[] next = this.next;
if (next == null) {
throw new NoSuchElementException();
}
int[] temp = ref;
@@ -207,10 +309,14 @@ public final class BlockIterator implements Iterator<int[]> {
this.next = ref;
calculateNext();
return next;
}
private static int floor(double value) {
int i = (int) value;
return value < (double) i ? i - 1 : i;
}
}
@@ -3,35 +3,55 @@ package com.vanillage.raytraceantixray.util;
import java.util.function.Consumer;
public final class BlockOcclusionCulling {
private static final IntArrayConsumer INCREASE_X = c -> c[0]++;
private static final IntArrayConsumer DECREASE_X = c -> c[0]--;
private static final IntArrayConsumer INCREASE_Y = c -> c[1]++;
private static final IntArrayConsumer DECREASE_Y = c -> c[1]--;
private static final IntArrayConsumer INCREASE_Z = c -> c[2]++;
private static final IntArrayConsumer DECREASE_Z = c -> c[2]--;
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_POS_Z_POS = new IntArrayConsumer[] { INCREASE_Y, INCREASE_Z, DECREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_POS_Z_NEG = new IntArrayConsumer[] { INCREASE_Y, DECREASE_Z, DECREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_NEG_Z_POS = new IntArrayConsumer[] { DECREASE_Y, INCREASE_Z, INCREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_NEG_Z_NEG = new IntArrayConsumer[] { DECREASE_Y, DECREASE_Z, INCREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_POS_X_POS = new IntArrayConsumer[] { INCREASE_Z, INCREASE_X, DECREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_POS_X_NEG = new IntArrayConsumer[] { INCREASE_Z, DECREASE_X, DECREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_NEG_X_POS = new IntArrayConsumer[] { DECREASE_Z, INCREASE_X, INCREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_NEG_X_NEG = new IntArrayConsumer[] { DECREASE_Z, DECREASE_X, INCREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_POS_Y_POS = new IntArrayConsumer[] { INCREASE_Y, INCREASE_X, DECREASE_Y /* INCREASE_X, INCREASE_Y, DECREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_POS_Y_NEG = new IntArrayConsumer[] { DECREASE_Y, INCREASE_X, INCREASE_Y /* INCREASE_X, DECREASE_Y, DECREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_POS = new IntArrayConsumer[] { INCREASE_Y, DECREASE_X, DECREASE_Y /* DECREASE_X, INCREASE_Y, INCREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_NEG = new IntArrayConsumer[] { DECREASE_Y, DECREASE_X, INCREASE_Y /* DECREASE_X, DECREASE_Y, INCREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_POS_Z_POS = new IntArrayConsumer[] { INCREASE_Y,
INCREASE_Z, DECREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_POS_Z_NEG = new IntArrayConsumer[] { INCREASE_Y,
DECREASE_Z, DECREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_NEG_Z_POS = new IntArrayConsumer[] { DECREASE_Y,
INCREASE_Z, INCREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_X_PLANE_Y_NEG_Z_NEG = new IntArrayConsumer[] { DECREASE_Y,
DECREASE_Z, INCREASE_Y };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_POS_X_POS = new IntArrayConsumer[] { INCREASE_Z,
INCREASE_X, DECREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_POS_X_NEG = new IntArrayConsumer[] { INCREASE_Z,
DECREASE_X, DECREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_NEG_X_POS = new IntArrayConsumer[] { DECREASE_Z,
INCREASE_X, INCREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Y_PLANE_Z_NEG_X_NEG = new IntArrayConsumer[] { DECREASE_Z,
DECREASE_X, INCREASE_Z };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_POS_Y_POS = new IntArrayConsumer[] { INCREASE_Y,
INCREASE_X, DECREASE_Y /* INCREASE_X, INCREASE_Y, DECREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_POS_Y_NEG = new IntArrayConsumer[] { DECREASE_Y,
INCREASE_X, INCREASE_Y /* INCREASE_X, DECREASE_Y, DECREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_POS = new IntArrayConsumer[] { INCREASE_Y,
DECREASE_X, DECREASE_Y /* DECREASE_X, INCREASE_Y, INCREASE_X */ };
private static final IntArrayConsumer[] NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_NEG = new IntArrayConsumer[] { DECREASE_Y,
DECREASE_X, INCREASE_Y /* DECREASE_X, DECREASE_Y, INCREASE_X */ };
private final BlockIteratorFactory blockIteratorFactory;
private final BlockOcclusionGetter blockOcclusionGetter;
private final boolean frustumCullingEnabled;
public BlockOcclusionCulling(BlockIteratorFactory blockIteratorFactory, BlockOcclusionGetter blockOcclusionGetter, boolean frustumCullingEnabled) {
public BlockOcclusionCulling(BlockIteratorFactory blockIteratorFactory, BlockOcclusionGetter blockOcclusionGetter,
boolean frustumCullingEnabled)
{
this.blockIteratorFactory = blockIteratorFactory;
this.blockOcclusionGetter = blockOcclusionGetter;
this.frustumCullingEnabled = frustumCullingEnabled;
}
public boolean isVisible(int x, int y, int z, double vectorX, double vectorY, double vectorZ, double directionX, double directionY, double directionZ) {
public boolean isVisible(int x, int y, int z, double vectorX, double vectorY, double vectorZ, double directionX,
double directionY, double directionZ)
{
double centerX = x + 0.5;
double centerY = y + 0.5;
double centerZ = z + 0.5;
@@ -39,33 +59,54 @@ public final class BlockOcclusionCulling {
double differenceY = vectorY - centerY;
double differenceZ = vectorZ - centerZ;
double distanceSquared = differenceX * differenceX + differenceY * differenceY + differenceZ * differenceZ;
return isVisible(x, y, z, centerX, centerY, centerZ, differenceX, differenceY, differenceZ, distanceSquared, directionX, directionY, directionZ);
return isVisible(x, y, z, centerX, centerY, centerZ, differenceX, differenceY, differenceZ, distanceSquared,
directionX, directionY, directionZ);
}
public boolean isVisible(int x, int y, int z, double centerX, double centerY, double centerZ, double differenceX, double differenceY, double differenceZ, double distanceSquared, double directionX, double directionY, double directionZ) {
if (frustumCullingEnabled && (differenceX - directionX) * directionX + (differenceY - directionY) * directionY + (differenceZ - directionZ) * directionZ > 0.) { // Should actually be (difference - Math.sqrt(3.) * direction / 2.) * direction.
public boolean isVisible(int x, int y, int z, double centerX, double centerY, double centerZ, double differenceX,
double differenceY, double differenceZ, double distanceSquared, double directionX, double directionY,
double directionZ)
{
if (frustumCullingEnabled && (differenceX - directionX) * directionX + (differenceY - directionY) * directionY
+ (differenceZ - directionZ) * directionZ > 0.)
{ // Should actually be (difference - Math.sqrt(3.) * direction / 2.) * direction.
return false;
}
double distance = Math.sqrt(distanceSquared);
double fixedDistance = distance == 0. ? Double.NaN : distance;
BlockIterator blockIterator = blockIteratorFactory.getBlockIterator(x, y, z, centerX, centerY, centerZ, differenceX / fixedDistance, differenceY / fixedDistance, differenceZ / fixedDistance, distance);
BlockIterator blockIterator = blockIteratorFactory.getBlockIterator(x, y, z, centerX, centerY, centerZ,
differenceX / fixedDistance, differenceY / fixedDistance, differenceZ / fixedDistance, distance);
int[] ray;
while ((ray = blockIterator.calculateNext()) != null) {
int rayX = ray[0];
int rayY = ray[1];
int rayZ = ray[2];
if (blockOcclusionGetter.isOccludingRay(rayX, rayY, rayZ) && checkNearbyBlocks(x, y, z, ray, rayX, rayY, rayZ, differenceX, differenceY, differenceZ)) {
if (blockOcclusionGetter.isOccludingRay(rayX, rayY, rayZ)
&& checkNearbyBlocks(x, y, z, ray, rayX, rayY, rayZ, differenceX, differenceY, differenceZ))
{
return false;
}
}
return true;
}
private boolean checkNearbyBlocks(int x, int y, int z, int[] ray, int rayX, int rayY, int rayZ, double differenceX, double differenceY, double differenceZ) {
private boolean checkNearbyBlocks(int x, int y, int z, int[] ray, int rayX, int rayY, int rayZ, double differenceX,
double differenceY, double differenceZ)
{
IntArrayConsumer[] nearbyBlocks;
IntArrayConsumer increase;
IntArrayConsumer decrease;
@@ -77,118 +118,195 @@ public final class BlockOcclusionCulling {
double rayDifferenceZ = rayZ - z;
if (absDifferenceX > absDifferenceY) {
if (absDifferenceZ > absDifferenceX) {
double factor = divide(differenceZ, rayDifferenceZ);
rayDifferenceX = multiply(factor, rayDifferenceX) - differenceX;
rayDifferenceY = multiply(factor, rayDifferenceY) - differenceY;
if (rayDifferenceX > 0.) {
if (rayDifferenceY > 0.) {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_POS;
}
} else {
if (rayDifferenceY > 0.) {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_POS_Y_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_POS_Y_POS;
}
}
if (differenceZ > 0.) {
increase = DECREASE_Z;
decrease = INCREASE_Z;
} else {
increase = INCREASE_Z;
decrease = DECREASE_Z;
}
} else {
double factor = divide(differenceX, rayDifferenceX);
rayDifferenceY = multiply(factor, rayDifferenceY) - differenceY;
rayDifferenceZ = multiply(factor, rayDifferenceZ) - differenceZ;
if (rayDifferenceY > 0.) {
if (rayDifferenceZ > 0.) {
nearbyBlocks = NEARBY_BLOCKS_X_PLANE_Y_NEG_Z_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_X_PLANE_Y_NEG_Z_POS;
}
} else {
if (rayDifferenceZ > 0.) {
nearbyBlocks = NEARBY_BLOCKS_X_PLANE_Y_POS_Z_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_X_PLANE_Y_POS_Z_POS;
}
}
if (differenceX > 0.) {
increase = DECREASE_X;
decrease = INCREASE_X;
} else {
increase = INCREASE_X;
decrease = DECREASE_X;
}
}
} else if (absDifferenceY > absDifferenceZ) {
double factor = divide(differenceY, rayDifferenceY);
rayDifferenceZ = multiply(factor, rayDifferenceZ) - differenceZ;
rayDifferenceX = multiply(factor, rayDifferenceX) - differenceX;
if (rayDifferenceZ > 0.) {
if (rayDifferenceX > 0.) {
nearbyBlocks = NEARBY_BLOCKS_Y_PLANE_Z_NEG_X_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_Y_PLANE_Z_NEG_X_POS;
}
} else {
if (rayDifferenceX > 0.) {
nearbyBlocks = NEARBY_BLOCKS_Y_PLANE_Z_POS_X_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_Y_PLANE_Z_POS_X_POS;
}
}
if (differenceY > 0.) {
increase = DECREASE_Y;
decrease = INCREASE_Y;
} else {
increase = INCREASE_Y;
decrease = DECREASE_Y;
}
} else {
double factor = divide(differenceZ, rayDifferenceZ);
rayDifferenceX = multiply(factor, rayDifferenceX) - differenceX;
rayDifferenceY = multiply(factor, rayDifferenceY) - differenceY;
if (rayDifferenceX > 0.) {
if (rayDifferenceY > 0.) {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_NEG_Y_POS;
}
} else {
if (rayDifferenceY > 0.) {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_POS_Y_NEG;
} else {
nearbyBlocks = NEARBY_BLOCKS_Z_PLANE_X_POS_Y_POS;
}
}
if (differenceZ > 0.) {
increase = DECREASE_Z;
decrease = INCREASE_Z;
} else {
increase = INCREASE_Z;
decrease = DECREASE_Z;
}
}
for (int step = 0; step < nearbyBlocks.length; step++) {
nearbyBlocks[step].accept(ray);
if (blockOcclusionGetter.isOccludingNearby(ray[0], ray[1], ray[2])) {
continue;
}
increase.accept(ray);
@@ -197,21 +315,29 @@ public final class BlockOcclusionCulling {
rayZ = ray[2];
if (rayX == x && rayY == y && rayZ == z || !blockOcclusionGetter.isOccludingNearby(rayX, rayY, rayZ)) {
return false;
}
decrease.accept(ray);
}
return true;
}
private static double divide(double dividend, double divisor) {
return (divisor == 0. && !Double.isNaN(dividend) ? Math.copySign(1., dividend) : dividend) / divisor;
}
private static double multiply(double factor1, double factor2) {
return (factor2 == 0. ? Math.signum(factor1) : factor1) * factor2;
}
@FunctionalInterface
@@ -221,19 +347,29 @@ public final class BlockOcclusionCulling {
@FunctionalInterface
public interface BlockIteratorFactory {
BlockIterator getBlockIterator(int x, int y, int z, double startX, double startY, double startZ, double directionX, double directionY, double directionZ, double distance);
BlockIterator getBlockIterator(int x, int y, int z, double startX, double startY, double startZ,
double directionX, double directionY, double directionZ, double distance);
}
@FunctionalInterface
public interface BlockOcclusionGetter {
boolean isOccluding(int x, int y, int z);
default boolean isOccludingRay(int x, int y, int z) {
return isOccluding(x, y, z);
}
default boolean isOccludingNearby(int x, int y, int z) {
return isOccluding(x, y, z);
}
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.