From 761d07b8696bfa7271b6ba6c0b45075b7453a290 Mon Sep 17 00:00:00 2001 From: Telesphoreo Date: Fri, 1 Oct 2021 01:03:36 -0500 Subject: [PATCH] Reimplement checkstyle and formatting --- .github/workflows/downstream.yml | 43 - .github/workflows/gradle.yml | 16 +- .gitignore | 2 + .travis.yml | 13 - CONTRIBUTING.md | 3 +- LICENSE.md | 66 +- README.md | 10 +- SECURITY.md | 26 +- build.gradle | 13 +- .../checkstyle/checkstyle.xml | 10 +- config/checkstyle/suppressions.xml | 7 + config/xsl/checkstyle-custom.xsl | 244 +++++ gradle.properties | 7 +- .../totalfreedommod/AntiSpam.java | 4 +- .../totalfreedommod/ChatManager.java | 3 +- .../totalfreedom/totalfreedommod/Metrics.java | 848 ------------------ .../totalfreedommod/TotalFreedomMod.java | 3 +- .../admin/ActivityLogEntry.java | 5 +- .../totalfreedommod/blocking/EditBlocker.java | 27 +- .../command/Command_coins.java | 30 +- .../command/Command_namehistory.java | 9 +- .../totalfreedommod/discord/Discord.java | 8 +- .../discord/DiscordToAdminChatListener.java | 2 +- .../totalfreedommod/httpd/HTTPDaemon.java | 2 +- .../totalfreedommod/rank/RankManager.java | 2 +- .../totalfreedommod/util/FUtil.java | 16 +- .../totalfreedommod/util/TimeUnit.java | 6 +- src/main/resources/config.yml | 8 +- src/main/resources/indefinitebans.yml | 2 +- src/main/resources/permissions.yml | 2 +- supressions.xml | 9 - 31 files changed, 439 insertions(+), 1007 deletions(-) delete mode 100644 .github/workflows/downstream.yml delete mode 100644 .travis.yml rename checkstyle.xml => config/checkstyle/checkstyle.xml (95%) create mode 100644 config/checkstyle/suppressions.xml create mode 100644 config/xsl/checkstyle-custom.xsl delete mode 100644 src/main/java/me/totalfreedom/totalfreedommod/Metrics.java delete mode 100644 supressions.xml diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml deleted file mode 100644 index b5e72dcc..00000000 --- a/.github/workflows/downstream.yml +++ /dev/null @@ -1,43 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Downstream Branch Updates - -on: - schedule: - - cron: '20 7 * * *' - # scheduled at 07:00 every Monday and Thursday - - workflow_dispatch: # click the button on Github repo! - - -jobs: - sync_with_upstream: - runs-on: ubuntu-latest - name: Sync main with upstream latest - - steps: - # Step 1: run a standard checkout action, provided by github - - name: Checkout main - uses: actions/checkout@v2 - with: - ref: main - # submodules: 'recursive' ### may be needed in your situation - - # Step 2: run this sync action - specify the upstream repo, upstream branch to sync with, and target sync branch - - name: Pull (Fast-Forward) upstream changes - id: sync - uses: aormsby/Fork-Sync-With-Upstream-action@v2.1 - with: - upstream_repository: AtlasMediaGroup/TotalFreedomMod - upstream_branch: main - target_branch: development - git_pull_args: --ff-only # optional arg use, defaults to simple 'pull' - - # Step 3: Display a message if 'sync' step had new commits (simple test) - - name: Check for new commits - if: steps.sync.outputs.has_new_commits - run: echo "There were new commits." - - # Step 4: Print a helpful timestamp for your records (not required, just nice) - - name: Timestamp - run: date diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 2f72fbf4..a7f43287 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,15 +1,15 @@ name: Gradle-Build -on: [push] +on: [ push ] jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Set up JDK 16 - uses: actions/setup-java@v1 - with: - java-version: 16 - - name: Build with Gradle - run: chmod a+x gradlew && ./gradlew build -x buildProperties + - uses: actions/checkout@v1 + - name: Set up JDK 16 + uses: actions/setup-java@v1 + with: + java-version: 16 + - name: Build with Gradle + run: chmod a+x gradlew && ./gradlew build -x buildProperties diff --git a/.gitignore b/.gitignore index 3c9f8e2a..4fbf0856 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # TFM excludes build.properties dependency-reduced-pom.xml +*.html +*.css # Netbeans excludes /nbproject/private diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 141c7052..00000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: java -jdk: - - oraclejdk11 - - openjdk11 -notifications: - email: false -addons: - apt: - packages: - - sshpass -script: mvn clean install -after_success: - - ./travis-upload.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76586aaf..0623673d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,4 @@ # Contributing to TotalFreedomMod -For information about contributing to TotalFreedomMod, please see the [contributing guidelines](https://github.com/TotalFreedom/TotalFreedomMod/wiki/Contributing). +For information about contributing to TotalFreedomMod, please see +the [contributing guidelines](https://github.com/TotalFreedom/TotalFreedomMod/wiki/Contributing). diff --git a/LICENSE.md b/LICENSE.md index 5ee5fb7c..2fb57549 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -14,37 +14,62 @@ All rights reserved. "Licensor" shall mean the copyright holder or entity authorised by the copyright owner that is granting the License. -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are +under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of +fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You", "Your" or "Yourself" shall mean an individual or Legal Entity exercising permissions granted by this License. -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, +documentation source, and configuration files. -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, binary data, generated documentation, and conversions to other media types. +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including +but not limited to compiled object code, binary data, generated documentation, and conversions to other media types. -"Work" and "This Software" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work. +"Work" and "This Software" shall mean the work of authorship, whether in Source or Object form, made available under the +License, as indicated by a copyright notice that is included in or attached to the work. -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work +and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain +separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or +additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the +Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. +For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to +the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code +control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of +discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in +writing by the copyright owner as "Not a Contribution." -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received +by Licensor and subsequently incorporated within the Work. -"Redistribution" shall mean any partial or complete availability, transfer or publication of the Work from one Legal Entity to another. +"Redistribution" shall mean any partial or complete availability, transfer or publication of the Work from one Legal +Entity to another. ##### 2. Grant of Copyright License -Subject to the terms and conditions of this License, You are granted a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to prepare Derivative Works of, publicly display, publicly perform, inspect and redistribute the Work and such Derivative Works as long as the following conditions are met: +Subject to the terms and conditions of this License, You are granted a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable copyright license to prepare Derivative Works of, publicly display, publicly perform, inspect +and redistribute the Work and such Derivative Works as long as the following conditions are met: -1. Redistributions of This Software must solely occur in Source form. Redistribution in Object form is prohibited without prior written permission from the Licensor. +1. Redistributions of This Software must solely occur in Source form. Redistribution in Object form is prohibited + without prior written permission from the Licensor. -2. Neither the names of the copyright holders nor the names this software's contributors may be removed from This Software's source code. +2. Neither the names of the copyright holders nor the names this software's contributors may be removed from This + Software's source code. -3. Neither the names of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from This Software without specific prior written permission. +3. Neither the names of the copyright holders nor the names of its contributors may be used to endorse or promote + products derived from This Software without specific prior written permission. -4. Accreditations referencing This Software's copyright holders or contributors may neither be altered or removed from source code nor withheld from reproduction in Object form whatsoever. +4. Accreditations referencing This Software's copyright holders or contributors may neither be altered or removed from + source code nor withheld from reproduction in Object form whatsoever. -5. Any conditions specified by this license may be temporarily or permanently waived by any the aforementioned copyright holders. +5. Any conditions specified by this license may be temporarily or permanently waived by any the aforementioned copyright + holders. 6. Redistributions of This Software must retain this License document in its exact form. @@ -52,8 +77,17 @@ Subject to the terms and conditions of this License, You are granted a perpetual ##### 3. Submission of Contributions -Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the +Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may +have executed with Licensor regarding such Contributions. ##### 4. Disclaimer of Warranty -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index aeb24b3d..b1596cfa 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,14 @@ # TotalFreedomMod ![Build Status](https://github.com/StevenNL2000Freedom/TotalFreedomMod/actions/workflows/gradle.yml/badge.svg) -TotalFreedomMod is a CraftBukkit server plugin designed primarily to support the [Official TotalFreedom Minecraft Server](https://totalfreedom.me/). However, you are more than welcome to adapt the source for your own server. +TotalFreedomMod is a CraftBukkit server plugin designed primarily to support +the [Official TotalFreedom Minecraft Server](https://totalfreedom.me/). However, you are more than welcome to adapt the +source for your own server. -This plugin was originally coded by StevenLawson (Madgeek1450), with Jerom van der Sar (Prozza) becoming heavily involved in its development some time later. It consists of over 85 custom coded commands and a large variety of distinguishable features not included in any other plugin. The plugin has since its beginning grown immensely. Together, with the main TotalFreedom server, TotalFreedomMod has a long-standing reputation of effectiveness whilst maintaining a clear feeling of openness towards the administrators and the players themselves. +This plugin was originally coded by StevenLawson (Madgeek1450), with Jerom van der Sar (Prozza) becoming heavily +involved in its development some time later. It consists of over 85 custom coded commands and a large variety of +distinguishable features not included in any other plugin. The plugin has since its beginning grown immensely. Together, +with the main TotalFreedom server, TotalFreedomMod has a long-standing reputation of effectiveness whilst maintaining a +clear feeling of openness towards the administrators and the players themselves. ### Contributing diff --git a/SECURITY.md b/SECURITY.md index adc91e1d..4f6e57d9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,26 +2,33 @@ ## Supported Versions -We currently support the code running on the "main" branch and "development" branch of this repository. This is supported in addition to those formal releases, but note anything not yet released should be treated as in-development. +We currently support the code running on the "main" branch and "development" branch of this repository. This is +supported in addition to those formal releases, but note anything not yet released should be treated as in-development. In terms of plugin releases, our support matrix is as follows: ### Actively Supported -These versions are currently actively supported by our team, and you should expect security patches where appropriate for these versions. + +These versions are currently actively supported by our team, and you should expect security patches where appropriate +for these versions. | Version | Supported | Support End: | | ------------------- | ------------------ | ------------------------------ | -| 2021.05 | :white_check_mark: | No Earlier than August 2021 | +| 7.0.0 | :white_check_mark: | No Earlier than August 2021 | ### Legacy Supported -These versions are no longer under active development, however we will look to release critical secuirty patches where appropriate. + +These versions are no longer under active development, however we will look to release critical secuirty patches where +appropriate. | Version | Supported | Support End: | | ------------------- | ------------------ | ------------ | | 2021.04 | :white_check_mark: | July 2021 | ### No Longer Supported -These versions are no longer supported at all. It is strongly advised to update if you are running any of these versions. + +These versions are no longer supported at all. It is strongly advised to update if you are running any of these +versions. | Version | Supported | Support Ended: | | ------------------- | ------------------ | ------------------- | @@ -33,6 +40,11 @@ These versions are no longer supported at all. It is strongly advised to update ## Reporting a Vulnerability -If the report has minor security implications (ie we've added a super admin to a senior admins permission) please raise an post on [our forums](https://forum.totalfreedom.me/) in the first instance. If you do not have a forum account and do not wish to sign up, please e-mail us using the e-mail in the next sentence. +If the report has minor security implications (ie we've added a super admin to a senior admins permission) please raise +an post on [our forums](https://forum.totalfreedom.me/) in the first instance. If you do not have a forum account and do +not wish to sign up, please e-mail us using the e-mail in the next sentence. -For security vulnerabilities that are more severe and that may pose a more significant threat to the servers running this plugin, please e-mail os-security-reports [ AT ] atlas-media.co.uk - You can expect an automated response immediately to acknowledge receipt of your e-mail, and one of our team will aim to respond within 72 hours and will work with you on the best way to address your concerns. +For security vulnerabilities that are more severe and that may pose a more significant threat to the servers running +this plugin, please e-mail os-security-reports [ AT ] atlas-media.co.uk - You can expect an automated response +immediately to acknowledge receipt of your e-mail, and one of our team will aim to respond within 72 hours and will work +with you on the best way to address your concerns. diff --git a/build.gradle b/build.gradle index 297ce2a9..aa0a1f03 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'maven-publish' id 'idea' + id 'checkstyle' id 'com.github.johnrengelman.shadow' version '7.0.0' id 'net.minecrell.plugin-yml.bukkit' version '0.5.0' } @@ -102,6 +103,7 @@ dependencies { implementation('com.mattmalec:Pterodactyl4J:2.BETA_80') implementation('org.junit.jupiter:junit-jupiter:5.8.1') implementation('org.projectlombok:lombok:1.18.20') + implementation('org.bstats:bstats-bukkit:2.2.1') compileOnly('org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT') compileOnly('me.totalfreedom:bukkittelnet:4.6') compileOnly('me.totalfreedom:TF-LibsDisguises:10.0.26-SNAPSHOT') @@ -144,8 +146,7 @@ def getGitHash() { return stdout.toString().trim() } -def getBuildNumber() -{ +def getBuildNumber() { def stdout = new ByteArrayOutputStream() exec { commandLine 'git', 'rev-list', 'HEAD', '--count' @@ -154,6 +155,14 @@ def getBuildNumber() return stdout.toString().trim() } +tasks.withType(Checkstyle) { + reports { + xml.required = false + html.required = true + html.stylesheet resources.text.fromFile('config/xsl/checkstyle-custom.xsl') + } +} + task buildProperties { ant.propertyfile(file: "$project.rootDir/src/main/resources/build.properties") { entry(key: "buildAuthor", default: "unknown") diff --git a/checkstyle.xml b/config/checkstyle/checkstyle.xml similarity index 95% rename from checkstyle.xml rename to config/checkstyle/checkstyle.xml index b060ebbe..f728051f 100644 --- a/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -7,11 +7,15 @@ - + + + + + @@ -20,10 +24,6 @@ value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/> - - - - diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 00000000..9a0cd4b6 --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/config/xsl/checkstyle-custom.xsl b/config/xsl/checkstyle-custom.xsl new file mode 100644 index 00000000..1bda77b1 --- /dev/null +++ b/config/xsl/checkstyle-custom.xsl @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+ + +

