42 Commits
Author SHA1 Message Date
NotAlexNoyle 746e2b1c21 Update canonical Gitea links 2026-10-29 09:18:09 -04:00
NotAlexNoyle b12adcda0d Update canonical Gitea links 2026-10-29 09:18:09 -04:00
NotAlexNoyle 19cbd369c8 Exclude CODEOWNERS from language statistics 2026-10-28 15:32:12 -04:00
NotAlexNoyle 15d1410c88 Add CODEOWNERS (one staff approval) 2026-10-28 15:32:12 -04:00
NotAlexNoyle e1a928d90a Persist NoClip state after login (dependent on /gmic) 2026-09-10 13:14:03 -04:00
NotAlexNoyle c3a5c1f5a0 Fix spawn rules 2026-08-08 10:40:07 -04:00
NotAlexNoyle 190610e6f0 Remove unused Utilities-OG API 2026-07-20 00:43:21 -04:00
NotAlexNoyle ee6bcacbec Update Utilities-OG API 2026-05-20 11:46:51 -04:00
NotAlexNoyle ef128e0f7d Update Utilities-OG 2026-05-11 01:00:51 -04:00
NotAlexNoyle ca87bff553 Update Utilities-OG API 2026-04-20 02:38:31 -04:00
NotAlexNoyle 0cc15e557d Soft depend on GMI-OG 2026-04-15 12:44:45 -04:00
NotAlexNoyle a1f5486347 Add compatibility with true-ogGameModeInventories-OG 2026-04-15 12:41:59 -04:00
NotAlexNoyle 33381ec711 Update Utilities-OG API 2026-04-05 13:55:37 -04:00
NotAlexNoyle 32d141f515 Update Utilities-OG API 2026-03-30 05:11:47 -04:00
NotAlexNoyle 2bc16b73fe Update Utilities-OG 2026-03-25 12:02:12 -04:00
NotAlexNoyle 9637eb4133 Update Utilities-OG API 2025-12-13 12:07:40 -05:00
NotAlexNoyle 0cc080d4ef Remove CLA 2025-12-07 23:53:59 -05:00
NotAlexNoyle 06669cff78 Update Utilities-OG dependency 2025-12-07 20:00:00 -05:00
NotAlexNoyle 8d123883c4 Update gradle to 8.14.3 2025-08-15 11:10:45 -04:00
NotAlexNoyle e9e751ca4a Update Utilities-OG API 2025-07-07 09:56:58 -04:00
NotAlexNoyle 50fb568232 Update dependencies 2025-06-21 15:35:31 -04:00
NotAlexNoyle 6cd8bd4b09 Update gradle to 8.14.2, add auto formatting 2025-06-21 07:48:45 -04:00
NotAlexNoyle 6b162a1c33 Update gradle to 8.14.2 2025-06-20 19:27:22 -04:00
NotAlexNoyle b439d9cdc2 Update Utilities-OG API 2025-06-06 09:46:49 -04:00
NotAlexNoyle 4f294370c0 Update gradle to 8.14.1 2025-06-03 17:47:40 -04:00
NotAlexNoyle 5603dfd656 Update CHANGELOG.md 2023-12-07 18:02:07 +00:00
NotAlexNoyle 5498363c8a Update README.md 2023-12-07 17:03:27 +00:00
NotAlexNoyle a8fa79e4b2 Update CHANGELOG.md 2023-12-07 17:01:48 +00:00
NotAlexNoyle 53eb9fb245 Update README.md 2023-12-07 17:00:02 +00:00
NotAlexNoyle 61b0b4470e Update README.md 2023-12-07 16:59:15 +00:00
NotAlexNoyle bb3e8ed5bb 1.2.1 Update - Finalize 1.19 Update 2023-12-06 13:07:46 -05:00
NotAlexNoyle cbd50fcb6a Bump to 1.2 2023-12-02 13:19:31 +00:00
NotAlexNoyle 865e6aecbf Fix typo 2023-12-02 13:17:23 +00:00
NotAlexNoyle 8398f143a7 Update gradle from 7 to 8 2023-12-02 13:16:58 +00:00
NotAlexNoyle 5ccce81d1f Finish 1.19 update 2023-12-02 12:05:23 +00:00
NotAlexNoyle bea9fcaeb0 Fix colors and prefixes in chat 2023-11-30 09:17:22 +00:00
NotAlexNoyle 9d8a4900ce 1.19 Update 2023-11-29 12:37:07 +00:00
NotAlexNoyle 8780b4a65d Update gradle build script, correct indentation 2023-01-10 13:26:27 -05:00
NotAlexNoyle d567724e4d Minor refactor 2022-12-30 04:45:12 -05:00
NotAlexNoyle 18c6c250bd Added link to Spigot
https://www.spigotmc.org/resources/noclip-og.104461/
2022-08-12 04:35:52 +00:00
NotAlexNoyle 3bb8f5672b Update README.md
Added CLA and fixed Icon URLs
2022-08-12 04:18:48 +00:00
NotAlexNoyle f03fd2bd7c Add CLA and image assets 2022-08-12 00:15:58 -04:00
24 changed files with 1330 additions and 441 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
View File
Whitespace-only changes.
+15
View File
@@ -0,0 +1,15 @@
**1.3.0:**
Compatibility with GameModeInventories-OG 3.5.0+: noclip.use permission now bypasses GMI's spectator restriction, so players with noclip access can phase freely. Also fixed a feedback loop where NoClip would spam gamemode-change events every move tick, causing GMI's "not allowed to be a SPECTATOR" message to repeat.
**1.2.1:**
Fix chat colors and prefix
**1.2:**
1.19.4 Update
**1.0:**
Initial Release (1.18.2)
+13 -5
View File
@@ -1,17 +1,27 @@
**NoClip-OG**
![NoClip OG](https://i.imgur.com/HI7rKuT.png)
![Icon](https://git.trueog.net/trueog/NoClip-OG/raw/branch/main/assets/icon.png)
*A Spigot plugin that allows you to phase through solid blocks like in Portal 2's console mode!*
![NoClip OG](https://git.trueog.net/trueog/NoClip-OG/raw/branch/main/assets/example.png)
The most free (as in freedom) and full-featured plugin of it's kind. NoClip-OG will teleport the player to any safe location above them upon exiting NoClip mode, even if it's not the surface of the world.
It works by seamlessly blending together creative and spectator mode. The code is fully documented, and I am happy to answer any questions you have about it. Pull requests and issues are welcomed.
Supports LuckPerms, Java 17, and Gradle. Built against Purpur 1.18.2, though it may support other versions as well.
Supports LuckPerms, Java 17, and Gradle. Built against Purpur 1.19.4, though it may support later versions as well.
Compatible with [GameModeInventories-OG](https://git.trueog.net/trueog/GameModeInventories-OG) (3.5.0+). Players with `noclip.use` permission can freely enter spectator mode even when GMI's `restrict_spectator` option is enabled.
Enter creative with `/gmic` before enabling `/nc`. NoClip remembers the toggle in the player's persistent data across disconnects and restarts, including when the player was standing on the ground. Turning `/nc` off, dying, or leaving creative/spectator while NoClip is active clears it.
[Spawn-OG](https://git.trueog.net/trueog/Spawn-OG) controls restoration. With login safety enabled in a managed world, NoClip resumes when `/gmic` and `noclip.use` are still permitted at the login location or the destination of a configured join teleport or rescue. `/spawnback` checks those same permissions and destination rules. A grounded toggle stays grounded when restored. `spawnog.login-migration.bypass` only exempts players from autopsy migration; it does not govern NoClip, `/gmic`, or `/fly` restoration. NoClip never starts phasing merely because saved player data was loaded; without Spawn-OG, enable it again using `/nc`.
NoClip-OG and all other plugins in the "OG" suite are developed for [TrueOG](https://trueog.net), a 100% free and open source Minecraft Server. Need support? Join our [Discord](https://discord.gg/ma9pMYpBU6) and ask your question in #developer-chat.
All contributors to this repository must sign the Contributor License Agreement. See CLA.txt for details.
Future Enhancements Planned:
- Switching to survival mode should disable NoClip and teleport the player to the nearest safe location above them
@@ -24,6 +34,4 @@ Future Enhancements Planned:
- When the server is halted, players who were inside blocks should be teleported to a safe location or kept in NoClip mode
Changelog:
v1.0 - Initial Release
Changelog [here](https://git.trueog.net/trueog/NoClip-OG/src/branch/main/CHANGELOG.md).
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/bash
# Fetch all submodule content.
git submodule update --force --recursive --init
-75
View File
@@ -1,75 +0,0 @@
plugins {
id "java"
id "com.github.johnrengelman.shadow" version "7.1.2"
}
group = "net.trueog.noclip-og"
version = "1.0"
def apiVersion = "1.18.2"
def targetJavaVersion = 17
processResources {
def props = [
version: version,
apiVersion: apiVersion,
]
inputs.properties props // indicates to rerun if version changes
filesMatching("plugin.yml") {
expand props
}
}
repositories {
mavenCentral()
maven {
url "https://repo.purpurmc.org/snapshots"
}
}
dependencies {
compileOnly "org.purpurmc.purpur:purpur-api:1.18.2-R0.1-SNAPSHOT"
}
shadowJar {
minimize()
}
jar.dependsOn shadowJar
tasks.jar.configure {
classifier = "part"
}
tasks.shadowJar.configure {
classifier = null
}
compileJava {
options.compilerArgs += ["-parameters"]
options.fork = true
options.forkOptions.executable = 'javac'
}
+110
View File
@@ -0,0 +1,110 @@
/* This is free and unencumbered software released into the public domain */
/* ------------------------------ Plugins ------------------------------ */
plugins {
id("java") // Import Java plugin.
id("java-library") // Import Java Library plugin.
id("com.diffplug.spotless") version "8.1.0" // Import Spotless plugin.
id("com.gradleup.shadow") version "8.3.9" // Import Shadow plugin.
id("checkstyle") // Import Checkstyle plugin.
eclipse // Import Eclipse plugin.
kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin.
}
/* --------------------------- 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 = "net.trueog.noclip-og" // Declare bundle identifier.
version = "1.3.0" // Declare plugin version (will be in .jar).
val apiVersion = "1.19" // Declare minecraft server target version.
/* ----------------------------- Resources ----------------------------- */
tasks.named<ProcessResources>("processResources") {
val props = mapOf("version" to version, "apiVersion" to apiVersion)
inputs.properties(props) // Indicates to rerun if version changes.
filesMatching("plugin.yml") { expand(props) }
from("LICENSE") { into("/") } // Bundle licenses into jarfiles.
}
/* ---------------------------- Repos ---------------------------------- */
repositories {
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.
}
/* ---------------------- 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.github.miniplaceholders:miniplaceholders-api:2.2.3") // Import MiniPlaceholders API.
testImplementation("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.mockito:mockito-core:5.14.2")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.2")
}
tasks.test { useJUnitPlatform() }
/* ---------------------- 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("") // Use empty string instead of null.
minimize()
}
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } // Build depends on spotless and shadow.
/* --------------------------- Javac opts ------------------------------- */
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters") // Enable reflection for java code.
options.isFork = true // Run javac in its own process.
options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages.
options.encoding = "UTF-8" // Use UTF-8 file encoding.
}
/* ----------------------------- Auto Formatting ------------------------ */
spotless {
java {
eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting.
leadingTabsToSpaces() // Convert leftover leading tabs to spaces.
removeUnusedImports() // Remove imports that aren't being called.
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting.
target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format.
}
}
checkstyle {
toolVersion = "10.18.1" // Declare checkstyle version to use.
configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file.
isIgnoreFailures = true // Don't fail the build if checkstyle does not pass.
isShowViolations = true // Show the violations in any IDE with the checkstyle plugin.
}
tasks.named("compileJava") {
dependsOn("spotlessApply") // Run spotless before compiling with the JDK.
}
tasks.named("spotlessCheck") {
dependsOn("spotlessApply") // Run spotless before checking if spotless ran.
}
+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.
+3 -1
View File
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+32 -15
View File
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# 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/.
@@ -80,13 +82,11 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# 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"'
# 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
@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -133,22 +133,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
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
@@ -193,18 +200,28 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# 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" \
org.gradle.wrapper.GradleWrapperMain \
-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.
Vendored
+94 -89
View File
@@ -1,89 +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
@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=.
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%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="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!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@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
-1
View File
@@ -1 +0,0 @@
rootProject.name = "NoClip-OG"
+13
View File
@@ -0,0 +1,13 @@
rootProject.name = "NoClip-OG"
ProcessBuilder("sh", "bootstrap.sh").directory(rootDir).inheritIO().start().let {
if (it.waitFor() != 0) throw GradleException("bootstrap.sh failed")
}
file("libs")
.listFiles()
?.filter { it.isDirectory && !it.name.startsWith(".") }
?.forEach { dir ->
include(":libs:${dir.name}")
project(":libs:${dir.name}").projectDir = dir
}
+158 -124
View File
@@ -3,7 +3,8 @@
package plugin;
import org.bukkit.ChatColor;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.command.Command;
@@ -13,148 +14,181 @@ import org.bukkit.entity.Player;
// Extends bukkit class to run commands.
public class CommandManager implements CommandExecutor {
// Keep inheritance of command manager private so nothing else can hook into it and run an unrelated command.
private static CommandManager instance;
String chatTag = ChatColor.translateAlternateColorCodes('&', "&8[&aNoClip &4OG&6&8] ");
// Shared NoClip state, owned by the plugin and injected here.
private final NoClipManager manager;
// Static getter allows multiple players to be processed through the same class declaration.
public static CommandManager getInstance() {
public CommandManager(NoClipManager manager) {
return instance;
this.manager = manager;
}
}
// Extending method from bukkit's CommandManager.
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
// Takes over command execution if plugin is invoked.
if (cmd.getName().equalsIgnoreCase("noclip")) {
// Command execution event handler extending bukkit's CommandManager
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
// Checks to make sure the command is being run in-game and not in the console.
if (sender instanceof Player) {
// Convert sender to player once it has been determined that they are one.
Player player = (Player) sender;
// Only run the command in appropriate gamemodes.
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
// Make sure the player has permission first.
if (player.hasPermission("noclip.use")) {
// Checks whether the "enabled" code has been run for the player yet.
if (Listeners.getInstance().noclip.contains(player.getName())) {
// Remove player from NoClip mode
Listeners.getInstance().noclip.remove(player.getName());
// Teleport player to nearest safe location above their head.
teleportToSafety(player);
// Return player to creative mode so they no longer phase through blocks.
player.setGameMode(GameMode.CREATIVE);
// Confirm that the plugin has been shut off to the user.
player.sendMessage(ChatColor.translateAlternateColorCodes('&', String.valueOf(chatTag) + "&6NoClip mode disabled!"));
}
//
else {
// Keeps track of all players in NoClip mode.
Listeners.getInstance().noclip.add(player.getName());
// Confirm that the plugin has been turned on to the user.
player.sendMessage(ChatColor.translateAlternateColorCodes('&', String.valueOf(chatTag) + "&aNoClip mode enabled!"));
}
}
}
// Do nothing if run from survival mode.
else {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', String.valueOf(chatTag) + "&cERROR: You must be in creative to use this command!"));
}
// Create a colored Prefix using the Minimessage API.
final String chatPrefix = "&8[&aNoClip &4OG&6&8] ";
}
// Do nothing if run from console.
else {
// Send error message to console.
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', String.valueOf(chatTag) + "ERROR: The console cannot execute this command!"));
}
// Takes over command execution if plugin is invoked.
if (cmd.getName().equalsIgnoreCase("noclip")) {
}
// Healthy exit status.
return true;
// Checks to make sure the command is being run in-game and not in the console.
if (sender instanceof Player) {
}
// Convert sender to player once it has been determined that they are one.
final Player player = (Player) sender;
// Teleports player to nearest safe (creative) location.
// Don't use this for survival, it has no mitigation for lava or other threats.
public void teleportToSafety(Player player) {
// Only run the command in appropriate gamemodes.
if (player.getGameMode() == GameMode.CREATIVE
|| player.getGameMode() == GameMode.SPECTATOR && manager.isNoClipping(player.getUniqueId()))
{
// Fetch player location.
Location newPlayerLocation = player.getLocation();
// Assume location is unsafe before testing it.
boolean blockUnsafe = true;
while(blockUnsafe) {
// If location is not air...
if(locationIsSolid(newPlayerLocation, player)) {
// Move location to check one block up.
newPlayerLocation = newPlayerLocation.add(0, 1, 0);
}
// Runs if new foot location is safe.
else {
// Runs if new head location is unsafe.
if(locationIsSolid(newPlayerLocation.add(0, 1, 0), player)) {
// Checks whether the "enabled" code has been run for the player yet.
if (manager.isNoClipping(player.getUniqueId())) {
// Keep scanning for a safe location higher up.
newPlayerLocation = newPlayerLocation.add(0, 1, 0);
}
// Runs if both new head and foot location are safe.
else {
// Remove player from NoClip mode
manager.exitNoClip(player);
// Teleport player to nearest safe location above their head.
teleportToSafety(player, chatPrefix);
// Return player to creative mode so they no longer phase through blocks.
player.setGameMode(GameMode.CREATIVE);
// Makes this the last iteration of the loop.
blockUnsafe = false;
// Teleports player to new, safe location.
player.teleport(newPlayerLocation);
player.sendMessage(ChatColor.translateAlternateColorCodes('&', String.valueOf(chatTag) + "&aYou have been teleported to the nearest safe location above you."));
// Create a colored disabled message using the TextComponent API.
final String disabledMessage = chatPrefix + "&6NoClip mode disabled!";
final TextComponent disabledMessageContainer = LegacyComponentSerializer.legacyAmpersand()
.deserialize(disabledMessage);
}
// Confirm that the plugin has been shut off to the user.
player.sendMessage(disabledMessageContainer);
}
}
}
// Engage NoClip mode, permission permitting.
else if (manager.enterNoClip(player)) {
}
// Create a colored enabled message using the TextComponent API.
final String enabledMessage = chatPrefix + "&aNoClip mode enabled!";
final TextComponent enabledMessageContainer = LegacyComponentSerializer.legacyAmpersand()
.deserialize(enabledMessage);
// Confirm that the plugin has been turned on to the user.
player.sendMessage(enabledMessageContainer);
// Checks whether block will make player stuck or not.
public boolean locationIsSolid(Location location, Player player) {
// If block is unsafe.
if(location.getBlock().getType().isSolid()) {
}
// The only remaining reason entry can fail here is permission.
else {
return true;
}
// If block is safe.
else {
// Create a colored permission error message using the TextComponent API.
final String permissionErrorMessage = chatPrefix
+ "&cERROR: You do not have permission to use this command!";
final TextComponent permissionErrorContainer = LegacyComponentSerializer.legacyAmpersand()
.deserialize(permissionErrorMessage);
return false;
// Send the error message to the player.
player.sendMessage(permissionErrorContainer);
}
}
}
}
}
// Do nothing if run from survival mode.
else {
// Create a colored gamemode error message using the TextComponent API.
final String gamemodeErrorMessage = chatPrefix
+ "&cERROR: You must be in creative to use this command!";
final TextComponent gamemodeErrorContainer = LegacyComponentSerializer.legacyAmpersand()
.deserialize(gamemodeErrorMessage);
// Send the error message to the player.
player.sendMessage(gamemodeErrorContainer);
}
}
// Do nothing if run from console.
else {
// Send error message to console.
sender.sendMessage("[NoClip-OG] ERROR: The console cannot execute this command!");
}
}
// Healthy exit status.
return true;
}
// Teleports player to nearest safe (creative) location.
// Don't use this for survival, it has no mitigation for lava or other threats.
public void teleportToSafety(Player player, String chatPrefix) {
// Fetch player location.
Location newPlayerLocation = player.getLocation();
// Assume location is unsafe before testing it.
boolean blockUnsafe = true;
while (blockUnsafe) {
// If location is not air...
if (locationIsSolid(newPlayerLocation, player)) {
// Move location to check one block up.
newPlayerLocation = newPlayerLocation.add(0, 1, 0);
}
// Runs if new foot location is safe.
else {
// Runs if new head location is unsafe.
if (locationIsSolid(newPlayerLocation.add(0, 1, 0), player)) {
// Keep scanning for a safe location higher up.
newPlayerLocation = newPlayerLocation.add(0, 1, 0);
}
// Runs if both new head and foot location are safe.
else {
// Makes this the last iteration of the loop.
blockUnsafe = false;
// Teleports the player to a new, safe location above them.
player.teleport(newPlayerLocation);
// Create a colored disabled message using the TextComponent API.
final String nearesetSafeLocationMessage = chatPrefix
+ "&aYou have been teleported to the nearest safe location above you.";
final TextComponent nearesetSafeLocationContainer = LegacyComponentSerializer.legacyAmpersand()
.deserialize(nearesetSafeLocationMessage);
// Inform the player that their return teleport location has changed.
player.sendMessage(nearesetSafeLocationContainer);
}
}
}
}
// Checks whether block will make player stuck or not.
public boolean locationIsSolid(Location location, Player player) {
// If block is unsafe.
if (location.getBlock().getType().isSolid()) {
return true;
}
// If block is safe.
else {
return false;
}
}
}
+130 -90
View File
@@ -3,131 +3,171 @@
package plugin;
import java.util.ArrayList;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class Listeners implements Listener {
// Declare instance of class as static so multiple players can use it.
private static Listeners instance;
// Declare object to hold players in NoClip mode in memory
public ArrayList<String> noclip = new ArrayList<>();;
// Declare bukkit object to determine whether a player is intentionally trying to phase into a block or not
private final BlockFace[] surrounding;
// Allow phasing into a block from any direction
public Listeners() {
// Shared NoClip state, owned by the plugin and injected here.
private final NoClipManager manager;
// Declare bukkit object to determine whether a player is intentionally trying
// to phase into a block or not
private final BlockFace[] surrounding;
this.surrounding = new BlockFace[] { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST };
instance = this;
// Allow phasing into a block from any direction
public Listeners(NoClipManager manager) {
}
this.manager = manager;
this.surrounding = new BlockFace[] { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST,
BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST };
// Return instance of class as static so multiple players can use it.
public static Listeners getInstance() {
return instance;
}
}
// Hooks player movement event
@EventHandler
public void onNearBlock(PlayerMoveEvent playerMovement) {
// Hooks player movement event
@EventHandler
public void onNearBlock(PlayerMoveEvent playerMovement) {
// Derive the relevant player object from their movement event
Player player = playerMovement.getPlayer();
// Derive the relevant player object from their movement event
final Player player = playerMovement.getPlayer();
// If player is not in survival AND they have a registered NoClip instance in the array list
if ((player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) && this.noclip.contains(player.getName())) {
// If player is not in survival AND they have a registered NoClip instance
if ((player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
&& manager.isNoClipping(player.getUniqueId()))
{
// If player is trying to phase into a block, do this
if (nearBlock(player)) {
// If player is trying to phase into a block, do this
if (nearBlock(player)) {
// Use spectator mode to enable phasing
player.setGameMode(GameMode.SPECTATOR);
}
else {
// Use spectator mode to enable phasing (skip if already set to avoid
// firing PlayerGameModeChangeEvent every tick, which can spam listeners
// on other plugins that restrict spectator mode)
if (player.getGameMode() != GameMode.SPECTATOR) {
// User creative mode to disable phasing
player.setGameMode(GameMode.CREATIVE);
}
player.setGameMode(GameMode.SPECTATOR);
}
}
}
} else {
// Hook player death listener
@EventHandler
public void onPlayerDeath(PlayerDeathEvent playerThatDied) {
// Use creative mode to disable phasing (skip if already set)
if (player.getGameMode() != GameMode.CREATIVE) {
// Derive player object from their death event
Player player = playerThatDied.getEntity();
player.setGameMode(GameMode.CREATIVE);
// If player has a NoClip instance in the array list...
if (Listeners.getInstance().noclip.contains(player.getName())) {
}
// Remove player from NoClip mode
Listeners.getInstance().noclip.remove(player.getName());
// Set gamemode back to survival upon death
player.setGameMode(GameMode.SURVIVAL);
}
}
}
// Determine if a player is trying to phase into their environment
public boolean nearBlock(Player player) {
// Declare array to hold block locations at and near the player
Location[] nearby = {
player.getLocation(),
player.getLocation().add(0.0D, 1.0D, 0.0D),
player.getLocation().add(0.0D, 2.0D, 0.0D)
};
}
// First loop runs as many times as there are locations near and at the player which we have declared in the nearby array
for (int i = 0; i < nearby.length; i++) {
}
// Feed surrounding block faces into an array for evaluation
BlockFace[] arrayOfBlockFace = this.surrounding;
// Second loop evaluates all relevant block faces at current frame of reference
for (int j = 0; j < arrayOfBlockFace.length; j++) {
// Hook player death listener
@EventHandler
public void onPlayerDeath(PlayerDeathEvent playerThatDied) {
// Isolates the block face to phase into
BlockFace staringAt = arrayOfBlockFace[j];
// Derive player object from their death event
final Player player = playerThatDied.getEntity();
// If the block is solid, initiate the phase
if (! nearby[i].getBlock().getRelative(staringAt, 1).isEmpty()) {
// Player is near block and wants to phase into it
return true;
}
// If player has a NoClip instance in the set...
if (manager.exitNoClip(player)) {
}
// Set gamemode back to survival upon death
player.setGameMode(GameMode.SURVIVAL);
}
}
// If nearby blocks are not empty, player is near a block
if (! player.getLocation().add(0.0D, 2.0D, 0.0D).getBlock().isEmpty() || ! player.getLocation().subtract(0.0D, 1.0D, 0.0D).getBlock().isEmpty()) {
}
return true;
}
// /gmic off and region-enforced survival end the active toggle. Cancelled
// changes and creative/spectator phasing leave it intact. An inactive login
// may be normalized before Spawn-OG reads the saved toggle, so leave it alone.
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onGameModeChange(PlayerGameModeChangeEvent event) {
// None of the conditions have been met for phasing
return false;
if (event.getNewGameMode() != GameMode.CREATIVE && event.getNewGameMode() != GameMode.SPECTATOR
&& manager.isNoClipping(event.getPlayer().getUniqueId()))
manager.exitNoClip(event.getPlayer());
}
}
}
// MONITOR so Spawn-OG's LOWEST-priority quit snapshot reads NoClip state
// before it is cleared here. Kicks funnel into this same quit event; a
// dedicated kick handler would run before that snapshot and corrupt it.
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent playerThatQuit) {
// Derive player object from their quit event
final Player player = playerThatQuit.getPlayer();
// If player has a NoClip instance in the set...
if (manager.suspendNoClip(player)) {
// Leave creative behind, never spectator, so a relog on a server
// without Spawn-OG does not strand the player phased into a block.
if (player.getGameMode() != GameMode.CREATIVE) {
player.setGameMode(GameMode.CREATIVE);
}
}
}
// Determine if a player is trying to phase into their environment
public boolean nearBlock(Player player) {
// Declare array to hold block locations at and near the player
final Location[] nearby = { player.getLocation(), player.getLocation().add(0.0D, 1.0D, 0.0D),
player.getLocation().add(0.0D, 2.0D, 0.0D) };
// First loop runs as many times as there are locations near and at the player
// which we have declared in the
// nearby array
for (int i = 0; i < nearby.length; i++) {
// Feed surrounding block faces into an array for evaluation
final BlockFace[] arrayOfBlockFace = this.surrounding;
// Second loop evaluates all relevant block faces at current frame of reference
for (int j = 0; j < arrayOfBlockFace.length; j++) {
// Isolates the block face to phase into
final BlockFace staringAt = arrayOfBlockFace[j];
// If the block is solid, initiate the phase
if (!nearby[i].getBlock().getRelative(staringAt, 1).isEmpty()) {
// Player is near block and wants to phase into it
return true;
}
}
}
// If nearby blocks are not empty, player is near a block
if (!player.getLocation().add(0.0D, 2.0D, 0.0D).getBlock().isEmpty()
|| !player.getLocation().subtract(0.0D, 1.0D, 0.0D).getBlock().isEmpty())
{
return true;
}
// None of the conditions have been met for phasing
return false;
}
}
+50 -38
View File
@@ -3,54 +3,66 @@
package plugin;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
// Extending this class is standard bukkit boilerplate for any plugin, or the server software won't load the classes.
// Extending this class is standard bukkit boilerplate for any plugin, or else the server software won't load the
// classes.
public class NoClip extends JavaPlugin {
// Shared NoClip state, injected into the listener and the command handler.
private NoClipManager manager;
// Keep plugin class private so nothing else can use it.
private static NoClip instance;
// What to do when the plugin is run by the server.
public void onEnable() {
// Getter for instance of primary class. Each new instance in memory is a new player.
public NoClip() {
instance = this;
}
// Create the shared state holder before anything can consume it.
manager = new NoClipManager(new NamespacedKey(this, "enabled"));
// Register the instantiation of the plugin (triggers loading with messages in
// console).
getServer().getPluginManager().registerEvents(new Listeners(manager), (Plugin) this);
// Run command when plugin event is triggered.
getCommand("noclip").setExecutor(new CommandManager(manager));
// Public getter for plugin execution
public static NoClip getPlugin() {
return instance;
}
// What to do when the plugin is run by the server.
public void onEnable() {
}
// Register the instantiation of the plugin (triggers loading with messages in console).
Bukkit.getServer().getPluginManager().registerEvents(new Listeners(), (Plugin) this);
// Run command when plugin event is triggered.
getCommand("noclip").setExecutor(new CommandManager());
}
// What to do when the plugin is disabled by the server (such as during a reboot).
public void onDisable() {
// Loop runs once for every player in NoClip mode
for (String userName : Listeners.getInstance().noclip) {
// Compile-time API for depending plugins (such as Spawn-OG) to query and
// drive NoClip state on their own players.
public NoClipManager getManager() {
// Get player out of block-phase (spectator) mode
Bukkit.getPlayer(userName).setGameMode(GameMode.CREATIVE);
// Remove player from active list
Listeners.getInstance().noclip.remove(userName);
return manager;
}
}
}
}
// What to do when the plugin is disabled by the server (such as during a
// reboot).
public void onDisable() {
if (manager == null)
return;
// Iterate a snapshot copy so removal cannot upset the loop.
for (UUID playerId : manager.activePlayers()) {
// The player may already be gone; only touch the ones still online.
final Player player = Bukkit.getPlayer(playerId);
// Stop the live session before any gamemode listeners can mistake
// shutdown cleanup for an intentional exit.
manager.suspendNoClip(player);
if (player != null && player.isOnline()) {
// Get player out of block-phase (spectator) mode.
player.setGameMode(GameMode.CREATIVE);
}
}
}
}
+113
View File
@@ -0,0 +1,113 @@
// This is free and unencumbered software released into the public domain.
// Author: NotAlexNoyle (admin@true-og.net)
package plugin;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.GameMode;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
// Owns the set of players in NoClip mode. Keyed by UUID so a username change
// cannot orphan or hijack an entry. Main-thread only, like all Bukkit state.
// Depending plugins reach this through NoClip#getManager().
public class NoClipManager {
// Players currently in NoClip mode.
private final Set<UUID> active = new HashSet<>();
// Saved with the player, independently of the live phasing session. Spawn-OG
// decides when it may be restored; loading player data never enables /nc.
private final NamespacedKey intentKey;
public NoClipManager(NamespacedKey intentKey) {
this.intentKey = intentKey;
}
public boolean hasNoClipIntent(Player player) {
return player != null && Byte.valueOf((byte) 1)
.equals(player.getPersistentDataContainer().get(intentKey, PersistentDataType.BYTE));
}
// Reports whether the player is currently in NoClip mode.
public boolean isNoClipping(UUID playerId) {
return playerId != null && active.contains(playerId);
}
// The caller must put the player in creative before entry. Active phasing
// may re-enter from spectator. Requires noclip.use in either case.
public boolean enterNoClip(Player player) {
// Guard against offline handles passed in by other plugins.
if (player == null || !player.isOnline()) {
return false;
}
// Enter through creative (/gmic) first. Plain spectator must not bypass
// creative's inventory and region rules; active phasing is idempotent.
if (player.getGameMode() != GameMode.CREATIVE
&& !(player.getGameMode() == GameMode.SPECTATOR && isNoClipping(player.getUniqueId())))
{
return false;
}
// Make sure the player has permission first.
if (!player.hasPermission("noclip.use")) {
return false;
}
// Keeps track of all players in NoClip mode. Re-entry is idempotent.
active.add(player.getUniqueId());
player.getPersistentDataContainer().set(intentKey, PersistentDataType.BYTE, (byte) 1);
return true;
}
// Removes the player from NoClip mode without touching gamemode or
// location. Returns false when the player was not in NoClip mode.
public boolean exitNoClip(Player player) {
if (player == null) {
return false;
}
player.getPersistentDataContainer().remove(intentKey);
return suspendNoClip(player);
}
// Disconnect/shutdown stops phasing without forgetting the toggle. Callers
// decide about gamemode and teleports, as with an explicit exit.
public boolean suspendNoClip(Player player) {
if (player == null)
return false;
return active.remove(player.getUniqueId());
}
// Snapshot copy for shutdown cleanup, so callers can mutate while iterating.
public Set<UUID> activePlayers() {
return Set.copyOf(active);
}
}
+6 -3
View File
@@ -1,8 +1,11 @@
name: NoClip-OG
version: 1.0
author: NotAlexNoyle
description: A Spigot plugin that allows you to phase through solid blocks like in Portal 2's console mode!
website: https://git.trueog.net/trueog/NoClip-OG
version: '${version}'
api-version: '${apiVersion}'
main: plugin.NoClip
api-version: 1.18
softdepend: [GameModeInventories-OG]
commands:
noclip:
@@ -12,4 +15,4 @@ commands:
permissions:
noclip.use:
description: Permission to phase through blocks.
default: op
default: op
+147
View File
@@ -0,0 +1,147 @@
package plugin;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyByte;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import org.bukkit.GameMode;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class NoClipManagerTest {
private final NamespacedKey key = NamespacedKey.fromString("noclip-og:enabled");
private final Player player = mock(Player.class);
private final NoClipManager manager = new NoClipManager(key);
private final AtomicReference<Byte> saved = new AtomicReference<>();
@BeforeEach
void setUp() {
when(player.getUniqueId()).thenReturn(UUID.randomUUID());
when(player.isOnline()).thenReturn(true);
when(player.getGameMode()).thenReturn(GameMode.CREATIVE);
when(player.hasPermission("noclip.use")).thenReturn(true);
final PersistentDataContainer data = mock(PersistentDataContainer.class);
when(player.getPersistentDataContainer()).thenReturn(data);
when(data.get(key, PersistentDataType.BYTE)).thenAnswer(invocation -> saved.get());
doAnswer(invocation -> {
saved.set(invocation.getArgument(2));
return null;
}).when(data).set(eq(key), eq(PersistentDataType.BYTE), anyByte());
doAnswer(invocation -> {
saved.set(null);
return null;
}).when(data).remove(key);
}
@Test
void quitAndReloadRememberToggleWithoutStartingPhasing() {
assertTrue(manager.enterNoClip(player));
final PlayerQuitEvent quit = mock(PlayerQuitEvent.class);
when(quit.getPlayer()).thenReturn(player);
new Listeners(manager).onPlayerQuit(quit);
assertFalse(manager.isNoClipping(player.getUniqueId()));
assertTrue(manager.hasNoClipIntent(player));
final NoClipManager reloaded = new NoClipManager(key);
assertTrue(reloaded.hasNoClipIntent(player));
assertFalse(reloaded.isNoClipping(player.getUniqueId()));
assertTrue(reloaded.enterNoClip(player));
assertTrue(reloaded.isNoClipping(player.getUniqueId()));
}
@Test
void explicitExitForgetsToggleEvenWhenSuspended() {
manager.enterNoClip(player);
manager.suspendNoClip(player);
manager.exitNoClip(player);
assertFalse(new NoClipManager(key).hasNoClipIntent(player));
}
@Test
void deathForgetsToggle() {
manager.enterNoClip(player);
final PlayerDeathEvent death = mock(PlayerDeathEvent.class);
when(death.getEntity()).thenReturn(player);
new Listeners(manager).onPlayerDeath(death);
assertFalse(manager.isNoClipping(player.getUniqueId()));
assertFalse(manager.hasNoClipIntent(player));
}
@Test
void creativeSpectatorPhasingRetainsToggleButGmicOffClearsIt() {
manager.enterNoClip(player);
final PlayerGameModeChangeEvent change = mock(PlayerGameModeChangeEvent.class);
when(change.getPlayer()).thenReturn(player);
when(change.getNewGameMode()).thenReturn(GameMode.SPECTATOR);
final Listeners listeners = new Listeners(manager);
listeners.onGameModeChange(change);
assertTrue(manager.isNoClipping(player.getUniqueId()));
assertTrue(manager.hasNoClipIntent(player));
when(change.getNewGameMode()).thenReturn(GameMode.SURVIVAL);
listeners.onGameModeChange(change);
assertFalse(manager.isNoClipping(player.getUniqueId()));
assertFalse(manager.hasNoClipIntent(player));
}
@Test
void loginNormalizationDoesNotEraseSuspendedIntent() {
manager.enterNoClip(player);
manager.suspendNoClip(player);
final PlayerGameModeChangeEvent change = mock(PlayerGameModeChangeEvent.class);
when(change.getPlayer()).thenReturn(player);
when(change.getNewGameMode()).thenReturn(GameMode.SURVIVAL);
new Listeners(manager).onGameModeChange(change);
assertTrue(manager.hasNoClipIntent(player));
}
@Test
void entryRequiresCreativeAndPermissionButActivePhasingIsIdempotent() {
when(player.getGameMode()).thenReturn(GameMode.SPECTATOR);
assertFalse(manager.enterNoClip(player));
when(player.getGameMode()).thenReturn(GameMode.SURVIVAL);
assertFalse(manager.enterNoClip(player));
when(player.getGameMode()).thenReturn(GameMode.CREATIVE);
when(player.hasPermission("noclip.use")).thenReturn(false);
assertFalse(manager.enterNoClip(player));
assertFalse(manager.hasNoClipIntent(player));
when(player.hasPermission("noclip.use")).thenReturn(true);
assertTrue(manager.enterNoClip(player));
when(player.getGameMode()).thenReturn(GameMode.SPECTATOR);
assertTrue(manager.enterNoClip(player));
when(player.isOnline()).thenReturn(false);
assertFalse(manager.enterNoClip(player));
}
}