79 Commits
Author SHA1 Message Date
NotAlexNoyle 34dc28b3c1 Point submodules at canonical Gitea repositories 2026-11-01 12:52:59 -05:00
NotAlexNoyle eb117db784 Update canonical Gitea links 2026-10-31 11:41:20 -04:00
NotAlexNoyle c8dec26372 Exclude CODEOWNERS from language statistics 2026-10-31 09:54:56 -04:00
NotAlexNoyle 510418c689 Add CODEOWNERS (one staff approval) 2026-10-31 09:54:56 -04:00
NotAlexNoyle dbfdd62217 Update Utilities-OG API 2026-09-14 02:05:39 -04:00
NotAlexNoyle 1b9cb42cfd Update DiamondBank-OG API 2026-07-29 11:41:19 -04:00
NotAlexNoyle 30e548d4ca Update DiamondBank-OG API 2026-07-27 08:01:57 -04:00
NotAlexNoyle b1561bb7f1 Update DiamondBank-OG API 2026-07-22 07:09:59 -04:00
NotAlexNoyle 6d3a36d787 Update Utilities-OG API 2026-07-20 00:52:37 -04:00
NotAlexNoyle 81cc8965c2 Update GxUI-OG 2026-07-17 12:51:30 -04:00
NotAlexNoyle 854a06dbb3 Fix signs 2026-07-15 15:50:31 -04:00
NotAlexNoyle 4bbdac1a96 Remove broken sign 2026-07-15 15:32:44 -04:00
NotAlexNoyle 06fa21a2a1 Remove stale signs 2026-05-25 11:54:55 -04:00
NotAlexNoyle 090d4b33e3 Remove stale signs 2026-05-25 11:22:12 -04:00
NotAlexNoyle 5ca4ec60db Update GxUI-OG 2026-05-21 11:38:33 -04:00
NotAlexNoyle 16a893f7db Update Utilities-OG API 2026-05-20 11:21:51 -04:00
NotAlexNoyle ee3eeabf10 Update Utilities-OG 2026-05-11 00:55:23 -04:00
NotAlexNoyle dfa2e7d95f Fix duplicate handling, delete invalid signs with /ss delete 2026-04-23 13:50:42 -04:00
NotAlexNoyle acfcbe4ea1 Update GxUI-OG and Utilities-OG APIs 2026-04-20 02:15:57 -04:00
NotAlexNoyle 951900d827 More detailed errors 2026-04-14 14:14:33 -04:00
NotAlexNoyle 9891ddc85c Fix sign detection and de-duplicate sign config 2026-04-13 04:22:22 -04:00
NotAlexNoyle 77e50f83ac Update DiamondBank-OG API 2026-04-07 09:28:59 -04:00
NotAlexNoyle aedcfecd0d Optimize Hopper checks 2026-04-06 02:52:13 -04:00
NotAlexNoyle e11979a4d4 Update DiamondBank-OG API 2026-04-06 00:20:18 -04:00
NotAlexNoyle e04e0defd0 DiamondBank-OG API Update 2026-04-05 13:37:58 -04:00
NotAlexNoyle 47bea30ba0 Update TrueOG Network APIs 2026-04-05 13:13:47 -04:00
NotAlexNoyle 61792b1f52 Update DiamondBank-OG API 2026-04-05 11:13:39 -04:00
NotAlexNoyle 71cc15863d Update DiamondBank-OG API 2026-04-04 14:10:52 -04:00
NotAlexNoyle 4c82e3b229 Update DiamondBank-OG API 2026-04-01 15:30:40 -04:00
NotAlexNoyle a1898bfb01 Update DiamondBank-OG API 2026-04-01 05:58:20 -04:00
NotAlexNoyle 44e855cfbb Update DiamondBank-OG API 2026-04-01 05:03:41 -04:00
NotAlexNoyle 48d7b49a78 Update DiamondBank-OG API 2026-03-30 08:36:41 -04:00
NotAlexNoyle 51a5748dde Update Utilities-OG API 2026-03-30 05:10:06 -04:00
NotAlexNoyle 22122393cd Update Utilities-OG 2026-03-25 11:58:16 -04:00
NotAlexNoyle b4d2590962 Fix depends 2026-03-24 11:16:50 -04:00
NotAlexNoyle a0003bf608 Update DiamondBank-OG 2026-03-11 00:28:21 -04:00
NotAlexNoyle 10122c5440 Fix GxUI-OG 2026-03-09 05:22:06 -04:00
NotAlexNoyle b759d2ad56 Depend on DiamondBank-OG 2026-03-02 06:11:59 -05:00
NotAlexNoyle d11cf4cb2e 1.3 Update 2026-03-02 05:45:18 -05:00
NotAlexNoyle cbab8af288 Update DiamondBank-OG API 2026-01-24 10:57:28 -05:00
NotAlexNoyle e607a983d9 Update DiamondBank-OG API 2026-01-19 13:31:00 -05:00
NotAlexNoyle 96452cb51e Include TrueOG Network config file 2025-12-26 12:43:43 -05:00
NotAlexNoyle 9f00558489 Use TrueOG Network config file, relocate dependencies 2025-12-26 12:01:48 -05:00
NotAlexNoyle de22c0b99d Update TrueOG libraries 2025-12-11 07:39:49 -05:00
NotAlexNoyle b84274368a Update GxUI-OG 2025-12-07 21:02:18 -05:00
NotAlexNoyle 5bf281f6b8 Update dependencies 2025-12-07 19:11:22 -05:00
NotAlexNoyle abfa8cf769 Update DiamondBank-OG API 2025-11-12 00:52:28 -05:00
NotAlexNoyle 1b8d8733d4 Update DB-OG API 2025-09-27 17:19:23 -04:00
NotAlexNoyle 9d09a3b220 Update DiamondBank-OG API 2025-08-27 12:41:07 -04:00
NotAlexNoyle 6257edaf1c Update eclise.gradle.kts 2025-08-27 11:51:27 -04:00
NotAlexNoyle bb70b3a5c6 Update gradle to 8.14.3, add formatting 2025-08-18 14:39:53 -04:00
NotAlexNoyle ca20c02f45 Update DiamondBank-OG API 2025-07-09 11:20:31 -04:00
NotAlexNoyle c8cc35cfb7 Update Utilities-OG dependency 2025-07-07 11:39:35 -04:00
NotAlexNoyle 9b027f620d Update dependencies 2025-06-23 20:16:02 -04:00
NotAlexNoyle 8474eb3ad7 Update gradle to 8.14.2, add auto formatting 2025-06-18 20:10:12 -04:00
NotAlexNoyle 5b2dcaf652 Update dependencies 2025-06-18 14:12:23 -04:00
NotAlexNoyle 517355ee2a Update DiamondBank-OG dependency 2025-06-11 19:31:42 -04:00
NotAlexNoyle 53cf20ba5d Update DiamondBank dependency 2025-06-11 15:54:47 -04:00
NotAlexNoyle 1d06e2858f Update DiamondBank-OG 2025-06-11 15:36:41 -04:00
NotAlexNoyle 134f2c1ff8 Update DiamondBank-OG 2025-06-11 11:59:47 -04:00
NotAlexNoyle 6ba351c1d6 Update gradle to 8.14.1 2025-06-06 08:46:18 -04:00
NotAlexNoyle 3770ea5c98 Fix typo 2023-12-30 20:35:04 +00:00
NotAlexNoyle 3fdd50cb65 1.2.3 Update 2023-12-30 20:23:36 +00:00
NotAlexNoyle 69fd426d47 1.2.2 Update 2023-12-28 18:59:29 -05:00
NotAlexNoyle a64da4ac91 1.2.1 Update 2023-12-26 09:48:00 -05:00
NotAlexNoyle e7e40197aa 1.19 Update 2023-12-24 08:14:35 -05:00
MylesMor 60e728ea8f Merge pull request #3 from MylesMor/development
Development
2021-02-26 01:42:43 +00:00
MylesMor 748a9b8279 Fix price issues 2021-02-26 01:40:21 +00:00
Myles c85416ff08 Merge branch 'development' of https://github.com/MylesMor/SudoSigns into development 2020-12-01 01:47:17 +00:00
Myles 55ce1ac0e0 Add TabCompleter and fix bugs 2020-12-01 01:47:15 +00:00
MylesMor b3e2700cd4 Update README.md 2020-11-28 00:37:03 +00:00
Myles ea0da4ff07 Add Vault sign price + UpdateChecker
- Add Vault integration for adding prices to signs.
- Add an UpdateChecker class which informs the user if there is an available update to the plugin.
2020-11-28 00:34:12 +00:00
Myles a9a07f3406 Fix error with Near command 2020-11-20 00:34:45 +00:00
Myles 38ef4279e6 Add sign text editing 2020-11-20 00:26:57 +00:00
Myles 2c152c78d9 Add foundation for sign text editing 2020-11-14 01:03:43 +00:00
Myles 1c320feddc Remove Player Command with Permission
- Removed due to dangerous nature and the fact it doesn't work properly anyway.
2020-11-14 00:47:33 +00:00
Myles aadbaa848d Add delays to messages/commands + reorganise configuration 2020-11-13 02:37:53 +00:00
Myles 0ad76d3abe Fix Multiverse issue
Add Multiverse as a softdepend - fix for issue #2
2020-08-31 14:47:57 +01:00
MylesMor 35934ea25e Update README.md 2020-07-04 16:32:18 +01:00
64 changed files with 6598 additions and 1454 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
+14 -28
View File
@@ -1,28 +1,14 @@
# Compiled class file
*.class
/target
/.idea
/out
*.iml
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
gradle.properties
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
.kotlin/
.classpath
.factorypath
.project
.settings
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
+9
View File
@@ -0,0 +1,9 @@
[submodule "libs/Utilities-OG"]
path = libs/Utilities-OG
url = https://git.trueog.net/trueog/Utilities-OG
[submodule "libs/GxUI-OG"]
path = libs/GxUI-OG
url = https://git.trueog.net/trueog/GxUI-OG
[submodule "libs/DiamondBank-OG"]
path = libs/DiamondBank-OG
url = https://git.trueog.net/trueog/DiamondBank-OG
+66 -15
View File
@@ -1,32 +1,83 @@
![SudoSigns logo](https://mylesmor.dev/sudosigns/logo.png)
# SudoSigns-OG
A modern fork of SudoSigns: A Spigot plugin used to run commands by interacting with a sign. Some inspiration for commands has been taken from [Nokorbis' Command Signs](https://www.spigotmc.org/resources/command-signs.10512/). MylesMor implemented a convenient inventory-based GUI. NotAlexNoyle updated the plugin for 1.19 on behalf of [TrueOG Network](https://true-og.net).
# SudoSigns
A Spigot plugin used to run commands by interacting with a sign. Some inspiration for commands has been taken from [Nokorbis' Command Signs](https://www.spigotmc.org/resources/command-signs.10512/), but all the code is my own, and I have also implemented a convenient inventory-based GUI.
This allows you to perform actions on SudoSigns such as:
* Renaming the SudoSign
* Editing the sign's text
* Adding permissions that a player must have to run the sign's commands
* Adding either player or console commands to a sign
* Adding messages which are shown to the player
* Use colour codes (`&`) on the sign for coloured text
* Use color codes (`&`) on the sign for coloured text
* Adding delays to commands/messages
* (Vault Economy) Setting the price of running a sign
For in-depth details on the command, permissions and features of this plugin, visit the [Wiki](https://github.com/MylesMor/SudoSigns/wiki)!
## Installation
1. Download the Spigot plugin [HERE](https://spigot.com/LINK).
2. Place the JAR file inside your `./plugins` directory.
3. Reload or restart the server.
1. Clone the git repository: [https://git.trueog.net/trueog/SudoSigns-OG](https://git.trueog.net/trueog/SudoSigns-OG).
2. Build the plugin with `./gradlew build`
3. Place the JAR file from SudoSigns-OG/build/libs inside your server's `./plugins` directory.
4. Reload or restart the server.
## Getting Started
Visit the [Getting Started](https://github.com/MylesMor/SudoSigns/wiki/Getting-Started) page to find out how to setup your first SudoSign!
## Issues
The best course of action would be opening an issue [here](https://github.com/MylesMor/SudoSigns/issues), but I will also try to keep up-to-date with the Spigot comments section.
Contact the developer in #plugin-help on the [TrueOG Network Discord](https://discord.gg/ma9pMYpBU6).
In your issue report, please include as much information as possible including:
* The Spigot version
* Any errors in the console (please copy these in full)
* The steps to reproduce the issue
* The Spigot version.
* Any errors in the console (please copy these in full).
* The steps to reproduce the issue.
## Upcoming Features
These features will be available in future updates!
* Edit the sign's text from the GUI menu.
## Planned Features
- Add cooldowns to sign usage.
- Fix messages being sent to chat that should only be captured by SudoSigns.
## Changelog:
**1.3.1:**
- Fix sign detection.
**1.3:**
- Switch from Vault API to [DiamondBank-OG](https://git.trueog.net/trueog/DiamondBank-OG) API.
- Refactor chat messages.
**1.2.3:**
- Added a config option to change the console prefix.
- Added a config option to change the location of the currency symbol.
**1.2.2:**
- Added an option to change or completely disable the prefix in config file (Fix [#5](https://github.com/MylesMor/SudoSigns/issues/5) upstream).
- Added a config option to change the currency symbol.
- Added a config option for whether or not to use decimals in the prices.
**1.2.1:**
- Uppercase color code support.
- Fixed NullPointerException with unrecognized commands.
**1.2.0:**
- 1.19.4 Support.
- Convert from maven to gradle.
- Removed spigot update checker.
- Ignore formatting codes when calculating the maximum line length (Adopt [#4](https://github.com/MylesMor/SudoSigns/pull/4) upstream).
- Lowercase color code support.
- Fixed errors when missing command parameters.
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/bash
# Fetch all submodule content.
git submodule update --force --recursive --init
+125
View File
@@ -0,0 +1,125 @@
/* ------------------------------ 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.
}
extra["kotlinAttribute"] = Attribute.of("kotlin-tag", Boolean::class.javaObjectType)
val kotlinAttribute: Attribute<Boolean> by rootProject.extra
/* --------------------------- JDK / Kotlin ---------------------------- */
java {
sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility.
toolchain { // Select Java toolchain.
languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17.
vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE.
}
}
kotlin { jvmToolchain(17) }
/* ----------------------------- Metadata ------------------------------ */
group = "net.trueog.sudosigns-og" // Declare bundle identifier.
version = "1.3.2" // 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.
maven { url = uri("https://jitpack.io") } // Import Jitpack 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.
compileOnlyApi(project(":libs:Utilities-OG")) // Import TrueOG Network Utilities-OG Java API (from source).
compileOnlyApi(project(":libs:GxUI-OG")) // Import TrueOG Network GxUI-OG Java API (from source).
compileOnlyApi(project(":libs:DiamondBank-OG")) {
attributes { attribute(kotlinAttribute, true) }
} // Import TrueOG network DiamondBank-OG Kotlin API (from source).
}
apply(from = "eclipse.gradle.kts") // Import eclipse classpath support script.
/* ---------------------- 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.
isEnableRelocation = true
relocationPrefix = "${project.group}.shadow"
archiveClassifier.set("") // Use empty string instead of null.
minimize()
}
tasks.jar { enabled = false } // Only the shaded jar is deployable to the server.
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.
}
/* ------------------------------ Eclipse SHIM ------------------------- */
// This can't be put in eclipse.gradle.kts because Gradle is weird.
subprojects {
apply(plugin = "java-library")
apply(plugin = "eclipse")
eclipse.project.name = "${project.name}-${rootProject.name}"
tasks.withType<Jar>().configureEach { archiveBaseName.set("${project.name}-${rootProject.name}") }
}
+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>
+151
View File
@@ -0,0 +1,151 @@
/* This is free and unencumbered software released into the public domain */
import org.gradle.plugins.ide.eclipse.model.EclipseModel
import java.nio.file.Files
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
val kotlinAttribute: Attribute<Boolean> by rootProject.extra
val kotlinPluginProjects = configurations
.getByName("compileClasspath")
.allDependencies
.filterIsInstance<ProjectDependency>()
.filter { it -> it.attributes.getAttribute(kotlinAttribute) != null }
.map { it.path }
kotlinPluginProjects.forEach { evaluationDependsOn(it) }
val ideLibs: Configuration by
configurations.creating {
isCanBeResolved = true
isCanBeConsumed = false
}
configure<EclipseModel> {
project {
name = "SudoSigns-OG"
}
classpath {
plusConfigurations.add(ideLibs)
}
}
val ideLibDir = layout.buildDirectory.dir("ide-libs")
val hashRegex = Regex("-[0-9a-fA-F]{10}(?=\\.jar$)") // Black magic.
val copyTasks = mutableListOf<TaskProvider<Copy>>()
kotlinPluginProjects.forEach { path ->
val sub = project(path)
val shadowJarProv = sub.tasks.named("shadowJar")
val copyTask =
tasks.register<Copy>("ideCopy${sub.name.replaceFirstChar(Char::titlecase)}") {
dependsOn(shadowJarProv)
from(shadowJarProv)
into(ideLibDir)
rename { it.replace(hashRegex, "") } // Remove git commit hash from jarfile.
}
copyTasks += copyTask
}
/* Ensure the jars exist before .classpath is generated */
tasks.named("eclipseClasspath").configure { dependsOn(copyTasks) }
/* Supply those jars to the ideLibs configuration (after evaluation) */
afterEvaluate { dependencies { add("ideLibs", fileTree(ideLibDir) { include("*.jar") }) } }
val injectIdeLibs =
tasks.register("injectIdeLibs") {
dependsOn("eclipse") // run after all eclipse files are generated
doLast {
val cpFile = file(".classpath")
if (!cpFile.exists()) return@doLast
val jars = fileTree(ideLibDir.get()) { include("*.jar") }.files.sortedBy { it.name }
if (jars.isEmpty()) return@doLast
// Parse DOM
val dbf = DocumentBuilderFactory.newInstance()
val doc = dbf.newDocumentBuilder().parse(cpFile)
val root = doc.documentElement
// Helper to see if an entry already exists
fun exists(path: String): Boolean =
root.getElementsByTagName("classpathentry").let { list ->
(0 until list.length).any { i ->
val n = list.item(i)
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
val p = n.attributes?.getNamedItem("path")?.nodeValue
kind == "lib" && p == path
}
}
// Remove any entry that points to ide-libs dir (folder or jars) to avoid dupes
val toRemove = mutableListOf<org.w3c.dom.Node>()
val list = root.getElementsByTagName("classpathentry")
val dirPath = ideLibDir.get().asFile.absolutePath
for (i in 0 until list.length) {
val n = list.item(i)
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
val p = n.attributes?.getNamedItem("path")?.nodeValue ?: ""
if (kind == "lib" && (p == dirPath || p.startsWith("$dirPath/"))) {
toRemove += n
}
}
toRemove.forEach { root.removeChild(it) }
// Append our jar entries LAST
jars.forEach { f ->
val abs = f.absolutePath
if (!exists(abs)) {
val entry = doc.createElement("classpathentry")
entry.setAttribute("kind", "lib")
entry.setAttribute("path", abs)
root.appendChild(entry)
}
}
// Write back pretty
val tf =
TransformerFactory.newInstance().newTransformer().apply {
setOutputProperty(OutputKeys.INDENT, "yes")
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "1")
setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no")
setOutputProperty(OutputKeys.ENCODING, "UTF-8")
}
Files.newBufferedWriter(cpFile.toPath()).use { w -> tf.transform(DOMSource(doc), StreamResult(w)) }
}
}
tasks.named("eclipse").configure { finalizedBy(injectIdeLibs) }
val eclipseModel = extensions.getByType<EclipseModel>()
fun Project.addResolvableEclipseConfigs() {
val jarAttr =
objects.named(org.gradle.api.attributes.LibraryElements::class, org.gradle.api.attributes.LibraryElements.JAR)
val apiAttr = objects.named(org.gradle.api.attributes.Usage::class, org.gradle.api.attributes.Usage.JAVA_API)
val compileOnlyRes =
configurations.create("eclipseCompileOnly") {
extendsFrom(configurations.getByName("compileOnly"))
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
}
val compileOnlyApiRes =
configurations.create("eclipseCompileOnlyApi") {
extendsFrom(configurations.getByName("compileOnlyApi"))
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
}
eclipseModel.classpath.plusConfigurations.addAll(listOf(compileOnlyRes, compileOnlyApiRes))
}
addResolvableEclipseConfigs()
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+251
View File
@@ -0,0 +1,251 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+94
View File
@@ -0,0 +1,94 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
Submodule libs/DiamondBank-OG added at 39d5a2b936.
Submodule
+1
Submodule libs/GxUI-OG added at 287d0eb3ee.
+1
Submodule libs/Utilities-OG added at 8b5c86cc9c.
-34
View File
@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<groupId>dev.mylesmor.sudosigns</groupId>
<artifactId>SudoSigns</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
+13
View File
@@ -0,0 +1,13 @@
rootProject.name = "SudoSigns-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
}
@@ -1,6 +1,18 @@
package dev.mylesmor.sudosigns;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import dev.mylesmor.sudosigns.commands.Commands;
import dev.mylesmor.sudosigns.commands.SudoSignsTabCompleter;
import dev.mylesmor.sudosigns.config.ConfigManager;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
@@ -8,48 +20,81 @@ import dev.mylesmor.sudosigns.listeners.ChatListener;
import dev.mylesmor.sudosigns.listeners.InventoryListener;
import dev.mylesmor.sudosigns.listeners.PlayerListener;
import dev.mylesmor.sudosigns.listeners.SignListener;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.*;
import java.util.function.BiConsumer;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
/**
* Main class for SudoSigns.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
public class SudoSigns extends JavaPlugin {
public static Map<String, SudoSign> signs = new HashMap<>();
public static ArrayList<String> invalidSigns = new ArrayList<>();
public static Map<UUID, SudoUser> users = new HashMap<>();
public static ConfigManager config;
public static Plugin sudoSignsPlugin;
public static String version;
public DiamondBankAPIJava diamondBankAPI;
@Override
public void onEnable() {
String version = getServer().getVersion().split("MC: ")[1];
SudoSigns.version = version.substring(0, version.length()-1);
getServer().getPluginManager().registerEvents(new SignListener(), this);
final String version = getServer().getVersion().split("MC: ")[1];
SudoSigns.version = StringUtils.substring(version, 0, version.length() - 1);
final RegisteredServiceProvider<DiamondBankAPIJava> provider = getServer().getServicesManager()
.getRegistration(DiamondBankAPIJava.class);
if (provider == null) {
getLogger().severe("DiamondBank-OG API is null – disabling plugin.");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
this.diamondBankAPI = provider.getProvider();
getServer().getPluginManager().registerEvents(new SignListener(diamondBankAPI), this);
getServer().getPluginManager().registerEvents(new InventoryListener(), this);
getServer().getPluginManager().registerEvents(new ChatListener(), this);
getServer().getPluginManager().registerEvents(new PlayerListener(), this);
sudoSignsPlugin = this;
config = new ConfigManager();
this.getCommand("sudosigns").setExecutor(new Commands());
// Import signs.yml file(s).
config = new ConfigManager(diamondBankAPI);
config.loadModules();
// Import config.yml file.
getConfig().options().copyDefaults(true);
saveDefaultConfig();
this.getCommand("sudosigns").setExecutor(new Commands(diamondBankAPI));
this.getCommand("sudosigns").setTabCompleter(new SudoSignsTabCompleter());
}
public static Plugin getPlugin() {
return sudoSignsPlugin;
}
public static void setSudoSignsPlugin(Plugin sudoSignsPlugin) {
SudoSigns.sudoSignsPlugin = sudoSignsPlugin;
}
@Override
public void onDisable() {
getLogger().info("SudoSigns-OG v" + version + " has been disabled.");
}
}
}
@@ -1,60 +1,103 @@
package dev.mylesmor.sudosigns.commands;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoUser;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class Commands implements CommandExecutor {
DiamondBankAPIJava diamondBankAPI;
Map<String, BiConsumer<Player, String[]>> commands = new HashMap<>();
public Commands() {
public Commands(DiamondBankAPIJava diamondBankAPI) {
this.diamondBankAPI = diamondBankAPI;
commands.put("help", Help::help);
commands.put("near", Near::near);
commands.put("list", List::list);
commands.put("delete", Delete::delete);
commands.put("edit", Edit::edit);
commands.put("edit", (p, args) -> Edit.edit(p, args, diamondBankAPI));
commands.put("view", View::view);
commands.put("run", Run::run);
commands.put("confirmdelete", Delete::confirmDelete);
commands.put("reload", Reload::reload);
commands.put("create", Create::create);
commands.put("create", (p, args) -> Create.create(p, args, diamondBankAPI));
commands.put("tp", Teleport::tp);
commands.put("copy", Copy::copy);
commands.put("copy", (p, args) -> Copy.copy(p, args, diamondBankAPI));
commands.put("select", Select::select);
commands.put("purge", Purge::purge);
commands.put("confirmpurge", Purge::confirmPurge);
commands.put("fix", Fix::fix);
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if ((sender instanceof Player)) {
final Player p = (Player) sender;
SudoSigns.users.computeIfAbsent(p.getUniqueId(), k -> new SudoUser(p));
try {
BiConsumer<Player, String[]> command = commands.get(args[0].toLowerCase());
if (sender instanceof Player p) {
SudoSigns.users.computeIfAbsent(p.getUniqueId(), k -> new SudoUser(p));
try {
final BiConsumer<Player, String[]> command = commands.get(StringUtils.lowerCase(args[0]));
if (command != null) {
if (args.length > 1) {
String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
final String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
command.accept(p, newArgs);
} else {
command.accept(p, null);
try {
command.accept(p, null);
} catch (CommandException error) {
invalidCommandError(p);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid command!" + ChatColor.GRAY + " Type " + ChatColor.LIGHT_PURPLE + "/ss help " + ChatColor.GRAY + "for a list of commands.", null);
} else {
invalidCommandError(p);
}
} catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
invalidCommandError(p);
}
}
return true;
}
}
private void invalidCommandError(Player p) {
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid command! &6Type &d/ss help &6for a list of valid commands.");
}
}
@@ -1,59 +1,97 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class Copy {
/**
* Copies one sign's data to another.
* @param p The player running the command.
* @param args 1 or 2 arguments: If 1, the name of the new sign. If 2, the name of the old sign in index 0 and name of new one in index 1.
*
* @param p The player running the command.
* @param args 1 or 2 arguments: If 1, the name of the new sign. If 2, the name
* of the old sign in index 0 and name of new one in index 1.
*/
public static void copy(Player p, String[] args) {
public static void copy(Player p, String[] args, DiamondBankAPIJava diamondBankAPI) {
if (p.hasPermission(Permissions.COPY)) {
String oldName = null;
String newName = null;
if (args == null || args.length < 1 || args.length > 2) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss copy [old-sign-name] <new-sign-name>" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p,
"&cERROR: Invalid syntax! &6Correct syntax: &d/ss copy [old-sign-name] <new-sign-name>&6.");
return;
}
if (args.length == 1) {
newName = args[0];
} else {
newName = args[1];
oldName = args[0];
}
if (Util.checkName(newName)) {
SudoSigns.users.get(p.getUniqueId()).setPassThru(newName);
if (oldName == null) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to copy from!", null);
UtilitiesOG.trueogMessage(p, "&6Please click the sign you'd like to copy from.");
SudoSigns.users.get(p.getUniqueId()).setSelectToCopy(true);
} else {
SudoSign oldSign = SudoSigns.signs.get(oldName);
final SudoSign oldSign = SudoSigns.signs.get(oldName);
if (oldSign != null) {
if (!SudoSigns.signs.containsKey(newName)) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to copy to!", null);
SudoSign newSign = new SudoSign(newName);
UtilitiesOG.trueogMessage(p, "&6Please click the sign you'd like to copy to.");
final SudoSign newSign = new SudoSign(newName, diamondBankAPI);
newSign.copyFrom(oldSign);
SudoSigns.users.get(p.getUniqueId()).setCopy(true);
SudoSigns.signs.put(newName, newSign);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% already exists!", newName);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e%NAME% &calready exists!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.GRAY, "A sign with name %NAME% doesn't exist!", oldName);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e%NAME% &cdoes not exist!");
}
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "The name of a SudoSign must only contain numbers and letters!", null);
UtilitiesOG.trueogMessage(p, "&cERROR: The name of a SudoSign must only contain numbers and letters!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,40 +1,67 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class Create {
/**
* Creates a sign.
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click selection).
*
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click
* selection).
*/
public static void create(Player p, String[] args) {
public static void create(Player p, String[] args, DiamondBankAPIJava diamondBankAPI) {
if (p.hasPermission(Permissions.CREATE)) {
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss create <name>" + ChatColor.GRAY + ".", null);
if (args == null) {
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &6Correct syntax: &d/ss create <name>&6.");
return;
}
String name = args[0];
if (Util.checkName(name)) {
if (!SudoSigns.signs.containsKey(name)) {
SudoSigns.users.get(p.getUniqueId()).setCreate(true);
SudoSigns.users.get(p.getUniqueId()).setPassThru(name);
SudoSigns.signs.put(name, new SudoSign(name));
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to create!", null);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% already exists!", name);
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "The name of a SudoSign must only contain numbers and letters!", null);
final String name = args[0];
if (Util.checkName(name)) {
if (!SudoSigns.signs.containsKey(name)) {
SudoSigns.users.get(p.getUniqueId()).setCreate(true);
SudoSigns.users.get(p.getUniqueId()).setPassThru(name);
SudoSigns.signs.put(name, new SudoSign(name, diamondBankAPI));
UtilitiesOG.trueogMessage(p, "&6Please click on the sign you'd like to create.");
} else {
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with name &e" + name + " &calready exists!");
}
} else {
UtilitiesOG.trueogMessage(p,
"&cERROR: The name of a SudoSign must only contain numbers and letters!");
}
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,58 +1,108 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class Delete {
/**
* Deletes a sign.
* @param p The player running the command.
* @param args 1 or 2 arguments: The name of the sign (or null for click selection).
*
* @param p The player running the command.
* @param args 1 or 2 arguments: The name of the sign (or null for click
* selection).
*/
public static void delete(Player p, String[] args) {
if (p.hasPermission(Permissions.DELETE)) {
String name;
final String name;
if (args != null) {
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss delete [name]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &7Correct syntax: &d/ss delete [name]&7.");
return;
}
} else {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to delete!", null);
UtilitiesOG.trueogMessage(p, "&6Please click the sign you'd like to delete.");
SudoSigns.users.get(p.getUniqueId()).setDelete(true);
return;
}
name = args[0];
if (SudoSigns.signs.containsKey(name)) {
SudoSigns.signs.remove(name);
SudoSigns.config.deleteSign(name);
Util.sudoSignsMessage(p, ChatColor.GRAY, "Sign %NAME% successfully deleted!", name);
UtilitiesOG.trueogMessage(p, "&6Sign &e" + name + " &6successfully deleted.");
} else if (SudoSigns.config.getInvalidEntriesManager().purgeInvalidEntry(name, false)) {
UtilitiesOG.trueogMessage(p, "&6Sign &e" + name + " &6successfully deleted.");
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% doesn't exist!", name);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + name + " &cdoes not exist!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
/**
* Confirms deletion of a sign (only run when [DELETE] is clicked in the selection message).
* @param p The player running the command.
* Confirms deletion of a sign (only run when [DELETE] is clicked in the
* selection message).
*
* @param p The player running the command.
* @param args 1 argument: The name of the sign.
*/
public static void confirmDelete(Player p, String[] args) {
if (p.hasPermission(Permissions.DELETE)) {
if (args.length != 1) return;
if (SudoSigns.signs.containsKey(args[0])) {
String message = "[\"\",{\"text\":\"[SUDOSIGNS] \",\"color\":\"yellow\"},{\"text\":\"Are you sure you want to delete sign \",\"color\":\"gray\"},{\"text\":\"" + args[0] + "\",\"color\":\"gold\"},{\"text\":\"? \",\"color\":\"gray\"},{\"text\":\"[YES] \",\"bold\":true,\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss delete " + args[0] + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Yes, delete the sign!\",\"color\":\"green\"}]}}]";
p.spigot().sendMessage(ComponentSerializer.parse(message));
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% doesn't exist!", args[0]);
}
// If the player has permission to delete signs, do this...
if (!p.hasPermission(Permissions.DELETE)) {
return;
}
// If the sign that was selected does not exist, do this...
if (args.length != 1) {
return;
}
if (SudoSigns.signs.containsKey(args[0])) {
// Send a deletion confirmation menu with a clickable button.
Util.selectMenuParser(p, "&c&l[CONFIRM DELETION]",
("&6Are you sure you want to delete sign &e" + args[0] + "&6?"), p.getName(),
("/ss delete " + args[0]), ("&cYes, delete the sign: &6" + args[0] + "&c!"));
} else {
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + args[0] + " &cdoes not exist!");
}
}
}
}
@@ -1,40 +1,63 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class Edit {
/**
* Edits a sign.
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click selection).
*
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click
* selection).
*/
public static void edit(Player p, String[] args) {
public static void edit(Player p, String[] args, DiamondBankAPIJava diamondBankAPI) {
if (p.hasPermission(Permissions.EDIT)) {
String name;
final String name;
if (args == null) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to edit!", null);
UtilitiesOG.trueogMessage(p, "&6Please click on the sign you'd like to edit.");
SudoSigns.users.get(p.getUniqueId()).setEdit(true);
return;
}
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss edit [name]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &aCorrect syntax: &d/ss edit [name]&a.");
return;
}
name = args[0];
if (SudoSigns.signs.containsKey(name)) {
SignEditor editor = new SignEditor(p, SudoSigns.signs.get(name), SudoSigns.users.get(p.getUniqueId()));
final SignEditor editor = new SignEditor(p, SudoSigns.signs.get(name),
SudoSigns.users.get(p.getUniqueId()), diamondBankAPI);
SudoSigns.users.get(p.getUniqueId()).setEditor(editor);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% doesn't exist!", name);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + name + " &cdoes not exist!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,51 +1,92 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class Fix {
/**
* Attempt to fix an invalid entry by placing a sign in the config location.
*
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign.
*/
public static void fix(Player p, String[] args) {
if (p.hasPermission(Permissions.FIX)) {
String name;
final String name;
if (args == null) {
int size = SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size();
final int size = SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size();
if (SudoSigns.config.getInvalidEntriesManager().fixInvalidEntry(null, true)) {
SudoSigns.config.loadSigns();
if (SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size() == 0) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "All invalid entries successfully purged from the config!", null);
UtilitiesOG.trueogMessage(p,
"&aAll invalid entries have been successfully purged from the config.");
} else if (SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size() == size) {
Util.sudoSignsMessage(p, ChatColor.RED, "No invalid entries were able to be fixed automatically!", null);
UtilitiesOG.trueogMessage(p,
"&cERROR: No invalid entries were able to be automatically purged from the config!");
} else if (SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size() < size) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "" + ChatColor.GOLD + (SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size() - size) + " invalid entries were able to be fixed automatically!" + ChatColor.GOLD + Integer.toString(SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size()) + ChatColor.RED + " were unable to be fixed!", null);
UtilitiesOG.trueogMessage(p,
"&e" + (SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size() - size)
+ "&a invalid entries were able to be automatically purged from the config. &e"
+ Integer.toString(
SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size())
+ "&c were unable to be automatically purged from the config!");
}
}
return;
}
if (args.length > 2) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss fix [name]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &6Correct syntax: &d/ss fix [name]&6.");
return;
}
name = args[0];
if (SudoSigns.config.getInvalidEntriesManager().fixInvalidEntry(name, false)) {
SudoSigns.config.loadSigns();
if (SudoSigns.signs.containsKey(name)) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "Sign " + ChatColor.GOLD + name + ChatColor.GREEN + " successfully fixed!", null);
UtilitiesOG.trueogMessage(p, "&aSign &e" + name + "&asuccessfully fixed!");
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "Sign " + ChatColor.GOLD + name + ChatColor.RED + " was unable to be fixed!", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Sign &e" + name + "&c was unable to be fixed!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "Nothing fixed! That entry is not invalid.", null);
UtilitiesOG.trueogMessage(p, "&6WARNING: Nothing fixed! That entry is not invalid.");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,62 +1,113 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Help {
/**
* Sends the player a help message.
* @param p The player running the command.
*
* @param p The player running the command.
* @param args Not required.
*/
public static void help(Player p, String[] args) {
if (p.hasPermission(Permissions.HELP)) {
p.sendMessage(ChatColor.GRAY + "======" + ChatColor.YELLOW + " SudoSigns Help " + ChatColor.GRAY + "======");
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " <>" + ChatColor.GRAY + " indicates a required argument.");
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " []" + ChatColor.GRAY + " indicates an optional argument.");
Util.sudoSignsMessageNoPrefix(p, "&b======" + Util.chatPrefix + " &eHelp" + "&b======");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d <>" + "&f - &6indicates a required argument.");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d []" + "&f - &6indicates an optional argument.");
if (p.hasPermission(Permissions.HELP)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss help" + ChatColor.GRAY + " - Displays this menu.");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d /ss help" + " &f- &6Displays this menu.");
}
if (p.hasPermission(Permissions.LIST)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss list" + ChatColor.GRAY + " - Lists all SudoSigns.");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d /ss list" + " &f- &6Lists all SudoSigns.");
}
if (p.hasPermission(Permissions.NEAR)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss near [radius]" + ChatColor.GRAY + " - Lists SudoSigns within a specified radius (default 5 blocks).");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d /ss near [radius]"
+ " &f- &6Lists SudoSigns within a specified radius (default 5 blocks).");
}
if (p.hasPermission(Permissions.VIEW)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss view [name]" + ChatColor.GRAY + " - Displays the details of a SudoSign.");
Util.sudoSignsMessageNoPrefix(p,
"&e[!]" + "&d /ss view [name]" + " &f- &6Displays the details of a SudoSign.");
}
if (p.hasPermission(Permissions.RUN)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss run [name]" + ChatColor.GRAY + " - Runs a SudoSigns commands remotely.");
Util.sudoSignsMessageNoPrefix(p,
"&e[!]" + "&d /ss run [name]" + " &f- &6Runs a SudoSigns commands remotely.");
}
if (p.hasPermission(Permissions.TP)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss tp [name]" + ChatColor.GRAY + " - Teleport to a SudoSign.");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d /ss tp [name]" + " &f- &6Teleport to a SudoSign.");
}
if (p.hasPermission(Permissions.CREATE)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss create <name>" + ChatColor.GRAY + " - Creates a SudoSign with the specified name.");
Util.sudoSignsMessageNoPrefix(p,
"&e[!]" + "&d /ss create <name>" + " &f- &6Creates a SudoSign with the specified name.");
}
if (p.hasPermission(Permissions.EDIT)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss edit [name]" + ChatColor.GRAY + " - Displays the editor for the specified SudoSign.");
Util.sudoSignsMessageNoPrefix(p,
"&e[!]" + "&d /ss edit [name]" + " &f- &6Displays the editor for the specified SudoSign.");
}
if (p.hasPermission(Permissions.COPY)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss copy [old-sign-name] <new-sign-name>" + ChatColor.GRAY + " - Copies the specified SudoSign to a new sign.");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d /ss copy [old-sign-name] <new-sign-name>"
+ " &f- &6Copies the specified SudoSign to a new sign.");
}
if (p.hasPermission(Permissions.DELETE)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss delete [name]" + ChatColor.GRAY + " - Deletes the specified SudoSign.");
Util.sudoSignsMessageNoPrefix(p,
"&e[!]" + "&d /ss delete [name]" + " &f- &6Deletes the specified SudoSign.");
}
if (p.hasPermission(Permissions.RELOAD)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss reload" + ChatColor.GRAY + " - Reloads the configuration file (signs.yml).");
Util.sudoSignsMessageNoPrefix(p,
"&e[!]" + "&d /ss reload" + " &f- &6Reloads the configuration file (signs.yml).");
}
if (p.hasPermission(Permissions.PURGE)) {
p.sendMessage(ChatColor.YELLOW + "[!]" + ChatColor.LIGHT_PURPLE + " /ss purge [name]" + ChatColor.GRAY + " - Removes a specified invalid entry from the config (leave name black to purge all invalid entries).");
Util.sudoSignsMessageNoPrefix(p, "&e[!]" + "&d /ss purge [name]"
+ " &f- &6Removes a specified invalid entry from the config (leave name blank to purge all invalid entries).");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,34 +1,42 @@
package dev.mylesmor.sudosigns.commands;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.Map;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.trueog.utilitiesog.UtilitiesOG;
public class List {
/**
* Lists all signs.
* @param p The player running the command.
*
* @param p The player running the command.
* @param args Not required
*/
public static void list(Player p, String[] args) {
if (p.hasPermission(Permissions.LIST)) {
if (SudoSigns.signs.size() == 0) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "No SudoSigns were found!", null);
if (SudoSigns.signs.isEmpty()) {
UtilitiesOG.trueogMessage(p, "&cERROR: No SudoSigns were found!");
return;
}
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
String message = Util.getSelectString(p, entry.getKey());
p.spigot().sendMessage(ComponentSerializer.parse(message));
}
UtilitiesOG.trueogMessage(p, "&6Listing all SudoSigns...");
SudoSigns.signs.entrySet().forEach(entry -> Util.sendSelectMenus(p, entry.getKey()));
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,61 +1,106 @@
package dev.mylesmor.sudosigns.commands;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import java.util.Map;
import net.trueog.utilitiesog.UtilitiesOG;
public class Near {
/**
* Displays signs within a set radius.
* @param p The player running the command.
* @param args 0 or 1 arguments, with the only argument being the radius to search in (default is 5 blocks).
*
* @param p The player running the command.
* @param args 0 or 1 arguments, with the only argument being the radius to
* search in (default is 5 blocks).
*/
public static void near(Player p, String[] args) {
if (p.hasPermission(Permissions.NEAR)) {
int r;
String radius = null;
if (args != null) {
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss near [radius]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p,
"&cERROR: Invalid syntax! " + "&6Correct syntax: " + "&d/ss near [radius]" + "&6.");
return;
} else if (args.length == 1) {
radius = args[0];
}
}
if (radius == null) {
r = 5;
} else {
try {
r = Integer.parseInt(radius);
} catch (NumberFormatException e) {
Util.sudoSignsMessage(p, ChatColor.RED, ChatColor.GOLD + radius + ChatColor.RED + " is not a valid number! Reverting to a radius of 5.", null);
} catch (NumberFormatException numberFormatException) {
UtilitiesOG.trueogMessage(p,
"&cERROR: &e" + radius + " &cis not a valid number! &6Reverting to a radius of &e5&6.");
r = 5;
}
}
boolean found = false;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
Location signLoc = entry.getValue().getSign().getLocation();
if (signLoc.distance(p.getLocation()) <= r) {
if (!found) Util.sudoSignsMessage(p, ChatColor.GRAY, "Displaying SudoSigns within a radius of %NAME% block(s):", Integer.toString(r));
found = true;
String message = Util.getSelectString(p, entry.getKey());
p.spigot().sendMessage(ComponentSerializer.parse(message));
final Location signLoc = entry.getValue().getSign().getLocation();
try {
if (signLoc.distance(p.getLocation()) <= r) {
if (!found) {
UtilitiesOG.trueogMessage(p, "&6Displaying SudoSigns within a radius of &e"
+ Integer.toString(r) + " &6block(s):&e");
}
found = true;
Util.sendSelectMenus(p, entry.getKey());
}
} catch (Exception ignored) {
}
}
if (!found) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "No SudoSigns found within a radius of %NAME% block(s).", Integer.toString(r));
UtilitiesOG.trueogMessage(p,
"&6No SudoSigns found within a radius of &e" + Integer.toString(r) + " &6block(s).&e");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,68 +1,123 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class Purge {
/**
* Purge an invalid sign's config entry (or all if name not provided).
*
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign.
*/
public static void purge(Player p, String[] args) {
if (p.hasPermission(Permissions.PURGE)) {
String name = null;
if (args == null) {
purgeAll(p);
return;
}
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss purge [name]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p,
"&cERROR: Invalid syntax! " + "&6Correct syntax: " + "&d/ss purge [name]" + "&6.");
return;
}
if (args.length == 1) name = args[0];
if (args.length == 1) {
name = args[0];
}
if (name != null) {
if (SudoSigns.config.getInvalidEntriesManager().purgeInvalidEntry(args[0], false)) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "Sign " + ChatColor.GOLD + args[0] + ChatColor.GREEN + " successfully purged from the config!", null);
UtilitiesOG.trueogMessage(p, "&aSign &e" + args[0] + "&a successfully purged from the config!");
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "Nothing purged! That entry is not invalid.", null);
UtilitiesOG.trueogMessage(p, "&eWARNING: &6Nothing purged! That entry is not invalid.");
}
} else {
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
private static void purgeAll(Player p) {
int beforeSize = SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size();
final int beforeSize = SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size();
if (beforeSize == 0) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "No invalid entries found to remove from the config!", null);
UtilitiesOG.trueogMessage(p, "&eWARNING: &6No invalid entries found to remove from the config!");
return;
}
if (SudoSigns.config.getInvalidEntriesManager().purgeInvalidEntry(null, true)) {
int afterSize = SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size();
final int afterSize = SudoSigns.config.getInvalidEntriesManager().getInvalidEntries().size();
if (afterSize == 0) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "All invalid entries successfully purged from the config!", null);
UtilitiesOG.trueogMessage(p, "&aAll invalid entries have been successfully purged from the config!");
} else if (afterSize == beforeSize) {
Util.sudoSignsMessage(p, ChatColor.RED, "No invalid entries were able to be removed automatically!", null);
UtilitiesOG.trueogMessage(p, "&cERROR: No invalid entries were able to be removed automatically!");
} else {
Util.sudoSignsMessage(p, ChatColor.GREEN, "" + ChatColor.GOLD + (beforeSize - afterSize) + " invalid entries were able to be removed automatically!" + ChatColor.GOLD + afterSize + ChatColor.RED + " were unable to be removed!", null);
UtilitiesOG.trueogMessage(p,
"&e" + (beforeSize - afterSize)
+ "&a invalid config entries were able to be removed automatically. &e" + afterSize
+ " &6were unable to be removed automatically.");
}
}
return;
}
public static void confirmPurge(Player p, String[] args) {
if (p.hasPermission(Permissions.PURGE)) {
if (args.length != 1) return;
String message = "[\"\",{\"text\":\"[SUDOSIGNS] \",\"color\":\"yellow\"},{\"text\":\"Are you sure you want to purge sign \",\"color\":\"gray\"},{\"text\":\"" + args[0] + "\",\"color\":\"gold\"},{\"text\":\"? \",\"color\":\"gray\"},{\"text\":\"[YES] \",\"bold\":true,\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss purge " + args[0] + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Yes, delete the sign!\",\"color\":\"green\"}]}}]";
p.spigot().sendMessage(ComponentSerializer.parse(message));
if (!p.hasPermission(Permissions.PURGE)) {
return;
}
if (args.length != 1) {
return;
}
Util.selectMenuParser(p, "&a&l[YES]", ("&6Are you sure you want to purge sign &e" + args[0] + "&6?"),
p.getName(), ("/ss purge " + args[0]), ("&aYes, delete the sign: &6" + args[0] + "&a!"));
}
}
@@ -1,59 +1,93 @@
package dev.mylesmor.sudosigns.commands;
import java.util.ArrayList;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.StringJoiner;
import net.trueog.utilitiesog.UtilitiesOG;
public class Reload {
/**
* Reloads the config file (signs.yml)
* @param p The player running the command.
*
* @param p The player running the command.
* @param args Not required
*/
public static void reload(Player p, String[] args) {
if (p.hasPermission(Permissions.RELOAD)) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Reloading config...", null);
UtilitiesOG.trueogMessage(p, "&6Reloading config...");
SudoSigns.signs.clear();
if (SudoSigns.config.loadCustomConfig()) {
ArrayList<String> invalidSigns = SudoSigns.config.loadSigns();
if (invalidSigns != null) {
if (invalidSigns.size() == 0) {
Util.sudoSignsMessage(p, ChatColor.GREEN, "Config successfully reloaded! Found " + invalidSigns.size() + " invalid signs! ", null);
} else {
Util.sudoSignsMessage(p, ChatColor.GREEN, "Config successfully reloaded!" + ChatColor.RED + " Found " + invalidSigns.size() + " invalid sign(s): ", null);
for (String name : invalidSigns) {
StringBuilder clickableMessage = new StringBuilder("[\"\",{\"text\":\"[SUDOSIGNS] \",\"color\":\"yellow\"},{\"text\":\"Sign: \",\"color\":\"red\"},{\"text\":\"" + name + " \",\"bold\":true,\"color\":\"gold\"}]");
final ArrayList<String> invalidSigns = SudoSigns.config.loadSigns();
if (invalidSigns != null) {
if (invalidSigns.size() == 0) {
UtilitiesOG.trueogMessage(p, "&aConfig successfully reloaded! No invalid signs found.");
} else {
UtilitiesOG.trueogMessage(p, "&aConfig successfully reloaded! &cERROR: Found &e"
+ invalidSigns.size() + " &cinvalid signs!");
invalidSigns.forEach(name -> {
// If the player has permission to purge a sign, do this...
if (p.hasPermission(Permissions.PURGE)) {
clickableMessage = new StringBuilder(clickableMessage.substring(0, clickableMessage.length() - 1));
clickableMessage.append(",{\"text\":\"[FIX] \",\"bold\":true,\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss fix ").append(name).append("\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Fix ").append(name).append(" by placing a replica of the sign at the location\",\"color\":\"green\"}]}}]");
// Send a fix confirmation menu with a clickable button.
Util.selectMenuParser(p, "&a&l[FIX]", ("&cSign: &e&l" + name), name,
("/ss fix " + name),
("&6Fix &e" + name + "&6by placing a replica of the sign at the location."));
}
// If the player has permission to fix a sign, do this...
if (p.hasPermission(Permissions.FIX)) {
clickableMessage = new StringBuilder(clickableMessage.substring(0, clickableMessage.length() - 1));
clickableMessage.append(",{\"text\":\"[PURGE]\",\"bold\":true,\"color\":\"red\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss confirmpurge ").append(name).append("\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Remove ").append(name).append(" from the config file\",\"color\":\"red\"}]}}]");
// Send a purge confirmation menu with a clickable button.
Util.selectMenuParser(p, "&c&l[PURGE]", ("&cSign: &e&l" + name), name,
("/ss confirmpurge " + name),
(("&cRemove &e" + name + "&6from the config file.")));
}
p.spigot().sendMessage(ComponentSerializer.parse(clickableMessage.toString()));
}
});
}
return;
}
Bukkit.getLogger().warning("[SUDOSIGNS] There was an error with the SudoSigns config!");
Util.sudoSignsMessage(p, ChatColor.RED, "There was an error with the SudoSigns config! Continuing to use old config...", null);
Bukkit.getLogger().warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "There was an error with the SudoSigns config!");
UtilitiesOG.trueogMessage(p,
"&cERROR: The latest update to the SudoSigns config was invalid! &6Continuing to use old config...");
} else {
Bukkit.getLogger().warning("[SUDOSIGNS] There was an error with the SudoSigns config!");
Util.sudoSignsMessage(p, ChatColor.RED, "There was an error with the SudoSigns config! Please attempt to fix before the next server reload/restart.", null);
Bukkit.getLogger().warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "There was an error with the SudoSigns config!");
UtilitiesOG.trueogMessage(p,
"&cERROR: The latest update to the SudoSigns config was invalid! &6Please attempt to fix it before the next server restart or plugin reload attempt.");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,40 +1,64 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class Run {
/**
* Runs a sign remotely.
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click selection).
*
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click
* selection).
*/
public static void run(Player p, String[] args) {
if (p.hasPermission(Permissions.RUN)) {
String name;
final String name;
if (args == null) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to run!", null);
UtilitiesOG.trueogMessage(p, "&6Please click on the sign you would like to run.");
SudoSigns.users.get(p.getUniqueId()).setRun(true);
return;
}
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss run [name]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &6Correct syntax: &d/ss run [name]&6.");
return;
}
name = args[0];
if (SudoSigns.signs.containsKey(name)) {
SudoSign sign = SudoSigns.signs.get(name);
Util.sudoSignsMessage(p, ChatColor.GRAY, "Executing " + ChatColor.LIGHT_PURPLE + sign.getMessages().size() + ChatColor.GRAY + " messages and " + ChatColor.LIGHT_PURPLE + (sign.getPlayerCommands().size() + sign.getConsoleCommands().size()) + ChatColor.GRAY + " commands...", null);
final SudoSign sign = SudoSigns.signs.get(name);
UtilitiesOG.trueogMessage(p, "&6Executing &e" + sign.getMessages().size() + "&6 message(s) and &e"
+ (sign.getPlayerCommands().size() + sign.getConsoleCommands().size()) + "&6 command(s)...");
SudoSigns.signs.get(name).executeCommands(p);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% doesn't exist!", name);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + name + " &cdoes not exist!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,28 +1,39 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class Select {
/**
* Select a sign (display selection message in chat).
* @param p The player running the command.
*
* @param p The player running the command.
* @param args 1 argument: The name of the sign.
*/
public static void select(Player p, String[] args) {
if (p.hasPermission(Permissions.SELECT)) {
if (args == null || args.length != 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss select <name>" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! " + "&6Correct syntax: &d/ss select <name> &6.");
} else {
String message = Util.getSelectString(p, args[0]);
p.spigot().sendMessage(ComponentSerializer.parse(message));
Util.sendSelectMenus(p, args[0]);
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -0,0 +1,214 @@
package dev.mylesmor.sudosigns.commands;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
public class SudoSignsTabCompleter implements TabCompleter {
@Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String label, String[] args) {
if (commandSender instanceof Player p) {
if (args.length == 1) {
final ArrayList<String> commands = new ArrayList<>();
if (p.hasPermission(Permissions.HELP)) {
commands.add("help");
}
if (p.hasPermission(Permissions.RELOAD)) {
commands.add("reload");
}
if (p.hasPermission(Permissions.CREATE)) {
commands.add("create");
}
if (p.hasPermission(Permissions.LIST)) {
commands.add("list");
}
if (p.hasPermission(Permissions.NEAR)) {
commands.add("near");
}
if (p.hasPermission(Permissions.DELETE)) {
commands.add("delete");
}
if (p.hasPermission(Permissions.VIEW)) {
commands.add("view");
}
if (p.hasPermission(Permissions.RUN)) {
commands.add("run");
}
if (p.hasPermission(Permissions.RELOAD)) {
commands.add("reload");
}
if (p.hasPermission(Permissions.TP)) {
commands.add("tp");
}
if (p.hasPermission(Permissions.COPY)) {
commands.add("copy");
}
if (p.hasPermission(Permissions.SELECT)) {
commands.add("select");
}
if (p.hasPermission(Permissions.PURGE)) {
commands.add("purge");
}
if (p.hasPermission(Permissions.FIX)) {
commands.add("fix");
}
if (p.hasPermission(Permissions.EDIT)) {
commands.add("edit");
}
return commands;
}
if (args.length == 2) {
final ArrayList<String> suggestions = new ArrayList<>();
switch (args[0]) {
case "create" -> {
if (p.hasPermission(Permissions.CREATE)) {
suggestions.add("<sign-name>");
}
return suggestions;
}
case "delete" -> {
if (p.hasPermission(Permissions.DELETE)) {
SudoSigns.signs.values().forEach(s -> suggestions.add(s.getName()));
suggestions.addAll(SudoSigns.invalidSigns);
}
return suggestions;
}
case "view", "run", "tp", "copy", "select", "edit" -> {
if (p.hasPermission(Permissions.SELECT) || p.hasPermission(Permissions.VIEW)
|| p.hasPermission(Permissions.RUN) || p.hasPermission(Permissions.TP)
|| p.hasPermission(Permissions.COPY) || p.hasPermission(Permissions.SELECT)
|| p.hasPermission(Permissions.EDIT))
{
SudoSigns.signs.values().forEach(s -> suggestions.add(s.getName()));
}
return suggestions;
}
case "fix", "purge" -> {
if (p.hasPermission(Permissions.PURGE)) {
suggestions.addAll(SudoSigns.invalidSigns);
}
return suggestions;
}
case "near" -> {
if (p.hasPermission(Permissions.NEAR)) {
suggestions.add("2");
suggestions.add("5");
suggestions.add("10");
suggestions.add("25");
suggestions.add("50");
}
return suggestions;
}
}
}
if (args.length == 3) {
final ArrayList<String> suggestions = new ArrayList<>();
switch (args[0]) {
case "copy" -> {
suggestions.add("<new-sign-name>");
return suggestions;
}
}
}
}
return null;
}
}
@@ -1,36 +1,53 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class Teleport {
/**
* Teleports a player to the sign.
* @param p The player running the command.
*
* @param p The player running the command.
* @param args 1 argument: The name of the sign.
*/
public static void tp(Player p, String[] args) {
if (p.hasPermission(Permissions.TP)) {
if (args == null || args.length != 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss tp <name>" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &6Correct syntax: &d/ss tp <name>&6.");
return;
}
String name = args[0];
final String name = args[0];
if (SudoSigns.signs.containsKey(name)) {
Location newLoc = SudoSigns.signs.get(name).getSign().getLocation();
final Location newLoc = SudoSigns.signs.get(name).getSign().getLocation();
newLoc.setX(newLoc.getX() + 0.5);
newLoc.setZ(newLoc.getZ() + 0.5);
p.teleport(newLoc);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% doesn't exist!", name);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + name + " &cdoes not exist!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -1,54 +1,163 @@
package dev.mylesmor.sudosigns.commands;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import net.trueog.utilitiesog.UtilitiesOG;
public class View {
/**
* Views a sign's details, including location and number of permissions and commands assigned to it.
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click selection).
* Views a sign's details, including location and number of permissions and
* commands assigned to it.
*
* @param p The player running the command.
* @param args 0 or 1 arguments: The name of the sign (or null for click
* selection).
*/
public static void view(Player p, String[] args) {
if (p.hasPermission(Permissions.VIEW)) {
String name = null;
if (args == null) {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Please click the sign you'd like to view!", null);
UtilitiesOG.trueogMessage(p, "&6Please click on the sign you would like to view.");
SudoSigns.users.get(p.getUniqueId()).setView(true);
return;
}
if (args.length > 1) {
Util.sudoSignsMessage(p, ChatColor.RED, "Invalid syntax! " + ChatColor.GRAY + "Correct syntax: " + ChatColor.LIGHT_PURPLE + "/ss view [name]" + ChatColor.GRAY + ".", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid syntax! &6Correct syntax: &d/ss view [name]&6.");
return;
}
name = args[0];
SudoSign sign = SudoSigns.signs.get(name);
final SudoSign sign = SudoSigns.signs.get(name);
if (sign != null) {
Location signLoc = sign.getSign().getLocation();
String locString = "x=" + signLoc.getX() + " y=" + signLoc.getY() + " z=" + signLoc.getZ();
Util.sudoSignsMessage(p, ChatColor.GRAY, "Displaying details for sign %NAME%:", name);
final Location signLoc = sign.getSign().getLocation();
final String locString = "x=" + signLoc.getX() + " y=" + signLoc.getY() + " z=" + signLoc.getZ() + " ";
UtilitiesOG.trueogMessage(p, "&6Displaying details for sign &e" + name + "&6:");
if (p.hasPermission(Permissions.TP)) {
String locMessage = "[\"\",{\"text\":\"[SUDOSIGNS] \",\"color\":\"yellow\"},{\"text\":\"Location: \",\"color\":\"gray\"},{\"text\":\"" + locString + " \",\"color\":\"light_purple\"},{\"text\":\"[TP]\",\"bold\":true,\"color\":\"aqua\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss tp " + name + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Teleport to " + name + "\",\"color\":\"aqua\"}]}},{\"text\":\"\",\"bold\":true,\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss delete NAME\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Yes, delete the sign!\",\"color\":\"green\"}]}}]";
p.spigot().sendMessage(ComponentSerializer.parse(locMessage));
// Send a teleport confirmation menu with a clickable button.
Util.selectMenuParser(p, "&d&l[TP]", ("&6Location: &e" + "&a" + locString), p.getName(),
("/ss tp " + name), ("&dTeleport to: &e" + name));
} else {
Util.sudoSignsMessage(p, ChatColor.GRAY,"Location: " + ChatColor.LIGHT_PURPLE + locString, null);
UtilitiesOG.trueogMessage(p, "&6Location: &e" + locString);
}
Util.sudoSignsMessage(p, ChatColor.GRAY, "Messages: " + ChatColor.LIGHT_PURPLE + sign.getMessages().size(), null);
Util.sudoSignsMessage(p, ChatColor.GRAY, "Permissions: " + ChatColor.LIGHT_PURPLE + sign.getPermissions().size(), null);
Util.sudoSignsMessage(p, ChatColor.GRAY,"Player Commands: " + ChatColor.LIGHT_PURPLE + sign.getPlayerCommands().size(), null);
Util.sudoSignsMessage(p, ChatColor.GRAY,"Console Commands: " + ChatColor.LIGHT_PURPLE + sign.getConsoleCommands().size(), null);
if (!SudoSigns.getPlugin().getConfig().getBoolean("config.currency-symbol-in-front")) {
if (Util.priceIsInteger()) {
if (sign.getPriceAsInteger() == 1) {
UtilitiesOG.trueogMessage(p, "&6Price: &e" + sign.getPriceAsInteger()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ "&6.");
} else {
UtilitiesOG.trueogMessage(p, "&6Price: &e" + sign.getPriceAsInteger()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ "&6.");
}
} else {
if (sign.getPriceAsDouble() == 1.0) {
UtilitiesOG.trueogMessage(p, "&6Price: &e" + sign.getPriceAsDouble()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ "&6.");
} else {
UtilitiesOG.trueogMessage(p, "&6Price: &e" + sign.getPriceAsDouble()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ "&6.");
}
}
} else {
if (Util.priceIsInteger()) {
if (sign.getPriceAsInteger() == 1) {
UtilitiesOG.trueogMessage(p,
"&6Price: "
+ SudoSigns.getPlugin().getConfig()
.getString("config.currency-symbol-singular")
+ "&e" + sign.getPriceAsInteger() + "&6.");
} else {
UtilitiesOG.trueogMessage(p,
"&6Price: "
+ SudoSigns.getPlugin().getConfig()
.getString("config.currency-symbol-plural")
+ "&e" + sign.getPriceAsInteger() + "&6.");
}
} else {
if (sign.getPriceAsDouble() == 1.0) {
UtilitiesOG.trueogMessage(p,
"&6Price: "
+ SudoSigns.getPlugin().getConfig()
.getString("config.currency-symbol-singular")
+ "&e" + sign.getPriceAsDouble() + "&6.");
} else {
UtilitiesOG.trueogMessage(p,
"&6Price: "
+ SudoSigns.getPlugin().getConfig()
.getString("config.currency-symbol-plural")
+ "&e" + sign.getPriceAsDouble() + "&6.");
}
}
}
UtilitiesOG.trueogMessage(p, "&bPrice: " + sign.getMessages().size());
UtilitiesOG.trueogMessage(p, "&6Messages: &e" + sign.getMessages().size());
UtilitiesOG.trueogMessage(p, "&6Permissions: &e" + sign.getPermissions().size());
UtilitiesOG.trueogMessage(p, "&6Player Commands: &e" + sign.getPlayerCommands().size());
UtilitiesOG.trueogMessage(p, "&6Console Commands: &e" + sign.getConsoleCommands().size());
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign with name %NAME% doesn't exist!", name);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + name + " &cdoes not exist!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to do this!", null);
Util.sudoSignsPermissionsError(p);
}
}
}
}
@@ -0,0 +1,131 @@
package dev.mylesmor.sudosigns.config;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.configuration.file.FileConfiguration;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SudoSign;
public class CommandConfig {
private final FileConfiguration signConfig;
private final ConfigManager configManager;
CommandConfig(ConfigManager configManager) {
this.configManager = configManager;
this.signConfig = configManager.getSignConfig();
}
public void addCommandToConfig(SudoSign s, SignCommand cmd, PlayerInput type) {
if (signConfig.isConfigurationSection("signs." + s.getName())) {
final HashMap<String, Double> map;
switch (type) {
case PLAYER_COMMAND -> {
final List<Map<?, ?>> pCmds = signConfig.getMapList("signs." + s.getName() + ".player-commands");
map = new HashMap<>();
map.put(cmd.getCommand(), cmd.getDelay());
pCmds.add(map);
signConfig.set("signs." + s.getName() + ".player-commands", pCmds);
}
case CONSOLE_COMMAND -> {
final List<Map<?, ?>> cCmds = signConfig.getMapList("signs." + s.getName() + ".console-commands");
map = new HashMap<>();
map.put(cmd.getCommand(), cmd.getDelay());
cCmds.add(map);
signConfig.set("signs." + s.getName() + ".console-commands", cCmds);
}
default -> {
}
}
}
configManager.save();
}
/**
* Deletes a command from a sign in the config.
*
* @param s The SudoSign object to edit.
* @param s The .
* @param s The SudoSign object to edit.
*/
public void deleteCommandFromConfig(SudoSign s, SignCommand cmd, PlayerInput type, double oldDelay) {
if (type.equals(PlayerInput.PLAYER_COMMAND)) {
final List<Map<?, ?>> mapList = signConfig.getMapList("signs." + s.getName() + ".player-commands");
Map<?, ?> found = null;
for (Map<?, ?> map : mapList) {
for (Map.Entry<?, ?> cmds : map.entrySet()) {
if (cmds.getKey().equals(cmd.getCommand()) && (Double) cmds.getValue() == oldDelay) {
found = map;
break;
}
}
}
if (found != null) {
mapList.remove(found);
}
signConfig.set("signs." + s.getName() + ".player-commands", mapList);
} else if (type.equals(PlayerInput.CONSOLE_COMMAND)) {
final List<Map<?, ?>> mapList = signConfig.getMapList("signs." + s.getName() + ".console-commands");
Map<?, ?> found = null;
for (Map<?, ?> map : mapList) {
for (Map.Entry<?, ?> cmds : map.entrySet()) {
if (cmds.getKey().equals(cmd.getCommand()) && (Double) cmds.getValue() == oldDelay) {
found = map;
break;
}
}
}
if (found != null) {
mapList.remove(found);
}
signConfig.set("signs." + s.getName() + ".console-commands", mapList);
}
configManager.save();
}
}
@@ -1,27 +1,28 @@
package dev.mylesmor.sudosigns.config;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Util;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Sign;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
import java.util.*;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SignMessage;
import dev.mylesmor.sudosigns.data.SudoSign;
import net.kyori.adventure.text.TextComponent;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
/**
* The class for managing the plugins config.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
@@ -30,259 +31,293 @@ public class ConfigManager {
private FileConfiguration signConfig;
private File signConfigFile;
private InvalidEntriesManager invalidEntriesManager;
private SignConfig signConfigManager;
private MessageConfig messageConfig;
private CommandConfig commandConfig;
private PermissionConfig permissionConfig;
private final DiamondBankAPIJava diamondBankAPI;
public ConfigManager(DiamondBankAPIJava diamondBankAPI) {
this.diamondBankAPI = diamondBankAPI;
public ConfigManager() {
createCustomConfig();
loadCustomConfig();
}
public void loadModules() {
invalidEntriesManager = new InvalidEntriesManager(this, signConfig);
loadSigns();
signConfigManager = new SignConfig(this, diamondBankAPI);
signConfigManager.loadSigns();
messageConfig = new MessageConfig(this);
commandConfig = new CommandConfig(this);
permissionConfig = new PermissionConfig(this);
}
public InvalidEntriesManager getInvalidEntriesManager() {
return invalidEntriesManager;
}
public FileConfiguration getSignConfig() {
return signConfig;
private void createCustomConfig() {
if (!SudoSigns.sudoSignsPlugin.getDataFolder().exists()) {
SudoSigns.sudoSignsPlugin.getDataFolder().mkdir();
}
signConfigFile = new File(SudoSigns.sudoSignsPlugin.getDataFolder(), "signs.yml");
if (!signConfigFile.exists()) {
try {
signConfigFile.createNewFile();
} catch (IOException e) {
Bukkit.getLogger().warning("[SUDOSIGNS] Failed to create config!");
e.printStackTrace();
}
}
}
public boolean loadCustomConfig() {
signConfig = new YamlConfiguration();
try {
signConfig.load(signConfigFile);
if (!signConfig.isConfigurationSection("signs")) {
signConfig.createSection("signs");
save();
}
if (invalidEntriesManager != null) {
invalidEntriesManager.setConfig(signConfig);
}
} catch (IOException | InvalidConfigurationException e) {
Bukkit.getLogger().warning("[SUDOSIGNS] Failed to initialise signs.yml!");
e.printStackTrace();
return false;
}
return true;
}
/**
* Loads the signs from the config.
* @return True if successful, false if not
*/
public ArrayList<String> loadSigns() {
Map<String, SudoSign> tempSigns = new HashMap<>();
Set<String> signSection = signConfig.getConfigurationSection("signs").getKeys(false);
String name;
ArrayList<String> invalidSigns = new ArrayList<>();
for (String key : signSection) {
name = key;
try {
ConfigurationSection locSec = signConfig.getConfigurationSection("signs." + key + ".location");
String world = locSec.getString("world");
double x = locSec.getDouble("x");
double y = locSec.getDouble("y");
double z = locSec.getDouble("z");
World w = Bukkit.getServer().getWorld(world);
if (w != null) {
Location loc = new Location(Bukkit.getServer().getWorld(world), x, y, z);
if (loc.getBlock().getState() instanceof Sign) {
Sign sign = (Sign) loc.getBlock().getState();
SudoSign ss = new SudoSign(key);
ss.setSign(sign);
List<String> pCommands = signConfig.getStringList("signs." + key + ".player-commands");
List<String> opCommands = signConfig.getStringList("signs." + key + ".op-commands");
List<String> cCommands = signConfig.getStringList("signs." + key + ".console-commands");
List<String> permissions = signConfig.getStringList("signs." + key + ".permissions");
List<String> messages = signConfig.getStringList("signs." + key + ".messages");
for (String cmd : pCommands) {
ss.addPlayerCommand(new SignCommand(cmd, PlayerInput.PLAYER_COMMAND), false);
}
for (String cmd : opCommands) {
ss.addPlayerCommand(new SignCommand(cmd, PlayerInput.PLAYER_COMMAND), true);
}
for (String cmd : cCommands) {
ss.addConsoleCommand(new SignCommand(cmd, PlayerInput.CONSOLE_COMMAND));
}
for (String perm : permissions) {
ss.addPermission(perm);
}
for (String message : messages) {
ss.addMessage(message);
}
tempSigns.put(name, ss);
} else {
invalidSigns.add(key);
Bukkit.getLogger().warning("[SUDOSIGNS] Failed to load Sign " + key + "! The block at the provided location is not a sign. Skipping...");
}
} else {
invalidSigns.add(key);
Bukkit.getLogger().warning("[SUDOSIGNS] Failed to load Sign " + key + "! The world name for this sign is invalid. Skipping...");
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
invalidEntriesManager.setInvalidEntries(invalidSigns);
SudoSigns.signs = tempSigns;
return invalidSigns;
}
void save() {
try {
signConfig.save(signConfigFile);
} catch (IOException e) {
Bukkit.getLogger().warning("[SUDOSIGNS] Failed to save to signs.yml!");
e.printStackTrace();
}
return signConfigManager.loadSigns();
}
public void saveSign(SudoSign s, boolean singular, Player p) {
public void addPermissionToConfig(SudoSign s, String perm) {
String path = "signs." + s.getName() + ".permissions";
List<String> perms = signConfig.getStringList(path);
perms.add(perm);
signConfig.set(path, perms);
save();
}
signConfigManager.saveToFile(s, singular, p);
public void deletePermissionFromConfig(SudoSign s, String perm) {
String path = "signs." + s.getName() + ".permissions";
List<String> perms = signConfig.getStringList(path);
perms.remove(perm);
signConfig.set(path, perms);
save();
}
public void addMessageToConfig(SudoSign s, String message) {
String path = "signs." + s.getName() + ".messages";
List<String> messages = signConfig.getStringList(path);
messages.add(message);
signConfig.set(path, messages);
save();
}
public void deleteMessageFromConfig(SudoSign s, String message) {
String path = "signs." + s.getName() + ".messages";
List<String> messages = signConfig.getStringList(path);
messages.remove(message);
signConfig.set(path, messages);
save();
}
public void addCommandToConfig(SudoSign s, SignCommand cmd, PlayerInput type) {
if (signConfig.isConfigurationSection("signs." + s.getName())) {
switch (type) {
case PLAYER_COMMAND:
List<String> pCmds = signConfig.getStringList("signs." + s.getName() + ".player-commands");
pCmds.add(cmd.getCommand());
signConfig.set("signs." + s.getName() + ".player-commands", pCmds);
break;
case PLAYER_COMMAND_WITH_PERMISSIONS:
List<String> opCmds = signConfig.getStringList("signs." + s.getName() + ".op-commands");
opCmds.add(cmd.getCommand());
signConfig.set("signs." + s.getName() + ".op-commands", opCmds);
break;
case CONSOLE_COMMAND:
List<String> cCmds = signConfig.getStringList("signs." + s.getName() + ".console-commands");
cCmds.add(cmd.getCommand());
signConfig.set("signs." + s.getName() + ".console-commands", cCmds);
break;
}
}
save();
}
public void deleteCommandFromConfig(SudoSign s, SignCommand cmd, PlayerInput type) {
if (signConfig.isConfigurationSection("signs." + s.getName())) {
if (type.equals(PlayerInput.PLAYER_COMMAND)) {
if (signConfig.isList("signs." + s.getName() + ".player-commands")) {
List<String> cmds = signConfig.getStringList("signs." + s.getName() + ".player-commands");
cmds.remove(cmd.getCommand());
signConfig.set("signs." + s.getName() + ".player-commands", cmds);
}
} else if (type.equals(PlayerInput.CONSOLE_COMMAND)) {
if (signConfig.isList("signs." + s.getName() + ".console-commands")) {
List<String> cmds = signConfig.getStringList("signs." + s.getName() + ".console-commands");
cmds.remove(cmd.getCommand());
signConfig.set("signs." + s.getName() + ".console-commands", cmds);
}
}
}
save();
}
public void deleteSign(String name) {
if (signConfig.isConfigurationSection("signs." + name + "")) {
signConfig.set("signs." + name + "", null);
}
save();
signConfigManager.deleteSign(name);
}
public void saveToFile(SudoSign s, Boolean singular, Player p) {
if (singular) {
saveSign(s, p);
} else {
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
saveSign(entry.getValue(), p);
}
}
save();
public void editSignText(String name, int lineNumber, TextComponent message) {
signConfigManager.editText(name, lineNumber, message);
}
public void saveSign(SudoSign s, Player p) {
String name = s.getName();
public void addMessage(SudoSign s, SignMessage sm) {
messageConfig.addMessageToConfig(s, sm);
}
public void deleteMessage(SudoSign s, SignMessage sm, double delay) {
messageConfig.deleteMessageFromConfig(s, sm, delay);
}
public void addCommand(SudoSign s, SignCommand sm, PlayerInput type) {
commandConfig.addCommandToConfig(s, sm, type);
}
public void deleteCommand(SudoSign s, SignCommand sm, PlayerInput type, double oldDelay) {
commandConfig.deleteCommandFromConfig(s, sm, type, oldDelay);
}
public void setPrice(String name, double price) {
signConfigManager.setPrice(name, price);
}
public void addPermission(SudoSign s, String permission) {
permissionConfig.addPermissionToConfig(s, permission);
}
public void deletePermission(SudoSign s, String permission) {
permissionConfig.deletePermissionFromConfig(s, permission);
}
public boolean loadCustomConfig() {
try {
if (!signConfig.isConfigurationSection("signs." + name + "")) {
signConfig.createSection("signs." + name + "");
signConfig.createSection("signs." + name + ".text");
ArrayList<String> lines = new ArrayList<>();
lines.addAll(s.getText());
signConfig.set("signs." + name + ".text", lines);
ConfigurationSection locSec = signConfig.createSection("signs." + name + ".location");
String world = s.getSign().getWorld().getName();
double x = s.getSign().getLocation().getX();
double y = s.getSign().getLocation().getY();
double z = s.getSign().getLocation().getZ();
signConfig.set("signs." + name + ".blocktype", s.getSign().getType().toString());
locSec.set("world", world);
locSec.set("x", x);
locSec.set("y", y);
locSec.set("z", z);
if (s.getSign().getWorld().getBlockAt(s.getSign().getLocation()).getBlockData() instanceof org.bukkit.block.data.type.Sign) {
org.bukkit.block.data.type.Sign facing = (org.bukkit.block.data.type.Sign) s.getSign().getWorld().getBlockAt(s.getSign().getLocation()).getBlockData();
locSec.set("rotation", facing.getRotation().toString());
} else if (s.getSign().getWorld().getBlockAt(s.getSign().getLocation()).getBlockData() instanceof org.bukkit.block.data.type.WallSign) {
org.bukkit.block.data.type.WallSign facing = (org.bukkit.block.data.type.WallSign) s.getSign().getWorld().getBlockAt(s.getSign().getLocation()).getBlockData();
locSec.set("rotation", facing.getFacing().toString());
}
signConfig.createSection("signs." + name + ".permissions");
signConfig.createSection("signs." + name + ".messages");
signConfig.createSection("signs." + name + ".player-commands");
signConfig.createSection("signs." + name + ".console-commands");
final File dataFolder = SudoSigns.sudoSignsPlugin.getDataFolder();
if (!dataFolder.exists() && !dataFolder.mkdirs()) {
Bukkit.getLogger().warning("ERROR: Failed to create plugin data folder!");
return false;
}
} catch (Exception e) {
if (p != null) {
Util.sudoSignsMessage(p, ChatColor.RED, "Failed to save sign %NAME% to the config!", name);
signConfigFile = new File(dataFolder, "signs.yml");
// Copy default from jar if missing
if (!signConfigFile.exists()) {
SudoSigns.sudoSignsPlugin.saveResource("signs.yml", false);
}
Bukkit.getLogger().warning("[SUDOSIGNS] Failed to save " + name + " to signs.yml!");
e.printStackTrace();
signConfig = YamlConfiguration.loadConfiguration(signConfigFile);
if (signConfigManager != null) {
signConfigManager.setSignConfig(signConfig);
}
if (!signConfig.isConfigurationSection("signs")) {
signConfig.createSection("signs");
save();
}
if (invalidEntriesManager != null) {
invalidEntriesManager.setConfig(signConfig);
}
if (!signConfig.contains("version")) {
signConfig.set("version", "1.2.3");
save();
fixConfig();
}
return true;
} catch (Exception error) {
Bukkit.getLogger().warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "ERROR: Failed to initialise signs.yml!");
error.printStackTrace();
return false;
}
}
public void fixConfig() {
final Set<String> signSection = signConfig.getConfigurationSection("signs").getKeys(false);
String name = null;
for (String key : signSection) {
signConfig.set("signs." + key + ".op-commands", null);
signConfig.set("signs." + key + ".price", 0.0);
name = key;
final List<String> pCommands = signConfig.getStringList("signs." + key + ".player-commands");
final List<String> cCommands = signConfig.getStringList("signs." + key + ".console-commands");
final List<String> messages = signConfig.getStringList("signs." + key + ".messages");
if (pCommands.size() == 0 && cCommands.size() == 0 && messages.size() == 0) {
save();
continue;
}
if (pCommands.size() != 0) {
try {
final ArrayList<HashMap<String, Double>> mapList = new ArrayList<>();
HashMap<String, Double> map = new HashMap<>();
for (String cmd : pCommands) {
map.put(cmd, 0.0);
mapList.add(map);
map = new HashMap<>();
}
signConfig.set("signs." + name + ".player-commands", mapList);
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
signConfig.set("signs." + key + ".op-commands", null);
if (cCommands.size() != 0) {
try {
final ArrayList<HashMap<String, Double>> mapList = new ArrayList<>();
HashMap<String, Double> map = new HashMap<>();
for (String cmd : cCommands) {
map.put(cmd, 0.0);
mapList.add(map);
map = new HashMap<>();
}
signConfig.set("signs." + name + ".console-commands", mapList);
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
if (messages.size() != 0) {
try {
final ArrayList<HashMap<String, Double>> mapList = new ArrayList<>();
HashMap<String, Double> map = new HashMap<>();
for (String cmd : messages) {
map.put(cmd, 0.0);
mapList.add(map);
map = new HashMap<>();
}
signConfig.set("signs." + name + ".messages", mapList);
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
save();
}
}
public void save() {
try {
signConfig.save(signConfigFile);
} catch (IOException e) {
Bukkit.getLogger().warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "ERROR: Failed to save to signs.yml!");
e.printStackTrace();
}
}
}
@@ -1,142 +1,229 @@
package dev.mylesmor.sudosigns.config;
import dev.mylesmor.sudosigns.SudoSigns;
import org.bukkit.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.List;
import dev.mylesmor.sudosigns.SudoSigns;
import net.trueog.utilitiesog.UtilitiesOG;
public class InvalidEntriesManager {
/**
* The class for managing invalid sign entries in the config.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
ArrayList<String> invalidEntries = new ArrayList<>();
ConfigManager configManager;
FileConfiguration config;
InvalidEntriesManager(ConfigManager configManager, FileConfiguration config) {
this.configManager = configManager;
this.config = config;
}
public void setConfig(FileConfiguration config) {
this.config = config;
}
/**
* Attempts to a fix an invalid entry by placing a sign in the correct position.
*
* @param s The sign's name.
* @return True if sign successfully fixed, otherwise False.
*/
private boolean fixEntry(String s) {
try {
ConfigurationSection locSec = config.getConfigurationSection("signs." + s + ".location");
String world = locSec.getString("world");
double x = locSec.getDouble("x");
double y = locSec.getDouble("y");
double z = locSec.getDouble("z");
final ConfigurationSection locSec = config.getConfigurationSection("signs." + s + ".location");
final String world = locSec.getString("world");
final double x = locSec.getDouble("x");
final double y = locSec.getDouble("y");
final double z = locSec.getDouble("z");
String matString = config.getString("signs." + s + ".blocktype");
if (SudoSigns.version.contains("1.13")) {
if (StringUtils.contains(SudoSigns.version, "1.13")) {
matString = "SIGN";
}
Material material = Material.valueOf(matString);
BlockFace blockFace = BlockFace.valueOf(locSec.getString("rotation"));
World w = Bukkit.getServer().getWorld(world);
final Material material = Material.valueOf(matString);
final BlockFace blockFace = BlockFace.valueOf(locSec.getString("rotation"));
final World w = Bukkit.getServer().getWorld(world);
if (w != null) {
Location loc = new Location(Bukkit.getServer().getWorld(world), x, y, z);
final Location loc = new Location(Bukkit.getServer().getWorld(world), x, y, z);
w.getBlockAt(loc).setType(material);
Block b = w.getBlockAt(loc);
final Block b = w.getBlockAt(loc);
if (b.getBlockData() instanceof org.bukkit.block.data.type.Sign) {
org.bukkit.block.data.type.Sign facing = (org.bukkit.block.data.type.Sign) b.getBlockData();
final org.bukkit.block.data.type.Sign facing = (org.bukkit.block.data.type.Sign) b.getBlockData();
facing.setRotation(blockFace);
b.setBlockData(facing);
} else if (b.getBlockData() instanceof org.bukkit.block.data.type.WallSign){
org.bukkit.block.data.type.WallSign facing = (org.bukkit.block.data.type.WallSign) b.getBlockData();
} else if (b.getBlockData() instanceof org.bukkit.block.data.type.WallSign) {
final org.bukkit.block.data.type.WallSign facing = (org.bukkit.block.data.type.WallSign) b
.getBlockData();
facing.setFacing(blockFace);
b.setBlockData(facing);
}
Sign newSign = (Sign) b.getState();
Bukkit.getLogger().warning(w.getBlockAt(loc).getBlockData().toString());
List<String> lines = getSignText(s);
final Sign newSign = (Sign) b.getState();
final List<String> lines = getSignText(s);
int i = 0;
for (String line : lines) {
newSign.setLine(i, ChatColor.translateAlternateColorCodes('&', line));
newSign.line(i, UtilitiesOG.trueogColorize(line));
i++;
}
newSign.update();
}
} catch (Exception e) {
e.printStackTrace();
} catch (Exception error) {
error.printStackTrace();
return false;
}
return true;
}
public ArrayList<String> getInvalidEntries() {
return invalidEntries;
}
public void setInvalidEntries(ArrayList<String> invalid) {
invalidEntries = invalid;
}
public void addInvalidEntry(String entry) {
invalidEntries.add(entry);
}
/**
* Retrieves the invalid sign's text from the config.
*
* @param name Name of the sign.
* @return The sign's message or null if not found.
*/
public List<String> getSignText(String name) {
List<String> signSec = config.getStringList("signs." + name + ".text");
for (String item : signSec) {
item = ChatColor.translateAlternateColorCodes('&', item);
}
final List<String> signSec = config.getStringList("signs." + name + ".text");
signSec.forEach(item -> item = UtilitiesOG.trueogColorize(item).content());
if (signSec.size() != 0) {
return signSec;
}
return null;
}
/**
* Removes a sign's entry in the config.
*
* @param name Name of the sign.
* @param all True if all invalid entries should be purged, or False for just
* one.
* @return The sign's message or null if not found.
*/
public boolean purgeInvalidEntry(String name, boolean all) {
if (all) {
for (String s : invalidEntries) {
invalidEntries.forEach(s -> {
Bukkit.getLogger().warning(Boolean.toString(config.isConfigurationSection("signs." + s)));
config.set("signs." + s, null);
}
});
configManager.loadSigns();
configManager.save();
return true;
} else {
for (String s : invalidEntries) {
if (name.equalsIgnoreCase(s)) {
if (StringUtils.equalsIgnoreCase(name, s)) {
Bukkit.getLogger().warning(Boolean.toString(config.isConfigurationSection("signs." + s)));
config.set("signs." + name, null);
configManager.loadSigns();
configManager.save();
return true;
}
}
}
return false;
}
public boolean fixInvalidEntry(String name, boolean all) {
if (all) {
for (String s : invalidEntries) {
fixEntry(s);
}
invalidEntries.forEach(this::fixEntry);
configManager.save();
return true;
} else {
for (String s : invalidEntries) {
if (name.equals(s)) {
if (fixEntry(s)) {
configManager.save();
return true;
}
if (name.equals(s) && fixEntry(s)) {
configManager.save();
return true;
}
}
}
return false;
}
}
}
@@ -0,0 +1,67 @@
package dev.mylesmor.sudosigns.config;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.configuration.file.FileConfiguration;
import dev.mylesmor.sudosigns.data.SignMessage;
import dev.mylesmor.sudosigns.data.SudoSign;
public class MessageConfig {
private final FileConfiguration signConfig;
private final ConfigManager configManager;
MessageConfig(ConfigManager configManager) {
this.configManager = configManager;
this.signConfig = configManager.getSignConfig();
}
public void addMessageToConfig(SudoSign s, SignMessage sm) {
final HashMap<String, Double> map;
final List<Map<?, ?>> messages = signConfig.getMapList("signs." + s.getName() + ".messages");
map = new HashMap<>();
map.put(sm.getMessage(), sm.getDelay());
messages.add(map);
signConfig.set("signs." + s.getName() + ".messages", messages);
configManager.save();
}
public void deleteMessageFromConfig(SudoSign s, SignMessage sm, double oldDelay) {
final List<Map<?, ?>> mapList = signConfig.getMapList("signs." + s.getName() + ".messages");
Map<?, ?> found = null;
for (Map<?, ?> map : mapList) {
for (Map.Entry<?, ?> messages : map.entrySet()) {
final String key = (String) messages.getKey();
if (key.equals(sm.getMessage()) && (Double) messages.getValue() == oldDelay) {
found = map;
break;
}
}
}
if (found != null) {
mapList.remove(found);
}
signConfig.set("signs." + s.getName() + ".messages", mapList);
configManager.save();
}
}
@@ -0,0 +1,41 @@
package dev.mylesmor.sudosigns.config;
import java.util.List;
import org.bukkit.configuration.file.FileConfiguration;
import dev.mylesmor.sudosigns.data.SudoSign;
public class PermissionConfig {
private final FileConfiguration signConfig;
private final ConfigManager configManager;
PermissionConfig(ConfigManager configManager) {
this.configManager = configManager;
this.signConfig = configManager.getSignConfig();
}
public void addPermissionToConfig(SudoSign s, String perm) {
final String path = "signs." + s.getName() + ".permissions";
final List<String> perms = signConfig.getStringList(path);
perms.add(perm);
signConfig.set(path, perms);
configManager.save();
}
public void deletePermissionFromConfig(SudoSign s, String perm) {
final String path = "signs." + s.getName() + ".permissions";
final List<String> perms = signConfig.getStringList(path);
perms.remove(perm);
signConfig.set(path, perms);
configManager.save();
}
}
@@ -0,0 +1,358 @@
package dev.mylesmor.sudosigns.config;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Rotatable;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SignMessage;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Util;
import net.kyori.adventure.text.TextComponent;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class SignConfig {
private FileConfiguration signConfig;
private final ConfigManager configManager;
private final DiamondBankAPIJava diamondBankAPI;
SignConfig(ConfigManager configManager, DiamondBankAPIJava diamondBankAPI) {
this.configManager = configManager;
this.signConfig = configManager.getSignConfig();
this.diamondBankAPI = diamondBankAPI;
}
public void setSignConfig(FileConfiguration signConfig) {
this.signConfig = signConfig;
}
// Loads the signs from the config.
public ArrayList<String> loadSigns() {
final Map<String, SudoSign> tempSigns = new HashMap<>();
final Set<String> loadedLocations = new HashSet<>();
final Set<String> signSection = signConfig.getConfigurationSection("signs").getKeys(false);
String name;
final ArrayList<String> invalidSigns = new ArrayList<>();
for (String key : signSection) {
name = key;
try {
final ConfigurationSection locSec = signConfig.getConfigurationSection("signs." + key + ".location");
final String world = locSec.getString("world");
final double x = locSec.getDouble("x");
final double y = locSec.getDouble("y");
final double z = locSec.getDouble("z");
final World w = Bukkit.getServer().getWorld(world);
if (w != null) {
final Location loc = new Location(Bukkit.getServer().getWorld(world), x, y, z);
final String locationKey = world + ":" + loc.getBlockX() + ":" + loc.getBlockY() + ":"
+ loc.getBlockZ();
if (!loadedLocations.add(locationKey)) {
invalidSigns.add(key);
Bukkit.getLogger()
.warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "ERROR: Failed to load Sign " + key + " at " + world + " " + loc.getBlockX()
+ ", " + loc.getBlockY() + ", " + loc.getBlockZ()
+ "! Cause: another SudoSign already uses that block location. Skipping...");
continue;
}
final Sign sign = Util.getSign(loc.getBlock());
if (sign != null) {
final SudoSign ss = new SudoSign(key, diamondBankAPI);
ss.setSign(sign);
final List<Map<?, ?>> pCommands = signConfig.getMapList("signs." + key + ".player-commands");
final List<Map<?, ?>> cCommands = signConfig.getMapList("signs." + key + ".console-commands");
final List<String> permissions = signConfig.getStringList("signs." + key + ".permissions");
final List<Map<?, ?>> messages = signConfig.getMapList("signs." + key + ".messages");
if (Util.priceIsInteger()) {
try {
ss.setPriceAsInteger((Integer) signConfig.get("signs." + key + ".price"));
} catch (Exception error) {
UtilitiesOG.logToConsole(
SudoSigns.getPlugin().getConfig().getString("config.console-prefix"),
"ERROR: Invalid price for sign " + name + "! Defaulting to 0...");
ss.setPriceAsInteger(0);
}
} else {
try {
ss.setPriceAsDouble((Double) signConfig.get("signs." + key + ".price"));
} catch (Exception error) {
Bukkit.getLogger()
.info(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "ERROR: Invalid price for sign " + name + "! Defaulting to 0...");
ss.setPriceAsDouble(0.0);
}
}
int number = 0;
for (Map<?, ?> sc : pCommands) {
for (Map.Entry<?, ?> cmd : sc.entrySet()) {
ss.addPlayerCommand(new SignCommand(number++, (String) cmd.getKey(),
(Double) cmd.getValue(), PlayerInput.PLAYER_COMMAND));
}
}
for (Map<?, ?> sc : cCommands) {
for (Map.Entry<?, ?> cmd : sc.entrySet()) {
ss.addConsoleCommand(new SignCommand(number++, (String) cmd.getKey(),
(Double) cmd.getValue(), PlayerInput.CONSOLE_COMMAND));
}
}
permissions.forEach(ss::addPermission);
number = 0;
for (Map<?, ?> sc : messages) {
for (Map.Entry<?, ?> message : sc.entrySet()) {
ss.addMessage(new SignMessage(number++, (String) message.getKey(),
(Double) message.getValue(), PlayerInput.MESSAGE));
}
}
tempSigns.put(name, ss);
} else {
invalidSigns.add(key);
final String actualBlockType = loc.getBlock().getType().toString();
Bukkit.getLogger()
.warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "ERROR: Failed to load Sign " + key + " at " + world + " " + loc.getBlockX()
+ ", " + loc.getBlockY() + ", " + loc.getBlockZ()
+ "! Cause: the block at the provided location is " + actualBlockType
+ ", not a sign. Skipping...");
}
} else {
invalidSigns.add(key);
Bukkit.getLogger().warning(SudoSigns.getPlugin().getConfig().getString("config.console-prefix")
+ "ERROR: Failed to load Sign " + key + " at " + world + " " + x + ", " + y + ", " + z
+ "! Cause: the world '" + world + "' does not exist or is not loaded. Skipping...");
}
} catch (Exception error) {
error.printStackTrace();
return null;
}
}
configManager.getInvalidEntriesManager().setInvalidEntries(invalidSigns);
SudoSigns.signs = tempSigns;
SudoSigns.invalidSigns = invalidSigns;
return invalidSigns;
}
/**
* Deletes a sign from the config.
*
* @param name The name of the sign.
*/
public void deleteSign(String name) {
if (signConfig.isSet("signs." + name)) {
signConfig.set("signs." + name, null);
}
configManager.save();
}
/**
* Saves the SudoSigns to config.
*
* @param s The SudoSign object.
* @param singular True to save a singular sign, False to save all.
* @param p The player who has edited the sign.
*/
public void saveToFile(SudoSign s, boolean singular, Player p) {
if (singular) {
saveSign(s, p);
} else {
SudoSigns.signs.entrySet().forEach(entry -> saveSign(entry.getValue(), p));
}
configManager.save();
}
/**
* Saves a SudoSign in the config.
*
* @param s The SudoSign object.
* @param p The player who has edited the sign.
*/
public void saveSign(SudoSign s, Player p) {
final String name = s.getName();
try {
if (!signConfig.isConfigurationSection("signs." + name + "")) {
signConfig.createSection("signs." + name + "");
signConfig.createSection("signs." + name + ".text");
final ArrayList<String> lines = new ArrayList<>(s.getText());
signConfig.set("signs." + name + ".text", lines);
signConfig.set("signs." + name + ".price", 0.0);
final ConfigurationSection locSec = signConfig.createSection("signs." + name + ".location");
final String world = s.getSign().getWorld().getName();
final double x = s.getSign().getLocation().getX();
final double y = s.getSign().getLocation().getY();
final double z = s.getSign().getLocation().getZ();
signConfig.set("signs." + name + ".blocktype", s.getSign().getType().toString());
locSec.set("world", world);
locSec.set("x", x);
locSec.set("y", y);
locSec.set("z", z);
final BlockData blockData = s.getSign().getWorld().getBlockAt(s.getSign().getLocation()).getBlockData();
if (blockData instanceof Rotatable) {
final Rotatable data = (Rotatable) blockData;
final BlockFace rotation = data.getRotation();
locSec.set("rotation", rotation);
} else if (blockData instanceof WallSign) {
final WallSign facing = (WallSign) blockData;
locSec.set("rotation", facing.getFacing().toString());
}
signConfig.createSection("signs." + name + ".permissions");
signConfig.createSection("signs." + name + ".messages");
signConfig.createSection("signs." + name + ".player-commands");
signConfig.createSection("signs." + name + ".console-commands");
configManager.save();
}
} catch (Exception error) {
if (p != null) {
UtilitiesOG.trueogMessage(p, "&cERROR: Failed to save sign &e" + name + " &cto the config!");
error.printStackTrace();
}
}
}
public void editText(String name, int lineNumber, TextComponent newText) {
if (signConfig.isConfigurationSection("signs." + name + "")) {
final List<String> text = signConfig.getStringList("signs." + name + ".text");
text.set(lineNumber - 1, newText.content());
signConfig.set("signs." + name + ".text", text);
}
configManager.save();
}
public void setPrice(String name, double price) {
if (signConfig.isConfigurationSection("signs." + name + "")) {
signConfig.set("signs." + name + ".price", price);
}
configManager.save();
}
}
@@ -2,14 +2,11 @@ package dev.mylesmor.sudosigns.data;
/**
* Enum used for determing the type of player chat input.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
public enum PlayerInput {
PLAYER_COMMAND,
PLAYER_COMMAND_WITH_PERMISSIONS,
CONSOLE_COMMAND,
RENAME,
PERMISSION,
MESSAGE,
PLAYER_COMMAND, CONSOLE_COMMAND, RENAME, PERMISSION, MESSAGE, COMMAND_DELAY, MESSAGE_DELAY, EDIT_TEXT_NUMBER,
EDIT_TEXT, SET_PRICE,
}
@@ -1,29 +1,55 @@
package dev.mylesmor.sudosigns.data;
import dev.mylesmor.sudosigns.data.PlayerInput;
/**
* The SignCommand class for storing sign command data.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
public class SignCommand {
private String command;
private PlayerInput type;
private final String command;
private final PlayerInput type;
private final int number;
private double delay;
public SignCommand(String cmd, PlayerInput type) {
public SignCommand(int number, String cmd, double delay, PlayerInput type) {
this.number = number;
command = cmd;
this.type = type;
this.delay = delay;
}
public String getCommand() {
return command;
}
public PlayerInput getType() {
return type;
}
public int getNumber() {
return number;
}
public double getDelay() {
return delay;
}
public void setDelay(double delay) {
this.delay = delay;
}
}
@@ -0,0 +1,49 @@
package dev.mylesmor.sudosigns.data;
public class SignMessage {
private final String message;
private final PlayerInput type;
private final int number;
private double delay;
public SignMessage(int number, String message, double delay, PlayerInput type) {
this.number = number;
this.message = message;
this.type = type;
this.delay = delay;
}
public String getMessage() {
return message;
}
public PlayerInput getType() {
return type;
}
public int getNumber() {
return number;
}
public double getDelay() {
return delay;
}
public void setDelay(double delay) {
this.delay = delay;
}
}
@@ -1,188 +1,718 @@
package dev.mylesmor.sudosigns.data;
import dev.mylesmor.sudosigns.SudoSigns;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.util.Util;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.trueog.diamondbankog.DiamondBankException.EconomyDisabledException;
import net.trueog.diamondbankog.DiamondBankException.InsufficientFundsException;
import net.trueog.diamondbankog.DiamondBankException.InvalidPlayerException;
import net.trueog.diamondbankog.DiamondBankException.PlayerNotOnlineException;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
/**
* The class assigned to each created sign.
*
* @author MylesMor
* @author https://mylesmor.dev
* @maintainer NotAlexxNoyle
* @maintainer https://true-og.net
*/
public class SudoSign {
private HashMap<SignCommand, Boolean> playerCommands = new HashMap<>();
private ArrayList<SignCommand> playerCommands = new ArrayList<>();
private ArrayList<SignCommand> consoleCommands = new ArrayList<>();
private ArrayList<String> permissions = new ArrayList<>();
private ArrayList<String> messages = new ArrayList<>();
private ArrayList<String> text = new ArrayList<>();
private ArrayList<SignMessage> messages = new ArrayList<>();
private final ArrayList<String> text = new ArrayList<>();
private double priceAsDouble = 0;
private int priceAsInteger = 0;
private String worldName;
private double x;
private double y;
private double z;
private String name;
private final DiamondBankAPIJava diamondBankAPI;
public SudoSign(String name, DiamondBankAPIJava diamondBankAPI) {
public SudoSign(String name) {
this.name = name;
this.diamondBankAPI = diamondBankAPI;
}
public void setSign(Sign sign) {
Location loc = sign.getLocation();
final Location loc = sign.getLocation();
this.worldName = loc.getWorld().getName();
this.x = loc.getX();
this.y = loc.getY();
this.z = loc.getZ();
}
public Sign getSign() {
if (worldName != null) {
final Location loc = new Location(Bukkit.getWorld(worldName), x, y, z);
return Util.getSign(loc.getBlock());
}
Bukkit.getLogger().warning("Failed to locate sign " + name + "!");
return null;
}
public String getWorldName() {
return worldName;
}
public int getBlockX() {
return (int) x;
}
public int getBlockY() {
return (int) y;
}
public int getBlockZ() {
return (int) z;
}
public void setName(String name) {
this.name = name;
}
public void addPlayerCommand(SignCommand sc, boolean permissions) {
playerCommands.put(sc, permissions);
public void addPlayerCommand(SignCommand sc) {
playerCommands.add(sc);
}
public List<String> getText() {
return text;
}
public void addLines() {
Sign sign = getSign();
String[] lines = sign.getLines();
final Sign sign = getSign();
for (int i = 0; i < 4; i++) {
String line = lines[i];
final String line = PlainTextComponentSerializer.plainText().serialize(sign.line(i));
text.add(line.replaceAll("§", "&"));
line = ChatColor.translateAlternateColorCodes('&', line);
//line = ChatColor.translateAlternateColorCodes('§', line);
sign.setLine(i, line);
sign.line(i, UtilitiesOG.trueogColorize(line));
}
sign.update();
}
public void editLine(int lineNumber, TextComponent message) {
final Sign sign = getSign();
final String line = PlainTextComponentSerializer.plainText().serialize(sign.line(lineNumber));
text.add(line.replaceAll("§", "&"));
sign.line(lineNumber, message);
sign.update();
}
public void addConsoleCommand(SignCommand sc) {
consoleCommands.add(sc);
}
public void deleteConsoleCommand(SignCommand sc) {
consoleCommands.remove(sc);
}
public void deletePlayerCommand(SignCommand sc) {
playerCommands.remove(sc);
}
public void addPermission(String s) {
permissions.add(s);
}
public void removePermission(String s) {
permissions.remove(s);
}
public ArrayList<String> getPermissions() {
return permissions;
}
public void addMessage(String s) {
public void addMessage(SignMessage s) {
messages.add(s);
}
public void removeMessage(String s) {
public void removeMessage(SignMessage s) {
messages.remove(s);
}
public void copyFrom(SudoSign s) {
this.permissions = s.getPermissions();
this.playerCommands = s.getPlayerCommands();
this.consoleCommands = s.getConsoleCommands();
this.messages = s.getMessages();
if (Util.priceIsInteger()) {
this.priceAsInteger = s.getPriceAsInteger();
} else {
this.priceAsDouble = s.getPriceAsDouble();
}
}
public ArrayList<String> getMessages() { return messages; }
public ArrayList<SignMessage> getMessages() {
public void setMessages(ArrayList<String> messages) { this.messages = messages; }
return messages;
}
public void setMessages(ArrayList<SignMessage> messages) {
this.messages = messages;
}
public void setPlayerCommands(ArrayList<SignCommand> playerCommands) {
public void setPlayerCommands(HashMap<SignCommand, Boolean> playerCommands) {
this.playerCommands = playerCommands;
}
public void setConsoleCommands(ArrayList<SignCommand> consoleCommands) {
this.consoleCommands = consoleCommands;
}
public void setPermissions(ArrayList<String> permissions) {
this.permissions = permissions;
}
public HashMap<SignCommand, Boolean> getPlayerCommands() {
public ArrayList<SignCommand> getPlayerCommands() {
return playerCommands;
}
public ArrayList<SignCommand> getConsoleCommands() {
return consoleCommands;
}
public void setPriceAsDouble(double price) {
this.priceAsDouble = price;
}
public double getPriceAsDouble() {
return priceAsDouble;
}
public void setPriceAsInteger(int price) {
this.priceAsInteger = price;
}
public int getPriceAsInteger() {
return priceAsInteger;
}
/**
* Executes all of the commands attached to the sign, if the player has the required permissions.
* Executes all of the commands attached to the sign, if the player has the
* required permissions.
*
* @param p The player who is running the sign.
*/
public void executeCommands(Player p) {
boolean hasPermission = true;
for (String perm : permissions) {
if (!p.hasPermission(perm)) {
hasPermission = false;
}
final boolean hasPermission = permissions.stream().allMatch(p::hasPermission);
if (!hasPermission) {
Util.sudoSignsPermissionsError(p);
return;
}
if (hasPermission) {
for (String s : messages) {
p.sendMessage(ChatColor.translateAlternateColorCodes('&', s).replaceAll("(?i)%PLAYER%", p.getName()));
final boolean priceIsInteger = Util.priceIsInteger();
final double priceAsDiamonds = priceIsInteger ? (double) priceAsInteger : priceAsDouble;
final boolean paidSign = priceIsInteger ? priceAsInteger != 0 : priceAsDouble != 0.0D;
if (paidSign) {
if (diamondBankAPI == null) {
UtilitiesOG.trueogMessage(p,
"&cERROR: The Diamond economy is currently unavailable. You cannot purchase this sign right now.");
return;
}
for (Map.Entry<SignCommand, Boolean> entry : playerCommands.entrySet()) {
String cmd = entry.getKey().getCommand().replaceAll("(?i)%PLAYER%", p.getName());
if (entry.getValue()) {
try {
p.setOp(true);
p.performCommand(cmd);
p.setOp(false);
} catch (Exception ignored) { }
finally {
p.setOp(false);
final long priceAsShards;
try {
priceAsShards = diamondBankAPI.diamondsToShards(priceAsDiamonds);
} catch (RuntimeException conversionError) {
if (!priceIsInteger) {
final BigDecimal entered = BigDecimal.valueOf(priceAsDouble).stripTrailingZeros();
final String enteredText = entered.toPlainString();
String suggestionText = null;
if (entered.scale() > 1) {
suggestionText = entered.setScale(1, RoundingMode.DOWN).stripTrailingZeros().toPlainString();
}
if (suggestionText != null && !suggestionText.equals(enteredText)) {
UtilitiesOG.trueogMessage(p,
"&cERROR: Invalid price number: &e" + enteredText
+ "&c. Use at most one decimal place (for example, enter &e" + suggestionText
+ "&c instead of &e" + enteredText + "&c).");
} else {
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid price number: &e" + enteredText
+ "&c. Use at most one decimal place (for example, &e1.1&c instead of &e1.11&c).");
}
} else {
p.performCommand(cmd);
UtilitiesOG.trueogMessage(p, "&cERROR: Invalid price number configured on this sign.");
}
SudoSigns.getPlugin().getLogger()
.warning("Invalid DiamondBank-OG price precision while executing sign for " + p.getName()
+ " (price=" + priceAsDiamonds + ").");
conversionError.printStackTrace();
return;
}
for (SignCommand sc : consoleCommands) {
String cmd = sc.getCommand().replaceAll("(?i)%PLAYER%", p.getName());
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
try {
if (priceAsShards > 0L) {
diamondBankAPI.consumeFromPlayer(p.getUniqueId(), priceAsShards, "Player " + p.getName() + " paid "
+ diamondBankAPI.shardsToDiamonds(priceAsShards) + " Diamonds to execute a SudoSign.",
"Plugin: SudoSigns-OG");
}
} catch (InsufficientFundsException insufficientFundsError) {
sendNotEnoughMoneyMessage(p, priceIsInteger);
return;
} catch (EconomyDisabledException economyDisabledError) {
SudoSigns.getPlugin().getLogger().severe("DiamondBank-OG economy disabled while executing sign for "
+ p.getName() + ": " + economyDisabledError.getMessage());
economyDisabledError.printStackTrace();
UtilitiesOG.trueogMessage(p,
"&cERROR: The Diamond economy is currently disabled. You cannot purchase this sign right now.");
return;
} catch (InvalidPlayerException invalidPlayerError) {
SudoSigns.getPlugin().getLogger()
.warning("Invalid player in DiamondBank-OG while executing sign for " + p.getName() + ".");
invalidPlayerError.printStackTrace();
UtilitiesOG.trueogMessage(p,
"&cERROR: Your player account could not be found by DiamondBank-OG. Contact an administrator.");
return;
} catch (PlayerNotOnlineException temporaryPlayerNotOnlineError) {
// TODO: Remove after DiamondBank-OG update if this is no longer thrown.
SudoSigns.getPlugin().getLogger()
.warning("DiamondBank-OG reported PlayerNotOnlineException while charging " + p.getName()
+ " for sign execution.");
temporaryPlayerNotOnlineError.printStackTrace();
UtilitiesOG.trueogMessage(p, "&cERROR: Could not charge your account right now. Please try again.");
return;
}
} else {
p.sendMessage(ChatColor.RED + "You don't have permission to do this!");
sendWithdrawnMessage(p, priceIsInteger);
}
messages.forEach(sm -> new BukkitRunnable() {
@Override
public void run() {
UtilitiesOG.trueogMessage(p, (sm.getMessage().replaceAll("(?i)%PLAYER%", p.getName())));
}
}.runTaskLater(SudoSigns.sudoSignsPlugin, (long) (sm.getDelay() / 50)));
playerCommands.forEach(sc -> new BukkitRunnable() {
@Override
public void run() {
p.performCommand(sc.getCommand());
}
}.runTaskLater(SudoSigns.sudoSignsPlugin, (long) (sc.getDelay() / 50)));
consoleCommands.forEach(sc -> {
final String cmd = sc.getCommand().replaceAll("(?i)%PLAYER%", p.getName());
new BukkitRunnable() {
@Override
public void run() {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
}
}.runTaskLater(SudoSigns.sudoSignsPlugin, (long) (sc.getDelay() / 50));
});
}
private void sendNotEnoughMoneyMessage(Player p, boolean priceIsInteger) {
if (!SudoSigns.getPlugin().getConfig().getBoolean("config.currency-symbol-in-front")) {
if (priceIsInteger) {
if (priceAsInteger == 1) {
UtilitiesOG.trueogMessage(p, "&cERROR: You do not have a"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ " &cto run this sign! &6The cost is: &e" + priceAsInteger
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&6.");
} else {
UtilitiesOG.trueogMessage(p, "&cERROR: You do not have enough"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ " &cto run this sign! &6The cost is: &e" + priceAsInteger
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&6.");
}
} else {
if (priceAsDouble == 1.0) {
UtilitiesOG.trueogMessage(p, "&cERROR: You do not have a"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ " &cto run this sign! &6The cost is: &e" + priceAsDouble
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&6.");
} else {
UtilitiesOG.trueogMessage(p, "&cERROR: You do not have enough"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ " &cto run this sign! &6The cost is: &e" + priceAsDouble
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&6.");
}
}
return;
}
if (priceIsInteger) {
if (priceAsInteger == 1) {
UtilitiesOG.trueogMessage(p,
"&cERROR: You do not have a"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ " &cto run this sign! &6The cost is: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ priceAsInteger + "&6.");
} else {
UtilitiesOG.trueogMessage(p,
"&cERROR: You do not have enough"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ " &cto run this sign! &6The cost is: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ priceAsInteger + "&6.");
}
} else {
if (priceAsDouble == 1.0) {
UtilitiesOG.trueogMessage(p,
"&cERROR: You do not have a"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ " &cto run this sign! &6The cost is: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ priceAsDouble + "&6.");
} else {
UtilitiesOG.trueogMessage(p,
"&cERROR: You do not have enough"
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ " &cto run this sign! &6The cost is: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ priceAsDouble + "&6.");
}
}
}
private void sendWithdrawnMessage(Player p, boolean priceIsInteger) {
if (!SudoSigns.getPlugin().getConfig().getBoolean("config.currency-symbol-in-front")) {
if (priceIsInteger) {
if (priceAsInteger == 1) {
UtilitiesOG.trueogMessage(p,
"&e" + priceAsInteger
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ " &6has been withdrawn from your balance.");
} else if (priceAsInteger != 0) {
UtilitiesOG.trueogMessage(p,
"&e" + priceAsInteger
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ " &6have been withdrawn from your balance.");
}
} else {
if (priceAsDouble == 1.0) {
UtilitiesOG.trueogMessage(p,
"&e" + priceAsDouble
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular")
+ " &6has been withdrawn from your balance.");
} else if (priceAsDouble != 0.0) {
UtilitiesOG.trueogMessage(p,
"&e" + priceAsDouble
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural")
+ " &6have been withdrawn from your balance.");
}
}
return;
}
if (priceIsInteger) {
if (priceAsInteger == 1) {
UtilitiesOG.trueogMessage(p,
SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ priceAsInteger + " &6has been withdrawn from your balance.");
} else if (priceAsInteger != 0) {
UtilitiesOG.trueogMessage(p,
SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ priceAsInteger + " &6have been withdrawn from your balance.");
}
} else {
if (priceAsDouble == 1.0) {
UtilitiesOG.trueogMessage(p,
SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ priceAsDouble + " &6has been withdrawn from your balance.");
} else if (priceAsDouble != 0.0) {
UtilitiesOG.trueogMessage(p,
SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ priceAsDouble + " &6have been withdrawn from your balance.");
}
}
}
public String getName() {
return name;
}
public Sign getSign() {
if (worldName != null) {
Location loc = new Location(Bukkit.getWorld(worldName), x, y, z);
if (loc.getBlock().getState() instanceof Sign) {
return (Sign) loc.getBlock().getState();
}
public int getNextCommandNumber() {
int number = 0;
for (SignCommand c : consoleCommands) {
number = Math.max(c.getNumber(), number);
}
Bukkit.getLogger().warning("Failed to locate sign " + name + "!");
return null;
for (SignCommand sc : playerCommands) {
number = Math.max(sc.getNumber(), number);
}
return number + 1;
}
public int getNextMessageNumber() {
int number = 0;
for (SignMessage m : messages) {
number = Math.max(m.getNumber(), number);
}
return number + 1;
}
public SignMessage getSignMessageByNumber(int number) {
for (SignMessage sm : messages) {
if (sm.getNumber() == number) {
return sm;
}
}
return null;
}
public SignCommand getSignCommandByNumber(int number) {
for (SignCommand c : consoleCommands) {
if (c.getNumber() == number) {
return c;
}
}
for (SignCommand sc : playerCommands) {
if (sc.getNumber() == number) {
return sc;
}
}
return null;
}
}
@@ -1,10 +1,12 @@
package dev.mylesmor.sudosigns.data;
import dev.mylesmor.sudosigns.menus.SignEditor;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.menus.SignEditor;
/**
* SudoUser class to store all user variables.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
@@ -25,109 +27,171 @@ public class SudoUser {
private PlayerInput inputType;
public SudoUser(Player p) {
this.p = p;
}
public Player getPlayer() {
return p;
}
public void setPlayer(Player p) {
this.p = p;
}
public boolean isSelectToCopy() {
return selectToCopy;
}
public void setSelectToCopy(boolean selectToCopy) {
this.selectToCopy = selectToCopy;
}
public boolean isEdit() {
return edit;
}
public SignEditor getEditor() {
return editor;
}
public boolean isEditing() {
return editing;
}
public void setEditor(SignEditor editor) {
editing = true;
this.editor = editor;
}
public void removeEditor() {
editing = false;
editor = null;
}
public boolean isTextInput() {
return textInput;
}
public PlayerInput getInputType() {
return inputType;
}
public void addTextInput(PlayerInput type) {
this.textInput = true;
this.inputType = type;
}
public void removeTextInput() {
this.textInput = false;
this.inputType = null;
}
}
private String passThru;
public String getPassThru() {
return passThru;
}
public void setPassThru(String passThru) {
this.passThru = passThru;
}
public boolean isView() {
return view;
}
public void setView(boolean view) {
this.view = view;
}
public void setEdit(boolean edit) {
this.edit = edit;
}
public boolean isCreate() {
return create;
}
public void setCreate(boolean create) {
this.create = create;
}
public boolean isDelete() {
return delete;
}
public void setDelete(boolean delete) {
this.delete = delete;
}
public boolean isCopy() {
return copy;
}
public void setCopy(boolean copy) {
this.copy = copy;
}
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
@@ -1,93 +1,393 @@
package dev.mylesmor.sudosigns.listeners;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.util.Consumer;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.util.Util;
import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.trueog.utilitiesog.UtilitiesOG;
/**
* The ChatListener class for taking user input in chat.
*
* @author MylesMor
* @author https://mylesmor.dev
* @Maintainer NotAlexNoyle
* @Maintainer https://true-og.net
*/
public class ChatListener implements Listener {
@EventHandler
public void onPlayerCommandPreprocessEvent(PlayerCommandPreprocessEvent e) {
Player p = e.getPlayer();
SudoUser user = SudoSigns.users.get(p.getUniqueId());
if (user != null) {
if (user.isTextInput() && user.isEditing()) {
e.setCancelled(true);
if (user.getInputType() == PlayerInput.CONSOLE_COMMAND || user.getInputType() == PlayerInput.PLAYER_COMMAND || user.getInputType() == PlayerInput.PLAYER_COMMAND_WITH_PERMISSIONS) {
user.getEditor().getCommandsMenu().addCommand(e.getMessage().substring(1), user.getInputType());
user.removeTextInput();
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "Cancelled!", null);
user.removeTextInput();
}
}
public void onPlayerCommandPreprocessEvent(PlayerCommandPreprocessEvent playerCommandPreprocessEvent) {
final Player p = playerCommandPreprocessEvent.getPlayer();
final SudoUser user = SudoSigns.users.get(p.getUniqueId());
final boolean condition = user != null && user.isTextInput() && user.isEditing();
if (!condition) {
return;
}
if (user.getInputType() == PlayerInput.CONSOLE_COMMAND || user.getInputType() == PlayerInput.PLAYER_COMMAND) {
user.getEditor().getCommandsMenu().addCommand(playerCommandPreprocessEvent.getMessage().substring(1),
user.getInputType());
user.removeTextInput();
} else {
UtilitiesOG.trueogMessage(p, "&eWARNING: &6Operation Cancelled!");
user.removeTextInput();
}
playerCommandPreprocessEvent.setCancelled(true);
}
@EventHandler
public void onAsyncPlayerChat(AsyncPlayerChatEvent e) {
Player p = e.getPlayer();
SudoUser user = SudoSigns.users.get(p.getUniqueId());
if (user != null) {
if (user.isTextInput() && user.isEditing()) {
SignEditor editor = user.getEditor();
switch (user.getInputType()) {
case PLAYER_COMMAND: case CONSOLE_COMMAND: case PLAYER_COMMAND_WITH_PERMISSIONS:
if (e.getMessage().equalsIgnoreCase("cancel")) {
handle(e, true, "Cancelled!", editor, user, null, editor::goToCommands);
return;
}
user.removeTextInput();
handle(e, true, "No command found! Cancelling...", editor, user, null, editor::goToCommands);
break;
case RENAME:
if (e.getMessage().equalsIgnoreCase("cancel")) {
handle(e, true, "Cancelled!", editor, user, null, editor::goToMain);
return;
}
handle(e, true, null, editor, user, edit -> editor.renameSign(ChatColor.stripColor(e.getMessage())), editor::goToMain);
break;
case PERMISSION:
if (e.getMessage().equalsIgnoreCase("cancel")) {
handle(e, true, "Cancelled!", editor, user, null, editor::goToPermissions);
return;
}
handle(e, true, null, editor, user, edit -> editor.getPermMenu().addPermission(true, ChatColor.stripColor(e.getMessage())), editor::goToPermissions);
break;
case MESSAGE:
if (e.getMessage().equalsIgnoreCase("cancel")) {
handle(e, true, "Cancelled!", editor, user, null, editor::goToMessages);
return;
}
handle(e, true, null, editor, user, edit -> editor.getMessagesMenu().addMessage(ChatColor.stripColor(e.getMessage())), editor::goToMessages);
break;
public void onAsyncPlayerChat(AsyncChatEvent asyncChatEvent) {
final Player p = asyncChatEvent.getPlayer();
final SudoUser user = SudoSigns.users.get(p.getUniqueId());
final boolean condition = user != null && user.isTextInput() && user.isEditing();
if (!condition) {
return;
}
final SignEditor editor = user.getEditor();
switch (user.getInputType()) {
case PLAYER_COMMAND, CONSOLE_COMMAND -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToCommands);
return;
}
user.removeTextInput();
handle(asyncChatEvent, true, "No command found! Cancelling...", editor, user, null,
editor::goToCommands);
}
case RENAME -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToMain);
return;
}
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.renameSign(
PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())),
editor::goToMain);
}
case PERMISSION -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToPermissions);
return;
}
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getPermMenu().addPermission(true,
PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())),
editor::goToPermissions);
}
case MESSAGE -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToMessages);
return;
}
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getMessagesMenu().addMessage(
PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())),
editor::goToMessages);
}
case COMMAND_DELAY -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToCommands);
return;
}
double delay = 0;
try {
delay = Double
.parseDouble(PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message()));
} catch (NumberFormatException numberFormatException) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter a valid number.");
return;
}
final double finalDelay = delay;
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getCommandOptionsMenu().setDelay(finalDelay), editor::goToCommands);
}
case MESSAGE_DELAY -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToMessages);
return;
}
double messageDelay = 0;
try {
messageDelay = Double
.parseDouble(PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message()));
} catch (NumberFormatException nfe) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter a valid number!");
return;
}
final double finalMessageDelay = messageDelay;
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getMessageOptionsMenu().setDelay(finalMessageDelay), editor::goToMessages);
}
case EDIT_TEXT_NUMBER -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToMessages);
return;
}
int lineNumber = 0;
try {
lineNumber = Integer
.parseInt(PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message()));
} catch (NumberFormatException nfe) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter a valid number between 1-4!");
return;
}
if (lineNumber < 1 || lineNumber > 4) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter a valid number between 1-4!");
return;
}
final int finalLineNumber = lineNumber;
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getMainMenu().setLineNumber(finalLineNumber), null);
}
case EDIT_TEXT -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToMessages);
return;
}
// Regular expression contributed by lazerl0rd (MIT) at
// https://github.com/MylesMor/SudoSigns/pull/4
// https://web.archive.org/web/20260302082938/https://github.com/MylesMor/SudoSigns/pull/4
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.replaceAll("&([0-9]|[a-g]|[k-o]|r)", "").length() > 15)
{
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: The message can't be greater than 15 characters!");
return;
}
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getMainMenu()
.setText(UtilitiesOG.trueogColorize(
PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message()))),
editor::goToMain);
}
case SET_PRICE -> {
if (PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message())
.equalsIgnoreCase("cancel"))
{
handle(asyncChatEvent, true, "Cancelled!", editor, user, null, editor::goToMessages);
return;
}
if (Util.priceIsInteger()) {
final int price;
try {
price = Integer
.parseInt(PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message()));
} catch (NumberFormatException nfe) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter a valid integer!");
return;
}
if (price < 0) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter &e0&c, or a positive integer!");
return;
}
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getMainMenu().setPriceAsInteger(price), editor::goToMain);
} else {
final double price;
try {
price = Double.parseDouble(
PlainTextComponentSerializer.plainText().serialize(asyncChatEvent.message()));
} catch (NumberFormatException nfe) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter a valid number!");
return;
}
if (price < 0) {
asyncChatEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p, "&cERROR: Please enter &e0&c, or a positive number!");
return;
}
handle(asyncChatEvent, true, null, editor, user,
edit -> editor.getMainMenu().setPriceAsDouble(price), editor::goToMain);
}
}
}
}
private void handle(AsyncPlayerChatEvent e, boolean cancel, String message, SignEditor editor, SudoUser user, Consumer<SignEditor> eventConsumer, Runnable finalAction) {
if (cancel) e.setCancelled(true);
if (message != null) Util.sudoSignsMessage(e.getPlayer(), ChatColor.RED, message, null);
if (eventConsumer != null) Bukkit.getScheduler().runTask(SudoSigns.sudoSignsPlugin, () -> eventConsumer.accept(editor));
private void handle(AsyncChatEvent e, boolean cancel, String message, SignEditor editor, SudoUser user,
Consumer<SignEditor> eventConsumer, Runnable finalAction)
{
if (cancel) {
e.setCancelled(true);
}
if (message != null) {
UtilitiesOG.trueogMessage(e.getPlayer(), "&c" + message);
}
if (eventConsumer != null) {
Bukkit.getScheduler().runTask(SudoSigns.sudoSignsPlugin, () -> eventConsumer.accept(editor));
}
user.removeTextInput();
Bukkit.getScheduler().runTask(SudoSigns.sudoSignsPlugin, finalAction);
if (finalAction != null) {
Bukkit.getScheduler().runTask(SudoSigns.sudoSignsPlugin, finalAction);
}
}
}
}
@@ -1,12 +1,8 @@
package dev.mylesmor.sudosigns.listeners;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import java.util.Objects;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -14,12 +10,18 @@ import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import java.util.Objects;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.util.Permissions;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
/**
* InventoryListener class to listen for GUI actions.
*
* @author MylesMor
* @author https://mylesmor.dev
*/
@@ -27,179 +29,262 @@ public class InventoryListener implements Listener {
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
Player p = (Player) e.getWhoClicked();
SudoUser user = SudoSigns.users.get(p.getUniqueId());
if (user != null) {
if (user.isEditing()) {
if (Objects.equals(e.getClickedInventory(), e.getView().getTopInventory())) {
SignEditor editor = user.getEditor();
if (e.getCurrentItem() != null) {
e.setCancelled(true);
Material m = e.getCurrentItem().getType();
String itemName = ChatColor.stripColor(Objects.requireNonNull(e.getCurrentItem().getItemMeta()).getDisplayName());
switch (editor.getCurrentPage()) {
case MAIN:
checkForMainMenuClicks(editor, m);
break;
case COMMANDS:
checkForCommandsClicks(p, editor, m, itemName);
break;
case PERMISSIONS:
checkForPermissionsClicks(p, editor, m, itemName);
break;
case CHOOSE_COMMAND:
chooseCommandType(editor, m, itemName);
break;
case CHOOSE_PERMISSION:
choosePermissionType(editor, m);
break;
case MESSAGES:
if (e.getCurrentItem().getItemMeta().getLore() != null) {
checkForMessagesClicks(p, editor, m, e.getCurrentItem().getItemMeta().getLore().get(0).replace("§", "&"));
} else {
checkForMessagesClicks(p, editor, m, null);
}
}
}
final Player p = (Player) e.getWhoClicked();
final SudoUser user = SudoSigns.users.get(p.getUniqueId());
final boolean condition = user != null && user.isEditing()
&& Objects.equals(e.getClickedInventory(), e.getView().getTopInventory());
if (condition) {
final SignEditor editor = user.getEditor();
if (e.getCurrentItem() != null) {
e.setCancelled(true);
final Material m = e.getCurrentItem().getType();
final String itemName = e.getCurrentItem().getDisplayName();
switch (editor.getCurrentPage()) {
case MAIN -> checkForMainMenuClicks(editor, m);
case COMMANDS -> checkForCommandsClicks(p, editor, m, e.getCurrentItem());
case PERMISSIONS -> checkForPermissionsClicks(p, editor, m, itemName);
case CHOOSE_COMMAND -> chooseCommandType(editor, m, itemName);
case CHOOSE_PERMISSION -> choosePermissionType(editor, m);
case MESSAGES -> checkForMessagesClicks(p, editor, m, e.getCurrentItem());
case COMMAND_OPTIONS -> checkForCommandOptionClicks(p, editor, m, itemName);
case MESSAGE_OPTIONS -> checkForMessageOptionClicks(p, editor, m, itemName);
}
}
}
}
@EventHandler
public void closeInventory(InventoryCloseEvent e) {
Player p = (Player) e.getPlayer();
SudoUser user = SudoSigns.users.get(p.getUniqueId());
if (user != null) {
// Checks whether the user has closed the GUI.
if (user.isEditing()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(SudoSigns.sudoSignsPlugin, () -> {
InventoryView currentInv = p.getOpenInventory();
if (currentInv.getTitle().equalsIgnoreCase("CRAFTING") && !user.isTextInput()) {
user.getEditor().endEditor();
user.removeEditor();
}
}, 5L);
}
final Player p = (Player) e.getPlayer();
final SudoUser user = SudoSigns.users.get(p.getUniqueId());
final boolean condition = user != null && user.isEditing();
// Checks whether the user has closed the GUI.
if (condition) {
Bukkit.getScheduler().scheduleSyncDelayedTask(SudoSigns.sudoSignsPlugin, () -> {
final InventoryView currentInv = p.getOpenInventory();
if (PlainTextComponentSerializer.plainText().serialize(currentInv.title()).equalsIgnoreCase("CRAFTING")
&& !user.isTextInput())
{
user.getEditor().endEditor();
user.removeEditor();
}
}, 5L);
}
}
/**
* Checks for GUI clicks in the main menu.
*
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
* @param m The material clicked on in the menu.
*/
public void checkForMainMenuClicks(SignEditor editor, Material m) {
if (SudoSigns.version.contains("1.13")) {
if (m.equals(Material.valueOf("SIGN"))) {
editor.goToMessages();
return;
if (m.equals(Material.OAK_SIGN)) {
editor.goToMessages();
return;
}
switch (m) {
case NAME_TAG -> editor.prepareRename();
case WRITABLE_BOOK -> editor.editSignNumber();
case BARRIER -> editor.goToPermissions();
case COMMAND_BLOCK -> editor.goToCommands();
case BIRCH_SIGN -> editor.goToMessages();
case GOLD_NUGGET -> editor.getMainMenu().prepareSetPrice();
default -> {
}
}
switch (m) {
case BOOK:
editor.prepareRename();
break;
case OAK_SIGN:
editor.editSignText();
break;
case BARRIER:
editor.goToPermissions();
break;
case COMMAND_BLOCK:
editor.goToCommands();
break;
case BIRCH_SIGN:
editor.goToMessages();
}
}
/**
* Checks for GUI clicks in the Commands menu.
* Checks for GUI clicks in the Command Options menu.
*
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
* @param m The material clicked on in the menu.
* @param item The ItemStack of the clicked item.
*/
public void checkForCommandsClicks(Player p, SignEditor editor, Material m, ItemStack item) {
switch (m) {
case WRITABLE_BOOK -> editor.getCommandsMenu().prepareCommand();
case BOOK -> {
if (p.hasPermission(Permissions.COMMAND_OPTIONS)) {
editor.goToCommandOptionsMenu(item);
}
}
case ARROW -> editor.goToMain();
default -> {
}
}
}
/**
* Checks for GUI clicks in the Command Options menu.
*
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
* @param itemName The name of the item clicked.
*/
public void checkForCommandsClicks(Player p, SignEditor editor, Material m, String itemName) {
public void checkForCommandOptionClicks(Player p, SignEditor editor, Material m, String itemName) {
switch (m) {
case WRITABLE_BOOK:
editor.getCommandsMenu().prepareCommand();
break;
case BOOK:
case CLOCK -> editor.getCommandOptionsMenu().addDelay();
case BARRIER -> {
if (p.hasPermission(Permissions.DELETE_COMMAND)) {
editor.getCommandsMenu().deleteCommand(ChatColor.stripColor(itemName));
editor.getCommandOptionsMenu().deleteCommand();
}
break;
case ARROW:
editor.goToMain();
}
case ARROW -> editor.goToCommands();
default -> {
}
}
}
/**
* Checks for GUI clicks in the Commands menu.
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
*
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
* @param itemName The name of the item clicked.
*/
public void checkForMessagesClicks(Player p, SignEditor editor, Material m, String itemName) {
public void checkForMessageOptionClicks(Player p, SignEditor editor, Material m, String itemName) {
switch (m) {
case WRITABLE_BOOK:
editor.getMessagesMenu().prepareMessage();
break;
case BOOK:
case CLOCK -> editor.getMessageOptionsMenu().addDelay();
case BARRIER -> {
if (p.hasPermission(Permissions.DELETE_MESSAGE)) {
editor.getMessagesMenu().deleteMessage(itemName.substring(4));
editor.getMessageOptionsMenu().deleteMessage();
}
break;
case ARROW:
editor.goToMain();
}
case ARROW -> editor.goToMessages();
default -> {
}
}
}
/**
* Checks for GUI clicks in the Commands menu.
*
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
* @param item The ItemStack of the clicked item.
*/
public void checkForMessagesClicks(Player p, SignEditor editor, Material m, ItemStack item) {
switch (m) {
case WRITABLE_BOOK -> editor.getMessagesMenu().prepareMessage();
case BOOK -> {
if (p.hasPermission(Permissions.MESSAGE_OPTIONS)) {
editor.goToMessageOptionsMenu(item);
}
}
case ARROW -> editor.goToMain();
default -> {
}
}
}
public void choosePermissionType(SignEditor editor, Material m) {
switch (m) {
case PLAYER_HEAD:
editor.getPermMenu().addPermission(true, null);
break;
case COMMAND_BLOCK:
editor.getPermMenu().addPermission(false, null);
break;
case ARROW:
editor.goToPermissions();
case PLAYER_HEAD -> editor.getPermMenu().addPermission(true, null);
case COMMAND_BLOCK -> editor.getPermMenu().addPermission(false, null);
case ARROW -> editor.goToPermissions();
default -> {
}
}
}
public void chooseCommandType(SignEditor editor, Material m, String itemName) {
switch (m) {
case CHAIN_COMMAND_BLOCK:
editor.getCommandsMenu().chooseCommandType(PlayerInput.PLAYER_COMMAND_WITH_PERMISSIONS);
break;
case PLAYER_HEAD:
editor.getCommandsMenu().chooseCommandType(PlayerInput.PLAYER_COMMAND);
break;
case COMMAND_BLOCK:
editor.getCommandsMenu().chooseCommandType(PlayerInput.CONSOLE_COMMAND);
break;
case ARROW:
editor.goToCommands();
break;
case PLAYER_HEAD -> editor.getCommandsMenu().chooseCommandType(PlayerInput.PLAYER_COMMAND);
case COMMAND_BLOCK -> editor.getCommandsMenu().chooseCommandType(PlayerInput.CONSOLE_COMMAND);
case ARROW -> editor.goToCommands();
default -> {
}
}
}
/**
* Checks for GUI clicks in the Permissions menu.
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
*
* @param editor The SignEditor class of the particular user.
* @param m The material clicked on in the menu.
* @param itemName The name of the item clicked.
*/
public void checkForPermissionsClicks(Player p, SignEditor editor, Material m, String itemName) {
switch (m) {
case BOOK:
if (p.hasPermission(Permissions.DELETE_PERMISSION)) {
editor.getPermMenu().deletePermission(ChatColor.stripColor(itemName));
editor.getPermMenu().deletePermission(itemName);
}
break;
case WRITABLE_BOOK:
@@ -207,6 +292,11 @@ public class InventoryListener implements Listener {
break;
case ARROW:
editor.goToMain();
default:
break;
}
}
}
@@ -1,14 +1,18 @@
package dev.mylesmor.sudosigns.listeners;
import dev.mylesmor.sudosigns.SudoSigns;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import dev.mylesmor.sudosigns.SudoSigns;
public class PlayerListener implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
SudoSigns.users.remove(e.getPlayer().getUniqueId());
}
}
@@ -1,13 +1,9 @@
package dev.mylesmor.sudosigns.listeners;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.ChatColor;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
@@ -16,317 +12,500 @@ import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.*;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.menus.SignEditor;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class SignListener implements Listener {
private final DiamondBankAPIJava diamondBankAPI;
public SignListener(DiamondBankAPIJava diamondBankAPI) {
this.diamondBankAPI = diamondBankAPI;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
Player p = e.getPlayer();
if (e.getClickedBlock() != null) {
SudoUser user = SudoSigns.users.get(p.getUniqueId());
if (user != null) {
Block b = e.getClickedBlock();
if (user.isCreate()) {
e.setCancelled(true);
create(p, user, b);
} else if (user.isSelectToCopy()) {
e.setCancelled(true);
selectToCopy(p, user, b);
} else if (user.isCopy()) {
e.setCancelled(true);
copy(p, user, b);
} else if (user.isEdit()) {
e.setCancelled(true);
edit(p, user, b);
} else if (user.isDelete()) {
e.setCancelled(true);
delete(p, user, b);
} else if (user.isRun()) {
e.setCancelled(true);
runRemote(p, user, b);
} else if (user.isView()) {
e.setCancelled(true);
view(p, user, b);
} else {
runSign(p, e);
}
} else {
runSign(p, e);
}
public void onPlayerInteract(PlayerInteractEvent playerInteractEvent) {
final Player p = playerInteractEvent.getPlayer();
if (playerInteractEvent.getClickedBlock() == null) {
return;
}
final SudoUser user = SudoSigns.users.get(p.getUniqueId());
if (user != null) {
final Block b = playerInteractEvent.getClickedBlock();
if (user.isCreate()) {
playerInteractEvent.setCancelled(true);
create(p, user, b);
} else if (user.isSelectToCopy()) {
playerInteractEvent.setCancelled(true);
selectToCopy(p, user, b);
} else if (user.isCopy()) {
playerInteractEvent.setCancelled(true);
copy(p, user, b);
} else if (user.isEdit()) {
playerInteractEvent.setCancelled(true);
edit(p, user, b);
} else if (user.isDelete()) {
playerInteractEvent.setCancelled(true);
delete(p, user, b);
} else if (user.isRun()) {
playerInteractEvent.setCancelled(true);
runRemote(p, user, b);
} else if (user.isView()) {
playerInteractEvent.setCancelled(true);
view(p, user, b);
} else {
runSign(p, playerInteractEvent);
}
} else {
runSign(p, playerInteractEvent);
}
}
private void selectToCopy(Player p, SudoUser user, Block b) {
if (b.getState() instanceof Sign) {
Sign sign = (Sign) b.getState();
String name = Util.findSign(sign);
final Sign sign = Util.getSign(b);
if (sign != null) {
final String name = Util.findSign(sign);
if (name != null) {
user.setSelectToCopy(false);
p.performCommand("ss copy " + name + " " + user.getPassThru());
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "Failed to copy: this is not a SudoSign!", null);
UtilitiesOG.trueogMessage(p, "&cERROR: Failed to copy: that is not a SudoSign!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign wasn't clicked! &6Cancelling...");
}
user.setSelectToCopy(false);
}
private void runSign(Player p, PlayerInteractEvent e) {
if (Objects.requireNonNull(e.getClickedBlock()).getState() instanceof Sign) {
if (p.hasPermission(Permissions.SELECT) && e.getAction() == Action.RIGHT_CLICK_BLOCK || !p.hasPermission(Permissions.SELECT)) {
Sign sign = (Sign) e.getClickedBlock().getState();
String name = Util.findSign(sign);
if (name != null) {
SudoSigns.signs.get(name).executeCommands(p);
}
}
final boolean condition = Util.isSignBlock(Objects.requireNonNull(e.getClickedBlock()))
&& (p.hasPermission(Permissions.SELECT) && e.getAction() == Action.RIGHT_CLICK_BLOCK
|| !p.hasPermission(Permissions.SELECT));
if (!condition) {
return;
}
final Sign sign = Util.getSign(e.getClickedBlock());
if (sign == null) {
return;
}
final String name = Util.findSign(sign);
if (name != null) {
SudoSigns.signs.get(name).executeCommands(p);
}
}
private void create(Player p, SudoUser user, Block b) {
if (b.getBlockData() instanceof org.bukkit.block.data.type.Sign || b.getBlockData() instanceof org.bukkit.block.data.type.WallSign) {
//if (b.getState() instanceof Sign) {
Sign sign = (Sign) b.getState();
String name = Util.findSign(sign);
final Sign sign = Util.getSign(b);
if (sign != null) {
final String name = Util.findSign(sign);
if (name != null) {
user.setCreate(false);
SudoSigns.signs.remove(user.getPassThru());
Util.sudoSignsMessage(p, ChatColor.RED, "This sign is already a SudoSign! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: That SudoSign already exists! &6Cancelling...");
return;
}
SudoSigns.signs.get(user.getPassThru()).setSign(sign);
SudoSigns.signs.get(user.getPassThru()).addLines();
if (p.hasPermission(Permissions.EDIT)) {
SignEditor editor = new SignEditor(p, SudoSigns.signs.get(user.getPassThru()), user);
final SignEditor editor = new SignEditor(p, SudoSigns.signs.get(user.getPassThru()), user,
diamondBankAPI);
user.setEditor(editor);
}
SudoSigns.config.saveToFile(SudoSigns.signs.get(user.getPassThru()), true, p);
SudoSigns.config.saveSign(SudoSigns.signs.get(user.getPassThru()), true, p);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign was not clicked! Cancelling...");
user.setCreate(false);
SudoSigns.signs.remove(user.getPassThru());
}
user.setCreate(false);
}
private void copy(Player p, SudoUser user, Block b) {
if (b.getState() instanceof Sign) {
Sign newSign = (Sign) b.getState();
String name = Util.findSign(newSign);
final Sign newSign = Util.getSign(b);
if (newSign != null) {
final String name = Util.findSign(newSign);
if (name != null) {
user.setCopy(false);
SudoSigns.signs.remove(user.getPassThru());
Util.sudoSignsMessage(p, ChatColor.RED, "This sign is already a SudoSign! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: That sign is already a SudoSign! Cancelling...");
return;
}
SudoSigns.signs.get(user.getPassThru()).setSign(newSign);
SudoSigns.signs.get(user.getPassThru()).addLines();
SudoSigns.config.saveToFile(SudoSigns.signs.get(user.getPassThru()), true, p);
Util.sudoSignsMessage(p, ChatColor.GRAY, "Sign has been copied to sign %NAME% successfully!", user.getPassThru());
SudoSigns.config.saveSign(SudoSigns.signs.get(user.getPassThru()), true, p);
UtilitiesOG.trueogMessage(p, "&aSign has been copied to sign &e" + user.getPassThru() + " &asuccessfully!");
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign was not clicked! &6Cancelling...");
SudoSigns.signs.remove(user.getPassThru());
}
user.setCopy(false);
}
private void runRemote(Player p, SudoUser user, Block b) {
if (b.getState() instanceof Sign) {
Sign sign = (Sign) b.getState();
String name = Util.findSign(sign);
final Sign sign = Util.getSign(b);
if (sign != null) {
final String name = Util.findSign(sign);
if (name != null) {
p.performCommand("ss run " +name);
p.performCommand("ss run " + name);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "This is not a SudoSign. Use " + ChatColor.GRAY + "/ss create <name>" + ChatColor.RED + " instead.", null);
UtilitiesOG.trueogMessage(p, "&cERROR: That is not a SudoSign! &6Use: &d/ss create <name> &6instead.");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED,"A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign was not clicked! Cancelling...");
}
user.setRun(false);
}
private void edit(Player p, SudoUser user, Block b) {
if (b.getState() instanceof Sign) {
Sign sign = (Sign) b.getState();
String name = Util.findSign(sign);
final Sign sign = Util.getSign(b);
if (sign != null) {
final String name = Util.findSign(sign);
if (name != null) {
p.performCommand("ss edit " + name);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "This is not a SudoSign. Use " + ChatColor.GRAY + "/ss create <name>" + ChatColor.RED + " instead.", null);
UtilitiesOG.trueogMessage(p, "&cERROR: That is not a SudoSign! &6Use: &d/ss create <name> &6instead.");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED,"A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign was not clicked! Cancelling...");
}
user.setEdit(false);
}
private void delete(Player p, SudoUser user, Block b) {
if (b.getState() instanceof Sign) {
Sign sign = (Sign) b.getState();
String name = Util.findSign(sign);
final Sign sign = Util.getSign(b);
if (sign != null) {
final String name = Util.findSign(sign);
if (name != null) {
p.performCommand("ss delete " + name);
Util.sudoSignsMessage(p, ChatColor.RED, "This is not a SudoSign!", null);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "This is not a SudoSign!", null);
UtilitiesOG.trueogMessage(p, "&cERROR: That is not a SudoSign!");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED,"A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign was not clicked! &6Cancelling...");
}
user.setDelete(false);
}
private void view(Player p, SudoUser user, Block b) {
if (b.getState() instanceof Sign) {
Sign sign = (Sign) b.getState();
String name = Util.findSign(sign);
final Sign sign = Util.getSign(b);
if (sign != null) {
final String name = Util.findSign(sign);
if (name != null) {
p.performCommand("ss view " + name);
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "This is not a SudoSign. Use " + ChatColor.GRAY + "/ss create <name>" + ChatColor.RED + " instead.", null);
UtilitiesOG.trueogMessage(p, "&cERROR: That is not a SudoSign! &6Use: &d/ss create <name> &6instead.");
}
} else {
Util.sudoSignsMessage(p, ChatColor.RED,"A sign wasn't clicked! Cancelling...", null);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign was not clicked! &6Cancelling...");
}
user.setView(false);
}
@EventHandler
public void onDestroy(BlockBreakEvent e) {
Player p = e.getPlayer();
if (e.getBlock().getState() instanceof Sign) {
Sign sign = (Sign) e.getBlock().getState();
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
e.setCancelled(true);
if (p.hasPermission(Permissions.SELECT)) {
String message = Util.getSelectString(p, entry.getKey());
p.spigot().sendMessage(ComponentSerializer.parse(message));
} else {
Util.sudoSignsMessage(p, ChatColor.RED, "You don't have permission to destroy this sign!", null);
}
}
}
public void onDestroy(BlockBreakEvent blockBreakEvent) {
final Player p = blockBreakEvent.getPlayer();
final Sign sign = Util.getSign(blockBreakEvent.getBlock());
if (sign != null) {
SudoSigns.signs.entrySet().stream()
.filter(entry -> Util.sameBlockLocation(entry.getValue(), sign.getLocation())).forEach(entry ->
{
blockBreakEvent.setCancelled(true);
if (p.hasPermission(Permissions.SELECT)) {
Util.sendSelectMenus(p, entry.getKey());
} else {
Util.sudoSignsPermissionsError(p);
}
});
} else {
final BlockFace[] faces = {BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
final BlockFace[] faces = { BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH,
BlockFace.WEST };
for (BlockFace face : faces) {
Block br = e.getBlock().getRelative(face);
BlockState bs = br.getState();
if (bs instanceof Sign) {
Sign sign = (Sign) bs;
final Block br = blockBreakEvent.getBlock().getRelative(face);
final BlockState bs = br.getState();
if (Util.isSignState(bs)) {
final Sign nearbySign = (Sign) bs;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
if (br.getBlockData() instanceof org.bukkit.block.data.type.Sign) {
if (e.getBlock().equals(sign.getBlock().getRelative(BlockFace.DOWN))) {
e.setCancelled(true);
Util.sudoSignsMessage(p, ChatColor.RED, "You can't destroy a block that's attached to a SudoSign!", null);
if (Util.sameBlockLocation(entry.getValue(), nearbySign.getLocation())) {
if (br.getBlockData() instanceof Sign) {
if (blockBreakEvent.getBlock()
.equals(nearbySign.getBlock().getRelative(BlockFace.DOWN)))
{
blockBreakEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p,
"&cERROR: You cannot destroy a block that is attached to a SudoSign!");
return;
}
} else if (br.getBlockData() instanceof org.bukkit.block.data.type.WallSign) {
WallSign signData = (WallSign) sign.getBlock().getState().getBlockData();
BlockFace attached = signData.getFacing().getOppositeFace();
Block blockAttached = sign.getBlock().getRelative(attached);
if (e.getBlock().equals(blockAttached)) {
e.setCancelled(true);
Util.sudoSignsMessage(p, ChatColor.RED, "You can't destroy a block that's attached to a SudoSign!", null);
} else if (br.getBlockData() instanceof WallSign) {
final WallSign signData = (WallSign) nearbySign.getBlock().getState().getBlockData();
final BlockFace attached = signData.getFacing().getOppositeFace();
final Block blockAttached = nearbySign.getBlock().getRelative(attached);
if (blockBreakEvent.getBlock().equals(blockAttached)) {
blockBreakEvent.setCancelled(true);
UtilitiesOG.trueogMessage(p,
"&cERROR: You cannot destroy a block that is attached to a SudoSign!");
return;
}
}
}
}
}
}
}
}
// The following events all attempts to prevent a SudoSign from being broken.
@EventHandler
public void onEntityExplode(EntityExplodeEvent e) {
ArrayList<Block> blocksToRemove = new ArrayList<>();
for (Block block : e.blockList()) {
if (block.getState() instanceof Sign) {
Sign sign = (Sign) block.getState();
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
blocksToRemove.add(block);
}
}
public void onEntityExplode(EntityExplodeEvent entityExplodeEvent) {
final ArrayList<Block> blocksToRemove = new ArrayList<>();
entityExplodeEvent.blockList().forEach(block -> {
final Sign sign = Util.getSign(block);
if (sign != null) {
SudoSigns.signs.entrySet().stream()
.filter(entry -> Util.sameBlockLocation(entry.getValue(), sign.getLocation()))
.forEach(entry -> blocksToRemove.add(block));
}
final BlockFace[] faces = {BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
final BlockFace[] faces = { BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH,
BlockFace.WEST };
for (BlockFace face : faces) {
BlockState b = block.getRelative(face).getState();
if (b instanceof Sign) {
Sign sign = (Sign) b;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
blocksToRemove.add(block);
}
}
final BlockState b = block.getRelative(face).getState();
if (Util.isSignState(b)) {
final Sign nearbySign = (Sign) b;
SudoSigns.signs.entrySet().stream()
.filter(entry -> Util.sameBlockLocation(entry.getValue(), nearbySign.getLocation()))
.forEach(entry -> blocksToRemove.add(block));
}
}
}
for (Block b : blocksToRemove) {
e.blockList().remove(b);
}
});
blocksToRemove.forEach(b -> entityExplodeEvent.blockList().remove(b));
}
@EventHandler
public void onBlockBurn(BlockBurnEvent e) {
final BlockFace[] faces = {BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
public void onBlockBurn(BlockBurnEvent blockBurnEvent) {
final BlockFace[] faces = { BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
for (BlockFace face : faces) {
BlockState b = e.getBlock().getRelative(face).getState();
if (b instanceof Sign) {
Sign sign = (Sign) b;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
e.setCancelled(true);
}
}
final BlockState b = blockBurnEvent.getBlock().getRelative(face).getState();
if (Util.isSignState(b)) {
final Sign sign = (Sign) b;
SudoSigns.signs.entrySet().stream()
.filter(entry -> Util.sameBlockLocation(entry.getValue(), sign.getLocation()))
.forEach(entry -> blockBurnEvent.setCancelled(true));
}
}
}
@EventHandler
public void onBlockFade(BlockFadeEvent e) {
final BlockFace[] faces = {BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
public void onBlockFade(BlockFadeEvent blockFadeEvent) {
final BlockFace[] faces = { BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
for (BlockFace face : faces) {
BlockState b = e.getBlock().getRelative(face).getState();
if (b instanceof Sign) {
Sign sign = (Sign) b;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
e.setCancelled(true);
}
}
final BlockState b = blockFadeEvent.getBlock().getRelative(face).getState();
if (Util.isSignState(b)) {
final Sign sign = (Sign) b;
SudoSigns.signs.entrySet().stream()
.filter(entry -> Util.sameBlockLocation(entry.getValue(), sign.getLocation()))
.forEach(entry -> blockFadeEvent.setCancelled(true));
}
}
}
@EventHandler
public void onLeavesDecay(LeavesDecayEvent e) {
final BlockFace[] faces = {BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
public void onLeavesDecay(LeavesDecayEvent leavesDecayEvent) {
final BlockFace[] faces = { BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
for (BlockFace face : faces) {
BlockState b = e.getBlock().getRelative(face).getState();
if (b instanceof Sign) {
Sign sign = (Sign) b;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
if (entry.getValue().getSign().equals(sign)) {
e.setCancelled(true);
}
}
final BlockState b = leavesDecayEvent.getBlock().getRelative(face).getState();
if (Util.isSignState(b)) {
final Sign sign = (Sign) b;
SudoSigns.signs.entrySet().stream()
.filter(entry -> Util.sameBlockLocation(entry.getValue(), sign.getLocation()))
.forEach(entry -> leavesDecayEvent.setCancelled(true));
}
}
}
}
@@ -0,0 +1,166 @@
package dev.mylesmor.sudosigns.menus;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.kyori.adventure.text.TextComponent;
import net.trueog.utilitiesog.UtilitiesOG;
public class CommandOptionsMenu {
private Inventory menu;
private final SudoUser su;
private final SudoSign sign;
private final SignCommand sc;
private final Player p;
private final SignEditor editor;
CommandOptionsMenu(SudoUser su, Player p, SudoSign sign, ItemStack item, SignEditor editor) {
this.su = su;
this.sign = sign;
this.p = p;
this.editor = editor;
this.sc = findSignCommand(item);
if (this.sc == null) {
editor.goToCommands();
return;
}
}
public void goToCommandOptionsMenu() {
createCommandOptionsMenu();
p.openInventory(menu);
}
private SignCommand findSignCommand(ItemStack item) {
final NamespacedKey key = new NamespacedKey(SudoSigns.sudoSignsPlugin, "command-number");
final ItemMeta itemMeta = item.getItemMeta();
final PersistentDataContainer container = itemMeta.getPersistentDataContainer();
if (container.has(key, PersistentDataType.INTEGER)) {
final int foundValue = container.get(key, PersistentDataType.INTEGER);
return sign.getSignCommandByNumber(foundValue);
}
return null;
}
private void createCommandOptionsMenu() {
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("Command options: /" + sc.getCommand());
menu = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
}
final List<String> lore = new ArrayList<>();
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
final ItemStack clock = new ItemStack(Material.CLOCK);
final ItemMeta clockMeta = clock.getItemMeta();
lore.add("&eChange the delay after which the command executes");
clockMeta.displayName(UtilitiesOG.trueogColorize("&r&dChange Delay"));
clockMeta.lore(Util.convertToTextComponents(lore));
clock.setItemMeta(clockMeta);
final ItemStack barrier = new ItemStack(Material.BARRIER);
final ItemMeta barrierMeta = barrier.getItemMeta();
barrierMeta.displayName(UtilitiesOG.trueogColorize("&r&cDelete Command"));
barrier.setItemMeta(barrierMeta);
if (p.hasPermission(Permissions.COMMAND_OPTIONS) && p.hasPermission(Permissions.DELETE_COMMAND)) {
menu.setItem(20, clock);
menu.setItem(24, barrier);
} else {
menu.setItem(22, clock);
}
menu.setItem(36, arrow);
}
public void addDelay() {
p.closeInventory();
UtilitiesOG.trueogMessage(p, "&6Please enter the delay in seconds. To cancel, type &cCANCEL&6.");
su.addTextInput(PlayerInput.COMMAND_DELAY);
}
public void setDelay(double delay) {
final double oldDelay = sc.getDelay();
sc.setDelay(delay * 1000);
SudoSigns.config.deleteCommand(sign, sc, sc.getType(), oldDelay);
SudoSigns.config.addCommand(sign, sc, sc.getType());
}
public void deleteCommand() {
if (sc.getType() == PlayerInput.CONSOLE_COMMAND) {
SudoSigns.config.deleteCommand(sign, sc, PlayerInput.CONSOLE_COMMAND, sc.getDelay());
sign.deleteConsoleCommand(sc);
} else if (sc.getType() == PlayerInput.PLAYER_COMMAND) {
SudoSigns.config.deleteCommand(sign, sc, PlayerInput.PLAYER_COMMAND, sc.getDelay());
sign.deletePlayerCommand(sc);
}
editor.goToCommands();
}
}
@@ -1,5 +1,19 @@
package dev.mylesmor.sudosigns.menus;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
@@ -7,221 +21,256 @@ import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.kyori.adventure.text.TextComponent;
import net.trueog.utilitiesog.UtilitiesOG;
public class CommandsMenu {
private final GUIPage PAGE = GUIPage.COMMANDS;
private Inventory menu;
private Player p;
private SudoSign sign;
private SignEditor editor;
private SudoUser su;
private final Player p;
private final SudoSign sign;
private final SignEditor editor;
private final SudoUser su;
public CommandsMenu(SudoUser su, Player p, SudoSign sign, SignEditor editor) {
this.su = su;
this.sign = sign;
this.editor = editor;
this.p = p;
}
public void goToCommandsMenu() {
createCommandsMenu();
p.openInventory(menu);
editor.setCurrentPage(PAGE);
}
private void createCommandsMenu() {
menu = Bukkit.createInventory(p, 45, "Commands: " + sign.getName());
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("Commands: " + sign.getName());
menu = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
}
ItemStack arrow = new ItemStack(Material.ARROW);
ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "BACK");
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
if (p.hasPermission(Permissions.ADD_COMMAND)) {
ItemStack bookQuill = new ItemStack(Material.WRITABLE_BOOK);
ItemMeta bqMeta = bookQuill.getItemMeta();
bqMeta.setDisplayName("" + ChatColor.RESET + ChatColor.GREEN + "Add new command");
final ItemStack bookQuill = new ItemStack(Material.WRITABLE_BOOK);
final ItemMeta bqMeta = bookQuill.getItemMeta();
bqMeta.displayName(UtilitiesOG.trueogColorize("&r&2Add new command"));
bookQuill.setItemMeta(bqMeta);
menu.setItem(40, bookQuill);
}
ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
cmdBlockMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Console Commands");
final ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
final ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
cmdBlockMeta.displayName(UtilitiesOG.trueogColorize("&r&5Console Commands"));
cmdBlock.setItemMeta(cmdBlockMeta);
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
ItemMeta headMeta = head.getItemMeta();
headMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Player Commands");
final ItemStack head = new ItemStack(Material.PLAYER_HEAD);
final ItemMeta headMeta = head.getItemMeta();
headMeta.displayName(UtilitiesOG.trueogColorize("&r&d Player Commands"));
head.setItemMeta(headMeta);
List<String> lore = new ArrayList<>();
final List<String> lore = new ArrayList<>();
final NamespacedKey key = new NamespacedKey(SudoSigns.sudoSignsPlugin, "command-number");
ArrayList<SignCommand> orderedSignCommands = sign.getPlayerCommands();
orderedSignCommands.sort(Comparator.comparing(SignCommand::getDelay));
// Populates spaces with commands.
int i = 1;
for (Map.Entry<SignCommand, Boolean> entry : sign.getPlayerCommands().entrySet()) {
SignCommand sc = entry.getKey();
if (i > 26) break;
ItemStack book = new ItemStack(Material.BOOK);
ItemMeta bookMeta = book.getItemMeta();
if (entry.getValue()) {
lore.add(ChatColor.YELLOW + "Player Command with Permissions (player is granted OP for this command only).");
} else {
lore.add(ChatColor.YELLOW + "Player Command");
for (SignCommand sc : orderedSignCommands) {
if (i > 26) {
break;
}
bookMeta.setDisplayName("" + ChatColor.RESET + ChatColor.GOLD + "/" + sc.getCommand());
if (p.hasPermission(Permissions.DELETE_COMMAND)) {
final ItemStack book = new ItemStack(Material.BOOK);
final ItemMeta bookMeta = book.getItemMeta();
lore.add("&6Player Command");
bookMeta.displayName(UtilitiesOG.trueogColorize("&r&6/" + sc.getCommand()));
lore.add("&6Delay: &e" + (sc.getDelay() / 1000) + "s");
if (p.hasPermission(Permissions.COMMAND_OPTIONS)) {
lore.add("");
lore.add(ChatColor.RED + "Click to delete!");
lore.add("&2Click for options!");
}
bookMeta.setLore(lore);
bookMeta.getPersistentDataContainer().set(key, PersistentDataType.INTEGER, sc.getNumber());
bookMeta.lore(Util.convertToTextComponents(lore));
lore.clear();
book.setItemMeta(bookMeta);
if (i == 9) i++;
if (i == 9) {
i++;
}
menu.setItem(i, book);
i++;
}
orderedSignCommands = sign.getConsoleCommands();
orderedSignCommands.sort(Comparator.comparing(SignCommand::getDelay));
i = 19;
for (SignCommand sc : sign.getConsoleCommands()) {
if (i > 35) break;
ItemStack book = new ItemStack(Material.BOOK);
ItemMeta bookMeta = book.getItemMeta();
bookMeta.setDisplayName("" + ChatColor.RESET + ChatColor.GOLD + "/" + sc.getCommand());
if (p.hasPermission(Permissions.DELETE_COMMAND)) {
lore.add("");
lore.add(ChatColor.RED + "Click to delete!");
for (SignCommand sc : orderedSignCommands) {
if (i > 35) {
break;
}
bookMeta.setLore(lore);
final ItemStack book = new ItemStack(Material.BOOK);
final ItemMeta bookMeta = book.getItemMeta();
lore.add("&6Console Command");
bookMeta.displayName(UtilitiesOG.trueogColorize("&r&6/" + sc.getCommand()));
lore.add("&6Delay: &e" + (sc.getDelay() / 1000) + "s");
if (p.hasPermission(Permissions.COMMAND_OPTIONS)) {
lore.add("");
lore.add("&2Click for options!");
}
bookMeta.getPersistentDataContainer().set(key, PersistentDataType.INTEGER, sc.getNumber());
bookMeta.lore(Util.convertToTextComponents(lore));
lore.clear();
book.setItemMeta(bookMeta);
if (i == 27) i++;
if (i == 27) {
i++;
}
menu.setItem(i, book);
i++;
}
menu.setItem(0, head);
menu.setItem(9, head);
menu.setItem(18, cmdBlock);
menu.setItem(27, cmdBlock);
menu.setItem(36, arrow);
}
public void prepareCommand() {
Inventory choiceInv = Bukkit.createInventory(p, 45, "Player or Console command?");
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("Player or Console command?");
final Inventory choiceInv = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < choiceInv.getSize(); i++) {
choiceInv.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
}
ItemStack arrow = new ItemStack(Material.ARROW);
ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "BACK");
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
ItemMeta headMeta = head.getItemMeta();
List<String> lore = new ArrayList<>();
lore.add(ChatColor.RED + "The player must have permission to run the command!");
headMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Player Command");
headMeta.setLore(lore);
final ItemStack head = new ItemStack(Material.PLAYER_HEAD);
final ItemMeta headMeta = head.getItemMeta();
final List<String> lore = new ArrayList<>();
lore.add("&cThe player must have permission to run the command!");
headMeta.displayName(UtilitiesOG.trueogColorize("&r&dPlayer Command"));
headMeta.lore(Util.convertToTextComponents(lore));
head.setItemMeta(headMeta);
ItemStack chainCmdBlock = new ItemStack(Material.CHAIN_COMMAND_BLOCK);
ItemMeta chainCmdBlockItemMeta = chainCmdBlock.getItemMeta();
lore.clear();
lore.add(ChatColor.YELLOW + "The player is granted operator for this command only.");
lore.add("");
lore.add(ChatColor.RED + "THIS IS DISCOURAGED FOR SECURITY REASONS");
lore.add(ChatColor.RED + "ONLY USE IF CONSOLE COMMAND CANNOT BE USED.");
chainCmdBlockItemMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Player Command with Permissions");
chainCmdBlockItemMeta.setLore(lore);
chainCmdBlock.setItemMeta(chainCmdBlockItemMeta);
ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
cmdBlockMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Console Command");
final ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
final ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
cmdBlockMeta.displayName(UtilitiesOG.trueogColorize("&r&dConsole Command"));
cmdBlock.setItemMeta(cmdBlockMeta);
if (p.hasPermission(Permissions.CONSOLE_COMMAND)) {
choiceInv.setItem(20, head);
choiceInv.setItem(22, chainCmdBlock);
choiceInv.setItem(24, cmdBlock);
choiceInv.setItem(21, head);
choiceInv.setItem(23, cmdBlock);
} else {
choiceInv.setItem(22, head);
}
choiceInv.setItem(36, arrow);
editor.setCurrentPage(GUIPage.CHOOSE_COMMAND);
p.openInventory(choiceInv);
}
public void deleteCommand(String cmd) {
SignCommand found = null;
for (SignCommand c : sign.getConsoleCommands()) {
if (c.getCommand().equals(cmd)) {
found = c;
SudoSigns.config.deleteCommandFromConfig(sign, c, PlayerInput.CONSOLE_COMMAND);
}
}
if (found != null) {
sign.deleteConsoleCommand(found);
}
found = null;
for (Map.Entry<SignCommand, Boolean> entry : sign.getPlayerCommands().entrySet()) {
SignCommand command = entry.getKey();
if (command.getCommand().equals(cmd.replace("/", ""))) {
found = command;
if (entry.getValue()) {
SudoSigns.config.deleteCommandFromConfig(sign, command, PlayerInput.PLAYER_COMMAND_WITH_PERMISSIONS);
} else {
SudoSigns.config.deleteCommandFromConfig(sign, command, PlayerInput.PLAYER_COMMAND);
}
}
}
if (found != null) {
sign.deletePlayerCommand(found);
}
goToCommandsMenu();
}
public void chooseCommandType(PlayerInput type) {
p.closeInventory();
p.sendMessage(Util.prefix + ChatColor.GRAY + " Please enter the full command in chat with the beginning /. The phrase" + ChatColor.GOLD + " %PLAYER%" + ChatColor.GRAY +
" will be replaced with the player who clicked the sign. To cancel, type " + ChatColor.RED + "CANCEL" + ChatColor.GRAY + ".");
UtilitiesOG.trueogMessage(p,
"&6Please enter the full command in chat with the beginning &e/&6. The placeholder &e%PLAYER% &6will be replaced with the player who clicked the sign. To cancel, type &cCANCEL&6.");
su.addTextInput(type);
}
public void addCommand(String cmd, PlayerInput type) {
SignCommand command = new SignCommand(cmd, type);
final SignCommand command = new SignCommand(sign.getNextCommandNumber(), cmd, 0, type);
switch (type) {
case CONSOLE_COMMAND:
sign.addConsoleCommand(command);
break;
case PLAYER_COMMAND:
sign.addPlayerCommand(command, false);
break;
case PLAYER_COMMAND_WITH_PERMISSIONS:
sign.addPlayerCommand(command, true);
break;
case CONSOLE_COMMAND -> sign.addConsoleCommand(command);
case PLAYER_COMMAND -> sign.addPlayerCommand(command);
default -> {
}
}
SudoSigns.config.addCommandToConfig(sign, command, type);
Util.sudoSignsMessage(p, ChatColor.GRAY, "Command added successfully!", null);
goToCommandsMenu();
SudoSigns.config.addCommand(sign, command, type);
UtilitiesOG.trueogMessage(p, "&aCommand added successfully!");
editor.goToCommands();
}
}
}
@@ -1,10 +1,5 @@
package dev.mylesmor.sudosigns.menus;
public enum GUIPage {
MAIN,
COMMANDS,
PERMISSIONS,
CHOOSE_PERMISSION,
CHOOSE_COMMAND,
MESSAGES,
MAIN, COMMANDS, PERMISSIONS, CHOOSE_PERMISSION, CHOOSE_COMMAND, MESSAGES, COMMAND_OPTIONS, MESSAGE_OPTIONS
}
@@ -1,98 +1,265 @@
package dev.mylesmor.sudosigns.menus;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.kyori.adventure.text.TextComponent;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class MainMenu {
private final GUIPage PAGE = GUIPage.MAIN;
private Inventory menu;
private SudoSign sign;
private SignEditor editor;
private Player p;
private final SudoSign sign;
private final Player p;
private int lineNumber = 0;
private final DiamondBankAPIJava diamondBankAPI;
public MainMenu(Player p, SudoSign sign, SignEditor editor, DiamondBankAPIJava diamondBankAPI) {
public MainMenu(Player p, SudoSign sign, SignEditor editor) {
this.sign = sign;
this.editor = editor;
this.p = p;
this.diamondBankAPI = diamondBankAPI;
}
public void goToMainMenu() {
createMainMenu();
p.openInventory(menu);
editor.setCurrentPage(PAGE);
}
private void createMainMenu() {
ArrayList<ItemStack> items = new ArrayList<>();
menu = Bukkit.createInventory(p, 45, "Editing: " + sign.getName());
final ArrayList<ItemStack> items = new ArrayList<>();
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("&r&2Editing: &e" + sign.getName());
menu = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
final List<String> lore = new ArrayList<>();
lore.add(" ");
menu.getItem(i).lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
}
if (p.hasPermission(Permissions.RENAME)) {
ItemStack book = new ItemStack(Material.BOOK);
ItemMeta bookMeta = book.getItemMeta();
bookMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Rename Sign");
final ItemStack nametag = new ItemStack(Material.NAME_TAG);
final ItemMeta ntMeta = nametag.getItemMeta();
ntMeta.displayName(UtilitiesOG.trueogColorize("&r&5Rename Sign"));
final List<String> lore = new ArrayList<>();
lore.add("&eChange the text that refers");
lore.add("&eto this sign in the config");
lore.add("&efile and in commands.");
ntMeta.lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
nametag.setItemMeta(ntMeta);
items.add(nametag);
}
if (p.hasPermission(Permissions.EDIT_TEXT)) {
final ItemStack book = new ItemStack(Material.WRITABLE_BOOK);
final ItemMeta bookMeta = book.getItemMeta();
bookMeta.displayName(UtilitiesOG.trueogColorize("&r&5Edit Sign Text"));
final List<String> lore = new ArrayList<>();
lore.add("&eChange the text that displays");
lore.add("&eon the sign itself. Colored");
lore.add("&esigns require another plugin.");
bookMeta.lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
book.setItemMeta(bookMeta);
items.add(book);
}
if (p.hasPermission(Permissions.VIEW_PERMISSION)) {
ItemStack barrier = new ItemStack(Material.BARRIER);
ItemMeta barrierMeta = barrier.getItemMeta();
barrierMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Permissions");
List<String> lore = new ArrayList<>();
lore.add(ChatColor.YELLOW + "Players must have all permissions");
lore.add(ChatColor.YELLOW + "listed in this section to be able");
lore.add(ChatColor.YELLOW + "to use the sign.");
barrierMeta.setLore(lore);
final ItemStack barrier = new ItemStack(Material.BARRIER);
final ItemMeta barrierMeta = barrier.getItemMeta();
barrierMeta.displayName(UtilitiesOG.trueogColorize("&r&dPermissions"));
final List<String> lore = new ArrayList<>();
lore.add("&ePlayers must have all permissions");
lore.add("&elisted in this section to be able");
lore.add("&eto use the sign.");
barrierMeta.lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
barrier.setItemMeta(barrierMeta);
items.add(barrier);
}
if (p.hasPermission(Permissions.VIEW_COMMAND)) {
ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
List<String> lore = new ArrayList<>();
lore.add(ChatColor.YELLOW + "Commands listed here will be executed");
lore.add(ChatColor.YELLOW + "when a player uses the sign.");
cmdBlockMeta.setLore(lore);
cmdBlockMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Commands");
final ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
final ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
final List<String> lore = new ArrayList<>();
lore.add("&eCommands listed here will be executed");
lore.add("&ewhen a player uses the sign.");
cmdBlockMeta.lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
cmdBlockMeta.displayName(UtilitiesOG.trueogColorize("&r&5Commands"));
cmdBlock.setItemMeta(cmdBlockMeta);
items.add(cmdBlock);
}
if (p.hasPermission(Permissions.VIEW_MESSAGE)) {
ItemStack signBlock;
if (SudoSigns.version.contains("1.13")) {
signBlock = new ItemStack(Material.valueOf("SIGN"));
} else {
signBlock = new ItemStack(Material.BIRCH_SIGN);
}
ItemMeta signMeta = signBlock.getItemMeta();
signMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Messages");
List<String> lore = new ArrayList<>();
lore.add(ChatColor.YELLOW + "Messages listed here will be shown");
lore.add(ChatColor.YELLOW + "to the player when they use the sign.");
signMeta.setLore(lore);
final ItemStack signBlock = new ItemStack(Material.OAK_SIGN);
final ItemMeta signMeta = signBlock.getItemMeta();
signMeta.displayName(UtilitiesOG.trueogColorize("&r&5Messages"));
final List<String> lore = new ArrayList<>();
lore.add("&eMessages listed here will be shown");
lore.add("&eto the player when they use the sign.");
signMeta.lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
signBlock.setItemMeta(signMeta);
items.add(signBlock);
}
final boolean condition = diamondBankAPI != null && p.hasPermission(Permissions.VIEW_PRICE);
if (condition) {
final ItemStack goldNugget = new ItemStack(Material.GOLD_NUGGET);
final ItemMeta goldNuggetItemMeta = goldNugget.getItemMeta();
final List<String> lore = new ArrayList<>();
lore.add("&eThe cost to use this sign.");
lore.add("&e");
if (!SudoSigns.getPlugin().getConfig().getBoolean("config.currency-symbol-in-front")) {
if (Util.priceIsInteger()) {
if (sign.getPriceAsInteger() == 1) {
lore.add("&e" + sign.getPriceAsInteger()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular"));
} else {
lore.add("&e" + sign.getPriceAsInteger()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural"));
}
} else {
if (sign.getPriceAsDouble() == 1.0) {
lore.add("&e" + sign.getPriceAsDouble()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular"));
} else {
lore.add("&e" + sign.getPriceAsDouble()
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural"));
}
}
} else {
if (Util.priceIsInteger()) {
if (sign.getPriceAsInteger() == 1) {
lore.add(SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ sign.getPriceAsInteger());
} else {
lore.add(SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ sign.getPriceAsInteger());
}
} else {
if (sign.getPriceAsDouble() == 1.0) {
lore.add(SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ sign.getPriceAsDouble());
} else {
lore.add(SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ sign.getPriceAsDouble());
}
}
}
if (p.hasPermission(Permissions.SET_PRICE)) {
lore.add("&e");
lore.add("&aClick to edit!");
}
goldNuggetItemMeta.lore(lore.stream().map(UtilitiesOG::trueogColorize).toList());
goldNuggetItemMeta.displayName(UtilitiesOG.trueogColorize("&r&dPrice"));
goldNugget.setItemMeta(goldNuggetItemMeta);
items.add(goldNugget);
}
switch (items.size()) {
case 6:
menu.setItem(11, items.get(0));
menu.setItem(13, items.get(1));
menu.setItem(15, items.get(2));
menu.setItem(29, items.get(3));
menu.setItem(31, items.get(4));
menu.setItem(33, items.get(5));
case 5:
menu.setItem(11, items.get(0));
menu.setItem(13, items.get(1));
menu.setItem(15, items.get(2));
menu.setItem(29, items.get(3));
menu.setItem(31, items.get(4));
case 4:
menu.setItem(11, items.get(0));
menu.setItem(13, items.get(1));
@@ -111,6 +278,118 @@ public class MainMenu {
case 1:
menu.setItem(22, items.get(0));
break;
}
}
}
public void prepareSetPrice() {
p.closeInventory();
UtilitiesOG.trueogMessage(p,
"&6Please enter the price to use the sign! Type &cCANCEL &6to cancel the operation.");
SudoSigns.users.get(p.getUniqueId()).addTextInput(PlayerInput.SET_PRICE);
}
public void setPriceAsDouble(double price) {
sign.setPriceAsDouble(price);
SudoSigns.config.setPrice(sign.getName(), price);
if (!SudoSigns.getPlugin().getConfig().getBoolean("config.currency-symbol-in-front")) {
if (sign.getPriceAsDouble() == 1.0) {
UtilitiesOG.trueogMessage(p, "&6The price of &e" + sign.getName() + " &6has been set to: &e" + price
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&6.");
} else {
UtilitiesOG.trueogMessage(p, "&6The price of &e" + sign.getName() + " &6has been set to: &e" + price
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&6.");
}
} else {
if (sign.getPriceAsInteger() == 1) {
UtilitiesOG.trueogMessage(p,
"&6The price of &e" + sign.getName() + " &6has been set to: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ price + "&6.");
} else {
UtilitiesOG.trueogMessage(p,
"&6The price of &e" + sign.getName() + " &6has been set to: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ price + "&6.");
}
}
}
public void setPriceAsInteger(int price) {
sign.setPriceAsInteger(price);
SudoSigns.config.setPrice(sign.getName(), price);
if (!SudoSigns.getPlugin().getConfig().getBoolean("config.currency-symbol-in-front")) {
if (sign.getPriceAsInteger() == 1) {
UtilitiesOG.trueogMessage(p, "&6The price of &e" + sign.getName() + " &6has been set to: &e" + price
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&6.");
} else {
UtilitiesOG.trueogMessage(p, "&6The price of &e" + sign.getName() + " &6has been set to: &e" + price
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&6.");
}
} else {
if (sign.getPriceAsInteger() == 1) {
UtilitiesOG.trueogMessage(p,
"&6The price of &e" + sign.getName() + " &6has been set to: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-singular") + "&e"
+ price + "&6.");
} else {
UtilitiesOG.trueogMessage(p,
"&6The price of &e" + sign.getName() + " &6has been set to: "
+ SudoSigns.getPlugin().getConfig().getString("config.currency-symbol-plural") + "&e"
+ price + "&6.");
}
}
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
UtilitiesOG.trueogMessage(p,
"&6Please enter the new text (maximum 15 characters), using the &e& &6symbol for color codes. Type &cCANCEL &6to cancel the operation.");
SudoSigns.users.get(p.getUniqueId()).addTextInput(PlayerInput.EDIT_TEXT);
}
public void setText(TextComponent message) {
UtilitiesOG.trueogMessage(p, "&aLine &e" + lineNumber + " &ahas been set to: " + message.content());
sign.editLine(lineNumber - 1, message);
SudoSigns.config.editSignText(sign.getName(), lineNumber, message);
}
}
@@ -0,0 +1,158 @@
package dev.mylesmor.sudosigns.menus;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignMessage;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import net.kyori.adventure.text.TextComponent;
import net.trueog.utilitiesog.UtilitiesOG;
public class MessageOptionsMenu {
private Inventory menu;
private final SudoUser su;
private final SudoSign sign;
private final SignMessage sm;
private final Player p;
private final SignEditor editor;
MessageOptionsMenu(SudoUser su, Player p, SudoSign sign, ItemStack item, SignEditor editor) {
this.su = su;
this.sign = sign;
this.p = p;
this.editor = editor;
this.sm = findSignMessage(item);
if (this.sm == null) {
editor.goToMessages();
return;
}
}
public void goToMessageOptionsMenu() {
createMessageOptionsMenu();
p.openInventory(menu);
}
private SignMessage findSignMessage(ItemStack item) {
final NamespacedKey key = new NamespacedKey(SudoSigns.sudoSignsPlugin, "message-number");
final ItemMeta itemMeta = item.getItemMeta();
final PersistentDataContainer container = itemMeta.getPersistentDataContainer();
if (container.has(key, PersistentDataType.INTEGER)) {
final int foundValue = container.get(key, PersistentDataType.INTEGER);
return sign.getSignMessageByNumber(foundValue);
}
return null;
}
private void createMessageOptionsMenu() {
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("&6Message options");
menu = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
}
final List<String> lore = new ArrayList<>();
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
final ItemStack clock = new ItemStack(Material.CLOCK);
final ItemMeta clockMeta = clock.getItemMeta();
lore.add("&eChange the delay after which the message is sent");
clockMeta.displayName(UtilitiesOG.trueogColorize("&r&dChange Delay"));
clockMeta.lore(Util.convertToTextComponents(lore));
clock.setItemMeta(clockMeta);
final ItemStack barrier = new ItemStack(Material.BARRIER);
final ItemMeta barrierMeta = barrier.getItemMeta();
barrierMeta.displayName(UtilitiesOG.trueogColorize("&r&dDelete Message"));
barrier.setItemMeta(barrierMeta);
if (p.hasPermission(Permissions.MESSAGE_OPTIONS) && p.hasPermission(Permissions.DELETE_MESSAGE)) {
menu.setItem(20, clock);
menu.setItem(24, barrier);
} else {
menu.setItem(22, clock);
}
menu.setItem(36, arrow);
}
public void addDelay() {
p.closeInventory();
UtilitiesOG.trueogMessage(p, "&6Please enter the delay in seconds. To cancel, type &cCANCEL &6.");
su.addTextInput(PlayerInput.MESSAGE_DELAY);
}
public void setDelay(double delay) {
final double oldDelay = sm.getDelay();
sm.setDelay(delay * 1000);
SudoSigns.config.deleteMessage(sign, sm, oldDelay);
SudoSigns.config.addMessage(sign, sm);
}
public void deleteMessage() {
sign.removeMessage(sm);
SudoSigns.config.deleteMessage(sign, sm, sm.getDelay());
editor.goToMessages();
}
}
@@ -1,92 +1,146 @@
package dev.mylesmor.sudosigns.menus;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SignMessage;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import net.kyori.adventure.text.TextComponent;
import net.trueog.utilitiesog.UtilitiesOG;
import org.apache.commons.lang3.StringUtils;
public class MessagesMenu {
private final GUIPage PAGE = GUIPage.MESSAGES;
private Inventory menu;
private Player p;
private SudoSign sign;
private SignEditor editor;
private SudoUser su;
private final Player p;
private final SudoSign sign;
private final SudoUser su;
public MessagesMenu(SudoUser su, Player p, SudoSign sign, SignEditor editor) {
this.su = su;
this.sign = sign;
this.editor = editor;
this.p = p;
}
public void goToMessagesMenu() {
createMessagesMenu();
p.openInventory(menu);
editor.setCurrentPage(PAGE);
}
private void createMessagesMenu() {
menu = Bukkit.createInventory(p, 45, "Messages: " + sign.getName());
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("&6Messages: " + sign.getName());
menu = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
}
ItemStack arrow = new ItemStack(Material.ARROW);
ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "BACK");
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
if (p.hasPermission(Permissions.ADD_MESSAGE)) {
ItemStack bookQuill = new ItemStack(Material.WRITABLE_BOOK);
ItemMeta bqMeta = bookQuill.getItemMeta();
bqMeta.setDisplayName("" + ChatColor.RESET + ChatColor.GREEN + "Add new message");
final ItemStack bookQuill = new ItemStack(Material.WRITABLE_BOOK);
final ItemMeta bqMeta = bookQuill.getItemMeta();
bqMeta.displayName(UtilitiesOG.trueogColorize("&r&2Add new message"));
bookQuill.setItemMeta(bqMeta);
menu.setItem(40, bookQuill);
}
ItemStack signItem = null;
if (SudoSigns.version.contains("1.13")) {
if (StringUtils.contains(SudoSigns.version, "1.13")) {
signItem = new ItemStack(Material.valueOf("SIGN"));
} else {
signItem = new ItemStack(Material.BIRCH_SIGN);
} ItemMeta signMeta = signItem.getItemMeta();
signMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Messages");
}
final ItemMeta signMeta = signItem.getItemMeta();
signMeta.displayName(UtilitiesOG.trueogColorize("&r&dMessages"));
signItem.setItemMeta(signMeta);
List<String> lore = new ArrayList<>();
final List<String> lore = new ArrayList<>();
final NamespacedKey key = new NamespacedKey(SudoSigns.sudoSignsPlugin, "message-number");
final ArrayList<SignMessage> orderedSignMessages = sign.getMessages();
orderedSignMessages.sort(Comparator.comparing(SignMessage::getDelay));
int i = 1;
for (String message : sign.getMessages()) {
if (i > 35) break;
ItemStack book = new ItemStack(Material.BOOK);
ItemMeta bookMeta = book.getItemMeta();
if (p.hasPermission(Permissions.DELETE_MESSAGE)) {
bookMeta.setDisplayName(ChatColor.RED + "Click to delete!");
} else {
bookMeta.setDisplayName(ChatColor.LIGHT_PURPLE + "Message:");
for (SignMessage sm : orderedSignMessages) {
if (i > 35) {
break;
}
final ItemStack book = new ItemStack(Material.BOOK);
final ItemMeta bookMeta = book.getItemMeta();
lore.clear();
lore.add("" + ChatColor.RESET + ChatColor.WHITE + ChatColor.translateAlternateColorCodes('&', message));
bookMeta.setLore(lore);
bookMeta.displayName(UtilitiesOG.trueogColorize("&dMessage:"));
lore.add("&r&f" + sm.getMessage());
lore.add("");
lore.add("");
lore.add("&6Delay: &e" + (sm.getDelay() / 1000) + "s");
if (p.hasPermission(Permissions.MESSAGE_OPTIONS)) {
lore.add("");
lore.add("&2Click for options!");
}
bookMeta.getPersistentDataContainer().set(key, PersistentDataType.INTEGER, sm.getNumber());
bookMeta.lore(Util.convertToTextComponents(lore));
book.setItemMeta(bookMeta);
if (i == 9 || i == 18 || i == 27) i++;
if (i == 9 || i == 18 || i == 27) {
i++;
}
menu.setItem(i, book);
i++;
}
menu.setItem(0, signItem);
@@ -94,30 +148,26 @@ public class MessagesMenu {
menu.setItem(18, signItem);
menu.setItem(27, signItem);
menu.setItem(36, arrow);
}
public void addMessage(String message) {
SudoSigns.config.addMessageToConfig(sign, message);
sign.addMessage(message);
final SignMessage signMessage = new SignMessage(sign.getNextMessageNumber(), message, 0, PlayerInput.MESSAGE);
SudoSigns.config.addMessage(sign, signMessage);
sign.addMessage(signMessage);
}
public void prepareMessage() {
p.closeInventory();
p.sendMessage(Util.prefix + ChatColor.GRAY + " Please enter in chat the message which will be shown. Use the " + ChatColor.GOLD + "& " + ChatColor.GRAY + "symbol for chat colour codes and the phrase" + ChatColor.GOLD + " %PLAYER% " + ChatColor.GRAY + "for the player who clicked the sign. To cancel type " + ChatColor.RED + "CANCEL" + ChatColor.GRAY + ".");
UtilitiesOG.trueogMessage(p,
"&6Please enter in chat the message which will be shown when the sign is clicked. Use the & symbol for chat color codes and the placeholder &e%PLAYER% &6for the player who clicked the sign. To cancel the operation, type &cCANCEL&6.");
su.addTextInput(PlayerInput.MESSAGE);
}
public void deleteMessage(String message) {
String found = null;
for (String m : sign.getMessages()) {
if (message.equalsIgnoreCase(ChatColor.translateAlternateColorCodes('&', m))) {
found = m;
}
}
sign.removeMessage(found);
SudoSigns.config.deleteMessageFromConfig(sign, found);
goToMessagesMenu();
}
}
}
@@ -1,87 +1,124 @@
package dev.mylesmor.sudosigns.menus;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import net.kyori.adventure.text.TextComponent;
import net.trueog.utilitiesog.UtilitiesOG;
public class PermissionsMenu {
private final GUIPage PAGE = GUIPage.PERMISSIONS;
private Inventory menu;
private Player p;
private SudoSign sign;
private SignEditor editor;
private SudoUser su;
private final Player p;
private final SudoSign sign;
private final SignEditor editor;
private final SudoUser su;
public PermissionsMenu(SudoUser su, Player p, SudoSign sign, SignEditor editor) {
this.su = su;
this.sign = sign;
this.editor = editor;
this.p = p;
}
public void goToPermissionsMenu() {
createPermissionsMenu();
p.openInventory(menu);
editor.setCurrentPage(PAGE);
}
private void createPermissionsMenu() {
menu = Bukkit.createInventory(p, 45, "Permissions: " + sign.getName());
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("&6Default or Custom?");
menu = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
}
ItemStack arrow = new ItemStack(Material.ARROW);
ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "BACK");
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
ItemStack barrier = new ItemStack(Material.BARRIER);
ItemMeta barrierMeta = barrier.getItemMeta();
barrierMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Permissions");
final ItemStack barrier = new ItemStack(Material.BARRIER);
final ItemMeta barrierMeta = barrier.getItemMeta();
barrierMeta.displayName(UtilitiesOG.trueogColorize("&r&5Permissions"));
barrier.setItemMeta(barrierMeta);
if (p.hasPermission(Permissions.ADD_PERMISSION)) {
ItemStack bookQuill = new ItemStack(Material.WRITABLE_BOOK);
ItemMeta bqMeta = bookQuill.getItemMeta();
bqMeta.setDisplayName("" + ChatColor.RESET + ChatColor.GREEN + "Add new permission");
final ItemStack bookQuill = new ItemStack(Material.WRITABLE_BOOK);
final ItemMeta bqMeta = bookQuill.getItemMeta();
bqMeta.displayName(UtilitiesOG.trueogColorize("&aAdd new permission"));
bookQuill.setItemMeta(bqMeta);
menu.setItem(40, bookQuill);
}
final List<String> lore = new ArrayList<>();
List<String> lore = new ArrayList<>();
lore.add(ChatColor.RED + "Click to delete!");
lore.add("&cClick to delete!");
int i = 1;
for (String perm : sign.getPermissions()) {
if (i > 35) break;
ItemStack book = new ItemStack(Material.BOOK);
ItemMeta bookMeta = book.getItemMeta();
bookMeta.setDisplayName("" + ChatColor.RESET + ChatColor.GOLD + perm);
if (p.hasPermission(Permissions.DELETE_PERMISSION)) {
lore.add("");
bookMeta.setLore(lore);
if (i > 35) {
break;
}
final ItemStack book = new ItemStack(Material.BOOK);
final ItemMeta bookMeta = book.getItemMeta();
bookMeta.displayName(UtilitiesOG.trueogColorize("&r&6" + perm));
if (p.hasPermission(Permissions.DELETE_PERMISSION)) {
lore.add("");
bookMeta.lore(Util.convertToTextComponents(lore));
}
book.setItemMeta(bookMeta);
if (i == 9 || i == 18 || i == 27) i++;
if (i == 9 || i == 18 || i == 27) {
i++;
}
menu.setItem(i, book);
i++;
}
menu.setItem(0, barrier);
@@ -89,30 +126,46 @@ public class PermissionsMenu {
menu.setItem(18, barrier);
menu.setItem(27, barrier);
menu.setItem(36, arrow);
}
public void preparePermission() {
Inventory choiceInv = Bukkit.createInventory(p, 45, "Default or Custom?");
for (int i = 0; i < choiceInv.getSize(); i++) {
final Inventory playersInventory = p.getInventory();
final InventoryHolder inventoryContainer = playersInventory.getHolder(false);
final TextComponent nameHandler = UtilitiesOG.trueogColorize("&6Default or Custom?");
final Inventory choiceInv = Bukkit.createInventory(inventoryContainer, 45, nameHandler);
final int inventorySize = choiceInv.getSize();
final ArrayList<String> lore = new ArrayList<>(inventorySize);
for (int i = 0; i < inventorySize; i++) {
lore.add("");
choiceInv.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
choiceInv.getItem(i).lore(Util.convertToTextComponents(lore));
}
ItemStack arrow = new ItemStack(Material.ARROW);
ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "BACK");
final ItemStack arrow = new ItemStack(Material.ARROW);
final ItemMeta arrowMeta = arrow.getItemMeta();
arrowMeta.displayName(UtilitiesOG.trueogColorize("&r&dBACK"));
arrow.setItemMeta(arrowMeta);
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
ItemMeta headMeta = head.getItemMeta();
List<String> lore = new ArrayList<>();
lore.add(ChatColor.GOLD + "sudosigns.sign." + sign.getName());
headMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Default Permission");
headMeta.setLore(lore);
final ItemStack head = new ItemStack(Material.PLAYER_HEAD);
final ItemMeta headMeta = head.getItemMeta();
final List<String> loreString = new ArrayList<>();
loreString.add("&6sudosigns.sign." + sign.getName());
headMeta.displayName(UtilitiesOG.trueogColorize("&r&dDefault Permission"));
headMeta.lore(Util.convertToTextComponents(loreString));
head.setItemMeta(headMeta);
ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
cmdBlockMeta.setDisplayName("" + ChatColor.RESET + ChatColor.LIGHT_PURPLE + "Custom Permission");
final ItemStack cmdBlock = new ItemStack(Material.COMMAND_BLOCK);
final ItemMeta cmdBlockMeta = cmdBlock.getItemMeta();
cmdBlockMeta.displayName(UtilitiesOG.trueogColorize("&r&5Custom Permission"));
cmdBlock.setItemMeta(cmdBlockMeta);
choiceInv.setItem(21, head);
@@ -120,30 +173,49 @@ public class PermissionsMenu {
choiceInv.setItem(36, arrow);
editor.setCurrentPage(GUIPage.CHOOSE_PERMISSION);
p.openInventory(choiceInv);
}
public void addPermission(boolean provided, String perm) {
if (provided) {
if (perm == null) {
sign.addPermission("sudosigns.sign." + sign.getName());
SudoSigns.config.addPermissionToConfig(sign, "sudosigns.sign." + sign.getName());
SudoSigns.config.addPermission(sign, "sudosigns.sign." + sign.getName());
goToPermissionsMenu();
} else {
SudoSigns.config.addPermissionToConfig(sign, perm);
SudoSigns.config.addPermission(sign, perm);
sign.addPermission(perm);
}
} else {
p.closeInventory();
p.sendMessage(Util.prefix + ChatColor.GRAY + " Please enter in chat the permission which the player must have to run this sign or type " + ChatColor.RED + "CANCEL" + ChatColor.GRAY + ".");
UtilitiesOG.trueogMessage(p,
"&6Please enter in chat the permission which the player must have to run this sign, or type &cCANCEL &6to cancel the operation.");
su.addTextInput(PlayerInput.PERMISSION);
}
}
public void deletePermission(String perm) {
sign.removePermission(perm);
SudoSigns.config.deletePermissionFromConfig(sign, perm);
SudoSigns.config.deletePermission(sign, perm);
goToPermissionsMenu();
}
}
}
@@ -1,123 +1,224 @@
package dev.mylesmor.sudosigns.menus;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.PlayerInput;
import dev.mylesmor.sudosigns.data.SignCommand;
import dev.mylesmor.sudosigns.data.SudoSign;
import dev.mylesmor.sudosigns.data.SudoUser;
import dev.mylesmor.sudosigns.util.Permissions;
import dev.mylesmor.sudosigns.util.Util;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
import net.trueog.utilitiesog.UtilitiesOG;
public class SignEditor {
private Player p;
private SudoUser su;
private SudoSign sign;
private final Player p;
private final SudoUser su;
private final SudoSign sign;
private MainMenu mainMenu;
private PermissionsMenu permMenu;
private CommandsMenu commandsMenu;
private CommandOptionsMenu commandOptionsMenu;
private MessageOptionsMenu messageOptionsMenu;
private MessagesMenu messagesMenu;
private GUIPage currentPage;
private final DiamondBankAPIJava diamondBankAPI;
public SignEditor(Player p, SudoSign s, SudoUser su, DiamondBankAPIJava diamondBankAPI) {
public SignEditor(Player p, SudoSign s, SudoUser su) {
this.su = su;
this.p = p;
this.sign = s;
this.diamondBankAPI = diamondBankAPI;
goToMain();
}
public GUIPage getCurrentPage() {
return currentPage;
}
public void setCurrentPage(GUIPage page) {
currentPage = page;
}
public void goToMain() {
if (mainMenu == null) mainMenu = new MainMenu(p, sign, this);
if (mainMenu == null) {
mainMenu = new MainMenu(p, sign, this, diamondBankAPI);
}
setCurrentPage(GUIPage.MAIN);
mainMenu.goToMainMenu();
}
public void goToPermissions() {
if (permMenu == null) permMenu = new PermissionsMenu(su, p, sign, this);
if (permMenu == null) {
permMenu = new PermissionsMenu(su, p, sign, this);
}
setCurrentPage(GUIPage.PERMISSIONS);
permMenu.goToPermissionsMenu();
}
public void goToCommands() {
if (commandsMenu == null) commandsMenu = new CommandsMenu(su, p, sign, this);
if (commandsMenu == null) {
commandsMenu = new CommandsMenu(su, p, sign, this);
}
setCurrentPage(GUIPage.COMMANDS);
commandsMenu.goToCommandsMenu();
}
public void goToMessages() {
if (messagesMenu == null) messagesMenu = new MessagesMenu(su, p, sign, this);
if (messagesMenu == null) {
messagesMenu = new MessagesMenu(su, p, sign, this);
}
setCurrentPage(GUIPage.MESSAGES);
messagesMenu.goToMessagesMenu();
}
public void goToCommandOptionsMenu(ItemStack item) {
commandOptionsMenu = new CommandOptionsMenu(su, p, sign, item, this);
setCurrentPage(GUIPage.COMMAND_OPTIONS);
commandOptionsMenu.goToCommandOptionsMenu();
}
public void goToMessageOptionsMenu(ItemStack item) {
messageOptionsMenu = new MessageOptionsMenu(su, p, sign, item, this);
setCurrentPage(GUIPage.MESSAGE_OPTIONS);
messageOptionsMenu.goToMessageOptionsMenu();
}
public MainMenu getMainMenu() {
return mainMenu;
}
public PermissionsMenu getPermMenu() {
return permMenu;
}
public CommandsMenu getCommandsMenu() {
return commandsMenu;
}
public CommandOptionsMenu getCommandOptionsMenu() {
return commandOptionsMenu;
}
public MessagesMenu getMessagesMenu() {
return messagesMenu;
}
public MessageOptionsMenu getMessageOptionsMenu() {
return messageOptionsMenu;
}
public void endEditor() {
Util.sudoSignsMessage(p, ChatColor.GRAY, "Changes saved to sign %NAME%.", sign.getName());
UtilitiesOG.trueogMessage(p, "&aChanges saved to sign &e" + sign.getName() + " &a.");
}
public void editSignNumber() {
UtilitiesOG.trueogMessage(p, "&6Please enter the line you would like to edit (1-4) or type &cCANCEL&6!");
su.addTextInput(PlayerInput.EDIT_TEXT_NUMBER);
p.closeInventory();
public void editSignText() {
//TODO: Add editing of sign text.
}
public void prepareRename() {
p.sendMessage(Util.prefix + ChatColor.GRAY + " Please enter the new name for the sign in chat or type " + ChatColor.RED + "CANCEL" + ChatColor.GRAY + ".");
UtilitiesOG.trueogMessage(p, "&6Please enter the new name for the sign in chat or type &cCANCEL&6!");
su.addTextInput(PlayerInput.RENAME);
p.closeInventory();
}
public void renameSign(String s) {
if (SudoSigns.signs.containsKey(s)) {
Util.sudoSignsMessage(p, ChatColor.RED,"A sign with name %NAME% already exists! Cancelling...", s);
UtilitiesOG.trueogMessage(p, "&cERROR: A sign with the name &e" + s + " &calready exists! &6Cancelling...");
} else {
sign.setName(s);
Map.Entry<String, SudoSign> found = null;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
for (Iterator<Entry<String, SudoSign>> iterator = SudoSigns.signs.entrySet().iterator(); iterator
.hasNext();)
{
final Map.Entry<String, SudoSign> entry = iterator.next();
if (entry.getValue().equals(sign)) {
found = entry;
}
}
if (found != null) {
SudoSigns.signs.remove(found.getKey());
SudoSigns.signs.put(s, sign);
Util.sudoSignsMessage(p, ChatColor.GRAY, "Sign successfully renamed to %NAME%.", s);
SudoSigns.config.saveToFile(found.getValue(), true, p);
UtilitiesOG.trueogMessage(p, "&aSign successfully renamed to &e" + s + "&a.");
SudoSigns.config.saveSign(found.getValue(), true, p);
SudoSigns.config.deleteSign(found.getKey());
}
}
}
}
}
@@ -2,10 +2,14 @@ package dev.mylesmor.sudosigns.util;
/**
* Permissions class for SudoSigns.
*
* @author MylesMor
* @author https://mylesmor.dev
* @Maintainer NotAlexNoyle
* @Maintainer https://true-og.net
*/
public final class Permissions {
public static final String CREATE = "sudosigns.create";
public static final String EDIT = "sudosigns.edit";
public static final String DELETE = "sudosigns.delete";
@@ -25,11 +29,16 @@ public final class Permissions {
public static final String ADD_COMMAND = "sudosigns.command.add";
public static final String DELETE_COMMAND = "sudosigns.command.delete";
public static final String CONSOLE_COMMAND = "sudosigns.command.console";
public static final String COMMAND_OPTIONS = "sudosigns.command.options";
public static final String VIEW_PERMISSION = "sudosigns.permission.view";
public static final String ADD_PERMISSION = "sudosigns.permission.add";
public static final String DELETE_PERMISSION = "sudosigns.permission.delete";
public static final String VIEW_MESSAGE = "sudosigns.message.view";
public static final String ADD_MESSAGE = "sudosigns.message.add";
public static final String DELETE_MESSAGE = "sudosigns.message.delete";
public static final String MESSAGE_OPTIONS = "sudosigns.message.options";
public static final String EDIT_TEXT = "sudosigns.text.edit";
public static final String VIEW_PRICE = "sudosigns.price.view";
public static final String SET_PRICE = "sudosigns.price.set";
}
}
@@ -1,68 +1,237 @@
package dev.mylesmor.sudosigns.util;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import org.bukkit.ChatColor;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import dev.mylesmor.sudosigns.SudoSigns;
import dev.mylesmor.sudosigns.data.SudoSign;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.trueog.utilitiesog.UtilitiesOG;
public class Util {
public static final String prefix = ChatColor.YELLOW + "[SUDOSIGNS]";
// Create a colored chat prefix.
public static String chatPrefix = SudoSigns.getPlugin().getConfig().getString("config.prefix");
public static ArrayList<TextComponent> convertToTextComponents(List<String> stringList) {
final ArrayList<TextComponent> textComponents = new ArrayList<>(18);
stringList.stream().map(UtilitiesOG::trueogColorize)
.forEach(textComponent -> textComponents.add(textComponent));
return textComponents;
}
// Send the sign selection menu according to permissions.
public static void sendSelectMenus(Player p, String name) {
selectMenuParser(p, chatPrefix, "&e-----", name, "", "&2True&4OG&a's Fork of &BSudoSigns&a.");
public static String getSelectString(Player p, String name) {
String message = "[\"\",{\"text\":\"[SUDOSIGNS] \",\"color\":\"yellow\"},{\"text\":\"Sign: \",\"color\":\"gray\"},{\"text\":\"" + name + " \",\"bold\":true,\"color\":\"gold\"}]";
if (p.hasPermission(Permissions.VIEW)) {
message = message.substring(0, message.length() - 1);
message += ",{\"text\":\"[V] \",\"bold\":true,\"color\":\"blue\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss view " + name + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"View " + name + "'s details\",\"color\":\"blue\"}]}}]";
}
if (p.hasPermission(Permissions.RUN)) {
message = message.substring(0, message.length() - 1);
message += ",{\"text\":\"[R] \",\"bold\":true,\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss run " + name + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Run " + name + "'s commands\",\"color\":\"green\"}]}}]";
}
if (p.hasPermission(Permissions.TP)) {
message = message.substring(0, message.length() - 1);
message += ",{\"text\":\"[TP] \",\"bold\":true,\"color\":\"aqua\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss tp " + name + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Teleport to " + name + "\",\"color\":\"aqua\"}]}}]";
selectMenuParser(p, "&9&l[V]", "&9View Details", name, ("/ss view " + name),
("&9View &6" + name + "\'s &9details."));
}
if (p.hasPermission(Permissions.RUN)) {
selectMenuParser(p, "&2&l[R]", "&2Run Commands", name, ("/ss run " + name),
("&2Run &6" + name + "\'s &2commands."));
}
if (p.hasPermission(Permissions.TP)) {
selectMenuParser(p, "&3&l[TP]", "&3Teleport To", name, ("/ss tp " + name),
("&3Teleport to &6" + name + "&3."));
}
if (p.hasPermission(Permissions.EDIT)) {
message = message.substring(0, message.length() - 1);
message += ",{\"text\":\"[EDIT] \",\"bold\":true,\"color\":\"light_purple\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss edit " + name + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Edit "+ name +"\",\"color\":\"light_purple\"}]}}]";
selectMenuParser(p, "&d&l[EDIT]", "&dEdit Details", name, ("/ss edit " + name),
("&dEdit &6" + name + "\'s &dcolor."));
}
if (p.hasPermission(Permissions.DELETE)) {
message = message.substring(0, message.length() - 1);
message += ",{\"text\":\"[DEL]\",\"bold\":true,\"color\":\"red\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/ss confirmdelete " + name + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":[\"\",{\"text\":\"Delete " + name + "\",\"color\":\"red\"}]}}]";
selectMenuParser(p, "&c&l[DEL]", "&cDelete SudoSign", name, ("/ss confirmdelete " + name),
("&cDelete &6" + name + "&c."));
}
return message;
}
public static void sudoSignsMessage(Player p, ChatColor color, String message, String name) {
if (message.contains("%NAME%")) {
message = message.replace("%NAME%", ChatColor.GOLD + name + color);
// Sends customizable clickable message dialogues to the player.
public static void selectMenuParser(Player p, String prefix, String prompt, String name, String command,
String hoverMessage)
{
// The clickable part of the confirmation message.
TextComponent button = UtilitiesOG.trueogColorize(prefix);
// Add a hover dialogue to the clickable confirmation text.
button.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, UtilitiesOG.trueogColorize(hoverMessage)));
// Make sure that a command is intended to be run.
if (!"".equals(command)) {
// Create a click event on the delete confirmation chat text.
button = button.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, (command)));
}
p.sendMessage(prefix + color + " " + message);
// Send the prompt and clickable confirmation button to the player.
sudoSignsPrompt(p, (prompt + " "), button);
}
// Sends a permissions error message to the player.
public static void sudoSignsPermissionsError(Player p) {
UtilitiesOG.trueogMessage(p, "&c&lERROR: &cYou do not have permission to do that!");
}
// Sends a formatted message without a prefix to the player.
public static void sudoSignsMessageNoPrefix(Player p, String message) {
UtilitiesOG.trueogMessage(p, message);
}
// Sends a formatted prompt and clickable chat button to the player.
public static void sudoSignsPrompt(Player player, String prompt, TextComponent button) {
player.sendMessage(UtilitiesOG.trueogColorize(prompt).append(button));
}
public static boolean checkName(String name) {
String regex = "^[A-z0-9]+$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(name);
final String regex = "^[A-z0-9]+$";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(name);
return matcher.matches();
}
public static String findSign(Sign s) {
String found = null;
for (Map.Entry<String, SudoSign> entry : SudoSigns.signs.entrySet()) {
Sign sign = entry.getValue().getSign();
if (sign != null && sign.equals(s)) {
if (sameBlockLocation(entry.getValue(), s.getLocation())) {
found = entry.getKey();
}
}
return found;
}
public static boolean sameBlockLocation(Location first, Location second) {
if (first == null || second == null || first.getWorld() == null || second.getWorld() == null) {
return false;
}
return first.getWorld().getName().equals(second.getWorld().getName()) && first.getBlockX() == second.getBlockX()
&& first.getBlockY() == second.getBlockY() && first.getBlockZ() == second.getBlockZ();
}
public static boolean sameBlockLocation(SudoSign sign, Location location) {
if (sign == null || sign.getWorldName() == null || location == null || location.getWorld() == null) {
return false;
}
return sign.getWorldName().equals(location.getWorld().getName()) && sign.getBlockX() == location.getBlockX()
&& sign.getBlockY() == location.getBlockY() && sign.getBlockZ() == location.getBlockZ();
}
public static boolean isSignState(BlockState blockState) {
return blockState instanceof Sign;
}
private static boolean isSignMaterial(Material material) {
return material != null && material.name().endsWith("SIGN");
}
private static void ensureChunkLoaded(Block block) {
final Chunk chunk = block.getChunk();
if (!chunk.isLoaded()) {
chunk.load();
}
}
public static boolean isSignBlock(Block block) {
ensureChunkLoaded(block);
if (isSignMaterial(block.getType())) {
return true;
}
return isSignState(block.getState());
}
public static Sign getSign(Block block) {
ensureChunkLoaded(block);
final BlockState blockState = block.getState();
if (isSignState(blockState)) {
return (Sign) blockState;
}
return null;
}
public static boolean priceIsInteger() {
return SudoSigns.getPlugin().getConfig().getBoolean("config.use-decimals-in-prices");
}
}
+7
View File
@@ -0,0 +1,7 @@
config:
prefix: "&7[&3SudoSigns&4-OG&7] "
console-prefix: "[SudoSigns-OG] "
currency-symbol-singular: " &BDiamond"
currency-symbol-plural: " &BDiamonds"
currency-symbol-in-front: false
use-decimals-in-prices: false
+7 -5
View File
@@ -1,9 +1,11 @@
name: SudoSigns
version: 1.0
author: MylesMor
name: SudoSigns-OG
version: '${version}'
authors: [ MylesMor, NotAlexNoyle ]
main: dev.mylesmor.sudosigns.SudoSigns
api-version: 1.13
depend: [DiamondBank-OG]
softdepend: [Multiverse-Core]
api-version: '${apiVersion}'
commands:
sudosigns:
description: Opens the SudoSigns help menu.
description: Opens the SudoSigns-OG help menu.
aliases: [sudosign, ss]
+192
View File
@@ -0,0 +1,192 @@
signs:
SpleggFFA:
text:
- §8[§aFFA§8]
- §60 of 10
- §6Players Waiting
- §8[§B§lJOIN§8]
price: 0.0
location:
world: world
x: 1.0
y: 64.0
z: -249.0
rotation: SOUTH
blocktype: OAK_WALL_SIGN
permissions: {}
messages:
- Splegg is not out yet!: 0.0
player-commands: {}
console-commands: {}
communitychest:
text:
- ''
- §5Community
- §BChest
- ''
price: 0.0
location:
world: world
x: -21.0
y: 63.0
z: -200.0
rotation: NORTH
blocktype: OAK_WALL_SIGN
permissions: {}
messages:
- Use this chest to share items with the community.: 0.0
player-commands: {}
console-commands: {}
balance:
text:
- ''
- §BCHECK
- §BBALANCE
- ''
price: 0.0
location:
world: world
x: -125.0
y: 43.0
z: -261.0
rotation: NORTH
blocktype: WARPED_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- balance: 0.0
console-commands: {}
deposit:
text:
- ''
- §BDEPOSIT
- §BDIAMONDS
- ''
price: 0.0
location:
world: world
x: -123.0
y: 43.0
z: -261.0
rotation: NORTH
blocktype: WARPED_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- deposit all: 0.0
console-commands: {}
withdraw1:
text:
- ''
- §BWITHDRAW
- §B1 DIAMOND
- ''
price: 0.0
location:
world: world
x: -120.0
y: 41.0
z: -261.0
rotation: NORTH
blocktype: WARPED_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- withdraw 1: 0.0
console-commands: {}
withdraw16:
text:
- ''
- §BWITHDRAW
- §B16 DIAMONDS
- ''
price: 0.0
location:
world: world
x: -120.0
y: 43.0
z: -261.0
rotation: NORTH
blocktype: WARPED_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- withdraw 16: 0.0
console-commands: {}
withdraw64:
text:
- ''
- §BWITHDRAW
- §B64 DIAMONDS
- ''
price: 0.0
location:
world: world
x: -121.0
y: 43.0
z: -261.0
rotation: NORTH
blocktype: WARPED_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- withdraw 64: 0.0
console-commands: {}
store:
text:
- §2True§4OG Shop
- §BClick here to
- §bpurchase a
- §brank!
price: 0.0
location:
world: world
x: -128.0
y: 42.0
z: -261.0
rotation: NORTH
blocktype: OAK_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- ranks: 0.0
console-commands: {}
withdraw4:
text:
- ''
- '&BWITHDRAW'
- '&B4 DIAMONDS'
- ''
price: 0.0
location:
world: world
x: -120.0
y: 42.0
z: -261.0
rotation: NORTH
blocktype: WARPED_WALL_SIGN
permissions: {}
messages: {}
player-commands:
- withdraw 4: 0.0
console-commands: {}
SpleggFFA2:
text:
- '[1v1 Duel]'
- 0 of 10
- Players Waiting
- '[JOIN]'
price: 0.0
location:
world: world
x: -1.0
y: 64.0
z: -249.0
rotation: SOUTH
blocktype: OAK_WALL_SIGN
permissions: {}
messages:
- Splegg is not out yet!: 0.0
player-commands: {}
console-commands: {}
version: 1.2.3