CheckStyle Audit

+
Designed for use with + CheckStyle + and Ant. +
+
+ + + +
+ + + +
+ + + + + +

+

+ +


+ + +
+ +

Summary

+ + + + + + + + + + + + + + + +
FilesErrorsWarnings
+ + + + + +
+
+ +

Authors

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameErrorsWarnings
+ + + + + + + +
+
+ + + + + + + +
+

File + +
+ Author + +

+ + + + + + + + + + + + + +
Error DescriptionLine
+ + + +
+
Back to top + + + + + + + + + + substring-after($path, '\') + + + + + + + + + + + + a + b + + + +
\ No newline at end of file diff --git a/gradle.properties b/gradle.properties index e3667e91..78a624a3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,6 @@ -project.pluginVersion = 7.0.0 -project.buildAuthor = unknown -project.buildCodeName = Ember - +project.pluginVersion=7.0.0 +project.buildAuthor=unknown +project.buildCodeName=Ember org.gradle.cache=true org.gradle.caching=true org.gradle.parallel=true diff --git a/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java b/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java index 998e1d52..e3f36035 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/AntiSpam.java @@ -81,8 +81,8 @@ public class AntiSpam extends FreedomService playerdata.setMuted(true, time); FSync.bcastMsg(String.format("%s has automatically been muted for %d minutes for spamming chat.", - player.getName(), - time), + player.getName(), + time), ChatColor.RED); playerdata.resetMsgCount(); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java b/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java index e05965ec..0686c863 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/ChatManager.java @@ -162,7 +162,8 @@ public class ChatManager extends FreedomService server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player -> { Admin admin = plugin.al.getAdmin(player); - if (!Strings.isNullOrEmpty(admin.getAcFormat())) { + if (!Strings.isNullOrEmpty(admin.getAcFormat())) + { String format = admin.getAcFormat(); ChatColor color = getColor(display); String msg = format.replace("%name%", sender.getName()).replace("%rank%", display.getAbbr()).replace("%rankcolor%", color.toString()).replace("%msg%", message); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/Metrics.java b/src/main/java/me/totalfreedom/totalfreedommod/Metrics.java deleted file mode 100644 index 5ee064a2..00000000 --- a/src/main/java/me/totalfreedom/totalfreedommod/Metrics.java +++ /dev/null @@ -1,848 +0,0 @@ -package me.totalfreedom.totalfreedommod; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Method; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.stream.Collectors; -import java.util.zip.GZIPOutputStream; -import javax.net.ssl.HttpsURLConnection; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; - -public class Metrics { - - private final Plugin plugin; - - private final MetricsBase metricsBase; - - /** - * Creates a new Metrics instance. - * - * @param plugin Your plugin instance. - * @param serviceId The id of the service. It can be found at What is my plugin id? - */ - public Metrics(JavaPlugin plugin, int serviceId) { - this.plugin = plugin; - // Get the config file - File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); - File configFile = new File(bStatsFolder, "config.yml"); - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); - if (!config.isSet("serverUuid")) { - config.addDefault("enabled", true); - config.addDefault("serverUuid", UUID.randomUUID().toString()); - config.addDefault("logFailedRequests", false); - config.addDefault("logSentData", false); - config.addDefault("logResponseStatusText", false); - // Inform the server owners about bStats - config - .options() - .header( - "bStats (https://bStats.org) collects some basic information for plugin authors, like how\n" - + "many people use their plugin and their total player count. It's recommended to keep bStats\n" - + "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n" - + "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n" - + "anonymous.") - .copyDefaults(true); - try { - config.save(configFile); - } catch (IOException ignored) { - } - } - // Load the data - boolean enabled = config.getBoolean("enabled", true); - String serverUUID = config.getString("serverUuid"); - boolean logErrors = config.getBoolean("logFailedRequests", false); - boolean logSentData = config.getBoolean("logSentData", false); - boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false); - metricsBase = - new MetricsBase( - "bukkit", - serverUUID, - serviceId, - enabled, - this::appendPlatformData, - this::appendServiceData, - submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask), - plugin::isEnabled, - (message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error), - (message) -> this.plugin.getLogger().log(Level.INFO, message), - logErrors, - logSentData, - logResponseStatusText); - } - - /** - * Adds a custom chart. - * - * @param chart The chart to add. - */ - public void addCustomChart(CustomChart chart) { - metricsBase.addCustomChart(chart); - } - - private void appendPlatformData(JsonObjectBuilder builder) { - builder.appendField("playerAmount", getPlayerAmount()); - builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0); - builder.appendField("bukkitVersion", Bukkit.getVersion()); - builder.appendField("bukkitName", Bukkit.getName()); - builder.appendField("javaVersion", System.getProperty("java.version")); - builder.appendField("osName", "SunOS"); - builder.appendField("osArch", System.getProperty("os.arch")); - builder.appendField("osVersion", "5.11"); - builder.appendField("coreCount", Runtime.getRuntime().availableProcessors()); - } - - private void appendServiceData(JsonObjectBuilder builder) { - builder.appendField("pluginVersion", plugin.getDescription().getVersion()); - } - - private int getPlayerAmount() { - try { - // Around MC 1.8 the return type was changed from an array to a collection, - // This fixes java.lang.NoSuchMethodError: - // org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; - Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); - return onlinePlayersMethod.getReturnType().equals(Collection.class) - ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() - : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; - } catch (Exception e) { - // Just use the new method if the reflection failed - return Bukkit.getOnlinePlayers().size(); - } - } - - public static class MetricsBase { - - /** The version of the Metrics class. */ - public static final String METRICS_VERSION = "2.2.1"; - - private static final ScheduledExecutorService scheduler = - Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics")); - - private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s"; - - private final String platform; - - private final String serverUuid; - - private final int serviceId; - - private final Consumer appendPlatformDataConsumer; - - private final Consumer appendServiceDataConsumer; - - private final Consumer submitTaskConsumer; - - private final Supplier checkServiceEnabledSupplier; - - private final BiConsumer errorLogger; - - private final Consumer infoLogger; - - private final boolean logErrors; - - private final boolean logSentData; - - private final boolean logResponseStatusText; - - private final Set customCharts = new HashSet<>(); - - private final boolean enabled; - - /** - * Creates a new MetricsBase class instance. - * - * @param platform The platform of the service. - * @param serviceId The id of the service. - * @param serverUuid The server uuid. - * @param enabled Whether or not data sending is enabled. - * @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and - * appends all platform-specific data. - * @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and - * appends all service-specific data. - * @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be - * used to delegate the data collection to a another thread to prevent errors caused by - * concurrency. Can be {@code null}. - * @param checkServiceEnabledSupplier A supplier to check if the service is still enabled. - * @param errorLogger A consumer that accepts log message and an error. - * @param infoLogger A consumer that accepts info log messages. - * @param logErrors Whether or not errors should be logged. - * @param logSentData Whether or not the sent data should be logged. - * @param logResponseStatusText Whether or not the response status text should be logged. - */ - public MetricsBase( - String platform, - String serverUuid, - int serviceId, - boolean enabled, - Consumer appendPlatformDataConsumer, - Consumer appendServiceDataConsumer, - Consumer submitTaskConsumer, - Supplier checkServiceEnabledSupplier, - BiConsumer errorLogger, - Consumer infoLogger, - boolean logErrors, - boolean logSentData, - boolean logResponseStatusText) { - this.platform = platform; - this.serverUuid = serverUuid; - this.serviceId = serviceId; - this.enabled = enabled; - this.appendPlatformDataConsumer = appendPlatformDataConsumer; - this.appendServiceDataConsumer = appendServiceDataConsumer; - this.submitTaskConsumer = submitTaskConsumer; - this.checkServiceEnabledSupplier = checkServiceEnabledSupplier; - this.errorLogger = errorLogger; - this.infoLogger = infoLogger; - this.logErrors = logErrors; - this.logSentData = logSentData; - this.logResponseStatusText = logResponseStatusText; - checkRelocation(); - if (enabled) { - startSubmitting(); - } - } - - public void addCustomChart(CustomChart chart) { - this.customCharts.add(chart); - } - - private void startSubmitting() { - final Runnable submitTask = - () -> { - if (!enabled || !checkServiceEnabledSupplier.get()) { - // Submitting data or service is disabled - scheduler.shutdown(); - return; - } - if (submitTaskConsumer != null) { - submitTaskConsumer.accept(this::submitData); - } else { - this.submitData(); - } - }; - // Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution - // of requests on the - // bStats backend. To circumvent this problem, we introduce some randomness into the initial - // and second delay. - // WARNING: You must not modify and part of this Metrics class, including the submit delay or - // frequency! - // WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it! - long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3)); - long secondDelay = (long) (1000 * 60 * (Math.random() * 30)); - scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS); - scheduler.scheduleAtFixedRate( - submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS); - } - - private void submitData() { - final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder(); - appendPlatformDataConsumer.accept(baseJsonBuilder); - final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder(); - appendServiceDataConsumer.accept(serviceJsonBuilder); - JsonObjectBuilder.JsonObject[] chartData = - customCharts.stream() - .map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors)) - .filter(Objects::nonNull) - .toArray(JsonObjectBuilder.JsonObject[]::new); - serviceJsonBuilder.appendField("id", serviceId); - serviceJsonBuilder.appendField("customCharts", chartData); - baseJsonBuilder.appendField("service", serviceJsonBuilder.build()); - baseJsonBuilder.appendField("serverUUID", serverUuid); - baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION); - JsonObjectBuilder.JsonObject data = baseJsonBuilder.build(); - scheduler.execute( - () -> { - try { - // Send the data - sendData(data); - } catch (Exception e) { - // Something went wrong! :( - if (logErrors) { - errorLogger.accept("Could not submit bStats metrics data", e); - } - } - }); - } - - private void sendData(JsonObjectBuilder.JsonObject data) throws Exception { - if (logSentData) { - infoLogger.accept("Sent bStats metrics data: " + data.toString()); - } - String url = String.format(REPORT_URL, platform); - HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); - // Compress the data to save bandwidth - byte[] compressedData = compress(data.toString()); - connection.setRequestMethod("POST"); - connection.addRequestProperty("Accept", "application/json"); - connection.addRequestProperty("Connection", "close"); - connection.addRequestProperty("Content-Encoding", "gzip"); - connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("User-Agent", "Metrics-Service/1"); - connection.setDoOutput(true); - try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) { - outputStream.write(compressedData); - } - StringBuilder builder = new StringBuilder(); - try (BufferedReader bufferedReader = - new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - String line; - while ((line = bufferedReader.readLine()) != null) { - builder.append(line); - } - } - if (logResponseStatusText) { - infoLogger.accept("Sent data to bStats and received response: " + builder); - } - } - - /** Checks that the class was properly relocated. */ - private void checkRelocation() { - // You can use the property to disable the check in your test environment - if (System.getProperty("bstats.relocatecheck") == null - || !System.getProperty("bstats.relocatecheck").equals("false")) { - // Maven's Relocate is clever and changes strings, too. So we have to use this little - // "trick" ... :D - final String defaultPackage = - new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'}); - final String examplePackage = - new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); - // We want to make sure no one just copy & pastes the example and uses the wrong package - // names - if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage) - || MetricsBase.class.getPackage().getName().startsWith(examplePackage)) { - throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); - } - } - } - - /** - * Gzips the given string. - * - * @param str The string to gzip. - * @return The gzipped string. - */ - private static byte[] compress(final String str) throws IOException { - if (str == null) { - return null; - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) { - gzip.write(str.getBytes(StandardCharsets.UTF_8)); - } - return outputStream.toByteArray(); - } - } - - public static class AdvancedBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class SimpleBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimpleBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - for (Map.Entry entry : map.entrySet()) { - valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()}); - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class MultiLineChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public MultiLineChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class AdvancedPie extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedPie(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public abstract static class CustomChart { - - private final String chartId; - - protected CustomChart(String chartId) { - if (chartId == null) { - throw new IllegalArgumentException("chartId must not be null"); - } - this.chartId = chartId; - } - - public JsonObjectBuilder.JsonObject getRequestJsonObject( - BiConsumer errorLogger, boolean logErrors) { - JsonObjectBuilder builder = new JsonObjectBuilder(); - builder.appendField("chartId", chartId); - try { - JsonObjectBuilder.JsonObject data = getChartData(); - if (data == null) { - // If the data is null we don't send the chart. - return null; - } - builder.appendField("data", data); - } catch (Throwable t) { - if (logErrors) { - errorLogger.accept("Failed to get data for custom chart with id " + chartId, t); - } - return null; - } - return builder.build(); - } - - protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception; - } - - public static class SingleLineChart extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SingleLineChart(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - int value = callable.call(); - if (value == 0) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("value", value).build(); - } - } - - public static class SimplePie extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimplePie(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - String value = callable.call(); - if (value == null || value.isEmpty()) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("value", value).build(); - } - } - - public static class DrilldownPie extends CustomChart { - - private final Callable>> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public DrilldownPie(String chartId, Callable>> callable) { - super(chartId); - this.callable = callable; - } - - @Override - public JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map> map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JsonObjectBuilder valueBuilder = new JsonObjectBuilder(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build()); - } - } - if (reallyAllSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - /** - * An extremely simple JSON builder. - * - *

While this class is neither feature-rich nor the most performant one, it's sufficient enough - * for its use-case. - */ - public static class JsonObjectBuilder { - - private StringBuilder builder = new StringBuilder(); - - private boolean hasAtLeastOneField = false; - - public JsonObjectBuilder() { - builder.append("{"); - } - - /** - * Appends a null field to the JSON. - * - * @param key The key of the field. - * @return A reference to this object. - */ - public JsonObjectBuilder appendNull(String key) { - appendFieldUnescaped(key, "null"); - return this; - } - - /** - * Appends a string field to the JSON. - * - * @param key The key of the field. - * @param value The value of the field. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, String value) { - if (value == null) { - throw new IllegalArgumentException("JSON value must not be null"); - } - appendFieldUnescaped(key, "\"" + escape(value) + "\""); - return this; - } - - /** - * Appends an integer field to the JSON. - * - * @param key The key of the field. - * @param value The value of the field. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, int value) { - appendFieldUnescaped(key, String.valueOf(value)); - return this; - } - - /** - * Appends an object to the JSON. - * - * @param key The key of the field. - * @param object The object. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, JsonObject object) { - if (object == null) { - throw new IllegalArgumentException("JSON object must not be null"); - } - appendFieldUnescaped(key, object.toString()); - return this; - } - - /** - * Appends a string array to the JSON. - * - * @param key The key of the field. - * @param values The string array. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, String[] values) { - if (values == null) { - throw new IllegalArgumentException("JSON values must not be null"); - } - String escapedValues = - Arrays.stream(values) - .map(value -> "\"" + escape(value) + "\"") - .collect(Collectors.joining(",")); - appendFieldUnescaped(key, "[" + escapedValues + "]"); - return this; - } - - /** - * Appends an integer array to the JSON. - * - * @param key The key of the field. - * @param values The integer array. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, int[] values) { - if (values == null) { - throw new IllegalArgumentException("JSON values must not be null"); - } - String escapedValues = - Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(",")); - appendFieldUnescaped(key, "[" + escapedValues + "]"); - return this; - } - - /** - * Appends an object array to the JSON. - * - * @param key The key of the field. - * @param values The integer array. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, JsonObject[] values) { - if (values == null) { - throw new IllegalArgumentException("JSON values must not be null"); - } - String escapedValues = - Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(",")); - appendFieldUnescaped(key, "[" + escapedValues + "]"); - return this; - } - - /** - * Appends a field to the object. - * - * @param key The key of the field. - * @param escapedValue The escaped value of the field. - */ - private void appendFieldUnescaped(String key, String escapedValue) { - if (builder == null) { - throw new IllegalStateException("JSON has already been built"); - } - if (key == null) { - throw new IllegalArgumentException("JSON key must not be null"); - } - if (hasAtLeastOneField) { - builder.append(","); - } - builder.append("\"").append(escape(key)).append("\":").append(escapedValue); - hasAtLeastOneField = true; - } - - /** - * Builds the JSON string and invalidates this builder. - * - * @return The built JSON string. - */ - public JsonObject build() { - if (builder == null) { - throw new IllegalStateException("JSON has already been built"); - } - JsonObject object = new JsonObject(builder.append("}").toString()); - builder = null; - return object; - } - - /** - * Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt. - * - *

This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'. - * Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n"). - * - * @param value The value to escape. - * @return The escaped value. - */ - private static String escape(String value) { - final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < value.length(); i++) { - char c = value.charAt(i); - if (c == '"') { - builder.append("\\\""); - } else if (c == '\\') { - builder.append("\\\\"); - } else if (c <= '\u000F') { - builder.append("\\u000").append(Integer.toHexString(c)); - } else if (c <= '\u001F') { - builder.append("\\u00").append(Integer.toHexString(c)); - } else { - builder.append(c); - } - } - return builder.toString(); - } - - /** - * A super simple representation of a JSON object. - * - *

This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not - * allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String, - * JsonObject)}. - */ - public static class JsonObject { - - private final String value; - - private JsonObject(String value) { - this.value = value; - } - - @Override - public String toString() { - return value; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java index 980be33d..ac6c0873 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/TotalFreedomMod.java @@ -48,6 +48,7 @@ import me.totalfreedom.totalfreedommod.util.MethodTimer; import me.totalfreedom.totalfreedommod.world.CleanroomChunkGenerator; import me.totalfreedom.totalfreedommod.world.WorldManager; import me.totalfreedom.totalfreedommod.world.WorldRestrictions; +import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.Plugin; @@ -214,7 +215,7 @@ public class TotalFreedomMod extends JavaPlugin FLog.info("Version " + pluginVersion + " for " + ServerInterface.COMPILE_NMS_VERSION + " enabled in " + timer.getTotal() + "ms"); // Metrics @ https://bstats.org/plugin/bukkit/TotalFreedomMod/2966 - new Metrics(this, 2966); + Metrics metrics = new Metrics(this, 2966); // little workaround to stop spigot from autorestarting - causing AMP to detach from process. SpigotConfig.config.set("settings.restart-on-crash", false); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java index eb056fcb..457c59c4 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java @@ -74,10 +74,11 @@ public class ActivityLogEntry implements IConfig { // Fix of Array index out of bonds issue: FS-131 String lastLoginString; - if(timestamps.size() > 1) + if (timestamps.size() > 1) { lastLoginString = timestamps.get(timestamps.size() - 1); - }else + } + else { lastLoginString = timestamps.get(0); } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/blocking/EditBlocker.java b/src/main/java/me/totalfreedom/totalfreedommod/blocking/EditBlocker.java index 831142aa..35fb4205 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/blocking/EditBlocker.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/blocking/EditBlocker.java @@ -10,23 +10,29 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; -public class EditBlocker extends FreedomService { +public class EditBlocker extends FreedomService +{ @Override - public void onStart() { + public void onStart() + { } @Override - public void onStop() { + public void onStop() + { } @EventHandler(priority = EventPriority.LOW) - public void onBlockPlace(BlockPlaceEvent event) { + public void onBlockPlace(BlockPlaceEvent event) + { FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer()); - if (!fPlayer.isEditBlocked()) { + if (!fPlayer.isEditBlocked()) + { return; } - if (plugin.al.isAdminSync(event.getPlayer())) { + if (plugin.al.isAdminSync(event.getPlayer())) + { fPlayer.setEditBlocked(false); return; } @@ -36,13 +42,16 @@ public class EditBlocker extends FreedomService { } @EventHandler(priority = EventPriority.LOW) - public void onBlockBreak(BlockBreakEvent event) { + public void onBlockBreak(BlockBreakEvent event) + { FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer()); - if (!fPlayer.isEditBlocked()) { + if (!fPlayer.isEditBlocked()) + { return; } - if (plugin.al.isAdminSync(event.getPlayer())) { + if (plugin.al.isAdminSync(event.getPlayer())) + { fPlayer.setEditBlocked(false); return; } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java index 7cde1e49..f50b8985 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_coins.java @@ -11,27 +11,39 @@ import org.bukkit.entity.Player; @CommandPermissions(level = Rank.OP, source = SourceType.BOTH) @CommandParameters(description = "Shows the amount of coins you have or another player has", usage = "/ [playername]") -public class Command_coins extends FreedomCommand { +public class Command_coins extends FreedomCommand +{ @Override - public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { - if (!ConfigEntry.SHOP_ENABLED.getBoolean()) { + public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (!ConfigEntry.SHOP_ENABLED.getBoolean()) + { msg("The shop is currently disabled!", ChatColor.RED); return true; } Player p; final String prefix = FUtil.colorize(ConfigEntry.SHOP_PREFIX.getString() + " "); - if (args.length > 0) { - if (getPlayer(args[0]) != null) { + if (args.length > 0) + { + if (getPlayer(args[0]) != null) + { p = getPlayer(args[0]); - } else { + } + else + { msg(PLAYER_NOT_FOUND); return true; } - } else { - if (senderIsConsole) { + } + else + { + if (senderIsConsole) + { msg(prefix + ChatColor.RED + "You are not a player, use /coins "); return true; - } else { + } + else + { p = playerSender; } } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory.java b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory.java index 43fc2e4e..1bc2033c 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/command/Command_namehistory.java @@ -8,10 +8,13 @@ import org.bukkit.entity.Player; @CommandPermissions(level = Rank.OP, source = SourceType.BOTH) @CommandParameters(description = "Check the name history of a specified player.", usage = "/ ", aliases = "nh") -public class Command_namehistory extends FreedomCommand { +public class Command_namehistory extends FreedomCommand +{ @Override - public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) { - if (args.length != 1) { + public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) + { + if (args.length != 1) + { return false; } History.reportHistory(sender, args[0]); diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java index 153d3a44..9d14fc1e 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java @@ -405,7 +405,7 @@ public class Discord extends FreedomService { return; } - + if (message.contains("§")) { message = StringUtils.remove(message, "§"); @@ -417,7 +417,7 @@ public class Discord extends FreedomService while (DISCORD_MENTION_MATCHER.find()) { String mention = DISCORD_MENTION_MATCHER.group(1); - message = message.replace(mention, mention.replace("@","")); + message = message.replace(mention, mention.replace("@", "")); } if (enabled && !chat_channel_id.isEmpty()) @@ -439,7 +439,7 @@ public class Discord extends FreedomService { return; } - + if (message.contains("§")) { message = StringUtils.remove(message, "§"); @@ -451,7 +451,7 @@ public class Discord extends FreedomService while (DISCORD_MENTION_MATCHER.find()) { String mention = DISCORD_MENTION_MATCHER.group(1); - message = message.replace(mention, mention.replace("@","")); + message = message.replace(mention, mention.replace("@", "")); } if (enabled && !chat_channel_id.isEmpty()) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToAdminChatListener.java b/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToAdminChatListener.java index 4e0ff6fb..51521161 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToAdminChatListener.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/discord/DiscordToAdminChatListener.java @@ -48,7 +48,7 @@ public class DiscordToAdminChatListener extends ListenerAdapter if (!msg.getAttachments().isEmpty()) { - + logmessage.append(mediamessage); // Actually for logging... } diff --git a/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDaemon.java b/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDaemon.java index 177df52a..4cc44553 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDaemon.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/httpd/HTTPDaemon.java @@ -146,7 +146,7 @@ public class HTTPDaemon extends FreedomService { super(port); } - + @Override public Response serve(HTTPSession session) { diff --git a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java index d246b19f..ce56d960 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/rank/RankManager.java @@ -61,7 +61,7 @@ public class RankManager extends FreedomService { return Title.EXECUTIVE; } - + if (ConfigEntry.SERVER_ASSISTANT_EXECUTIVES.getList().contains(player.getName()) && plugin.al.isAdmin(player)) { return Title.ASSTEXEC; diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java b/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java index b22d7eb8..2fc87036 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/FUtil.java @@ -275,7 +275,7 @@ public class FUtil public static Response sendRequest(String endpoint, String method, List headers, String body) throws IOException { URL url = new URL(endpoint); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod(method); @@ -405,7 +405,8 @@ public class FUtil add("s"); }}; - public static boolean isValidUsername(String s) { + public static boolean isValidUsername(String s) + { return s != null && s.matches("^[a-zA-Z0-9_]*$"); } @@ -413,7 +414,8 @@ public class FUtil { StringBuilder sb = new StringBuilder(); - regxList.forEach(obj -> { + regxList.forEach(obj -> + { if (parse.endsWith(obj)) { sb.append(parse.split(obj)[0]); @@ -572,7 +574,7 @@ public class FUtil { Field field = checkClass.getDeclaredField(name); field.setAccessible(true); - return (T) field.get(from); + return (T)field.get(from); } catch (NoSuchFieldException | IllegalAccessException ignored) @@ -654,7 +656,7 @@ public class FUtil public static int randomInteger(int min, int max) { int range = max - min + 1; - return (int) (Math.random() * range) + min; + return (int)(Math.random() * range) + min; } public static String randomString(int length) @@ -792,7 +794,7 @@ public class FUtil { c1values[i] = Math.round(c1values[i] + factor * (c2values[i] - c1values[i])); } - return Color.fromRGB((int) c1values[0], (int) c1values[1], (int) c1values[2]); + return Color.fromRGB((int)c1values[0], (int)c1values[1], (int)c1values[2]); } public static boolean isValidIPv4(String ip) @@ -890,7 +892,7 @@ public class FUtil public int getPageCount() { - return (int) Math.ceil((double) size() / (double) epp); + return (int)Math.ceil((double)size() / (double)epp); } public List getPage(int page) diff --git a/src/main/java/me/totalfreedom/totalfreedommod/util/TimeUnit.java b/src/main/java/me/totalfreedom/totalfreedommod/util/TimeUnit.java index 20132d0a..5ffe521d 100644 --- a/src/main/java/me/totalfreedom/totalfreedommod/util/TimeUnit.java +++ b/src/main/java/me/totalfreedom/totalfreedommod/util/TimeUnit.java @@ -12,11 +12,13 @@ public enum TimeUnit private final long time; - TimeUnit(long time) { + TimeUnit(long time) + { this.time = time; } - public long get() { + public long get() + { return time; } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 1c2b05ca..82105ed1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -37,7 +37,7 @@ server: executives: [ ] # All players who show up as assistant executive - assistant_executives: [] + assistant_executives: [ ] # All those who can manage the master builder list master_builder_management: [ ] @@ -194,7 +194,7 @@ social_links: Forum: 'https://forum.totalfreedom.me' Website: 'https://totalfreedom.me' Discord: 'https://discord.com/invite/PW4savJR9a' -# Reddit: 'https://reddit.com/r/TotalFreedom' + # Reddit: 'https://reddit.com/r/TotalFreedom' Twitter: 'https://twitter.com/TotalFreedomMC' Facebook: 'https://facebook.com/TotalFreedomMC' # Tumblr: 'https://totalfreedom.tumblr.com' @@ -556,7 +556,7 @@ announcer: - 'Join our Discord server! https://discord.com/invite/PW4savJR9a' - 'Remember to save your hotbar, otherwise you may lose your items!' - 'Link your discord account with &6/linkdiscord for extra features!' - # - 'Check out our reddit at &6https://www.reddit.com/r/TotalFreedom/ &byou can even link your account!' + # - 'Check out our reddit at &6https://www.reddit.com/r/TotalFreedom/ &byou can even link your account!' - 'Want to see cool builds? Check out our Master Builder World with &6/mbworld' - 'Be sure to follow our twitter for all the latest updates. &6https://twitter.com/totalfreedommc' @@ -573,7 +573,7 @@ admininfo: votinginfo: - '&bVoting Links:' - ' &2- https://minecraft-mp.com/server/228386/vote/' -# - ' &2- https://minecraft-server-list.com/server/443272/vote/' + # - ' &2- https://minecraft-server-list.com/server/443272/vote/' - ' &6- https://topg.org/Minecraft/in-599712' - ' &2- https://minecraftlist.org/vote/18975' - ' &6- https://minecraftservers.org/vote/595721' diff --git a/src/main/resources/indefinitebans.yml b/src/main/resources/indefinitebans.yml index 4e4404ce..d561ac28 100644 --- a/src/main/resources/indefinitebans.yml +++ b/src/main/resources/indefinitebans.yml @@ -12,4 +12,4 @@ badplayer2: ips: - 111.111.111.111 badplayer3: - ips: [] + ips: [ ] diff --git a/src/main/resources/permissions.yml b/src/main/resources/permissions.yml index ae404160..eeecc442 100644 --- a/src/main/resources/permissions.yml +++ b/src/main/resources/permissions.yml @@ -68,4 +68,4 @@ admins: - "bending.*" # Senior Admin permission nodes -senior_admins: [] +senior_admins: [ ] diff --git a/supressions.xml b/supressions.xml deleted file mode 100644 index 09efa3c8..00000000 --- a/supressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file