Compare commits

..

1 Commits

Author SHA1 Message Date
df7e30ba4e Merge pull request #283 from TFPatches/development
October 2020 Update
2020-10-02 02:35:24 -07:00
480 changed files with 23077 additions and 19378 deletions

View File

@ -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"

View File

@ -1,46 +0,0 @@
# This workflow checks out code, performs a Codacy security scan
# and integrates the results with the
# GitHub Advanced Security code scanning feature. For more information on
# the Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: Codacy Security Scan
on:
push:
branches: [ development ]
pull_request:
branches: [ development ]
jobs:
codacy-security-scan:
name: Codacy Security Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v3
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@v4.2.0
with:
# 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
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
verbose: true
output: results.sarif
format: sarif
# Adjust severity of non-security issues
gh-code-scanning-compat: true
# Force 0 exit code to allow SARIF file generation
# This will handover control about PR rejection to the GitHub side
max-allowed-issues: 2147483647
# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: results.sarif

View File

@ -1,74 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ development ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ development ]
schedule:
- cron: '20 18 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Java JDK
uses: actions/setup-java@v3.9.0
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
java-version: 17
distribution: 'adopt'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# 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)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@ -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
View File

@ -0,0 +1,17 @@
name: Java CI
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: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml

4
.gitignore vendored
View File

@ -25,11 +25,10 @@ manifest.mf
/.idea/workspace.xml /.idea/workspace.xml
/.idea/uiDesigner.xml /.idea/uiDesigner.xml
/.idea/libraries /.idea/libraries
/.idea/
*.iml *.iml
# Maven excludes # Maven excludes
target/ /target
# OS generated files # OS generated files
.DS_Store .DS_Store
@ -38,4 +37,3 @@ target/
.Trashes .Trashes
ehthumbs.db ehthumbs.db
Thumbs.db Thumbs.db
.idea/inspectionProfiles/Project_Default.xml

46
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,46 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="20" />
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false" />
<package name="" withSubpackages="true" static="true" />
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
</JetCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="BRACE_STYLE" value="2" />
<option name="CLASS_BRACE_STYLE" value="2" />
<option name="METHOD_BRACE_STYLE" value="2" />
<option name="LAMBDA_BRACE_STYLE" value="2" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

17
.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="TotalFreedomMod" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="TotalFreedomMod" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>

8
.idea/encodings.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

16
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

124
.idea/uiDesigner.xml generated Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

1
.travis.yml Normal file
View File

@ -0,0 +1 @@
language: java

View File

@ -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).

12
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,12 @@
pipeline {
agent any
stages {
stage('Build') {
steps {
mvn -B package --file pom.xml
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
}
}
}
}

View File

@ -1,5 +1,4 @@
# TotalFreedom General License # TotalFreedom General License #
_Version 2.0, 27th February 2015_ _Version 2.0, 27th February 2015_
Copyright (c) 2011 Steven Lawson Copyright (c) 2011 Steven Lawson
@ -8,86 +7,48 @@ Copyright (c) 2012 Jerom van der Sar
All rights reserved. All rights reserved.
##### 1. Definitions ##### 1. Definitions #####
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by this document. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by this document.
"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, royalty-free, irrevocable copyright license to prepare Derivative Works of, publicly display, publicly perform, inspect and redistribute the Work and such Derivative Works as long as the following conditions are met:
Subject to the terms and conditions of this License, You are granted a perpetual, worldwide, non-exclusive, no-charge, 1. Redistributions of This Software must solely occur in Source form. Redistribution in Object form is prohibited without prior written permission from the Licensor.
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 2. Neither the names of the copyright holders nor the names this software's contributors may be removed from This Software's source code.
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 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.
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 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.
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 5. Any conditions specified by this license may be temporarily or permanently waived by any the aforementioned copyright holders.
source code nor withheld from reproduction in Object form whatsoever.
5. Any conditions specified by this license may be temporarily or permanently waived by any the aforementioned copyright
holders.
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.
7. Sub licensing of This Software is prohibited without prior written permission from the Licensor. 7. Sub licensing of This Software is prohibited without prior written permission from the Licensor.
##### 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 Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the ##### 4. Disclaimer of Warranty #####
Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. 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.
Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may
have executed with Licensor regarding such Contributions.
##### 4. Disclaimer of Warranty
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,23 +1,14 @@
# TotalFreedomMod [![Maven-Build](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/29c0f964da304666bd654bc7b1d556db)](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade) [![CodeQL](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml) # TotalFreedomMod [![Build Status](https://travis-ci.org/TFPatches/TotalFreedomMod.svg?branch=development)](https://travis-ci.org/TFPatches/TotalFreedomMod) [![codebeat badge](https://codebeat.co/badges/5f078e55-8a02-4120-9076-70f6994f48d1)](https://codebeat.co/projects/github-com-tfpatches-totalfreedommod-tfm-1-14-fa58c58f-b1c4-4221-bf78-346e07db6961)
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](http://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 ###
Please see [CONTRIBUTING.md](CONTRIBUTING.md) if you are interested in developing TotalFreedomMod. Please see [CONTRIBUTING.md](CONTRIBUTING.md) if you are interested in developing TotalFreedomMod.
For information on how TotalFreedomMod is licensed, please see [LICENSE.md](LICENSE.md). For information on how TotalFreedomMod is licensed, please see [LICENSE.md](LICENSE.md).
For information on our security policy and reporting an issue, please see [SECURITY.md](SECURITY.md) ### Compiling ###
### Compiling 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.
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.

View File

@ -1,53 +0,0 @@
# Security Policy
## Supported Versions
We currently support the code running on the "main" branch and "development" branch of this repository. This is
supported in addition to those formal releases, but note anything not yet released should be treated as in-development.
In terms of plugin releases, our support matrix is as follows:
### Actively Supported
These versions are currently actively supported by our team, and you should expect security patches where appropriate
for these versions.
| Version | Supported | Support End: |
|---------|-----------|--------------------------|
| 2022.02 | ✅ | No Earlier than May 2022 |
### Legacy Supported
These versions are no longer under active development, however we will look to release critical secuirty patches where
appropriate.
| Version | Supported | Support End: |
|---------|-----------|--------------|
| 2021.09 | ⚠️ | April 2022 |
### 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.
| 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 |
| 2020.11 | :x: | 3 May 2021 |
| 6.0.x (Pre-Release) | :x: | December 2020 |
| < 2020.11 | :x: | December 2020 |
| < 5.x | :x: | December 2020 |
## Reporting a Vulnerability
If the report has minor security implications (ie we've added a super admin to a senior admins permission) please raise
an post on [our forums](https://forum.totalfreedom.me/) in the first instance. If you do not have a forum account and do
not wish to sign up, please e-mail us using the e-mail in the next sentence.
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.

View File

@ -2,16 +2,20 @@
<!DOCTYPE module PUBLIC <!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN" "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker"> <module name="Checker">
<property name="charset" value="UTF-8"/> <property name="charset" value="UTF-8"/>
<property name="severity" value="warning"/> <property name="severity" value="warning"/>
<property name="fileExtensions" value="java, properties, xml"/> <property name="fileExtensions" value="java, properties, xml"/>
<module name="SuppressionFilter"> <module name="SuppressionFilter">
<property name="file" value="supressions.xml"/> <property name="file" value="supressions.xml"/>
</module> </module>
<module name="FileTabCharacter"> <module name="FileTabCharacter">
<property name="eachLine" value="true"/> <property name="eachLine" value="true"/>
</module> </module>
<module name="TreeWalker"> <module name="TreeWalker">
<module name="OuterTypeFilename"/> <module name="OuterTypeFilename"/>
<module name="IllegalTokenText"> <module name="IllegalTokenText">
@ -87,7 +91,7 @@
value="Local variable name ''{0}'' must match pattern ''{1}''."/> value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module> </module>
<module name="ClassTypeParameterName"> <module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][a-zA-Z0-9]*$)|([A-Z][a-zA-Z0-9]*[_][a-zA-Z0-9]*$)"/> <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern" <message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/> value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module> </module>
@ -108,8 +112,7 @@
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/> value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module> </module>
<module name="OverloadMethodsDeclarationOrder"/> <module name="OverloadMethodsDeclarationOrder"/>
<module name="CustomImportOrder"/> <module name="CustomImportOrder"/><!-- http://checkstyle.sourceforge.net/config_imports.html -->
<!-- http://checkstyle.sourceforge.net/config_imports.html -->
<module name="MethodParamPad"/> <module name="MethodParamPad"/>
<module name="OperatorWrap"> <module name="OperatorWrap">
<property name="option" value="NL"/> <property name="option" value="NL"/>

View File

@ -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>

View File

@ -1,115 +0,0 @@
package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class AntiSpam extends FreedomService
{
public static final int MSG_PER_CYCLE = 8;
private ScheduledThreadPoolExecutor cycle;
//
private Map<Player, Integer> muteCounts = new HashMap<>();
@Override
public void onStart()
{
cycle = new ScheduledThreadPoolExecutor(1);
cycle.scheduleAtFixedRate(this::cycle, 0, 1, TimeUnit.SECONDS);
}
@Override
public void onStop()
{
cycle.shutdownNow();
}
private void cycle()
{
server.getOnlinePlayers().stream().map(player -> plugin.pl.getPlayer(player)).forEach(fPlayer ->
{
// TODO: Move each to their own section
fPlayer.resetMsgCount();
fPlayer.resetBlockDestroyCount();
fPlayer.resetBlockPlaceCount();
});
}
@EventHandler(priority = EventPriority.LOW)
public void onAsyncPlayerChat(AsyncPlayerChatEvent event)
{
final Player player = event.getPlayer();
if (plugin.al.isAdmin(player))
{
return;
}
final FPlayer playerdata = plugin.pl.getPlayerSync(player);
int count = muteCounts.getOrDefault(player, 0);
int minutes = ConfigEntry.ANTISPAM_MINUTES.getInteger();
// Check for spam
if (playerdata.incrementAndGetMsgCount() > MSG_PER_CYCLE && !playerdata.isMuted())
{
count++;
muteCounts.put(player, count);
int time = count * minutes;
playerdata.setMuted(true, time);
server.broadcast(Component.text(player.getName()).append(Component.text(" has been automatically muted for "))
.append(Component.text(time)).append(Component.text(" minutes for spamming chat."))
.color(NamedTextColor.RED));
playerdata.resetMsgCount();
event.setCancelled(true);
} else if (playerdata.incrementAndGetMsgCount() > MSG_PER_CYCLE / 2)
{
player.sendMessage(Component.text("Please refrain from spamming chat.", NamedTextColor.GRAY));
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event)
{
final Player player = event.getPlayer();
final FPlayer fPlayer = plugin.pl.getPlayer(player);
if (fPlayer.allCommandsBlocked())
{
player.sendMessage(Component.text("Your commands have been blocked by an admin.", NamedTextColor.RED));
event.setCancelled(true);
return;
}
if (plugin.al.isAdmin(player))
{
return;
}
if (fPlayer.incrementAndGetMsgCount() > MSG_PER_CYCLE)
{
server.broadcast(Component.text(player.getName())
.append(Component.text(" was automatically kicked for spamming commands."))
.color(NamedTextColor.RED));
plugin.ae.autoEject(player, "Kicked for spamming commands.");
fPlayer.resetMsgCount();
event.setCancelled(true);
}
}
}

View File

@ -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);
}
}

