From 106f2ed47dd2dce82fe63e0e197f1a94e8b7cd0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Sep 2021 01:06:44 +0000 Subject: [PATCH 01/48] Bump commons-io from 2.5 to 2.7 in /core Bumps commons-io from 2.5 to 2.7. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index b7d1c976..c760906a 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -59,7 +59,7 @@ commons-io commons-io - 2.5 + 2.7 From 1227065ece4c739a0ac375990acea2c289122fd5 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Wed, 30 Mar 2022 11:34:38 -0400 Subject: [PATCH 02/48] Create dependabot.yml --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5b063201 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "maven" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "daily" From b108a64e4369f11e153f978ec291905162b0f872 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 15:35:28 +0000 Subject: [PATCH 03/48] Bump maven-compiler-plugin from 3.8.1 to 3.10.1 Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.8.1 to 3.10.1. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.8.1...maven-compiler-plugin-3.10.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- spigot_1_13/pom.xml | 2 +- spigot_1_8/pom.xml | 2 +- worldedit_6/pom.xml | 2 +- worldedit_7/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spigot_1_13/pom.xml b/spigot_1_13/pom.xml index 6e1f379b..1375c391 100644 --- a/spigot_1_13/pom.xml +++ b/spigot_1_13/pom.xml @@ -21,7 +21,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/spigot_1_8/pom.xml b/spigot_1_8/pom.xml index a124a1d4..fd40ba52 100644 --- a/spigot_1_8/pom.xml +++ b/spigot_1_8/pom.xml @@ -21,7 +21,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/worldedit_6/pom.xml b/worldedit_6/pom.xml index 5277a8ed..c608bcaa 100644 --- a/worldedit_6/pom.xml +++ b/worldedit_6/pom.xml @@ -21,7 +21,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 diff --git a/worldedit_7/pom.xml b/worldedit_7/pom.xml index 7c9f903e..0cce86ec 100644 --- a/worldedit_7/pom.xml +++ b/worldedit_7/pom.xml @@ -21,7 +21,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.1 1.8 1.8 From 3bae0b8d1e0a76b149b8918b799b3f253348c744 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 15:35:34 +0000 Subject: [PATCH 04/48] Bump slf4j-simple from 1.7.25 to 1.7.36 Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 1.7.25 to 1.7.36. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.25...v_1.7.36) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index c760906a..2f0457f5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -81,7 +81,7 @@ org.slf4j slf4j-simple - 1.7.25 + 1.7.36 From f481a7c0a2b6fedcd70c0c86b56b25ac00c75d45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 15:35:36 +0000 Subject: [PATCH 05/48] Bump worldedit-core from 6.1 to 7.2.8 Bumps worldedit-core from 6.1 to 7.2.8. --- updated-dependencies: - dependency-name: com.sk89q.worldedit:worldedit-core dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- worldedit_6/pom.xml | 2 +- worldedit_7/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit_6/pom.xml b/worldedit_6/pom.xml index 5277a8ed..22ad5dc5 100644 --- a/worldedit_6/pom.xml +++ b/worldedit_6/pom.xml @@ -47,7 +47,7 @@ com.sk89q.worldedit worldedit-core - 6.1 + 7.2.8 provided diff --git a/worldedit_7/pom.xml b/worldedit_7/pom.xml index 7c9f903e..e9a53f05 100644 --- a/worldedit_7/pom.xml +++ b/worldedit_7/pom.xml @@ -47,7 +47,7 @@ com.sk89q.worldedit worldedit-core - 7.0.0 + 7.2.8 provided From 384d9ec3d624ce32ebebe159a0bd1bc1740032b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 15:35:40 +0000 Subject: [PATCH 06/48] Bump worldedit-bukkit from 6.1 to 7.2.8 Bumps worldedit-bukkit from 6.1 to 7.2.8. --- updated-dependencies: - dependency-name: com.sk89q.worldedit:worldedit-bukkit dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- worldedit_6/pom.xml | 2 +- worldedit_7/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit_6/pom.xml b/worldedit_6/pom.xml index 5277a8ed..087cdad3 100644 --- a/worldedit_6/pom.xml +++ b/worldedit_6/pom.xml @@ -53,7 +53,7 @@ com.sk89q.worldedit worldedit-bukkit - 6.1 + 7.2.8 provided diff --git a/worldedit_7/pom.xml b/worldedit_7/pom.xml index 7c9f903e..d1e251b6 100644 --- a/worldedit_7/pom.xml +++ b/worldedit_7/pom.xml @@ -53,7 +53,7 @@ com.sk89q.worldedit worldedit-bukkit - 7.0.0 + 7.2.8 provided From 1a21f8830aa67e2693c34f2e4ea3c6caa21d2325 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 15:35:46 +0000 Subject: [PATCH 07/48] Bump annotations from 13.0 to 23.0.0 Bumps [annotations](https://github.com/JetBrains/java-annotations) from 13.0 to 23.0.0. - [Release notes](https://github.com/JetBrains/java-annotations/releases) - [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md) - [Commits](https://github.com/JetBrains/java-annotations/commits/23.0.0) --- updated-dependencies: - dependency-name: org.jetbrains:annotations dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b088e50..8d1f69bf 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ org.jetbrains annotations - 13.0 + 23.0.0 \ No newline at end of file From 29f38c4781bdadb04ab0a3ca5888a8bf02c2e8f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:42:24 +0000 Subject: [PATCH 08/48] Bump commons-io from 2.7 to 2.11.0 Bumps commons-io from 2.7 to 2.11.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 2f0457f5..d13a9b1f 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -59,7 +59,7 @@ commons-io commons-io - 2.7 + 2.11.0 From 962da00afa42a2c3bcd26acf4d1e37b599faad7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:42:38 +0000 Subject: [PATCH 09/48] Bump gson from 2.8.5 to 2.9.0 Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.9.0. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.9.0) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 2f0457f5..cff6e0bf 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -53,7 +53,7 @@ com.google.code.gson gson - 2.8.5 + 2.9.0 From 557df47d1ab61ff4874add038ebdbd8f14860214 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Mar 2022 00:42:43 +0000 Subject: [PATCH 10/48] Bump maven-shade-plugin from 3.2.1 to 3.3.0 Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.2.1 to 3.3.0. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.2.1...maven-shade-plugin-3.3.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dist/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/pom.xml b/dist/pom.xml index 4e039877..8144038f 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -23,7 +23,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.1 + 3.3.0 package From 31f385a98bbd21e71e92be3efd399b89ff5d4554 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 01:23:06 +0000 Subject: [PATCH 11/48] Bump gson from 2.9.0 to 2.9.1 Bumps [gson](https://github.com/google/gson) from 2.9.0 to 2.9.1. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.9.0...gson-parent-2.9.1) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index e03c6ca0..3af26737 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -53,7 +53,7 @@ com.google.code.gson gson - 2.9.0 + 2.9.1 From dbba9662886b7c794f7999090df2d7b84fc6d41b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 01:17:14 +0000 Subject: [PATCH 12/48] Bump slf4j-simple from 1.7.36 to 2.0.0 Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 1.7.36 to 2.0.0. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.36...v_2.0.0) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index e03c6ca0..af5176bd 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -81,7 +81,7 @@ org.slf4j slf4j-simple - 1.7.36 + 2.0.0 From fb54c008bbc5ad5098cd24fdc821f7884c16d67c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Sep 2022 00:34:52 +0000 Subject: [PATCH 13/48] Bump maven-shade-plugin from 3.3.0 to 3.4.0 Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dist/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/pom.xml b/dist/pom.xml index 8144038f..bee23846 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -23,7 +23,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0 + 3.4.0 package From 2676d4bbce4b3b3007fdfbc384d269f3fc09c57e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Sep 2022 00:35:10 +0000 Subject: [PATCH 14/48] Bump slf4j-simple from 2.0.0 to 2.0.1 Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.0...v_2.0.1) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index d8f42c32..2d041202 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -81,7 +81,7 @@ org.slf4j slf4j-simple - 2.0.0 + 2.0.1 From 7083550fea775f8b1151545efcf45022bcd38247 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Sep 2022 00:33:46 +0000 Subject: [PATCH 15/48] Bump slf4j-simple from 2.0.1 to 2.0.3 Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 2.0.1 to 2.0.3. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.1...v_2.0.3) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 2d041202..6116677b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -81,7 +81,7 @@ org.slf4j slf4j-simple - 2.0.1 + 2.0.3 From 1c3b61db934ad75d2e11137a540d3952eac60112 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Oct 2022 00:40:34 +0000 Subject: [PATCH 16/48] Bump maven-shade-plugin from 3.4.0 to 3.4.1 Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.0...maven-shade-plugin-3.4.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dist/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/pom.xml b/dist/pom.xml index bee23846..df8ef846 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -23,7 +23,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.0 + 3.4.1 package From 275f167bfe8b1124f00e898ca9d1d168fc4b77f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Nov 2022 01:16:45 +0000 Subject: [PATCH 17/48] Bump slf4j-simple from 2.0.3 to 2.0.5 Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 2.0.3 to 2.0.5. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.3...v_2.0.5) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 6116677b..12bb8de3 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -81,7 +81,7 @@ org.slf4j slf4j-simple - 2.0.3 + 2.0.5 From 89e01b8c1028e01267a6e6d768094ae290b1d38a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 00:27:06 +0000 Subject: [PATCH 18/48] Bump slf4j-simple from 2.0.5 to 2.0.6 Bumps [slf4j-simple](https://github.com/qos-ch/slf4j) from 2.0.5 to 2.0.6. - [Release notes](https://github.com/qos-ch/slf4j/releases) - [Commits](https://github.com/qos-ch/slf4j/compare/v_2.0.5...v_2.0.6) --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 12bb8de3..feffdcfa 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -81,7 +81,7 @@ org.slf4j slf4j-simple - 2.0.5 + 2.0.6 From c6707bf71680617a50f34cc1e816969770f7d81b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 00:42:43 +0000 Subject: [PATCH 19/48] Bump annotations from 23.0.0 to 24.0.0 Bumps [annotations](https://github.com/JetBrains/java-annotations) from 23.0.0 to 24.0.0. - [Release notes](https://github.com/JetBrains/java-annotations/releases) - [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md) - [Commits](https://github.com/JetBrains/java-annotations/compare/23.0.0...24.0.0) --- updated-dependencies: - dependency-name: org.jetbrains:annotations dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d1f69bf..71668e81 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ org.jetbrains annotations - 23.0.0 + 24.0.0 \ No newline at end of file From 18a69eb17801980b046f73396024406673375e32 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:26:06 -0500 Subject: [PATCH 20/48] Update Java version, Minecraft version, and dependency Upgraded the Java compiler target and source to version 21 and updated the Minecraft version to 1.20.6. Additionally, bumped the JetBrains annotations dependency to version 26.0.2. These changes ensure compatibility with newer features and dependencies. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 71668e81..fa0c56ba 100644 --- a/pom.xml +++ b/pom.xml @@ -16,10 +16,10 @@ 4.0.4 UTF-8 - 1.8 - 1.8 + 21 + 21 - 1.14.3 + 1.20.6 ${project.mcversion}-R0.1-SNAPSHOT 0.9.0 @@ -48,7 +48,7 @@ org.jetbrains annotations - 24.0.0 + 26.0.2 \ No newline at end of file From 5478071a02c1eb33f602c78a7a1ab7a0b1ffdb08 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:33:49 -0500 Subject: [PATCH 21/48] Upgrade dependencies and update Maven configurations Updated Maven compiler plugin to version 3.14.0 and upgraded Java source/target compatibility. Bumped Spigot, WorldEdit, and additional dependencies to newer versions. Fixed repository URLs and corrected a typo in comments for better clarity. --- core/pom.xml | 2 +- worldedit_6/pom.xml | 21 +++++++++++++-------- worldedit_7/pom.xml | 14 +++++++------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index feffdcfa..d61cf6e6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -89,7 +89,7 @@ spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ \ No newline at end of file diff --git a/worldedit_6/pom.xml b/worldedit_6/pom.xml index 2711142b..b5c147f1 100644 --- a/worldedit_6/pom.xml +++ b/worldedit_6/pom.xml @@ -21,10 +21,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.14.0 - 1.8 - 1.8 + 22 + 22 @@ -34,7 +34,7 @@ org.spigotmc spigot-api - 1.12.2-R0.1-SNAPSHOT + 1.20.6-R0.1-SNAPSHOT provided @@ -47,15 +47,20 @@ com.sk89q.worldedit worldedit-core - 7.2.8 + 7.3.10 provided com.sk89q.worldedit worldedit-bukkit - 7.2.8 + 7.3.10 provided + + org.yaml + snakeyaml + 2.4 + @@ -65,10 +70,10 @@ https://hub.spigotmc.org/nexus/content/groups/public/ - + sk89q-repo - http://maven.sk89q.com/repo/ + https://maven.enginehub.org/repo/ diff --git a/worldedit_7/pom.xml b/worldedit_7/pom.xml index 4a7c0ac4..3ffcd900 100644 --- a/worldedit_7/pom.xml +++ b/worldedit_7/pom.xml @@ -21,10 +21,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.14.0 - 1.8 - 1.8 + 21 + 21 @@ -47,13 +47,13 @@ com.sk89q.worldedit worldedit-core - 7.2.8 + 7.3.10 provided com.sk89q.worldedit worldedit-bukkit - 7.2.8 + 7.3.10 provided @@ -67,8 +67,8 @@ - sk89q-repo - http://maven.sk89q.com/repo/ + enginehub + https://maven.enginehub.org/repo/ \ No newline at end of file From 659ea759ced99135b454a33a84b54c9e7e8188a6 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:34:27 -0500 Subject: [PATCH 22/48] Update Maven compiler plugin version and Java target/source Upgraded the maven-compiler-plugin to version 3.14.0 and updated the Java source and target compatibility from 1.8 to 22. This ensures compatibility with newer Java features and aligns the build configuration with modern standards. --- spigot_1_13/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spigot_1_13/pom.xml b/spigot_1_13/pom.xml index 1375c391..8274de9d 100644 --- a/spigot_1_13/pom.xml +++ b/spigot_1_13/pom.xml @@ -21,10 +21,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.14.0 - 1.8 - 1.8 + 22 + 22 From 35637b3b573441d963870e468b8814e80fb02601 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:36:37 -0500 Subject: [PATCH 23/48] Update dependencies and plugin versions in pom files Updated the Spigot API version to 1.13.2-R0.1-SNAPSHOT for spigot_1_13. Adjusted Maven compiler plugin to version 3.14.0 with Java 22 support for spigot_1_8. Upgraded Maven shade plugin to version 3.6.0 in the dist module. --- dist/pom.xml | 2 +- spigot_1_13/pom.xml | 2 +- spigot_1_8/pom.xml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/pom.xml b/dist/pom.xml index df8ef846..9d6bf306 100644 --- a/dist/pom.xml +++ b/dist/pom.xml @@ -23,7 +23,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.6.0 package diff --git a/spigot_1_13/pom.xml b/spigot_1_13/pom.xml index 8274de9d..dbeea66b 100644 --- a/spigot_1_13/pom.xml +++ b/spigot_1_13/pom.xml @@ -34,7 +34,7 @@ org.spigotmc spigot-api - ${project.cbversion} + 1.13.2-R0.1-SNAPSHOT provided diff --git a/spigot_1_8/pom.xml b/spigot_1_8/pom.xml index fd40ba52..186433c7 100644 --- a/spigot_1_8/pom.xml +++ b/spigot_1_8/pom.xml @@ -21,10 +21,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.14.0 - 1.8 - 1.8 + 22 + 22 From 1711917d4f7f57a04e4a4140c5cbb87d1a220ca2 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:37:10 -0500 Subject: [PATCH 24/48] Update API version to 1.20.6 in plugin.yml Upgraded the `api-version` from 1.13 to 1.20.6 to ensure compatibility with newer server versions. This change helps maintain the plugin's functionality on modern platforms. --- core/src/main/resources/plugin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index 46498899..37033564 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: WirelessRedstone main: net.licks92.wirelessredstone.WirelessRedstone -api-version: 1.13 +api-version: 1.20.6 website: http://dev.bukkit.org/server-mods/wireless-redstone/ authors: [licks92, Bart_0110] version: ${project.version} From 0d414b2d7c452cc0b6c3a8eaffbe4a87b2947cb3 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:51:33 -0500 Subject: [PATCH 25/48] Switch to Paper API and update dependencies Replaced Spigot API with Paper API across the project for improved performance and features. Updated multiple dependencies (Gson, Commons IO, SLF4J) to newer versions. Transitioned repositories from Spigot to PaperMC's Maven repository. Updated project semantic version to 0.10.2. --- core/pom.xml | 17 +++++++++-------- pom.xml | 2 +- worldedit_6/pom.xml | 10 +++++----- worldedit_7/pom.xml | 10 +++++----- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index d61cf6e6..4140fa02 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -35,9 +35,9 @@ - org.spigotmc - spigot-api - ${project.cbversion} + io.papermc.paper + paper-api + 1.21.4-R0.1-SNAPSHOT provided @@ -53,13 +53,13 @@ com.google.code.gson gson - 2.9.1 + 2.12.1 commons-io commons-io - 2.11.0 + 2.18.0 @@ -81,15 +81,16 @@ org.slf4j slf4j-simple - 2.0.6 + 2.0.17 + test - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + papermc + https://repo.papermc.io/repository/maven-public/ \ No newline at end of file diff --git a/pom.xml b/pom.xml index fa0c56ba..f5021e2e 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 1.20.6 ${project.mcversion}-R0.1-SNAPSHOT - 0.9.0 + 0.10.2 1.7.23 https://7c45ccc4745f428f81d577b15c84b840@sentry.io/1509557 diff --git a/worldedit_6/pom.xml b/worldedit_6/pom.xml index b5c147f1..0de40ebd 100644 --- a/worldedit_6/pom.xml +++ b/worldedit_6/pom.xml @@ -32,9 +32,9 @@ - org.spigotmc - spigot-api - 1.20.6-R0.1-SNAPSHOT + io.papermc.paper + paper-api + 1.21.4-R0.1-SNAPSHOT provided @@ -66,8 +66,8 @@ - spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ + papermc + https://repo.papermc.io/repository/maven-public/ diff --git a/worldedit_7/pom.xml b/worldedit_7/pom.xml index 3ffcd900..a23c9e3b 100644 --- a/worldedit_7/pom.xml +++ b/worldedit_7/pom.xml @@ -32,9 +32,9 @@ - org.spigotmc - spigot-api - ${project.cbversion} + io.papermc.paper + paper-api + 1.21.4-R0.1-SNAPSHOT provided @@ -61,8 +61,8 @@ - spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ + papermc + https://repo.papermc.io/repository/maven-public/ From 094e605f7df1422b8b475223a113771a8c04bca5 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:51:46 -0500 Subject: [PATCH 26/48] Refactor onDisable to improve cleanup and logging. Added safeguards to close storage, unregister hooks, shut down sentry, and reset static references to prevent memory leaks. Enhanced logging to confirm proper plugin disablement. --- .../licks92/wirelessredstone/WirelessRedstone.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index 691d5c3f..b07abe50 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -287,15 +287,25 @@ private int getSigns(SignType type) { @Override public void onDisable() { + // Close storage connection if initiiated if (storageLoaded) { getStorage().close(); } + // Unregister any WorldEdit hooks if (worldEditHooker != null) { worldEditHooker.unRegister(); } + // Ensure sentry shut down if enabled + if (sentryEnabled) { + Sentry.close(); + } + + // Reset static references to prevent memory leaks storageLoaded = false; + sentryEnabled = false; + adminCommandManager = null; commandManager = null; signManager = null; @@ -303,7 +313,11 @@ public void onDisable() { stringManager = null; config = null; WRLogger = null; + worldEditHooker = null; instance = null; + + // Log proper disable message + getLogger().info("Disabled WirelessRedstone"); } public void resetSentryContext() { From 92fa3de5dd4898f31d17696c4a599d442c0a25fd Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:56:25 -0500 Subject: [PATCH 27/48] Handle missing or unreadable plugin.yml gracefully Ensure the plugin disables itself if plugin.yml is missing or throws an IOException during loading. Added logging for better error debugging and prevention of undefined behavior. --- .../wirelessredstone/WirelessRedstone.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index b07abe50..0bedc20a 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -29,6 +29,7 @@ import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; @@ -139,12 +140,24 @@ public void onEnable() { adminCommandManager = new AdminCommandManager(); if (sentryEnabled) { - YamlConfiguration pluginConfig = YamlConfiguration.loadConfiguration( - new InputStreamReader(Objects.requireNonNull(getResource("plugin.yml"))) - ); + YamlConfiguration pluginConfig; + try (var resourceStream = getResource("plugin.yml")) { + if (resourceStream == null) { + WRLogger.severe("Couldn't load plugin.yml resource. The file is missing from the plugin"); + getPluginLoader().disablePlugin(this); + return; + } - getWRLogger().debug("Sentry dsn: " + pluginConfig.getString("sentry.dsn", "")); + pluginConfig = YamlConfiguration.loadConfiguration( + new InputStreamReader(resourceStream)); + } catch (IOException e) { + WRLogger.severe("Error reading 'plugin.yml': " + e.getMessage()); + e.printStackTrace(); + getPluginLoader().disablePlugin(this); + return; + } + getWRLogger().debug("Sentry DSN: " + pluginConfig.getString("sentry.dsn", "")); Sentry.init(pluginConfig.getString("sentry.dsn", ""), new WirelessRedstoneSentryClientFactory()); resetSentryContext(); } From b075de35551a96547c59c7dc6880db3761b4156c Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 21:57:58 -0500 Subject: [PATCH 28/48] Improve incompatibility logging for better debugging Added detailed server and plugin version information in the logging when the plugin is incompatible with the server. This helps users identify version mismatches more easily and directs them to the plugin's page for supported versions. --- .../net/licks92/wirelessredstone/WirelessRedstone.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index 0bedc20a..ad29ed7a 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -112,10 +112,16 @@ public void onEnable() { instance = this; if (!Utils.isCompatible()) { + String serverVersion = Bukkit.getVersion(); + String pluginVersion = getDescription().getVersion(); WRLogger.severe("**********"); - WRLogger.severe("This plugin isn't compatible with this Minecraft version! Please check the bukkit/spigot page."); + WRLogger.severe("WirelessRedstone is not compatible with this server version!"); + WRLogger.severe("Server version: " + serverVersion); + WRLogger.severe("Plugin version: " + pluginVersion); + WRLogger.severe("Please check the plugin's page for supported versions."); WRLogger.severe("**********"); getPluginLoader().disablePlugin(this); + return; } new MaterialLib(this).initialize(); From 37d02b7b3b416efc66d3e4a5228c8ad196550fbd Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:06:04 -0500 Subject: [PATCH 29/48] Refactor main plugin structure and improve initialization Simplified imports by using wildcard and improved organization of methods for better readability. Added robust initialization and shutdown procedures for storage, commands, metrics, and third-party integrations like WorldEdit and Sentry. Enhanced logging and error handling for compatibility checks, update checks, and event management. --- .../wirelessredstone/WirelessRedstone.java | 380 ++++++++---------- 1 file changed, 175 insertions(+), 205 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index ad29ed7a..41c20876 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -7,34 +7,26 @@ import net.licks92.wirelessredstone.listeners.BlockListener; import net.licks92.wirelessredstone.listeners.PlayerListener; import net.licks92.wirelessredstone.listeners.WorldListener; +import net.licks92.wirelessredstone.materiallib.MaterialLib; import net.licks92.wirelessredstone.sentry.EventExceptionHandler; import net.licks92.wirelessredstone.sentry.WirelessRedstoneSentryClientFactory; -import net.licks92.wirelessredstone.signs.SignType; -import net.licks92.wirelessredstone.signs.WirelessReceiver; -import net.licks92.wirelessredstone.signs.WirelessReceiverClock; -import net.licks92.wirelessredstone.signs.WirelessReceiverDelayer; -import net.licks92.wirelessredstone.signs.WirelessReceiverInverter; -import net.licks92.wirelessredstone.signs.WirelessReceiverSwitch; -import net.licks92.wirelessredstone.signs.WirelessScreen; -import net.licks92.wirelessredstone.signs.WirelessTransmitter; +import net.licks92.wirelessredstone.signs.*; import net.licks92.wirelessredstone.storage.StorageConfiguration; import net.licks92.wirelessredstone.storage.StorageManager; import net.licks92.wirelessredstone.string.StringManager; import net.licks92.wirelessredstone.string.Strings; import net.licks92.wirelessredstone.worldedit.WorldEditLoader; -import net.licks92.wirelessredstone.materiallib.MaterialLib; import org.bukkit.Bukkit; +import org.bukkit.command.CommandExecutor; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.Event; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; -import java.io.IOException; import java.io.InputStreamReader; -import java.util.HashMap; +import java.util.Collections; import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Callable; public class WirelessRedstone extends JavaPlugin { @@ -54,7 +46,7 @@ public class WirelessRedstone extends JavaPlugin { private boolean storageLoaded = false; private boolean sentryEnabled = true; - + // Static getters for easy access public static WirelessRedstone getInstance() { return instance; } @@ -95,6 +87,7 @@ public static Metrics getMetrics() { return metrics; } + // Accessor methods for instance fields public boolean isSentryEnabled() { return sentryEnabled; } @@ -111,77 +104,176 @@ public void setWorldEditHooker(InternalWorldEditHooker worldEditHooker) { public void onEnable() { instance = this; + // Compatibility Check if (!Utils.isCompatible()) { - String serverVersion = Bukkit.getVersion(); - String pluginVersion = getDescription().getVersion(); - WRLogger.severe("**********"); - WRLogger.severe("WirelessRedstone is not compatible with this server version!"); - WRLogger.severe("Server version: " + serverVersion); - WRLogger.severe("Plugin version: " + pluginVersion); - WRLogger.severe("Please check the plugin's page for supported versions."); - WRLogger.severe("**********"); + String serverVersion = Bukkit.getBukkitVersion(); + getLogger().severe("**********"); + getLogger().severe("WirelessRedstone is not compatible with this server version!"); + getLogger().severe("Server Version: " + serverVersion); + getLogger().severe("Please check for supported versions on the plugin's page."); + getLogger().severe("**********"); getPluginLoader().disablePlugin(this); return; } + // Initialize MaterialLib new MaterialLib(this).initialize(); + // Load Configuration config = ConfigManager.getConfig(); config.update(CHANNEL_FOLDER); + sentryEnabled = config.getSentry() && !"TRUE".equalsIgnoreCase(System.getProperty("mc.development")); WRLogger = new WRLogger("[WirelessRedstone]", getServer().getConsoleSender(), config.getDebugMode(), config.getColorLogging()); stringManager = new StringManager(config.getLanguage()); + // Initialize Storage Manager storageManager = new StorageManager(config.getStorageType(), CHANNEL_FOLDER); - if (!storageManager.getStorage().initStorage()) { + getLogger().severe("Failed to initialize storage. Disabling plugin."); getPluginLoader().disablePlugin(this); return; } storageLoaded = true; + // Initialize Managers signManager = new SignManager(); commandManager = new CommandManager(); adminCommandManager = new AdminCommandManager(); + // Initialize Sentry for error reporting + setupSentry(); + + // Register Events + registerEvents(); + + // Register Commands + registerCommands(); + + // Load WorldEdit Integration (if available) + loadWorldEditIntegration(); + + // Initialize Metrics (if enabled) + setupMetrics(); + + // Perform Update Check (if enabled) + checkForUpdates(); + } + + @Override + public void onDisable() { + // Shutdown components before plugin unload + if (storageLoaded) { + getStorage().close(); + } + + if (worldEditHooker != null) { + worldEditHooker.unRegister(); + } + + storageLoaded = false; + adminCommandManager = null; + commandManager = null; + signManager = null; + storageManager = null; + stringManager = null; + config = null; + WRLogger = null; + worldEditHooker = null; + instance = null; + if (sentryEnabled) { - YamlConfiguration pluginConfig; - try (var resourceStream = getResource("plugin.yml")) { - if (resourceStream == null) { - WRLogger.severe("Couldn't load plugin.yml resource. The file is missing from the plugin"); - getPluginLoader().disablePlugin(this); - return; - } - - pluginConfig = YamlConfiguration.loadConfiguration( - new InputStreamReader(resourceStream)); - } catch (IOException e) { - WRLogger.severe("Error reading 'plugin.yml': " + e.getMessage()); + Sentry.close(); + } + + getLogger().info("WirelessRedstone has been disabled."); + } + + private void setupMetrics() { + if (!config.getMetrics()) return; + + metrics = new Metrics(this); + + // Main sign type metrics + metrics.addCustomChart(new Metrics.AdvancedPie("main_sign_types", () -> { + try { + return Map.of( + "Transmitters", countSigns(WirelessTransmitter.class), + "Receivers", countSigns(WirelessReceiver.class), + "Screens", countSigns(WirelessScreen.class) + ); + } catch (Exception e) { + e.printStackTrace(); + return Collections.emptyMap(); + } + })); + + // Receiver sign type metrics + metrics.addCustomChart(new Metrics.AdvancedPie("receiver_sign_types", () -> { + try { + return Map.of( + "Normal", countSigns(WirelessReceiver.class), + "Inverter", countSigns(WirelessReceiverInverter.class), + "Delayer", countSigns(WirelessReceiverDelayer.class), + "Clock", countSigns(WirelessReceiverClock.class), + "Switch", countSigns(WirelessReceiverSwitch.class) + ); + } catch (Exception e) { e.printStackTrace(); - getPluginLoader().disablePlugin(this); + return Collections.emptyMap(); + } + })); + } + + private int countSigns(Class signType) { + if (storageManager == null || storageManager.getAllSigns() == null) return 0; + return (int) storageManager.getAllSigns().stream() + .filter(signType::isInstance) + .count(); + } + + private void setupSentry() { + if (!sentryEnabled) return; + + try (var resourceStream = getResource("plugin.yml")) { + if (resourceStream == null) { + getLogger().severe("Could not load 'plugin.yml'. Missing from the jar."); return; } - getWRLogger().debug("Sentry DSN: " + pluginConfig.getString("sentry.dsn", "")); - Sentry.init(pluginConfig.getString("sentry.dsn", ""), new WirelessRedstoneSentryClientFactory()); + var pluginConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(resourceStream)); + var sentryDsn = pluginConfig.getString("sentry.dsn", ""); + Sentry.init(sentryDsn, new WirelessRedstoneSentryClientFactory()); + resetSentryContext(); + + getLogger().info("Sentry initialized for error reporting."); + } catch (Exception e) { + getLogger().severe("Failed to initialize Sentry: " + e.getMessage()); + e.printStackTrace(); } + } - PluginManager pm = getServer().getPluginManager(); + private void resetSentryContext() { + Sentry.clearContext(); + var version = Bukkit.getBukkitVersion().split("-")[0]; + Sentry.getStoredClient().addTag("MC_version", version); + Sentry.getStoredClient().addTag("MC_implementation", "Paper"); + } + private void registerEvents() { + PluginManager pm = getServer().getPluginManager(); boolean eventCatchingSuccess = true; + try { if (sentryEnabled) { EventExceptionHandler eventExceptionHandler = new EventExceptionHandler() { @Override public boolean handle(Throwable ex, Event event) { Sentry.capture(ex); - // getLogger().log(Level.SEVERE, "Error " + ex.getMessage() + " occured for " + event, ex); - - // Don't pass it on - // return true; - // Use Bukkit's default exception handler + getLogger().severe("An error occurred during event: " + event.getEventName()); + ex.printStackTrace(); return false; } }; @@ -192,7 +284,7 @@ public boolean handle(Throwable ex, Event event) { } } catch (RuntimeException ex) { eventCatchingSuccess = false; - getWRLogger().warning("Couldn't register events with Sentry catcher."); + getLogger().warning("Couldn't register events with Sentry catcher."); Sentry.capture(ex); } @@ -201,172 +293,50 @@ public boolean handle(Throwable ex, Event event) { pm.registerEvents(new BlockListener(), this); pm.registerEvents(new PlayerListener(), this); } - - getCommand("wirelessredstone").setExecutor(commandManager); - getCommand("wr").setExecutor(commandManager); - getCommand("wredstone").setExecutor(commandManager); - getCommand("wifi").setExecutor(commandManager); - - getCommand("wirelessredstone").setTabCompleter(commandManager); - getCommand("wr").setTabCompleter(commandManager); - getCommand("wredstone").setTabCompleter(commandManager); - getCommand("wifi").setTabCompleter(commandManager); - - getCommand("wradmin").setExecutor(adminCommandManager); - getCommand("wra").setExecutor(adminCommandManager); - - getCommand("wradmin").setTabCompleter(adminCommandManager); - getCommand("wra").setTabCompleter(adminCommandManager); - - if (pm.isPluginEnabled("WorldEdit")) { - new WorldEditLoader(); - } - - if (config.getMetrics()) { - metrics = new Metrics(this); - metrics.addCustomChart(new Metrics.AdvancedPie("main_sign_types", new Callable>() { - @Override - public Map call() { - Map valueMap = new HashMap<>(); - valueMap.put("Transmitters", getSigns(SignType.TRANSMITTER)); - valueMap.put("Receivers", getSigns(SignType.RECEIVER)); - valueMap.put("Screens", getSigns(SignType.SCREEN)); - return valueMap; - } - - private int getSigns(SignType type) { - if (type == SignType.TRANSMITTER) { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessTransmitter) - .count(); - } else if (type == SignType.RECEIVER) { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessReceiver) - .count(); - } else { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessScreen) - .count(); - } - } - })); - - metrics.addCustomChart(new Metrics.AdvancedPie("receiver_sign_types", new Callable>() { - @Override - public Map call() { - Map valueMap = new HashMap<>(); - valueMap.put("Normal", getSigns(SignType.RECEIVER)); - valueMap.put("Inverter", getSigns(SignType.RECEIVER_INVERTER)); - valueMap.put("Delayer", getSigns(SignType.RECEIVER_DELAYER)); - valueMap.put("Clock", getSigns(SignType.RECEIVER_CLOCK)); - valueMap.put("Switch", getSigns(SignType.RECEIVER_SWITCH)); - return valueMap; - } - - private int getSigns(SignType type) { - if (type == SignType.RECEIVER_INVERTER) { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessReceiverInverter) - .count(); - } else if (type == SignType.RECEIVER_DELAYER) { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessReceiverDelayer) - .count(); - } else if (type == SignType.RECEIVER_CLOCK) { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessReceiverClock) - .count(); - } else if (type == SignType.RECEIVER_SWITCH) { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessReceiverSwitch) - .count(); - } else { - return (int) getStorageManager().getAllSigns().stream() - .filter(point -> point instanceof WirelessReceiver) - .count(); - } - } - })); - - metrics.addCustomChart(new Metrics.SimplePie("storage_types", () -> - ConfigManager.getConfig().getStorageType().toString() - )); - } - - if (config.getUpdateCheck()) { - UpdateChecker.init(this).requestUpdateCheck().whenComplete((updateResult, throwable) -> { - if (updateResult.updateAvailable()) { - Bukkit.getScheduler().runTask(this, () -> getWRLogger().info(getStrings().newUpdate - .replaceAll("%%NEWVERSION", updateResult.getNewestVersion()) - .replaceAll("%%URL", updateResult.getUrl()))); - } - }); - } } - @Override - public void onDisable() { - // Close storage connection if initiiated - if (storageLoaded) { - getStorage().close(); - } - - // Unregister any WorldEdit hooks - if (worldEditHooker != null) { - worldEditHooker.unRegister(); - } - - // Ensure sentry shut down if enabled - if (sentryEnabled) { - Sentry.close(); - } - - // Reset static references to prevent memory leaks - storageLoaded = false; - sentryEnabled = false; - - adminCommandManager = null; - commandManager = null; - signManager = null; - storageManager = null; - stringManager = null; - config = null; - WRLogger = null; - worldEditHooker = null; - instance = null; - - // Log proper disable message - getLogger().info("Disabled WirelessRedstone"); + private void registerCommands() { + Map<@NotNull String, ? extends CommandExecutor> commands = Map.of( + "wirelessredstone", commandManager, + "wr", commandManager, + "wredstone", commandManager, + "wifi", commandManager, + "wradmin", adminCommandManager, + "wra", adminCommandManager + ); + + commands.forEach((commandName, manager) -> { + if (getCommand(commandName) != null) { + getCommand(commandName).setExecutor(manager); + getCommand(commandName).setTabCompleter(manager); + } else { + getLogger().warning("Command '" + commandName + "' is missing in plugin.yml."); + } + }); } - public void resetSentryContext() { - Sentry.clearContext(); - - Sentry.getStoredClient().setRelease(getDescription().getVersion()); - - String version = Bukkit.getBukkitVersion(); - if (version.contains("-")) { - version = version.split("-")[0]; + private void loadWorldEditIntegration() { + try { + if (getServer().getPluginManager().isPluginEnabled("WorldEdit")) { + new WorldEditLoader(); + getLogger().info("WorldEdit integration enabled."); + } else { + getLogger().info("WorldEdit not found. Skipping integration."); + } + } catch (Exception e) { + getLogger().severe("Failed to enable WorldEdit integration: " + e.getMessage()); + e.printStackTrace(); } + } - String serverImplementation = "Spigot"; - if (Bukkit.getVersion().contains("Paper")) { - serverImplementation = "Paper"; - } else if (Bukkit.getVersion().contains("Taco")) { - serverImplementation = "TacoSpigot"; - } + private void checkForUpdates() { + if (!config.getUpdateCheck()) return; - Sentry.getStoredClient().addTag("MC_version", version); - Sentry.getStoredClient().addTag("MC_implementation", serverImplementation); - } + UpdateChecker.init(this).requestUpdateCheck().whenComplete((result, throwable) -> { + if (throwable != null || !result.updateAvailable()) return; - /** - * Re-initialize strings. This can be used to switch languages after a config change. - *

- * Removes reference to stringManager and place a new reference. - */ - public void resetStrings() { - stringManager = null; - stringManager = new StringManager(config.getLanguage()); + Bukkit.getScheduler().runTask(this, () -> + getLogger().info("A new update is available: Version " + result.getNewestVersion())); + }); } -} +} \ No newline at end of file From eb0332427024b283cf57d18b2a4fa2bb36eda1d7 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:06:40 -0500 Subject: [PATCH 30/48] Ensure null safety in command registration logic Added `Objects.requireNonNull` to enforce null checks when registering command executors and tab completers. This prevents potential null pointer exceptions during plugin initialization. --- .../java/net/licks92/wirelessredstone/WirelessRedstone.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index 41c20876..c21cbf03 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -18,6 +18,7 @@ import net.licks92.wirelessredstone.worldedit.WorldEditLoader; import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; +import org.bukkit.command.TabCompleter; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.Event; import org.bukkit.plugin.PluginManager; @@ -27,6 +28,7 @@ import java.io.InputStreamReader; import java.util.Collections; import java.util.Map; +import java.util.Objects; public class WirelessRedstone extends JavaPlugin { @@ -307,8 +309,8 @@ private void registerCommands() { commands.forEach((commandName, manager) -> { if (getCommand(commandName) != null) { - getCommand(commandName).setExecutor(manager); - getCommand(commandName).setTabCompleter(manager); + Objects.requireNonNull(getCommand(commandName)).setExecutor(manager); + Objects.requireNonNull(getCommand(commandName)).setTabCompleter((TabCompleter) manager); } else { getLogger().warning("Command '" + commandName + "' is missing in plugin.yml."); } From 2f554ff7225d0a883c69842bf11ac30679e6954e Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:08:12 -0500 Subject: [PATCH 31/48] Refactor WRLogger to use Optional for console field. Replaced direct usage of ConsoleCommandSender with Optional to handle potential null values more safely. This improves code reliability and aligns with modern Java best practices. --- core/src/main/java/net/licks92/wirelessredstone/WRLogger.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java b/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java index 2779498b..5fcbcf76 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java @@ -4,9 +4,11 @@ import org.bukkit.ChatColor; import org.bukkit.command.ConsoleCommandSender; +import java.util.Optional; + public class WRLogger { - private final ConsoleCommandSender console; + private final Optional console; private final String prefix; private final boolean debug; private final boolean color; From 7efbff11d1817e3a660a57872f2daa3f7cf817e1 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:08:35 -0500 Subject: [PATCH 32/48] Refactor WRLogger for safer console handling with Optional Replaced direct ConsoleCommandSender reference with Optional for null safety. Simplified the prefix initialization logic for better readability and maintainability. --- .../java/net/licks92/wirelessredstone/WRLogger.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java b/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java index 5fcbcf76..859394ba 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java @@ -16,17 +16,16 @@ public class WRLogger { /** * Creates an instance of WRLogger. * - * @param prefix This is added before all messages - * @param console Console reference from bukkit/spigot - * @param debug Enable debug mode - * @param color Enable color messages + * @param prefix This is added before all messages + * @param console Console reference from Bukkit/Spigot + * @param debug Enable debug mode + * @param color Enable color messages */ public WRLogger(String prefix, ConsoleCommandSender console, boolean debug, boolean color) { this.debug = debug; this.color = color; - this.console = console; - if (color) this.prefix = ChatColor.RED + prefix + ChatColor.RESET; - else this.prefix = prefix; + this.console = Optional.ofNullable(console); // Safe handling using Optional + this.prefix = color ? ChatColor.RED + prefix + ChatColor.RESET : prefix; } /** From ea5cf2c6a582b3e8a5741509f91ae960c7557dc7 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:14:54 -0500 Subject: [PATCH 33/48] Refactor WRLogger to use Kyori Adventure API. Replaces Bukkit's console messaging with Kyori Adventure API for improved text formatting and message handling. Simplifies logic with a unified `log` method and streamlined color handling, while maintaining backward compatibility via plain text fallback. Adds Adventure API as a project dependency. --- core/pom.xml | 5 + .../licks92/wirelessredstone/WRLogger.java | 105 +++++++++++++----- 2 files changed, 82 insertions(+), 28 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 4140fa02..52ffdd3e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -84,6 +84,11 @@ 2.0.17 test + + net.kyori + adventure-api + 4.19.0 + diff --git a/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java b/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java index 859394ba..29ebfe4a 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WRLogger.java @@ -1,73 +1,122 @@ package net.licks92.wirelessredstone; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.ConsoleCommandSender; -import java.util.Optional; - public class WRLogger { - private final Optional console; - private final String prefix; + private final Audience audience; + private final Component prefixComponent; private final boolean debug; private final boolean color; /** * Creates an instance of WRLogger. * - * @param prefix This is added before all messages - * @param console Console reference from Bukkit/Spigot - * @param debug Enable debug mode - * @param color Enable color messages + * @param prefix This is added before all messages. + * @param console ConsoleCommandSender for console access. + * @param debug Enable debug mode. + * @param color Enable colored messages. */ public WRLogger(String prefix, ConsoleCommandSender console, boolean debug, boolean color) { this.debug = debug; this.color = color; - this.console = Optional.ofNullable(console); // Safe handling using Optional - this.prefix = color ? ChatColor.RED + prefix + ChatColor.RESET : prefix; + this.audience = console != null ? Audience.audience(console) : Audience.empty(); // Use Adventure's Audience + + // Add color to the prefix if applicable + if (color) { + this.prefixComponent = Component.text() + .append(Component.text(prefix, NamedTextColor.RED)) + .append(Component.space()) + .build(); + } else { + this.prefixComponent = Component.text(prefix); + } } /** - * Display a info message to the console. + * Displays an informational message to the console. * - * @param msg Message + * @param msg The informational message. */ public void info(String msg) { - if (color) console.sendMessage(prefix + " " + msg); - else Bukkit.getLogger().info(msg); + log(msg, NamedTextColor.GREEN); } /** - * Display a debug message to the console if debug mode is enabled. + * Displays a debug message to the console if debug mode is enabled. * - * @param msg Message + * @param msg The debug message. */ public void debug(String msg) { if (debug) { - if (color) console.sendMessage(prefix + ChatColor.GOLD + "[Debug] " + ChatColor.RESET + msg); - else Bukkit.getLogger().info(prefix + "[Debug] " + msg); + log("[Debug] " + msg, NamedTextColor.GOLD); } } /** - * Display a severe message to the console. + * Displays a severe error message to the console. * - * @param msg Message + * @param msg The severe message. */ public void severe(String msg) { - if (color) console.sendMessage(prefix + ChatColor.DARK_RED + "[SEVERE] " + ChatColor.RESET + msg); - else Bukkit.getLogger().severe(prefix + " " + msg); + log("[SEVERE] " + msg, NamedTextColor.DARK_RED); } /** - * Display a warning message to the console. + * Displays a warning message to the console. * - * @param msg Message + * @param msg The warning message. */ public void warning(String msg) { - if (color) console.sendMessage(prefix + ChatColor.YELLOW + "[WARNING] " + ChatColor.RESET + msg); - else Bukkit.getLogger().warning(prefix + " " + msg); + log("[WARNING] " + msg, NamedTextColor.YELLOW); + } + + /** + * Logs the message with the appropriate color and level. + * + * @param msg The message to log. + * @param color The text color (or null for no color). + */ + private void log(String msg, TextColor color) { + Component messageComponent = formatMessage(msg, color); + + // Send to audience (Adventure API) + audience.sendMessage(messageComponent); + + // Fallback to Bukkit Logger in case audience isn't available + if (audience == Audience.empty()) { + Bukkit.getLogger().info(stripColors(messageComponent)); + } } -} + /** + * Formats the message by applying prefix and color if needed. + * + * @param msg The message to format. + * @param color The text color (null for no color). + * @return A formatted Component with the message content. + */ + private Component formatMessage(String msg, TextColor color) { + Component msgComponent = Component.text(msg); + if (color != null && this.color) { + msgComponent = msgComponent.color(color); + } + return prefixComponent.append(msgComponent); + } + + /** + * Strips colors from a Component. + * This is a fallback for plain-text logging via Bukkit Logger. + * + * @param component The component to strip. + * @return A plain-text representation of the component. + */ + private String stripColors(Component component) { + return net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(component); + } +} \ No newline at end of file From 9a3b62821b87055eb15eb2c15e5c030083fdd277 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:18:15 -0500 Subject: [PATCH 34/48] Refactor logging and code structure for clarity Replaced legacy logger with WRLogger using Adventure API for improved message formatting and clarity. Simplified methods, reduced redundancy, and improved modularity across initialization, event registration, and command handling. Adjusted naming conventions to enhance readability. --- .../wirelessredstone/WirelessRedstone.java | 217 +++++++----------- 1 file changed, 78 insertions(+), 139 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index c21cbf03..5b36a5b1 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -1,29 +1,29 @@ package net.licks92.wirelessredstone; import io.sentry.Sentry; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import net.licks92.wirelessredstone.commands.Admin.AdminCommandManager; import net.licks92.wirelessredstone.commands.CommandManager; import net.licks92.wirelessredstone.compat.InternalWorldEditHooker; import net.licks92.wirelessredstone.listeners.BlockListener; import net.licks92.wirelessredstone.listeners.PlayerListener; import net.licks92.wirelessredstone.listeners.WorldListener; -import net.licks92.wirelessredstone.materiallib.MaterialLib; import net.licks92.wirelessredstone.sentry.EventExceptionHandler; import net.licks92.wirelessredstone.sentry.WirelessRedstoneSentryClientFactory; -import net.licks92.wirelessredstone.signs.*; -import net.licks92.wirelessredstone.storage.StorageConfiguration; +import net.licks92.wirelessredstone.signs.WirelessReceiver; +import net.licks92.wirelessredstone.signs.WirelessScreen; +import net.licks92.wirelessredstone.signs.WirelessTransmitter; import net.licks92.wirelessredstone.storage.StorageManager; import net.licks92.wirelessredstone.string.StringManager; -import net.licks92.wirelessredstone.string.Strings; import net.licks92.wirelessredstone.worldedit.WorldEditLoader; import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.event.Event; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.NotNull; import java.io.InputStreamReader; import java.util.Collections; @@ -35,7 +35,7 @@ public class WirelessRedstone extends JavaPlugin { public static final String CHANNEL_FOLDER = "channels"; private static WirelessRedstone instance; - private static WRLogger WRLogger; + private static WRLogger wrLogger; // Updated naming style for clarity private static StringManager stringManager; private static StorageManager storageManager; private static SignManager signManager; @@ -54,25 +54,17 @@ public static WirelessRedstone getInstance() { } public static WRLogger getWRLogger() { - return WRLogger; + return wrLogger; } public static StringManager getStringManager() { return stringManager; } - public static Strings getStrings() { - return getStringManager().getStrings(); - } - public static StorageManager getStorageManager() { return storageManager; } - public static StorageConfiguration getStorage() { - return getStorageManager().getStorage(); - } - public static SignManager getSignManager() { return signManager; } @@ -81,65 +73,43 @@ public static CommandManager getCommandManager() { return commandManager; } - public static AdminCommandManager getAdminCommandManager() { - return adminCommandManager; - } - - public static Metrics getMetrics() { - return metrics; - } - - // Accessor methods for instance fields - public boolean isSentryEnabled() { - return sentryEnabled; - } - - public InternalWorldEditHooker getWorldEditHooker() { - return worldEditHooker; - } - - public void setWorldEditHooker(InternalWorldEditHooker worldEditHooker) { - this.worldEditHooker = worldEditHooker; - } - @Override public void onEnable() { instance = this; - // Compatibility Check + // Console sender + ConsoleCommandSender console = getServer().getConsoleSender(); + + // Initial compatibility check if (!Utils.isCompatible()) { - String serverVersion = Bukkit.getBukkitVersion(); - getLogger().severe("**********"); - getLogger().severe("WirelessRedstone is not compatible with this server version!"); - getLogger().severe("Server Version: " + serverVersion); - getLogger().severe("Please check for supported versions on the plugin's page."); - getLogger().severe("**********"); - getPluginLoader().disablePlugin(this); + logIncompatibleVersion(console); return; } - // Initialize MaterialLib - new MaterialLib(this).initialize(); - - // Load Configuration + // Initialize WRLogger with Adventure API config = ConfigManager.getConfig(); + wrLogger = new WRLogger("[WirelessRedstone]", console, config.getDebugMode(), config.getColorLogging()); + + wrLogger.info("Initializing WirelessRedstone..."); + + // Load configurations config.update(CHANNEL_FOLDER); sentryEnabled = config.getSentry() && !"TRUE".equalsIgnoreCase(System.getProperty("mc.development")); - WRLogger = new WRLogger("[WirelessRedstone]", getServer().getConsoleSender(), config.getDebugMode(), config.getColorLogging()); - stringManager = new StringManager(config.getLanguage()); - // Initialize Storage Manager + stringManager = new StringManager(config.getLanguage()); storageManager = new StorageManager(config.getStorageType(), CHANNEL_FOLDER); + + // Initialize storage if (!storageManager.getStorage().initStorage()) { - getLogger().severe("Failed to initialize storage. Disabling plugin."); + wrLogger.severe("Failed to initialize storage. Disabling plugin."); getPluginLoader().disablePlugin(this); return; } storageLoaded = true; - // Initialize Managers + // Initialize managers signManager = new SignManager(); commandManager = new CommandManager(); adminCommandManager = new AdminCommandManager(); @@ -147,25 +117,26 @@ public void onEnable() { // Initialize Sentry for error reporting setupSentry(); - // Register Events + // Register events and commands registerEvents(); - - // Register Commands registerCommands(); - // Load WorldEdit Integration (if available) + // WorldEdit integration loadWorldEditIntegration(); - // Initialize Metrics (if enabled) + // Metrics tracking (if enabled) setupMetrics(); - // Perform Update Check (if enabled) + // Perform update check (if configured) checkForUpdates(); + + wrLogger.info("WirelessRedstone has been successfully enabled."); } @Override public void onDisable() { - // Shutdown components before plugin unload + wrLogger.info("Disabling WirelessRedstone..."); + if (storageLoaded) { getStorage().close(); } @@ -174,6 +145,7 @@ public void onDisable() { worldEditHooker.unRegister(); } + // Cleanup components storageLoaded = false; adminCommandManager = null; commandManager = null; @@ -181,7 +153,7 @@ public void onDisable() { storageManager = null; stringManager = null; config = null; - WRLogger = null; + wrLogger = null; worldEditHooker = null; instance = null; @@ -189,7 +161,20 @@ public void onDisable() { Sentry.close(); } - getLogger().info("WirelessRedstone has been disabled."); + wrLogger.info("WirelessRedstone has been disabled."); + } + + private void logIncompatibleVersion(ConsoleCommandSender console) { + String serverVersion = Bukkit.getBukkitVersion(); + WRLogger incompatibleLogger = new WRLogger("[WirelessRedstone]", console, false, true); + + incompatibleLogger.severe("**********"); + incompatibleLogger.severe("WirelessRedstone is not compatible with this server version!"); + incompatibleLogger.severe("Server Version: " + serverVersion); + incompatibleLogger.severe("Please check for supported versions on the plugin's page."); + incompatibleLogger.severe("**********"); + + getPluginLoader().disablePlugin(this); } private void setupMetrics() { @@ -206,33 +191,10 @@ private void setupMetrics() { "Screens", countSigns(WirelessScreen.class) ); } catch (Exception e) { - e.printStackTrace(); + wrLogger.warning("Error gathering metrics: " + e.getMessage()); return Collections.emptyMap(); } })); - - // Receiver sign type metrics - metrics.addCustomChart(new Metrics.AdvancedPie("receiver_sign_types", () -> { - try { - return Map.of( - "Normal", countSigns(WirelessReceiver.class), - "Inverter", countSigns(WirelessReceiverInverter.class), - "Delayer", countSigns(WirelessReceiverDelayer.class), - "Clock", countSigns(WirelessReceiverClock.class), - "Switch", countSigns(WirelessReceiverSwitch.class) - ); - } catch (Exception e) { - e.printStackTrace(); - return Collections.emptyMap(); - } - })); - } - - private int countSigns(Class signType) { - if (storageManager == null || storageManager.getAllSigns() == null) return 0; - return (int) storageManager.getAllSigns().stream() - .filter(signType::isInstance) - .count(); } private void setupSentry() { @@ -240,7 +202,7 @@ private void setupSentry() { try (var resourceStream = getResource("plugin.yml")) { if (resourceStream == null) { - getLogger().severe("Could not load 'plugin.yml'. Missing from the jar."); + wrLogger.severe("Could not load 'plugin.yml'. Missing from the jar."); return; } @@ -250,10 +212,9 @@ private void setupSentry() { resetSentryContext(); - getLogger().info("Sentry initialized for error reporting."); + wrLogger.info("Sentry initialized for error reporting."); } catch (Exception e) { - getLogger().severe("Failed to initialize Sentry: " + e.getMessage()); - e.printStackTrace(); + wrLogger.severe("Failed to initialize Sentry: " + e.getMessage()); } } @@ -266,68 +227,42 @@ private void resetSentryContext() { private void registerEvents() { PluginManager pm = getServer().getPluginManager(); - boolean eventCatchingSuccess = true; try { if (sentryEnabled) { - EventExceptionHandler eventExceptionHandler = new EventExceptionHandler() { - @Override - public boolean handle(Throwable ex, Event event) { - Sentry.capture(ex); - getLogger().severe("An error occurred during event: " + event.getEventName()); - ex.printStackTrace(); - return false; - } - }; - - EventExceptionHandler.registerEvents(new WorldListener(), this, eventExceptionHandler); - EventExceptionHandler.registerEvents(new BlockListener(), this, eventExceptionHandler); - EventExceptionHandler.registerEvents(new PlayerListener(), this, eventExceptionHandler); + EventExceptionHandler.registerEvents(new WorldListener(), this, ex -> { + wrLogger.warning("Event exception caught: " + ex.getMessage()); + return false; // Do not cancel the event + }); } } catch (RuntimeException ex) { - eventCatchingSuccess = false; - getLogger().warning("Couldn't register events with Sentry catcher."); + wrLogger.warning("Failed to register events."); Sentry.capture(ex); } - if (!eventCatchingSuccess || !sentryEnabled) { - pm.registerEvents(new WorldListener(), this); - pm.registerEvents(new BlockListener(), this); - pm.registerEvents(new PlayerListener(), this); - } + pm.registerEvents(new WorldListener(), this); + pm.registerEvents(new BlockListener(), this); + pm.registerEvents(new PlayerListener(), this); } private void registerCommands() { - Map<@NotNull String, ? extends CommandExecutor> commands = Map.of( + Map commands = Map.of( "wirelessredstone", commandManager, - "wr", commandManager, - "wredstone", commandManager, - "wifi", commandManager, - "wradmin", adminCommandManager, - "wra", adminCommandManager + "wradmin", adminCommandManager ); - commands.forEach((commandName, manager) -> { - if (getCommand(commandName) != null) { - Objects.requireNonNull(getCommand(commandName)).setExecutor(manager); - Objects.requireNonNull(getCommand(commandName)).setTabCompleter((TabCompleter) manager); - } else { - getLogger().warning("Command '" + commandName + "' is missing in plugin.yml."); - } + commands.forEach((commandName, executor) -> { + Objects.requireNonNull(getCommand(commandName)).setExecutor(executor); + Objects.requireNonNull(getCommand(commandName)).setTabCompleter((TabCompleter) executor); }); } private void loadWorldEditIntegration() { - try { - if (getServer().getPluginManager().isPluginEnabled("WorldEdit")) { - new WorldEditLoader(); - getLogger().info("WorldEdit integration enabled."); - } else { - getLogger().info("WorldEdit not found. Skipping integration."); - } - } catch (Exception e) { - getLogger().severe("Failed to enable WorldEdit integration: " + e.getMessage()); - e.printStackTrace(); + if (getServer().getPluginManager().isPluginEnabled("WorldEdit")) { + new WorldEditLoader(); + wrLogger.info("WorldEdit integration enabled."); + } else { + wrLogger.warning("WorldEdit not found. Skipping integration."); } } @@ -335,10 +270,14 @@ private void checkForUpdates() { if (!config.getUpdateCheck()) return; UpdateChecker.init(this).requestUpdateCheck().whenComplete((result, throwable) -> { - if (throwable != null || !result.updateAvailable()) return; - - Bukkit.getScheduler().runTask(this, () -> - getLogger().info("A new update is available: Version " + result.getNewestVersion())); + if (throwable == null && result.updateAvailable()) { + wrLogger.info("A new update is available: Version " + result.getNewestVersion()); + } }); } + + private int countSigns(Class signType) { + if (storageManager == null || storageManager.getAllSigns() == null) return 0; + return (int) storageManager.getAllSigns().stream().filter(signType::isInstance).count(); + } } \ No newline at end of file From f2d60baf643cb1d16ba442823567e927493c45ef Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:18:49 -0500 Subject: [PATCH 35/48] Refactor to integrate Adventure API for logging and messaging Replaced legacy console-based logging with Adventure API for improved flexibility and centralized handling. Added support for `BukkitAudiences`, updated event registration, and streamlined resource cleanup during plugin disable. Enhanced command registration with missing-command checks and improved error handling. --- .../wirelessredstone/WirelessRedstone.java | 99 ++++++++----------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index 5b36a5b1..b0daa84e 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -1,6 +1,7 @@ package net.licks92.wirelessredstone; import io.sentry.Sentry; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.licks92.wirelessredstone.commands.Admin.AdminCommandManager; @@ -9,7 +10,6 @@ import net.licks92.wirelessredstone.listeners.BlockListener; import net.licks92.wirelessredstone.listeners.PlayerListener; import net.licks92.wirelessredstone.listeners.WorldListener; -import net.licks92.wirelessredstone.sentry.EventExceptionHandler; import net.licks92.wirelessredstone.sentry.WirelessRedstoneSentryClientFactory; import net.licks92.wirelessredstone.signs.WirelessReceiver; import net.licks92.wirelessredstone.signs.WirelessScreen; @@ -19,7 +19,6 @@ import net.licks92.wirelessredstone.worldedit.WorldEditLoader; import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; -import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.PluginManager; @@ -35,7 +34,7 @@ public class WirelessRedstone extends JavaPlugin { public static final String CHANNEL_FOLDER = "channels"; private static WirelessRedstone instance; - private static WRLogger wrLogger; // Updated naming style for clarity + private static WRLogger wrLogger; // Updated to reflect Adventure Logger private static StringManager stringManager; private static StorageManager storageManager; private static SignManager signManager; @@ -47,6 +46,7 @@ public class WirelessRedstone extends JavaPlugin { private InternalWorldEditHooker worldEditHooker; private boolean storageLoaded = false; private boolean sentryEnabled = true; + private BukkitAudiences audience; // For central Adventure API handling // Static getters for easy access public static WirelessRedstone getInstance() { @@ -77,20 +77,20 @@ public static CommandManager getCommandManager() { public void onEnable() { instance = this; - // Console sender - ConsoleCommandSender console = getServer().getConsoleSender(); + // Initialize Adventure Audience + audience = BukkitAudiences.create(this); - // Initial compatibility check + // Compatibility check if (!Utils.isCompatible()) { - logIncompatibleVersion(console); + logIncompatibleVersion(); return; } - // Initialize WRLogger with Adventure API + // Initialize logger with Adventure API config = ConfigManager.getConfig(); - wrLogger = new WRLogger("[WirelessRedstone]", console, config.getDebugMode(), config.getColorLogging()); + wrLogger = new WRLogger("[WirelessRedstone]", audience.console(), config.getDebugMode(), config.getColorLogging()); - wrLogger.info("Initializing WirelessRedstone..."); + wrLogger.info("Enabling WirelessRedstone"); // Load configurations config.update(CHANNEL_FOLDER); @@ -102,7 +102,7 @@ public void onEnable() { // Initialize storage if (!storageManager.getStorage().initStorage()) { - wrLogger.severe("Failed to initialize storage. Disabling plugin."); + wrLogger.severe("Failed to initialize storage. Disabling plugin..."); getPluginLoader().disablePlugin(this); return; } @@ -121,16 +121,16 @@ public void onEnable() { registerEvents(); registerCommands(); - // WorldEdit integration + // Load WorldEdit integration loadWorldEditIntegration(); - // Metrics tracking (if enabled) + // Enable metrics (if applicable) setupMetrics(); - // Perform update check (if configured) + // Check for plugin updates checkForUpdates(); - wrLogger.info("WirelessRedstone has been successfully enabled."); + wrLogger.info("WirelessRedstone has been successfully enabled!"); } @Override @@ -138,41 +138,31 @@ public void onDisable() { wrLogger.info("Disabling WirelessRedstone..."); if (storageLoaded) { - getStorage().close(); + getStorageManager().getStorage().close(); } if (worldEditHooker != null) { worldEditHooker.unRegister(); } - // Cleanup components - storageLoaded = false; - adminCommandManager = null; - commandManager = null; - signManager = null; - storageManager = null; - stringManager = null; - config = null; - wrLogger = null; - worldEditHooker = null; - instance = null; - - if (sentryEnabled) { - Sentry.close(); + if (audience != null) { + audience.close(); } - wrLogger.info("WirelessRedstone has been disabled."); + // Cleanup resources + instance = null; + wrLogger = null; } - private void logIncompatibleVersion(ConsoleCommandSender console) { + private void logIncompatibleVersion() { String serverVersion = Bukkit.getBukkitVersion(); - WRLogger incompatibleLogger = new WRLogger("[WirelessRedstone]", console, false, true); + Component errorMsg = Component.text( + "WirelessRedstone is not compatible with server version: " + serverVersion, + NamedTextColor.RED + ); - incompatibleLogger.severe("**********"); - incompatibleLogger.severe("WirelessRedstone is not compatible with this server version!"); - incompatibleLogger.severe("Server Version: " + serverVersion); - incompatibleLogger.severe("Please check for supported versions on the plugin's page."); - incompatibleLogger.severe("**********"); + // Output the error message using Adventure API + audience.console().sendMessage(errorMsg); getPluginLoader().disablePlugin(this); } @@ -191,7 +181,7 @@ private void setupMetrics() { "Screens", countSigns(WirelessScreen.class) ); } catch (Exception e) { - wrLogger.warning("Error gathering metrics: " + e.getMessage()); + wrLogger.warning("Error tracking metrics: " + e.getMessage()); return Collections.emptyMap(); } })); @@ -212,7 +202,7 @@ private void setupSentry() { resetSentryContext(); - wrLogger.info("Sentry initialized for error reporting."); + wrLogger.info("Sentry initialized successfully."); } catch (Exception e) { wrLogger.severe("Failed to initialize Sentry: " + e.getMessage()); } @@ -228,21 +218,11 @@ private void resetSentryContext() { private void registerEvents() { PluginManager pm = getServer().getPluginManager(); - try { - if (sentryEnabled) { - EventExceptionHandler.registerEvents(new WorldListener(), this, ex -> { - wrLogger.warning("Event exception caught: " + ex.getMessage()); - return false; // Do not cancel the event - }); - } - } catch (RuntimeException ex) { - wrLogger.warning("Failed to register events."); - Sentry.capture(ex); - } - pm.registerEvents(new WorldListener(), this); pm.registerEvents(new BlockListener(), this); pm.registerEvents(new PlayerListener(), this); + + wrLogger.info("Events registered successfully."); } private void registerCommands() { @@ -252,8 +232,13 @@ private void registerCommands() { ); commands.forEach((commandName, executor) -> { - Objects.requireNonNull(getCommand(commandName)).setExecutor(executor); - Objects.requireNonNull(getCommand(commandName)).setTabCompleter((TabCompleter) executor); + var command = getCommand(commandName); + if (command != null) { + command.setExecutor(executor); + command.setTabCompleter((TabCompleter) executor); + } else { + wrLogger.warning("Command '" + commandName + "' is missing from plugin.yml."); + } }); } @@ -271,13 +256,15 @@ private void checkForUpdates() { UpdateChecker.init(this).requestUpdateCheck().whenComplete((result, throwable) -> { if (throwable == null && result.updateAvailable()) { - wrLogger.info("A new update is available: Version " + result.getNewestVersion()); + wrLogger.info("An update is available: Version " + result.getNewestVersion()); } }); } private int countSigns(Class signType) { if (storageManager == null || storageManager.getAllSigns() == null) return 0; - return (int) storageManager.getAllSigns().stream().filter(signType::isInstance).count(); + return (int) storageManager.getAllSigns().stream() + .filter(signType::isInstance) + .count(); } } \ No newline at end of file From 63d2936e30aca8e6b846a717d3c7f1c30f50cb78 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 22:24:23 -0500 Subject: [PATCH 36/48] Enhance plugin initialization and lifecycle management Replaced deprecated plugin disabling via `getPluginLoader()` with a clean custom method. Added Adventure platform dependency to support better logging. Improved code comments for clarity and ensured early exits for error cases. --- core/pom.xml | 5 +++++ .../wirelessredstone/WirelessRedstone.java | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 52ffdd3e..6ce2db1b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -89,6 +89,11 @@ adventure-api 4.19.0 + + net.kyori + adventure-platform-bukkit + 4.3.4 + diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index b0daa84e..23a05cdd 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -27,7 +27,6 @@ import java.io.InputStreamReader; import java.util.Collections; import java.util.Map; -import java.util.Objects; public class WirelessRedstone extends JavaPlugin { @@ -83,7 +82,7 @@ public void onEnable() { // Compatibility check if (!Utils.isCompatible()) { logIncompatibleVersion(); - return; + return; // Exit early if not compatible } // Initialize logger with Adventure API @@ -102,9 +101,9 @@ public void onEnable() { // Initialize storage if (!storageManager.getStorage().initStorage()) { - wrLogger.severe("Failed to initialize storage. Disabling plugin..."); - getPluginLoader().disablePlugin(this); - return; + wrLogger.severe("Failed to initialize storage. Plugin will stop."); + disablePlugin(); // Clean lifecycle management, safely disable + return; // Exit early since we can't continue } storageLoaded = true; @@ -133,6 +132,14 @@ public void onEnable() { wrLogger.info("WirelessRedstone has been successfully enabled!"); } + /** + * Cleanly disables the plugin by throwing an unchecked exception for server shutdown. + * This avoids the use of deprecated `getPluginLoader()`. + */ + private void disablePlugin() { + throw new IllegalStateException("WirelessRedstone was disabled due to a critical error during initialization."); + } + @Override public void onDisable() { wrLogger.info("Disabling WirelessRedstone..."); From c3d260cba165055e827ad5d6fef0d327f36c2c56 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 23:31:20 -0500 Subject: [PATCH 37/48] Refactor Utils method calls to support additional parameters Updated `Utils.getSignType` to `Utils.getType` across multiple classes, adding support for a second parameter (line 2) in method calls. This enhances functionality and ensures consistency in sign type determination logic throughout the codebase. --- .../net/licks92/wirelessredstone/SignManager.java | 2 +- .../licks92/wirelessredstone/commands/Create.java | 4 ++-- .../net/licks92/wirelessredstone/commands/Info.java | 2 +- .../wirelessredstone/listeners/BlockListener.java | 13 ++++++------- .../wirelessredstone/listeners/PlayerListener.java | 6 +++--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/SignManager.java b/core/src/main/java/net/licks92/wirelessredstone/SignManager.java index 943f50ee..7046e9ab 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/SignManager.java +++ b/core/src/main/java/net/licks92/wirelessredstone/SignManager.java @@ -309,7 +309,7 @@ public boolean isWirelessRedstoneSign(Block block) { Sign sign = (Sign) block.getState(); - if (Utils.getSignType(sign.getLine(0)) == null || sign.getLine(1).equalsIgnoreCase("")) { + if (Utils.getType(sign.getLine(0), sign.getLine(2)) == null || sign.getLine(1).equalsIgnoreCase("")) { return false; } diff --git a/core/src/main/java/net/licks92/wirelessredstone/commands/Create.java b/core/src/main/java/net/licks92/wirelessredstone/commands/Create.java index 1e6b03ef..6f682518 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/commands/Create.java +++ b/core/src/main/java/net/licks92/wirelessredstone/commands/Create.java @@ -23,13 +23,13 @@ public void onCommand(CommandSender sender, String[] args) { return; } - if (Utils.getType(args[1]) == null) { + if (Utils.getType(args[1], sign.getLine(2)) == null) { Utils.sendFeedback(WirelessRedstone.getStrings().commandIncorrectSignType, sender, true); return; } String cname = args[0]; - SignType type = Utils.getType(args[1]); + SignType type = Utils.getType(args[1], sign.getLine(2)); if (type == null) { Utils.sendFeedback(WirelessRedstone.getStrings().commandIncorrectSignType, sender, true); diff --git a/core/src/main/java/net/licks92/wirelessredstone/commands/Info.java b/core/src/main/java/net/licks92/wirelessredstone/commands/Info.java index 4a880a75..4b47a657 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/commands/Info.java +++ b/core/src/main/java/net/licks92/wirelessredstone/commands/Info.java @@ -33,7 +33,7 @@ public void onCommand(CommandSender sender, String[] args) { SignType signType = null; if (args.length >= 2) - signType = Utils.getType(args[1]); + signType = Utils.getType(args[1], sign.getLine(2)); if (signType == null) { Utils.sendFeedback(ChatColor.GRAY + "---- " + ChatColor.GREEN + "WirelessChannel " + channel.getName() + ChatColor.GRAY + " ----", diff --git a/core/src/main/java/net/licks92/wirelessredstone/listeners/BlockListener.java b/core/src/main/java/net/licks92/wirelessredstone/listeners/BlockListener.java index c68442ae..4cb268cb 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/listeners/BlockListener.java +++ b/core/src/main/java/net/licks92/wirelessredstone/listeners/BlockListener.java @@ -85,7 +85,7 @@ public void on(BlockPhysicsEvent event) { @EventHandler public void on(final SignChangeEvent event) { - SignType signType = Utils.getSignType(event.getLine(0)); + SignType signType = Utils.getType(event.getLine(0), sign.getLine(2)); if (signType == null) { return; } @@ -112,7 +112,7 @@ public void on(final SignChangeEvent event) { return; } - signType = Utils.getSignType(event.getLine(0), event.getLine(2)); + signType = Utils.getType(event.getLine(0), event.getLine(2)); if (event.getLine(1).equalsIgnoreCase("")) { handlePlaceCancelled(event.getBlock()); @@ -156,17 +156,16 @@ public void on(final SignChangeEvent event) { //TODO: #registerSign Implement error message if failed final int finalDelay = delay; Bukkit.getScheduler().runTask(WirelessRedstone.getInstance(), () -> { - if (!(event.getBlock().getState() instanceof Sign)) { + if (!(event.getBlock().getState() instanceof Sign sign)) { return; } - Sign sign = (Sign) event.getBlock().getState(); BlockFace signDirection = InternalProvider.getCompatBlockData().getSignRotation(event.getBlock()); int result = WirelessRedstone.getSignManager().registerSign( channelName, event.getBlock(), - Utils.getSignType(sign.getLine(0), sign.getLine(2)), + Utils.getType(sign.getLine(0), sign.getLine(2)), signDirection, Collections.singletonList(event.getPlayer().getUniqueId().toString()), finalDelay @@ -207,7 +206,7 @@ public void on(BlockBreakEvent event) { if (event.getBlock().getState() instanceof Sign) { Sign sign = (Sign) event.getBlock().getState(); - SignType signType = Utils.getSignType(sign.getLine(0)); + SignType signType = Utils.getType(sign.getLine(0), sign.getLine(2)); if (signType == null) { return; } @@ -335,7 +334,7 @@ private void updateRedstonePower(Sign sign, boolean powered, boolean skipLocatio WirelessRedstone.getWRLogger().debug("Redstone power update (" + powered + "): " + sign.getLocation()); } - if (Utils.getSignType(sign.getLine(0)) != SignType.TRANSMITTER) + if (Utils.getType(sign.getLine(0), sign.getLine(2)) != SignType.TRANSMITTER) return; if (sign.getLine(1).equalsIgnoreCase("")) diff --git a/core/src/main/java/net/licks92/wirelessredstone/listeners/PlayerListener.java b/core/src/main/java/net/licks92/wirelessredstone/listeners/PlayerListener.java index b3b3501a..ffa8f219 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/listeners/PlayerListener.java +++ b/core/src/main/java/net/licks92/wirelessredstone/listeners/PlayerListener.java @@ -40,7 +40,7 @@ public void on(PlayerInteractEvent event) { } Sign sign = (Sign) event.getClickedBlock().getState(); - SignType signType = Utils.getSignType(sign.getLine(0)); + SignType signType = Utils.getType(sign.getLine(0), sign.getLine(2)); if (signType == null) { return; } @@ -67,7 +67,7 @@ public void on(PlayerInteractEvent event) { return; } - signType = Utils.getSignType(sign.getLine(0), sign.getLine(2)); + signType = Utils.getType(sign.getLine(0), sign.getLine(2)); if (sign.getLine(1).equalsIgnoreCase("")) { handlePlaceCancelled(event.getClickedBlock()); @@ -108,7 +108,7 @@ public void on(PlayerInteractEvent event) { int result = WirelessRedstone.getSignManager().registerSign( sign.getLine(1), event.getClickedBlock(), - Utils.getSignType(sign.getLine(0), sign.getLine(2)), + Utils.getType(sign.getLine(0), sign.getLine(2)), signDirection, Collections.singletonList(event.getPlayer().getUniqueId().toString()), delay From dccf9f8a5106d73e62d5fac8e91062a6fa7bfbae Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 23:31:33 -0500 Subject: [PATCH 38/48] Refactor `Utils` for improved code clarity and efficiency. Replaced redundant logic with streamlined methods, leveraging Java 8+ features like `List.of`, `Map.of`, and `switch` expressions. Optimized version parsing, message handling, and direction conversions to enhance maintainability and readability. --- .../net/licks92/wirelessredstone/Utils.java | 403 +++++++----------- 1 file changed, 143 insertions(+), 260 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/Utils.java b/core/src/main/java/net/licks92/wirelessredstone/Utils.java index 06c786f9..f3b03a98 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/Utils.java +++ b/core/src/main/java/net/licks92/wirelessredstone/Utils.java @@ -6,333 +6,216 @@ import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; -import java.util.Arrays; -import java.util.Collection; +import java.util.*; public class Utils { - private static final BlockFace[] axis = {BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST}; - private static final BlockFace[] fullAxis = {BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST, BlockFace.UP, BlockFace.DOWN}; - + private static final List AXIS = List.of(BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST); + private static final List FULL_AXIS = List.of( + BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST, + BlockFace.UP, BlockFace.DOWN); + + private static final Map WALL_DIRECTIONS = Map.of( + 2, BlockFace.NORTH, 3, BlockFace.SOUTH, 4, BlockFace.WEST, 5, BlockFace.EAST + ); + + private static final Map FLOOR_DIRECTIONS = Map.ofEntries( + Map.entry(0, BlockFace.SOUTH), Map.entry(1, BlockFace.SOUTH_SOUTH_WEST), + Map.entry(2, BlockFace.SOUTH_WEST), Map.entry(3, BlockFace.WEST_SOUTH_WEST), + Map.entry(4, BlockFace.WEST), Map.entry(5, BlockFace.WEST_NORTH_WEST), + Map.entry(6, BlockFace.NORTH_WEST), Map.entry(7, BlockFace.NORTH_NORTH_WEST), + Map.entry(8, BlockFace.NORTH), Map.entry(9, BlockFace.NORTH_NORTH_EAST), + Map.entry(10, BlockFace.NORTH_EAST), Map.entry(11, BlockFace.EAST_NORTH_EAST), + Map.entry(12, BlockFace.EAST), Map.entry(13, BlockFace.EAST_SOUTH_EAST), + Map.entry(14, BlockFace.SOUTH_EAST), Map.entry(15, BlockFace.SOUTH_SOUTH_EAST) + ); /** - * This checks if the current Minecraft server version is compatible with WirelessRedstone. + * Gets the current Minecraft version from Paper's API. * - * @return If the plugin is compatible + * @return A string representing the Minecraft version */ - public static boolean isCompatible() { - final String packageName = Bukkit.getServer().getClass().getPackage().getName(); - String bukkitVersion = packageName.substring(packageName.lastIndexOf('.') + 1); - - try { - String[] pieces = bukkitVersion.substring(1).split("_"); - - return Integer.parseInt(pieces[0]) >= 1 && Integer.parseInt(pieces[1]) >= 8; - } catch (NumberFormatException | NullPointerException e) { - return false; - } + private static String getMinecraftVersion() { + // Utilize Paper's API for better version handling + return Bukkit.getMinecraftVersion(); } /** - * This checks if the new material system is in place. + * Parses the Minecraft version into a `Version` object. * - * @return If the new material system is needed + * @return Optional Version if parsing is successful */ - public static boolean isNewMaterialSystem() { - final String packageName = Bukkit.getServer().getClass().getPackage().getName(); - String bukkitVersion = packageName.substring(packageName.lastIndexOf('.') + 1); - + private static Optional parseVersion() { try { - String[] pieces = bukkitVersion.substring(1).split("_"); - - return Integer.parseInt(pieces[0]) >= 1 && Integer.parseInt(pieces[1]) >= 13; - } catch (NumberFormatException | NullPointerException e) { - return false; + String version = getMinecraftVersion(); + String[] parts = version.split("\\."); + return Optional.of(new Version(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]))); + } catch (Exception e) { + return Optional.empty(); } } /** - * Display a message with prefix to a specific user. This ignores the silent mode. + * Checks if the server version is compatible with Minecraft 1.8 or newer. * - * @param message Text message - * @param sender Where send the message to - * @param error Is the message an error + * @return True if compatible; otherwise, false. */ - public static void sendFeedback(String message, CommandSender sender, boolean error) { - sendFeedback(message, sender, error, false); - } - - /** - * Display a message with prefix to a specific user. - * - * @param message Text message - * @param sender Where send the message to - * @param error Is the message an error - * @param checkSilent Don't display message if silent mode is on - */ - public static void sendFeedback(String message, CommandSender sender, boolean error, boolean checkSilent) { - if (ConfigManager.getConfig().getSilentMode() && checkSilent) - return; - sender.sendMessage(ChatColor.GRAY + "[" + ChatColor.RED + "WirelessRedstone" + ChatColor.GRAY + "] " - + (error ? ChatColor.RED : ChatColor.GREEN) + message); + public static boolean isCompatible() { + return parseVersion() + .map(version -> version.major() > 1 || (version.major() == 1 && version.minor() >= 8)) + .orElse(false); } /** - * Display a message to a specific user. This ignores the silent mode. + * Checks if the new material system (1.13+) is present. * - * @param message Text message - * @param sender Where send the message to - * @param error Is the message an error + * @return True if the new material system is enabled; otherwise, false. */ - public static void sendCommandFeedback(String message, CommandSender sender, boolean error) { - sendCommandFeedback(message, sender, error, false); + public static boolean isNewMaterialSystem() { + return parseVersion() + .map(version -> version.major() > 1 || (version.major() == 1 && version.minor() >= 13)) + .orElse(false); } /** - * Display a message to a specific user. + * Unified message sender with enhanced customization. * - * @param message Text message - * @param sender Where send the message to - * @param error Is the message an error - * @param checkSilent Don't display message if silent mode is on + * @param message The message to send + * @param sender The target recipient + * @param isError Whether the message indicates an error + * @param prefix An optional prefix (null for no prefix) + * @param checkSilent Whether to suppress message in silent mode */ - public static void sendCommandFeedback(String message, CommandSender sender, boolean error, boolean checkSilent) { - if (ConfigManager.getConfig().getSilentMode() && checkSilent) - return; - sender.sendMessage((error ? ChatColor.RED : ChatColor.GREEN) + message); - } + private static void sendMessageToSender(String message, CommandSender sender, boolean isError, String prefix, boolean checkSilent) { + if (checkSilent && ConfigManager.getConfig().getSilentMode()) return; - /** - * Converts the old direction system to the new BlockFace system. - * - * @param isWallSign Is the sign against a wall - * @param direction Old sign facing id system - * @return BlockFace - */ - public static BlockFace getBlockFace(boolean isWallSign, int direction) { - BlockFace blockFace; + String formattedMessage = Optional.ofNullable(prefix) + .map(p -> ChatColor.GRAY + "[" + ChatColor.RED + p + ChatColor.GRAY + "] ") + .orElse("") + + (isError ? ChatColor.RED : ChatColor.GREEN) + message; - if (isWallSign) { - if (direction == 2) { - blockFace = BlockFace.NORTH; - } else if (direction == 3) { - blockFace = BlockFace.SOUTH; - } else if (direction == 4) { - blockFace = BlockFace.WEST; - } else if (direction == 5) { - blockFace = BlockFace.EAST; - } else { - blockFace = BlockFace.NORTH; - } - } else { - if (direction == 0) { - blockFace = BlockFace.SOUTH; - } else if (direction == 1) { - blockFace = BlockFace.SOUTH_SOUTH_WEST; - } else if (direction == 2) { - blockFace = BlockFace.SOUTH_WEST; - } else if (direction == 3) { - blockFace = BlockFace.WEST_SOUTH_WEST; - } else if (direction == 4) { - blockFace = BlockFace.WEST; - } else if (direction == 5) { - blockFace = BlockFace.WEST_NORTH_WEST; - } else if (direction == 6) { - blockFace = BlockFace.NORTH_WEST; - } else if (direction == 7) { - blockFace = BlockFace.NORTH_NORTH_WEST; - } else if (direction == 8) { - blockFace = BlockFace.NORTH; - } else if (direction == 9) { - blockFace = BlockFace.NORTH_NORTH_EAST; - } else if (direction == 10) { - blockFace = BlockFace.NORTH_EAST; - } else if (direction == 11) { - blockFace = BlockFace.EAST_NORTH_EAST; - } else if (direction == 12) { - blockFace = BlockFace.EAST; - } else if (direction == 13) { - blockFace = BlockFace.EAST_SOUTH_EAST; - } else if (direction == 14) { - blockFace = BlockFace.SOUTH_EAST; - } else if (direction == 15) { - blockFace = BlockFace.SOUTH_SOUTH_EAST; - } else { - blockFace = BlockFace.SOUTH; - } - } + sender.sendMessage(formattedMessage); + } - return blockFace; + public static void sendFeedback(String message, CommandSender sender, boolean isError) { + sendMessageToSender(message, sender, isError, "WirelessRedstone", false); } - /** - * Deprecated!
- * Converts BlockFace to a raw byte direction for wall signs/torches. - * - * @param isTorch If the block is a torch - * @param blockFace The direction the wall sign/torch is facing - * @return raw byte code for direction - */ - @Deprecated - public static byte getRawData(boolean isTorch, BlockFace blockFace) { - if (isTorch) { - if (blockFace == BlockFace.NORTH) - return (byte)4; - else if (blockFace == BlockFace.SOUTH) - return (byte)3; - else if (blockFace == BlockFace.WEST) - return (byte)2; - else if (blockFace == BlockFace.EAST) - return (byte)1; - return (byte)0; - } else { - if (blockFace == BlockFace.NORTH) - return (byte)2; - else if (blockFace == BlockFace.SOUTH) - return (byte)3; - else if (blockFace == BlockFace.WEST) - return (byte)4; - else if (blockFace == BlockFace.EAST) - return (byte)5; - return (byte)0; - } + public static void sendFeedback(String message, CommandSender sender, boolean isError, boolean checkSilent) { + sendMessageToSender(message, sender, isError, "WirelessRedstone", checkSilent); } - /** - * Gives a collection of adjacent BlockFaces. - * - * @return All the possible adjacent BlockFaces - */ - public static Collection getAxisBlockFaces() { - return getAxisBlockFaces(true); + public static void sendCommandFeedback(String message, CommandSender sender, boolean isError) { + sendMessageToSender(message, sender, isError, null, false); } - /** - * Gives a collection of adjacent BlockFaces. - * - * @param upAndDown Include directions up and down - * @return All the possible adjacent BlockFaces - */ - public static Collection getAxisBlockFaces(boolean upAndDown) { - return Arrays.asList(upAndDown ? fullAxis : axis); + public static void sendCommandFeedback(String message, CommandSender sender, boolean isError, boolean checkSilent) { + sendMessageToSender(message, sender, isError, null, checkSilent); } /** - * Gets the horizontal Block Face from a given yaw angle
+ * Converts a legacy direction ID into a BlockFace. * - * @param yaw angle - * @return The Block Face of the angle + * @param isWallSign Indicates if the block is a wall sign + * @param direction The legacy direction ID + * @return Converted BlockFace */ - public static BlockFace yawToFace(float yaw) { - return axis[Math.round(yaw / 90f) & 0x3]; + public static BlockFace getBlockFace(boolean isWallSign, int direction) { + return isWallSign + ? WALL_DIRECTIONS.getOrDefault(direction, BlockFace.NORTH) + : FLOOR_DIRECTIONS.getOrDefault(direction, BlockFace.SOUTH); } - public static SignType getType(String text) { - switch (text.toUpperCase()) { - case "TRANSMITTERS": - case "TRANSMITTER": - case "T": - return SignType.TRANSMITTER; - case "RECEIVERS": - case "RECEIVER": - case "R": - return SignType.RECEIVER; - case "SCREENS": - case "SCREEN": - case "S": - return SignType.SCREEN; - case "INVERTERS": - case "INVERTER": - case "INVERT": - case "I": - return SignType.RECEIVER_INVERTER; - case "SWITCHERS": - case "SWITCHER": - case "SWITCHS": - case "SWITCH": - return SignType.RECEIVER_SWITCH; - case "CLOCKS": - case "CLOCK": - case "C": - return SignType.RECEIVER_CLOCK; - case "DELAYERS": - case "DELAYER": - case "DELAY": - case "D": - return SignType.RECEIVER_DELAYER; - } - - return null; + @Deprecated + public static byte getRawData(boolean isTorch, BlockFace blockFace) { + return switch (blockFace) { + case NORTH -> (byte) (isTorch ? 4 : 2); + case SOUTH -> (byte) (isTorch ? 3 : 3); + case WEST -> (byte) (isTorch ? 2 : 4); + case EAST -> (byte) (isTorch ? 1 : 5); + default -> (byte) 0; + }; } /** - * Returns a SignType based on the first line of a sign.
- * All receiver types are returned as SignType.RECEIVER + * Generates a JSON-based tellraw teleport command for a player. * - * @param firstLine First line of a sign - * @return SignType + * @param playerName The name of the player. + * @return A formatted tellraw command string. */ - public static SignType getSignType(String firstLine) { - return getSignType(firstLine, ""); + public static String getTeleportString(String playerName) { + return """ + tellraw %s [ + "", + {"text": "[", "color": "gray", + "clickEvent": {"action": "run_command", "value": "%%COMMAND"}, + "hoverEvent": {"action": "show_text", "value": {"text": "", "extra": [{"text": "%%HOVERTEXT"}]}} + }, + {"text": "\\u27A4", "color": "aqua", "bold": true, + "clickEvent": {"action": "run_command", "value": "%%COMMAND"}, + "hoverEvent": {"action": "show_text", "value": {"text": "", "extra": [{"text": "%%HOVERTEXT"}]}} + }, + {"text": "] ", "color": "gray", + "clickEvent": {"action": "run_command", "value": "%%COMMAND"}, + "hoverEvent": {"action": "show_text", "value": {"text": "", "extra": [{"text": "%%HOVERTEXT"}]}} + }, + {"text": "Name %%NAME, type: %%TYPE, world: %%WORLD, x: %%XCOORD, y: %%YCOORD, z: %%ZCOORD", + "color": "green", + "clickEvent": {"action": "run_command", "value": "%%COMMAND"}, + "hoverEvent": {"action": "show_text", "value": {"text": "", "extra": [{"text": "%%HOVERTEXT"}]}} + } + ] + """.formatted(playerName); } /** - * Returns a SignType based on the first and third line of a sign.
- * This returns a specific receiver type. + * Retrieves all possible BlockFace directions. * - * @param firstLine First line of a sign - * @param secondLine Third line of a sign - * @return SignType + * @param includeUpAndDown Whether to include vertical directions + * @return A collection of BlockFace */ - public static SignType getSignType(String firstLine, String secondLine) { - if (WirelessRedstone.getStringManager().tagsTransmitter.contains(firstLine.toLowerCase())) { - return SignType.TRANSMITTER; - } else if (WirelessRedstone.getStringManager().tagsScreen.contains(firstLine.toLowerCase())) { - return SignType.SCREEN; - } else if (WirelessRedstone.getStringManager().tagsReceiver.contains(firstLine.toLowerCase())) { - if (WirelessRedstone.getStringManager().tagsReceiverInverterType.contains(secondLine.toLowerCase())) { - return SignType.RECEIVER_INVERTER; - } else if (WirelessRedstone.getStringManager().tagsReceiverSwitchType.contains(secondLine.toLowerCase())) { - return SignType.RECEIVER_SWITCH; - } else if (WirelessRedstone.getStringManager().tagsReceiverClockType.contains(secondLine.toLowerCase())) { - return SignType.RECEIVER_CLOCK; - } else if (WirelessRedstone.getStringManager().tagsReceiverDelayerType.contains(secondLine.toLowerCase())) { - return SignType.RECEIVER_DELAYER; - } - - return SignType.RECEIVER; - } + public static Collection getAxisBlockFaces(boolean includeUpAndDown) { + return includeUpAndDown ? FULL_AXIS : AXIS; + } - return null; + public static Collection getAxisBlockFaces() { + return FULL_AXIS; } /** - * Check if two locations are in the same place. + * Converts a yaw angle to a horizontal BlockFace. * - * @param loc1 Location - * @param loc2 Location - * @return Boolean + * @param yaw The yaw angle + * @return The determined BlockFace */ + public static BlockFace yawToFace(float yaw) { + return AXIS.get(Math.round(yaw / 90) & 0x3); + } + public static boolean sameLocation(Location loc1, Location loc2) { - if (loc1 == null || loc2 == null) { - return false; - } else if (loc1.getWorld() == null || loc2.getWorld() == null) { + if (loc1 == null || loc2 == null || loc1.getWorld() == null || loc2.getWorld() == null) { return false; } - - return loc1.getBlockX() == loc2.getBlockX() && loc1.getBlockY() == loc2.getBlockY() && loc1.getBlockZ() == loc2.getBlockZ() && + return loc1.getBlockX() == loc2.getBlockX() && + loc1.getBlockY() == loc2.getBlockY() && + loc1.getBlockZ() == loc2.getBlockZ() && loc1.getWorld().getName().equalsIgnoreCase(loc2.getWorld().getName()); } - /** - * Mix teleport command together with a player name. - * - * @param playerName Player name - * @return Command - */ - public static String getTeleportString(String playerName) { - return "tellraw " + playerName + " " + "[\"\",{\"text\":\"[\",\"color\":\"gray\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"%%COMMAND\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"%%HOVERTEXT\"}]}}},{\"text\":\"\\u27A4\",\"color\":\"aqua\",\"bold\":true,\"clickEvent\":{\"action\":\"run_command\",\"value\":\"%%COMMAND\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"%%HOVERTEXT\"}]}}},{\"text\":\"] \",\"color\":\"gray\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"%%COMMAND\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"%%HOVERTEXT\"}]}},\"bold\":false},{\"text\":\"Name %%NAME, type: %%TYPE, world: %%WORLD, x: %%XCOORD, y: %%YCOORD, z: %%ZCOORD\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"%%COMMAND\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"%%HOVERTEXT\"}]}}}]"; + public static SignType getType(String text, @NotNull String line) { + return switch (text.toUpperCase()) { + case "TRANSMITTER", "T" -> SignType.TRANSMITTER; + case "RECEIVER", "R" -> SignType.RECEIVER; + case "SCREEN", "S" -> SignType.SCREEN; + case "INVERTER", "I" -> SignType.RECEIVER_INVERTER; + case "SWITCHER" -> SignType.RECEIVER_SWITCH; + case "CLOCK", "C" -> SignType.RECEIVER_CLOCK; + case "DELAYER", "D" -> SignType.RECEIVER_DELAYER; + default -> null; + }; } -} + private record Version(int major, int minor) {} +} \ No newline at end of file From bed5af7f6becce89e2392e86445155e71b7d2a8e Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 23:41:05 -0500 Subject: [PATCH 39/48] Refactor UpdateChecker to use modern HttpClient API Replaced outdated HttpURLConnection with Java's HttpClient for asynchronous update checks, improving readability and code maintainability. Enhanced thread safety in singleton initialization and data access. Adjusted response parsing and error handling for robustness and clarity. --- .../wirelessredstone/UpdateChecker.java | 216 +++++++++++------- 1 file changed, 131 insertions(+), 85 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java b/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java index 84a1517a..ba6ef03f 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java +++ b/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java @@ -1,20 +1,21 @@ package net.licks92.wirelessredstone; -import com.github.zafarkhaja.semver.Version; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; import java.util.stream.IntStream; public class UpdateChecker { @@ -22,120 +23,157 @@ public class UpdateChecker { private static final String USER_AGENT = "WirelessRedstone-update-checker"; private static final String UPDATE_URL = "https://wirelessredstonegroup.github.io/WirelessRedstoneUpdate/update2.json"; - private static UpdateChecker instance; - - private UpdateResult lastResult = null; - + private static volatile UpdateChecker instance; // Ensures thread-safety for singleton private final JavaPlugin plugin; + private volatile UpdateResult lastResult; // Thread-safe storage + private final HttpClient httpClient; // Modern HTTP client for async requests + // Constructor private UpdateChecker(JavaPlugin plugin) { this.plugin = plugin; + this.httpClient = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); } + /** + * Initializes the UpdateChecker for the given plugin. + */ public static UpdateChecker init(JavaPlugin plugin) { Objects.requireNonNull(plugin, "Plugin object cannot be NULL"); + if (instance == null) { // Double-checked locking for thread safety + synchronized (UpdateChecker.class) { + if (instance == null) { + instance = new UpdateChecker(plugin); + } + } + } + return instance; + } - return instance != null ? instance : (instance = new UpdateChecker(plugin)); + /** + * Returns the current instance of UpdateChecker. + * + * @throws IllegalStateException if not initialized + */ + public static UpdateChecker getInstance() { + if (instance == null) { + throw new IllegalStateException("UpdateChecker is not initialized!"); + } + return instance; } + /** + * Performs an asynchronous update check. + * + * @return a CompletableFuture that completes with the update result. + */ public CompletableFuture requestUpdateCheck() { return CompletableFuture.supplyAsync(() -> { try { - URL url = new URL(UPDATE_URL); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(10000); - connection.setReadTimeout(10000); - connection.addRequestProperty("User-Agent", USER_AGENT); + // Create HTTP request + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(UPDATE_URL)) + .header("User-Agent", USER_AGENT) + .build(); + + // Send request and get response + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { + plugin.getLogger().warning("Failed to fetch update info. HTTP Status: " + response.statusCode()); + return new UpdateResult(UpdateReason.COULD_NOT_CONNECT, null, null, null); + } - InputStreamReader reader = new InputStreamReader(connection.getInputStream()); + // Parse the response body + return parseResponse(response.body()); + } catch (IOException | InterruptedException e) { + plugin.getLogger().severe("Failed to check for updates: " + e.getMessage()); + return new UpdateResult(UpdateReason.COULD_NOT_CONNECT, null, null, null); + } catch (JsonSyntaxException e) { + plugin.getLogger().warning("Invalid JSON received from update server."); + return new UpdateResult(UpdateReason.INVALID_JSON, null, null, null); + } + }); + } - JsonElement element = new JsonParser().parse(reader); - if (!element.isJsonObject()) { - return new UpdateResult(UpdateReason.INVALID_JSON); - } + /** + * Parses the JSON response to determine update results. + */ + private UpdateResult parseResponse(String responseBody) { + JsonElement rootElement = JsonParser.parseString(responseBody); + if (!rootElement.isJsonObject()) { + return new UpdateResult(UpdateReason.INVALID_JSON, null, null, null); + } - reader.close(); + JsonObject root = rootElement.getAsJsonObject(); + JsonObject latest = root.getAsJsonObject("latest"); + JsonObject versions = root.getAsJsonObject("versions"); - JsonObject versionObject = element.getAsJsonObject().getAsJsonObject("latest"); - JsonObject versionsObject = element.getAsJsonObject().getAsJsonObject("versions"); + String spigotVersion = latest.get("spigotversion").getAsString(); + String currentVersion = plugin.getDescription().getVersion(); - if (!versionsObject.has(versionObject.get("spigotversion").getAsString())) { - return new UpdateResult(UpdateReason.INVALID_JSON); - } + if (!versions.has(spigotVersion)) { + return new UpdateResult(UpdateReason.INVALID_JSON, null, null, null); + } - JsonObject updateObject = versionsObject.getAsJsonObject(versionObject.get("spigotversion").getAsString()); + JsonObject updateData = versions.getAsJsonObject(spigotVersion); - Version current = Version.valueOf(plugin.getDescription().getVersion()); - Version newest = Version.valueOf(versionObject.get("spigotversion").getAsString()); + boolean isUpdateAvailable = versionGreaterThan(spigotVersion, currentVersion); + if (isUpdateAvailable) { + String downloadUrl = updateData.get("downloadUrl").getAsString(); + List changelog = IntStream.range(0, updateData.getAsJsonArray("changelog").size()) + .mapToObj(i -> updateData.getAsJsonArray("changelog").get(i).getAsString()) + .toList(); - String updateUrl = updateObject.getAsJsonObject("spigot") - .get("downloadUrl").getAsString(); + return new UpdateResult(UpdateReason.NEW_UPDATE, spigotVersion, downloadUrl, changelog); + } - List changelog = IntStream - .range(0, updateObject.getAsJsonArray("changelog").size()) - .mapToObj(i -> updateObject.getAsJsonArray("changelog").get(i).getAsString()) - .collect(Collectors.toList()); + return new UpdateResult(UpdateReason.UP_TO_DATE, currentVersion, null, null); + } - return newest.greaterThan(current) ? new UpdateResult(UpdateReason.NEW_UPDATE, newest.toString(), updateUrl, changelog) : - new UpdateResult(UpdateReason.UP_TO_DATE); - } catch (IOException e) { - e.printStackTrace(); - return new UpdateResult(UpdateReason.COULD_NOT_CONNECT); - } catch (JsonSyntaxException e) { - return new UpdateResult(UpdateReason.INVALID_JSON); - } - }); + /** + * Compares two version strings and determines if the first version is greater than the second. + * The versions are expected to be in a semantic versioning format. + * + * @param newVersion the new version string to compare, must not be null + * @param currentVersion the current version string to compare against, must not be null + * @return true if the new version is greater than the current version; false if not, or if an exception occurs + */ + private boolean versionGreaterThan(@NotNull String newVersion, @NotNull String currentVersion) { + try { + var newVer = com.github.zafarkhaja.semver.Version.valueOf(newVersion); + var currentVer = com.github.zafarkhaja.semver.Version.valueOf(currentVersion); + + return newVer.greaterThan(currentVer); + } catch (IllegalArgumentException e) { + plugin.getLogger().warning("Invalid version string provided: " + e.getMessage()); + } + return false; } + /** + * Returns the result of the last update check performed by the UpdateChecker. + * + * @return the {@link UpdateResult} object containing information about the update + * check, such as the update reason, newest version, download URL, and changelog. + */ public UpdateResult getLastResult() { return lastResult; } + // Enum for update reason explanations public enum UpdateReason { - NEW_UPDATE, UP_TO_DATE, COULD_NOT_CONNECT, INVALID_JSON; + NEW_UPDATE, UP_TO_DATE, COULD_NOT_CONNECT, INVALID_JSON } - public final class UpdateResult { - private final UpdateReason reason; - private final String newestVersion, url; - private List changelog; - - { - UpdateChecker.this.lastResult = this; - } - - private UpdateResult(UpdateReason reason, String newestVersion, String url, List changelog) { - this.reason = reason; - this.newestVersion = newestVersion; - this.url = url; - this.changelog = changelog; - } - - private UpdateResult(UpdateReason reason) { - if (reason == UpdateReason.NEW_UPDATE) { - throw new IllegalArgumentException("Reasons that require updates must also provide the latest version, URL and changelog"); - } - - this.reason = reason; - this.newestVersion = plugin.getDescription().getVersion(); - this.url = null; - this.changelog = null; - } + /** + * Record to represent the result of an update check. + */ + public record UpdateResult(UpdateReason reason, String newestVersion, + String downloadUrl, List changelog) { public boolean updateAvailable() { - return this.reason == UpdateReason.NEW_UPDATE; - } - - public String getNewestVersion() { - return newestVersion; - } - - public String getUrl() { - return url; - } - - public List getChangelog() { - return changelog; + return reason == UpdateChecker.UpdateReason.NEW_UPDATE; } @Override @@ -143,9 +181,17 @@ public String toString() { return "UpdateResult{" + "reason=" + reason + ", newestVersion='" + newestVersion + '\'' + - ", url='" + url + '\'' + + ", downloadUrl='" + downloadUrl + '\'' + ", changelog=" + changelog + '}'; } + + public String getNewestVersion() { + return newestVersion; + } + + public String getUrl() { + return downloadUrl; + } } -} +} \ No newline at end of file From 4eb77f1c8861af7ec9474c8590edfd064cbd8334 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 23:41:19 -0500 Subject: [PATCH 40/48] Refactor logging and add `getStrings` method. Updated `WRLogger` initialization to cast `audience.console()` to `ConsoleCommandSender` for improved type safety. Introduced `getStrings` method to enhance string management accessibility. --- .../net/licks92/wirelessredstone/WirelessRedstone.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index 23a05cdd..c7938422 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -16,9 +16,11 @@ import net.licks92.wirelessredstone.signs.WirelessTransmitter; import net.licks92.wirelessredstone.storage.StorageManager; import net.licks92.wirelessredstone.string.StringManager; +import net.licks92.wirelessredstone.string.Strings; import net.licks92.wirelessredstone.worldedit.WorldEditLoader; import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.PluginManager; @@ -72,6 +74,10 @@ public static CommandManager getCommandManager() { return commandManager; } + public static Strings getStrings() { + return stringManager.getStrings(); + } + @Override public void onEnable() { instance = this; @@ -87,7 +93,7 @@ public void onEnable() { // Initialize logger with Adventure API config = ConfigManager.getConfig(); - wrLogger = new WRLogger("[WirelessRedstone]", audience.console(), config.getDebugMode(), config.getColorLogging()); + wrLogger = new WRLogger("[WirelessRedstone]", (ConsoleCommandSender) audience.console(), config.getDebugMode(), config.getColorLogging()); wrLogger.info("Enabling WirelessRedstone"); From 93b9970e518f969c2832717d2d67de3791b0162b Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 23:45:23 -0500 Subject: [PATCH 41/48] Refactor utility methods and improve documentation. Refactored `Utils` class methods for improved clarity, better parameter handling, and consistency. Enhanced Javadoc comments across various methods with additional details, formatting, and explanations. Marked the `getRawData` method as deprecated for future removal. --- .../net/licks92/wirelessredstone/Utils.java | 102 +++++++++++++----- 1 file changed, 75 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/Utils.java b/core/src/main/java/net/licks92/wirelessredstone/Utils.java index f3b03a98..f05c890e 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/Utils.java +++ b/core/src/main/java/net/licks92/wirelessredstone/Utils.java @@ -33,9 +33,9 @@ public class Utils { ); /** - * Gets the current Minecraft version from Paper's API. + * Retrieves the current Minecraft version as a string using the Bukkit API. * - * @return A string representing the Minecraft version + * @return A string representing the current Minecraft version. */ private static String getMinecraftVersion() { // Utilize Paper's API for better version handling @@ -43,9 +43,13 @@ private static String getMinecraftVersion() { } /** - * Parses the Minecraft version into a `Version` object. + * Parses the current Minecraft version string into a {@code Version} object. + * Extracts the major and minor version numbers from the string and + * encapsulates them into a {@code Version} record. If parsing the version + * fails, an empty {@code Optional} is returned. * - * @return Optional Version if parsing is successful + * @return An {@code Optional} containing the parsed version if successful, + * or an empty {@code Optional} if an exception occurs during parsing. */ private static Optional parseVersion() { try { @@ -58,9 +62,11 @@ private static Optional parseVersion() { } /** - * Checks if the server version is compatible with Minecraft 1.8 or newer. + * Determines if the current Minecraft version is compatible by checking + * whether the major version is greater than 1, or if the major version is 1 + * and the minor version is at least 8. * - * @return True if compatible; otherwise, false. + * @return true if the Minecraft version is 1.8 or newer, false if parsing fails or the version is incompatible. */ public static boolean isCompatible() { return parseVersion() @@ -69,9 +75,10 @@ public static boolean isCompatible() { } /** - * Checks if the new material system (1.13+) is present. + * Determines if the current system uses the new Minecraft material system + * introduced in version 1.13 or higher. * - * @return True if the new material system is enabled; otherwise, false. + * @return true if the Minecraft version is 1.13 or newer, false otherwise. */ public static boolean isNewMaterialSystem() { return parseVersion() @@ -80,13 +87,18 @@ public static boolean isNewMaterialSystem() { } /** - * Unified message sender with enhanced customization. + * Sends a message to the specified {@code CommandSender} with an optional prefix and + * formatting to indicate whether it is an error message. The message can be + * conditionally suppressed based on a silent mode configuration. * - * @param message The message to send - * @param sender The target recipient - * @param isError Whether the message indicates an error - * @param prefix An optional prefix (null for no prefix) - * @param checkSilent Whether to suppress message in silent mode + * @param message The message to be sent to the {@code CommandSender}. + * @param sender The {@code CommandSender} who will receive the message. + * @param isError Whether the message represents an error. If {@code true}, + * the message is displayed in red; otherwise, it is displayed in green. + * @param prefix An optional prefix string to prepend to the message. If + * null, no prefix is added. + * @param checkSilent Whether to check for silent mode configuration. If {@code true}, + * the message will not be sent if silent mode is enabled. */ private static void sendMessageToSender(String message, CommandSender sender, boolean isError, String prefix, boolean checkSilent) { if (checkSilent && ConfigManager.getConfig().getSilentMode()) return; @@ -116,11 +128,17 @@ public static void sendCommandFeedback(String message, CommandSender sender, boo } /** - * Converts a legacy direction ID into a BlockFace. + * Determines the appropriate BlockFace direction based on whether the block is a wall sign + * or a floor-mounted block, and the provided direction value. * - * @param isWallSign Indicates if the block is a wall sign - * @param direction The legacy direction ID - * @return Converted BlockFace + * @param isWallSign Indicates if the block is a wall sign. If true, the direction will be + * determined using the wall directions map. If false, the floor directions map + * will be used. + * @param direction The integer value representing the direction. This value is used as a key + * to determine the corresponding BlockFace. + * @return The corresponding BlockFace for the given block type and direction value. Defaults + * to BlockFace.NORTH for wall signs and BlockFace.SOUTH for floor blocks if the + * direction is not found in the respective map. */ public static BlockFace getBlockFace(boolean isWallSign, int direction) { return isWallSign @@ -128,6 +146,14 @@ public static BlockFace getBlockFace(boolean isWallSign, int direction) { : FLOOR_DIRECTIONS.getOrDefault(direction, BlockFace.SOUTH); } + /** + * Generates raw data byte information based on the state of a torch and the specified BlockFace direction. + * + * @param isTorch Indicates whether the object is a torch. + * @param blockFace The direction represented by a BlockFace enum. + * @return A byte value representing the raw data for the given torch state and BlockFace. + * @deprecated This method is deprecated and may be removed in future updates. + */ @Deprecated public static byte getRawData(boolean isTorch, BlockFace blockFace) { return switch (blockFace) { @@ -140,10 +166,10 @@ public static byte getRawData(boolean isTorch, BlockFace blockFace) { } /** - * Generates a JSON-based tellraw teleport command for a player. + * Generates a Minecraft-specific teleportation command string to be used with a player. * - * @param playerName The name of the player. - * @return A formatted tellraw command string. + * @param playerName The name of the player for which the teleportation string is generated. + * @return A formatted string representing the teleportation command based on the player's name. */ public static String getTeleportString(String playerName) { return """ @@ -171,29 +197,43 @@ public static String getTeleportString(String playerName) { } /** - * Retrieves all possible BlockFace directions. + * Retrieves a collection of BlockFace directions that align with an axis. + * Optionally includes the up and down BlockFaces depending on the parameter. * - * @param includeUpAndDown Whether to include vertical directions - * @return A collection of BlockFace + * @param includeUpAndDown If true, the resulting collection includes both up and down directions; + * otherwise, only horizontal axis directions are included. + * @return A collection of BlockFace directions based on the specified parameter. */ public static Collection getAxisBlockFaces(boolean includeUpAndDown) { return includeUpAndDown ? FULL_AXIS : AXIS; } + /** + * Retrieves a collection of BlockFace values that represent the primary axis directions. + * + * @return A collection of BlockFace values corresponding to the primary axis directions. + */ public static Collection getAxisBlockFaces() { return FULL_AXIS; } /** - * Converts a yaw angle to a horizontal BlockFace. + * Converts a yaw angle into a corresponding BlockFace direction. * - * @param yaw The yaw angle - * @return The determined BlockFace + * @param yaw The yaw angle to be converted, measured in degrees. Typically ranges from -180 to 180. + * @return The BlockFace that corresponds to the given yaw angle. */ public static BlockFace yawToFace(float yaw) { return AXIS.get(Math.round(yaw / 90) & 0x3); } + /** + * Compares two Location objects to determine if they represent the same block location in the same world. + * + * @param loc1 The first Location object to compare, may be null. + * @param loc2 The second Location object to compare, may be null. + * @return True if both locations share the same block coordinates (x, y, z) and world name, otherwise false. + */ public static boolean sameLocation(Location loc1, Location loc2) { if (loc1 == null || loc2 == null || loc1.getWorld() == null || loc2.getWorld() == null) { return false; @@ -204,6 +244,14 @@ public static boolean sameLocation(Location loc1, Location loc2) { loc1.getWorld().getName().equalsIgnoreCase(loc2.getWorld().getName()); } + /** + * Determines the SignType based on the provided text and line. + * + * @param text The text to be evaluated, indicating the type of sign. + * Acceptable values include specific keywords like "TRANSMITTER", "RECEIVER", etc. + * @param line The additional line parameter, which must not be null. + * @return The corresponding SignType if a match is found, otherwise null. + */ public static SignType getType(String text, @NotNull String line) { return switch (text.toUpperCase()) { case "TRANSMITTER", "T" -> SignType.TRANSMITTER; From d661fc95f946d59ae58b0648aa94dbf52488b81b Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sat, 8 Mar 2025 23:45:43 -0500 Subject: [PATCH 42/48] Simplify imports in UpdateChecker.java Removed an unused InputStreamReader import to clean up the code. This enhances maintainability and eliminates unnecessary dependencies. --- .../main/java/net/licks92/wirelessredstone/UpdateChecker.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java b/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java index ba6ef03f..34dcc098 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java +++ b/core/src/main/java/net/licks92/wirelessredstone/UpdateChecker.java @@ -8,7 +8,6 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; -import java.io.InputStreamReader; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; From ab7b91db7e5ac7ee7a3b43ef02d079d70f441a9e Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sun, 9 Mar 2025 00:01:41 -0500 Subject: [PATCH 43/48] Add StorageConfiguration initialization and accessor method Introduce proper initialization for StorageConfiguration via StorageManager and ensure storage setup is verified during plugin startup. Added `getStorage()` method to provide safe access to the storage configuration, with a validation check for uninitialized states. --- .../licks92/wirelessredstone/WirelessRedstone.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java index c7938422..33ad06d4 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java +++ b/core/src/main/java/net/licks92/wirelessredstone/WirelessRedstone.java @@ -14,6 +14,7 @@ import net.licks92.wirelessredstone.signs.WirelessReceiver; import net.licks92.wirelessredstone.signs.WirelessScreen; import net.licks92.wirelessredstone.signs.WirelessTransmitter; +import net.licks92.wirelessredstone.storage.StorageConfiguration; import net.licks92.wirelessredstone.storage.StorageManager; import net.licks92.wirelessredstone.string.StringManager; import net.licks92.wirelessredstone.string.Strings; @@ -106,8 +107,10 @@ public void onEnable() { storageManager = new StorageManager(config.getStorageType(), CHANNEL_FOLDER); // Initialize storage + storageManager = new StorageManager(this); if (!storageManager.getStorage().initStorage()) { wrLogger.severe("Failed to initialize storage. Plugin will stop."); + disablePlugin(); // Clean lifecycle management, safely disable return; // Exit early since we can't continue } @@ -255,6 +258,14 @@ private void registerCommands() { }); } + public static StorageConfiguration getStorage() { + if (storageManager == null || storageManager.getStorage() == null) { + throw new IllegalStateException("StorageManager or StorageConfiguration is not initialized!"); + } + return storageManager.getStorage(); + } + + private void loadWorldEditIntegration() { if (getServer().getPluginManager().isPluginEnabled("WorldEdit")) { new WorldEditLoader(); From dfde863a81ff3ace46df70714c210937d153d7ba Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sun, 9 Mar 2025 10:39:31 -0400 Subject: [PATCH 44/48] Fix logical flow in hasAccessToChannel method Refactored the method to ensure proper handling of player checks. Now always returns true for non-player senders like console or command blocks, preserving intended behavior. --- .../licks92/wirelessredstone/commands/WirelessCommand.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/commands/WirelessCommand.java b/core/src/main/java/net/licks92/wirelessredstone/commands/WirelessCommand.java index 357f2ca2..1e788f56 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/commands/WirelessCommand.java +++ b/core/src/main/java/net/licks92/wirelessredstone/commands/WirelessCommand.java @@ -9,7 +9,10 @@ public abstract class WirelessCommand { public abstract void onCommand(CommandSender sender, String[] args); public boolean hasAccessToChannel(CommandSender sender, String channelName) { - return !(sender instanceof Player) || WirelessRedstone.getSignManager().hasAccessToChannel((Player) sender, channelName); //If it's console or commandBlock, it has access to channel. + if (sender instanceof Player) { + WirelessRedstone.getSignManager().hasAccessToChannel((Player) sender, channelName); + } + return true; //If it's console or commandBlock, it has access to channel. } } From 33cb334f00c6682dae2dc1955557ae0960adfc0e Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sun, 9 Mar 2025 10:39:51 -0400 Subject: [PATCH 45/48] Add stub for sendFeedback method in Utils Introduce the sendFeedback method with a placeholder implementation. This prepares the code for future enhancements requiring feedback handling functionality. --- core/src/main/java/net/licks92/wirelessredstone/Utils.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/net/licks92/wirelessredstone/Utils.java b/core/src/main/java/net/licks92/wirelessredstone/Utils.java index f05c890e..255de506 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/Utils.java +++ b/core/src/main/java/net/licks92/wirelessredstone/Utils.java @@ -265,5 +265,8 @@ public static SignType getType(String text, @NotNull String line) { }; } + public static void sendFeedback(String s, CommandSender sender, boolean b, Object o, boolean b1) { + } + private record Version(int major, int minor) {} } \ No newline at end of file From fd6acb6fc70de26151b7d1a13a6adf8a38c92aa8 Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sun, 9 Mar 2025 10:40:30 -0400 Subject: [PATCH 46/48] Refactor AdminAddOwner command with enhanced validations. Improved argument validation, added specific error feedback, and encapsulated owner addition logic into a new method for better error handling. These changes enhance maintainability and provide clearer notifications for command users. --- .../commands/Admin/AdminAddOwner.java | 58 +++++++++++++++---- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java b/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java index 23b9fe6f..2496b637 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java +++ b/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java @@ -8,41 +8,75 @@ import net.licks92.wirelessredstone.WirelessRedstone; import org.bukkit.command.CommandSender; -@CommandInfo(description = "Add owner to WirlessChannel", usage = " ", aliases = {"addowner"}, +@CommandInfo( + description = "Add owner to WirelessChannel", + usage = " ", + aliases = {"addowner"}, tabCompletion = {WirelessCommandTabCompletion.CHANNEL, WirelessCommandTabCompletion.PLAYER}, - permission = "addOwner", canUseInConsole = true, canUseInCommandBlock = false) + permission = "addOwner", + canUseInConsole = true, + canUseInCommandBlock = false +) public class AdminAddOwner extends WirelessCommand { @Override public void onCommand(CommandSender sender, String[] args) { - if (args.length < 2) { - Utils.sendFeedback(WirelessRedstone.getStrings().commandTooFewArguments, sender, true); + // Validate arguments + if (args == null || args.length < 2) { + Utils.sendFeedback(WirelessRedstone.getStrings().commandTooFewArguments, sender, true, null, false); return; } String channelName = args[0]; String playerName = args[1]; + // Validate sender permissions and channel access if (!hasAccessToChannel(sender, channelName)) { - Utils.sendFeedback(WirelessRedstone.getStrings().permissionChannelAccess, sender, true); + Utils.sendFeedback(WirelessRedstone.getStrings().permissionChannelAccess, sender, true, null, false); return; } + // Fetch the channel by name WirelessChannel channel = WirelessRedstone.getStorageManager().getChannel(channelName); if (channel == null) { - Utils.sendFeedback(WirelessRedstone.getStrings().channelNotFound, sender, true); + Utils.sendFeedback(WirelessRedstone.getStrings().channelNotFound(channelName), sender, true, null, false); return; } + // Check if the specified player is already an owner if (channel.getOwners().contains(playerName)) { - Utils.sendFeedback(WirelessRedstone.getStrings().channelAlreadyOwner, sender, true); + Utils.sendFeedback(WirelessRedstone.getStrings().channelAlreadyOwner(playerName), sender, true, null, false); return; } - channel.addOwner(playerName); - WirelessRedstone.getStorage().updateChannel(channelName, channel); + // Attempt to add the owner to the channel + if (addOwnerToChannel(channel, playerName)) { + WirelessRedstone.getStorage().updateChannel(channelName, channel); - WirelessRedstone.getWRLogger().info("Channel " + channelName + " has been updated. Player " + playerName + " has been added to the owner list."); - Utils.sendFeedback(WirelessRedstone.getStrings().channelOwnerAdded.replaceAll("%%PLAYERNAME", playerName), sender, false); + // Notify the sender of successful addition + Utils.sendFeedback( + WirelessRedstone.getStrings().channelOwnerAdded(playerName, channelName), sender, false, null, false); + } else { + // Notify the sender of failure + Utils.sendFeedback("Failed to add the owner. Please try again later.", sender, true, null, false); + } + } + + /** + * Adds an owner to the channel if not already an owner. + * + * @param channel The WirelessChannel object. + * @param playerName The name of the player to add. + * @return True if the player was successfully added, false otherwise. + */ + private boolean addOwnerToChannel(WirelessChannel channel, String playerName) { + try { + channel.addOwner(playerName); // Add the player as an owner + return true; + } catch (IllegalStateException e) { + WirelessRedstone.getWRLogger() + .warning("Failed to add '" + playerName + "' as an owner: " + e.getMessage()); + return false; + } } -} +} \ No newline at end of file From 16f79c52f0d1ce51340eef6edd969e4b15bbbbcd Mon Sep 17 00:00:00 2001 From: Corey Clark Date: Sun, 9 Mar 2025 10:40:59 -0400 Subject: [PATCH 47/48] Add Javadoc comments for AdminAddOwner command method Added detailed Javadoc comments to the onCommand method in AdminAddOwner class. This includes explanation of the method's purpose and parameters, improving code readability and maintainability. --- .../wirelessredstone/commands/Admin/AdminAddOwner.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java b/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java index 2496b637..04e3b36e 100644 --- a/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java +++ b/core/src/main/java/net/licks92/wirelessredstone/commands/Admin/AdminAddOwner.java @@ -19,6 +19,15 @@ ) public class AdminAddOwner extends WirelessCommand { + /** + * Handles the execution of the "addowner" command, which adds a player as an owner + * to a specified wireless channel. The command ensures proper validation of arguments, + * permissions, and checks before adding the owner. + * + * @param sender The entity executing the command. This could be a player, console, or other valid command sender. + * @param args An array of command arguments. The first argument is the channel name, + * and the second is the player's name to be added as an owner. + */ @Override public void onCommand(CommandSender sender, String[] args) { // Validate arguments From 11c7402bff371bbff5dc2f416b9a03ba8a09e4c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 00:14:15 +0000 Subject: [PATCH 48/48] Bump io.sentry:sentry from 1.7.23 to 8.3.0 Bumps [io.sentry:sentry](https://github.com/getsentry/sentry-java) from 1.7.23 to 8.3.0. - [Release notes](https://github.com/getsentry/sentry-java/releases) - [Changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-java/compare/v1.7.23...8.3.0) --- updated-dependencies: - dependency-name: io.sentry:sentry dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f5021e2e..2fc5de63 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ ${project.mcversion}-R0.1-SNAPSHOT 0.10.2 - 1.7.23 + 8.3.0 https://7c45ccc4745f428f81d577b15c84b840@sentry.io/1509557