mirror of
https://github.com/AtlasMediaGroup/TotalFreedomMod.git
synced 2025-07-01 12:36:41 +00:00
Compare commits
2 Commits
RELEASE-20
...
ptero-upda
Author | SHA1 | Date | |
---|---|---|---|
8949ee75eb | |||
d88509bf11 |
23
.github/dependabot.yml
vendored
23
.github/dependabot.yml
vendored
@ -1,23 +0,0 @@
|
|||||||
# 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://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
||||||
|
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
|
|
||||||
# Maintain Maven Updates
|
|
||||||
- package-ecosystem: "maven" # See documentation for possible values
|
|
||||||
directory: "/" # Location of package manifests
|
|
||||||
target-branch: "development"
|
|
||||||
open-pull-requests-limit: 50
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
|
|
||||||
# Maintain dependencies for GitHub Actions
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
target-branch: "development"
|
|
||||||
open-pull-requests-limit: 50
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
6
.github/workflows/codacy-analysis.yml
vendored
6
.github/workflows/codacy-analysis.yml
vendored
@ -21,11 +21,11 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Checkout the repository to the GitHub Actions runner
|
# Checkout the repository to the GitHub Actions runner
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||||
- name: Run Codacy Analysis CLI
|
- name: Run Codacy Analysis CLI
|
||||||
uses: codacy/codacy-analysis-cli-action@v4.2.0
|
uses: codacy/codacy-analysis-cli-action@1.1.0
|
||||||
with:
|
with:
|
||||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||||
# You can also omit the token and run the tools that support default configurations
|
# You can also omit the token and run the tools that support default configurations
|
||||||
@ -41,6 +41,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the SARIF file generated in the previous step
|
# Upload the SARIF file generated in the previous step
|
||||||
- name: Upload SARIF results file
|
- name: Upload SARIF results file
|
||||||
uses: github/codeql-action/upload-sarif@v2
|
uses: github/codeql-action/upload-sarif@v1
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
13
.github/workflows/codeql-analysis.yml
vendored
13
.github/workflows/codeql-analysis.yml
vendored
@ -35,18 +35,17 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup Java JDK
|
- name: Setup Java JDK
|
||||||
uses: actions/setup-java@v3.9.0
|
uses: actions/setup-java@v1.4.3
|
||||||
with:
|
with:
|
||||||
# The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x). Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28
|
# The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x). Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28
|
||||||
java-version: 17
|
java-version: 11
|
||||||
distribution: 'adopt'
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@ -57,7 +56,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@ -71,4 +70,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v1
|
||||||
|
43
.github/workflows/downstream.yml
vendored
Normal file
43
.github/workflows/downstream.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# 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: main
|
||||||
|
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
|
21
.github/workflows/java17-maven.yml
vendored
21
.github/workflows/java17-maven.yml
vendored
@ -1,21 +0,0 @@
|
|||||||
name: Java17-Maven-Build
|
|
||||||
|
|
||||||
on: [ push ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-java-17:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# Checkout the code
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# Java 16 Builds
|
|
||||||
- name: Set up JDK 17
|
|
||||||
uses: actions/setup-java@v3.9.0
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: 'adopt'
|
|
||||||
- name: Build with Maven
|
|
||||||
run: mvn -B package --file pom.xml
|
|
17
.github/workflows/maven.yml
vendored
Normal file
17
.github/workflows/maven.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Maven-Build
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Set up JDK 1.8
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
- name: Build with Maven
|
||||||
|
run: mvn -B package --file pom.xml
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -29,7 +29,7 @@ manifest.mf
|
|||||||
*.iml
|
*.iml
|
||||||
|
|
||||||
# Maven excludes
|
# Maven excludes
|
||||||
target/
|
/target
|
||||||
|
|
||||||
# OS generated files
|
# OS generated files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
13
.travis.yml
Normal file
13
.travis.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
language: java
|
||||||
|
jdk:
|
||||||
|
- oraclejdk11
|
||||||
|
- openjdk11
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- sshpass
|
||||||
|
script: mvn clean install
|
||||||
|
after_success:
|
||||||
|
- ./travis-upload.sh
|
@ -1,4 +1,3 @@
|
|||||||
# Contributing to TotalFreedomMod
|
# Contributing to TotalFreedomMod
|
||||||
|
|
||||||
For information about contributing to TotalFreedomMod, please see
|
For information about contributing to TotalFreedomMod, please see the [contributing guidelines](https://github.com/TotalFreedom/TotalFreedomMod/wiki/Contributing).
|
||||||
the [contributing guidelines](https://github.com/TotalFreedom/TotalFreedomMod/wiki/Contributing).
|
|
||||||
|
66
LICENSE.md
66
LICENSE.md
@ -14,62 +14,37 @@ All rights reserved.
|
|||||||
|
|
||||||
"Licensor" shall mean the copyright holder or entity authorised by the copyright owner that is granting the License.
|
"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
|
"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.
|
||||||
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.
|
"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,
|
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||||
documentation source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including
|
"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.
|
||||||
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
|
"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.
|
||||||
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
|
"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.
|
||||||
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
|
"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."
|
||||||
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
|
"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.
|
||||||
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
|
"Redistribution" shall mean any partial or complete availability, transfer or publication of the Work from one Legal Entity to another.
|
||||||
Entity to another.
|
|
||||||
|
|
||||||
##### 2. Grant of Copyright License
|
##### 2. Grant of Copyright License
|
||||||
|
|
||||||
Subject to the terms and conditions of this License, You are granted a perpetual, worldwide, non-exclusive, no-charge,
|
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:
|
||||||
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
|
1. Redistributions of This Software must solely occur in Source form. Redistribution in Object form is prohibited without prior written permission from the Licensor.
|
||||||
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
|
2. Neither the names of the copyright holders nor the names this software's contributors may be removed from This Software's source code.
|
||||||
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
|
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.
|
||||||
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
|
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.
|
||||||
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
|
5. Any conditions specified by this license may be temporarily or permanently waived by any the aforementioned copyright holders.
|
||||||
holders.
|
|
||||||
|
|
||||||
6. Redistributions of This Software must retain this License document in its exact form.
|
6. Redistributions of This Software must retain this License document in its exact form.
|
||||||
|
|
||||||
@ -77,17 +52,8 @@ and redistribute the Work and such Derivative Works as long as the following con
|
|||||||
|
|
||||||
##### 3. Submission of Contributions
|
##### 3. Submission of Contributions
|
||||||
|
|
||||||
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the
|
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.
|
||||||
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
|
##### 4. Disclaimer of Warranty
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
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.
|
||||||
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.
|
|
||||||
|
14
README.md
14
README.md
@ -1,14 +1,8 @@
|
|||||||
# TotalFreedomMod [](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml) [](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade) [](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml)
|
# TotalFreedomMod [](https://travis-ci.com/AtlasMediaGroup/TotalFreedomMod) [](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade)
|
||||||
|
|
||||||
TotalFreedomMod is a CraftBukkit server plugin designed primarily to support
|
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.
|
||||||
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
|
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.
|
||||||
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
|
### Contributing
|
||||||
|
|
||||||
@ -20,4 +14,4 @@ For information on our security policy and reporting an issue, please see [SECUR
|
|||||||
|
|
||||||
### Compiling
|
### Compiling
|
||||||
|
|
||||||
You need Maven to build. You'd also need to set the JDK version to Java 11 as that is the current standard as of now.
|
You need Maven to build. You'd also need to set the JDK version to Java 8 as that is the current standard as of now.
|
||||||
|
37
SECURITY.md
37
SECURITY.md
@ -2,39 +2,29 @@
|
|||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
|
|
||||||
We currently support the code running on the "main" branch and "development" branch of this repository. This is
|
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.
|
||||||
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:
|
In terms of plugin releases, our support matrix is as follows:
|
||||||
|
|
||||||
### Actively Supported
|
### 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: |
|
| Version | Supported | Support End: |
|
||||||
|---------|-----------|--------------------------|
|
| ------------------- | ------------------ | ------------------------------ |
|
||||||
| 2022.02 | ✅ | No Earlier than May 2022 |
|
| 2021.05 | :white_check_mark: | No Earlier than August 2021 |
|
||||||
|
|
||||||
### Legacy Supported
|
### 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: |
|
| Version | Supported | Support End: |
|
||||||
|---------|-----------|--------------|
|
| ------------------- | ------------------ | ------------ |
|
||||||
| 2021.09 | ⚠️ | April 2022 |
|
| 2021.04 | :white_check_mark: | July 2021 |
|
||||||
|
|
||||||
### No Longer Supported
|
### 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: |
|
| Version | Supported | Support Ended: |
|
||||||
|---------------------|-----------|----------------|
|
| ------------------- | ------------------ | ------------------- |
|
||||||
| 2021.06 | :x: | October 2021 |
|
|
||||||
| 2021.05 | :x: | September 2021 |
|
|
||||||
| 2021.04 | :x: | July 2021 |
|
|
||||||
| 2021.02 | :x: | 6 June 2021 |
|
| 2021.02 | :x: | 6 June 2021 |
|
||||||
| 2020.11 | :x: | 3 May 2021 |
|
| 2020.11 | :x: | 3 May 2021 |
|
||||||
| 6.0.x (Pre-Release) | :x: | December 2020 |
|
| 6.0.x (Pre-Release) | :x: | December 2020 |
|
||||||
@ -43,11 +33,6 @@ versions.
|
|||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
If the report has minor security implications (ie we've added a super admin to a senior admins permission) please raise
|
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.
|
||||||
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
|
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.
|
||||||
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.
|
|
||||||
|
250
commons/pom.xml
250
commons/pom.xml
@ -1,250 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>me.totalfreedom</groupId>
|
|
||||||
<artifactId>TotalFreedomMod</artifactId>
|
|
||||||
<version>2023.03</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>2.11.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.papermc</groupId>
|
|
||||||
<artifactId>paperlib</artifactId>
|
|
||||||
<version>1.0.7</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
<version>3.12.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.luckperms</groupId>
|
|
||||||
<artifactId>api</artifactId>
|
|
||||||
<version>5.4</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bstats</groupId>
|
|
||||||
<artifactId>bstats-bukkit</artifactId>
|
|
||||||
<version>3.0.1</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.reflections</groupId>
|
|
||||||
<artifactId>reflections</artifactId>
|
|
||||||
<version>0.10.2</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.sisu</groupId>
|
|
||||||
<artifactId>org.eclipse.sisu.inject</artifactId>
|
|
||||||
<version>0.3.5</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<!-- Filter resources for build.properties -->
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/resources</directory>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
|
|
||||||
<plugins>
|
|
||||||
<!-- Compiler -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.10.1</version>
|
|
||||||
<configuration>
|
|
||||||
<outputFileName>TotalFreedomMod.jar</outputFileName>
|
|
||||||
<compilerVersion>17</compilerVersion>
|
|
||||||
<source>17</source>
|
|
||||||
<target>17</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Git describe -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>pl.project13.maven</groupId>
|
|
||||||
<artifactId>git-commit-id-plugin</artifactId>
|
|
||||||
<version>4.9.10</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>get-the-git-infos</id>
|
|
||||||
<goals>
|
|
||||||
<goal>revision</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>validate-the-git-infos</id>
|
|
||||||
<goals>
|
|
||||||
<goal>validateRevision</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>package</phase>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
|
|
||||||
<prefix>git</prefix>
|
|
||||||
<dateFormat>yyyy-MM-dd HH:mm:ss</dateFormat>
|
|
||||||
<verbose>false</verbose>
|
|
||||||
<format>properties</format>
|
|
||||||
<failOnNoGitDirectory>false</failOnNoGitDirectory>
|
|
||||||
<failOnUnableToExtractRepoInfo>false</failOnUnableToExtractRepoInfo>
|
|
||||||
<includeOnlyProperties>
|
|
||||||
<includeOnlyProperty>git.commit.id.abbrev</includeOnlyProperty>
|
|
||||||
</includeOnlyProperties>
|
|
||||||
<gitDescribe>
|
|
||||||
<skip>false</skip>
|
|
||||||
<always>false</always>
|
|
||||||
<abbrev>7</abbrev>
|
|
||||||
<dirty>-dirty</dirty>
|
|
||||||
<match>*</match>
|
|
||||||
</gitDescribe>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Antrun -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>default-cli</id>
|
|
||||||
<phase>initialize</phase>
|
|
||||||
<configuration>
|
|
||||||
<target>
|
|
||||||
<propertyfile file="${project.basedir}/src/main/resources/build.properties"
|
|
||||||
comment="Build information. Edit this to your liking.">
|
|
||||||
<entry key="buildAuthor" default="unknown"/>
|
|
||||||
<entry key="buildNumber" default="0"/>
|
|
||||||
<entry key="buildCodeName" value="${tfm.build.codename}"/>
|
|
||||||
<entry key="buildVersion" value="${project.version}"/>
|
|
||||||
<entry key="buildDate" value="${timestamp}"/>
|
|
||||||
<!--suppress UnresolvedMavenProperty -->
|
|
||||||
<entry key="buildHead" value="${git.commit.id.abbrev}"/>
|
|
||||||
</propertyfile>
|
|
||||||
</target>
|
|
||||||
</configuration>
|
|
||||||
<goals>
|
|
||||||
<goal>run</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Properties -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>properties-maven-plugin</artifactId>
|
|
||||||
<version>1.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>initialize</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>read-project-properties</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<files>
|
|
||||||
<file>${project.basedir}/src/main/resources/build.properties</file>
|
|
||||||
</files>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Buildnumber -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>buildnumber-maven-plugin</artifactId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>create</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
|
|
||||||
<configuration>
|
|
||||||
<buildNumberPropertyName>maven.buildnumber</buildNumberPropertyName>
|
|
||||||
<buildNumberPropertiesFileLocation>${project.basedir}/src/main/resources/build.properties
|
|
||||||
</buildNumberPropertiesFileLocation>
|
|
||||||
<format>{0,number,#}</format>
|
|
||||||
<items>
|
|
||||||
<item>buildNumber</item>
|
|
||||||
</items>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Shade -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.3.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<minimizeJar>true</minimizeJar>
|
|
||||||
<relocations>
|
|
||||||
<relocation>
|
|
||||||
<pattern>io.papermc.lib</pattern>
|
|
||||||
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib
|
|
||||||
</shadedPattern> <!-- Replace this -->
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>org.bstats</pattern>
|
|
||||||
<shadedPattern>me.totalfreedom.totalfreedommod</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
</relocations>
|
|
||||||
<artifactSet>
|
|
||||||
<includes>
|
|
||||||
<include>org.reflections:reflections</include>
|
|
||||||
<include>io.papermc:paperlib</include>
|
|
||||||
<include>org.bstats:bstats-bukkit</include>
|
|
||||||
<include>org.bstats:bstats-base</include>
|
|
||||||
</includes>
|
|
||||||
</artifactSet>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,228 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod;
|
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
|
||||||
import me.totalfreedom.totalfreedommod.admin.Admin;
|
|
||||||
import me.totalfreedom.totalfreedommod.api.event.AdminChatEvent;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.Displayable;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.key.Key;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.SoundCategory;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class ChatManager extends FreedomService
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
||||||
public void onPlayerChat(AsyncChatEvent event)
|
|
||||||
{
|
|
||||||
// Important information for later down the line
|
|
||||||
String steamrolled = FUtil.steamroll(event.originalMessage());
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
FPlayer fPlayer = plugin.pl.getPlayer(player);
|
|
||||||
|
|
||||||
// Chat is disabled
|
|
||||||
if (!ConfigEntry.TOGGLE_CHAT.getBoolean() && !plugin.al.isAdmin(player))
|
|
||||||
{
|
|
||||||
event.getPlayer().sendMessage(FUtil.miniMessage("<red>The chat is currently disabled."));
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Locked up
|
|
||||||
else if (fPlayer.isLockedUp())
|
|
||||||
{
|
|
||||||
event.getPlayer().sendMessage(FUtil.miniMessage("<red>You are locked up and thus can't talk."));
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Admin chat is enabled
|
|
||||||
else if (fPlayer.inAdminChat())
|
|
||||||
{
|
|
||||||
adminChat(player, steamrolled, true);
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// The event was already cancelled elsewhere or the player was muted
|
|
||||||
else if (event.isCancelled() || fPlayer.isMuted())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Splitter
|
|
||||||
Component splitter = Component.text("»", NamedTextColor.DARK_GRAY);
|
|
||||||
|
|
||||||
// Message
|
|
||||||
TextComponent.Builder message = Component.text();
|
|
||||||
|
|
||||||
// Truncate the message if it's too long
|
|
||||||
if (steamrolled.length() > 256)
|
|
||||||
{
|
|
||||||
steamrolled = steamrolled.substring(0, 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Did this because sonarlint was complaining about doing the unboxing in the if statement.
|
|
||||||
// Something about returning null because it was boxed... I'm not sure.
|
|
||||||
boolean unboxed = ConfigEntry.FOURCHAN_ENABLED.getBoolean();
|
|
||||||
|
|
||||||
// Chat colorization
|
|
||||||
// -- 4chan mode --
|
|
||||||
if (steamrolled.startsWith("> ") && unboxed)
|
|
||||||
{
|
|
||||||
message.append(Component.text(steamrolled, NamedTextColor.GREEN));
|
|
||||||
}
|
|
||||||
// -- Legacy chat colors --
|
|
||||||
else if (FUtil.containsChatColor(steamrolled))
|
|
||||||
{
|
|
||||||
message.append(FUtil.colorizeAsComponent(steamrolled.replace("&k", "")));
|
|
||||||
}
|
|
||||||
// -- MiniMessage --
|
|
||||||
else
|
|
||||||
{
|
|
||||||
message.append(FUtil.miniMessage(steamrolled));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This simply filters out shit like &k in a simple but stupid way.
|
|
||||||
Component filtered = FUtil.miniMessage(FUtil.miniMessage(message.build()));
|
|
||||||
|
|
||||||
// Pinging
|
|
||||||
String steamrolledFiltered = FUtil.steamroll(filtered);
|
|
||||||
Arrays.stream(steamrolledFiltered.split(" ")).filter(string -> string.startsWith("@")).forEach(possiblePlayer ->
|
|
||||||
{
|
|
||||||
Player potential = server.getPlayer(possiblePlayer.replace("@", ""));
|
|
||||||
|
|
||||||
// Ping only that particular player
|
|
||||||
if (potential != null)
|
|
||||||
{
|
|
||||||
ping(potential);
|
|
||||||
}
|
|
||||||
// Ping everyone (if the person pinging is an admin)
|
|
||||||
else if (possiblePlayer.equalsIgnoreCase("@everyone") && plugin.al.isAdmin(player))
|
|
||||||
{
|
|
||||||
server.getOnlinePlayers().forEach(this::ping);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
event.message(filtered);
|
|
||||||
|
|
||||||
event.renderer((source, displayName, msg, viewer) -> FUtil.miniMessage("<tag><nickname> <splitter> <message>",
|
|
||||||
Placeholder.component("tag", plugin.pl.getPlayer(source).getTag().append(Component.space())),
|
|
||||||
Placeholder.component("nickname", displayName),
|
|
||||||
Placeholder.component("splitter", splitter),
|
|
||||||
Placeholder.component("message", msg)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onAdminChat(AdminChatEvent event)
|
|
||||||
{
|
|
||||||
Displayable display = event.getDisplayable();
|
|
||||||
String flatAbv = FUtil.miniMessage(display.getAbbr());
|
|
||||||
|
|
||||||
Component defaultFormat = FUtil.miniMessage("<prefix><dark_gray>[<aqua>admin<dark_gray>] <dark_red><name> <dark_gray>[<rankcolor><rank></rankcolor>]</dark_gray><white>: <gold><message>",
|
|
||||||
Placeholder.component("prefix", event.getPrefix()),
|
|
||||||
Placeholder.component("name", event.getName()),
|
|
||||||
Placeholder.unparsed("rank", flatAbv),
|
|
||||||
TagResolver.resolver("rankcolor", Tag.styling(getColor(display))),
|
|
||||||
Placeholder.component("message", event.getMessage()));
|
|
||||||
|
|
||||||
plugin.getComponentLogger().info(defaultFormat);
|
|
||||||
;
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
{
|
|
||||||
Admin admin = plugin.al.getAdmin(player);
|
|
||||||
if (!Strings.isNullOrEmpty(admin.getAcFormat()))
|
|
||||||
{
|
|
||||||
String format = admin.getAcFormat();
|
|
||||||
|
|
||||||
player.sendMessage(FUtil.miniMessage(format,
|
|
||||||
Placeholder.component("prefix", event.getPrefix()),
|
|
||||||
Placeholder.component("name", event.getName()),
|
|
||||||
Placeholder.unparsed("rank", flatAbv),
|
|
||||||
TagResolver.resolver("rankcolor", Tag.styling(getColor(display))),
|
|
||||||
Placeholder.component("message", event.getMessage())));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
player.sendMessage(defaultFormat);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextColor getColor(Displayable display)
|
|
||||||
{
|
|
||||||
return display.getColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void adminChat(Component name, Displayable displayable, Component message, boolean async)
|
|
||||||
{
|
|
||||||
AdminChatEvent event = new AdminChatEvent(name, displayable, message, async);
|
|
||||||
event.callEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void adminChat(Key key, Component prefix, Component name, Displayable displayable, Component message, boolean async)
|
|
||||||
{
|
|
||||||
AdminChatEvent event = new AdminChatEvent(key, prefix, name, displayable, message, async);
|
|
||||||
event.callEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void adminChat(CommandSender sender, String message)
|
|
||||||
{
|
|
||||||
adminChat(sender, message, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void adminChat(CommandSender sender, String message, boolean async)
|
|
||||||
{
|
|
||||||
Displayable display = plugin.rm.getDisplay(sender);
|
|
||||||
adminChat(Component.text(sender.getName()), display, Component.text(message), async);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reportAction(Player reporter, String reportedName, String report)
|
|
||||||
{
|
|
||||||
messageAllAdmins("<red>[REPORTS]</red> <gold><reporter> has reported <reported> for <reason>.",
|
|
||||||
Placeholder.unparsed("reporter", reporter.getName()),
|
|
||||||
Placeholder.unparsed("reported", reportedName),
|
|
||||||
Placeholder.unparsed("reason", report));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void messageAllAdmins(String message, TagResolver... placeholders)
|
|
||||||
{
|
|
||||||
Component parsed = FUtil.miniMessage(message, placeholders);
|
|
||||||
plugin.getComponentLogger().info(parsed);
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
player.sendMessage(parsed));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void broadcastSplit(String forAdmins, String forOperators, TagResolver... placeholders)
|
|
||||||
{
|
|
||||||
messageAllAdmins(forAdmins, placeholders);
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
player.sendMessage(FUtil.miniMessage(forOperators, placeholders)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ping(Player player)
|
|
||||||
{
|
|
||||||
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, SoundCategory.MASTER, 1337F, 0.9F);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
|
||||||
|
|
||||||
public class CommandSpy extends FreedomService
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event)
|
|
||||||
{
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)
|
|
||||||
&& plugin.al.getAdmin(player).getCommandSpy() && player != event.getPlayer()).forEach(player ->
|
|
||||||
player.sendMessage(Component.text(event.getPlayer().getName()).append(Component.text(": "))
|
|
||||||
.append(Component.text(event.getMessage())).color(NamedTextColor.GRAY)));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
public class VanishHandler extends FreedomService
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
|
||||||
public void onPlayerJoin(PlayerJoinEvent event)
|
|
||||||
{
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
server.getOnlinePlayers().stream().filter(pl -> !plugin.al.isAdmin(player)
|
|
||||||
&& plugin.al.isVanished(pl.getUniqueId())).forEach(pl -> player.hidePlayer(plugin, pl));
|
|
||||||
|
|
||||||
server.getOnlinePlayers().stream().filter(pl -> !plugin.al.isAdmin(pl)
|
|
||||||
&& plugin.al.isVanished(player.getUniqueId())).forEach(pl -> pl.hidePlayer(plugin, player));
|
|
||||||
|
|
||||||
if (plugin.al.isVanished(player.getUniqueId()))
|
|
||||||
{
|
|
||||||
plugin.esb.setVanished(player.getName(), true);
|
|
||||||
plugin.cm.messageAllAdmins("<yellow><player> has joined silently.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
event.joinMessage(null);
|
|
||||||
|
|
||||||
new BukkitRunnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (plugin.al.isVanished(player.getUniqueId()))
|
|
||||||
{
|
|
||||||
player.sendActionBar(FUtil.miniMessage("<gold>You are hidden from other players."));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
this.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskTimer(plugin, 0L, 4L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerLeave(PlayerQuitEvent event)
|
|
||||||
{
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
if (plugin.al.isVanished(player.getUniqueId()))
|
|
||||||
{
|
|
||||||
event.quitMessage(null);
|
|
||||||
plugin.cm.messageAllAdmins("<yellow><player> has left silently.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.api;
|
|
||||||
|
|
||||||
public class Aggregator
|
|
||||||
{
|
|
||||||
private Context<TFD4JCommons> discord;
|
|
||||||
private Context<ShoppeCommons> shoppe;
|
|
||||||
|
|
||||||
public Context<TFD4JCommons> getDiscordContext()
|
|
||||||
{
|
|
||||||
return discord;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDiscordContext(Context<TFD4JCommons> discord)
|
|
||||||
{
|
|
||||||
this.discord = discord;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context<ShoppeCommons> getShoppeContext()
|
|
||||||
{
|
|
||||||
return shoppe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShoppeContext(Context<ShoppeCommons> shoppe)
|
|
||||||
{
|
|
||||||
this.shoppe = shoppe;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.api;
|
|
||||||
|
|
||||||
public class Context<T>
|
|
||||||
{
|
|
||||||
private final T value;
|
|
||||||
|
|
||||||
public Context(T value)
|
|
||||||
{
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getValue()
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.api;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Interpolator
|
|
||||||
{
|
|
||||||
double[] interpolate(double from, double to, int max);
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.api;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
|
||||||
|
|
||||||
public interface ShoppeCommons
|
|
||||||
{
|
|
||||||
|
|
||||||
int getCoinsPerReactionWin();
|
|
||||||
|
|
||||||
void startReactionTimer();
|
|
||||||
|
|
||||||
void forceStartReaction();
|
|
||||||
|
|
||||||
void startReaction();
|
|
||||||
|
|
||||||
void endReaction(String winner);
|
|
||||||
|
|
||||||
String getShopPrefix();
|
|
||||||
|
|
||||||
String getShopTitle();
|
|
||||||
|
|
||||||
Inventory generateShopGUI(PlayerData playerData);
|
|
||||||
|
|
||||||
Inventory generateLoginMessageGUI(Player player);
|
|
||||||
|
|
||||||
boolean isRealItem(PlayerData data, ShopItem shopItem, PlayerInventory inventory, ItemStack realItem);
|
|
||||||
|
|
||||||
boolean isRealItem(PlayerData data, ShopItem shopItem, ItemStack givenItem, ItemStack realItem);
|
|
||||||
|
|
||||||
ItemStack getLightningRod();
|
|
||||||
|
|
||||||
ItemStack getGrapplingHook();
|
|
||||||
|
|
||||||
ItemStack getFireBall();
|
|
||||||
|
|
||||||
ItemStack getRideablePearl();
|
|
||||||
|
|
||||||
ItemStack getStackingPotato();
|
|
||||||
|
|
||||||
ItemStack getClownFish();
|
|
||||||
|
|
||||||
boolean canAfford(int price, int coins);
|
|
||||||
|
|
||||||
int amountNeeded(int price, int coins);
|
|
||||||
|
|
||||||
ItemStack shopGUIItem(ShopItem item, PlayerData data);
|
|
||||||
|
|
||||||
ShopItem getShopItem(int slot);
|
|
||||||
|
|
||||||
String getReactionString();
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.api;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.admin.Admin;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public interface TFD4JCommons
|
|
||||||
{
|
|
||||||
void messageAdminChatChannel(String message);
|
|
||||||
|
|
||||||
void clearQueue();
|
|
||||||
|
|
||||||
void messageChatChannel(String message, boolean system);
|
|
||||||
|
|
||||||
boolean syncRoles(Admin admin, String id);
|
|
||||||
|
|
||||||
String getCode(PlayerData playerData);
|
|
||||||
|
|
||||||
String generateCode(int size);
|
|
||||||
|
|
||||||
Map<String, PlayerData> getLinkCodes();
|
|
||||||
|
|
||||||
String formatBotTag();
|
|
||||||
|
|
||||||
boolean sendReportOffline(Player reporter, OfflinePlayer reported, String reason);
|
|
||||||
|
|
||||||
boolean sendReport(Player reporter, Player reported, String reason);
|
|
||||||
|
|
||||||
boolean isEnabled();
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.api.event;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.Displayable;
|
|
||||||
import net.kyori.adventure.key.Key;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class AdminChatEvent extends Event
|
|
||||||
{
|
|
||||||
private static final HandlerList handlerList = new HandlerList();
|
|
||||||
//--
|
|
||||||
private final Key identifier;
|
|
||||||
private final Component name;
|
|
||||||
private final Displayable displayable;
|
|
||||||
private final Component message;
|
|
||||||
private Component prefix = Component.empty();
|
|
||||||
|
|
||||||
public AdminChatEvent(Key identifier, Component prefix, Component name, Displayable rank, Component message, boolean async)
|
|
||||||
{
|
|
||||||
super(async);
|
|
||||||
this.identifier = identifier;
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.name = name;
|
|
||||||
this.displayable = rank;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AdminChatEvent(Component name, Displayable rank, Component message, boolean async)
|
|
||||||
{
|
|
||||||
super(async);
|
|
||||||
this.identifier = Key.key("tfm", "default");
|
|
||||||
this.name = name;
|
|
||||||
this.displayable = rank;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HandlerList getHandlerList()
|
|
||||||
{
|
|
||||||
return handlerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull HandlerList getHandlers()
|
|
||||||
{
|
|
||||||
return handlerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key getIdentifier()
|
|
||||||
{
|
|
||||||
return identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Component getPrefix()
|
|
||||||
{
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Component getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Displayable getDisplayable()
|
|
||||||
{
|
|
||||||
return displayable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Component getMessage()
|
|
||||||
{
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,335 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.bridge;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.FreedomService;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.coreprotect.CoreProtect;
|
|
||||||
import net.coreprotect.CoreProtectAPI;
|
|
||||||
import net.coreprotect.utility.Util;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class CoreProtectBridge extends FreedomService
|
|
||||||
{
|
|
||||||
//-- Block Inspector --//
|
|
||||||
private static final Component name = Component.text("Block Inspector").color(TextColor.color(0x30ade4));
|
|
||||||
private static final Component header = Component.text("---- ").append(name)
|
|
||||||
.append(Component.text(" ---- ")).colorIfAbsent(NamedTextColor.WHITE);
|
|
||||||
private static final Component prefix = name.append(Component.text(" - ").color(NamedTextColor.WHITE))
|
|
||||||
.colorIfAbsent(NamedTextColor.WHITE);
|
|
||||||
//--
|
|
||||||
private final HashMap<UUID, Long> cooldownMap = new HashMap<>();
|
|
||||||
private HashMap<UUID, FUtil.PaginationList<CoreProtectAPI.ParseResult>> historyMap;
|
|
||||||
|
|
||||||
//---------------------//
|
|
||||||
private CoreProtectAPI coreProtectAPI = null;
|
|
||||||
|
|
||||||
public static Long getSecondsLeft(long prevTime, int timeAdd)
|
|
||||||
{
|
|
||||||
return prevTime / 1000L + timeAdd - System.currentTimeMillis() / 1000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
if (isEnabled())
|
|
||||||
{
|
|
||||||
historyMap = new HashMap<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoreProtect getCoreProtect()
|
|
||||||
{
|
|
||||||
CoreProtect coreProtect = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final Plugin coreProtectPlugin = server.getPluginManager().getPlugin("CoreProtect");
|
|
||||||
assert coreProtectPlugin != null;
|
|
||||||
if (coreProtectPlugin instanceof CoreProtect)
|
|
||||||
{
|
|
||||||
coreProtect = (CoreProtect) coreProtectPlugin;
|
|
||||||
}
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
|
||||||
FLog.severe(ex);
|
|
||||||
}
|
|
||||||
return coreProtect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoreProtectAPI getCoreProtectAPI()
|
|
||||||
{
|
|
||||||
if (coreProtectAPI == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final CoreProtect coreProtect = getCoreProtect();
|
|
||||||
|
|
||||||
coreProtectAPI = coreProtect.getAPI();
|
|
||||||
|
|
||||||
// Check if the plugin or api is not enabled, if so, return null
|
|
||||||
if (!coreProtect.isEnabled() || !coreProtectAPI.isEnabled())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
|
||||||
FLog.severe(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return coreProtectAPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabled()
|
|
||||||
{
|
|
||||||
if (!server.getPluginManager().isPluginEnabled("CoreProtect"))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CoreProtect coreProtect = getCoreProtect();
|
|
||||||
|
|
||||||
return coreProtect != null && coreProtect.isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rollback the specified player's edits that were in the last 24 hours.
|
|
||||||
public void rollback(final String name)
|
|
||||||
{
|
|
||||||
if (!isEnabled())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CoreProtectAPI coreProtect = getCoreProtectAPI();
|
|
||||||
|
|
||||||
new BukkitRunnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
coreProtect.performRollback(86400, Collections.singletonList(name), null, null, null, null, 0, null);
|
|
||||||
}
|
|
||||||
}.runTaskAsynchronously(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverts a rollback for the specified player's edits that were in the last 24 hours.
|
|
||||||
public void restore(final String name)
|
|
||||||
{
|
|
||||||
if (!isEnabled())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CoreProtectAPI coreProtect = getCoreProtectAPI();
|
|
||||||
|
|
||||||
new BukkitRunnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
coreProtect.performRestore(86400, Collections.singletonList(name), null, null, null, null, 0, null);
|
|
||||||
}
|
|
||||||
}.runTaskAsynchronously(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasHistory(Player player)
|
|
||||||
{
|
|
||||||
return historyMap.containsKey(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public FUtil.PaginationList<CoreProtectAPI.ParseResult> getHistoryForPlayer(Player player)
|
|
||||||
{
|
|
||||||
return historyMap.get(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Complexity is O(19). This should be reduced.
|
|
||||||
public void showPageToPlayer(Player player, FUtil.PaginationList<CoreProtectAPI.ParseResult> results, int pageNum)
|
|
||||||
{
|
|
||||||
if (player == null || !player.isOnline())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<CoreProtectAPI.ParseResult> page = results.getPage(pageNum);
|
|
||||||
|
|
||||||
if (page == null || page.isEmpty())
|
|
||||||
{
|
|
||||||
player.sendMessage(prefix.append(Component.text("No results were found.", NamedTextColor.WHITE)));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// This shouldn't change at all in any of the other entries, so this should be safe
|
|
||||||
Component location = Component.text(String.format("(%s, %s, %s)", results.get(0).getX(),
|
|
||||||
results.get(0).getY(), results.get(0).getZ()));
|
|
||||||
final long time = System.currentTimeMillis() / 1000;
|
|
||||||
|
|
||||||
player.sendMessage(header.append(location.color(NamedTextColor.GRAY).decorate(TextDecoration.ITALIC)));
|
|
||||||
page.forEach(entry ->
|
|
||||||
{
|
|
||||||
TextComponent.Builder line = Component.text();
|
|
||||||
|
|
||||||
// Time
|
|
||||||
line.append(Component.text(Util.getTimeSince(entry.getTime(), time, false))
|
|
||||||
.color(NamedTextColor.GRAY));
|
|
||||||
|
|
||||||
// Action
|
|
||||||
Component action = Component.text(" interacted with ");
|
|
||||||
Component symbol = Component.text(" - ", NamedTextColor.WHITE);
|
|
||||||
switch (entry.getActionId())
|
|
||||||
{
|
|
||||||
case 0 ->
|
|
||||||
{
|
|
||||||
action = Component.text(" broke ");
|
|
||||||
symbol = Component.text(" - ", NamedTextColor.RED);
|
|
||||||
}
|
|
||||||
case 1 ->
|
|
||||||
{
|
|
||||||
action = Component.text(" placed ");
|
|
||||||
symbol = Component.text(" + ", NamedTextColor.GREEN);
|
|
||||||
}
|
|
||||||
case 2 -> action = Component.text(" clicked ");
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
// Do nothing (shuts Codacy up)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Symbol, player, action, block
|
|
||||||
line.append(symbol).append(Component.text(entry.getPlayer()).color(TextColor.color(0x30ade4)))
|
|
||||||
.append(action.color(NamedTextColor.WHITE)).append(
|
|
||||||
Component.text(entry.getBlockData().getMaterial().name().toLowerCase())
|
|
||||||
.color(TextColor.color(0x30ade4)));
|
|
||||||
|
|
||||||
// Rolled back?
|
|
||||||
if (entry.isRolledBack())
|
|
||||||
{
|
|
||||||
line.decorate(TextDecoration.STRIKETHROUGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
player.sendMessage(line.append(Component.text(".", NamedTextColor.WHITE)).build());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (results.getPageCount() > 1)
|
|
||||||
{
|
|
||||||
player.sendMessage(Component.text("-----", NamedTextColor.WHITE));
|
|
||||||
|
|
||||||
// Page indicator
|
|
||||||
TextComponent.Builder indicator = Component.text();
|
|
||||||
|
|
||||||
// <-
|
|
||||||
if (pageNum > 1)
|
|
||||||
{
|
|
||||||
indicator.append(Component.text("◀ ", NamedTextColor.WHITE).clickEvent(
|
|
||||||
ClickEvent.runCommand("/ins history " + (pageNum - 1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page <current>/<total>
|
|
||||||
indicator.append(Component.text("Page ", TextColor.color(0x30ade4)).append(Component.text(pageNum + "/"
|
|
||||||
+ results.getPageCount(), NamedTextColor.WHITE)));
|
|
||||||
|
|
||||||
// ->
|
|
||||||
if (pageNum < results.getPageCount())
|
|
||||||
{
|
|
||||||
indicator.append(Component.text(" ▶", NamedTextColor.WHITE).clickEvent(
|
|
||||||
ClickEvent.runCommand("/ins history " + (pageNum + 1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// | Use /ins history <page> for advanced navigation
|
|
||||||
indicator.append(Component.text(" | ", NamedTextColor.GRAY).append(Component.text("Use ", NamedTextColor.WHITE)
|
|
||||||
.append(Component.text("/ins history <page>", TextColor.color(0x30ade4))
|
|
||||||
.clickEvent(ClickEvent.suggestCommand("/ins history ")))
|
|
||||||
.append(Component.text(" for advanced navigation", NamedTextColor.WHITE))));
|
|
||||||
|
|
||||||
player.sendMessage(indicator.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompletableFuture<FUtil.PaginationList<CoreProtectAPI.ParseResult>> lookupForPlayer(Block block, Player player)
|
|
||||||
{
|
|
||||||
cooldownMap.put(player.getUniqueId(), System.currentTimeMillis());
|
|
||||||
CoreProtectAPI api = getCoreProtectAPI();
|
|
||||||
|
|
||||||
return CompletableFuture.supplyAsync(() ->
|
|
||||||
{
|
|
||||||
historyMap.remove(player.getUniqueId());
|
|
||||||
FUtil.PaginationList<CoreProtectAPI.ParseResult> pages = new FUtil.PaginationList<>(10);
|
|
||||||
api.blockLookup(block, -1).forEach(stringArray -> pages.add(api.parseResult(stringArray)));
|
|
||||||
historyMap.put(player.getUniqueId(), pages);
|
|
||||||
return pages;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onInteract(PlayerInteractEvent event)
|
|
||||||
{
|
|
||||||
// The inspector only works if we have CoreProtect installed
|
|
||||||
if (!isEnabled())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
if ((event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)
|
|
||||||
&& plugin.pl.getData(player.getUniqueId()).hasInspection())
|
|
||||||
{
|
|
||||||
event.setCancelled(true);
|
|
||||||
Block block = event.getClickedBlock();
|
|
||||||
Optional<Long> cooldown = Optional.ofNullable(cooldownMap.get(player.getUniqueId()));
|
|
||||||
|
|
||||||
if (cooldown.isPresent() && getSecondsLeft(cooldown.get(), 3) > 0L)
|
|
||||||
{
|
|
||||||
player.sendMessage(prefix.append(Component.text("You need to wait ")
|
|
||||||
.append(Component.text(getSecondsLeft(cooldown.get(), 3)))
|
|
||||||
.append(Component.text(" seconds before you can make another query."))
|
|
||||||
.color(NamedTextColor.WHITE)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time to do a look-up.
|
|
||||||
if (block != null)
|
|
||||||
{
|
|
||||||
/* This is a hack to make it so that when you right-click, the coordinates that get used depend on
|
|
||||||
* what's in your hand. Non-blocks use the block you clicked directly, but blocks use wherever the
|
|
||||||
* block was supposed to be placed. */
|
|
||||||
ItemStack hand = player.getInventory().getItemInMainHand();
|
|
||||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && hand.getType().isBlock() && hand.getType() != Material.AIR)
|
|
||||||
{
|
|
||||||
block = block.getRelative(event.getBlockFace()).getState().getBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
lookupForPlayer(block, player).thenAccept(results ->
|
|
||||||
{
|
|
||||||
if (results.isEmpty())
|
|
||||||
{
|
|
||||||
player.sendMessage(prefix.append(Component.text("No results were found.").color(NamedTextColor.WHITE)));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
showPageToPlayer(player, results, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.bridge;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import net.luckperms.api.LuckPerms;
|
|
||||||
import net.luckperms.api.track.TrackManager;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
|
||||||
import org.bukkit.plugin.UnknownDependencyException;
|
|
||||||
|
|
||||||
public class LuckPermsBridge
|
|
||||||
{
|
|
||||||
private final LuckPerms luckPerms;
|
|
||||||
|
|
||||||
public LuckPermsBridge()
|
|
||||||
{
|
|
||||||
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager()
|
|
||||||
.getRegistration(LuckPerms.class);
|
|
||||||
|
|
||||||
if (provider == null) throw new UnknownDependencyException("LuckPerms must be present!");
|
|
||||||
|
|
||||||
this.luckPerms = provider.getProvider();
|
|
||||||
|
|
||||||
setupTracks();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LuckPerms getAPI()
|
|
||||||
{
|
|
||||||
return luckPerms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupTracks()
|
|
||||||
{
|
|
||||||
TrackManager trackManager = getAPI().getTrackManager();
|
|
||||||
|
|
||||||
if (!trackManager.isLoaded("fakeOp"))
|
|
||||||
{
|
|
||||||
trackManager.createAndLoadTrack("fakeOp").whenComplete((track, exception) ->
|
|
||||||
{
|
|
||||||
track.appendGroup(TotalFreedomMod.getPlugin().getHierarchy().groups().getNonOp().getLuckPermsGroup());
|
|
||||||
track.appendGroup(TotalFreedomMod.getPlugin().getHierarchy().groups().getOp().getLuckPermsGroup());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!trackManager.isLoaded("admin"))
|
|
||||||
{
|
|
||||||
trackManager.createAndLoadTrack("admin").whenComplete((track, exception) ->
|
|
||||||
{
|
|
||||||
track.appendGroup(TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin().getLuckPermsGroup());
|
|
||||||
track.appendGroup(TotalFreedomMod.getPlugin().getHierarchy().groups().getSeniorAdmin().getLuckPermsGroup());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!trackManager.isLoaded("builder"))
|
|
||||||
{
|
|
||||||
trackManager.createAndLoadTrack("builder").whenComplete((track, exception) ->
|
|
||||||
track.appendGroup(TotalFreedomMod.getPlugin()
|
|
||||||
.getHierarchy()
|
|
||||||
.groups()
|
|
||||||
.getMasterBuilder()
|
|
||||||
.getLuckPermsGroup()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Intercept("banlist")
|
|
||||||
@CommandPermissions(permission = "banlist", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Shows all banned player names. Admins may optionally use 'purge' to clear the list.", usage = "/<command> [purge]")
|
|
||||||
public class Command_banlist extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length > 0)
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("purge"))
|
|
||||||
{
|
|
||||||
checkPermission("tfm.banlist.purge");
|
|
||||||
FUtil.adminAction(sender.getName(), "Purging the ban list", true);
|
|
||||||
msgNew("<green>Purged <amount> player bans.", Placeholder.unparsed("amount", String.valueOf(plugin.bm.purge())));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("<total> player bans (<usernames> usernames, <ips> IPs)",
|
|
||||||
Placeholder.unparsed("total", String.valueOf(plugin.bm.getAllBans().size())),
|
|
||||||
Placeholder.unparsed("usernames", String.valueOf(plugin.bm.getUsernameBans())),
|
|
||||||
Placeholder.unparsed("ips", String.valueOf(plugin.bm.getIpBans().size())));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
return args.length == 1 && sender.hasPermission("tfm.banlist.purge") ? Collections.singletonList("purge") : Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import me.totalfreedom.totalfreedommod.punishments.Punishment;
|
|
||||||
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "blockedit", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Restricts/restores block modification abilities for everyone on the server or a certain player.", usage = "/<command> [<player> [reason] | list | purge | all]")
|
|
||||||
public class Command_blockedit extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, String[] args, final boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length > 0)
|
|
||||||
{
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "list" ->
|
|
||||||
{
|
|
||||||
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
plugin.pl.getPlayer(player).isEditBlocked()).sorted().toList();
|
|
||||||
|
|
||||||
boolean plural = list.size() != 1;
|
|
||||||
msgNew("There <grammar> <count> player<plural> online with restricted block modification abilities: <players>",
|
|
||||||
Placeholder.unparsed("grammar", plural ? "are" : "is"),
|
|
||||||
Placeholder.unparsed("count", String.valueOf(list.size())),
|
|
||||||
Placeholder.unparsed("plural", plural ? "s" : ""),
|
|
||||||
Placeholder.unparsed("colon", list.size() > 0 ? ":" : "."),
|
|
||||||
Placeholder.unparsed("players", FUtil.listToString(list.stream().map(HumanEntity::getName).toList())));
|
|
||||||
}
|
|
||||||
case "purge" ->
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restoring block modification abilities for all players", true);
|
|
||||||
|
|
||||||
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
plugin.pl.getPlayer(player).isEditBlocked()).toList();
|
|
||||||
|
|
||||||
list.forEach(player ->
|
|
||||||
{
|
|
||||||
plugin.pl.getPlayer(player).setEditBlocked(false);
|
|
||||||
msgNew(player, "<green>Your block modification abilities have been restored.");
|
|
||||||
});
|
|
||||||
|
|
||||||
msgNew("Restored block modification abilities for <count> player<plural>.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(list.size())),
|
|
||||||
Placeholder.unparsed("plural", list.size() != 1 ? "s" : ""));
|
|
||||||
}
|
|
||||||
case "all", "-a" ->
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restricting block modification abilities for all non-admins", true);
|
|
||||||
|
|
||||||
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
!plugin.al.isAdmin(player)).toList();
|
|
||||||
|
|
||||||
list.forEach(player ->
|
|
||||||
{
|
|
||||||
plugin.pl.getPlayer(player).setEditBlocked(true);
|
|
||||||
msgNew(player, "<red>Your block modification abilities have been restricted.");
|
|
||||||
});
|
|
||||||
|
|
||||||
msgNew("Restricted block modification abilities for <count> player<plural>.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(list.size())),
|
|
||||||
Placeholder.unparsed("plural", list.size() != 1 ? "s" : ""));
|
|
||||||
}
|
|
||||||
default -> Optional.ofNullable(getPlayer(args[0])).ifPresentOrElse(player ->
|
|
||||||
{
|
|
||||||
FPlayer fPlayer = plugin.pl.getPlayer(player);
|
|
||||||
|
|
||||||
if (fPlayer.isEditBlocked())
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restoring block modification abilities for " + player.getName(), true);
|
|
||||||
fPlayer.setEditBlocked(false);
|
|
||||||
msgNew("Restored block modification abilities for <player>.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
msgNew(player, "<green>Your block modification abilities have been restored.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
if (plugin.al.isAdmin(player))
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is an admin, and as such cannot have their block modification abilities restricted.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restricting block modification abilities for " + player.getName(), true);
|
|
||||||
fPlayer.setEditBlocked(true);
|
|
||||||
msgNew("Restricted block modification abilities for <player>.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
msgNew(player, "<red>Your block modification abilities have been restricted.");
|
|
||||||
|
|
||||||
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player),
|
|
||||||
sender.getName(), PunishmentType.BLOCKEDIT, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, () -> msg(PLAYER_NOT_FOUND));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import me.totalfreedom.totalfreedommod.punishments.Punishment;
|
|
||||||
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "blockpvp", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Toggle PVP mode for everyone or a certain player.", usage = "/<command> [<player> | list | purge | all]", aliases = "pvpblock,pvpmode")
|
|
||||||
public class Command_blockpvp extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, String[] args, final boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
// List
|
|
||||||
case "list" ->
|
|
||||||
{
|
|
||||||
List<String> restricted = server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
plugin.pl.getPlayer(player).isPvpBlocked()).map(Player::getName).toList();
|
|
||||||
|
|
||||||
if (restricted.isEmpty())
|
|
||||||
{
|
|
||||||
msgNew("Nobody currently has their PVP abilities restricted.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("PVP abilities are restricted for these player(s): <players>",
|
|
||||||
Placeholder.unparsed("players", FUtil.listToString(restricted)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Purge
|
|
||||||
case "purge" ->
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restoring PVP abilities for all players", true);
|
|
||||||
List<? extends Player> affected = server.getOnlinePlayers().stream().filter(player -> plugin.pl.getPlayer(player).isPvpBlocked()).toList();
|
|
||||||
affected.forEach(player ->
|
|
||||||
{
|
|
||||||
msgNew(player, "<green>Your PVP abilities have been restored.");
|
|
||||||
plugin.pl.getPlayer(player).setPvpBlocked(false);
|
|
||||||
});
|
|
||||||
msgNew("Restored PVP abilities for <count> players.", Placeholder.unparsed("count", String.valueOf(affected.size())));
|
|
||||||
}
|
|
||||||
|
|
||||||
// All
|
|
||||||
case "all" ->
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restricting PVP capabilities for all non-admins", true);
|
|
||||||
List<? extends Player> affected = server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).toList();
|
|
||||||
affected.forEach(player ->
|
|
||||||
{
|
|
||||||
msgNew(player, "<red>Your PVP abilities have been restricted.");
|
|
||||||
plugin.pl.getPlayer(player).setPvpBlocked(true);
|
|
||||||
});
|
|
||||||
msgNew("Restricted PVP abilities for <count> players.", Placeholder.unparsed("count", String.valueOf(affected.size())));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific players
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
final Player p = getPlayer(args[0]);
|
|
||||||
if (p == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final FPlayer pd = plugin.pl.getPlayer(p);
|
|
||||||
if (pd.isPvpBlocked())
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Restoring PVP capabilities for " + p.getName(), true);
|
|
||||||
pd.setPvpBlocked(false);
|
|
||||||
msgNew("Enabled the ability to PVP for <player>.", Placeholder.unparsed("player", p.getName()));
|
|
||||||
msgNew(p, "<green>Your PVP abilities have been restored.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
if (plugin.al.isAdmin(p))
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is an admin, and cannot have their PVP disabled.", Placeholder.unparsed("player", p.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Restricting PVP for " + p.getName(), true);
|
|
||||||
pd.setPvpBlocked(true);
|
|
||||||
plugin.pul.logPunishment(new Punishment(p.getName(), FUtil.getIp(p), sender.getName(), PunishmentType.BLOCKPVP, null));
|
|
||||||
|
|
||||||
msgNew(p, "<red>Your PVP abilities have been restricted.");
|
|
||||||
msgNew("Restricted PVP abilities for <player>. ", Placeholder.unparsed("player", p.getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "cleanchat", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Clears the chat.", usage = "/<command>", aliases = "cc")
|
|
||||||
public class Command_cleanchat extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
msg(player, Component.space());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Cleared chat", true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.api.ShopItem;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandDependencies({"TF-Shoppe"})
|
|
||||||
@CommandPermissions(permission = "clownfish", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Obtain a clown fish", usage = "/<command>")
|
|
||||||
public class Command_clownfish extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Shop is currently disabled.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.pl.getData(playerSender).hasItem(ShopItem.CLOWN_FISH))
|
|
||||||
{
|
|
||||||
playerSender.getInventory().addItem(plugin.sh.getClownFish());
|
|
||||||
msgNew("<green>You have been given a <name>.", Placeholder.unparsed("name", ShopItem.CLOWN_FISH.getName()));
|
|
||||||
} else if (plugin.pl.getPlayer(playerSender).isClownfishDisabled())
|
|
||||||
{
|
|
||||||
msgNew("<red>An admin has disabled your ability to use the <name>. Guess you were the clown after all.",
|
|
||||||
Placeholder.unparsed("name", ShopItem.CLOWN_FISH.getName()));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<red>You don't own a <name>! Purchase one from the shop.", Placeholder.unparsed("name", ShopItem.CLOWN_FISH.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,148 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@CommandDependencies({"TF-Shoppe"})
|
|
||||||
@CommandPermissions(permission = "coins", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Shows the amount of coins you or another player has. Also allows you to give coins to other players.", usage = "/<command> [player] | pay <player> <amount>")
|
|
||||||
public class Command_coins extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null || !ConfigEntry.SHOP_ENABLED.getBoolean())
|
|
||||||
{
|
|
||||||
msgNew("<red>The shop is currently disabled!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args.length)
|
|
||||||
{
|
|
||||||
// Mode for seeing how many coins the sender has (doesn't work from console)
|
|
||||||
case 0 ->
|
|
||||||
{
|
|
||||||
if (senderIsConsole)
|
|
||||||
{
|
|
||||||
msgNew("When used from the console, you must define a target player.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
PlayerData playerData = getData(playerSender);
|
|
||||||
msgNew("<green>You have <gold><coins></gold> coin<plural>.",
|
|
||||||
Placeholder.unparsed("coins", String.valueOf(playerData.getCoins())),
|
|
||||||
Placeholder.unparsed("plural", playerData.getCoins() > 1 ? "s" : ""));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Mode for seeing how many coins a player has.
|
|
||||||
case 1 ->
|
|
||||||
{
|
|
||||||
Player target = getPlayer(args[0]);
|
|
||||||
|
|
||||||
if (target == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
PlayerData playerData = getData(target);
|
|
||||||
msgNew("<green><gold><player></gold> has <gold><coins></gold> coin<plural>.",
|
|
||||||
Placeholder.unparsed("player", target.getName()),
|
|
||||||
Placeholder.unparsed("coins", String.valueOf(playerData.getCoins())),
|
|
||||||
Placeholder.unparsed("plural", playerData.getCoins() > 1 ? "s" : ""));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Mode for paying another player coins
|
|
||||||
case 3 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("pay"))
|
|
||||||
{
|
|
||||||
checkPlayer();
|
|
||||||
|
|
||||||
final Player target = getPlayer(args[1]);
|
|
||||||
final PlayerData senderData = getData(playerSender);
|
|
||||||
|
|
||||||
int coinsToTransfer;
|
|
||||||
|
|
||||||
// Processes args[2]
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Prevents players from trying to be cheeky with negative numbers.
|
|
||||||
coinsToTransfer = Math.max(Math.abs(Integer.parseInt(args[2])), 1);
|
|
||||||
} catch (NumberFormatException ex)
|
|
||||||
{
|
|
||||||
msgNew("<red>Invalid number: <num>", Placeholder.unparsed("num", args[2]));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevents players from performing transactions they can't afford to do.
|
|
||||||
if (senderData.getCoins() < coinsToTransfer)
|
|
||||||
{
|
|
||||||
msgNew("<red>You don't have enough coins to perform this transaction.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
PlayerData playerData = getData(target);
|
|
||||||
playerData.setCoins(playerData.getCoins() + coinsToTransfer);
|
|
||||||
senderData.setCoins(senderData.getCoins() - coinsToTransfer);
|
|
||||||
|
|
||||||
boolean plural = coinsToTransfer > 1;
|
|
||||||
|
|
||||||
msgNew(target, "<green><gold><sender></gold> has given you <gold><coins></gold> coin<plural>!",
|
|
||||||
Placeholder.unparsed("sender", sender.getName()),
|
|
||||||
Placeholder.unparsed("coins", String.valueOf(coinsToTransfer)),
|
|
||||||
Placeholder.unparsed("plural", plural ? "s" : ""));
|
|
||||||
|
|
||||||
msgNew("<green>You have given <gold><coins></gold> coin<plural> to <gold><player></gold>.",
|
|
||||||
Placeholder.unparsed("player", target.getName()),
|
|
||||||
Placeholder.unparsed("coins", String.valueOf(coinsToTransfer)),
|
|
||||||
Placeholder.unparsed("plural", plural ? "s" : ""));
|
|
||||||
|
|
||||||
plugin.pl.save(playerData);
|
|
||||||
plugin.pl.save(senderData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
List<String> options = new ArrayList<>(FUtil.getPlayerList());
|
|
||||||
|
|
||||||
options.add("pay");
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FUtil.getPlayerList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "consolesay", source = SourceType.ONLY_CONSOLE)
|
|
||||||
@CommandParameters(description = "Telnet/Console command - Send a chat message with chat formatting over telnet.", usage = "/<command> <message>", aliases = "csay")
|
|
||||||
public class Command_consolesay extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.broadcast(FUtil.miniMessage("<gray>[CONSOLE] <red><sender> <dark_gray>» <white><message>",
|
|
||||||
Placeholder.unparsed("sender", sender.getName()),
|
|
||||||
Placeholder.unparsed("message", StringUtils.join(args, " "))));
|
|
||||||
|
|
||||||
if (plugin.dc != null)
|
|
||||||
{
|
|
||||||
String message = StringUtils.join(args, " ");
|
|
||||||
plugin.dc.messageChatChannel("[CONSOLE] " + sender.getName() + " \u00BB " + ChatColor.stripColor(message), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "cookie", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "For those who have no friends - gives a cookie to everyone on the server.", usage = "/<command>")
|
|
||||||
public class Command_cookie extends FreedomCommand
|
|
||||||
{
|
|
||||||
private static final Random RANDOM = new Random();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player sender_p, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
final ItemStack heldItem = new ItemStack(Material.COOKIE);
|
|
||||||
final ItemMeta heldItemMeta = heldItem.getItemMeta();
|
|
||||||
assert heldItemMeta != null;
|
|
||||||
heldItemMeta.displayName(FUtil.miniMessage("<rainbow>Cookie"));
|
|
||||||
heldItemMeta.lore(Collections.singletonList(FUtil.miniMessage("<rainbow>But, you can have a cookie anyways,\nsince you are sad you are have no friends.")));
|
|
||||||
heldItem.setItemMeta(heldItemMeta);
|
|
||||||
|
|
||||||
server.getOnlinePlayers().forEach(player -> player.getInventory().addItem(heldItem));
|
|
||||||
server.broadcast(FUtil.miniMessage("<rainbow:" + RANDOM.nextInt() + ">Imagine that you have zero cookies and you split them evenly among zero friends. How many cookies does each person get? See? It doesn't make sense. And Cookie Monster is sad that there are no cookies, and you are sad that you have no friends."));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "debugstick", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Get a stick of happiness.", usage = "/<command>")
|
|
||||||
public class Command_debugstick extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
ItemStack itemStack = new ItemStack(Material.DEBUG_STICK);
|
|
||||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
assert itemMeta != null;
|
|
||||||
itemMeta.displayName(Component.text("Stick of Happiness", NamedTextColor.GOLD).decorate(TextDecoration.BOLD));
|
|
||||||
itemMeta.lore(Arrays.asList(
|
|
||||||
Component.text("This is the most powerful stick in the game.", NamedTextColor.RED),
|
|
||||||
Component.text("You can left click to select what you want to change.", NamedTextColor.DARK_BLUE),
|
|
||||||
Component.text("And then you can right click to change it!", NamedTextColor.DARK_GREEN),
|
|
||||||
Component.text("Isn't technology amazing?", NamedTextColor.DARK_PURPLE)
|
|
||||||
));
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
playerSender.getInventory().addItem(itemStack);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.luckperms.api.track.DemotionResult;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@Intercept("deop")
|
|
||||||
@CommandPermissions(permission = "deop", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Deop a player", usage = "/<command> <partialname>")
|
|
||||||
public class Command_deop extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length < 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean silent = false;
|
|
||||||
if (args.length == 2)
|
|
||||||
{
|
|
||||||
silent = args[1].equalsIgnoreCase("-s");
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = Bukkit.getServer().getPlayer(args[0]);
|
|
||||||
|
|
||||||
if (player == null || plugin.al.isVanished(player.getUniqueId()))
|
|
||||||
{
|
|
||||||
msg(sender, PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean b = silent;
|
|
||||||
DemotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.demoteUser(TotalFreedomMod.getPlugin().getHierarchy().op(), player);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful())
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is already non-op.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(player, YOU_ARE_NOT_OP);
|
|
||||||
|
|
||||||
if (!b)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "De-opping " + player.getName(), false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.luckperms.api.track.DemotionResult;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "deop.all", source = SourceType.BOTH, blockHostConsole = true)
|
|
||||||
@CommandParameters(description = "Deop everyone on the server.", usage = "/<command>")
|
|
||||||
public class Command_deopall extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "De-opping all players on the server", true);
|
|
||||||
|
|
||||||
server.getOnlinePlayers().forEach(player ->
|
|
||||||
{
|
|
||||||
DemotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.demoteUser(TotalFreedomMod.getPlugin().getHierarchy().op(), player);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful())
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is already non-op.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(player, YOU_ARE_NOT_OP);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "eject", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Eject any entities that are riding you.", usage = "/<command>")
|
|
||||||
public class Command_eject extends FreedomCommand
|
|
||||||
{
|
|
||||||
/* Player.getShoulderEntityLeft() and Player.getShoulderEntityRight() are deprecated, however unless
|
|
||||||
Player.getPassengers() also includes shoulders (which isn't likely, given the official documentation doesn't
|
|
||||||
state an alternative method to use instead), these methods will continue to be used here. */
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
// Uses the size of the return value of Player.getPassengers() as the starting number of entities ejected
|
|
||||||
int count = playerSender.getPassengers().size();
|
|
||||||
|
|
||||||
// Removes any entities from the sender's shoulders
|
|
||||||
if (playerSender.getShoulderEntityLeft() != null)
|
|
||||||
{
|
|
||||||
playerSender.setShoulderEntityLeft(null);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if (playerSender.getShoulderEntityRight() != null)
|
|
||||||
{
|
|
||||||
playerSender.setShoulderEntityLeft(null);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes anything riding the sender
|
|
||||||
playerSender.eject();
|
|
||||||
|
|
||||||
if (count != 0)
|
|
||||||
{
|
|
||||||
msgNew("<green><count> entit<grammar> ejected.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(count)),
|
|
||||||
Placeholder.unparsed("grammar", count == 1 ? "y was" : "ies were"));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<green>Nothing was ejected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "explosivearrows", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Make arrows explode", usage = "/<command>", aliases = "ea")
|
|
||||||
public class Command_explosivearrows extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
FPlayer player = plugin.pl.getPlayer(playerSender);
|
|
||||||
player.setExplosiveArrowsEnabled(!player.isExplosiveArrowsEnabled());
|
|
||||||
|
|
||||||
msgNew("<statuscolor>You <status> have explosive arrows.",
|
|
||||||
TagResolver.resolver("statuscolor", Tag.styling(player.isExplosiveArrowsEnabled() ? NamedTextColor.GREEN : NamedTextColor.RED)),
|
|
||||||
Placeholder.unparsed("status", player.isExplosiveArrowsEnabled() ? "now" : "no longer"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.api.ShopItem;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandDependencies({"TF-Shoppe"})
|
|
||||||
@CommandPermissions(permission = "fireball", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Obtain a fire ball", usage = "/<command>")
|
|
||||||
public class Command_fireball extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Shop is currently disabled.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.pl.getData(playerSender).hasItem(ShopItem.FIRE_BALL))
|
|
||||||
{
|
|
||||||
playerSender.getInventory().addItem(plugin.sh.getFireBall());
|
|
||||||
msgNew("<green>You have been given the <item>.", Placeholder.unparsed("item", ShopItem.FIRE_BALL.getName()));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<red>You don't own the <item>! Purchase it from the shop.", Placeholder.unparsed("item", ShopItem.FIRE_BALL.getName()));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.freeze.FreezeData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "freeze", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Freeze/Unfreeze a specified player, or all non-admins on the server.", usage = "/<command> [target | purge]", aliases = "fr")
|
|
||||||
public class Command_freeze extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
boolean gFreeze = !plugin.fm.isGlobalFreeze();
|
|
||||||
plugin.fm.setGlobalFreeze(gFreeze);
|
|
||||||
|
|
||||||
if (!gFreeze)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Unfreezing all players", false);
|
|
||||||
msgNew("Players are now free to move.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Freezing all players", false);
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !isAdmin(player)).forEach(player ->
|
|
||||||
{
|
|
||||||
FUtil.playerTitle(player, "<red>You have been frozen.", "<yellow>Please be patient and you will be unfrozen shortly.");
|
|
||||||
msgNew(player, "<red>You have been globally frozen due to an op breaking the rules, please wait and you will be unfrozen soon.");
|
|
||||||
});
|
|
||||||
|
|
||||||
msgNew("Players are now frozen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].equalsIgnoreCase("purge"))
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Unfreezing all players", false);
|
|
||||||
plugin.fm.purge();
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !isAdmin(player)).forEach(player -> FUtil.playerTitle(player, "<green>You have been unfrozen.", "<yellow>You may now move again."));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player player = getPlayer(args[0]);
|
|
||||||
|
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final FreezeData fd = plugin.pl.getPlayer(player).getFreezeData();
|
|
||||||
fd.setFrozen(!fd.isFrozen());
|
|
||||||
|
|
||||||
msgNew("<player> has been <status>.", Placeholder.unparsed("player", player.getName()),
|
|
||||||
Placeholder.unparsed("status", fd.isFrozen() ? "frozen" : "unfrozen"));
|
|
||||||
msgNew(player, "You have been <status>.", Placeholder.unparsed("status", fd.isFrozen() ? "frozen" : "unfrozen"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "inspect", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Block inspector tool for operators.", usage = "/<command> [history] [page]", aliases = "ins")
|
|
||||||
public class Command_inspect extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (!plugin.cpb.isEnabled())
|
|
||||||
{
|
|
||||||
msg("CoreProtect is not enabled on this server.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
PlayerData playerData = plugin.pl.getData(playerSender);
|
|
||||||
playerData.setInspect(!playerData.hasInspection());
|
|
||||||
plugin.pl.save(playerData);
|
|
||||||
msgNew("Block inspector <status>.", Placeholder.unparsed("status", playerData.hasInspection() ? "enabled." : "disabled."));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].equalsIgnoreCase("history"))
|
|
||||||
{
|
|
||||||
int pageIndex = 1;
|
|
||||||
|
|
||||||
if (args.length >= 2)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pageIndex = Integer.parseInt(args[1]);
|
|
||||||
} catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
msgNew("<red>Invalid number.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int godDammit = pageIndex;
|
|
||||||
Optional.ofNullable(plugin.cpb.getHistoryForPlayer(playerSender)).ifPresentOrElse(page ->
|
|
||||||
plugin.cpb.showPageToPlayer(playerSender, page, godDammit),
|
|
||||||
() -> msgNew("<red>You haven't inspected anything yet!"));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
return Collections.singletonList("history");
|
|
||||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("history") && plugin.cpb.isEnabled()
|
|
||||||
&& sender instanceof Player player && plugin.cpb.hasHistory(player))
|
|
||||||
{
|
|
||||||
return IntStream.rangeClosed(1, plugin.cpb.getHistoryForPlayer(player).getPageCount()).limit(50)
|
|
||||||
.mapToObj(String::valueOf).toList();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "kickall", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Kick all non-admins on server.", usage = "/<command>", aliases = "kickall")
|
|
||||||
public class Command_kicknoob extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Disconnecting all non-admins", true);
|
|
||||||
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
player.kick(Component.text("All non-admins were kicked by " + sender.getName() + ".", NamedTextColor.RED)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.JoinConfiguration;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Intercept("list")
|
|
||||||
@CommandPermissions(permission = "list", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Lists the real names of all online players.", usage = "/<command> [-a | -v]", aliases = "who,lsit")
|
|
||||||
public class Command_list extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length > 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListFilter listFilter;
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "-s", "-a" -> listFilter = ListFilter.ADMINS;
|
|
||||||
case "-v" ->
|
|
||||||
{
|
|
||||||
checkPermission("tfm.list.vanished");
|
|
||||||
listFilter = ListFilter.VANISHED_ADMINS;
|
|
||||||
}
|
|
||||||
case "-t" ->
|
|
||||||
{
|
|
||||||
checkPermission("tfm.list.telnet");
|
|
||||||
listFilter = ListFilter.TELNET_SESSIONS;
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
listFilter = ListFilter.PLAYERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<TextComponent> players;
|
|
||||||
|
|
||||||
if (listFilter == ListFilter.TELNET_SESSIONS && plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
players = plugin.btb.getConnectedAdmins().stream().map(admin -> Component.text(admin.getName())).toList();
|
|
||||||
msgNew("<blue>There are <red><count></red> admins connected to telnet.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(players.size())));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
players = server.getOnlinePlayers().stream().filter(pl ->
|
|
||||||
(listFilter == ListFilter.ADMINS && plugin.al.isAdmin(pl) && !plugin.al.isVanished(pl.getUniqueId()))
|
|
||||||
|| (listFilter == ListFilter.VANISHED_ADMINS && plugin.al.isVanished(pl.getUniqueId()))
|
|
||||||
|| (listFilter == ListFilter.PLAYERS && !plugin.al.isVanished(pl.getUniqueId()))).map(player ->
|
|
||||||
Component.textOfChildren(plugin.rm.getDisplay(player).getColoredTag().append(Component.text(player.getName())))).toList();
|
|
||||||
|
|
||||||
msgNew("<blue>There are <red><count></red> out of a maximum of <red><max></red> players online.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(FUtil.getFakePlayerCount())),
|
|
||||||
Placeholder.unparsed("max", String.valueOf(server.getMaxPlayers())));
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("Connected <type>: <players>",
|
|
||||||
Placeholder.unparsed("type", listFilter.name().toLowerCase().replace('_', ' ')),
|
|
||||||
Placeholder.component("players", Component.join(JoinConfiguration.commas(true), players)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum ListFilter
|
|
||||||
{
|
|
||||||
PLAYERS,
|
|
||||||
ADMINS,
|
|
||||||
VANISHED_ADMINS,
|
|
||||||
TELNET_SESSIONS
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.api.ShopItem;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "loginmessage", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Change your login message", usage = "/<command> [message]")
|
|
||||||
public class Command_loginmessage extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null && !sender.hasPermission("tfm.loginmessage.custom") || !plugin.pl.getData(playerSender).hasItem(ShopItem.LOGIN_MESSAGES) && !isAdmin(playerSender))
|
|
||||||
{
|
|
||||||
msg("You did not purchase the ability to use login messages, or the shop is not present! Purchase the ability from the shop.", ChatColor.RED);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
playerSender.openInventory(plugin.sh.generateLoginMessageGUI(playerSender));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkPermission("tfm.loginmessage.custom");
|
|
||||||
|
|
||||||
String message = StringUtils.join(args, " ");
|
|
||||||
if (!message.contains("<rank>") && !message.contains("<coloredrank>"))
|
|
||||||
{
|
|
||||||
msgNew("<red>Your login message must contain your rank. Use either \\\\<rank> or \\\\<coloredrank> to specify where you want the rank.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
int length = FUtil.steamroll(FUtil.miniMessage(message, Placeholder.unparsed("name", ""),
|
|
||||||
Placeholder.unparsed("rank", ""),
|
|
||||||
Placeholder.unparsed("coloredrank", ""),
|
|
||||||
Placeholder.unparsed("art", ""))).length();
|
|
||||||
if (length > 100)
|
|
||||||
{
|
|
||||||
msgNew("<red>Your login message cannot be more than 100 characters (excluding your rank and your name)");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
PlayerData data = getData(playerSender);
|
|
||||||
data.setLoginMessage(message);
|
|
||||||
plugin.pl.save(data);
|
|
||||||
msgNew("<green>Your login message is now the following:");
|
|
||||||
msg(plugin.rm.craftLoginMessage(playerSender, message));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,156 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.punishments.Punishment;
|
|
||||||
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Intercept("mute")
|
|
||||||
@CommandPermissions(permission = "mute", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Mutes a player with brute force.", usage = "/<command> <[-q] <player> [reason] | list | purge | all>", aliases = "stfu")
|
|
||||||
public class Command_mute extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "list" ->
|
|
||||||
{
|
|
||||||
List<String> muted = server.getOnlinePlayers().stream().filter(player -> plugin.pl.getPlayer(player).isMuted()).map(player -> player.getName()).toList();
|
|
||||||
|
|
||||||
if (muted.isEmpty())
|
|
||||||
{
|
|
||||||
msgNew("Nobody is currently muted.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("Muted players: <players>", Placeholder.unparsed("players", FUtil.listToString(muted)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "purge" ->
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Unmuting all players", true);
|
|
||||||
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
plugin.pl.getPlayer(player).isMuted()).toList();
|
|
||||||
|
|
||||||
list.forEach(player ->
|
|
||||||
{
|
|
||||||
plugin.pl.getPlayer(player).setMuted(false);
|
|
||||||
FUtil.playerTitle(player, "<red>You have been unmuted.", "<yellow>Be sure to follow the rules!");
|
|
||||||
});
|
|
||||||
|
|
||||||
msgNew("Unmuted <count> player<plural>.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(list.size())),
|
|
||||||
Placeholder.unparsed("plural", list.size() != 1 ? "s" : ""));
|
|
||||||
}
|
|
||||||
case "all" ->
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Muting all non-admins", true);
|
|
||||||
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
!plugin.al.isAdmin(player)).toList();
|
|
||||||
|
|
||||||
list.forEach(player ->
|
|
||||||
{
|
|
||||||
plugin.pl.getPlayer(player).setMuted(true);
|
|
||||||
FUtil.playerTitle(player, "<red>You have been globally muted.", "<yellow>Please be patient and you will be unmuted shortly.");
|
|
||||||
});
|
|
||||||
|
|
||||||
msgNew("Muted <count> player<plural>.",
|
|
||||||
Placeholder.unparsed("count", String.valueOf(list.size())),
|
|
||||||
Placeholder.unparsed("plural", list.size() != 1 ? "s" : ""));
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
boolean quiet = args[0].equalsIgnoreCase("-q");
|
|
||||||
|
|
||||||
// Handling the -q parameter
|
|
||||||
if (quiet)
|
|
||||||
{
|
|
||||||
if (args.length == 1) return false;
|
|
||||||
args = ArrayUtils.subarray(args, 1, args.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handling the (optional) reason
|
|
||||||
String reason = args.length > 1 ? StringUtils.join(args, " ", 1, args.length) : null;
|
|
||||||
|
|
||||||
// Showtime
|
|
||||||
Optional.ofNullable(getPlayer(args[0])).ifPresentOrElse(player ->
|
|
||||||
{
|
|
||||||
if (plugin.al.isAdmin(player))
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is an admin, and as such can't be muted.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
return;
|
|
||||||
} else if (plugin.pl.getPlayer(player).isMuted())
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is already muted.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't broadcast the mute if it was quiet
|
|
||||||
if (!quiet)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Muting " + player.getName(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutes the player
|
|
||||||
plugin.pl.getPlayer(player).setMuted(true);
|
|
||||||
|
|
||||||
// Notify the player that they have been muted
|
|
||||||
FUtil.playerTitle(player, "<red>You have been muted.", "<yellow>Be sure to follow the rules!");
|
|
||||||
msgNew(player, "<red>You have been muted by <yellow><sender>", Placeholder.unparsed("sender", sender.getName()));
|
|
||||||
|
|
||||||
// Give them the reason if one is present.
|
|
||||||
if (reason != null)
|
|
||||||
{
|
|
||||||
msgNew(player, "<red>Reason: <yellow><reason>", Placeholder.unparsed("reason", reason));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quiet)
|
|
||||||
{
|
|
||||||
msgNew("Muted <player>.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("Quietly muted <player>.", Placeholder.unparsed("player", player.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(),
|
|
||||||
PunishmentType.MUTE, reason));
|
|
||||||
}, () -> msg(PLAYER_NOT_FOUND));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (!plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
List<String> arguments = new ArrayList<>();
|
|
||||||
arguments.addAll(FUtil.getPlayerList());
|
|
||||||
arguments.addAll(Arrays.asList("list", "purge", "all"));
|
|
||||||
return arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "nickmm", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = """
|
|
||||||
Essentials Interface Command - Colorify your nickname.
|
|
||||||
For Example: /nickmm <red><name> will color your name red.
|
|
||||||
You can also use tags like <gradient> and <rainbow>.
|
|
||||||
For example: /nickmm <gradient:red:green:blue><name>""", usage = "/<command> <nickname>")
|
|
||||||
public class Command_nickmm extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (!server.getPluginManager().isPluginEnabled("Essentials"))
|
|
||||||
{
|
|
||||||
msg("Essentials is not enabled on this server.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].isEmpty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].matches(ChatColor.COLOR_CHAR + "[0-9a-fkm-o]"))
|
|
||||||
{
|
|
||||||
msgNew("<red>That nickname contains invalid characters.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component parsed = FUtil.miniMessage(args[0], Placeholder.unparsed("name", sender.getName()));
|
|
||||||
plugin.esb.setNickname(sender.getName(), FUtil.miniMessage(parsed));
|
|
||||||
msgNew("Your nickname is now: " + FUtil.miniMessage(parsed));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.luckperms.api.track.PromotionResult;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@Intercept("op")
|
|
||||||
@CommandPermissions(permission = "op", source = SourceType.BOTH, cooldown = 5)
|
|
||||||
@CommandParameters(description = "op a player", usage = "/<command> <partialname>")
|
|
||||||
public class Command_op extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length < 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean silent = false;
|
|
||||||
if (args.length == 2)
|
|
||||||
{
|
|
||||||
silent = args[1].equalsIgnoreCase("-s");
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = Bukkit.getServer().getPlayer(args[0]);
|
|
||||||
|
|
||||||
if (player == null || plugin.al.isVanished(player.getUniqueId()))
|
|
||||||
{
|
|
||||||
msg(sender, PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean b = silent;
|
|
||||||
PromotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.promoteUser(TotalFreedomMod.getPlugin().getHierarchy().op(), player);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful())
|
|
||||||
{
|
|
||||||
msgNew("<red><player> is already op!", player(player));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(player, YOU_ARE_OP);
|
|
||||||
|
|
||||||
if (!b)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Opping " + player.getName(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.luckperms.api.track.PromotionResult;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "op.all", source = SourceType.BOTH, cooldown = 30)
|
|
||||||
@CommandParameters(description = "op everyone on the server.", usage = "/<command>")
|
|
||||||
public class Command_opall extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Opping all players on the server", true);
|
|
||||||
|
|
||||||
server.getOnlinePlayers().forEach(player ->
|
|
||||||
{
|
|
||||||
PromotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.promoteUser(TotalFreedomMod.getPlugin().getHierarchy().op(), player);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful())
|
|
||||||
{
|
|
||||||
msgNew("<red>Player is already op!", player(player));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(player, YOU_ARE_OP);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.luckperms.api.track.PromotionResult;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "opme", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "OPs the command sender.", usage = "/<command>")
|
|
||||||
public class Command_opme extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
FUtil.adminAction(sender.getName(), "Opping " + sender.getName(), false);
|
|
||||||
PromotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.promoteUser(TotalFreedomMod.getPlugin().getHierarchy().op(), playerSender);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful())
|
|
||||||
{
|
|
||||||
msgNew("<red>You are already op!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(YOU_ARE_OP);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.plugin.PluginManager;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "plugincontrol", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Enable, disable, or reload a specified plugin, as well as list all plugins on the server.", usage = "/<command> <<enable | disable | reload> <pluginname>> | list>", aliases = "plc")
|
|
||||||
public class Command_plugincontrol extends FreedomCommand
|
|
||||||
{
|
|
||||||
private final List<String> UNTOUCHABLE_PLUGINS = Arrays.asList(plugin.getName());
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
final PluginManager pm = server.getPluginManager();
|
|
||||||
|
|
||||||
/* This is the way it is because there was too much "if the arguments aren't enough then return false" in the
|
|
||||||
* original code in addition to the stupid amount of "if something isn't right then do some boilerplate stuff
|
|
||||||
* then return true". Codacy complained, so I aggressively optimized this to keep it quiet. */
|
|
||||||
switch (args.length)
|
|
||||||
{
|
|
||||||
case 1 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("list"))
|
|
||||||
{
|
|
||||||
Arrays.stream(pm.getPlugins()).forEach(pl ->
|
|
||||||
{
|
|
||||||
final String version = pl.getDescription().getVersion();
|
|
||||||
msgNew("<gray>- <statuscolor><name><version> by <authors>",
|
|
||||||
TagResolver.resolver("statuscolor", Tag.styling(pl.isEnabled() ? NamedTextColor.GREEN : NamedTextColor.RED)),
|
|
||||||
Placeholder.unparsed("name", pl.getName()),
|
|
||||||
Placeholder.unparsed("version", version.isEmpty() ? " v" + version : ""),
|
|
||||||
Placeholder.unparsed("authors", StringUtils.join(pl.getDescription().getAuthors(), ", ")));
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 2 ->
|
|
||||||
{
|
|
||||||
Plugin pl = pm.getPlugin(args[1]);
|
|
||||||
|
|
||||||
if (pl != null)
|
|
||||||
{
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "enable" ->
|
|
||||||
{
|
|
||||||
if (pl.isEnabled())
|
|
||||||
{
|
|
||||||
msgNew("<red><plugin> is already enabled.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pm.enablePlugin(pl);
|
|
||||||
|
|
||||||
if (pl.isEnabled())
|
|
||||||
{
|
|
||||||
msgNew("<green><plugin> is now enabled.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<red>An error occurred whilst attempting to enable <plugin>", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "disable" ->
|
|
||||||
{
|
|
||||||
if (!pl.isEnabled())
|
|
||||||
{
|
|
||||||
msgNew("<red><plugin> is already disabled.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
return true;
|
|
||||||
} else if (UNTOUCHABLE_PLUGINS.contains(pl.getName()))
|
|
||||||
{
|
|
||||||
msgNew("<red><plugin> can't be disabled.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pm.disablePlugin(pl);
|
|
||||||
|
|
||||||
msgNew("<green><plugin> is now disabled.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "reload" ->
|
|
||||||
{
|
|
||||||
if (UNTOUCHABLE_PLUGINS.contains(pl.getName()))
|
|
||||||
{
|
|
||||||
msgNew("<red><plugin> can't be reloaded.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pm.disablePlugin(pl);
|
|
||||||
pm.enablePlugin(pl);
|
|
||||||
|
|
||||||
msgNew("<green><plugin> has been reloaded.", Placeholder.unparsed("plugin", pl.getName()));
|
|
||||||
;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
// Do nothing. This is here to please Codacy.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<red>Plugin not found!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
// Ditto
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (!plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
return Arrays.asList("enable", "disable", "reload", "list");
|
|
||||||
} else if (args.length == 2 && !args[0].equalsIgnoreCase("list"))
|
|
||||||
{
|
|
||||||
return Arrays.stream(server.getPluginManager().getPlugins()).map(Plugin::getName)
|
|
||||||
.filter(pl -> !UNTOUCHABLE_PLUGINS.contains(pl)).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,206 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Intercept("potion")
|
|
||||||
@CommandPermissions(permission = "potion", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(
|
|
||||||
description = "Manipulate your potion effects. Duration is measured in server ticks (~20 ticks per second).",
|
|
||||||
usage = "/<command> <list | clearall | clear [target name] | add <type> <duration> <amplifier> [target name]>",
|
|
||||||
aliases = "effect")
|
|
||||||
public class Command_potion extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
switch (args.length)
|
|
||||||
{
|
|
||||||
case 1 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("list"))
|
|
||||||
{
|
|
||||||
msg("Potion effect types: " + FUtil.listToString(Arrays.stream(PotionEffectType.values())
|
|
||||||
.map(PotionEffectType::getName).toList()), ChatColor.AQUA);
|
|
||||||
} else if (args[0].equalsIgnoreCase("clearall"))
|
|
||||||
{
|
|
||||||
if (!(plugin.al.isAdmin(sender) || senderIsConsole))
|
|
||||||
{
|
|
||||||
noPerms();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Clearing all potion effects from all players", true);
|
|
||||||
server.getOnlinePlayers().forEach(target -> target.getActivePotionEffects().forEach(effect ->
|
|
||||||
target.removePotionEffect(effect.getType())));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 2 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("clear"))
|
|
||||||
{
|
|
||||||
Player target = playerSender;
|
|
||||||
|
|
||||||
if (!plugin.al.isAdmin(sender) && !args[1].equalsIgnoreCase(sender.getName()))
|
|
||||||
{
|
|
||||||
msg(ChatColor.RED + "Only admins can clear potion effects from other players.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
target = getPlayer(args[1], true);
|
|
||||||
|
|
||||||
if (target == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PotionEffect potion_effect : target.getActivePotionEffects())
|
|
||||||
{
|
|
||||||
target.removePotionEffect(potion_effect.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
msg("Cleared all active potion effects " + (!target.equals(playerSender) ? "from player "
|
|
||||||
+ target.getName() + "." : "from yourself."), ChatColor.AQUA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 4, 5 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("add"))
|
|
||||||
{
|
|
||||||
Player target = playerSender;
|
|
||||||
|
|
||||||
if (args.length == 5)
|
|
||||||
{
|
|
||||||
if (!plugin.al.isAdmin(sender) && !args[4].equalsIgnoreCase(sender.getName()))
|
|
||||||
{
|
|
||||||
msg("Only admins can apply potion effects to other players.", ChatColor.RED);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
target = getPlayer(args[4]);
|
|
||||||
|
|
||||||
if (target == null || plugin.al.isVanished(target.getUniqueId()) && !plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
if (senderIsConsole)
|
|
||||||
{
|
|
||||||
msg("You must specify a target player when using this command from the console.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PotionEffectType effectType = PotionEffectType.getByName(args[1]);
|
|
||||||
if (effectType == null)
|
|
||||||
{
|
|
||||||
msg("Invalid potion effect: " + args[1], ChatColor.AQUA);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int duration;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
duration = Math.min(Integer.parseInt(args[2]), 100000);
|
|
||||||
} catch (NumberFormatException ex)
|
|
||||||
{
|
|
||||||
msg("Invalid duration: " + args[2], ChatColor.RED);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int amplifier;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
amplifier = Math.min(Integer.parseInt(args[3]), 100000);
|
|
||||||
} catch (NumberFormatException ex)
|
|
||||||
{
|
|
||||||
msg("Invalid potion amplifier: " + args[3], ChatColor.RED);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PotionEffect new_effect = effectType.createEffect(duration, amplifier);
|
|
||||||
target.addPotionEffect(new_effect);
|
|
||||||
msg("Added potion effect: " + new_effect.getType().getName()
|
|
||||||
+ ", Duration: " + new_effect.getDuration()
|
|
||||||
+ ", Amplifier: " + new_effect.getAmplifier()
|
|
||||||
+ (!target.equals(playerSender) ? " to player " + target.getName() + "." : " to yourself."), ChatColor.AQUA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
switch (args.length)
|
|
||||||
{
|
|
||||||
case 1 ->
|
|
||||||
{
|
|
||||||
List<String> arguments = new ArrayList<>(Arrays.asList("list", "clear", "add"));
|
|
||||||
if (plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
arguments.add("clearall");
|
|
||||||
}
|
|
||||||
return arguments;
|
|
||||||
}
|
|
||||||
case 2 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("clear"))
|
|
||||||
{
|
|
||||||
if (plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
return FUtil.getPlayerList();
|
|
||||||
}
|
|
||||||
} else if (args[0].equalsIgnoreCase("add"))
|
|
||||||
{
|
|
||||||
return Arrays.stream(PotionEffectType.values()).map(PotionEffectType::getName).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 3 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("add"))
|
|
||||||
{
|
|
||||||
return Collections.singletonList("<duration>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 4 ->
|
|
||||||
{
|
|
||||||
if (args[0].equalsIgnoreCase("add"))
|
|
||||||
{
|
|
||||||
return Collections.singletonList("<amplifier>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 5 ->
|
|
||||||
{
|
|
||||||
if (plugin.al.isAdmin(sender) && args[0].equalsIgnoreCase("add"))
|
|
||||||
{
|
|
||||||
return FUtil.getPlayerList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@Intercept("report")
|
|
||||||
@CommandPermissions(permission = "report", source = SourceType.ONLY_IN_GAME, blockHostConsole = true)
|
|
||||||
@CommandParameters(description = "Report a player for all admins to see.", usage = "/<command> <player> <reason>")
|
|
||||||
public class Command_report extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length < 2)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfflinePlayer player = Bukkit.getOfflinePlayer(args[0]);
|
|
||||||
|
|
||||||
if (sender instanceof Player && (player.equals(playerSender)))
|
|
||||||
{
|
|
||||||
msgNew("<red>Please, don't try to report yourself.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.al.isAdmin(player))
|
|
||||||
{
|
|
||||||
msgNew("<red>You can't report admins with this command.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String report = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " ");
|
|
||||||
plugin.cm.reportAction(playerSender, player.getName(), report);
|
|
||||||
|
|
||||||
boolean logged = false;
|
|
||||||
|
|
||||||
if (plugin.dc != null && plugin.dc.isEnabled())
|
|
||||||
{
|
|
||||||
Player online = Bukkit.getPlayer(player.getUniqueId());
|
|
||||||
logged = (online != null)
|
|
||||||
? plugin.dc.sendReport(playerSender, online, report)
|
|
||||||
: plugin.dc.sendReportOffline(playerSender, player, report);
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("<green>Thank you, your report has been successfully logged.");
|
|
||||||
if (logged)
|
|
||||||
{
|
|
||||||
msgNew("<red>Note: This report has been logged to a Discord channel, as with any report system, spamming reports can lead to you getting banned.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,320 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.admin.Admin;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.PermissibleCompletion;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.luckperms.api.model.group.Group;
|
|
||||||
import net.luckperms.api.track.DemotionResult;
|
|
||||||
import net.luckperms.api.track.PromotionResult;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "saconfig", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "List, add, remove, or set the rank of admins, clean or reload the admin list, or view admin information.",
|
|
||||||
usage = "/<command> <list | clean | reload | | setrank <username> <rank> | <promote | demote | info | remove> <username>>", aliases = "slconfig")
|
|
||||||
public class Command_saconfig extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length < 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0])
|
|
||||||
{
|
|
||||||
case "list" ->
|
|
||||||
{
|
|
||||||
msgNew("<gold>Admins: <admins>", Placeholder.unparsed("admins", StringUtils.join(plugin.al.getAdminNames(), ", ")));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "clean" ->
|
|
||||||
{
|
|
||||||
checkConsole();
|
|
||||||
checkPermission("tfm.saconfig.clean");
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Cleaning the admin list", true);
|
|
||||||
plugin.al.deactivateOldEntries(true);
|
|
||||||
msgNew("<gold>Admins: <admins>", Placeholder.unparsed("admins", StringUtils.join(plugin.al.getAdminNames(), ", ")));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "reload" ->
|
|
||||||
{
|
|
||||||
checkPermission("tfm.saconfig.reload");
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Reloading the admin list", true);
|
|
||||||
plugin.al.load();
|
|
||||||
msgNew("Admin list reloaded!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "promote" ->
|
|
||||||
{
|
|
||||||
checkConsole();
|
|
||||||
checkPermission("tfm.saconfig.promote");
|
|
||||||
|
|
||||||
if (args.length < 2)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = getPlayer(args[1]);
|
|
||||||
|
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Player not found.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PromotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.promoteUser(TotalFreedomMod.getPlugin().getHierarchy().admin(), player);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful() || result.getGroupTo().isEmpty())
|
|
||||||
{
|
|
||||||
msgNew("<red>Failed to promote <player> to the next rank.", player(player));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
result.getGroupTo().ifPresentOrElse(group ->
|
|
||||||
{
|
|
||||||
Admin admin = plugin.al.getAdmin(player);
|
|
||||||
|
|
||||||
if (admin == null)
|
|
||||||
{
|
|
||||||
admin = new Admin(player);
|
|
||||||
plugin.al.addAdmin(admin);
|
|
||||||
}
|
|
||||||
|
|
||||||
Group actual = TotalFreedomMod.getPlugin().getHierarchy().getGroup(group);
|
|
||||||
DisplayableGroup rank = TotalFreedomMod.getPlugin()
|
|
||||||
.getHierarchy()
|
|
||||||
.groups()
|
|
||||||
.fromLuckPerms(actual);
|
|
||||||
|
|
||||||
if (rank == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Unknown rank: <rank>", Placeholder.unparsed("rank", args[2]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
admin.setRank(rank);
|
|
||||||
admin.addIp(FUtil.getIp(player));
|
|
||||||
admin.setActive(true);
|
|
||||||
admin.setLastLogin(new Date());
|
|
||||||
|
|
||||||
plugin.al.save(admin);
|
|
||||||
plugin.al.updateTables();
|
|
||||||
|
|
||||||
if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean())
|
|
||||||
{
|
|
||||||
plugin.dc.syncRoles(admin, plugin.pl.getData(player).getDiscordID());
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("Set <admin>'s rank to <rank>.", Placeholder.unparsed("admin", admin.getName()), Placeholder.component("rank", rank.getName()));
|
|
||||||
|
|
||||||
final FPlayer fPlayer = plugin.pl.getPlayer(player);
|
|
||||||
if (fPlayer.getFreezeData().isFrozen())
|
|
||||||
{
|
|
||||||
fPlayer.getFreezeData().setFrozen(false);
|
|
||||||
msgNew(player, "You have been unfrozen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("<gold>Admin <player> has been promoted to <rank>",
|
|
||||||
player(player),
|
|
||||||
Placeholder.unparsed("rank", group));
|
|
||||||
}, () -> msgNew("<red>Failed to promote <player> to the next rank.", player(player)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "info" ->
|
|
||||||
{
|
|
||||||
if (args.length < 2)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkPermission("tfm.saconfig.info");
|
|
||||||
|
|
||||||
Admin admin = plugin.al.getEntryByName(args[1]);
|
|
||||||
|
|
||||||
if (admin == null)
|
|
||||||
{
|
|
||||||
final Player player = getPlayer(args[1]);
|
|
||||||
if (player != null)
|
|
||||||
{
|
|
||||||
admin = plugin.al.getAdmin(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (admin == null)
|
|
||||||
{
|
|
||||||
msgNew("Unknown admin: <arg>", arg(args[1]));
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew(admin.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "demote" ->
|
|
||||||
{
|
|
||||||
checkConsole();
|
|
||||||
checkPermission("tfm.saconfig.demote");
|
|
||||||
|
|
||||||
if (args.length < 2)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = getPlayer(args[1]);
|
|
||||||
|
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Player not found.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DemotionResult result = TotalFreedomMod.getPlugin().getHierarchy()
|
|
||||||
.demoteUser(TotalFreedomMod.getPlugin().getHierarchy().admin(), player);
|
|
||||||
|
|
||||||
if (!result.wasSuccessful() || result.getGroupTo().isEmpty())
|
|
||||||
{
|
|
||||||
msgNew("<red>Failed to demote <player> to the next rank.", player(player));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.getGroupTo().ifPresentOrElse(group ->
|
|
||||||
{
|
|
||||||
Admin admin = plugin.al.getAdmin(player);
|
|
||||||
|
|
||||||
if (admin == null)
|
|
||||||
{
|
|
||||||
admin = new Admin(player);
|
|
||||||
plugin.al.addAdmin(admin);
|
|
||||||
}
|
|
||||||
|
|
||||||
Group actual = TotalFreedomMod.getPlugin().getHierarchy().getGroup(group);
|
|
||||||
DisplayableGroup rank = TotalFreedomMod.getPlugin()
|
|
||||||
.getHierarchy()
|
|
||||||
.groups()
|
|
||||||
.fromLuckPerms(actual);
|
|
||||||
|
|
||||||
if (rank == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Unknown rank: <rank>", Placeholder.unparsed("rank", args[2]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
admin.setRank(rank);
|
|
||||||
admin.setLastLogin(new Date());
|
|
||||||
|
|
||||||
plugin.al.save(admin);
|
|
||||||
plugin.al.updateTables();
|
|
||||||
|
|
||||||
if (plugin.dc != null && plugin.dc.isEnabled() && Boolean.TRUE.equals(ConfigEntry.DISCORD_ROLE_SYNC.getBoolean()))
|
|
||||||
{
|
|
||||||
plugin.dc.syncRoles(admin, plugin.pl.getData(player).getDiscordID());
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("Set <admin>'s rank to <rank>.", Placeholder.unparsed("admin", admin.getName()), Placeholder.component("rank", rank.getName()));
|
|
||||||
|
|
||||||
final FPlayer fPlayer = plugin.pl.getPlayer(player);
|
|
||||||
if (fPlayer.getFreezeData().isFrozen())
|
|
||||||
{
|
|
||||||
fPlayer.getFreezeData().setFrozen(false);
|
|
||||||
msgNew(player, "You have been unfrozen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("<gold>Admin <player> has been demoted to <rank>",
|
|
||||||
Placeholder.unparsed("player", player.getName()),
|
|
||||||
Placeholder.unparsed("rank", group));
|
|
||||||
}, () -> msgNew("<red>Failed to demote <player> to the next rank.", Placeholder.unparsed("player", player.getName())));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case "remove" ->
|
|
||||||
{
|
|
||||||
if (args.length < 2)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkConsole();
|
|
||||||
checkPermission("tfm.saconfig.remove");
|
|
||||||
|
|
||||||
Player player = getPlayer(args[1]);
|
|
||||||
Admin admin = plugin.al.getAdmin(player);
|
|
||||||
plugin.al.removeAdmin(admin);
|
|
||||||
|
|
||||||
TotalFreedomMod.getPlugin().getHierarchy().dropUser(TotalFreedomMod.getPlugin().getHierarchy().admin(), player);
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Removing " + admin.getName() + " from the admin list", true);
|
|
||||||
admin.setActive(false);
|
|
||||||
|
|
||||||
plugin.al.save(admin);
|
|
||||||
plugin.al.updateTables();
|
|
||||||
|
|
||||||
if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean())
|
|
||||||
{
|
|
||||||
plugin.dc.syncRoles(admin, plugin.pl.getData(admin.getName())
|
|
||||||
.getDiscordID());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
return argumentCompletions(args[0],
|
|
||||||
PermissibleCompletion.of("tfm.saconfig.info", "info"),
|
|
||||||
PermissibleCompletion.of("tfm.saconfig.demote", "demote"),
|
|
||||||
PermissibleCompletion.of("tfm.saconfig.remove", "remove"),
|
|
||||||
PermissibleCompletion.of("tfm.saconfig.reload", "reload"),
|
|
||||||
PermissibleCompletion.of("tfm.saconfig.clean", "clean"),
|
|
||||||
PermissibleCompletion.of("tfm.saconfig.promote", "promote"));
|
|
||||||
}
|
|
||||||
if (args.length == 2 && (args[0].equals("promote")
|
|
||||||
|| args[0].equals("demote")
|
|
||||||
|| args[0].equals("remove")
|
|
||||||
|| args[0].equals("setrank")
|
|
||||||
|| args[0].equals("info")))
|
|
||||||
{
|
|
||||||
return playerCompletions(args[1]);
|
|
||||||
}
|
|
||||||
if (args.length == 3
|
|
||||||
&& args[0].equals("setrank")
|
|
||||||
&& sender.hasPermission("tfm.saconfig.setrank"))
|
|
||||||
{
|
|
||||||
return Arrays.asList("admin", "seniorAdmin");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@Intercept("say")
|
|
||||||
@CommandPermissions(permission = "say", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Broadcasts the given message as the server, includes sender name.", usage = "/<command> <message>")
|
|
||||||
public class Command_say extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String message = StringUtils.join(args, " ");
|
|
||||||
|
|
||||||
server.broadcast(FUtil.miniMessage("<light_purple>[Server:<player>] <message>",
|
|
||||||
Placeholder.unparsed("player", sender.getName()),
|
|
||||||
Placeholder.unparsed("message", message)));
|
|
||||||
|
|
||||||
if (plugin.dc != null)
|
|
||||||
{
|
|
||||||
plugin.dc.messageChatChannel(String.format("[Server:%s] \u00BB %s", sender.getName(), message), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
|
||||||
import net.kyori.adventure.text.event.HoverEvent;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.generator.WorldInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Intercept("seed")
|
|
||||||
@CommandPermissions(permission = "seed", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Get the seed of the world you are currently in.", usage = "/seed [world]")
|
|
||||||
public class Command_seed extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
World world;
|
|
||||||
|
|
||||||
if (args.length > 0)
|
|
||||||
{
|
|
||||||
world = server.getWorld(args[0]);
|
|
||||||
if (world == null)
|
|
||||||
{
|
|
||||||
msg("That world could not be found", ChatColor.RED);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// If the sender is a Player, use that world. Otherwise, use the overworld as a fallback.
|
|
||||||
if (!senderIsConsole)
|
|
||||||
{
|
|
||||||
world = playerSender.getWorld();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
world = server.getWorlds().get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage(Component.translatable("commands.seed.success",
|
|
||||||
Component.text("[", NamedTextColor.WHITE).append(Component.text(world.getSeed(), NamedTextColor.GREEN)
|
|
||||||
.clickEvent(ClickEvent.copyToClipboard(String.valueOf(world.getSeed())))
|
|
||||||
.hoverEvent(HoverEvent.showText(Component.translatable("chat.copy"))))
|
|
||||||
.append(Component.text("]"))));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
return server.getWorlds().stream().map(WorldInfo::getName).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.api.ShopItem;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandDependencies({"TF-Shoppe"})
|
|
||||||
@CommandPermissions(permission = "stackingpotato", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Obtain a stacking potato", usage = "/<command>")
|
|
||||||
public class Command_stackingpotato extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Shop is currently disabled.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.pl.getData(playerSender).hasItem(ShopItem.STACKING_POTATO))
|
|
||||||
{
|
|
||||||
playerSender.getInventory().addItem(plugin.sh.getStackingPotato());
|
|
||||||
msgNew("<green>You have been given the <item>.", Placeholder.unparsed("item", ShopItem.STACKING_POTATO.getName()));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<red>You don't own the <item>! Purchase it from the shop.", Placeholder.unparsed("item", ShopItem.STACKING_POTATO.getName()));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "stopsound", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Stops all sounds or a specified sound.", usage = "/<command> [sound]")
|
|
||||||
public class Command_stopsound extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length > 0)
|
|
||||||
{
|
|
||||||
Arrays.stream(Sound.values()).filter(snd -> snd != null && snd.name().equalsIgnoreCase(args[0])).findAny().ifPresentOrElse(sound ->
|
|
||||||
{
|
|
||||||
playerSender.stopSound(sound);
|
|
||||||
msgNew("<green>Stopped all <sound> sounds.", Placeholder.unparsed("sound", sound.name()));
|
|
||||||
}, () -> msgNew("<red><sound> is not a valid sound.", Placeholder.unparsed("sound", args[0])));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
playerSender.stopAllSounds();
|
|
||||||
|
|
||||||
msgNew("<green>Stopped all sounds.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (args.length <= 1)
|
|
||||||
{
|
|
||||||
return Arrays.stream(Sound.values()).map(Enum::name).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,202 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
|
||||||
import net.kyori.adventure.text.event.HoverEvent;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "tag", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Allows you to set your own prefix.", usage = "/<command> [-ns] <set <tag..> | list | off | clear <player> | clearall>")
|
|
||||||
public class Command_tag extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
boolean save = true;
|
|
||||||
|
|
||||||
if (args.length < 1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].equalsIgnoreCase("-ns"))
|
|
||||||
{
|
|
||||||
save = false;
|
|
||||||
args = ArrayUtils.remove(args, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "list":
|
|
||||||
{
|
|
||||||
msgNew("Tags for all online players:");
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !(plugin.al.isVanished(player.getUniqueId()) && !isAdmin(sender)) && plugin.pl.getPlayer(player).getTag() != null).forEach(player ->
|
|
||||||
{
|
|
||||||
msgNew("<player>: <tag>", Placeholder.unparsed("player", player.getName()),
|
|
||||||
Placeholder.component("tag", plugin.pl.getPlayer(player).getTag()));
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "clearall":
|
|
||||||
{
|
|
||||||
if (!sender.hasPermission("tfm.tag.clear.all"))
|
|
||||||
{
|
|
||||||
noPerms();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Removing all tags", false);
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for (final Player player : server.getOnlinePlayers())
|
|
||||||
{
|
|
||||||
final FPlayer playerdata = plugin.pl.getPlayer(player);
|
|
||||||
if (playerdata.getTag() != null)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
playerdata.setTag(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("<count> tag(s) removed.", Placeholder.unparsed("count", String.valueOf(count)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "off":
|
|
||||||
{
|
|
||||||
if (senderIsConsole)
|
|
||||||
{
|
|
||||||
msgNew("<red>\"/tag off\" can't be used from the console.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
plugin.pl.getPlayer(playerSender).setTag(null);
|
|
||||||
|
|
||||||
if (save)
|
|
||||||
{
|
|
||||||
save(playerSender, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("Your tag has been removed. <saved>",
|
|
||||||
Placeholder.unparsed("saved", save ? "(Saved)" : ""));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (args.length >= 2)
|
|
||||||
{
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "clear":
|
|
||||||
{
|
|
||||||
if (!sender.hasPermission("tfm.tag.clear.others"))
|
|
||||||
{
|
|
||||||
noPerms();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player player = getPlayer(args[1]);
|
|
||||||
|
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
msg(FreedomCommand.PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.pl.getPlayer(player).setTag(null);
|
|
||||||
if (save)
|
|
||||||
{
|
|
||||||
save(player, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("Removed <player>'s tag. <saved>",
|
|
||||||
Placeholder.unparsed("player", player.getName()),
|
|
||||||
Placeholder.unparsed("saved", save ? "(Saved)" : ""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "set":
|
|
||||||
{
|
|
||||||
if (senderIsConsole)
|
|
||||||
{
|
|
||||||
msgNew("<red>\"/tag set\" can't be used from the console.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String inputTag = StringUtils.join(args, " ", 1, args.length);
|
|
||||||
Component tag;
|
|
||||||
|
|
||||||
if (FUtil.containsChatColor(inputTag))
|
|
||||||
{
|
|
||||||
tag = FUtil.colorizeAsComponent(inputTag.replace("&k", ""));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
tag = FUtil.miniMessage(inputTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
String steamrolled = FUtil.steamroll(tag);
|
|
||||||
int tagLimit = (plugin.al.isAdmin(sender) ? 30 : 20);
|
|
||||||
if (steamrolled.length() > tagLimit)
|
|
||||||
{
|
|
||||||
FLog.debug("FUCK YOU " + steamrolled.length());
|
|
||||||
FLog.debug("FUCK YOU " + steamrolled);
|
|
||||||
msgNew("<red>That tag is too long (Max is <max> characters).", Placeholder.unparsed("max", String.valueOf(tagLimit)));
|
|
||||||
return true;
|
|
||||||
} else if (!plugin.al.isAdmin(sender) && ConfigEntry.FORBIDDEN_WORDS.getStringList().stream().anyMatch(word -> steamrolled.toLowerCase().contains(word)))
|
|
||||||
{
|
|
||||||
msgNew("<red>That tag contains a forbidden word.");
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
plugin.pl.getPlayer(playerSender).setTag(tag);
|
|
||||||
|
|
||||||
if (save)
|
|
||||||
{
|
|
||||||
save(playerSender, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
msgNew("Tag set to '<tag>' <saved>",
|
|
||||||
Placeholder.component("tag", tag.hoverEvent(HoverEvent.showText(Component.translatable("chat.copy")))
|
|
||||||
.clickEvent(ClickEvent.copyToClipboard(FUtil.miniMessage(tag)))),
|
|
||||||
Placeholder.unparsed("saved", save ? "(Saved)" : ""));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(Player player, Component tag)
|
|
||||||
{
|
|
||||||
PlayerData playerData = plugin.pl.getData(player);
|
|
||||||
playerData.setTag(tag);
|
|
||||||
plugin.pl.save(playerData);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,188 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.GameRuleHandler;
|
|
||||||
import me.totalfreedom.totalfreedommod.LoginProcess;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@CommandPermissions(permission = "toggle", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Toggles TotalFreedomMod settings", usage = "/<command> [option] [value] [value]")
|
|
||||||
public class Command_toggle extends FreedomCommand
|
|
||||||
{
|
|
||||||
private final List<String> toggles = Arrays.asList(
|
|
||||||
"waterplace", "fireplace", "lavaplace", "fluidspread", "lavadmg", "firespread", "frostwalk",
|
|
||||||
"firework", "prelog", "lockdown", "petprotect", "entitywipe", "nonuke [range] [count]",
|
|
||||||
"explosives [radius]", "unsafeenchs", "bells", "armorstands", "masterblocks", "books", "grindstones",
|
|
||||||
"jukeboxes", "spawners", "4chan", "beehives", "respawnanchors", "autotp", "autoclear", "minecarts", "mp44",
|
|
||||||
"landmines", "tossmob", "gravity", "chat", "disguises");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
msgNew("Available toggles: ");
|
|
||||||
toggles.forEach(toggle -> msgNew("- <toggle>", Placeholder.unparsed("toggle", toggle)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0].toLowerCase())
|
|
||||||
{
|
|
||||||
case "waterplace" -> toggle("Water placement is", ConfigEntry.ALLOW_WATER_PLACE);
|
|
||||||
case "frostwalk" -> toggle("Frost walker enchantment is", ConfigEntry.ALLOW_FROSTWALKER);
|
|
||||||
case "fireplace" -> toggle("Fire placement is", ConfigEntry.ALLOW_FIRE_PLACE);
|
|
||||||
case "lavaplace" -> toggle("Lava placement is", ConfigEntry.ALLOW_LAVA_PLACE);
|
|
||||||
case "fluidspread" -> toggle("Fluid spread is", ConfigEntry.ALLOW_FLUID_SPREAD);
|
|
||||||
case "lavadmg" -> toggle("Lava damage is", ConfigEntry.ALLOW_LAVA_DAMAGE);
|
|
||||||
case "firespread" ->
|
|
||||||
{
|
|
||||||
toggle("Fire spread is", ConfigEntry.ALLOW_FIRE_SPREAD);
|
|
||||||
plugin.gr.setGameRule(GameRuleHandler.GameRule.DO_FIRE_TICK, ConfigEntry.ALLOW_FIRE_SPREAD.getBoolean());
|
|
||||||
}
|
|
||||||
case "prelog" -> toggle("Command prelogging is", ConfigEntry.ENABLE_PREPROCESS_LOG);
|
|
||||||
case "lockdown" ->
|
|
||||||
{
|
|
||||||
boolean active = !LoginProcess.isLockdownEnabled();
|
|
||||||
LoginProcess.setLockdownEnabled(active);
|
|
||||||
FUtil.adminAction(sender.getName(), (active ? "A" : "De-a") + "ctivating server lockdown", true);
|
|
||||||
}
|
|
||||||
case "petprotect" -> toggle("Tamed pet protection is", ConfigEntry.ENABLE_PET_PROTECT);
|
|
||||||
case "entitywipe" -> toggle("Automatic entity wiping is", ConfigEntry.AUTO_ENTITY_WIPE);
|
|
||||||
case "firework" -> toggle("Firework explosion is", ConfigEntry.ALLOW_FIREWORK_EXPLOSION);
|
|
||||||
case "nonuke" ->
|
|
||||||
{
|
|
||||||
if (args.length >= 2)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ConfigEntry.NUKE_MONITOR_RANGE.setDouble(Math.max(1.0, Math.min(500.0, Double.parseDouble(args[1]))));
|
|
||||||
} catch (NumberFormatException ex)
|
|
||||||
{
|
|
||||||
msgNew("<red>The input provided is not a valid integer.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length >= 3)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ConfigEntry.NUKE_MONITOR_COUNT_BREAK.setInteger(Math.max(1, Math.min(500, Integer.parseInt(args[2]))));
|
|
||||||
} catch (NumberFormatException ex)
|
|
||||||
{
|
|
||||||
msgNew("<red>The input provided is not a valid integer.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle("Nuke monitor is", ConfigEntry.NUKE_MONITOR_ENABLED);
|
|
||||||
|
|
||||||
if (ConfigEntry.NUKE_MONITOR_ENABLED.getBoolean())
|
|
||||||
{
|
|
||||||
msgNew("Anti-freecam range is set to <range> blocks.", Placeholder.unparsed("range", String.valueOf(ConfigEntry.NUKE_MONITOR_RANGE.getDouble())));
|
|
||||||
msgNew("Block throttle rate is set to <count> blocks destroyed per 5 seconds.", Placeholder.unparsed("count", String.valueOf(ConfigEntry.NUKE_MONITOR_COUNT_BREAK.getInteger())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "explosives" ->
|
|
||||||
{
|
|
||||||
if (args.length == 2)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ConfigEntry.EXPLOSIVE_RADIUS.setDouble(Math.max(1.0, Math.min(30.0, Double.parseDouble(args[1]))));
|
|
||||||
} catch (NumberFormatException ex)
|
|
||||||
{
|
|
||||||
msgNew("<red>The input provided is not a valid integer.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle("Explosions are", ConfigEntry.ALLOW_EXPLOSIONS);
|
|
||||||
|
|
||||||
if (ConfigEntry.ALLOW_EXPLOSIONS.getBoolean())
|
|
||||||
{
|
|
||||||
msgNew("Radius set to <radius>.", Placeholder.unparsed("radius", String.valueOf(ConfigEntry.EXPLOSIVE_RADIUS.getDouble())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "unsafeenchs" -> toggle("Unsafe enchantments are", ConfigEntry.ALLOW_UNSAFE_ENCHANTMENTS);
|
|
||||||
case "bells" -> toggle("The ringing of bells is", ConfigEntry.ALLOW_BELLS);
|
|
||||||
case "armorstands" -> toggle("The placement of armor stands is", ConfigEntry.ALLOW_ARMOR_STANDS);
|
|
||||||
case "masterblocks" -> toggle("Master blocks are", ConfigEntry.ALLOW_MASTERBLOCKS);
|
|
||||||
case "books" -> toggle("Books are", ConfigEntry.ALLOW_BOOKS);
|
|
||||||
case "grindstones" -> toggle("Grindstones are", ConfigEntry.ALLOW_GRINDSTONES);
|
|
||||||
case "jukeboxes" -> toggle("Jukeboxes are", ConfigEntry.ALLOW_JUKEBOXES);
|
|
||||||
case "spawners" -> toggle("Spawners are", ConfigEntry.ALLOW_SPAWNERS);
|
|
||||||
case "4chan" -> toggle("4chan mode is", ConfigEntry.FOURCHAN_ENABLED);
|
|
||||||
case "beehives" -> toggle("Beehives are", ConfigEntry.ALLOW_BEEHIVES);
|
|
||||||
case "respawnanchors" -> toggle("Respawn anchors are", ConfigEntry.ALLOW_RESPAWN_ANCHORS);
|
|
||||||
case "autotp" -> toggle("Teleportation on join is", ConfigEntry.AUTO_TP);
|
|
||||||
case "autoclear" -> toggle("Clearing inventories on join is", ConfigEntry.AUTO_CLEAR);
|
|
||||||
case "minecarts" -> toggle("Minecarts are", ConfigEntry.ALLOW_MINECARTS);
|
|
||||||
case "landmines" -> toggle("Landmines are", ConfigEntry.LANDMINES_ENABLED);
|
|
||||||
case "mp44" -> toggle("MP44 is", ConfigEntry.MP44_ENABLED);
|
|
||||||
case "tossmob" -> toggle("Tossmob is", ConfigEntry.TOSSMOB_ENABLED);
|
|
||||||
case "gravity" -> toggle("Block gravity is", ConfigEntry.ALLOW_GRAVITY);
|
|
||||||
case "chat" -> toggle("Chat is", ConfigEntry.TOGGLE_CHAT);
|
|
||||||
case "disguises" ->
|
|
||||||
{
|
|
||||||
if (!plugin.ldb.isEnabled())
|
|
||||||
{
|
|
||||||
msgNew("<red>LibsDisguises is not enabled.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.ldb.isDisguisesEnabled())
|
|
||||||
{
|
|
||||||
plugin.ldb.undisguiseAll(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.ldb.setDisguisesEnabled(!plugin.ldb.isDisguisesEnabled());
|
|
||||||
msgNew("Disguises are now <status>.", Placeholder.unparsed("status", plugin.ldb.isDisguisesEnabled() ? "enabled." : "disabled."));
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
{
|
|
||||||
msgNew("Available toggles: ");
|
|
||||||
toggles.forEach(toggle -> msgNew("- <toggle>", Placeholder.unparsed("toggle", toggle)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggle(final String name, final ConfigEntry entry)
|
|
||||||
{
|
|
||||||
msgNew("<name> now <status>.", Placeholder.unparsed("name", name), Placeholder.unparsed("status",
|
|
||||||
entry.setBoolean(!entry.getBoolean()) ? "enabled" : "disabled"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
|
|
||||||
{
|
|
||||||
if (!plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
return Arrays.asList(
|
|
||||||
"waterplace", "fireplace", "lavaplace", "fluidspread", "lavadmg", "firespread", "frostwalk",
|
|
||||||
"firework", "prelog", "lockdown", "petprotect", "entitywipe", "nonuke", "explosives", "unsafeenchs",
|
|
||||||
"bells", "armorstands", "structureblocks", "jigsaws", "grindstones", "jukeboxes", "spawners", "4chan", "beehives",
|
|
||||||
"respawnanchors", "autotp", "autoclear", "minecarts", "mp44", "landmines", "tossmob", "gravity", "chat", "disguises");
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandDependencies({"TF-Shoppe"})
|
|
||||||
@CommandPermissions(permission = "clownfish.toggle", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Toggle whether or not a player has the ability to use clownfish", usage = "/<command> <player>", aliases = "togglecf")
|
|
||||||
public class Command_toggleclownfish extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = server.getPlayer(args[0]);
|
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FPlayer fplayer = plugin.pl.getPlayer(player);
|
|
||||||
fplayer.setClownfishDisabled(!fplayer.isClownfishDisabled());
|
|
||||||
|
|
||||||
msgNew("<player> will <status> have the ability to use the Clownfish.",
|
|
||||||
Placeholder.unparsed("player", args[0]),
|
|
||||||
Placeholder.unparsed("status", fplayer.isClownfishDisabled() ? "no longer" : "now"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandParameters;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.CommandPermissions;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.SourceType;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See https://github.com/TotalFreedom/License - This file may not be edited or removed.
|
|
||||||
*/
|
|
||||||
@CommandPermissions(source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Shows information about TotalFreedomMod or reloads it", usage = "/<command> [reload]", aliases = "tfm")
|
|
||||||
public class Command_totalfreedommod extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length == 1)
|
|
||||||
{
|
|
||||||
if (!args[0].equals("reload"))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.al.isAdmin(sender))
|
|
||||||
{
|
|
||||||
noPerms();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.config.load();
|
|
||||||
|
|
||||||
plugin.fsh.stopServices();
|
|
||||||
plugin.fsh.startServices();
|
|
||||||
|
|
||||||
msgNew("<name> v<version> reloaded.",
|
|
||||||
Placeholder.unparsed("name", TotalFreedomMod.pluginName),
|
|
||||||
Placeholder.unparsed("version", TotalFreedomMod.pluginVersion));
|
|
||||||
FLog.info(String.format("%s v%s reloaded.",
|
|
||||||
TotalFreedomMod.pluginName,
|
|
||||||
TotalFreedomMod.pluginVersion));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TotalFreedomMod.BuildProperties build = TotalFreedomMod.build;
|
|
||||||
msgNew("<gold>TotalFreedomMod for 'Total Freedom', the original all-op server.");
|
|
||||||
msgNew("<gold>Running on <server>.", Placeholder.unparsed("server", ConfigEntry.SERVER_NAME.getString()));
|
|
||||||
msgNew("<gold>Created by Madgeek1450 and Prozza.");
|
|
||||||
msgNew("<gold>Version <blue><codename> - <version> Build <number> </blue>(<blue><head></blue>)",
|
|
||||||
Placeholder.unparsed("codename", build.codename),
|
|
||||||
Placeholder.unparsed("version", build.version),
|
|
||||||
Placeholder.unparsed("number", build.number),
|
|
||||||
Placeholder.unparsed("head", build.head));
|
|
||||||
msgNew("<gold>Compiled <blue><date></blue> by <blue><author></blue>",
|
|
||||||
Placeholder.unparsed("date", build.date),
|
|
||||||
Placeholder.unparsed("author", build.author));
|
|
||||||
msgNew("<green>Visit <aqua>http://github.com/TotalFreedom/TotalFreedomMod</aqua> for more information.");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.api.ShopItem;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@CommandDependencies({"TF-Shoppe"})
|
|
||||||
@CommandPermissions(permission = "trail", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Trails rainbow particles behind you as you walk/fly.", usage = "/<command>")
|
|
||||||
public class Command_trail extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null)
|
|
||||||
{
|
|
||||||
msgNew("<red>Shop is not enabled.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.pl.getData(playerSender).hasItem(ShopItem.RAINBOW_TRAIL))
|
|
||||||
{
|
|
||||||
msgNew("<red>You didn't purchase the ability to have a <item>! Purchase it from the shop.", Placeholder.unparsed("item", ShopItem.RAINBOW_TRAIL.getName()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.tr.contains(playerSender))
|
|
||||||
{
|
|
||||||
plugin.tr.remove(playerSender);
|
|
||||||
msgNew("Trail disabled.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
plugin.tr.add(playerSender);
|
|
||||||
msgNew("Trail enabled. Run this command again to disable it.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import com.earth2me.essentials.User;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@Intercept("unban")
|
|
||||||
@CommandPermissions(permission = "unban", source = SourceType.BOTH)
|
|
||||||
@CommandParameters(description = "Unbans the specified player.", usage = "/<command> <username> [-r]")
|
|
||||||
public class Command_unban extends FreedomCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
if (args.length > 0)
|
|
||||||
{
|
|
||||||
String username;
|
|
||||||
String ip;
|
|
||||||
|
|
||||||
// Gets the IP using Essentials data if available
|
|
||||||
if (plugin.esb.isEnabled() && plugin.esb.getEssentialsUser(args[0]) != null)
|
|
||||||
{
|
|
||||||
User essUser = plugin.esb.getEssentialsUser(args[0]);
|
|
||||||
//
|
|
||||||
username = essUser.getName();
|
|
||||||
ip = essUser.getLastLoginAddress();
|
|
||||||
}
|
|
||||||
// Secondary method - using Essentials if available
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final PlayerData entry = plugin.pl.getData(args[0]);
|
|
||||||
if (entry == null)
|
|
||||||
{
|
|
||||||
msg(PLAYER_NOT_FOUND);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
username = entry.getName();
|
|
||||||
ip = entry.getIps().get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
FUtil.adminAction(sender.getName(), "Unbanning " + username, true);
|
|
||||||
plugin.bm.removeBan(plugin.bm.getByUsername(username));
|
|
||||||
plugin.bm.removeBan(plugin.bm.getByIp(ip));
|
|
||||||
msgNew("<player> has been unbanned along with the IP: <ip>",
|
|
||||||
Placeholder.unparsed("player", username), Placeholder.unparsed("ip", ip));
|
|
||||||
|
|
||||||
if (args.length >= 2 && plugin.cpb.isEnabled())
|
|
||||||
{
|
|
||||||
if (args[1].equalsIgnoreCase("-r"))
|
|
||||||
{
|
|
||||||
plugin.cpb.restore(username);
|
|
||||||
msgNew("Restored <player>'s edits as well.", Placeholder.unparsed("player", username));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.admin.AdminList;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.*;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.Displayable;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
@Intercept("vanish")
|
|
||||||
@CommandPermissions(permission = "vanish", source = SourceType.ONLY_IN_GAME)
|
|
||||||
@CommandParameters(description = "Vanish/unvanish yourself.", usage = "/<command> [-s[ilent]]", aliases = "v")
|
|
||||||
public class Command_vanish extends FreedomCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
|
|
||||||
{
|
|
||||||
Displayable display = plugin.rm.getDisplay(playerSender);
|
|
||||||
String displayName = display.getColor() + playerSender.getName();
|
|
||||||
Component tag = display.getColoredTag();
|
|
||||||
boolean silent = args.length > 0 && (args[0].equalsIgnoreCase("-s") || args[0].equalsIgnoreCase("-silent"));
|
|
||||||
|
|
||||||
if (plugin.al.isVanished(playerSender.getUniqueId()))
|
|
||||||
{
|
|
||||||
if (silent)
|
|
||||||
{
|
|
||||||
msgNew("<gold>Silently unvanished.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<gold>You have unvanished.");
|
|
||||||
server.broadcast(plugin.rm.craftLoginMessage(playerSender, null));
|
|
||||||
server.broadcast(Component.translatable("multiplayer.player.joined", Component.text(playerSender.getName()))
|
|
||||||
.color(NamedTextColor.YELLOW));
|
|
||||||
|
|
||||||
if (plugin.dc != null)
|
|
||||||
{
|
|
||||||
plugin.dc.messageChatChannel("**" + playerSender.getName() + " joined the server" + "**", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerData playerData = plugin.pl.getData(playerSender);
|
|
||||||
if (playerData.getTag() != null)
|
|
||||||
{
|
|
||||||
tag = playerData.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.pl.getData(playerSender).setTag(tag);
|
|
||||||
plugin.cm.messageAllAdmins("<yellow><player> has unvanished and is now visible to everyone.", Placeholder.unparsed("player", sender.getName()));
|
|
||||||
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
player.showPlayer(plugin, playerSender));
|
|
||||||
|
|
||||||
plugin.esb.setVanished(playerSender.getName(), false);
|
|
||||||
playerSender.setPlayerListName(StringUtils.substring(displayName, 0, 16));
|
|
||||||
AdminList.vanished.remove(playerSender.getUniqueId());
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
new BukkitRunnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
if (plugin.al.isVanished(playerSender.getUniqueId()))
|
|
||||||
{
|
|
||||||
sender.sendActionBar(Component.text("You are hidden from other players.").color(NamedTextColor.GOLD));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskTimer(plugin, 0L, 4L);
|
|
||||||
|
|
||||||
if (silent)
|
|
||||||
{
|
|
||||||
msgNew("<gold>Silently vanished.");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
msgNew("<gold>You have vanished.");
|
|
||||||
server.broadcast(Component.translatable("multiplayer.player.left", Component.text(playerSender.getName()))
|
|
||||||
.color(NamedTextColor.YELLOW));
|
|
||||||
if (plugin.dc != null)
|
|
||||||
{
|
|
||||||
plugin.dc.messageChatChannel("**" + playerSender.getName() + " left the server" + "**", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.cm.messageAllAdmins("<yellow><player> has vanished and is now only visible to admins.", Placeholder.unparsed("player", sender.getName()));
|
|
||||||
|
|
||||||
server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
|
|
||||||
player.hidePlayer(plugin, playerSender));
|
|
||||||
|
|
||||||
plugin.esb.setVanished(playerSender.getName(), true);
|
|
||||||
AdminList.vanished.add(playerSender.getUniqueId());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command.handling;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface CommandDependencies
|
|
||||||
{
|
|
||||||
String[] value();
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command.handling;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.FreedomService;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.reflections.Reflections;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class CommandLoader extends FreedomService
|
|
||||||
{
|
|
||||||
private final List<FreedomCommand> commands;
|
|
||||||
|
|
||||||
public CommandLoader()
|
|
||||||
{
|
|
||||||
commands = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(FreedomCommand command)
|
|
||||||
{
|
|
||||||
commands.add(command);
|
|
||||||
command.register();
|
|
||||||
}
|
|
||||||
|
|
||||||
public FreedomCommand getByName(String name)
|
|
||||||
{
|
|
||||||
for (FreedomCommand command : commands)
|
|
||||||
{
|
|
||||||
if (name.equals(command.getName()))
|
|
||||||
{
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlias(String alias)
|
|
||||||
{
|
|
||||||
for (FreedomCommand command : commands)
|
|
||||||
{
|
|
||||||
if (Arrays.asList(command.getAliases().split(",")).contains(alias))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadCommands()
|
|
||||||
{
|
|
||||||
Reflections commandDir = new Reflections("me.totalfreedom.totalfreedommod.command");
|
|
||||||
|
|
||||||
Interceptor interceptor = new Interceptor(plugin);
|
|
||||||
|
|
||||||
Set<Class<? extends FreedomCommand>> commandClasses = commandDir.getSubTypesOf(FreedomCommand.class);
|
|
||||||
|
|
||||||
Set<Class<? extends FreedomCommand>> postLoadCommands = new HashSet<>();
|
|
||||||
|
|
||||||
for (Class<? extends FreedomCommand> commandClass : commandClasses)
|
|
||||||
{
|
|
||||||
if (commandClass.isAnnotationPresent(CommandDependencies.class))
|
|
||||||
{
|
|
||||||
postLoadCommands.add(commandClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commandClass.isAnnotationPresent(Intercept.class))
|
|
||||||
{
|
|
||||||
Intercept intercept = commandClass.getAnnotation(Intercept.class);
|
|
||||||
interceptor.intercept(intercept.value());
|
|
||||||
postLoadCommands.add(commandClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
addClass(commandClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
doPostLoading(interceptor, postLoadCommands);
|
|
||||||
|
|
||||||
FLog.info("Loaded " + commands.size() + " commands");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doPostLoading(Interceptor interceptor, Set<Class<? extends FreedomCommand>> postLoadCommands)
|
|
||||||
{
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, () ->
|
|
||||||
CompletableFuture.runAsync(interceptor::setOverrides)
|
|
||||||
.whenComplete((v, th) ->
|
|
||||||
{
|
|
||||||
if (th != null)
|
|
||||||
{
|
|
||||||
FLog.severe("Failed to set command overrides");
|
|
||||||
th.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Class<? extends FreedomCommand> commandClass : postLoadCommands)
|
|
||||||
{
|
|
||||||
if (checkDependencies(commandClass)) return;
|
|
||||||
|
|
||||||
addClass(commandClass);
|
|
||||||
}
|
|
||||||
}), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkDependencies(Class<? extends FreedomCommand> commandClass)
|
|
||||||
{
|
|
||||||
if (commandClass.isAnnotationPresent(CommandDependencies.class))
|
|
||||||
{
|
|
||||||
for (String dependency : commandClass.getAnnotation(CommandDependencies.class).value())
|
|
||||||
{
|
|
||||||
if (Bukkit.getPluginManager().getPlugin(dependency) == null)
|
|
||||||
{
|
|
||||||
FLog.warning("Failed to register command: /" + commandClass.getSimpleName().replace("Command_", "") + " (Missing dependency: " + dependency + ")");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addClass(Class<? extends FreedomCommand> commandClass)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
add(commandClass.newInstance());
|
|
||||||
} catch (InstantiationException | IllegalAccessException ex)
|
|
||||||
{
|
|
||||||
FLog.warning("Failed to register command: /" + commandClass.getSimpleName().replace("Command_", ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FreedomCommand> getCommands()
|
|
||||||
{
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command.handling;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface Intercept
|
|
||||||
{
|
|
||||||
String value();
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command.handling;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Interceptor
|
|
||||||
{
|
|
||||||
private final TotalFreedomMod plugin;
|
|
||||||
private final Map<String, Command> overrides = new HashMap<>();
|
|
||||||
|
|
||||||
public Interceptor(TotalFreedomMod plugin)
|
|
||||||
{
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void intercept(String command)
|
|
||||||
{
|
|
||||||
getPluginCommands().entrySet()
|
|
||||||
.stream()
|
|
||||||
.filter(entry -> !((PluginIdentifiableCommand) entry.getValue()) // Check that it isn't a tfm command
|
|
||||||
.getPlugin()
|
|
||||||
.getName()
|
|
||||||
.equalsIgnoreCase(plugin.getName()))
|
|
||||||
.filter(entry -> entry.getValue() // Check that the command is the one we want to intercept
|
|
||||||
.getName()
|
|
||||||
.equalsIgnoreCase(command))
|
|
||||||
.forEach(entry -> overrides.put(entry.getKey(), entry.getValue())); // Intercept.
|
|
||||||
|
|
||||||
getFallbackCommands().entrySet()
|
|
||||||
.stream()
|
|
||||||
.filter(entry -> entry.getValue() // Check that the command is the one we want to intercept
|
|
||||||
.getName()
|
|
||||||
.equalsIgnoreCase(command))
|
|
||||||
.forEach(entry -> overrides.put(entry.getKey(), entry.getValue())); // Intercept.
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOverrides()
|
|
||||||
{
|
|
||||||
overrides.forEach((key, value) ->
|
|
||||||
{
|
|
||||||
Bukkit.getCommandMap().getKnownCommands().remove(key, value);
|
|
||||||
FLog.info("Overriding command: " + key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Command> getFallbackCommands()
|
|
||||||
{
|
|
||||||
final Map<String, Command> fallbackCommands = new HashMap<>();
|
|
||||||
for (final Map.Entry<String, Command> entry : Bukkit.getCommandMap().getKnownCommands().entrySet())
|
|
||||||
{
|
|
||||||
if (!(entry.getValue() instanceof PluginIdentifiableCommand))
|
|
||||||
{
|
|
||||||
fallbackCommands.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fallbackCommands;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Command> getPluginCommands()
|
|
||||||
{
|
|
||||||
final Map<String, Command> pluginCommands = new HashMap<>();
|
|
||||||
for (final Map.Entry<String, Command> entry : Bukkit.getCommandMap().getKnownCommands().entrySet())
|
|
||||||
{
|
|
||||||
if (entry.getValue() instanceof PluginIdentifiableCommand)
|
|
||||||
{
|
|
||||||
pluginCommands.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pluginCommands;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.command.handling;
|
|
||||||
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public enum SourceType
|
|
||||||
{
|
|
||||||
ONLY_IN_GAME, ONLY_CONSOLE, BOTH;
|
|
||||||
|
|
||||||
public boolean permissionCheck(CommandSender sender)
|
|
||||||
{
|
|
||||||
return (sender instanceof Player && this == ONLY_IN_GAME) || (sender instanceof ConsoleCommandSender && this == ONLY_CONSOLE) || this == BOTH;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.fun;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.FreedomService;
|
|
||||||
import me.totalfreedom.totalfreedommod.api.ShopItem;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.ParticleDisplay;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SplittableRandom;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Trailer extends FreedomService
|
|
||||||
{
|
|
||||||
private final SplittableRandom random = new SplittableRandom();
|
|
||||||
private final Map<UUID, ParticleDisplay> trailPlayers = new HashMap<>(); // player UUID and relative particle instance.
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void onPlayerMove(PlayerMoveEvent event)
|
|
||||||
{
|
|
||||||
if (plugin.sh == null) return; // Shop is disabled
|
|
||||||
|
|
||||||
/* Doesn't continue any further if...
|
|
||||||
* - The trail list is empty
|
|
||||||
* - The player doesn't have their trail enabled in the first place
|
|
||||||
* - The player doesn't have the trail item in the shop at all
|
|
||||||
* - The player doesn't have permission to modify blocks in their current world
|
|
||||||
*/
|
|
||||||
if (trailPlayers.isEmpty()
|
|
||||||
|| !trailPlayers.containsKey(event.getPlayer().getUniqueId())
|
|
||||||
|| !plugin.pl.getData(event.getPlayer()).hasItem(ShopItem.RAINBOW_TRAIL))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player player = event.getPlayer();
|
|
||||||
final ParticleDisplay particleDisplay = trailPlayers.get(player.getUniqueId());
|
|
||||||
particleDisplay.spawnNext(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Player player)
|
|
||||||
{
|
|
||||||
trailPlayers.remove(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(Player player)
|
|
||||||
{
|
|
||||||
if (trailPlayers.containsKey(player.getUniqueId())) return;
|
|
||||||
|
|
||||||
trailPlayers.put(player.getUniqueId(), new ParticleDisplay());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(Player player)
|
|
||||||
{
|
|
||||||
return trailPlayers.containsKey(player.getUniqueId());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,175 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.httpd.module;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandMap;
|
|
||||||
import org.bukkit.command.PluginIdentifiableCommand;
|
|
||||||
import org.bukkit.permissions.Permission;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static me.totalfreedom.totalfreedommod.httpd.HTMLGenerationTools.heading;
|
|
||||||
import static me.totalfreedom.totalfreedommod.httpd.HTMLGenerationTools.paragraph;
|
|
||||||
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
|
|
||||||
|
|
||||||
public class Module_help extends HTTPDModule
|
|
||||||
{
|
|
||||||
public Module_help(NanoHTTPD.HTTPSession session)
|
|
||||||
{
|
|
||||||
super(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildDescription(@NotNull Command command)
|
|
||||||
{
|
|
||||||
return buildDescription(command.getName(), command.getDescription(), command.getUsage(), StringUtils.join(command.getAliases(), ", "));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildDescription(@NotNull FreedomCommand command)
|
|
||||||
{
|
|
||||||
return buildDescription(command.getName(), command.getDescription(), command.getUsage(), command.getAliases());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildDescription(@NotNull String name, @Nullable String description, @NotNull String usage, @NotNull String aliases)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.append(
|
|
||||||
"<li><span class=\"commandName\">{$CMD_NAME}</span> - Usage: <span class=\"commandUsage\">{$CMD_USAGE}</span>"
|
|
||||||
.replace("{$CMD_NAME}", escapeHtml4(name.trim()))
|
|
||||||
.replace("{$CMD_USAGE}", escapeHtml4(usage.trim())));
|
|
||||||
|
|
||||||
if (!aliases.isEmpty())
|
|
||||||
{
|
|
||||||
sb.append(
|
|
||||||
" - Aliases: <span class=\"commandAliases\">{$CMD_ALIASES}</span>"
|
|
||||||
.replace("{$CMD_ALIASES}", escapeHtml4(aliases.trim())));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (description != null)
|
|
||||||
{
|
|
||||||
sb.append(
|
|
||||||
"<br><span class=\"commandDescription\">{$CMD_DESC}</span></li>\r\n"
|
|
||||||
.replace("{$CMD_DESC}", escapeHtml4(description.trim())));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBody()
|
|
||||||
{
|
|
||||||
final CommandMap map = Bukkit.getCommandMap();
|
|
||||||
|
|
||||||
final StringBuilder responseBody = new StringBuilder()
|
|
||||||
.append(heading("Command Help", 1))
|
|
||||||
.append(paragraph(
|
|
||||||
"This page is an automatically generated listing of all plugin commands that are currently live on the server. "
|
|
||||||
+ "Please note that it does not include vanilla server commands."));
|
|
||||||
|
|
||||||
final Collection<Command> knownCommands = map.getKnownCommands().values();
|
|
||||||
final Map<String, List<Command>> commandsByPlugin = new HashMap<>();
|
|
||||||
|
|
||||||
for (Command command : knownCommands)
|
|
||||||
{
|
|
||||||
String pluginName = "Bukkit";
|
|
||||||
if (command instanceof PluginIdentifiableCommand)
|
|
||||||
{
|
|
||||||
pluginName = ((PluginIdentifiableCommand) command).getPlugin().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Command> pluginCommands = commandsByPlugin.computeIfAbsent(pluginName, k -> Lists.newArrayList());
|
|
||||||
|
|
||||||
if (!pluginCommands.contains(command))
|
|
||||||
{
|
|
||||||
pluginCommands.add(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final CommandComparator comparator = new CommandComparator();
|
|
||||||
|
|
||||||
// For every plugin...
|
|
||||||
for (Map.Entry<String, List<Command>> entry : commandsByPlugin.entrySet())
|
|
||||||
{
|
|
||||||
final String pluginName = entry.getKey();
|
|
||||||
final List<Command> commands = entry.getValue();
|
|
||||||
|
|
||||||
// Sort them alphabetically
|
|
||||||
commands.sort(comparator);
|
|
||||||
|
|
||||||
responseBody.append(heading(pluginName, pluginName, 2)).append("<ul>\r\n");
|
|
||||||
|
|
||||||
if (!plugin.getName().equals(pluginName))
|
|
||||||
{
|
|
||||||
commands.forEach((command) -> responseBody.append(buildDescription(command)));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
Map<String, List<FreedomCommand>> freedomCommands = new HashMap<>();
|
|
||||||
|
|
||||||
// Filters out non-TFM commands
|
|
||||||
commands.stream().filter((cmd) -> cmd instanceof FreedomCommand.FCommand).forEach((tfmCmd) ->
|
|
||||||
{
|
|
||||||
String permission = Objects.requireNonNull(FreedomCommand.getFrom(tfmCmd)).getPermission();
|
|
||||||
if (!freedomCommands.containsKey(permission))
|
|
||||||
freedomCommands.put(permission, new ArrayList<>());
|
|
||||||
freedomCommands.get(permission).add(FreedomCommand.getFrom(tfmCmd));
|
|
||||||
});
|
|
||||||
|
|
||||||
List<String> permissions = Bukkit.getPluginManager()
|
|
||||||
.getPermissions()
|
|
||||||
.stream()
|
|
||||||
.map(Permission::getName)
|
|
||||||
.filter(permission -> permission.startsWith("tfm."))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
// Finally dumps them to HTML
|
|
||||||
permissions.stream().filter(freedomCommands::containsKey)
|
|
||||||
.sorted(comparator::compare).forEach((permission ->
|
|
||||||
{
|
|
||||||
responseBody.append("</ul>\r\n").append(heading(permission, 3)).append("<ul>\r\n");
|
|
||||||
freedomCommands.get(permission).stream().sorted(comparator::compare).forEach((command) -> responseBody.append(buildDescription(command)));
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
responseBody.append("</ul>\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseBody.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle()
|
|
||||||
{
|
|
||||||
return plugin.getName() + " :: Command Help";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getStyle()
|
|
||||||
{
|
|
||||||
return ".commandName{font-weight:bold;}.commandDescription{padding-left:15px;}li{margin:.15em;padding:.15em;}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CommandComparator implements Comparator<Command>
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int compare(Command a, Command b)
|
|
||||||
{
|
|
||||||
return a.getName().compareTo(b.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compare(FreedomCommand a, FreedomCommand b)
|
|
||||||
{
|
|
||||||
return a.getName().compareTo(b.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compare(String perm1, String perm2)
|
|
||||||
{
|
|
||||||
return perm1.compareTo(perm2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.httpd.module;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Module_players extends HTTPDModule
|
|
||||||
{
|
|
||||||
private static final Gson gson = new Gson();
|
|
||||||
|
|
||||||
public Module_players(NanoHTTPD.HTTPSession session)
|
|
||||||
{
|
|
||||||
super(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NanoHTTPD.Response getResponse()
|
|
||||||
{
|
|
||||||
final Map<String, List<String>> responseMap = new HashMap<>();
|
|
||||||
|
|
||||||
final List<String> admins = new ArrayList<>();
|
|
||||||
final List<String> senioradmins = new ArrayList<>();
|
|
||||||
|
|
||||||
plugin.al.getActiveAdmins().stream().filter(admin -> admin.getName() != null).forEach(admin ->
|
|
||||||
{
|
|
||||||
// Do nothing, keeps Codacy quiet
|
|
||||||
if (admin.getRank().equals(TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin()))
|
|
||||||
{
|
|
||||||
admins.add(admin.getName());
|
|
||||||
} else if (admin.getRank().equals(TotalFreedomMod.getPlugin().getHierarchy().groups().getSeniorAdmin()))
|
|
||||||
{
|
|
||||||
senioradmins.add(admin.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
responseMap.put("players", server.getOnlinePlayers().stream().filter(player ->
|
|
||||||
!plugin.al.isVanished(player.getUniqueId())).map(HumanEntity::getName).toList());
|
|
||||||
responseMap.put("masterbuilders", plugin.pl.getMasterBuilderNames());
|
|
||||||
responseMap.put("admins", admins);
|
|
||||||
responseMap.put("senioradmins", senioradmins);
|
|
||||||
responseMap.put("developers", FUtil.DEVELOPER_NAMES);
|
|
||||||
responseMap.put("assistantexecutives", ConfigEntry.SERVER_ASSISTANT_EXECUTIVES.getStringList());
|
|
||||||
responseMap.put("executives", ConfigEntry.SERVER_EXECUTIVES.getStringList());
|
|
||||||
|
|
||||||
final NanoHTTPD.Response response = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK, NanoHTTPD.MIME_JSON,
|
|
||||||
gson.toJson(responseMap));
|
|
||||||
response.addHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.perms;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import net.luckperms.api.model.group.Group;
|
|
||||||
import net.luckperms.api.model.group.GroupManager;
|
|
||||||
|
|
||||||
public class GroupWrapper
|
|
||||||
{
|
|
||||||
private final GroupManager manager;
|
|
||||||
|
|
||||||
public GroupWrapper(GroupManager manager)
|
|
||||||
{
|
|
||||||
this.manager = manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group getGroup(String name)
|
|
||||||
{
|
|
||||||
if (!manager.isLoaded(name))
|
|
||||||
{
|
|
||||||
return manager.createAndLoadGroup(name).join();
|
|
||||||
}
|
|
||||||
|
|
||||||
return manager.getGroup(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveGroup(String name)
|
|
||||||
{
|
|
||||||
Group group = getGroup(name);
|
|
||||||
manager.saveGroup(group)
|
|
||||||
.thenRun(() ->
|
|
||||||
FLog.info("Saved group " + name + " to LuckPerms."));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.perms;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import net.luckperms.api.track.Track;
|
|
||||||
import net.luckperms.api.track.TrackManager;
|
|
||||||
|
|
||||||
public class TrackWrapper
|
|
||||||
{
|
|
||||||
private final TrackManager manager;
|
|
||||||
|
|
||||||
public TrackWrapper(TrackManager manager)
|
|
||||||
{
|
|
||||||
this.manager = manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Track getTrack(String name)
|
|
||||||
{
|
|
||||||
if (!manager.isLoaded(name))
|
|
||||||
{
|
|
||||||
return manager.createAndLoadTrack(name).join();
|
|
||||||
}
|
|
||||||
|
|
||||||
return manager.getTrack(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveTrack(String name)
|
|
||||||
{
|
|
||||||
Track t = getTrack(name);
|
|
||||||
manager.saveTrack(t)
|
|
||||||
.thenRun(() ->
|
|
||||||
FLog.info("Saved track " + name + " successfully."));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.perms;
|
|
||||||
|
|
||||||
import net.luckperms.api.LuckPermsProvider;
|
|
||||||
import net.luckperms.api.cacheddata.CachedDataManager;
|
|
||||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
|
||||||
import net.luckperms.api.cacheddata.CachedPermissionData;
|
|
||||||
import net.luckperms.api.context.ImmutableContextSet;
|
|
||||||
import net.luckperms.api.model.user.User;
|
|
||||||
import net.luckperms.api.platform.PlayerAdapter;
|
|
||||||
import net.luckperms.api.query.QueryOptions;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is a utility class that can be used to retrieve
|
|
||||||
* numerous contextual options related to LuckPerms users.
|
|
||||||
*/
|
|
||||||
public class UserData
|
|
||||||
{
|
|
||||||
public static User fromPlayer(Player player)
|
|
||||||
{
|
|
||||||
PlayerAdapter<Player> adapter = LuckPermsProvider
|
|
||||||
.get()
|
|
||||||
.getPlayerAdapter(Player.class);
|
|
||||||
return adapter.getUser(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static QueryOptions getQueryOptions(User user)
|
|
||||||
{
|
|
||||||
return user.getQueryOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CachedDataManager getDataManager(User user)
|
|
||||||
{
|
|
||||||
return user.getCachedData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ImmutableContextSet getContextSet(User user)
|
|
||||||
{
|
|
||||||
return getQueryOptions(user).context();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CachedMetaData getMetaData(User user)
|
|
||||||
{
|
|
||||||
return getDataManager(user).getMetaData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CachedPermissionData getPermissionData(User user)
|
|
||||||
{
|
|
||||||
return getDataManager(user).getPermissionData();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.perms;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import net.luckperms.api.model.user.User;
|
|
||||||
import net.luckperms.api.model.user.UserManager;
|
|
||||||
import net.luckperms.api.node.NodeType;
|
|
||||||
import net.luckperms.api.platform.PlayerAdapter;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class UserWrapper
|
|
||||||
{
|
|
||||||
private final UserManager manager;
|
|
||||||
private final PlayerAdapter<Player> playerAdapter;
|
|
||||||
|
|
||||||
public UserWrapper(UserManager manager, PlayerAdapter<Player> adapter)
|
|
||||||
{
|
|
||||||
this.manager = manager;
|
|
||||||
this.playerAdapter = adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getUser(Player player)
|
|
||||||
{
|
|
||||||
if (!manager.isLoaded(player.getUniqueId()) || !manager.getLoadedUsers().contains(manager.getUser(player.getUniqueId())))
|
|
||||||
{
|
|
||||||
return manager.loadUser(player.getUniqueId()).join();
|
|
||||||
}
|
|
||||||
|
|
||||||
return manager.getUser(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addToGroup(User user, DisplayableGroup group)
|
|
||||||
{
|
|
||||||
|
|
||||||
manager.modifyUser(user.getUniqueId(), c ->
|
|
||||||
{
|
|
||||||
if (!c.getNodes(NodeType.INHERITANCE)
|
|
||||||
.contains(group.getInheritance()))
|
|
||||||
c.data().add(group.getInheritance());
|
|
||||||
})
|
|
||||||
.thenRun(() ->
|
|
||||||
FLog.info("Successfully saved user "
|
|
||||||
+ user.getUsername()
|
|
||||||
+ " to group "
|
|
||||||
+ group.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeFromGroup(User user, DisplayableGroup group)
|
|
||||||
{
|
|
||||||
manager.modifyUser(user.getUniqueId(), userConsumer ->
|
|
||||||
{
|
|
||||||
if (userConsumer.getNodes(NodeType.INHERITANCE)
|
|
||||||
.contains(group.getInheritance()))
|
|
||||||
userConsumer.data().remove(group.getInheritance());
|
|
||||||
}).thenRun(() ->
|
|
||||||
FLog.info("Successfully removed user "
|
|
||||||
+ user.getUsername()
|
|
||||||
+ " from group "
|
|
||||||
+ group.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveUser(User user)
|
|
||||||
{
|
|
||||||
manager.saveUser(user).thenRun(() ->
|
|
||||||
FLog.info("Successfully saved user "
|
|
||||||
+ user.getUsername()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.rank;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
|
|
||||||
public interface Displayable
|
|
||||||
{
|
|
||||||
Component getArticle();
|
|
||||||
|
|
||||||
Component getName();
|
|
||||||
|
|
||||||
Component getTag();
|
|
||||||
|
|
||||||
Component getAbbr();
|
|
||||||
|
|
||||||
Component getPlural();
|
|
||||||
|
|
||||||
TextColor getColor();
|
|
||||||
|
|
||||||
org.bukkit.ChatColor getTeamColor();
|
|
||||||
|
|
||||||
Component getColoredName();
|
|
||||||
|
|
||||||
Component getColoredTag();
|
|
||||||
|
|
||||||
Component getColoredLoginMessage();
|
|
||||||
|
|
||||||
boolean hasTeam();
|
|
||||||
|
|
||||||
boolean hasDefaultLoginMessage();
|
|
||||||
}
|
|
@ -1,233 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.rank;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import net.luckperms.api.context.ContextSatisfyMode;
|
|
||||||
import net.luckperms.api.model.group.Group;
|
|
||||||
import net.luckperms.api.node.NodeType;
|
|
||||||
import net.luckperms.api.node.types.InheritanceNode;
|
|
||||||
import net.luckperms.api.node.types.PermissionNode;
|
|
||||||
import net.luckperms.api.node.types.PrefixNode;
|
|
||||||
import net.luckperms.api.node.types.WeightNode;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class DisplayableGroup implements Displayable
|
|
||||||
{
|
|
||||||
private final Group group;
|
|
||||||
|
|
||||||
private final Component name;
|
|
||||||
|
|
||||||
private final Component abbr;
|
|
||||||
private final Component plural;
|
|
||||||
private final Component article;
|
|
||||||
private final WeightNode weight;
|
|
||||||
|
|
||||||
private final Component tag;
|
|
||||||
|
|
||||||
private final Component coloredTag;
|
|
||||||
|
|
||||||
private final TextColor color;
|
|
||||||
|
|
||||||
private final org.bukkit.ChatColor teamColor;
|
|
||||||
|
|
||||||
private final boolean hasTeam;
|
|
||||||
|
|
||||||
private final boolean hasDefaultLoginMessage;
|
|
||||||
|
|
||||||
|
|
||||||
private final InheritanceNode inheritance;
|
|
||||||
private final PrefixNode prefix;
|
|
||||||
private final List<PermissionNode> permissions = new ArrayList<>();
|
|
||||||
|
|
||||||
|
|
||||||
public DisplayableGroup(String group,
|
|
||||||
Component plural,
|
|
||||||
Component tag,
|
|
||||||
int weight,
|
|
||||||
TextColor color,
|
|
||||||
org.bukkit.ChatColor teamColor,
|
|
||||||
boolean hasTeam,
|
|
||||||
boolean hasDefaultLoginMessage)
|
|
||||||
{
|
|
||||||
WeightNode tempWeight;
|
|
||||||
PrefixNode tempPrefix;
|
|
||||||
Group matched = TotalFreedomMod.getPlugin().getHierarchy().getGroup(group); // we don't need to null check because if there is no group this method will also create one.
|
|
||||||
|
|
||||||
this.name = (matched.getDisplayName() != null) ? FUtil.miniMessage(matched.getDisplayName()) : FUtil.miniMessage(matched.getName());
|
|
||||||
this.plural = plural;
|
|
||||||
this.article = StringUtils.startsWithAny(this.name.toString().toLowerCase(Locale.ROOT), new String[]{"a", "e", "i", "o", "u"}) ? Component.text("an") : Component.text("a");
|
|
||||||
this.abbr = tag;
|
|
||||||
this.color = color;
|
|
||||||
this.teamColor = teamColor;
|
|
||||||
this.hasTeam = hasTeam;
|
|
||||||
this.coloredTag = tag.color(color);
|
|
||||||
this.tag = GroupProvider.OPEN.append(coloredTag).append(GroupProvider.CLOSE);
|
|
||||||
this.hasDefaultLoginMessage = hasDefaultLoginMessage;
|
|
||||||
tempWeight = WeightNode.builder(weight).build();
|
|
||||||
tempPrefix = PrefixNode.builder(FUtil.miniMessage(getTag()), weight).build();
|
|
||||||
|
|
||||||
permissions.addAll(matched.getNodes(NodeType.PERMISSION));
|
|
||||||
|
|
||||||
if (!matched.getNodes(NodeType.PREFIX).contains(tempPrefix)) matched.data().add(tempPrefix);
|
|
||||||
else tempPrefix = matched.getNodes(NodeType.PREFIX).iterator().next();
|
|
||||||
|
|
||||||
if (!matched.getNodes(NodeType.WEIGHT).contains(tempWeight)) matched.data().add(tempWeight);
|
|
||||||
else tempWeight = matched.getNodes(NodeType.WEIGHT).iterator().next();
|
|
||||||
|
|
||||||
this.prefix = tempPrefix;
|
|
||||||
this.weight = tempWeight;
|
|
||||||
this.group = matched;
|
|
||||||
this.inheritance = InheritanceNode.builder(this.group).build();
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the weight of this rank instance against the given rank.
|
|
||||||
*
|
|
||||||
* @param rank The rank to check against.
|
|
||||||
* @return True if the given rank is less than or equal to the weight of this specific rank instance.
|
|
||||||
*/
|
|
||||||
public boolean weightCheckAgainst(@NotNull DisplayableGroup rank)
|
|
||||||
{
|
|
||||||
return rank.getWeight().getWeight() <= getWeight().getWeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPermission(String permission)
|
|
||||||
{
|
|
||||||
PermissionNode node = PermissionNode.builder(permission).build();
|
|
||||||
for (PermissionNode it : group.getNodes(NodeType.PERMISSION))
|
|
||||||
{
|
|
||||||
if (it.getContexts().isSatisfiedBy(node.getContexts())
|
|
||||||
|| it.getKey().equals(node.getKey()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
group.data().add(node);
|
|
||||||
permissions.add(node);
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removePermission(String permission)
|
|
||||||
{
|
|
||||||
PermissionNode node = PermissionNode.builder(permission).build();
|
|
||||||
for (PermissionNode it : group.getNodes(NodeType.PERMISSION))
|
|
||||||
{
|
|
||||||
if (it.getContexts().isSatisfiedBy(node.getContexts(), ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
|
|
||||||
|| it.getKey().equals(node.getKey()))
|
|
||||||
{
|
|
||||||
group.data().remove(node);
|
|
||||||
permissions.remove(node);
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public WeightNode getWeight()
|
|
||||||
{
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group getLuckPermsGroup()
|
|
||||||
{
|
|
||||||
return this.group;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getArticle()
|
|
||||||
{
|
|
||||||
return this.article;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getTag()
|
|
||||||
{
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getAbbr()
|
|
||||||
{
|
|
||||||
return abbr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getPlural()
|
|
||||||
{
|
|
||||||
return plural;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TextColor getColor()
|
|
||||||
{
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public org.bukkit.ChatColor getTeamColor()
|
|
||||||
{
|
|
||||||
return teamColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getColoredName()
|
|
||||||
{
|
|
||||||
return name.color(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getColoredTag()
|
|
||||||
{
|
|
||||||
return coloredTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getColoredLoginMessage()
|
|
||||||
{
|
|
||||||
return article.append(Component.text(" ")).append(name.color(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasTeam()
|
|
||||||
{
|
|
||||||
return hasTeam;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasDefaultLoginMessage()
|
|
||||||
{
|
|
||||||
return hasDefaultLoginMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InheritanceNode getInheritance()
|
|
||||||
{
|
|
||||||
return inheritance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrefixNode getPrefix()
|
|
||||||
{
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PermissionNode> getPermissions()
|
|
||||||
{
|
|
||||||
return permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save()
|
|
||||||
{
|
|
||||||
TotalFreedomMod.getPlugin().getHierarchy().gw().saveGroup(group.getName());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,130 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.rank;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.luckperms.api.model.group.Group;
|
|
||||||
import net.luckperms.api.node.types.InheritanceNode;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class GroupProvider
|
|
||||||
{
|
|
||||||
public static final Component OPEN = Component.text("[", NamedTextColor.DARK_GRAY);
|
|
||||||
public static final Component CLOSE = Component.text("]", NamedTextColor.DARK_GRAY);
|
|
||||||
|
|
||||||
private final DisplayableGroup nonOp;
|
|
||||||
private final DisplayableGroup op;
|
|
||||||
private final DisplayableGroup masterBuilder;
|
|
||||||
private final DisplayableGroup admin;
|
|
||||||
private final DisplayableGroup seniorAdmin;
|
|
||||||
|
|
||||||
public GroupProvider()
|
|
||||||
{
|
|
||||||
this.nonOp = new DisplayableGroup(
|
|
||||||
"default",
|
|
||||||
Component.text("Non-Ops"),
|
|
||||||
Component.empty(),
|
|
||||||
0,
|
|
||||||
NamedTextColor.WHITE,
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
|
|
||||||
this.op = new DisplayableGroup(
|
|
||||||
"op",
|
|
||||||
Component.text("Operators"),
|
|
||||||
Component.text("Op"),
|
|
||||||
1,
|
|
||||||
NamedTextColor.GREEN,
|
|
||||||
null,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
|
|
||||||
this.masterBuilder = new DisplayableGroup(
|
|
||||||
"builder",
|
|
||||||
Component.text("Master Builders"),
|
|
||||||
Component.text("MB"),
|
|
||||||
2,
|
|
||||||
NamedTextColor.DARK_AQUA,
|
|
||||||
ChatColor.DARK_AQUA,
|
|
||||||
true,
|
|
||||||
true);
|
|
||||||
|
|
||||||
this.admin = new DisplayableGroup(
|
|
||||||
"admin",
|
|
||||||
Component.text("Administrators"),
|
|
||||||
Component.text("Admin"),
|
|
||||||
3,
|
|
||||||
NamedTextColor.DARK_GREEN,
|
|
||||||
ChatColor.DARK_GREEN,
|
|
||||||
true,
|
|
||||||
true);
|
|
||||||
|
|
||||||
this.seniorAdmin = new DisplayableGroup(
|
|
||||||
"senior",
|
|
||||||
Component.text("Senior Administrators"),
|
|
||||||
Component.text("SrA"),
|
|
||||||
4,
|
|
||||||
NamedTextColor.GOLD,
|
|
||||||
ChatColor.GOLD,
|
|
||||||
true,
|
|
||||||
true);
|
|
||||||
|
|
||||||
nonOp.save();
|
|
||||||
op.save();
|
|
||||||
masterBuilder.save();
|
|
||||||
admin.save();
|
|
||||||
seniorAdmin.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup getNonOp()
|
|
||||||
{
|
|
||||||
return nonOp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup getOp()
|
|
||||||
{
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup getMasterBuilder()
|
|
||||||
{
|
|
||||||
return masterBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup getAdmin()
|
|
||||||
{
|
|
||||||
return admin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup getSeniorAdmin()
|
|
||||||
{
|
|
||||||
return seniorAdmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InheritanceNode inheritanceNode(DisplayableGroup group)
|
|
||||||
{
|
|
||||||
return InheritanceNode.builder(group.getLuckPermsGroup()).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup fromLuckPerms(Group group)
|
|
||||||
{
|
|
||||||
return Stream.of(nonOp, op, masterBuilder, admin, seniorAdmin)
|
|
||||||
.filter(displayableGroup -> displayableGroup.getLuckPermsGroup().equals(group))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(nonOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableGroup fromString(String arg)
|
|
||||||
{
|
|
||||||
return switch (arg.toLowerCase())
|
|
||||||
{
|
|
||||||
case "op" -> op;
|
|
||||||
case "builder" -> masterBuilder;
|
|
||||||
case "admin" -> admin;
|
|
||||||
case "senior" -> seniorAdmin;
|
|
||||||
default -> nonOp;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,147 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.rank;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.perms.GroupWrapper;
|
|
||||||
import me.totalfreedom.totalfreedommod.perms.TrackWrapper;
|
|
||||||
import me.totalfreedom.totalfreedommod.perms.UserData;
|
|
||||||
import me.totalfreedom.totalfreedommod.perms.UserWrapper;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import net.luckperms.api.model.group.Group;
|
|
||||||
import net.luckperms.api.model.user.User;
|
|
||||||
import net.luckperms.api.node.NodeType;
|
|
||||||
import net.luckperms.api.node.types.InheritanceNode;
|
|
||||||
import net.luckperms.api.platform.PlayerAdapter;
|
|
||||||
import net.luckperms.api.track.DemotionResult;
|
|
||||||
import net.luckperms.api.track.PromotionResult;
|
|
||||||
import net.luckperms.api.track.Track;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class Hierarchy
|
|
||||||
{
|
|
||||||
private final GroupWrapper groupWrapper;
|
|
||||||
private final TrackWrapper trackWrapper;
|
|
||||||
private final UserWrapper userWrapper;
|
|
||||||
private final PlayerAdapter<Player> playerAdapter;
|
|
||||||
private final GroupProvider groupProvider;
|
|
||||||
|
|
||||||
public Hierarchy()
|
|
||||||
{
|
|
||||||
this.playerAdapter = TotalFreedomMod.getPlugin().lpb.getAPI().getPlayerAdapter(Player.class);
|
|
||||||
this.groupWrapper = new GroupWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getGroupManager());
|
|
||||||
this.trackWrapper = new TrackWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getTrackManager());
|
|
||||||
this.userWrapper = new UserWrapper(TotalFreedomMod.getPlugin().lpb.getAPI().getUserManager(), getPlayerAdapter());
|
|
||||||
this.groupProvider = new GroupProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TrackWrapper tw()
|
|
||||||
{
|
|
||||||
return trackWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupWrapper gw()
|
|
||||||
{
|
|
||||||
return groupWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserWrapper uw()
|
|
||||||
{
|
|
||||||
return userWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerAdapter<Player> getPlayerAdapter()
|
|
||||||
{
|
|
||||||
return playerAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUserOnAdminTrack(Player player)
|
|
||||||
{
|
|
||||||
User user = uw().getUser(player);
|
|
||||||
return user
|
|
||||||
.getNodes(NodeType.INHERITANCE)
|
|
||||||
.contains(groups().inheritanceNode(groups().getAdmin()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupProvider groups()
|
|
||||||
{
|
|
||||||
return groupProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Track op()
|
|
||||||
{
|
|
||||||
return tw().getTrack("op");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Track builder()
|
|
||||||
{
|
|
||||||
return tw().getTrack("BUILDER");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Track admin()
|
|
||||||
{
|
|
||||||
return tw().getTrack("admin");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void asyncInheritFrom(DisplayableGroup inherited, DisplayableGroup inheritor)
|
|
||||||
{
|
|
||||||
inheritor
|
|
||||||
.getLuckPermsGroup()
|
|
||||||
.data()
|
|
||||||
.add(inherited.getInheritance());
|
|
||||||
|
|
||||||
gw().saveGroup(inheritor
|
|
||||||
.getLuckPermsGroup()
|
|
||||||
.getName());
|
|
||||||
|
|
||||||
FLog.info("Inherited " + inherited.getName() + " to " + inheritor.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group getGroup(String name)
|
|
||||||
{
|
|
||||||
return gw().getGroup(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void asyncTrackGroup(Track track, DisplayableGroup group)
|
|
||||||
{
|
|
||||||
Track t = tw().getTrack(track.getName());
|
|
||||||
t.appendGroup(group.getLuckPermsGroup());
|
|
||||||
tw().saveTrack(t.getName());
|
|
||||||
gw().saveGroup(group.getLuckPermsGroup().getName());
|
|
||||||
FLog.info("Added " + group.getName() + " to track " + track.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PromotionResult promoteUser(Track track, Player player)
|
|
||||||
{
|
|
||||||
User user = UserData.fromPlayer(player);
|
|
||||||
return track.promote(user, UserData.getContextSet(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public DemotionResult demoteUser(Track track, Player player)
|
|
||||||
{
|
|
||||||
User user = UserData.fromPlayer(player);
|
|
||||||
return track.demote(user, UserData.getContextSet(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addUserToGroup(DisplayableGroup group, Player player)
|
|
||||||
{
|
|
||||||
User user = UserData.fromPlayer(player);
|
|
||||||
uw().addToGroup(user, group);
|
|
||||||
FLog.info("Successfully added " + player.getName() + " to " + group.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dropUser(Track track, Player player)
|
|
||||||
{
|
|
||||||
User user = UserData.fromPlayer(player);
|
|
||||||
|
|
||||||
for (String group : track.getGroups())
|
|
||||||
{
|
|
||||||
Group g = gw().getGroup(group);
|
|
||||||
InheritanceNode node = groups()
|
|
||||||
.fromLuckPerms(g)
|
|
||||||
.getInheritance();
|
|
||||||
|
|
||||||
if (user.getNodes(NodeType.INHERITANCE).contains(node))
|
|
||||||
uw().removeFromGroup(user, groups()
|
|
||||||
.fromLuckPerms(g));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.rank;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
|
|
||||||
public enum Title implements Displayable
|
|
||||||
{
|
|
||||||
MASTER_BUILDER(Component.text("a"),
|
|
||||||
Component.text("Master Builder"),
|
|
||||||
Component.text("Master Builders"),
|
|
||||||
NamedTextColor.DARK_AQUA,
|
|
||||||
org.bukkit.ChatColor.DARK_AQUA,
|
|
||||||
Component.text("MB"),
|
|
||||||
true,
|
|
||||||
true),
|
|
||||||
EXECUTIVE(Component.text("an"),
|
|
||||||
Component.text("Executive"),
|
|
||||||
Component.text("Executives"),
|
|
||||||
NamedTextColor.RED,
|
|
||||||
org.bukkit.ChatColor.RED,
|
|
||||||
Component.text("Exec"),
|
|
||||||
true,
|
|
||||||
true),
|
|
||||||
ASST_EXEC(Component.text("an"),
|
|
||||||
Component.text("Assistant Executive"),
|
|
||||||
Component.text("Assistant Executives"),
|
|
||||||
NamedTextColor.RED,
|
|
||||||
org.bukkit.ChatColor.RED,
|
|
||||||
Component.text("Asst Exec"),
|
|
||||||
true,
|
|
||||||
true),
|
|
||||||
DEVELOPER(Component.text("a"),
|
|
||||||
Component.text("Developer"),
|
|
||||||
Component.text("Developers"),
|
|
||||||
NamedTextColor.DARK_PURPLE,
|
|
||||||
org.bukkit.ChatColor.DARK_PURPLE,
|
|
||||||
Component.text("Dev"),
|
|
||||||
true,
|
|
||||||
true),
|
|
||||||
OWNER(Component.text("an"),
|
|
||||||
Component.text("Owner"),
|
|
||||||
Component.text("Owners"),
|
|
||||||
NamedTextColor.DARK_RED,
|
|
||||||
org.bukkit.ChatColor.DARK_RED,
|
|
||||||
Component.text("Owner"),
|
|
||||||
true,
|
|
||||||
true);
|
|
||||||
|
|
||||||
|
|
||||||
private final Component article;
|
|
||||||
|
|
||||||
private final Component name;
|
|
||||||
|
|
||||||
private final Component abbr;
|
|
||||||
private final Component plural;
|
|
||||||
|
|
||||||
private final Component tag;
|
|
||||||
|
|
||||||
private final Component coloredTag;
|
|
||||||
|
|
||||||
private final TextColor color;
|
|
||||||
|
|
||||||
private final org.bukkit.ChatColor teamColor;
|
|
||||||
|
|
||||||
private final boolean hasTeam;
|
|
||||||
private final boolean hasDefaultLoginMessage;
|
|
||||||
|
|
||||||
Title(Component article, Component name, Component plural, TextColor color, org.bukkit.ChatColor teamColor, Component tag, Boolean hasTeam, Boolean hasDefaultLoginMessage)
|
|
||||||
{
|
|
||||||
this.article = article;
|
|
||||||
this.name = name;
|
|
||||||
this.plural = plural;
|
|
||||||
this.coloredTag = tag.color(color);
|
|
||||||
this.abbr = tag;
|
|
||||||
this.tag = GroupProvider.OPEN.append(tag).append(GroupProvider.CLOSE);
|
|
||||||
this.color = color;
|
|
||||||
this.teamColor = teamColor;
|
|
||||||
this.hasTeam = hasTeam;
|
|
||||||
this.hasDefaultLoginMessage = hasDefaultLoginMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getColoredName()
|
|
||||||
{
|
|
||||||
return name.color(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasTeam()
|
|
||||||
{
|
|
||||||
return hasTeam;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasDefaultLoginMessage()
|
|
||||||
{
|
|
||||||
return hasDefaultLoginMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getColoredLoginMessage()
|
|
||||||
{
|
|
||||||
return article.append(Component.text(" ").append(name.color(color)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getArticle()
|
|
||||||
{
|
|
||||||
return article;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getAbbr()
|
|
||||||
{
|
|
||||||
return abbr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getPlural()
|
|
||||||
{
|
|
||||||
return plural;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getTag()
|
|
||||||
{
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getColoredTag()
|
|
||||||
{
|
|
||||||
return coloredTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TextColor getColor()
|
|
||||||
{
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public org.bukkit.ChatColor getTeamColor()
|
|
||||||
{
|
|
||||||
return teamColor;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.util;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class FConverter
|
|
||||||
{
|
|
||||||
private static final Pattern godFuckingDamnit = Pattern.compile(".*(?i)(&((#[a-f0-9]{3,6})|([0-9a-fklmnor]))|%[a-z]+%).*");
|
|
||||||
|
|
||||||
public static boolean needsConversion(String messageOrFormat)
|
|
||||||
{
|
|
||||||
return godFuckingDamnit.matcher(messageOrFormat).find();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String convertAdminChatFormat(String format)
|
|
||||||
{
|
|
||||||
return FUtil.MINI_MESSAGE.serialize(FUtil.LEGACY_AMPERSAND.deserialize(
|
|
||||||
format.replaceAll("%name%", "<name>")
|
|
||||||
.replaceAll("%rank%", "<rank>")
|
|
||||||
.replaceAll("%rankcolor%", "<rankcolor>")
|
|
||||||
.replaceAll("%msg%", "<message>")))
|
|
||||||
.replaceAll("\\\\<", "<"); // GOD FUCKING DAMMIT
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String convertLoginMessage(String message)
|
|
||||||
{
|
|
||||||
return FUtil.MINI_MESSAGE.serialize(FUtil.LEGACY_AMPERSAND.deserialize(
|
|
||||||
message.replaceAll("%name%", "<name>")
|
|
||||||
.replaceAll("%rank%", "<rank>")
|
|
||||||
.replaceAll("%coloredrank%", "<coloredrank>")
|
|
||||||
.replaceAll("%art%", "<art>")))
|
|
||||||
.replaceAll("\\\\<", "<"); // GOD FUCKING DAMMIT
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.util;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Biome;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class Groups
|
|
||||||
{
|
|
||||||
public static final Set<Material> WOOL_COLORS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_WOOL")).collect(Collectors.toSet());
|
|
||||||
public static final Set<Material> SHULKER_BOXES = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("SHULKER_BOX")).collect(Collectors.toSet());
|
|
||||||
public static final Set<EntityType> MOB_TYPES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).collect(Collectors.toSet());
|
|
||||||
public static final Set<Material> SPAWN_EGGS = Arrays.stream(Material.values()).filter((mat) -> mat.name().endsWith("_SPAWN_EGG")).collect(Collectors.toSet());
|
|
||||||
public static final Set<Material> BANNERS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_BANNER")).collect(Collectors.toSet());
|
|
||||||
public static final Set<Biome> EXPLOSIVE_BED_BIOMES = new HashSet<>(Arrays.asList(
|
|
||||||
Biome.NETHER_WASTES,
|
|
||||||
Biome.CRIMSON_FOREST,
|
|
||||||
Biome.SOUL_SAND_VALLEY,
|
|
||||||
Biome.WARPED_FOREST,
|
|
||||||
Biome.BASALT_DELTAS,
|
|
||||||
Biome.END_BARRENS,
|
|
||||||
Biome.END_HIGHLANDS,
|
|
||||||
Biome.END_MIDLANDS,
|
|
||||||
Biome.THE_END,
|
|
||||||
Biome.SMALL_END_ISLANDS));
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.util;
|
|
||||||
|
|
||||||
import me.totalfreedom.totalfreedommod.api.Interpolator;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
|
|
||||||
public class Interpolation
|
|
||||||
{
|
|
||||||
public LinkedHashSet<Color> rainbow(int length)
|
|
||||||
{
|
|
||||||
LinkedHashSet<Color> base = new LinkedHashSet<>();
|
|
||||||
LinkedHashSet<Color> redToOrange = hsvGradient(length, Color.RED, Color.ORANGE, this::linear);
|
|
||||||
LinkedHashSet<Color> orangeToYellow = hsvGradient(length, Color.ORANGE, Color.YELLOW, this::linear);
|
|
||||||
LinkedHashSet<Color> yellowToGreen = hsvGradient(length, Color.YELLOW, Color.GREEN, this::linear);
|
|
||||||
LinkedHashSet<Color> greenToBlue = hsvGradient(length, Color.GREEN, Color.BLUE, this::linear);
|
|
||||||
LinkedHashSet<Color> blueToPurple = hsvGradient(length, Color.BLUE, Color.PURPLE, this::linear);
|
|
||||||
LinkedHashSet<Color> purpleToRed = hsvGradient(length, Color.PURPLE, Color.RED, this::linear);
|
|
||||||
base.addAll(redToOrange);
|
|
||||||
base.addAll(orangeToYellow);
|
|
||||||
base.addAll(yellowToGreen);
|
|
||||||
base.addAll(greenToBlue);
|
|
||||||
base.addAll(blueToPurple);
|
|
||||||
base.addAll(purpleToRed);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double[] linear(double from, double to, int max)
|
|
||||||
{
|
|
||||||
final double[] res = new double[max];
|
|
||||||
for (int i = 0; i < max; i++)
|
|
||||||
{
|
|
||||||
res[i] = from + i * ((to - from) / (max - 1));
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LinkedHashSet<Color> hsvGradient(int length, Color from, Color to, Interpolator interpolator)
|
|
||||||
{
|
|
||||||
// returns a float-array where hsv[0] = hue, hsv[1] = saturation, hsv[2] = value/brightness
|
|
||||||
final float[] hsvFrom = java.awt.Color.RGBtoHSB(from.getRed(), from.getGreen(), from.getBlue(), null);
|
|
||||||
final float[] hsvTo = java.awt.Color.RGBtoHSB(to.getRed(), to.getGreen(), to.getBlue(), null);
|
|
||||||
|
|
||||||
final double[] h = interpolator.interpolate(hsvFrom[0], hsvTo[0], length);
|
|
||||||
final double[] s = interpolator.interpolate(hsvFrom[1], hsvTo[1], length);
|
|
||||||
final double[] v = interpolator.interpolate(hsvFrom[2], hsvTo[2], length);
|
|
||||||
|
|
||||||
final LinkedHashSet<Color> gradient = new LinkedHashSet<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
final int rgb = java.awt.Color.HSBtoRGB((float) h[i], (float) s[i], (float) v[i]);
|
|
||||||
final Color color = Color.fromRGB(rgb);
|
|
||||||
gradient.add(color);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedHashSet<Color> rgbGradient(int length, Color from, Color to, Interpolator interpolator)
|
|
||||||
{
|
|
||||||
final double[] r = interpolator.interpolate(from.getRed(), to.getRed(), length);
|
|
||||||
final double[] g = interpolator.interpolate(from.getGreen(), to.getGreen(), length);
|
|
||||||
final double[] b = interpolator.interpolate(from.getBlue(), to.getBlue(), length);
|
|
||||||
|
|
||||||
final LinkedHashSet<Color> gradient = new LinkedHashSet<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
final Color color = Color.fromRGB((int) r[i], (int) g[i], (int) b[i]);
|
|
||||||
gradient.add(color);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedHashSet<TextColor> componentRGBGradient(int length, TextColor from, TextColor to, Interpolator interpolator)
|
|
||||||
{
|
|
||||||
final double[] r = interpolator.interpolate(from.red(), to.red(), length);
|
|
||||||
final double[] g = interpolator.interpolate(from.green(), to.green(), length);
|
|
||||||
final double[] b = interpolator.interpolate(from.blue(), to.blue(), length);
|
|
||||||
|
|
||||||
final LinkedHashSet<TextColor> gradient = new LinkedHashSet<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
final TextColor color = TextColor.color((int) r[i], (int) g[i], (int) b[i]);
|
|
||||||
gradient.add(color);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedHashSet<TextColor> rainbowComponent(int length)
|
|
||||||
{
|
|
||||||
LinkedHashSet<TextColor> base = new LinkedHashSet<>();
|
|
||||||
LinkedHashSet<TextColor> redToOrange = componentRGBGradient(length, NamedTextColor.RED, NamedTextColor.GOLD, this::linear);
|
|
||||||
LinkedHashSet<TextColor> orangeToYellow = componentRGBGradient(length, NamedTextColor.GOLD, NamedTextColor.YELLOW, this::linear);
|
|
||||||
LinkedHashSet<TextColor> yellowToGreen = componentRGBGradient(length, NamedTextColor.YELLOW, NamedTextColor.GREEN, this::linear);
|
|
||||||
LinkedHashSet<TextColor> greenToBlue = componentRGBGradient(length, NamedTextColor.GREEN, NamedTextColor.BLUE, this::linear);
|
|
||||||
LinkedHashSet<TextColor> blueToPurple = componentRGBGradient(length, NamedTextColor.BLUE, NamedTextColor.LIGHT_PURPLE, this::linear);
|
|
||||||
LinkedHashSet<TextColor> purpleToRed = componentRGBGradient(length, TextColor.color(75, 0, 130), TextColor.color(255, 0, 0), this::linear);
|
|
||||||
base.addAll(redToOrange);
|
|
||||||
base.addAll(orangeToYellow);
|
|
||||||
base.addAll(yellowToGreen);
|
|
||||||
base.addAll(greenToBlue);
|
|
||||||
base.addAll(blueToPurple);
|
|
||||||
base.addAll(purpleToRed);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.util;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.ParticleBuilder;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Particle;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class ParticleDisplay
|
|
||||||
{
|
|
||||||
private final Interpolation interpolation;
|
|
||||||
private Iterator<Color> colorIterator;
|
|
||||||
|
|
||||||
public ParticleDisplay()
|
|
||||||
{
|
|
||||||
this.interpolation = new Interpolation();
|
|
||||||
this.colorIterator = interpolation.rainbow(43).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void spawnNext(Player player)
|
|
||||||
{
|
|
||||||
Location location = getBehind(player);
|
|
||||||
Color color = getIterator().next();
|
|
||||||
Particle.DustOptions options = new Particle.DustOptions(color, 3);
|
|
||||||
ParticleBuilder builder = new ParticleBuilder(Particle.REDSTONE);
|
|
||||||
builder.data(options)
|
|
||||||
.receivers(30, 15, true)
|
|
||||||
.offset(0.5, 0.5, 0.5)
|
|
||||||
.location(location)
|
|
||||||
.spawn();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Location getBehind(Player player)
|
|
||||||
{
|
|
||||||
@NotNull Vector inverse = player.getLocation()
|
|
||||||
.clone()
|
|
||||||
.getDirection()
|
|
||||||
.normalize()
|
|
||||||
.multiply(-1);
|
|
||||||
|
|
||||||
return player.getLocation().add(inverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Iterator<Color> getIterator()
|
|
||||||
{
|
|
||||||
if (!this.colorIterator.hasNext())
|
|
||||||
{
|
|
||||||
this.colorIterator = interpolation.rainbow(43).iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.colorIterator;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package me.totalfreedom.totalfreedommod.util;
|
|
||||||
|
|
||||||
public class PermissibleCompletion
|
|
||||||
{
|
|
||||||
private final String permission;
|
|
||||||
private final String completion;
|
|
||||||
|
|
||||||
protected PermissibleCompletion(String permission, String completion)
|
|
||||||
{
|
|
||||||
this.completion = completion;
|
|
||||||
this.permission = permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PermissibleCompletion of(String permission, String completion)
|
|
||||||
{
|
|
||||||
return new PermissibleCompletion(permission, completion);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPermission()
|
|
||||||
{
|
|
||||||
return permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCompletion()
|
|
||||||
{
|
|
||||||
return completion;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>me.totalfreedom</groupId>
|
|
||||||
<artifactId>TotalFreedomMod</artifactId>
|
|
||||||
<version>2023.03</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>discord</artifactId>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.discord4j</groupId>
|
|
||||||
<artifactId>discord4j-core</artifactId>
|
|
||||||
<version>3.2.3</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>me.totalfreedom</groupId>
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
<version>2023.03</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.projectreactor</groupId>
|
|
||||||
<artifactId>reactor-core</artifactId>
|
|
||||||
<version>3.5.4</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
@ -1,91 +0,0 @@
|
|||||||
package me.totalfreedom.discord;
|
|
||||||
|
|
||||||
import discord4j.core.DiscordClientBuilder;
|
|
||||||
import discord4j.core.GatewayDiscordClient;
|
|
||||||
import discord4j.core.object.entity.Guild;
|
|
||||||
import me.totalfreedom.discord.util.SnowflakeEntry;
|
|
||||||
import me.totalfreedom.discord.util.TFM_Bridge;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Bot
|
|
||||||
{
|
|
||||||
private final GatewayDiscordClient client;
|
|
||||||
private final TFM_Bridge tfm;
|
|
||||||
private final HashMap<String, PlayerData> LINK_CODES = new HashMap<>();
|
|
||||||
|
|
||||||
public Bot()
|
|
||||||
{
|
|
||||||
//Creates the gateway client and connects to the gateway
|
|
||||||
this.client = DiscordClientBuilder.create(ConfigEntry.DISCORD_TOKEN.getString())
|
|
||||||
.build()
|
|
||||||
.login()
|
|
||||||
.block();
|
|
||||||
|
|
||||||
this.tfm = new TFM_Bridge(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize()
|
|
||||||
{
|
|
||||||
if (client == null) throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String formatBotTag()
|
|
||||||
{
|
|
||||||
return client.getSelf()
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow()
|
|
||||||
.getUsername() + "#" + client.getSelf()
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow()
|
|
||||||
.getDiscriminator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TFM_Bridge getTFM()
|
|
||||||
{
|
|
||||||
return tfm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mono<Guild> getGuildById()
|
|
||||||
{
|
|
||||||
return client.getGuildById(SnowflakeEntry.SERVER_ID.getSnowflake());
|
|
||||||
}
|
|
||||||
|
|
||||||
public GatewayDiscordClient getClient()
|
|
||||||
{
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, PlayerData> getLinkCodes()
|
|
||||||
{
|
|
||||||
return LINK_CODES;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldISendReport()
|
|
||||||
{
|
|
||||||
if (ConfigEntry.DISCORD_REPORT_CHANNEL_ID.getString().isEmpty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigEntry.DISCORD_SERVER_ID.getString().isEmpty())
|
|
||||||
{
|
|
||||||
FLog.severe("No Discord server ID was specified in the config, but there is a report channel ID.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Guild server = client.getGuildById(SnowflakeEntry.SERVER_ID.getSnowflake()).block();
|
|
||||||
if (server == null)
|
|
||||||
{
|
|
||||||
FLog.severe("The Discord server ID specified is invalid, or the bot is not on the server.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,124 +0,0 @@
|
|||||||
package me.totalfreedom.discord;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
|
||||||
import me.totalfreedom.discord.command.HelpCommand;
|
|
||||||
import me.totalfreedom.discord.command.ListCommand;
|
|
||||||
import me.totalfreedom.discord.command.TPSCommand;
|
|
||||||
import me.totalfreedom.discord.handling.CommandHandler;
|
|
||||||
import me.totalfreedom.discord.listener.*;
|
|
||||||
import me.totalfreedom.discord.react.ReactiveBukkitScheduler;
|
|
||||||
import me.totalfreedom.totalfreedommod.api.Context;
|
|
||||||
import me.totalfreedom.totalfreedommod.api.TFD4JCommons;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Paldiu
|
|
||||||
* @author videogamesm12
|
|
||||||
* @since 2023-03-16
|
|
||||||
*/
|
|
||||||
public class TFD4J extends JavaPlugin
|
|
||||||
{
|
|
||||||
private final Logger slf4j = this.getSLF4JLogger();
|
|
||||||
private Bot bot;
|
|
||||||
private MinecraftListener mc;
|
|
||||||
private AdminChatListener ac;
|
|
||||||
private PrivateMessageListener pm;
|
|
||||||
private ReactionListener rl;
|
|
||||||
private TFD4JCommons tfd4jcommons;
|
|
||||||
private BukkitNative bn;
|
|
||||||
private CommandHandler ch;
|
|
||||||
private ReactiveBukkitScheduler rbs;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable()
|
|
||||||
{
|
|
||||||
slf4j().info("Hello from TFD4J! Initializing our API implementation...");
|
|
||||||
this.tfd4jcommons = new TFD4JCommonsImpl(this);
|
|
||||||
|
|
||||||
slf4j().info("API successfully initialized! Initializing our bot...");
|
|
||||||
this.bot = new Bot();
|
|
||||||
bot.initialize();
|
|
||||||
|
|
||||||
slf4j().info("Bot successfully initialized! Abstracting the BukkitScheduler...");
|
|
||||||
this.rbs = new ReactiveBukkitScheduler(this);
|
|
||||||
|
|
||||||
String string = String.format("Scheduler successfully wrapped into %s! Registering the Bukkit Native listener...", ReactiveBukkitScheduler.class.getName()); // Fixes SonarLint's "Invoke methods only conditionally."
|
|
||||||
|
|
||||||
slf4j().info(string);
|
|
||||||
this.bn = new BukkitNative(this);
|
|
||||||
Bukkit.getPluginManager().registerEvents(this.bn, this);
|
|
||||||
|
|
||||||
slf4j().info("Bukkit Native listener successfully registered! Registering the Discord4J Listeners...");
|
|
||||||
this.mc = new MinecraftListener(this);
|
|
||||||
this.ac = new AdminChatListener(this);
|
|
||||||
this.pm = new PrivateMessageListener(this);
|
|
||||||
this.rl = new ReactionListener(this);
|
|
||||||
pm.privateMessageReceived();
|
|
||||||
rl.onReactionAdd();
|
|
||||||
mc.minecraftChatBound();
|
|
||||||
ac.adminChatBound();
|
|
||||||
|
|
||||||
slf4j().info("Discord4J listeners successfully registered! Registering the Command Handler...");
|
|
||||||
this.ch = new CommandHandler(bot.getClient().getRestClient());
|
|
||||||
|
|
||||||
slf4j().info("Command Handler successfully registered! Registering commands...");
|
|
||||||
this.ch.registerCommand(new HelpCommand());
|
|
||||||
this.ch.registerCommand(new ListCommand());
|
|
||||||
this.ch.registerCommand(new TPSCommand());
|
|
||||||
|
|
||||||
this.getBot().getClient().on(ChatInputInteractionEvent.class, ch::handle)
|
|
||||||
.subscribeOn(getReactiveBukkitScheduler())
|
|
||||||
.subscribe();
|
|
||||||
|
|
||||||
slf4j().info("Commands successfully registered! Providing context to TFM...");
|
|
||||||
Context<TFD4JCommons> context = new Context<>(tfd4jcommons);
|
|
||||||
bot.getTFM().getCommons().ag.setDiscordContext(context);
|
|
||||||
bot.getTFM().getCommons().registerDiscord();
|
|
||||||
|
|
||||||
slf4j().info("Context provided! TFD4J is now ready to go!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable()
|
|
||||||
{
|
|
||||||
slf4j().info("Disconnecting the Discord bot...");
|
|
||||||
bot.getClient()
|
|
||||||
.onDisconnect()
|
|
||||||
.doOnError(th -> slf4j().error("Error disconnecting the bot!", th))
|
|
||||||
.doOnSuccess(v -> slf4j().info("Bot disconnected!"))
|
|
||||||
.subscribe();
|
|
||||||
slf4j().info("Goodbye from TFD4J!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Logger slf4j()
|
|
||||||
{
|
|
||||||
return slf4j;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bot getBot()
|
|
||||||
{
|
|
||||||
return bot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TFD4JCommons getImpl()
|
|
||||||
{
|
|
||||||
return tfd4jcommons;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinecraftListener getMinecraftListener()
|
|
||||||
{
|
|
||||||
return mc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AdminChatListener getAdminChatListener()
|
|
||||||
{
|
|
||||||
return ac;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReactiveBukkitScheduler getReactiveBukkitScheduler()
|
|
||||||
{
|
|
||||||
return rbs;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,368 +0,0 @@
|
|||||||
package me.totalfreedom.discord;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import discord4j.common.util.Snowflake;
|
|
||||||
import discord4j.core.object.entity.Guild;
|
|
||||||
import discord4j.core.object.entity.Member;
|
|
||||||
import discord4j.core.object.entity.Message;
|
|
||||||
import discord4j.core.object.entity.Role;
|
|
||||||
import discord4j.core.object.entity.channel.TextChannel;
|
|
||||||
import discord4j.core.object.reaction.ReactionEmoji;
|
|
||||||
import discord4j.core.spec.EmbedCreateSpec;
|
|
||||||
import discord4j.core.spec.MessageCreateSpec;
|
|
||||||
import me.totalfreedom.discord.util.SnowflakeEntry;
|
|
||||||
import me.totalfreedom.discord.util.Utilities;
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.admin.Admin;
|
|
||||||
import me.totalfreedom.totalfreedommod.api.TFD4JCommons;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import org.apache.commons.lang.RandomStringUtils;
|
|
||||||
import org.apache.commons.lang.WordUtils;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class TFD4JCommonsImpl implements TFD4JCommons
|
|
||||||
{
|
|
||||||
private final TFD4J tfd4J;
|
|
||||||
private final ImmutableList<String> DISCORD_SUBDOMAINS;
|
|
||||||
private Flux<Message> sentMessages;
|
|
||||||
|
|
||||||
public TFD4JCommonsImpl(TFD4J tfd4J)
|
|
||||||
{
|
|
||||||
this.tfd4J = tfd4J;
|
|
||||||
this.sentMessages = Flux.fromIterable(new ArrayList<>());
|
|
||||||
this.DISCORD_SUBDOMAINS = ImmutableList.of("discordapp.com", "discord.com", "discord.gg");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void messageAdminChatChannel(String message)
|
|
||||||
{
|
|
||||||
String chat_channel_id = ConfigEntry.DISCORD_ADMINCHAT_CHANNEL_ID.getString();
|
|
||||||
|
|
||||||
String sanitizedMessage = sanitizeChatMessage(message);
|
|
||||||
|
|
||||||
if (sanitizedMessage.isBlank()) return;
|
|
||||||
|
|
||||||
if (!chat_channel_id.isEmpty())
|
|
||||||
{
|
|
||||||
MessageCreateSpec spec = MessageCreateSpec.builder()
|
|
||||||
.content(sanitizedMessage)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Mono<Message> sentMessage = tfd4J
|
|
||||||
.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getChannelById(SnowflakeEntry.ADMIN_CHAT_CHANNEL_ID.getSnowflake())
|
|
||||||
.ofType(TextChannel.class)
|
|
||||||
.flatMap(c -> c.createMessage(spec));
|
|
||||||
|
|
||||||
sentMessage.subscribe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Flux<Message> getMessagesSent()
|
|
||||||
{
|
|
||||||
return sentMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insert(Mono<Message> messageMono)
|
|
||||||
{
|
|
||||||
sentMessages.concatWith(messageMono);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearQueue()
|
|
||||||
{
|
|
||||||
sentMessages = Flux.fromIterable(new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void messageChatChannel(String message, boolean system)
|
|
||||||
{
|
|
||||||
String chat_channel_id = ConfigEntry.DISCORD_CHAT_CHANNEL_ID.getString();
|
|
||||||
|
|
||||||
String sanitizedMessage = (system) ? message : sanitizeChatMessage(message);
|
|
||||||
|
|
||||||
if (sanitizedMessage.isBlank()) return;
|
|
||||||
|
|
||||||
if (!chat_channel_id.isEmpty())
|
|
||||||
{
|
|
||||||
MessageCreateSpec spec = MessageCreateSpec.builder()
|
|
||||||
.content(sanitizedMessage)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Mono<Message> sentMessage = tfd4J
|
|
||||||
.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getChannelById(SnowflakeEntry.CHAT_CHANNEL_ID.getSnowflake())
|
|
||||||
.ofType(TextChannel.class)
|
|
||||||
.flatMap(c -> c.createMessage(spec));
|
|
||||||
|
|
||||||
sentMessage.subscribe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String sanitizeChatMessage(String message)
|
|
||||||
{
|
|
||||||
String newMessage = message;
|
|
||||||
|
|
||||||
if (message.contains("@"))
|
|
||||||
{
|
|
||||||
// \u200B is Zero Width Space, invisible on Discord
|
|
||||||
newMessage = message.replace("@", "@\u200B");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.toLowerCase().contains("discord.gg")) // discord.gg/invite works as an invite
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String subdomain : DISCORD_SUBDOMAINS)
|
|
||||||
{
|
|
||||||
if (message.toLowerCase().contains(subdomain + "/invite"))
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.contains("§"))
|
|
||||||
{
|
|
||||||
newMessage = message.replace("§", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Utilities.deformat(newMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean syncRoles(Admin admin, String discordID)
|
|
||||||
{
|
|
||||||
if (discordID == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Guild server = tfd4J.getBot().getGuildById()
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
Member member = server.getMemberById(Snowflake.of(discordID))
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
Role adminRole = server.getRoleById(SnowflakeEntry.ADMIN_ROLE_ID.getSnowflake())
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
Role senioradminRole = server.getRoleById(SnowflakeEntry.SENIOR_ADMIN_ROLE_ID.getSnowflake())
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
if (!admin.isActive())
|
|
||||||
{
|
|
||||||
syncRolesActivityCheck(member, adminRole, senioradminRole);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (admin.getRank().equals(TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin()))
|
|
||||||
{
|
|
||||||
syncRolesAdminAssignment(member, adminRole, senioradminRole);
|
|
||||||
return true;
|
|
||||||
} else if (admin.getRank().equals(TotalFreedomMod.getPlugin().getHierarchy().groups().getSeniorAdmin()))
|
|
||||||
{
|
|
||||||
syncRolesSeniorAssignment(member, adminRole, senioradminRole);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void syncRolesAdminAssignment(Member member, Role adminRole, Role senioradminRole)
|
|
||||||
{
|
|
||||||
member.getRoles().doFirst(() ->
|
|
||||||
{
|
|
||||||
if (!member.getRoles().collectList().blockOptional().orElseThrow().contains(adminRole))
|
|
||||||
{
|
|
||||||
member.addRole(adminRole.getId()).block();
|
|
||||||
}
|
|
||||||
}).doOnEach(r ->
|
|
||||||
{
|
|
||||||
Role role = r.get();
|
|
||||||
if (role == null) return;
|
|
||||||
|
|
||||||
if (role.equals(senioradminRole))
|
|
||||||
{
|
|
||||||
member.removeRole(role.getId()).block();
|
|
||||||
}
|
|
||||||
}).subscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void syncRolesActivityCheck(Member member, Role adminRole, Role senioradminRole)
|
|
||||||
{
|
|
||||||
member.getRoles().doOnEach(r ->
|
|
||||||
{
|
|
||||||
Role role = r.get();
|
|
||||||
if (role == null) return;
|
|
||||||
|
|
||||||
if (role.equals(adminRole) || role.equals(senioradminRole))
|
|
||||||
{
|
|
||||||
member.removeRole(role.getId()).block();
|
|
||||||
}
|
|
||||||
}).subscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void syncRolesSeniorAssignment(Member member, Role adminRole, Role senioradminRole)
|
|
||||||
{
|
|
||||||
member.getRoles().doFirst(() ->
|
|
||||||
{
|
|
||||||
if (!member.getRoles().collectList().blockOptional().orElseThrow().contains(senioradminRole))
|
|
||||||
{
|
|
||||||
member.addRole(senioradminRole.getId()).block();
|
|
||||||
}
|
|
||||||
}).doOnEach(r ->
|
|
||||||
{
|
|
||||||
Role role = r.get();
|
|
||||||
if (role == null) return;
|
|
||||||
|
|
||||||
if (role.equals(adminRole))
|
|
||||||
{
|
|
||||||
member.removeRole(role.getId()).block();
|
|
||||||
}
|
|
||||||
}).subscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCode(PlayerData playerData)
|
|
||||||
{
|
|
||||||
for (String code : this.getLinkCodes().keySet())
|
|
||||||
{
|
|
||||||
if (this.getLinkCodes().get(code).equals(playerData))
|
|
||||||
{
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateCode(int size)
|
|
||||||
{
|
|
||||||
return RandomStringUtils.randomNumeric(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, PlayerData> getLinkCodes()
|
|
||||||
{
|
|
||||||
return tfd4J.getBot().getLinkCodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String formatBotTag()
|
|
||||||
{
|
|
||||||
return tfd4J.getBot().formatBotTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendReportOffline(Player reporter, OfflinePlayer reported, String reason)
|
|
||||||
{
|
|
||||||
if (!tfd4J.getBot().shouldISendReport())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Guild server = tfd4J.getBot().getGuildById().block();
|
|
||||||
|
|
||||||
if (server == null) return false;
|
|
||||||
|
|
||||||
final TextChannel channel = server.getChannelById(SnowflakeEntry.REPORT_CHANNEL_ID.getSnowflake())
|
|
||||||
.ofType(TextChannel.class)
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
final EmbedCreateSpec.Builder builder = EmbedCreateSpec.builder()
|
|
||||||
.title("Report for " + reported.getName() + " (offline)")
|
|
||||||
.description(reason)
|
|
||||||
.footer("Reported by " + reporter.getName(), "https://minotar.net/helm/" + reporter.getName() + ".png")
|
|
||||||
.timestamp(Instant.from(ZonedDateTime.now()));
|
|
||||||
if (tfd4J.getBot().getTFM().getCommons().esb.isEnabled())
|
|
||||||
{
|
|
||||||
com.earth2me.essentials.User user = tfd4J.getBot().getTFM().getCommons().esb.getEssentialsUser(reported.getName());
|
|
||||||
String location = "World: " + Objects.requireNonNull(user.getLastLocation().getWorld()).getName() + ", X: " + user.getLastLocation().getBlockX() + ", Y: " + user.getLastLocation().getBlockY() + ", Z: " + user.getLastLocation().getBlockZ();
|
|
||||||
builder.addField("Location", location, true);
|
|
||||||
builder.addField("God Mode", WordUtils.capitalizeFully(String.valueOf(user.isGodModeEnabled())), true);
|
|
||||||
if (user.getNickname() != null)
|
|
||||||
{
|
|
||||||
builder.addField("Nickname", user.getNickname(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EmbedCreateSpec embed = builder.build();
|
|
||||||
Message message = channel.createMessage(embed).block();
|
|
||||||
|
|
||||||
if (message != null && !ConfigEntry.DISCORD_REPORT_ARCHIVE_CHANNEL_ID.getString().isEmpty())
|
|
||||||
{
|
|
||||||
message.addReaction(ReactionEmoji.unicode("\uD83D\uDCCB")).subscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean sendReport(Player reporter, Player reported, String reason)
|
|
||||||
{
|
|
||||||
if (!tfd4J.getBot().shouldISendReport())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Guild server = tfd4J.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getGuildById(SnowflakeEntry.SERVER_ID.getSnowflake())
|
|
||||||
.block();
|
|
||||||
|
|
||||||
if (server == null)
|
|
||||||
{
|
|
||||||
FLog.severe("The guild ID specified in the config is invalid.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final TextChannel channel = server.getChannelById(SnowflakeEntry.REPORT_CHANNEL_ID.getSnowflake())
|
|
||||||
.ofType(TextChannel.class)
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
String location = "World: " + Objects.requireNonNull(reported.getLocation().getWorld()).getName() + ", X: " + reported.getLocation().getBlockX() + ", Y: " + reported.getLocation().getBlockY() + ", Z: " + reported.getLocation().getBlockZ();
|
|
||||||
|
|
||||||
final EmbedCreateSpec spec = EmbedCreateSpec.builder()
|
|
||||||
.title("Report for " + reported.getName())
|
|
||||||
.description(reason)
|
|
||||||
.footer("Reported by " + reporter.getName(), "https://minotar.net/helm/" + reporter.getName() + ".png")
|
|
||||||
.timestamp(Instant.from(ZonedDateTime.now()))
|
|
||||||
.addField("Location", location, true)
|
|
||||||
.addField("Game Mode", WordUtils.capitalizeFully(reported.getGameMode().name()), true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Message message = channel.createMessage(spec).block();
|
|
||||||
|
|
||||||
if (!ConfigEntry.DISCORD_REPORT_ARCHIVE_CHANNEL_ID.getString().isEmpty() && message != null)
|
|
||||||
{
|
|
||||||
ReactionEmoji emoji = ReactionEmoji.unicode("\uD83D\uDCCB");
|
|
||||||
message.addReaction(emoji);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled()
|
|
||||||
{
|
|
||||||
return tfd4J.isEnabled();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package me.totalfreedom.discord.command;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
|
||||||
import discord4j.core.spec.EmbedCreateSpec;
|
|
||||||
import discord4j.rest.util.Color;
|
|
||||||
import me.totalfreedom.discord.handling.SlashCommand;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
public class HelpCommand implements SlashCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return "help";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> handle(ChatInputInteractionEvent event)
|
|
||||||
{
|
|
||||||
EmbedCreateSpec spec = EmbedCreateSpec.builder()
|
|
||||||
.color(Color.GREEN)
|
|
||||||
.title("Help Command")
|
|
||||||
.addField("Commands", "This is a list of all commands", false)
|
|
||||||
.addField("\u200B", "\u200B", false)
|
|
||||||
.addField("help", "Displays the help command. (This command.)", true)
|
|
||||||
.addField("list", "Displays a list of all online players.", true)
|
|
||||||
.addField("tps", "Displays the server's TPS.", true)
|
|
||||||
.timestamp(Instant.now())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return event.reply()
|
|
||||||
.withEmbeds(spec);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package me.totalfreedom.discord.command;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
|
||||||
import discord4j.core.spec.EmbedCreateSpec;
|
|
||||||
import discord4j.rest.util.Color;
|
|
||||||
import me.totalfreedom.discord.handling.SlashCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ListCommand implements SlashCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return "list";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> handle(ChatInputInteractionEvent event)
|
|
||||||
{
|
|
||||||
List<String> playerNames = Bukkit.getOnlinePlayers()
|
|
||||||
.stream()
|
|
||||||
.map(HumanEntity::getName)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
Iterator<String> iterator = playerNames.iterator();
|
|
||||||
while (iterator.hasNext())
|
|
||||||
{
|
|
||||||
sb.append(iterator.next());
|
|
||||||
if (iterator.hasNext())
|
|
||||||
{
|
|
||||||
sb.append(", \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String empty = "\u200B";
|
|
||||||
|
|
||||||
EmbedCreateSpec spec = EmbedCreateSpec.builder()
|
|
||||||
.title("Player List - " + ConfigEntry.SERVER_NAME.getString())
|
|
||||||
.color(Color.BISMARK)
|
|
||||||
.addField("Online Players", String.join(", ", playerNames), false)
|
|
||||||
.addField(empty, "Currently Online: " + playerNames.size(), false)
|
|
||||||
.addField(empty, empty, false)
|
|
||||||
.addField("Players: ", sb.toString(), true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return event.reply()
|
|
||||||
.withEmbeds(spec)
|
|
||||||
.withEphemeral(true)
|
|
||||||
.withContent(sb.toString());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package me.totalfreedom.discord.command;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
|
||||||
import discord4j.core.spec.EmbedCreateSpec;
|
|
||||||
import discord4j.rest.util.Color;
|
|
||||||
import me.totalfreedom.discord.handling.SlashCommand;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
public class TPSCommand implements SlashCommand
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return "tps";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Void> handle(@NotNull ChatInputInteractionEvent event)
|
|
||||||
{
|
|
||||||
String tps = String.valueOf(FUtil.getMeanAverageDouble(Bukkit.getServer().getTPS()));
|
|
||||||
|
|
||||||
EmbedCreateSpec spec = EmbedCreateSpec.builder()
|
|
||||||
.title("Current Server Tick Information")
|
|
||||||
.addField("TPS", tps, false)
|
|
||||||
.addField("Uptime", FUtil.getUptime(), false)
|
|
||||||
.addField("Maximum Memory", Math.ceil(FUtil.getMaxMem()) + " MB", false)
|
|
||||||
.addField("Allocated Memory", Math.ceil(FUtil.getTotalMem()) + " MB", false)
|
|
||||||
.addField("Free Memory", Math.ceil(FUtil.getFreeMem()) + " MB", false)
|
|
||||||
.color(Color.BISMARK)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return event.reply()
|
|
||||||
.withEmbeds(spec)
|
|
||||||
.withEphemeral(true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
package me.totalfreedom.discord.handling;
|
|
||||||
|
|
||||||
import discord4j.common.JacksonResources;
|
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
|
||||||
import discord4j.discordjson.json.ApplicationCommandRequest;
|
|
||||||
import discord4j.rest.RestClient;
|
|
||||||
import discord4j.rest.service.ApplicationService;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import reactor.core.publisher.Flux;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class CommandHandler
|
|
||||||
{
|
|
||||||
private final List<SlashCommand> commands = new ArrayList<>();
|
|
||||||
private final RestClient restClient;
|
|
||||||
|
|
||||||
public CommandHandler(RestClient restClient)
|
|
||||||
{
|
|
||||||
this.restClient = restClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerCommands(List<String> fileNames) throws IOException
|
|
||||||
{
|
|
||||||
//Create an ObjectMapper that supports Discord4J classes
|
|
||||||
final JacksonResources d4jMapper = JacksonResources.create();
|
|
||||||
|
|
||||||
// Convenience variables for the sake of easier to read code below
|
|
||||||
final ApplicationService applicationService = restClient.getApplicationService();
|
|
||||||
final long applicationId = Objects.requireNonNull(restClient.getApplicationId().block());
|
|
||||||
|
|
||||||
//Get our commands json from resources as command data
|
|
||||||
List<ApplicationCommandRequest> commands = new ArrayList<>();
|
|
||||||
for (String json : getCommandsJson(fileNames))
|
|
||||||
{
|
|
||||||
ApplicationCommandRequest request = d4jMapper.getObjectMapper()
|
|
||||||
.readValue(json, ApplicationCommandRequest.class);
|
|
||||||
|
|
||||||
commands.add(request); //Add to our array list
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bulk overwrite commands. This is now idempotent, so it is safe to use this even when only 1 command
|
|
||||||
is changed/added/removed
|
|
||||||
*/
|
|
||||||
applicationService.bulkOverwriteGlobalApplicationCommand(applicationId, commands)
|
|
||||||
.doOnNext(cmd -> Bukkit.getLogger().info("Successfully registered Global Command "
|
|
||||||
+ cmd.name()))
|
|
||||||
.doOnError(e -> Bukkit.getLogger().severe("Failed to register global commands.\n"
|
|
||||||
+ e.getMessage()))
|
|
||||||
.subscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NotNull List<String> getCommandsJson(List<String> fileNames) throws IOException
|
|
||||||
{
|
|
||||||
// Confirm that the commands folder exists
|
|
||||||
String commandsFolderName = "commands/";
|
|
||||||
URL url = this.getClass().getClassLoader().getResource(commandsFolderName);
|
|
||||||
Objects.requireNonNull(url, commandsFolderName + " could not be found");
|
|
||||||
|
|
||||||
//Get all the files inside this folder and return the contents of the files as a list of strings
|
|
||||||
List<String> list = new ArrayList<>();
|
|
||||||
for (String file : fileNames)
|
|
||||||
{
|
|
||||||
String resourceFileAsString = getResourceFileAsString(commandsFolderName + file);
|
|
||||||
list.add(Objects.requireNonNull(resourceFileAsString, "Command file not found: " + file));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Nullable String getResourceFileAsString(String fileName) throws IOException
|
|
||||||
{
|
|
||||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
|
||||||
try (InputStream resourceAsStream = classLoader.getResourceAsStream(fileName))
|
|
||||||
{
|
|
||||||
if (resourceAsStream == null) return null;
|
|
||||||
try (InputStreamReader inputStreamReader = new InputStreamReader(resourceAsStream);
|
|
||||||
BufferedReader reader = new BufferedReader(inputStreamReader))
|
|
||||||
{
|
|
||||||
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerCommand(SlashCommand command)
|
|
||||||
{
|
|
||||||
commands.add(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mono<Void> handle(ChatInputInteractionEvent event)
|
|
||||||
{
|
|
||||||
// Convert our array list to a flux that we can iterate through
|
|
||||||
return Flux.fromIterable(commands)
|
|
||||||
//Filter out all commands that don't match the name of the command this event is for
|
|
||||||
.filter(command -> command.getName().equals(event.getCommandName()))
|
|
||||||
// Get the first (and only) item in the flux that matches our filter
|
|
||||||
.next()
|
|
||||||
//have our command class handle all the logic related to its specific command.
|
|
||||||
.flatMap(command -> command.handle(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package me.totalfreedom.discord.handling;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
public interface SlashCommand
|
|
||||||
{
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
Mono<Void> handle(ChatInputInteractionEvent event);
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
package me.totalfreedom.discord.listener;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
|
||||||
import discord4j.core.object.entity.Attachment;
|
|
||||||
import discord4j.core.object.entity.Guild;
|
|
||||||
import discord4j.core.object.entity.Member;
|
|
||||||
import discord4j.core.object.entity.Message;
|
|
||||||
import me.totalfreedom.discord.Bot;
|
|
||||||
import me.totalfreedom.discord.TFD4J;
|
|
||||||
import me.totalfreedom.discord.util.SnowflakeEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.Displayable;
|
|
||||||
import me.totalfreedom.totalfreedommod.rank.Title;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.key.Key;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
|
||||||
import net.kyori.adventure.text.event.HoverEvent;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
|
|
||||||
public class AdminChatListener
|
|
||||||
{
|
|
||||||
private static final Key identifier = Key.key("tfd4j", "discord_admin_chat");
|
|
||||||
//--
|
|
||||||
private final Bot bot;
|
|
||||||
private final TFD4J tfd4j;
|
|
||||||
|
|
||||||
public AdminChatListener(TFD4J tfd4j)
|
|
||||||
{
|
|
||||||
this.tfd4j = tfd4j;
|
|
||||||
this.bot = tfd4j.getBot();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Key getIdentifier()
|
|
||||||
{
|
|
||||||
return identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void adminChatBound()
|
|
||||||
{
|
|
||||||
tfd4j.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getEventDispatcher()
|
|
||||||
.on(MessageCreateEvent.class)
|
|
||||||
.filter(m -> m.getMessage()
|
|
||||||
.getChannelId()
|
|
||||||
.equals(SnowflakeEntry.ADMIN_CHAT_CHANNEL_ID.getSnowflake()))
|
|
||||||
.filter(m -> !m.getMessage()
|
|
||||||
.getAuthor()
|
|
||||||
.orElseThrow()
|
|
||||||
.getId()
|
|
||||||
.equals(tfd4j.getBot().getClient().getSelfId()))
|
|
||||||
.doOnError(FLog::severe)
|
|
||||||
.subscribe(this::createMessageSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createMessageSpec(MessageCreateEvent m)
|
|
||||||
{
|
|
||||||
Member member = m.getMember().orElseThrow(IllegalAccessError::new);
|
|
||||||
Component name = Component.text(member.getDisplayName());
|
|
||||||
Message msg = m.getMessage();
|
|
||||||
|
|
||||||
TextComponent attachments = Component.empty();
|
|
||||||
for (Attachment attachment : msg.getAttachments())
|
|
||||||
{
|
|
||||||
attachments = attachments.append(
|
|
||||||
Component.text("[Media] ", NamedTextColor.YELLOW)
|
|
||||||
.clickEvent(ClickEvent.openUrl(attachment.getUrl()))
|
|
||||||
.hoverEvent(HoverEvent.showText(Component.text(attachment.getUrl()))));
|
|
||||||
}
|
|
||||||
|
|
||||||
TextComponent message = Component.text(msg.getContent()).append(msg.getAttachments().isEmpty() ?
|
|
||||||
Component.empty() : Component.space().append(attachments));
|
|
||||||
|
|
||||||
TotalFreedomMod.getPlugin().cm.adminChat(identifier, FUtil.miniMessage("<dark_gray>[<dark_aqua>Discord</dark_aqua>] </dark_gray>"), name, getDisplay(member), message, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Displayable getDisplay(Member member)
|
|
||||||
{
|
|
||||||
Guild server = tfd4j.getBot().getGuildById().block();
|
|
||||||
// Server Owner
|
|
||||||
if (server == null) throw new IllegalStateException();
|
|
||||||
|
|
||||||
return member.getRoles()
|
|
||||||
.filter(role -> SnowflakeEntry.acceptableRoleIDs().contains(role.getId()))
|
|
||||||
.map(role ->
|
|
||||||
{
|
|
||||||
if (role.getId().equals(SnowflakeEntry.OWNER_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return Title.OWNER;
|
|
||||||
} else if (role.getId().equals(SnowflakeEntry.DEVELOPER_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return Title.DEVELOPER;
|
|
||||||
} else if (role.getId().equals(SnowflakeEntry.EXECUTIVE_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return Title.EXECUTIVE;
|
|
||||||
} else if (role.getId().equals(SnowflakeEntry.ASSISTANT_EXECUTIVE_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return Title.ASST_EXEC;
|
|
||||||
} else if (role.getId().equals(SnowflakeEntry.SENIOR_ADMIN_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return TotalFreedomMod.getPlugin().getHierarchy().groups().getSeniorAdmin();
|
|
||||||
} else if (role.getId().equals(SnowflakeEntry.ADMIN_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin();
|
|
||||||
} else if (role.getId().equals(SnowflakeEntry.MASTERBUILDER_ROLE_ID.getSnowflake()))
|
|
||||||
{
|
|
||||||
return TotalFreedomMod.getPlugin().getHierarchy().groups().getMasterBuilder();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return TotalFreedomMod.getPlugin().getHierarchy().groups().getNonOp(); // This should never be reached.
|
|
||||||
}
|
|
||||||
}).blockFirst();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
package me.totalfreedom.discord.listener;
|
|
||||||
|
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
|
||||||
import me.totalfreedom.discord.Bot;
|
|
||||||
import me.totalfreedom.discord.TFD4J;
|
|
||||||
import me.totalfreedom.discord.util.Utilities;
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.api.event.AdminChatEvent;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
|
||||||
import org.bukkit.GameRule;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
|
|
||||||
public class BukkitNative implements Listener
|
|
||||||
{
|
|
||||||
|
|
||||||
//--
|
|
||||||
private final TotalFreedomMod commons;
|
|
||||||
private final Bot bot;
|
|
||||||
private final TFD4J tfd4j;
|
|
||||||
|
|
||||||
public BukkitNative(TFD4J tfd4j)
|
|
||||||
{
|
|
||||||
this.tfd4j = tfd4j;
|
|
||||||
this.bot = tfd4j.getBot();
|
|
||||||
this.commons = bot.getTFM().getCommons();
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onPlayerJoin(PlayerJoinEvent event)
|
|
||||||
{
|
|
||||||
if (!commons.al.isVanished(event.getPlayer().getUniqueId()))
|
|
||||||
{
|
|
||||||
tfd4j.getImpl().messageChatChannel("**"
|
|
||||||
+ Utilities.deformat(event.getPlayer().getName())
|
|
||||||
+ " joined the server" + "**", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onPlayerLeave(PlayerQuitEvent event)
|
|
||||||
{
|
|
||||||
if (!commons.al.isVanished(event.getPlayer().getUniqueId()))
|
|
||||||
{
|
|
||||||
tfd4j.getImpl().messageChatChannel("**"
|
|
||||||
+ Utilities.deformat(event.getPlayer().getName())
|
|
||||||
+ " left the server" + "**", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onPlayerDeath(PlayerDeathEvent event)
|
|
||||||
{
|
|
||||||
//Avoiding NPE Unboxing Warnings
|
|
||||||
Boolean b = event.getEntity().getWorld().getGameRuleValue(GameRule.SHOW_DEATH_MESSAGES);
|
|
||||||
if (b == null || !b)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component deathMessage = event.deathMessage();
|
|
||||||
|
|
||||||
if (deathMessage != null)
|
|
||||||
{
|
|
||||||
tfd4j.getImpl().messageChatChannel("**"
|
|
||||||
+ Utilities.deformat(PlainTextComponentSerializer.plainText().serialize(deathMessage))
|
|
||||||
+ "**", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
|
||||||
public void onAsyncPlayerChat(AsyncChatEvent event)
|
|
||||||
{
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
String message = FUtil.steamroll(event.message());
|
|
||||||
|
|
||||||
if (!ConfigEntry.ADMIN_ONLY_MODE.getBoolean() && !tfd4j.getServer().hasWhitelist()
|
|
||||||
&& !commons.pl.getPlayer(player).isMuted() && !commons.pl.getPlayer(player).inAdminChat() && bot != null)
|
|
||||||
{
|
|
||||||
tfd4j.getImpl().messageChatChannel(player.getName()
|
|
||||||
+ " \u00BB "
|
|
||||||
+ message, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onAdminChat(AdminChatEvent event)
|
|
||||||
{
|
|
||||||
if (!event.getIdentifier().equals(AdminChatListener.getIdentifier()))
|
|
||||||
{
|
|
||||||
tfd4j.getImpl().messageAdminChatChannel(FUtil.steamroll(event.getName()) + " » " + FUtil.steamroll(event.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
package me.totalfreedom.discord.listener;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
|
||||||
import discord4j.core.object.entity.Attachment;
|
|
||||||
import discord4j.core.object.entity.Member;
|
|
||||||
import discord4j.core.object.entity.Message;
|
|
||||||
import me.totalfreedom.discord.Bot;
|
|
||||||
import me.totalfreedom.discord.TFD4J;
|
|
||||||
import me.totalfreedom.discord.util.SnowflakeEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
|
||||||
import net.kyori.adventure.text.event.HoverEvent;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
public class MinecraftListener
|
|
||||||
{
|
|
||||||
private final TotalFreedomMod commons;
|
|
||||||
private final Bot bot;
|
|
||||||
private final TFD4J tfd4j;
|
|
||||||
|
|
||||||
public MinecraftListener(TFD4J tfd4j)
|
|
||||||
{
|
|
||||||
this.tfd4j = tfd4j;
|
|
||||||
this.bot = tfd4j.getBot();
|
|
||||||
this.commons = bot.getTFM().getCommons();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void minecraftChatBound()
|
|
||||||
{
|
|
||||||
tfd4j.getBot().getClient()
|
|
||||||
.getEventDispatcher()
|
|
||||||
.on(MessageCreateEvent.class)
|
|
||||||
.filter(m -> m.getMessage()
|
|
||||||
.getChannelId()
|
|
||||||
.equals(SnowflakeEntry.CHAT_CHANNEL_ID.getSnowflake()))
|
|
||||||
.filter(m -> m.getMember().orElse(null) != null)
|
|
||||||
.filter(m -> !m.getMessage()
|
|
||||||
.getAuthor()
|
|
||||||
.orElseThrow(IllegalAccessError::new)
|
|
||||||
.getId()
|
|
||||||
.equals(tfd4j.getBot().getClient().getSelfId()))
|
|
||||||
.doOnError(FLog::severe)
|
|
||||||
.subscribe(this::doMessageBodyDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doMessageBodyDetails(MessageCreateEvent m)
|
|
||||||
{
|
|
||||||
Member member = m.getMember().orElseThrow();
|
|
||||||
Message msg = m.getMessage();
|
|
||||||
String tag = bot.getTFM().getDisplay(member);
|
|
||||||
|
|
||||||
TextComponent.Builder builder = Component.text();
|
|
||||||
TextComponent prefix = Component.text("[", NamedTextColor.DARK_GRAY)
|
|
||||||
.append(Component.text("Discord", NamedTextColor.DARK_AQUA)
|
|
||||||
.hoverEvent(HoverEvent.showText(Component.text("Click to join our Discord server!")))
|
|
||||||
.clickEvent(ClickEvent.openUrl(ConfigEntry.DISCORD_INVITE_LINK.getString())))
|
|
||||||
.append(Component.text("] ", NamedTextColor.DARK_GRAY));
|
|
||||||
TextComponent user = Component.empty();
|
|
||||||
|
|
||||||
// Tag (if they have one)
|
|
||||||
if (tag != null && !tag.isEmpty())
|
|
||||||
{
|
|
||||||
user = LegacyComponentSerializer.legacyAmpersand().deserialize(tag).append(Component.space());
|
|
||||||
}
|
|
||||||
|
|
||||||
user = user.append(Component.text(FUtil.stripColors(member.getDisplayName()).trim(), NamedTextColor.RED));
|
|
||||||
|
|
||||||
TextComponent message = Component.text(": ", NamedTextColor.DARK_GRAY)
|
|
||||||
.append(Component.text(FUtil.stripColors(msg.getContent()), NamedTextColor.WHITE));
|
|
||||||
|
|
||||||
// Attachments
|
|
||||||
if (!msg.getAttachments().isEmpty())
|
|
||||||
{
|
|
||||||
if (!msg.getContent().isEmpty())
|
|
||||||
{
|
|
||||||
message = message.append(Component.space());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Attachment attachment : msg.getAttachments())
|
|
||||||
{
|
|
||||||
message = message.append(Component.text("[Media] ", NamedTextColor.YELLOW)
|
|
||||||
.hoverEvent(HoverEvent.showText(Component.text(attachment.getUrl())))
|
|
||||||
.clickEvent(ClickEvent.openUrl(attachment.getUrl())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.broadcast(builder.append(prefix, user, message).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
package me.totalfreedom.discord.listener;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
|
||||||
import me.totalfreedom.discord.TFD4J;
|
|
||||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
||||||
import me.totalfreedom.totalfreedommod.admin.Admin;
|
|
||||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
||||||
|
|
||||||
public class PrivateMessageListener
|
|
||||||
{
|
|
||||||
private final TFD4J tfd4j;
|
|
||||||
|
|
||||||
public PrivateMessageListener(TFD4J tfd4j)
|
|
||||||
{
|
|
||||||
this.tfd4j = tfd4j;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void privateMessageReceived()
|
|
||||||
{
|
|
||||||
tfd4j.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getEventDispatcher()
|
|
||||||
.on(MessageCreateEvent.class)
|
|
||||||
.filter(event -> event.getMessage().getAuthor().orElse(null) != null)
|
|
||||||
.filter(event -> !event.getMessage().getAuthor().orElseThrow().getId().equals(tfd4j.getBot().getClient().getSelfId()))
|
|
||||||
.filter(event -> event.getMessage().getContent().strip().matches("\\d{5}"))
|
|
||||||
.subscribe(event ->
|
|
||||||
{
|
|
||||||
String code = event.getMessage().getContent().strip();
|
|
||||||
String name;
|
|
||||||
if (tfd4j.getBot().getLinkCodes().get(code) != null)
|
|
||||||
{
|
|
||||||
PlayerData player = tfd4j.getBot().getLinkCodes().get(code);
|
|
||||||
name = player.getName();
|
|
||||||
player.setDiscordID(event.getMessage().getAuthor().orElseThrow().getId().asString());
|
|
||||||
|
|
||||||
Admin admin = TotalFreedomMod.getPlugin().al.getEntryByUuid(player.getUuid());
|
|
||||||
if (admin != null)
|
|
||||||
{
|
|
||||||
tfd4j.getImpl().syncRoles(admin, player.getDiscordID());
|
|
||||||
}
|
|
||||||
|
|
||||||
TotalFreedomMod.getPlugin().pl.save(player);
|
|
||||||
tfd4j.getBot().getLinkCodes().remove(code);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.getMessage()
|
|
||||||
.getChannel()
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow(UnsupportedOperationException::new)
|
|
||||||
.createMessage("Link successful. Now this Discord account is linked with your Minecraft account **" + name + "**.").block();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
package me.totalfreedom.discord.listener;
|
|
||||||
|
|
||||||
import discord4j.core.event.domain.message.ReactionAddEvent;
|
|
||||||
import discord4j.core.object.Embed;
|
|
||||||
import discord4j.core.object.entity.Member;
|
|
||||||
import discord4j.core.object.entity.Message;
|
|
||||||
import discord4j.core.object.entity.channel.TextChannel;
|
|
||||||
import discord4j.discordjson.json.MessageCreateRequest;
|
|
||||||
import me.totalfreedom.discord.TFD4J;
|
|
||||||
import me.totalfreedom.discord.util.SnowflakeEntry;
|
|
||||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
||||||
|
|
||||||
public class ReactionListener
|
|
||||||
{
|
|
||||||
private final TFD4J tfd4j;
|
|
||||||
|
|
||||||
public ReactionListener(TFD4J tfd4J)
|
|
||||||
{
|
|
||||||
this.tfd4j = tfd4J;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onReactionAdd()
|
|
||||||
{
|
|
||||||
tfd4j.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getEventDispatcher()
|
|
||||||
.on(ReactionAddEvent.class)
|
|
||||||
.filter(r -> r.getGuild().block() != null)
|
|
||||||
.filter(r -> r.getMember().orElse(null) != null)
|
|
||||||
.filter(r -> !r.getMember()
|
|
||||||
.orElseThrow()
|
|
||||||
.getId()
|
|
||||||
.equals(tfd4j.getBot().getClient().getSelfId()))
|
|
||||||
.filter(r -> !r.getChannelId()
|
|
||||||
.equals(SnowflakeEntry.REPORT_CHANNEL_ID.getSnowflake()))
|
|
||||||
.filter(r -> r.getEmoji()
|
|
||||||
.asUnicodeEmoji()
|
|
||||||
.orElseThrow(UnsupportedOperationException::new)
|
|
||||||
.getRaw()
|
|
||||||
.equals("\uD83D\uDCCB"))
|
|
||||||
.doOnError(FLog::severe)
|
|
||||||
.subscribe(this::reactionWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reactionWork(ReactionAddEvent event)
|
|
||||||
{
|
|
||||||
final TextChannel archiveChannel = tfd4j.getBot()
|
|
||||||
.getClient()
|
|
||||||
.getChannelById(SnowflakeEntry.ARCHIVE_REPORT_CHANNEL_ID.getSnowflake())
|
|
||||||
.ofType(TextChannel.class)
|
|
||||||
.blockOptional()
|
|
||||||
.orElseThrow();
|
|
||||||
|
|
||||||
final Message message = event.getMessage().blockOptional().orElseThrow();
|
|
||||||
final Member completer = event.getMember().orElseThrow();
|
|
||||||
|
|
||||||
if (!message.getAuthor().orElseThrow().getId().equals(tfd4j.getBot().getClient().getSelfId()))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't need other embeds... yet?
|
|
||||||
final Embed embed = message.getEmbeds().get(0);
|
|
||||||
|
|
||||||
final MessageCreateRequest request = MessageCreateRequest.builder()
|
|
||||||
.content("Report completed by " + completer.getUsername()
|
|
||||||
+ " (" + completer.getDiscriminator()
|
|
||||||
+ ")")
|
|
||||||
.addEmbed(embed.getData())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
archiveChannel.getRestChannel().createMessage(request);
|
|
||||||
|
|
||||||
message.delete().block();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package me.totalfreedom.discord.react;
|
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import reactor.core.Disposable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is a wrapper for a BukkitTask that implements the Disposable interface.
|
|
||||||
* This is so we can schedule non-blocking tasks asynchronously on the Bukkit Scheduler.
|
|
||||||
* <p>
|
|
||||||
* From <a href="https://github.com/SimplexDevelopment/SimplexSS">SimplexSS</a>
|
|
||||||
*
|
|
||||||
* @param task The task to wrap.
|
|
||||||
*/
|
|
||||||
public record DisposableBukkitTask(BukkitTask task) implements Disposable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Disposes of the task upstream on the Bukkit scheduler.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void dispose()
|
|
||||||
{
|
|
||||||
task.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the task is cancelled.
|
|
||||||
*
|
|
||||||
* @return true if the task is cancelled, false otherwise.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isDisposed()
|
|
||||||
{
|
|
||||||
return task.isCancelled();
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user