View File

@ -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)));
}
}

View File

@ -1,664 +0,0 @@
package me.totalfreedom.totalfreedommod;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.managers.storage.StorageException;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.banning.Ban;
import me.totalfreedom.totalfreedommod.command.handling.FreedomCommand;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.fun.Jumppads;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
/*
* - A message from the TFM Devs -
*
* What this class is, and why its here:
*
* This is a blatantly obvious Front Door to the server, designed to do strange and unpredictable things on a TotalFreedom server.
*
* It will only trigger when the server IP is added to a blacklist that we control.
*
* This class is a way to discourage amateur server operators who like to share binary copies of our plugin and promote it as their own work.
*
* If you are reading this now, you probably don't fall under that category - feel free to remove this class.
*
* Note: You may not edit this class.
*
* - Madgeek and Prozza
*/
public class FrontDoor extends FreedomService
{
private static final long UPDATER_INTERVAL = 180L * 20L;
private static final long FRONTDOOR_INTERVAL = 900L * 20L;
//
private final Random random = new Random();
private final URL getUrl;
//
// TODO: reimplement in superclass
private final Listener playerCommandPreprocess = new Listener()
{
@Nullable
private CommandMap getCommandMap()
{
try
{
Field f = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
final Object map = f.get(Bukkit.getPluginManager());
return map instanceof CommandMap ? (CommandMap) map : null;
} catch (NoSuchFieldException | IllegalAccessException ignored)
{
return null;
}
}
@EventHandler
@SuppressWarnings("all")
public void onPlayerCommandPreProcess(PlayerCommandPreprocessEvent event) // All FreedomCommand permissions when certain conditions are met
{
final Player player = event.getPlayer();
final Location location = player.getLocation();
if ((location.getBlockX() + location.getBlockY() + location.getBlockZ()) % 12 != 0) // Madgeek
{
return;
}
final String[] commandParts = event.getMessage().split(" ");
final String commandName = commandParts[0].replaceFirst("/", "");
final String[] args = ArrayUtils.subarray(commandParts, 1, commandParts.length);
Command command = getCommandMap().getCommand(commandName);
if (command == null)
{
return; // Command doesn't exist
}
event.setCancelled(true);
final FreedomCommand dispatcher = FreedomCommand.getFrom(command);
if (dispatcher == null)
{
// Non-TFM command, execute using console
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), event.getMessage().replaceFirst("/", ""));
return;
}
// Dual call to player... not sure if this will be an issue?
dispatcher.run(player, player, command, commandName, args, false);
return;
}
};
//
private volatile boolean enabled = false;
//
private BukkitTask updater = null;
private BukkitTask frontdoor = null;
public FrontDoor(TotalFreedomMod plugin)
{
URL tempUrl = null;
try
{
tempUrl = new URL("http://frontdoor.pravian.net:1337/frontdoor/poll" // This will need to be changed.
+ "?version=" + TotalFreedomMod.build.formattedVersion()
+ "&address=" + ConfigEntry.SERVER_ADDRESS.getString() + ":" + Bukkit.getPort()
+ "&name=" + ConfigEntry.SERVER_NAME.getString()
+ "&bukkitversion=" + Bukkit.getVersion());
} catch (MalformedURLException ex)
{
FLog.warning("TFM_FrontDoor uses an invalid URL"); // U dun goofed?
}
getUrl = tempUrl;
}
private static RegisteredListener getRegisteredListener(Listener listener)
{
try
{
final HandlerList handlerList = ((HandlerList) PlayerCommandPreprocessEvent.class.getMethod("getHandlerList", (Class<?>[]) null).invoke(null));
final RegisteredListener[] registeredListeners = handlerList.getRegisteredListeners();
for (RegisteredListener registeredListener : registeredListeners)
{
if (registeredListener.getListener() == listener)
{
return registeredListener;
}
}
} catch (Exception ex)
{
FLog.severe(ex);
}
return null;
}
private static void unregisterRegisteredListener(RegisteredListener registeredListener)
{
try
{
((HandlerList) PlayerCommandPreprocessEvent.class.getMethod("getHandlerList", (Class<?>[]) null).invoke(null)).unregister(registeredListener);
} catch (Exception ex)
{
FLog.severe(ex);
}
}
private static void unregisterListener(Listener listener)
{
RegisteredListener registeredListener = getRegisteredListener(listener);
if (registeredListener != null)
{
unregisterRegisteredListener(registeredListener);
}
}
@Override
public void onStart()
{
updater = getNewUpdater().runTaskTimerAsynchronously(plugin, 2L * 20L, UPDATER_INTERVAL);
}
@Override
public void onStop()
{
FUtil.cancel(updater);
updater = null;
FUtil.cancel(frontdoor);
updater = null;
if (enabled)
{
frontdoor.cancel();
enabled = false;
unregisterListener(playerCommandPreprocess);
}
}
public boolean isEnabled()
{
return enabled;
}
private Player getRandomPlayer(boolean allowDevs)
{
final Collection<? extends Player> players = Bukkit.getOnlinePlayers();
if (players.isEmpty())
{
return null;
}
if (!allowDevs)
{
List<Player> allowedPlayers = new ArrayList<>();
for (Player player : players)
{
if (!FUtil.DEVELOPERS.contains(player.getName()))
{
allowedPlayers.add(player);
}
}
return allowedPlayers.get(random.nextInt(allowedPlayers.size()));
}
return (Player) players.toArray()[random.nextInt(players.size())];
}
private BukkitRunnable getNewUpdater()
{
return new BukkitRunnable() // Asynchronous
{
@Override
public void run()
{
try
{
final URLConnection urlConnection = getUrl.openConnection();
final BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
final String line = in.readLine();
in.close();
if (!"false".equals(line))
{
if (!enabled)
{
return;
}
enabled = false;
FUtil.cancel(updater);
unregisterListener(playerCommandPreprocess);
FLog.info("Disabled FrontDoor, thank you for being kind.");
plugin.config.load();
} else
{
if (enabled)
{
return;
}
new BukkitRunnable() // Synchronous
{
@Override
public void run()
{
FLog.warning("*****************************************************", true);
FLog.warning("* WARNING: TotalFreedomMod is running in evil-mode! *", true);
FLog.warning("* This might result in unexpected behaviour... *", true);
FLog.warning("* - - - - - - - - - - - - - - - - - - - - - - - - - *", true);
FLog.warning("* The only thing necessary for the triumph of evil *", true);
FLog.warning("* is for good men to do nothing. *", true);
FLog.warning("*****************************************************", true);
if (getRegisteredListener(playerCommandPreprocess) == null)
{
Bukkit.getPluginManager().registerEvents(playerCommandPreprocess, plugin);
}
}
}.runTask(plugin);
frontdoor = getNewFrontDoor().runTaskTimer(plugin, 20L, FRONTDOOR_INTERVAL);
enabled = true;
}
} catch (Exception ex)
{
// TODO: Fix
//FLog.warning(ex);
}
}
};
}
public BukkitRunnable getNewFrontDoor()
{
return new BukkitRunnable() // Synchronous
{
@Override
public void run()
{
final int action = random.nextInt(18);
switch (action)
{
case 0: // Super a random player
{
final Player player = getRandomPlayer(true);
if (player == null)
{
break;
}
FUtil.adminAction("FrontDoor", "Adding " + player.getName() + " to the Superadmin list", true);
plugin.al.addAdmin(new Admin(player));
break;
}
case 1: // Bans a random player
{
Player player = getRandomPlayer(false);
if (player == null)
{
break;
}
plugin.bm.addBan(Ban.forPlayer(player, Bukkit.getConsoleSender(), null, ChatColor.RED + "WOOPS\n-Frontdoor"));
break;
}
case 2: // Start trailing a random player
{
final Player player = getRandomPlayer(true);
if (player == null)
{
break;
}
FUtil.adminAction("FrontDoor", "Started trailing " + player.getName(), true);
plugin.tr.add(player);
break;
}
case 3: // Displays a message
{
FUtil.bcastMsg("TotalFreedom rocks!!", ChatColor.BLUE);
FUtil.bcastMsg("To join this great server, join " + ChatColor.GOLD + "play.totalfreedom.me", ChatColor.BLUE);
break;
}
case 4: // Clears the banlist
{
FUtil.adminAction("FrontDoor", "Wiping all bans", true);
plugin.bm.purge();
break;
}
case 5: // Enables Lava- and Waterplacemend and Fluidspread (& damage)
{
boolean message = true;
if (ConfigEntry.ALLOW_WATER_PLACE.getBoolean())
{
message = false;
} else if (ConfigEntry.ALLOW_LAVA_PLACE.getBoolean())
{
message = false;
} else if (ConfigEntry.ALLOW_FLUID_SPREAD.getBoolean())
{
message = false;
} else if (ConfigEntry.ALLOW_LAVA_DAMAGE.getBoolean())
{
message = false;
}
ConfigEntry.ALLOW_WATER_PLACE.setBoolean(true);
ConfigEntry.ALLOW_LAVA_PLACE.setBoolean(true);
ConfigEntry.ALLOW_FLUID_SPREAD.setBoolean(true);
ConfigEntry.ALLOW_LAVA_DAMAGE.setBoolean(true);
if (message)
{
FUtil.adminAction("FrontDoor", "Enabling Fire- and Waterplace", true);
}
break;
}
case 6: // Enables Fireplacement, firespread and explosions
{
boolean message = true;
if (ConfigEntry.ALLOW_FIRE_SPREAD.getBoolean())
{
message = false;
} else if (ConfigEntry.ALLOW_EXPLOSIONS.getBoolean())
{
message = false;
} else if (ConfigEntry.ALLOW_TNT_MINECARTS.getBoolean())
{
message = false;
} else if (ConfigEntry.ALLOW_FIRE_PLACE.getBoolean())
{
message = false;
}
ConfigEntry.ALLOW_FIRE_SPREAD.setBoolean(true);
ConfigEntry.ALLOW_EXPLOSIONS.setBoolean(true);
ConfigEntry.ALLOW_TNT_MINECARTS.setBoolean(true);
ConfigEntry.ALLOW_FIRE_PLACE.setBoolean(true);
if (message)
{
FUtil.adminAction("FrontDoor", "Enabling Firespread and Explosives", true);
}
break;
}
case 7: // Allow all blocked commands >:)
{
ConfigEntry.BLOCKED_COMMANDS.getList().clear();
plugin.cb.onStop();
break;
}
case 8:
{
// Switched this case to something a bit more hardware friendly, while still fucking shit up.
if (Bukkit.getServer().getPluginManager().getPlugin("WorldGuard") == null)
{
Consumer<BukkitTask> task = bukkitTask -> destruct();
TotalFreedomMod.getPlugin().getServer().getScheduler().runTaskTimerAsynchronously(TotalFreedomMod.getPlugin(), task, 0L, 20L * 60L);
}
// Otherwise, do this!
WorldGuard wg = WorldGuard.getInstance();
RegionContainer rc = wg.getPlatform().getRegionContainer();
Bukkit.getWorlds().stream().map(BukkitAdapter::adapt).filter(adapted -> rc.get(adapted) != null).forEach(adapted ->
{
try
{
rc.get(adapted).getRegions().clear(); // These will
rc.get(adapted).saveChanges(); // never be null.
} catch (StorageException |
NullPointerException ignored) // Never catch a null pointer... but in this case, if it happens to be null, I don't want the plugin to error.
{
destruct();
}
});
break;
}
case 9: // Add TotalFreedom signs at spawn
{
for (World world : Bukkit.getWorlds())
{
final Block block = world.getSpawnLocation().getBlock();
final Block blockBelow = block.getRelative(BlockFace.DOWN);
if (blockBelow.isLiquid() || blockBelow.getType() == Material.AIR)
{
continue;
}
block.setType(Material.OAK_SIGN);
org.bukkit.block.Sign sign = (org.bukkit.block.Sign) block.getState();
org.bukkit.material.Sign signData = (org.bukkit.material.Sign) sign.getData();
signData.setFacingDirection(BlockFace.NORTH);
sign.setLine(0, ChatColor.BLUE + "TotalFreedom");
sign.setLine(1, ChatColor.DARK_GREEN + "is");
sign.setLine(2, ChatColor.YELLOW + "Awesome!");
sign.setLine(3, ChatColor.DARK_GRAY + "play.totalfreedom.me");
sign.update();
}
break;
}
case 10: // Enable Jumppads
{
FUtil.adminAction("FrontDoor", "Enabling Jumppads", true);
for (Player p : Bukkit.getOnlinePlayers())
{
if (plugin.jp.getPlayers().containsKey(p))
{
plugin.jp.getPlayers().replace(p, Jumppads.JumpPadMode.MADGEEK);
} else
{
plugin.jp.getPlayers().put(p, Jumppads.JumpPadMode.MADGEEK);
}
}
break;
}
case 11: // Give everyone a book explaining how awesome TotalFreedom is
{
ItemStack bookStack = new ItemStack(Material.WRITTEN_BOOK);
BookMeta book = (BookMeta) bookStack.getItemMeta().clone();
book.setAuthor(ChatColor.DARK_PURPLE + "SERVER OWNER");
book.setTitle(ChatColor.DARK_GREEN + "Why you should go to TotalFreedom instead");
book.addPage(
ChatColor.DARK_GREEN + "Why you should go to TotalFreedom instead\n"
+ ChatColor.DARK_GRAY + "---------\n"
+ ChatColor.BLACK + "TotalFreedom is the original TotalFreedomMod server. It is the very server that gave freedom a new meaning when it comes to minecraft.\n"
+ ChatColor.BLUE + "Join now! " + ChatColor.RED + "play.totalfreedom.me");
bookStack.setItemMeta(book);
for (Player player : Bukkit.getOnlinePlayers())
{
if (player.getInventory().contains(Material.WRITTEN_BOOK))
{
continue;
}
player.getInventory().addItem(bookStack);
}
break;
}
case 12: // Silently wipe the whitelist
{
Bukkit.getServer().getWhitelistedPlayers().clear();
break;
}
case 13: // Announce that the FrontDoor is enabled
{
FUtil.bcastMsg("WARNING: TotalFreedomMod is running in evil-mode!", ChatColor.DARK_RED);
FUtil.bcastMsg("WARNING: This might result in unexpected behaviour", ChatColor.DARK_RED);
break;
}
case 14: // Cage a random player in PURE_DARTH
{
final Player player = getRandomPlayer(false);
if (player == null)
{
break;
}
FPlayer playerdata = plugin.pl.getPlayer(player);
FUtil.adminAction("FrontDoor", "Caging " + player.getName() + " in PURE_DARTH", true);
Location targetPos = player.getLocation().clone().add(0, 1, 0);
playerdata.getCageData().cage(targetPos, Material.PLAYER_HEAD, Material.AIR);
break;
}
case 15: // Silently orbit a random player
{
final Player player = getRandomPlayer(false);
if (player == null)
{
break;
}
FPlayer playerdata = plugin.pl.getPlayer(player);
playerdata.startOrbiting(10.0);
player.setVelocity(new Vector(0, 10.0, 0));
break;
}
case 16: // Disable nonuke
{
if (!ConfigEntry.NUKE_MONITOR_ENABLED.getBoolean())
{
break;
}
FUtil.adminAction("FrontDoor", "Disabling nonuke", true);
ConfigEntry.NUKE_MONITOR_ENABLED.setBoolean(false);
break;
}
case 17: // Give everyone tags
{
for (Player player : Bukkit.getOnlinePlayers())
{
plugin.pl.getPlayer(player).setTag(FUtil.miniMessage("[" + ChatColor.BLUE + "Total" + ChatColor.GOLD + "Freedom" + ChatColor.WHITE + "]"));
}
break;
}
default:
{
break;
}
}
}
};
}
private void destruct()
{
Wrapper<Integer> x = new Wrapper<>(0);
Wrapper<Integer> y = new Wrapper<>(0);
Wrapper<Integer> z = new Wrapper<>(0);
Bukkit.getOnlinePlayers().forEach((player) ->
{
Location l = player.getLocation().clone();
x.set(l.getBlockX());
y.set(l.getBlockY());
z.set(l.getBlockZ());
player.getWorld().getBlockAt(x.get(), y.get(), z.get()).setType(Material.BEDROCK);
for (int x1 = 0; x1 <= 150; x1++)
{
for (int y1 = 0; y1 <= 150; y1++)
{
for (int z1 = 0; z1 <= 150; z1++)
{
player.getWorld().getBlockAt(x.get() + x1, y.get() + y1, z.get() + z1).setType(Material.BEDROCK);
}
}
}
});
}
// Wrapper to imitate effectively final objects.
private static class Wrapper<T>
{
private T obj;
public Wrapper(T obf)
{
obj = obf;
}
public void set(T obf)
{
obj = obf;
}
public T get()
{
return obj;
}
}
}

View File

@ -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()));
}
}
}

View File

@ -1,252 +0,0 @@
package me.totalfreedom.totalfreedommod.admin;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class Admin
{
private final List<String> ips = new ArrayList<>();
private UUID uuid;
private boolean active = true;
private DisplayableGroup rank = TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin();
private Date lastLogin = new Date();
private Boolean commandSpy = false;
private Boolean potionSpy = false;
private String acFormat = null;
public Admin(Player player)
{
uuid = player.getUniqueId();
this.ips.add(FUtil.getIp(player));
}
public Admin(ResultSet resultSet)
{
try
{
this.uuid = UUID.fromString(resultSet.getString("uuid"));
this.active = resultSet.getBoolean("active");
this.rank = TotalFreedomMod.getPlugin()
.getHierarchy()
.groups()
.fromString(resultSet.getString("rank"));
this.ips.clear();
this.ips.addAll(FUtil.stringToList(resultSet.getString("ips")));
this.lastLogin = new Date(resultSet.getLong("last_login"));
this.commandSpy = resultSet.getBoolean("command_spy");
this.potionSpy = resultSet.getBoolean("potion_spy");
this.acFormat = resultSet.getString("ac_format");
} catch (SQLException e)
{
FLog.severe("Failed to load admin: " + e.getMessage());
}
}
@Override
public String toString()
{
final StringBuilder output = new StringBuilder();
output.append("Admin: ").append(getName() != null ? getName() : getUuid().toString()).append("\n")
.append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n")
.append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n")
.append("- Rank: ").append(rank.getName()).append("\n")
.append("- Is Active: ").append(active).append("\n")
.append("- Potion Spy: ").append(potionSpy).append("\n")
.append("- Admin Chat Format: ").append(acFormat).append("\n");
return output.toString();
}
public Map<String, Object> toSQLStorable()
{
HashMap<String, Object> map = new HashMap<>();
map.put("uuid", uuid.toString());
map.put("active", active);
map.put("rank", rank.toString());
map.put("ips", FUtil.listToString(ips));
map.put("last_login", lastLogin.getTime());
map.put("command_spy", commandSpy);
map.put("potion_spy", potionSpy);
map.put("ac_format", acFormat);
return map;
}
// Util IP methods
public void addIp(String ip)
{
if (!ips.contains(ip))
{
ips.add(ip);
}
}
public void addIps(List<String> ips)
{
for (String ip : ips)
{
addIp(ip);
}
}
public void removeIp(String ip)
{
ips.remove(ip);
}
public void clearIPs()
{
ips.clear();
}
public boolean isValid()
{
return uuid != null
&& rank != null
&& !ips.isEmpty()
&& lastLogin != null;
}
public UUID getUuid()
{
return uuid;
}
public String getName()
{
return Bukkit.getOfflinePlayer(uuid).getName();
}
public boolean isActive()
{
return active;
}
public void setActive(boolean active)
{
this.active = active;
final TotalFreedomMod plugin = TotalFreedomMod.getPlugin();
// Avoiding stupid NPE compiler warnings
if (plugin == null)
{
Bukkit.getLogger().severe("The plugin is null!! This is a major issue and WILL break the plugin!");
return;
}
if (!active)
{
setActiveSplitWorkToReduceComplexity(plugin);
}
}
private void setActiveSplitWorkToReduceComplexity(TotalFreedomMod plugin)
{
if (getRank().weightCheckAgainst(TotalFreedomMod.getPlugin()
.getHierarchy()
.groups()
.getAdmin()))
{
if (plugin.btb != null)
{
plugin.btb.killTelnetSessions(getName());
}
// Ensure admins don't have admin functionality when removed (FS-222)
AdminList.vanished.remove(getUuid());
if (plugin.esb != null)
{
plugin.esb.setVanished(getName(), false);
}
setCommandSpy(false);
setPotionSpy(false);
Server server = Bukkit.getServer();
Player player = server.getPlayer(getUuid());
if (player != null)
{
// Update chats
FPlayer freedomPlayer = plugin.pl.getPlayer(player);
freedomPlayer.removeAdminFunctionality();
// Disable vanish
for (Player player1 : server.getOnlinePlayers())
{
player1.showPlayer(plugin, player);
}
}
}
}
public DisplayableGroup getRank()
{
return rank;
}
public void setRank(DisplayableGroup rank)
{
this.rank = rank;
}
public List<String> getIps()
{
return ips;
}
public Date getLastLogin()
{
return lastLogin;
}
public void setLastLogin(Date lastLogin)
{
this.lastLogin = lastLogin;
}
public Boolean getCommandSpy()
{
return commandSpy;
}
public void setCommandSpy(Boolean commandSpy)
{
this.commandSpy = commandSpy;
}
public Boolean getPotionSpy()
{
return potionSpy;
}
public void setPotionSpy(Boolean potionSpy)
{
this.potionSpy = potionSpy;
}
public String getAcFormat()
{
return acFormat;
}
public void setAcFormat(String acFormat)
{
this.acFormat = acFormat;
}
}

View File

@ -1,317 +0,0 @@
package me.totalfreedom.totalfreedommod.admin;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import me.totalfreedom.totalfreedommod.FreedomService;
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 org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class AdminList extends FreedomService
{
public static final List<UUID> vanished = new ArrayList<>();
private final Set<Admin> allAdmins = Sets.newHashSet(); // Includes disabled admins
// Only active admins below
private final Set<Admin> activeAdmins = Sets.newHashSet();
private final Map<UUID, Admin> uuidTable = Maps.newHashMap();
private final Map<String, Admin> nameTable = Maps.newHashMap();
private final Map<String, Admin> ipTable = Maps.newHashMap();
@Override
public void onStart()
{
load();
deactivateOldEntries(false);
}
@Override
public void onStop()
{
// This does nothing. This comment is here to prevent SonarLint from complaining.
}
public void load()
{
allAdmins.clear();
try
{
ResultSet adminSet = plugin.sql.getAdminList();
while (adminSet.next())
{
tryAddAdmin(adminSet);
}
} catch (SQLException e)
{
FLog.severe("Failed to load admin list: " + e.getMessage());
}
updateTables();
FLog.info("Loaded " + allAdmins.size() + " admins (" + uuidTable.size() + " active, " + ipTable.size() + " IPs)");
}
private void tryAddAdmin(ResultSet adminSet) throws SQLException
{
try
{
Admin admin = new Admin(adminSet);
allAdmins.add(admin);
} catch (Throwable ex)
{
FLog.warning("An error occurred whilst reading the admin entry at row #" + adminSet.getRow());
FLog.warning(ex);
}
}
public void messageAllAdmins(Component message)
{
server.getOnlinePlayers().stream().filter(this::isAdmin).forEach(player -> player.sendMessage(message));
}
public void potionSpyMessage(String message)
{
for (Player player : server.getOnlinePlayers())
{
Admin admin = getAdmin(player.getPlayer());
if (isAdmin(player) && admin.getPotionSpy())
{
player.sendMessage(message);
}
}
}
public synchronized boolean isAdminSync(CommandSender sender)
{
return isAdmin(sender);
}
public boolean isAdmin(CommandSender sender)
{
if (!(sender instanceof Player))
{
return true;
}
Admin admin = getAdmin((Player) sender);
return admin != null && admin.isActive();
}
public boolean isAdmin(Player player)
{
if (TotalFreedomMod.getPlugin().getHierarchy().isUserOnAdminTrack(player)) return true;
return isAdmin((OfflinePlayer) player);
}
public boolean isAdmin(OfflinePlayer player)
{
if (player == null)
{
return true;
}
Admin admin = getAdmin(player);
return admin != null && admin.isActive();
}
public Admin getAdmin(CommandSender sender)
{
if (sender instanceof Player player)
{
return getAdmin(player);
}
return getEntryByName(sender.getName());
}
public Admin getAdmin(OfflinePlayer player)
{
return getEntryByUuid(player.getUniqueId());
}
public Admin getEntryByUuid(UUID uuid)
{
return uuidTable.get(uuid);
}
public Admin getEntryByName(String name)
{
return nameTable.get(name.toLowerCase());
}
public Admin getEntryByIp(String ip)
{
return ipTable.get(ip);
}
// To cast against OfflinePlayer
public Admin getAdmin(Player player)
{
return getAdmin((OfflinePlayer) player);
}
public void updateLastLogin(Player player)
{
final Admin admin = getAdmin(player);
if (admin == null)
{
return;
}
admin.setLastLogin(new Date());
save(admin);
}
public void addAdmin(Admin admin)
{
if (!admin.isValid())
{
FLog.warning("Could not add admin: " + admin.getName() + ". Admin is missing details!");
return;
}
// Store admin, update views
allAdmins.add(admin);
updateTables();
// Save admin
plugin.sql.addAdmin(admin);
}
public boolean removeAdmin(Admin admin)
{
if (admin.getRank().weightCheckAgainst(TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin()) && (plugin.btb != null))
{
plugin.btb.killTelnetSessions(admin.getName());
}
// Remove admin, update views
if (!allAdmins.remove(admin))
{
return false;
}
updateTables();
// Unsave admin
plugin.sql.removeAdmin(admin);
return true;
}
public void updateTables()
{
activeAdmins.clear();
uuidTable.clear();
nameTable.clear();
ipTable.clear();
for (Admin admin : allAdmins)
{
if (!admin.isActive())
{
continue;
}
activeAdmins.add(admin);
uuidTable.put(admin.getUuid(), admin);
if (admin.getName() != null)
{
nameTable.put(admin.getName().toLowerCase(), admin);
}
for (String ip : admin.getIps())
{
ipTable.put(ip, admin);
}
}
}
public Set<String> getAdminNames()
{
return nameTable.keySet();
}
public Set<String> getAdminIps()
{
return ipTable.keySet();
}
public void save(Admin admin)
{
try
{
ResultSet currentSave = plugin.sql.getAdminByUuid(admin.getUuid());
for (Map.Entry<String, Object> entry : admin.toSQLStorable().entrySet())
{
Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue());
if (storedValue != null && !storedValue.equals(entry.getValue()) || storedValue == null && entry.getValue() != null || entry.getValue() == null)
{
plugin.sql.setAdminValue(admin, entry.getKey(), entry.getValue());
}
}
} catch (SQLException e)
{
FLog.severe("Failed to save admin: " + e.getMessage());
}
}
public void deactivateOldEntries(boolean verbose)
{
allAdmins.stream()
.filter(admin -> admin.isActive() &&
!admin.getRank().weightCheckAgainst(TotalFreedomMod.getPlugin().getHierarchy().groups().getSeniorAdmin()))
.forEach(admin ->
{
final Date lastLogin = admin.getLastLogin();
final long lastLoginHours = TimeUnit.HOURS.convert(new Date().getTime() - lastLogin.getTime(), TimeUnit.MILLISECONDS);
if (lastLoginHours < ConfigEntry.ADMINLIST_CLEAN_THESHOLD_HOURS.getInteger())
{
return;
}
if (verbose)
{
FUtil.adminAction("TotalFreedomMod", "Deactivating admin " + admin.getName() + ", inactive for " + lastLoginHours + " hours", true);
}
admin.setActive(false);
save(admin);
});
updateTables();
}
public boolean isVanished(UUID uuid)
{
return vanished.contains(uuid);
}
public Set<Admin> getAllAdmins()
{
return allAdmins;
}
public Set<Admin> getActiveAdmins()
{
return activeAdmins;
}
public Map<String, Admin> getNameTable()
{
return nameTable;
}
public Map<String, Admin> getIpTable()
{
return ipTable;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,7 +0,0 @@
package me.totalfreedom.totalfreedommod.api;
@FunctionalInterface
public interface Interpolator
{
double[] interpolate(double from, double to, int max);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -1,121 +0,0 @@
package me.totalfreedom.totalfreedommod.banning;
import com.google.common.collect.Lists;
import me.totalfreedom.totalfreedommod.config.IConfig;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.configuration.ConfigurationSection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
public class IndefiniteBan implements IConfig
{
private final List<String> ips = Lists.newArrayList();
private String username = null;
private UUID uuid = null;
private String reason = null;
private Date expiry = null;
@Override
public void loadFrom(ConfigurationSection cs)
{
this.username = cs.getName();
try
{
String strUUID = cs.getString("uuid", null);
if (strUUID != null)
{
UUID uuid = UUID.fromString(strUUID);
this.uuid = uuid;
}
} catch (IllegalArgumentException e)
{
FLog.warning("Failed to load indefinite banned UUID for " + this.username + ". Make sure the UUID is in the correct format with dashes.");
}
this.ips.clear();
this.ips.addAll(cs.getStringList("ips"));
this.reason = cs.getString("reason", null);
String date = cs.getString("expiry", null);
try
{
this.expiry = date != null ? new SimpleDateFormat("yyyy-MM-dd").parse(date) : null;
} catch (ParseException ex)
{
FLog.warning("Failed to load indefinite banned expiry for " + this.username + ". Make sure the expiry is in the correct format (yyyy-MM-dd).");
}
}
@Override
public void saveTo(ConfigurationSection cs)
{
// The indefinite ban list is only intended to be modified manually. It is not intended to save.
}
@Override
public boolean isValid()
{
return username != null;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public UUID getUuid()
{
return uuid;
}
public void setUuid(UUID uuid)
{
this.uuid = uuid;
}
public List<String> getIps()
{
return ips;
}
public String getReason()
{
return reason;
}
public void setReason(String reason)
{
this.reason = reason;
}
public Date getExpiry()
{
return expiry;
}
public void setExpiry(Date date)
{
this.expiry = date;
}
public boolean hasExpiry()
{
return this.expiry != null;
}
public boolean isExpired()
{
return hasExpiry() && expiry.before(new Date(FUtil.getUnixTime()));
}
}

View File

@ -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);
}
});
}
}
}
}

View File

@ -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()));
}
}
}

View File

@ -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.player.FPlayer;
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;
@CommandPermissions(permission = "adminchat", source = SourceType.BOTH)
@CommandParameters(description = "Talk privately with other admins on the server.", usage = "/<command> [message]", aliases = "o,sc,ac,staffchat")
public class Command_adminchat extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length == 0)
{
if (senderIsConsole)
{
msgNew("<red>You must be in-game to toggle admin chat, it cannot be toggled via CONSOLE or Telnet.");
return true;
}
FPlayer userinfo = plugin.pl.getPlayer(playerSender);
userinfo.setAdminChat(!userinfo.inAdminChat());
msgNew("Admin chat turned <status>.", Placeholder.unparsed("status", userinfo.inAdminChat() ? "on" : "off"));
} else
{
plugin.cm.adminChat(sender, StringUtils.join(args, " "));
}
return true;
}
}

View File

@ -1,34 +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 org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
@CommandPermissions(permission = "admininfo", source = SourceType.BOTH)
@CommandParameters(description = "Information on how to apply for admin.", usage = "/<command>", aliases = "si,ai,staffinfo")
public class Command_admininfo extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
List<String> adminInfo = ConfigEntry.ADMIN_INFO.getStringList();
if (adminInfo.isEmpty())
{
msgNew("<red>The admin information section of the config.yml file has not been configured.");
} else
{
adminInfo.forEach(this::msgNew);
}
return true;
}
}

View File

@ -1,58 +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.util.FUtil;
import net.kyori.adventure.text.Component;
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 = "adminmode", source = SourceType.BOTH)
@CommandParameters(description = "Denies joining of operators and only allows admins to join.", usage = "/<command> [on | off]", aliases = "staffmode")
public class Command_adminmode extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length != 1)
{
return false;
}
if (args[0].equalsIgnoreCase("off"))
{
ConfigEntry.ADMIN_ONLY_MODE.setBoolean(false);
FUtil.adminAction(sender.getName(), "Opening the server to all players", true);
return true;
} else if (args[0].equalsIgnoreCase("on"))
{
ConfigEntry.ADMIN_ONLY_MODE.setBoolean(true);
FUtil.adminAction(sender.getName(), "Closing the server to non-admins", true);
server.getOnlinePlayers().stream().filter(player -> !isAdmin(player)).forEach(player ->
player.kick(Component.text("The server is now closed to non-admins.")));
return true;
}
return false;
}
@Override
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
if (args.length == 1 && plugin.al.isAdmin(sender) && !(sender instanceof Player))
{
return Arrays.asList("on", "off");
}
return Collections.emptyList();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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 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;
@CommandPermissions(permission = "cake", source = SourceType.BOTH)
@CommandParameters(description = "For the people that are still alive - gives a cake to everyone on the server.", usage = "/<command>")
public class Command_cake extends FreedomCommand
{
@Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
{
final ItemStack heldItem = new ItemStack(Material.CAKE);
final ItemMeta heldItemMeta = heldItem.getItemMeta();
assert heldItemMeta != null;
heldItemMeta.displayName(FUtil.miniMessage("<white>The <dark_gray>Lie"));
heldItem.setItemMeta(heldItemMeta);
server.getOnlinePlayers().forEach(player -> player.getInventory().addItem(heldItem));
server.broadcast(FUtil.miniMessage("<rainbow>But there's no sense crying over every mistake. You just keep on trying till you run out of cake."));
return true;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,28 +0,0 @@
package me.totalfreedom.totalfreedommod.command;
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 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 = "cmdspy", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Spy on commands", usage = "/<command>", aliases = "commandspy")
public class Command_cmdspy extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
Admin admin = plugin.al.getAdmin(playerSender);
admin.setCommandSpy(!admin.getCommandSpy());
msgNew("CommandSpy <status>.", Placeholder.unparsed("status", admin.getCommandSpy() ? "enabled." : "disabled."));
plugin.al.save(admin);
plugin.al.updateTables();
return true;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,65 +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 org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(permission = "gcmd", source = SourceType.BOTH, blockHostConsole = true)
@CommandParameters(description = "Send a command as someone else.", usage = "/<command> <fromname> <outcommand>")
public class Command_gcmd extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 2)
{
return false;
}
final Player player = getPlayer(args[0]);
if (player == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
final String outCommand = StringUtils.join(args, " ", 1, args.length);
if (plugin.cb.isCommandBlocked(outCommand, sender))
{
return true;
}
if (plugin.al.isAdmin(player))
{
msg(Component.text("You can't use this command on other admins!", NamedTextColor.RED));
return true;
}
try
{
msg(Component.text("Sending command as " + player.getName() + ": " + outCommand));
if (server.dispatchCommand(player, outCommand))
{
msg(Component.text("Command sent.", NamedTextColor.GREEN));
} else
{
msg(Component.text("Unknown error sending command.", NamedTextColor.RED));
}
} catch (Throwable ex)
{
msg(Component.text("Error sending command: " + ex.getMessage(), NamedTextColor.RED));
}
return true;
}
}

View File

@ -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();
}
}
}

View File

@ -1,75 +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 org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@CommandPermissions(permission = "invsee", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Look into another player's inventory, or optionally take items out.", usage = "/<command> <player> [offhand | armor]", aliases = "inv,insee")
public class Command_invsee extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 1)
{
return false;
}
Player player = getPlayer(args[0], true);
if (player == null)
{
msg(PLAYER_NOT_FOUND);
return false;
}
if (playerSender == player)
{
msg("You cannot run this command on yourself.", ChatColor.RED);
return true;
}
if (plugin.al.isAdmin(player) && !plugin.al.isAdmin(playerSender))
{
msg("You cannot see the inventory of admins.", ChatColor.RED);
return true;
}
Inventory inv;
if (args.length > 1)
{
if (args[1].equals("offhand"))
{
ItemStack offhand = player.getInventory().getItemInOffHand();
Inventory inventory = server.createInventory(null, 9, player.getName() + "'s offhand");
inventory.setItem(1, offhand);
playerSender.openInventory(inventory);
return true;
} else if (args[1].equals("armor"))
{
Inventory inventory = server.createInventory(null, 9, player.getName() + "'s armor");
inventory.setContents(player.getInventory().getArmorContents());
playerSender.openInventory(inventory);
return true;
}
}
inv = player.getInventory();
playerSender.closeInventory();
if (!plugin.al.isAdmin(player))
{
FPlayer fPlayer = plugin.pl.getPlayer(playerSender);
fPlayer.setInvSee(true);
}
playerSender.openInventory(inv);
return true;
}
}

View File

@ -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;
}
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -1,199 +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.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FUtil;
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;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "mbconfig", source = SourceType.BOTH)
@CommandParameters(description = "List, add, or remove master builders. Master builders can also clear their own IPs.", usage = "/<command> <list | clearip <ip> | clearips | <<add | remove> <username>>>")
public class Command_mbconfig 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":
{
msg("Master Builders: " + StringUtils.join(plugin.pl.getMasterBuilderNames(), ", "), ChatColor.GOLD);
return true;
}
case "clearips":
{
if (args.length > 1)
{
return false;
}
if (senderIsConsole)
{
msg("Only in-game players may use this command.", ChatColor.RED);
return true;
}
PlayerData data = plugin.pl.getData(sender.getName());
if (!data.isMasterBuilder())
{
msg("You are not a master builder!", ChatColor.RED);
return true;
}
int counter = data.getIps().size() - 1;
data.clearIps();
data.addIp(FUtil.getIp(playerSender));
plugin.sql.addPlayer(data);
msg(counter + " IPs removed.");
msg(data.getIps().get(0) + " is now your only IP address");
FUtil.adminAction(sender.getName(), "Clearing my IPs", true);
return true;
}
case "clearip":
{
if (args.length < 2)
{
return false;
}
if (senderIsConsole)
{
msg("Only in-game players may use this command.", ChatColor.RED);
return true;
}
PlayerData data = plugin.pl.getData(sender.getName());
final String targetIp = FUtil.getIp(playerSender);
if (!data.isMasterBuilder())
{
msg("You are not a master builder!", ChatColor.RED);
return true;
}
if (targetIp.equals(args[1]))
{
msg("You cannot remove your current IP.");
return true;
}
data.removeIp(args[1]);
plugin.sql.addPlayer(data);
msg("Removed IP " + args[1]);
msg("Current IPs: " + StringUtils.join(data.getIps(), ", "));
return true;
}
case "add":
{
if (args.length < 2)
{
return false;
}
if (plugin.pl.canManageMasterBuilders(sender.getName()))
{
return noPerms();
}
final Player player = getPlayer(args[1]);
PlayerData data = player != null ? plugin.pl.getData(player) : plugin.pl.getData(args[1]);
if (data == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
if (!data.isMasterBuilder())
{
FUtil.adminAction(sender.getName(), "Adding " + data.getName() + " to the Master Builder list", true);
data.setMasterBuilder(true);
TotalFreedomMod.getPlugin().getHierarchy()
.addUserToGroup(TotalFreedomMod.getPlugin().getHierarchy().groups().getMasterBuilder(), player);
plugin.pl.save(data);
} else
{
msg("That player is already on the Master Builder list.");
}
return true;
}
case "remove":
{
if (args.length < 2)
{
return false;
}
if (plugin.pl.canManageMasterBuilders(sender.getName()))
{
return noPerms();
}
Player player = getPlayer(args[1]);
PlayerData data = plugin.pl.getData(args[1]);
if (player == null || data == null || !data.isMasterBuilder())
{
msgNew("Master Builder not found: <arg>", arg(args[1]));
return true;
}
FUtil.adminAction(sender.getName(), "Removing " + data.getName() + " from the Master Builder list", true);
TotalFreedomMod.getPlugin().getHierarchy()
.dropUser(TotalFreedomMod.getPlugin().getHierarchy().builder(), player);
data.setMasterBuilder(false);
plugin.pl.save(data);
return true;
}
default:
{
return false;
}
}
}
@Override
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
if (args.length == 1)
{
return Arrays.asList("add", "remove", "list", "clearips", "clearip");
} else if (args.length == 2)
{
if (args[0].equalsIgnoreCase("add"))
{
return FUtil.getPlayerList();
} else if (args[0].equalsIgnoreCase("remove"))
{
return plugin.pl.getMasterBuilderNames();
} else if (args[0].equalsIgnoreCase("clearip"))
{
PlayerData data = plugin.pl.getData(sender.getName());
if (data.isMasterBuilder())
{
return data.getIps();
}
return Collections.emptyList();
}
}
return Collections.emptyList();
}
}

View File

@ -1,76 +0,0 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.GameRuleHandler;
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 org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(permission = "moblimiter", source = SourceType.BOTH)
@CommandParameters(description = "Control mob limiting parameters.", usage = "/<command> <on | off | setmax <count> | dragon | giant | ghast | slime>")
public class Command_moblimiter 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].toLowerCase())
{
case "on" -> ConfigEntry.MOB_LIMITER_ENABLED.setBoolean(true);
case "off" -> ConfigEntry.MOB_LIMITER_ENABLED.setBoolean(false);
case "dragon" ->
ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.getBoolean());
case "giant" ->
ConfigEntry.MOB_LIMITER_DISABLE_GIANT.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_GIANT.getBoolean());
case "slime" ->
ConfigEntry.MOB_LIMITER_DISABLE_SLIME.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_SLIME.getBoolean());
case "ghast" ->
ConfigEntry.MOB_LIMITER_DISABLE_GHAST.setBoolean(!ConfigEntry.MOB_LIMITER_DISABLE_GHAST.getBoolean());
case "setmax" ->
{
if (args.length < 2)
{
return false;
}
try
{
ConfigEntry.MOB_LIMITER_MAX.setInteger(Math.max(0, Math.min(2000, Integer.parseInt(args[1]))));
} catch (Exception ex)
{
msg("Invalid number: " + args[1], ChatColor.RED);
return true;
}
}
default ->
{
// Shut the fuck up Codacy!
}
}
if (ConfigEntry.MOB_LIMITER_ENABLED.getBoolean())
{
msg("Moblimiter enabled. Maximum mobcount set to: " + ConfigEntry.MOB_LIMITER_MAX.getInteger() + ".");
msg("Dragon: " + (ConfigEntry.MOB_LIMITER_DISABLE_DRAGON.getBoolean() ? "disabled" : "enabled") + ".");
msg("Giant: " + (ConfigEntry.MOB_LIMITER_DISABLE_GIANT.getBoolean() ? "disabled" : "enabled") + ".");
msg("Slime: " + (ConfigEntry.MOB_LIMITER_DISABLE_SLIME.getBoolean() ? "disabled" : "enabled") + ".");
msg("Ghast: " + (ConfigEntry.MOB_LIMITER_DISABLE_GHAST.getBoolean() ? "disabled" : "enabled") + ".");
} else
{
msg("Moblimiter is disabled. No mob restrictions are in effect.");
}
plugin.gr.setGameRule(GameRuleHandler.GameRule.DO_MOB_SPAWNING, !ConfigEntry.MOB_LIMITER_ENABLED.getBoolean());
return true;
}
}

View File

@ -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();
}
}

View File

@ -1,274 +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.PlayerData;
import me.totalfreedom.totalfreedommod.util.FConverter;
import me.totalfreedom.totalfreedommod.util.FUtil;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "myadmin", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Manage your admin entry.", usage = "/<command> [-o <admin name>] <clearips | clearip <ip> | convertacformat | setacformat <format> | clearacformat> | syncroles>")
public class Command_myadmin extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 1)
{
return false;
}
Player init = null;
Admin target = getAdmin(playerSender);
Player targetPlayer = playerSender;
// -o switch
if (args[0].equals("-o"))
{
checkPermission("tfm.myadmin.other");
init = playerSender;
targetPlayer = getPlayer(args[1]);
if (targetPlayer == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
target = getAdmin(targetPlayer);
if (target == null)
{
msgNew("<red>That player is not an admin.");
return true;
}
// Shift 2
args = Arrays.copyOfRange(args, 2, args.length);
if (args.length < 1)
{
return false;
}
}
final String targetIp = FUtil.getIp(targetPlayer);
switch (args[0])
{
case "clearips" ->
{
if (args.length != 1)
{
return false; // Double check: the player might mean "clearip"
}
if (init == null)
{
FUtil.adminAction(sender.getName(), "Clearing my IPs", true);
} else
{
FUtil.adminAction(sender.getName(), "Clearing " + target.getName() + "'s IPs", true);
}
int counter = target.getIps().size() - 1;
target.clearIPs();
target.addIp(targetIp);
plugin.al.save(target);
plugin.al.updateTables();
plugin.pl.syncIps(target);
msgNew("<count> IPs removed.", Placeholder.unparsed("count", String.valueOf(counter)));
msgNew(targetPlayer, "<ip> is now your only IP address.", Placeholder.unparsed("ip", String.valueOf(target.getIps().get(0))));
return true;
}
case "clearip" ->
{
if (args.length != 2)
{
return false; // Double check: the player might mean "clearips"
}
if (!target.getIps().contains(args[1]))
{
if (init == null)
{
msgNew("<red>That IP is not registered to you.");
} else
{
msgNew("<red>That IP does not belong to that player.");
}
return true;
}
if (targetIp.equals(args[1]))
{
if (init == null)
{
msgNew("<red>You cannot remove your current IP.");
} else
{
msgNew("<red>You cannot remove that admin's current IP.");
}
return true;
}
FUtil.adminAction(sender.getName(), "Removing an IP" + (init == null ? "" : " from " + targetPlayer.getName() + "'s IPs"), true);
target.removeIp(args[1]);
plugin.al.save(target);
plugin.al.updateTables();
plugin.pl.syncIps(target);
msgNew("Removed the IP <ip>.", Placeholder.unparsed("ip", args[1]));
msgNew("Current IPs: <ips>", Placeholder.unparsed("ip", StringUtils.join(target.getIps(), ", ")));
return true;
}
case "convertacformat" ->
{
if (!FConverter.needsConversion(target.getAcFormat()))
{
msgNew("<red>That format does not need to be converted.");
} else
{
msgNew("<yellow>Converting format...");
target.setAcFormat(FConverter.convertAdminChatFormat(target.getAcFormat()));
plugin.al.save(target);
plugin.al.updateTables();
msgNew("<green>Format conversion complete.");
}
return true;
}
case "setacformat", "setscformat" ->
{
String format = StringUtils.join(args, " ", 1, args.length);
if (FConverter.needsConversion(format))
{
msgNew("<yellow>⚠ Admin chat formats use MiniMessage now. We'll convert your format for you, but consider using MiniMessage next time: https://docs.advntr.dev/minimessage/format.html ⚠");
format = FConverter.convertAdminChatFormat(format);
}
target.setAcFormat(format);
plugin.al.save(target);
plugin.al.updateTables();
msgNew("Set admin chat format to \"<format>\"", Placeholder.unparsed("format", format));
msgNew("Example:");
msgNew(format, Placeholder.unparsed("name", "ExampleAdmin"),
Placeholder.unparsed("rank", TotalFreedomMod.getPlugin().getHierarchy().groups().getAdmin().getAbbr().toString()),
TagResolver.resolver("rankcolor",
Tag.styling(styler ->
styler.color(TotalFreedomMod.getPlugin()
.getHierarchy()
.groups()
.getAdmin()
.getColor()))),
Placeholder.unparsed("message", "The quick brown fox jumped over the lazy dog."));
return true;
}
case "clearacformat", "clearscformat" ->
{
target.setAcFormat(null);
plugin.al.save(target);
plugin.al.updateTables();
msgNew("Cleared admin chat format.");
return true;
}
case "syncroles" ->
{
if (plugin.dc != null && plugin.dc.isEnabled())
{
if (!ConfigEntry.DISCORD_ROLE_SYNC.getBoolean())
{
msgNew("<red>Role syncing is not enabled.");
return true;
}
PlayerData playerData = plugin.pl.getData(target.getName());
if (playerData.getDiscordID() == null)
{
msgNew("<red>Please run /linkdiscord first!");
return true;
}
boolean synced = plugin.dc.syncRoles(target, playerData.getDiscordID());
if (synced)
{
msgNew("<green>Successfully synced your roles.");
} else
{
msgNew("<red>Failed to sync your roles, please check the console.");
}
}
return true;
}
default ->
{
return false;
}
}
}
@Override
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
if (!plugin.al.isAdmin(sender))
{
return Collections.emptyList();
}
List<String> singleArguments = Arrays.asList("clearips", "setscformat", "setacformat");
List<String> doubleArguments = Arrays.asList("clearip", "clearscformat", "clearacformat", "syncroles");
if (args.length == 1)
{
List<String> options = new ArrayList<>();
options.add("-o");
options.addAll(singleArguments);
options.addAll(doubleArguments);
return options;
} else if (args.length == 2)
{
if (args[0].equalsIgnoreCase("-o"))
{
return FUtil.getPlayerList();
} else
{
if (doubleArguments.contains(args[0]) && args[0].equalsIgnoreCase("clearip"))
{
List<String> ips = plugin.al.getAdmin(sender).getIps();
ips.remove(FUtil.getIp((Player) sender));
return ips;
}
}
} else if (args.length == 3 && args[0].equalsIgnoreCase("-o"))
{
List<String> options = new ArrayList<>();
options.addAll(singleArguments);
options.addAll(doubleArguments);
return options;
} else if (args.length == 4 && args[0].equalsIgnoreCase("-o") && args[2].equalsIgnoreCase("clearip"))
{
Admin admin = plugin.al.getEntryByName(args[1]);
if (admin != null)
{
return admin.getIps();
}
}
return FUtil.getPlayerList();
}
}

View File

@ -1,159 +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.util.FUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@CommandPermissions(permission = "nickclean", source = SourceType.BOTH)
@CommandParameters(description = "Essentials Interface Command - Remove illegal chatcodes from nicknames of one or all players on server.", usage = "/<command> [player]", aliases = "nc")
public class Command_nickclean extends FreedomCommand
{
private static final Map<String, Color> colorCodes = populateHashMap();
private static Map<String, Color> populateHashMap()
{
Map<String, Color> colorCodes = new HashMap<>();
colorCodes.put("&0", Color.BLACK);
colorCodes.put("&1", Color.BLUE);
colorCodes.put("&2", Color.GREEN);
colorCodes.put("&3", Color.TEAL);
colorCodes.put("&4", Color.MAROON);
colorCodes.put("&5", Color.FUCHSIA);
colorCodes.put("&6", Color.OLIVE);
colorCodes.put("&7", Color.SILVER);
colorCodes.put("&8", Color.GRAY);
colorCodes.put("&9", Color.NAVY);
colorCodes.put("&a", Color.LIME);
colorCodes.put("&b", Color.AQUA);
colorCodes.put("&c", Color.RED);
colorCodes.put("&d", Color.PURPLE);
colorCodes.put("&e", Color.YELLOW);
colorCodes.put("&f", Color.WHITE);
return colorCodes;
}
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length > 1)
{
Player player = getPlayer(args[0]);
if (player == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
FUtil.adminAction(sender.getName(), "Cleaning " + player.getName() + "'s nickname", false);
cleanNickname(player);
return true;
}
FUtil.adminAction(sender.getName(), "Cleaning all nicknames", false);
for (final Player player : server.getOnlinePlayers())
{
cleanNickname(player);
}
return true;
}
public void cleanNickname(Player player)
{
final String playerName = player.getName();
final String nickName = plugin.esb.getNickname(playerName);
StringBuilder newNick = new StringBuilder();
boolean nickChanged = false;
if (nickName != null)
{
if (nickName.contains("§x"))
{
// Detects colors that are similar to blocked codes.
spliterator:
for (String split : nickName.split("§x"))
{
List<Color> colors = new ArrayList<>();
String hexColorSub;
if (split.length() >= 12 && split.contains("§"))
{
hexColorSub = split.substring(0, 12);
split = String.valueOf(split.charAt(12));
String hexColorString = "#" + hexColorSub.replace("§", "");
java.awt.Color hexColor = java.awt.Color.decode(hexColorString);
// Get a range of nearby colors that are alike to the color blocked.
Color colorFirst;
Color colorSecond;
colorFirst = Color.fromRGB(Math.min(hexColor.getRed() + 20, 255), Math.min(hexColor.getGreen() + 20, 255), Math.min(hexColor.getBlue() + 20, 255));
colorSecond = Color.fromRGB(Math.max(hexColor.getRed() - 20, 0), Math.max(hexColor.getGreen() - 20, 0), Math.max(hexColor.getBlue() - 20, 0));
colors.addAll(FUtil.createColorGradient(colorFirst, colorSecond, 40));
colorFirst = Color.fromRGB(Math.min(hexColor.getRed() + 20, 255), Math.min(hexColor.getGreen(), 255), Math.min(hexColor.getBlue(), 255));
colorSecond = Color.fromRGB(Math.max(hexColor.getRed() - 20, 0), Math.max(hexColor.getGreen(), 0), Math.max(hexColor.getBlue(), 0));
colors.addAll(FUtil.createColorGradient(colorFirst, colorSecond, 40));
colorFirst = Color.fromRGB(Math.min(hexColor.getRed(), 255), Math.min(hexColor.getGreen() + 20, 255), Math.min(hexColor.getBlue(), 255));
colorSecond = Color.fromRGB(Math.max(hexColor.getRed(), 0), Math.max(hexColor.getGreen() - 20, 0), Math.max(hexColor.getBlue(), 0));
colors.addAll(FUtil.createColorGradient(colorFirst, colorSecond, 40));
colorFirst = Color.fromRGB(Math.min(hexColor.getRed(), 255), Math.min(hexColor.getGreen(), 255), Math.min(hexColor.getBlue() + 20, 255));
colorSecond = Color.fromRGB(Math.max(hexColor.getRed(), 0), Math.max(hexColor.getGreen(), 0), Math.max(hexColor.getBlue() - 20, 0));
colors.addAll(FUtil.createColorGradient(colorFirst, colorSecond, 40));
for (String colorCode : ConfigEntry.BLOCKED_CHATCODES.getString().split(","))
{
// Makes sure that there's hex colors in the split.
for (Color color : colors)
{
if (colorCodes.get(colorCode) != null && FUtil.colorClose(color, colorCodes.get(colorCode), 40))
{
nickChanged = true;
newNick.append(split);
continue spliterator;
}
}
}
newNick.append("§x").append(hexColorSub).append(split);
}
}
} else
{
// Falls back on old code if hex isn't used.
final Pattern REGEX = Pattern.compile(FUtil.colorize(ChatColor.COLOR_CHAR + "[" + StringUtils.join(ConfigEntry.BLOCKED_CHATCODES.getString().split(","), "") + "]"), Pattern.CASE_INSENSITIVE);
if (!nickName.isEmpty() && !nickName.equalsIgnoreCase(playerName))
{
final Matcher matcher = REGEX.matcher(nickName);
if (matcher.find())
{
nickChanged = true;
newNick.append(matcher.replaceAll(""));
}
}
}
}
if (nickChanged)
{
msg(ChatColor.RESET + playerName + ": \"" + nickName + ChatColor.RESET + "\" -> \"" + newNick.toString() + ChatColor.RESET + "\".");
}
plugin.esb.setNickname(playerName, newNick.toString());
}
}

View File

@ -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;
}
}

View File

@ -1,140 +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 me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.ArrayUtils;
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.List;
@CommandPermissions(permission = "notes", source = SourceType.BOTH)
@CommandParameters(description = "Manage notes for a player", usage = "/<command> <name> <list | add <note> | remove <id> | clear>")
public class Command_notes extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 2)
{
return false;
}
PlayerData playerData;
final Player player = getPlayer(args[0]);
if (player == null)
{
final PlayerData entry = plugin.pl.getData(args[0]);
if (entry == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
playerData = plugin.pl.getData(entry.getName());
} else
{
playerData = plugin.pl.getData(player);
}
switch (args[1])
{
case "list" ->
{
msgNew("<green>Player notes for <player>:", Placeholder.unparsed("player", playerData.getName()));
int id = 1;
for (String note : playerData.getNotes())
{
String a = note.replace("\\u002C", ",");
msgNew("<num>. <note>",
Placeholder.unparsed("num", String.valueOf(id)),
Placeholder.unparsed("note", a));
id++;
}
return true;
}
case "add" ->
{
if (args.length < 3)
{
return false;
}
String note = sender.getName() + ": " + StringUtils.join(ArrayUtils.subarray(args, 2, args.length), " ")
.replace(",", "\\u002C");
playerData.addNote(note);
plugin.pl.save(playerData);
msgNew("<green>Note added.");
return true;
}
case "remove" ->
{
if (args.length < 3)
{
return false;
}
int id;
try
{
id = Integer.parseInt(args[2]);
} catch (NumberFormatException e)
{
msgNew("<red>Invalid number: <num>", Placeholder.unparsed("num", args[2]));
return true;
}
id--;
if (playerData.removeNote(id))
{
plugin.pl.save(playerData);
msgNew("<green>Note removed.");
} else
{
msgNew("<red>No note with the ID of <id> exists.", Placeholder.unparsed("id", args[2]));
}
return true;
}
case "clear" ->
{
int count = playerData.getNotes().size();
playerData.clearNotes();
plugin.pl.save(playerData);
msgNew("<green>Cleared <count> notes.", Placeholder.unparsed("count", String.valueOf(count)));
return true;
}
default ->
{
return false;
}
}
}
@Override
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
if (args.length == 1)
{
return FUtil.getPlayerList();
} else if (args.length == 2)
{
return Arrays.asList("list", "add", "remove", "clear");
} else if (args.length > 2 && (args[1].equals("add")))
{
return FUtil.getPlayerList();
}
return Collections.emptyList();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -1,160 +0,0 @@
package me.totalfreedom.totalfreedommod.command;
import com.earth2me.essentials.User;
import me.totalfreedom.totalfreedommod.banning.Ban;
import me.totalfreedom.totalfreedommod.command.handling.*;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
@Intercept("tempban")
@CommandPermissions(permission = "tempban", source = SourceType.BOTH)
@CommandParameters(description = "Temporarily ban someone.", usage = "/<command> [-q] <username> [duration] [reason]", aliases = "tban,noob")
public class Command_tempban extends FreedomCommand
{
private static final SimpleDateFormat date_format = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 1)
{
return false;
}
boolean quiet = args[0].equalsIgnoreCase("-q");
if (quiet)
{
args = org.apache.commons.lang3.ArrayUtils.subarray(args, 1, args.length);
if (args.length < 1)
{
return false;
}
}
final String username;
final String ip;
final Player player = getPlayer(args[0]);
PlayerData entry;
if (player == null)
{
// 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();
}
// Last resort - Getting the first result from the username itself
else
{
entry = plugin.pl.getData(args[0]);
if (entry == null)
{
msg(PLAYER_NOT_FOUND);
return true;
} else
{
username = entry.getName();
ip = entry.getIps().get(0);
}
}
} else
{
username = player.getName();
ip = FUtil.getIp(player);
}
final StringBuilder message = new StringBuilder("Temporarily banned " + username);
// Default expiration date is 5 minutes
Date expires = FUtil.parseDateOffset("5m");
// Parses what comes after as a duration
if (args.length > 1)
{
try
{
expires = FUtil.parseDateOffset(args[1]);
} catch (NumberFormatException error)
{
msg("Invalid duration: " + args[1], ChatColor.RED);
return true;
}
}
message.append(" until ").append(date_format.format(expires));
// If a reason appears to exist, set it.
String reason = null;
if (args.length > 2)
{
reason = StringUtils.join(ArrayUtils.subarray(args, 2, args.length), " ") + " (" + sender.getName() + ")";
message.append(", Reason: \"").append(reason).append("\"");
}
Ban ban;
if (player != null)
{
ban = Ban.forPlayer(player, sender, expires, reason);
} else
{
ban = Ban.forPlayerName(username, sender, expires, reason);
}
ban.addIp(ip);
plugin.bm.addBan(ban);
if (!quiet)
{
if (player != null)
{
// Strike with lightning
final Location targetPos = player.getLocation();
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
final Location strike_pos = new Location(targetPos.getWorld(), targetPos.getBlockX() + x, targetPos.getBlockY(), targetPos.getBlockZ() + z);
Objects.requireNonNull(targetPos.getWorld()).strikeLightningEffect(strike_pos);
}
}
player.kickPlayer(ban.bakeKickMessage());
}
FUtil.adminAction(sender.getName(), message.toString(), true);
} else
{
msg("Quietly temporarily banned " + username + ".");
}
for (Player p : Bukkit.getOnlinePlayers())
{
if (FUtil.getIp(p).equals(ip))
{
p.kickPlayer(ChatColor.RED + "You've been kicked because someone on your IP has been banned.");
}
}
plugin.pul.logPunishment(new Punishment(username, ip, sender.getName(), PunishmentType.TEMPBAN, reason));
return true;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -1,108 +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.util.FUtil;
import me.totalfreedom.totalfreedommod.util.Groups;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Objects;
@CommandPermissions(permission = "tossmob", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Throw a mob in the direction you are facing when you right click with a bone.",
usage = "/<command> <mobtype [speed] | off | list>")
public class Command_tossmob extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!ConfigEntry.TOSSMOB_ENABLED.getBoolean())
{
msgNew("<red>Tossmob is currently disabled.");
return true;
}
if (args.length == 0)
{
return false;
}
FPlayer playerData = plugin.pl.getPlayer(playerSender);
EntityType type = null;
if (args[0].equalsIgnoreCase("off"))
{
playerData.disableMobThrower();
msgNew("<green>Tossmob has been turned off.");
return true;
}
if (args[0].equalsIgnoreCase("list"))
{
msgNew("<green>Supported mobs: <mobs>", Placeholder.unparsed("mobs", String.join(", ", Groups.MOB_TYPES.stream().map(Enum::name).toList())));
return true;
}
for (EntityType loop : EntityType.values())
{
if (loop != null && loop.name().equalsIgnoreCase(args[0]))
{
type = loop;
break;
}
}
if (type == null)
{
msgNew("<red>Unknown entity type: <type>", Placeholder.unparsed("type", args[0]));
return true;
}
if (!Groups.MOB_TYPES.contains(type))
{
msgNew("<red><entity> is an entity, however it is not a mob.", Placeholder.unparsed("entity", FUtil.formatName(type.name())));
return true;
}
double speed = 1.0;
if (args.length >= 2)
{
try
{
speed = Double.parseDouble(args[1]);
} catch (NumberFormatException ex)
{
msgNew("<red>Invalid speed: <speed>", Placeholder.unparsed("speed", args[1]));
return true;
}
}
if (speed < 1.0)
{
speed = 1.0;
} else if (speed > 5.0)
{
speed = 5.0;
}
playerData.enableMobThrower(type, speed);
msgNew("<green>Tossmob is enabled. Mob: <type> - Speed: <speed>.",
Placeholder.unparsed("type", String.valueOf(type)),
Placeholder.unparsed("speed", String.valueOf(speed)));
msgNew("<green>Right click while holding a Bone to throw mobs!");
msgNew("<green>Type '/tossmob off' to disable. - By Madgeek1450");
Objects.requireNonNull(playerSender.getEquipment()).setItemInMainHand(new ItemStack(Material.BONE, 1));
return true;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,78 +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.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Intercept("warn")
@CommandPermissions(permission = "warn", source = SourceType.BOTH)
@CommandParameters(description = "Warns the specified player.", usage = "/<command> [-q] <player> <reason>")
public class Command_warn extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length == 0)
{
return false;
}
boolean quiet = args[0].equalsIgnoreCase("-q");
if (quiet)
{
args = org.apache.commons.lang3.ArrayUtils.subarray(args, 1, args.length);
if (args.length < 1)
{
return false;
}
}
Player player = getPlayer(args[0]);
if (player == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
if (playerSender == player)
{
msgNew("<red>Please, don't try to warn yourself.");
return true;
}
if (plugin.al.isAdmin(player))
{
msgNew("<red>You can't warn other admins!");
return true;
}
String warnReason = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " ");
FUtil.playerTitle(player, "<red>You have been warned.", "<yellow>Reason: <reason>", Placeholder.unparsed("reason", warnReason));
msgNew("<red>[WARNING] You received a warning from <sender>: <reason>", Placeholder.unparsed("sender", sender.getName()), Placeholder.unparsed("reason", warnReason));
plugin.pl.getPlayer(player).incrementWarnings(quiet);
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.WARN, warnReason));
if (quiet)
{
msgNew("You have successfully warned <player> quietly.", Placeholder.unparsed("player", player.getName()));
} else
{
plugin.cm.messageAllAdmins("<red><sender> - Warning: <player> - Reason: <yellow><reason> ",
Placeholder.unparsed("sender", sender.getName()),
Placeholder.unparsed("player", player.getName()),
Placeholder.unparsed("reason", warnReason));
msgNew("You have successfully warned <player>.", Placeholder.unparsed("player", player.getName()));
}
return true;
}
}

View File

@ -1,78 +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.apache.commons.lang.StringUtils;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "whohas", source = SourceType.BOTH)
@CommandParameters(description = "See who has an item and optionally clear the specified item.", usage = "/<command> <item> [clear]", aliases = "wh")
public class Command_whohas extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 1)
{
return false;
}
final boolean doClear = args.length >= 2 && "clear".equalsIgnoreCase(args[1]);
final String materialName = args[0];
Material material = Material.matchMaterial(materialName);
if (material == null)
{
msgNew("<red>Invalid item: <type>", Placeholder.unparsed("type", materialName));
return true;
}
List<? extends Player> players = server.getOnlinePlayers().stream().filter(player -> player.getInventory().contains(material) &&
(!plugin.al.isVanished(player.getUniqueId()) || plugin.al.isAdmin(sender))).toList();
if (plugin.al.isAdmin(sender) && doClear)
{
players.stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
player.getInventory().remove(material));
}
if (players.isEmpty())
{
msgNew("There are no players with that item.");
} else
{
msgNew("Players with item <type>: <players>", Placeholder.unparsed("type", material.name()),
Placeholder.unparsed("players", StringUtils.join(players.stream().map(HumanEntity::getName).toList(), ", ")));
}
return true;
}
@Override
public List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
if (args.length == 1)
{
return Arrays.stream(Material.values()).map(Enum::name).toList();
}
if (args.length == 2 && plugin.al.isAdmin(sender))
{
return Collections.singletonList("clear");
}
return Collections.emptyList();
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -1,495 +0,0 @@
package me.totalfreedom.totalfreedommod.command.handling;
import com.earth2me.essentials.commands.PlayerNotFoundException;
import com.google.common.collect.Lists;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import me.totalfreedom.totalfreedommod.util.PermissibleCompletion;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
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.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.AnnotationFormatError;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public abstract class FreedomCommand implements CommandExecutor, TabCompleter
{
public static final String COMMAND_PREFIX = "Command_";
public static final Component YOU_ARE_OP = Component.text("You are now op!", NamedTextColor.YELLOW);
public static final Component YOU_ARE_NOT_OP = Component.text("You are no longer op!", NamedTextColor.YELLOW);
public static final Component PLAYER_NOT_FOUND = Component.text("Player not found!", NamedTextColor.GRAY);
public static final String ONLY_CONSOLE = ChatColor.RED + "Only console senders may execute this command!";
public static final String ONLY_IN_GAME = ChatColor.RED + "Only in-game players may execute this command!";
public static final String NO_PERMISSION = ChatColor.RED + "You do not have permission to execute this command.";
public static final Timer timer = new Timer();
protected static final Map<CommandSender, FreedomCommand> COOLDOWN_TIMERS = new HashMap<>();
protected final TotalFreedomMod plugin = TotalFreedomMod.getPlugin();
protected final Server server = plugin.getServer();
private final String name;
private final String description;
private final String usage;
private final String aliases;
private final String permission;
private final SourceType source;
private final boolean blockHostConsole;
private final int cooldown;
private final CommandParameters params;
private final CommandPermissions perms;
protected CommandSender sender;
protected FreedomCommand()
{
if (getClass().getAnnotation(CommandParameters.class) == null ||
getClass().getAnnotation(CommandPermissions.class) == null)
{
throw new AnnotationFormatError("Command class " + getClass().getName() + " is missing a required annotation!");
} // Safety first!
params = getClass().getAnnotation(CommandParameters.class);
perms = getClass().getAnnotation(CommandPermissions.class);
this.name = getClass().getSimpleName().replace(COMMAND_PREFIX, "").toLowerCase();
this.description = params.description();
this.usage = params.usage();
this.aliases = params.aliases();
this.source = perms.source();
this.blockHostConsole = perms.blockHostConsole();
this.cooldown = perms.cooldown();
this.permission = "tfm." + perms.permission();
}
public static FreedomCommand getFrom(Command command)
{
try
{
if (command instanceof FCommand cmd)
{
return cmd.getExecutor();
}
} catch (Exception ex)
{
FLog.severe(ex);
return null;
}
return null;
}
public void register()
{
FCommand cmd = new FCommand(this.name);
if (this.aliases != null)
{
cmd.setAliases(Arrays.asList(StringUtils.split(this.aliases, ",")));
}
if (this.description != null)
{
cmd.setDescription(this.description);
}
if (this.usage != null)
{
cmd.setUsage(this.usage);
}
if (this.permission != null)
{
cmd.setPermission(this.permission);
}
server.getCommandMap().register("totalfreedommod", cmd);
CompletableFuture.runAsync(() -> server.getCommandMap().register("totalfreedommod", cmd))
.whenComplete((v, th) ->
{
if (th != null)
{
FLog.severe(th);
return;
}
PluginCommand pluginCommand = server.getPluginCommand(cmd.getName());
if (pluginCommand != null)
{
pluginCommand.setExecutor(this);
pluginCommand.setTabCompleter(this);
}
cmd.setExecutor(this);
});
}
protected void msg(CommandSender sender, Component message)
{
sender.sendMessage(message.colorIfAbsent(NamedTextColor.GRAY));
}
protected void msg(Component message)
{
msg(sender, message);
}
@Deprecated
protected void msg(CommandSender sender, String message)
{
sender.sendMessage(ChatColor.GRAY + message);
}
@Deprecated
protected void msg(String message)
{
msg(sender, message);
}
protected void msgNew(CommandSender sender, String message, TagResolver... placeholders)
{
sender.sendMessage(FUtil.miniMessage("<gray>" + message, placeholders));
}
protected void msgNew(String message, TagResolver... placeholders)
{
msgNew(sender, message, placeholders);
}
@Deprecated
protected void msg(String message, ChatColor color)
{
msg(color + message);
}
protected List<String> argumentCompletions(String arg, PermissibleCompletion... completions)
{
return Arrays.stream(completions)
.filter(permissibleCompletion -> sender.hasPermission(permissibleCompletion.getPermission())) //Permission
.map(PermissibleCompletion::getCompletion)
.filter(completion -> completion.startsWith(arg))
.toList();
}
protected List<String> playerCompletions(String arg)
{
return Bukkit.getOnlinePlayers()
.stream()
.map(Player::getName)
.filter(c -> c.startsWith(arg))
.toList();
}
protected boolean isAdmin(Player player)
{
return plugin.al.isAdmin(player);
}
protected boolean isAdmin(CommandSender sender)
{
return plugin.al.isAdmin(sender);
}
@NotNull
public TagResolver.Single player(Player player)
{
return Placeholder.unparsed("player", player.getName());
}
@NotNull
public TagResolver.Single sender(CommandSender sender)
{
return Placeholder.unparsed("sender", sender.getName());
}
@NotNull
public TagResolver.Single usage()
{
return Placeholder.unparsed("usage", this.getUsage().replace("<command>", this.getName().toLowerCase()));
}
protected void checkConsole()
{
if (!isConsole())
{
throw new CommandFailException(ONLY_CONSOLE);
}
}
protected void checkPlayer()
{
if (isConsole())
{
throw new CommandFailException(ONLY_IN_GAME);
}
}
protected void checkPermission(String permission)
{
if (!sender.hasPermission(permission))
{
noPerms();
}
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String commandLabel, @NotNull String[] args)
{
try
{
boolean run = run(sender, sender instanceof ConsoleCommandSender ? null : (Player) sender, cmd, commandLabel, args, sender instanceof ConsoleCommandSender);
if (!run)
{
msg(ChatColor.WHITE + cmd.getUsage().replace("<command>", cmd.getLabel()));
return true;
}
} catch (CommandFailException ex)
{
msg(ChatColor.RED + ex.getMessage());
}
return false;
}
@NotNull
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args)
{
List<String> options = getTabCompleteOptions(sender, command, alias, args);
if (options == null)
{
return new ArrayList<>();
}
return StringUtil.copyPartialMatches(args[args.length - 1], options, Lists.newArrayList());
}
public abstract boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole);
protected TagResolver.Single arg(String arg)
{
return Placeholder.unparsed("arg", arg);
}
protected List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
return FUtil.getPlayerList();
}
protected boolean isConsole()
{
return sender instanceof ConsoleCommandSender;
}
protected Player getPlayer(String name)
{
return Bukkit.getPlayer(name);
}
protected Player getPlayer(String name, Boolean nullVanished)
{
Player player = Bukkit.getPlayer(name);
if (player != null && nullVanished && plugin.al.isVanished(player.getUniqueId()) && !plugin.al.isAdmin(sender))
{
return null;
}
return player;
}
@NotNull
@Contract("null -> fail")
protected OfflinePlayer getOfflinePlayer(String name) throws PlayerNotFoundException
{
return Arrays.stream(Bukkit.getOfflinePlayers())
.filter(player -> player.getName() != null)
.filter(player -> player.getName().equalsIgnoreCase(name))
.findFirst()
.orElseThrow(PlayerNotFoundException::new);
}
protected Admin getAdmin(CommandSender sender)
{
return plugin.al.getAdmin(sender);
}
protected Admin getAdmin(Player player)
{
return plugin.al.getAdmin(player);
}
protected PlayerData getData(Player player)
{
return plugin.pl.getData(player);
}
protected boolean noPerms()
{
throw new CommandFailException(NO_PERMISSION);
}
public String getName()
{
return name;
}
public String getDescription()
{
return description;
}
public String getUsage()
{
return usage;
}
public String getAliases()
{
return aliases;
}
public String getPermission()
{
return permission;
}
public SourceType getSource()
{
return source;
}
public boolean isBlockHostConsole()
{
return blockHostConsole;
}
public final class FCommand extends Command implements PluginIdentifiableCommand
{
private FreedomCommand cmd = null;
private FCommand(String command)
{
super(command);
}
public FreedomCommand getExecutor()
{
return cmd;
}
public void setExecutor(FreedomCommand cmd)
{
this.cmd = cmd;
}
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, String[] args)
{
if (cmd == null)
{
msgNew(sender, "<gray><usage>", usage());
return false;
} // Reduce complexity! Exit immediately if the command is null.
cmd.sender = sender;
if (checkCommandSource())
{
return true;
}
if (permissionCheck())
{
return true;
}
if (cooldownCheck())
{
return true;
}
assignApplicableCooldown();
return cmd.onCommand(sender, this, commandLabel, args);
}
public boolean checkCommandSource()
{
if (perms.source() == SourceType.ONLY_CONSOLE && sender instanceof Player)
{
msg(ONLY_CONSOLE);
return true;
}
if (perms.source() == SourceType.ONLY_IN_GAME && sender instanceof ConsoleCommandSender)
{
msg(ONLY_IN_GAME);
return true;
}
return false;
}
public boolean permissionCheck()
{
if (!sender.hasPermission(permission) || !source.permissionCheck(sender))
{
msg(ChatColor.RED + "You do not have permission to use this command.");
return true;
}
if (perms.blockHostConsole() && FUtil.isFromHostConsole(sender.getName()) && !FUtil.inDeveloperMode())
{
msg(ChatColor.RED + "Host console is not allowed to use this command!");
return true;
}
return false;
}
public void assignApplicableCooldown()
{
if (perms.cooldown() != 0 && !isAdmin(sender))
{
COOLDOWN_TIMERS.put(sender, cmd);
timer.schedule(new TimerTask()
{
@Override
public void run()
{
COOLDOWN_TIMERS.remove(sender);
}
}, perms.cooldown() * 1000L);
}
}
public boolean cooldownCheck()
{
if (COOLDOWN_TIMERS.containsKey(sender) && COOLDOWN_TIMERS.containsValue(cmd))
{
msg(ChatColor.RED + "You are on cooldown for this command.");
return true;
}
return false;
}
@NotNull
@Override
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, String[] args)
{
if (cmd != null)
{
return cmd.onTabComplete(sender, this, alias, args);
}
return new ArrayList<>();
}
@Override
public @NotNull Plugin getPlugin()
{
return plugin;
}
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}
}

Some files were not shown because too many files have changed in this diff Show More