Update to 1.17

As a consequence, TFM is now behind AMG
This commit is contained in:
Telesphoreo 2021-09-29 18:11:22 -05:00
commit cfd197b14d
95 changed files with 2736 additions and 1408 deletions

15
.github/workflows/gradle.yml vendored Normal file
View file

@ -0,0 +1,15 @@
name: Gradle-Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 16
uses: actions/setup-java@v1
with:
java-version: 16
- name: Build with Gradle
run: chmod a+x gradlew && ./gradlew build -x buildProperties

2
.gitignore vendored
View file

@ -31,6 +31,8 @@ manifest.mf
# Maven excludes
/target
/.gradle
# OS generated files
.DS_Store
._*

13
.travis.yml Normal file
View file

@ -0,0 +1,13 @@
language: java
jdk:
- oraclejdk11
- openjdk11
notifications:
email: false
addons:
apt:
packages:
- sshpass
script: mvn clean install
after_success:
- ./travis-upload.sh

View file

@ -1,4 +1,4 @@
# TotalFreedomMod [![Maven-Build](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/maven.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/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://github.com/StevenNL2000Freedom/TotalFreedomMod/actions/workflows/gradle.yml/badge.svg)
TotalFreedomMod is a CraftBukkit server plugin designed primarily to support the [Official TotalFreedom Minecraft Server](https://totalfreedom.me/). However, you are more than welcome to adapt the source for your own server.
@ -14,4 +14,4 @@ For information on our security policy and reporting an issue, please see [SECUR
### Compiling
You need Maven to build. You'd also need to set the JDK version to Java 11 as that is the current standard as of now.
You need Maven to build. You'd also need to set the JDK version to Java 8 as that is the current standard as of now.

38
SECURITY.md Normal file
View file

@ -0,0 +1,38 @@
# 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: |
| ------------------- | ------------------ | ------------------------------ |
| 2021.05 | :white_check_mark: | No Earlier than August 2021 |
### Legacy Supported
These versions are no longer under active development, however we will look to release critical secuirty patches where appropriate.
| Version | Supported | Support End: |
| ------------------- | ------------------ | ------------ |
| 2021.04 | :white_check_mark: | July 2021 |
### No Longer Supported
These versions are no longer supported at all. It is strongly advised to update if you are running any of these versions.
| Version | Supported | Support Ended: |
| ------------------- | ------------------ | ------------------- |
| 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.

175
build.gradle Normal file
View file

@ -0,0 +1,175 @@
plugins {
id 'java'
id 'maven-publish'
id 'idea'
id 'com.github.johnrengelman.shadow' version '7.0.0'
id 'net.minecrell.plugin-yml.bukkit' version '0.4.0'
}
repositories {
mavenLocal()
gradlePluginPortal()
maven {
url = uri('https://jitpack.io')
}
maven {
url = uri('https://repo.codemc.org/repository/maven-public/')
}
maven {
url = uri('https://repo.codemc.org/repository/nms/')
}
maven {
url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/')
}
maven {
url = uri('https://maven.enginehub.org/repo/')
}
maven {
url = uri('https://maven.elmakers.com/repository/')
}
maven {
url = uri('https://m2.dv8tion.net/releases/')
}
maven {
url = uri('https://maven.playpro.com/')
}
maven {
url = uri('https://repo.md-5.net/content/groups/public/')
}
maven {
url = uri('https://repo.dmulloy2.net/nexus/repository/public/')
}
maven {
url = uri('https://papermc.io/repo/repository/maven-public/')
}
maven {
url = uri('https://ci.ender.zone/plugin/repository/everything/')
}
maven {
url = uri('https://repo.mattmalec.com/repository/releases')
}
}
dependencies {
implementation('commons-io:commons-io:2.8.0')
implementation('org.apache.commons:commons-lang3:3.11')
implementation('commons-codec:commons-codec:1.15')
implementation('com.github.speedxx:Mojangson:1957eef8d6')
implementation('io.papermc:paperlib:1.0.6')
implementation('org.reflections:reflections:0.9.12')
implementation('org.javassist:javassist:3.28.0-GA')
implementation('org.jetbrains:annotations:21.0.1')
implementation('com.mattmalec:Pterodactyl4J:2.BETA_49')
implementation('org.junit.jupiter:junit-jupiter:5.7.2')
implementation('org.projectlombok:lombok:1.18.20')
compileOnly('org.spigotmc:spigot:1.17-R0.1-SNAPSHOT')
compileOnly('com.github.TotalFreedomMC:BukkitTelnet:541e9fdb84')
compileOnly('com.github.TotalFreedomMC:TF-LibsDisguises:48f01cf2fe')
compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.3.0-SNAPSHOT')
compileOnly('net.ess3:EssentialsX:2.18.2')
compileOnly('net.dv8tion:JDA:4.3.0_277')
compileOnly('net.coreprotect:coreprotect:19.5')
compileOnly('com.sk89q.worldguard:worldguard-bukkit:7.0.5')
compileOnly('com.github.vexsoftware:votifier:v1.9')
compileOnly('net.goldtreeservers:worldguardextraflags:4.0.0')
compileOnly('com.github.AtlasMediaGroup:TFGuilds:master-SNAPSHOT')
}
group = 'me.totalfreedom'
version = project.property('project.pluginVersion')
description = 'TotalFreedomMod'
java.sourceCompatibility = JavaVersion.VERSION_16
archivesBaseName = 'TotalFreedomMod-donotuse'
bukkit {
main = 'me.totalfreedom.totalfreedommod.TotalFreedomMod'
apiVersion = '1.17'
version = project.property('project.pluginVersion')
description = 'Plugin for the Total Freedom server.'
authors = ['Madgeek1450', 'Prozza']
softDepend = ['BukkitTelnet', 'Essentials', 'CoreProtect', 'LibsDisguises', 'WorldEdit',
'WorldGuard', 'WorldGuardExtraFlags', 'TFGuilds', 'JDA', 'Votifier']
}
static def getDate() {
return new Date().format('MM/dd/yyyy HH:mm')
}
def getGitHash() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
def getBuildNumber()
{
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', 'HEAD', '--count'
standardOutput = stdout
}
return stdout.toString().trim()
}
task buildProperties {
ant.propertyfile(file: "$project.rootDir/src/main/resources/build.properties") {
entry(key: "buildAuthor", default: "unknown")
entry(key: "buildNumber", value: getBuildNumber())
entry(key: "buildDate", value: getDate())
entry(key: "buildCodeName", value: project.property('project.buildCodeName'))
entry(key: "buildHead", value: getGitHash())
}
}
shadowJar {
shadowJar {
archiveBaseName.set('TotalFreedomMod')
archiveClassifier.set('')
archiveVersion.set('')
}
minimize()
dependencies {
include(dependency('commons-io:commons-io'))
include(dependency('org.apache.commons:commons-lang3'))
include(dependency('commons-codec:commons-codec'))
include(dependency('org.javassist:javassist'))
include(dependency('io.papermc:paperlib'))
include(dependency('org.reflections:reflections'))
include(dependency('com.github.speedxx:Mojangson'))
include(dependency('org.jetbrains:annotations'))
include(dependency('com.mattmalec:Pterodactyl4J'))
}
relocate 'org.bstats', 'me.totalfreedom.totalfreedommod'
relocate 'io.papermc.lib', 'me.totalfreedom.totalfreedommod.paperlib'
}
tasks.compileJava.finalizedBy tasks.buildProperties
tasks.build.dependsOn tasks.shadowJar
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

8
gradle.properties Normal file
View file

@ -0,0 +1,8 @@
project.pluginVersion = 7.0.0
project.buildAuthor = unknown
project.buildCodeName = Ember
org.gradle.cache=true
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.jvmargs='-Dfile.encoding=UTF-8'

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View file

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View file

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

90
pom.xml
View file

@ -5,12 +5,12 @@
<groupId>me.totalfreedom</groupId>
<artifactId>TotalFreedomMod</artifactId>
<version>2021.06</version>
<version>6.1.3</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tfm.build.codename>Phoenix</tfm.build.codename>
<tfm.build.codename>Ember</tfm.build.codename>
<jar.finalName>${project.name}</jar.finalName>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>MM/dd/yyyy HH:mm</maven.build.timestamp.format>
@ -18,7 +18,7 @@
<name>TotalFreedomMod</name>
<description>Server modification for the TotalFreedom server</description>
<url>https://github.com/AtlasMediaGroup/TotalFreedomMod</url>
<url>https://github.com/StevenNL2000Freedom/TotalFreedomMod</url>
<licenses>
<license>
@ -33,12 +33,17 @@
</organization>
<scm>
<connection>scm:git:git@github.com:TFPatches/TotalFreedomMod.git</connection>
<developerConnection>scm:git:git@github.com:TFPatches/TotalFreedomMod.git</developerConnection>
<url>git@github.com:TFPatches/TotalFreedomMod.git</url>
<connection>scm:git:git@github.com:StevenNL2000Freedom/TotalFreedomMod.git</connection>
<developerConnection>scm:git:git@github.com:StevenNL2000Freedom/TotalFreedomMod.git</developerConnection>
<url>git@github.com:StevenNL2000Freedom/TotalFreedomMod.git</url>
</scm>
<repositories>
<repository>
<id>apache-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
@ -109,6 +114,11 @@
<id>ess-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
<repository>
<id>mattmalec-repo</id>
<url>https://repo.mattmalec.com/repository/releases</url>
</repository>
</repositories>
<dependencies>
@ -141,17 +151,10 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>1.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@ -163,9 +166,9 @@
</dependency>
<dependency>
<groupId>com.github.AtlasMediaGroup</groupId>
<groupId>com.github.TotalFreedomMC</groupId>
<artifactId>TF-LibsDisguises</artifactId>
<version>5a340341b0</version>
<version>48f01cf2fe</version>
<scope>provided</scope>
</dependency>
@ -186,21 +189,21 @@
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>4.2.1_255</version>
<version>4.3.0_277</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.coreprotect</groupId>
<artifactId>coreprotect</artifactId>
<version>19.3</version>
<version>19.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.4</version>
<version>7.0.5</version>
<scope>provided</scope>
</dependency>
@ -235,7 +238,7 @@
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.27.0-GA</version>
<version>3.28.0-GA</version>
<scope>compile</scope>
</dependency>
@ -246,29 +249,53 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>20.1.0</version>
<version>21.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<version>3.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<version>5.7.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.inject</artifactId>
<version>0.3.4</version>
<scope>compile</scope>
</dependency>
<!-- Note that this requires JSON, it is now in JDA since you need JDA to use Pterodactyl in the first place -->
<dependency>
<groupId>com.mattmalec</groupId>
<artifactId>Pterodactyl4J</artifactId>
<version>2.BETA_49</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
@ -289,9 +316,9 @@
<version>3.8.1</version>
<configuration>
<outputFileName>TotalFreedomMod.jar</outputFileName>
<compilerVersion>11</compilerVersion>
<source>11</source>
<target>11</target>
<compilerVersion>16</compilerVersion>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
@ -299,7 +326,7 @@
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.0.2</version>
<version>4.0.5</version>
<executions>
<execution>
<id>get-the-git-infos</id>
@ -415,7 +442,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<version>3.3.0-SNAPSHOT</version>
<executions>
<execution>
<phase>package</phase>
@ -427,8 +454,7 @@
<relocations>
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib
</shadedPattern> <!-- Replace this -->
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
@ -444,8 +470,8 @@
<include>org.javassist:javassist</include>
<include>io.papermc:paperlib</include>
<include>com.github.speedxx:Mojangson</include>
<include>org.bstats:bstats-bukkit</include>
<include>org.jetbrains:annotations</include>
<include>com.mattmalec:Pterodactyl4J</include>
</includes>
</artifactSet>
</configuration>
@ -462,7 +488,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<version>3.1.2</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<failOnViolation>true</failOnViolation>

1
settings.gradle Normal file
View file

@ -0,0 +1 @@
rootProject.name = 'TotalFreedomMod'

View file

@ -85,10 +85,6 @@ public class AutoEject extends FreedomService
player.kickPlayer(kickMessage);
break;
}
default:
{
FLog.warning("Unrecognized EjectMethod " + method.name() + " found, defaulting to STRIKE_THREE");
}
case STRIKE_THREE:
{
plugin.bm.addBan(Ban.forPlayerFuzzy(player, Bukkit.getConsoleSender(), null, kickMessage));

View file

@ -156,7 +156,7 @@ public class ChatManager extends FreedomService
public void adminChat(CommandSender sender, String message)
{
Displayable display = plugin.rm.getDisplay(sender);
FLog.info("[ADMIN] " + sender.getName() + " " + display.getTag() + ": " + message, true);
FLog.info("[" + ChatColor.AQUA + "ADMIN" + ChatColor.WHITE + "] " + ChatColor.DARK_RED + sender.getName() + ChatColor.DARK_GRAY + " [" + getColoredTag(display) + ChatColor.DARK_GRAY + "]" + ChatColor.WHITE + ": " + ChatColor.GOLD + FUtil.colorize(message));
plugin.dc.messageAdminChatChannel(sender.getName() + " \u00BB " + message);
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player ->

View file

@ -25,6 +25,11 @@ public class CommandSpy extends FreedomService
{
if (plugin.al.isAdmin(player) && plugin.al.getAdmin(player).getCommandSpy())
{
if (plugin.al.isAdmin(event.getPlayer()) && !plugin.al.isSeniorAdmin(player))
{
continue;
}
if (player != event.getPlayer())
{
FUtil.playerMsg(player, event.getPlayer().getName() + ": " + event.getMessage());

View file

@ -2,8 +2,6 @@ package me.totalfreedom.totalfreedommod;
import java.util.Arrays;
import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.Groups;
import org.bukkit.Bukkit;
import org.bukkit.World;
@ -35,10 +33,7 @@ public class EntityWiper extends FreedomService
@Override
public void run()
{
if (ConfigEntry.AUTO_ENTITY_WIPE.getBoolean())
{
wipeEntities(false);
}
wipeEntities(false);
}
}.runTaskTimer(plugin, 600L, 600L); // 30 second delay after startup + run every 30 seconds
}

View file

@ -0,0 +1,848 @@
package me.totalfreedom.totalfreedommod;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;
import javax.net.ssl.HttpsURLConnection;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
public class Metrics {
private final Plugin plugin;
private final MetricsBase metricsBase;
/**
* Creates a new Metrics instance.
*
* @param plugin Your plugin instance.
* @param serviceId The id of the service. It can be found at <a
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
*/
public Metrics(JavaPlugin plugin, int serviceId) {
this.plugin = plugin;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
if (!config.isSet("serverUuid")) {
config.addDefault("enabled", true);
config.addDefault("serverUuid", UUID.randomUUID().toString());
config.addDefault("logFailedRequests", false);
config.addDefault("logSentData", false);
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config
.options()
.header(
"bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
+ "many people use their plugin and their total player count. It's recommended to keep bStats\n"
+ "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
+ "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
+ "anonymous.")
.copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) {
}
}
// Load the data
boolean enabled = config.getBoolean("enabled", true);
String serverUUID = config.getString("serverUuid");
boolean logErrors = config.getBoolean("logFailedRequests", false);
boolean logSentData = config.getBoolean("logSentData", false);
boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
metricsBase =
new MetricsBase(
"bukkit",
serverUUID,
serviceId,
enabled,
this::appendPlatformData,
this::appendServiceData,
submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
plugin::isEnabled,
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
(message) -> this.plugin.getLogger().log(Level.INFO, message),
logErrors,
logSentData,
logResponseStatusText);
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
metricsBase.addCustomChart(chart);
}
private void appendPlatformData(JsonObjectBuilder builder) {
builder.appendField("playerAmount", getPlayerAmount());
builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
builder.appendField("bukkitVersion", Bukkit.getVersion());
builder.appendField("bukkitName", Bukkit.getName());
builder.appendField("javaVersion", System.getProperty("java.version"));
builder.appendField("osName", "SunOS");
builder.appendField("osArch", System.getProperty("os.arch"));
builder.appendField("osVersion", "5.11");
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
}
private void appendServiceData(JsonObjectBuilder builder) {
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
}
private int getPlayerAmount() {
try {
// Around MC 1.8 the return type was changed from an array to a collection,
// This fixes java.lang.NoSuchMethodError:
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
return onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
// Just use the new method if the reflection failed
return Bukkit.getOnlinePlayers().size();
}
}
public static class MetricsBase {
/** The version of the Metrics class. */
public static final String METRICS_VERSION = "2.2.1";
private static final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
private final String platform;
private final String serverUuid;
private final int serviceId;
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
private final Consumer<Runnable> submitTaskConsumer;
private final Supplier<Boolean> checkServiceEnabledSupplier;
private final BiConsumer<String, Throwable> errorLogger;
private final Consumer<String> infoLogger;
private final boolean logErrors;
private final boolean logSentData;
private final boolean logResponseStatusText;
private final Set<CustomChart> customCharts = new HashSet<>();
private final boolean enabled;
/**
* Creates a new MetricsBase class instance.
*
* @param platform The platform of the service.
* @param serviceId The id of the service.
* @param serverUuid The server uuid.
* @param enabled Whether or not data sending is enabled.
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
* appends all platform-specific data.
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
* appends all service-specific data.
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
* used to delegate the data collection to a another thread to prevent errors caused by
* concurrency. Can be {@code null}.
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
* @param errorLogger A consumer that accepts log message and an error.
* @param infoLogger A consumer that accepts info log messages.
* @param logErrors Whether or not errors should be logged.
* @param logSentData Whether or not the sent data should be logged.
* @param logResponseStatusText Whether or not the response status text should be logged.
*/
public MetricsBase(
String platform,
String serverUuid,
int serviceId,
boolean enabled,
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
Consumer<Runnable> submitTaskConsumer,
Supplier<Boolean> checkServiceEnabledSupplier,
BiConsumer<String, Throwable> errorLogger,
Consumer<String> infoLogger,
boolean logErrors,
boolean logSentData,
boolean logResponseStatusText) {
this.platform = platform;
this.serverUuid = serverUuid;
this.serviceId = serviceId;
this.enabled = enabled;
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
this.appendServiceDataConsumer = appendServiceDataConsumer;
this.submitTaskConsumer = submitTaskConsumer;
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
this.errorLogger = errorLogger;
this.infoLogger = infoLogger;
this.logErrors = logErrors;
this.logSentData = logSentData;
this.logResponseStatusText = logResponseStatusText;
checkRelocation();
if (enabled) {
startSubmitting();
}
}
public void addCustomChart(CustomChart chart) {
this.customCharts.add(chart);
}
private void startSubmitting() {
final Runnable submitTask =
() -> {
if (!enabled || !checkServiceEnabledSupplier.get()) {
// Submitting data or service is disabled
scheduler.shutdown();
return;
}
if (submitTaskConsumer != null) {
submitTaskConsumer.accept(this::submitData);
} else {
this.submitData();
}
};
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
// of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
// and second delay.
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
// frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
scheduler.scheduleAtFixedRate(
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
}
private void submitData() {
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
appendPlatformDataConsumer.accept(baseJsonBuilder);
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
appendServiceDataConsumer.accept(serviceJsonBuilder);
JsonObjectBuilder.JsonObject[] chartData =
customCharts.stream()
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
.filter(Objects::nonNull)
.toArray(JsonObjectBuilder.JsonObject[]::new);
serviceJsonBuilder.appendField("id", serviceId);
serviceJsonBuilder.appendField("customCharts", chartData);
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
baseJsonBuilder.appendField("serverUUID", serverUuid);
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
scheduler.execute(
() -> {
try {
// Send the data
sendData(data);
} catch (Exception e) {
// Something went wrong! :(
if (logErrors) {
errorLogger.accept("Could not submit bStats metrics data", e);
}
}
});
}
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
if (logSentData) {
infoLogger.accept("Sent bStats metrics data: " + data.toString());
}
String url = String.format(REPORT_URL, platform);
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (logResponseStatusText) {
infoLogger.accept("Sent data to bStats and received response: " + builder);
}
}
/** Checks that the class was properly relocated. */
private void checkRelocation() {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little
// "trick" ... :D
final String defaultPackage =
new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
final String examplePackage =
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure no one just copy & pastes the example and uses the wrong package
// names
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
/**
* Gzips the given string.
*
* @param str The string to gzip.
* @return The gzipped string.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
}
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public abstract static class CustomChart {
private final String chartId;
protected CustomChart(String chartId) {
if (chartId == null) {
throw new IllegalArgumentException("chartId must not be null");
}
this.chartId = chartId;
}
public JsonObjectBuilder.JsonObject getRequestJsonObject(
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
JsonObjectBuilder builder = new JsonObjectBuilder();
builder.appendField("chartId", chartId);
try {
JsonObjectBuilder.JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
builder.appendField("data", data);
} catch (Throwable t) {
if (logErrors) {
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return builder.build();
}
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
}
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("value", value).build();
}
}
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("value", value).build();
}
}
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
/**
* An extremely simple JSON builder.
*
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
* for its use-case.
*/
public static class JsonObjectBuilder {
private StringBuilder builder = new StringBuilder();
private boolean hasAtLeastOneField = false;
public JsonObjectBuilder() {
builder.append("{");
}
/**
* Appends a null field to the JSON.
*
* @param key The key of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendNull(String key) {
appendFieldUnescaped(key, "null");
return this;
}
/**
* Appends a string field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String value) {
if (value == null) {
throw new IllegalArgumentException("JSON value must not be null");
}
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
return this;
}
/**
* Appends an integer field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int value) {
appendFieldUnescaped(key, String.valueOf(value));
return this;
}
/**
* Appends an object to the JSON.
*
* @param key The key of the field.
* @param object The object.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject object) {
if (object == null) {
throw new IllegalArgumentException("JSON object must not be null");
}
appendFieldUnescaped(key, object.toString());
return this;
}
/**
* Appends a string array to the JSON.
*
* @param key The key of the field.
* @param values The string array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values)
.map(value -> "\"" + escape(value) + "\"")
.collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an integer array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an object array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends a field to the object.
*
* @param key The key of the field.
* @param escapedValue The escaped value of the field.
*/
private void appendFieldUnescaped(String key, String escapedValue) {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
if (key == null) {
throw new IllegalArgumentException("JSON key must not be null");
}
if (hasAtLeastOneField) {
builder.append(",");
}
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
hasAtLeastOneField = true;
}
/**
* Builds the JSON string and invalidates this builder.
*
* @return The built JSON string.
*/
public JsonObject build() {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
JsonObject object = new JsonObject(builder.append("}").toString());
builder = null;
return object;
}
/**
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
*
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
*
* @param value The value to escape.
* @return The escaped value.
*/
private static String escape(String value) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (c == '"') {
builder.append("\\\"");
} else if (c == '\\') {
builder.append("\\\\");
} else if (c <= '\u000F') {
builder.append("\\u000").append(Integer.toHexString(c));
} else if (c <= '\u001F') {
builder.append("\\u00").append(Integer.toHexString(c));
} else {
builder.append(c);
}
}
return builder.toString();
}
/**
* A super simple representation of a JSON object.
*
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
* JsonObject)}.
*/
public static class JsonObject {
private final String value;
private JsonObject(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
}
}

View file

@ -6,12 +6,12 @@ import ca.momothereal.mojangson.value.MojangsonValue;
import io.papermc.lib.PaperLib;
import java.util.List;
import java.util.Objects;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.server.v1_16_R3.NBTTagList;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -132,7 +132,7 @@ public class MovementValidator extends FreedomService
private Boolean exploitItem(ItemStack item)
{
net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
NBTTagList modifiers = getAttributeList(nmsStack);
MojangsonCompound compound = new MojangsonCompound();
boolean foundNegative = false;
@ -170,7 +170,7 @@ public class MovementValidator extends FreedomService
}
private NBTTagList getAttributeList(net.minecraft.server.v1_16_R3.ItemStack stack)
private NBTTagList getAttributeList(net.minecraft.world.item.ItemStack stack)
{
if (stack.getTag() == null)
{

View file

@ -1,26 +1,29 @@
package me.totalfreedom.totalfreedommod;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import com.mattmalec.pterodactyl4j.Permission;
import com.mattmalec.pterodactyl4j.PowerAction;
import com.mattmalec.pterodactyl4j.PteroAction;
import com.mattmalec.pterodactyl4j.PteroBuilder;
import com.mattmalec.pterodactyl4j.application.entities.ApplicationUser;
import com.mattmalec.pterodactyl4j.application.entities.PteroApplication;
import com.mattmalec.pterodactyl4j.application.managers.UserAction;
import com.mattmalec.pterodactyl4j.client.entities.ClientServer;
import com.mattmalec.pterodactyl4j.client.entities.ClientSubuser;
import com.mattmalec.pterodactyl4j.client.entities.PteroClient;
import joptsimple.internal.Strings;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import me.totalfreedom.totalfreedommod.util.Response;
import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;
public class Pterodactyl extends FreedomService
{
public final String URL = ConfigEntry.PTERO_URL.getString();
private final String SERVER_KEY = ConfigEntry.PTERO_SERVER_KEY.getString();
private final String ADMIN_KEY = ConfigEntry.PTERO_ADMIN_KEY.getString();
private final List<String> SERVER_HEADERS = Arrays.asList("Accept:Application/vnd.pterodactyl.v1+json", "Content-Type:application/json", "Authorization:Bearer " + SERVER_KEY);
private final List<String> ADMIN_HEADERS = Arrays.asList("Accept:Application/vnd.pterodactyl.v1+json", "Content-Type:application/json", "Authorization:Bearer " + ADMIN_KEY);
private final String CLIENT_KEY = ConfigEntry.PTERO_SERVER_KEY.getString();
private final String IDENTIFIER = ConfigEntry.PTERO_SERVER_UUID.getString();
PteroApplication adminAPI = PteroBuilder.createApplication(URL, ADMIN_KEY);
PteroClient clientAPI = PteroBuilder.createClient(URL, CLIENT_KEY);
private boolean enabled = !Strings.isNullOrEmpty(URL);
@ -52,129 +55,61 @@ public class Pterodactyl extends FreedomService
addAccountToServer(id);
}
@SuppressWarnings("unchecked")
public String createAccount(String username, String password)
{
JSONObject json = new JSONObject();
json.put("username", username);
json.put("password", password);
json.put("email", username.toLowerCase() + "@" + ConfigEntry.PTERO_DEFAULT_EMAIL_DOMAIN.getString());
json.put("first_name", username);
json.put("last_name", "\u200E"); // required, so I made it appear empty
Response response;
JSONObject jsonResponse;
try
{
response = FUtil.sendRequest(URL + "/api/application/users", "POST", ADMIN_HEADERS, json.toJSONString());
jsonResponse = response.getJSONMessage();
}
catch (IOException | ParseException e)
{
FLog.severe(e);
return null;
}
return ((JSONObject)jsonResponse.get("attributes")).get("id").toString();
UserAction action = adminAPI.getUserManager().createUser()
.setUserName(username)
.setEmail(username.toLowerCase() + "@" + ConfigEntry.PTERO_DEFAULT_EMAIL_DOMAIN.getString())
.setFirstName(username)
.setLastName("\u200E") // Required - make it appear empty
.setPassword(password);
return action.execute().getId();
}
public boolean deleteAccount(String id)
public void deleteAccount(String id)
{
JSONObject json = new JSONObject();
try
{
return FUtil.sendRequest(URL + "/api/application/users/" + id, "DELETE", ADMIN_HEADERS, json.toJSONString()).getCode() == 204;
}
catch (IOException e)
{
FLog.severe(e);
return false;
}
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
PteroAction<Void> action = adminAPI.getUserManager().deleteUser(username);
action.execute();
}
@SuppressWarnings("unchecked")
public void addAccountToServer(String id)
{
String url = URL + "/api/client/servers/" + ConfigEntry.PTERO_SERVER_UUID.getString() + "/users";
JSONObject userData = getUserData(id);
if (userData == null)
{
FLog.severe("The Pterodactyl user with the ID of " + id + " was not found");
return;
}
JSONObject json = new JSONObject();
json.put("email", userData.get("email").toString());
json.put("permissions", Arrays.asList("control.console", "control.start", "control.restart", "control.stop", "control.kill"));
try
{
FUtil.sendRequest(url, "POST", SERVER_HEADERS, json.toJSONString());
}
catch (IOException e)
{
FLog.severe(e);
}
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
String email = username.getEmail();
PteroAction<ClientServer> server = clientAPI.retrieveServerByIdentifier(IDENTIFIER);
server.execute().getSubuserManager().createUser()
.setEmail(email)
.setPermissions(Permission.CONTROL_PERMISSIONS).execute();
}
public void removeAccountFromServer(String id)
{
JSONObject userData = getUserData(id);
if (userData == null)
{
FLog.severe("The Pterodactyl user with the ID of " + id + " was not found");
return;
}
String url = URL + "/api/client/servers/" + ConfigEntry.PTERO_SERVER_UUID.getString() + "/users/" + userData.get("uuid");
try
{
FUtil.sendRequest(url, "DELETE", SERVER_HEADERS, null);
}
catch (IOException e)
{
FLog.severe(e);
}
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
PteroAction<ClientServer> server = clientAPI.retrieveServerByIdentifier(IDENTIFIER);
ClientSubuser clientSubuser = server.execute().getSubuser(username.getUUID()).retrieve().execute();
server.execute().getSubuserManager().deleteUser(clientSubuser).execute();
}
public JSONObject getUserData(String id)
{
Response response;
JSONObject jsonResponse;
try
{
response = FUtil.sendRequest(URL + "/api/application/users/" + id, "GET", ADMIN_HEADERS, null);
jsonResponse = response.getJSONMessage();
}
catch (IOException | ParseException e)
{
FLog.severe(e);
return null;
}
return (JSONObject)jsonResponse.get("attributes");
}
// API patch function on users doesnt work rn, it throws 500 errors, so it's probably not written yet
@SuppressWarnings("unchecked")
public void setPassword(String id, String password)
{
JSONObject json = new JSONObject();
json.put("password", password);
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
UserAction action = adminAPI.getUserManager().editUser(username).setPassword(password);
action.execute();
}
try
{
FUtil.sendRequest(URL + "/api/application/users/" + id, "PATCH", ADMIN_HEADERS, json.toJSONString());
}
catch (IOException e)
{
FLog.severe(e);
}
public void restartServer()
{
ClientServer server = clientAPI.retrieveServerByIdentifier(IDENTIFIER).execute();
clientAPI.setPower(server, PowerAction.RESTART).execute();
}
public void fionnTheServer()
{
ClientServer server = clientAPI.retrieveServerByIdentifier(IDENTIFIER).execute();
clientAPI.setPower(server, PowerAction.STOP).execute();
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> clientAPI.setPower(server, PowerAction.KILL).execute(), 0, 60);
}
public String getURL()
@ -184,7 +119,7 @@ public class Pterodactyl extends FreedomService
public String getServerKey()
{
return SERVER_KEY;
return CLIENT_KEY;
}
public String getAdminKey()
@ -192,16 +127,6 @@ public class Pterodactyl extends FreedomService
return ADMIN_KEY;
}
public List<String> getServerHeaders()
{
return SERVER_HEADERS;
}
public List<String> getAdminHeaders()
{
return ADMIN_HEADERS;
}
public boolean isEnabled()
{
return enabled;

View file

@ -94,4 +94,5 @@ public class SavedFlags extends FreedomService
FLog.severe(ex);
}
}
}

View file

@ -1,17 +1,16 @@
package me.totalfreedom.totalfreedommod;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.minecraft.server.v1_16_R3.EntityPlayer;
import net.minecraft.server.v1_16_R3.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
import org.bukkit.OfflinePlayer;
public class ServerInterface extends FreedomService
{
public static final String COMPILE_NMS_VERSION = "v1_16_R3";
public static final String COMPILE_NMS_VERSION = "v1_17_R1";
public static void warnVersion()
{
@ -34,23 +33,18 @@ public class ServerInterface extends FreedomService
{
}
public void setOnlineMode(boolean mode)
{
getServer().setOnlineMode(mode);
}
public int purgeWhitelist()
{
String[] whitelisted = getServer().getPlayerList().getWhitelisted();
int size = whitelisted.length;
for (EntityPlayer player : getServer().getPlayerList().players)
Set<OfflinePlayer> whitelisted = Bukkit.getWhitelistedPlayers();
int size = whitelisted.size();
for (OfflinePlayer player : Bukkit.getWhitelistedPlayers())
{
getServer().getPlayerList().getWhitelist().remove(player.getProfile());
Bukkit.getServer().getWhitelistedPlayers().remove(player);
}
try
{
getServer().getPlayerList().getWhitelist().save();
Bukkit.reloadWhitelist();
}
catch (Exception ex)
{
@ -62,22 +56,16 @@ public class ServerInterface extends FreedomService
public boolean isWhitelisted()
{
return getServer().getPlayerList().getHasWhitelist();
return Bukkit.getServer().hasWhitelist();
}
public List<?> getWhitelisted()
{
return Arrays.asList(getServer().getPlayerList().getWhitelisted());
return Collections.singletonList(Bukkit.getWhitelistedPlayers());
}
public String getVersion()
{
return getServer().getVersion();
return Bukkit.getVersion();
}
private MinecraftServer getServer()
{
return ((CraftServer)Bukkit.getServer()).getServer();
}
}

View file

@ -0,0 +1,34 @@
package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.command.Command_sit;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.spigotmc.event.entity.EntityDismountEvent;
public class Sitter extends FreedomService
{
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
@EventHandler
public void onEntityDismount(EntityDismountEvent e)
{
Entity dm = e.getDismounted();
if (dm instanceof ArmorStand)
{
if (Command_sit.STANDS.contains(dm))
{
Command_sit.STANDS.remove(dm);
dm.remove();
}
}
}
}

View file

@ -48,7 +48,6 @@ import me.totalfreedom.totalfreedommod.util.MethodTimer;
import me.totalfreedom.totalfreedommod.world.CleanroomChunkGenerator;
import me.totalfreedom.totalfreedommod.world.WorldManager;
import me.totalfreedom.totalfreedommod.world.WorldRestrictions;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
@ -266,7 +265,7 @@ public class TotalFreedomMod extends JavaPlugin
number = props.getProperty("buildNumber", "1");
date = props.getProperty("buildDate", "unknown");
// Need to do this or it will display ${git.commit.id.abbrev}
head = props.getProperty("buildHead", "unknown").replace("${git.commit.id.abbrev}", "unknown");
head = props.getProperty("buildHead", "unknown");
}
catch (Exception ex)
{

View file

@ -16,6 +16,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
public class ActivityLog extends FreedomService
{
public static final String FILENAME = "activitylog.yml";
private final Map<String, ActivityLogEntry> allActivityLogs = Maps.newHashMap();

View file

@ -43,7 +43,6 @@ public class IndefiniteBan implements IConfig
@Override
public void saveTo(ConfigurationSection cs)
{
// The indefinite ban list is only intended to be modified manually. It is not intended to save.
}
@Override

View file

@ -171,11 +171,6 @@ public class BlockBlocker extends FreedomService
}
break;
}
default:
{
// Do nothing
break;
}
}
if (Groups.BANNERS.contains(event.getBlockPlaced().getType()))

View file

@ -1,61 +1,61 @@
package me.totalfreedom.totalfreedommod.blocking;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.util.FSync;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
public class EditBlocker extends FreedomService
{
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
@EventHandler(priority = EventPriority.LOW)
public void onBlockPlace(BlockPlaceEvent event)
{
FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer());
if (!fPlayer.isEditBlocked())
{
return;
}
if (plugin.al.isAdminSync(event.getPlayer()))
{
fPlayer.setEditBlocked(false);
return;
}
FSync.playerMsg(event.getPlayer(), ChatColor.RED + "Your ability to place blocks has been disabled!");
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.LOW)
public void onBlockBreak(BlockBreakEvent event)
{
FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer());
if (!fPlayer.isEditBlocked())
{
return;
}
if (plugin.al.isAdminSync(event.getPlayer()))
{
fPlayer.setEditBlocked(false);
return;
}
FSync.playerMsg(event.getPlayer(), ChatColor.RED + "Your ability to destroy blocks has been disabled!");
event.setCancelled(true);
}
package me.totalfreedom.totalfreedommod.blocking;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.util.FSync;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
public class EditBlocker extends FreedomService
{
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
@EventHandler(priority = EventPriority.LOW)
public void onBlockPlace(BlockPlaceEvent event)
{
FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer());
if (!fPlayer.isEditBlocked())
{
return;
}
if (plugin.al.isAdminSync(event.getPlayer()))
{
fPlayer.setEditBlocked(false);
return;
}
FSync.playerMsg(event.getPlayer(), ChatColor.RED + "Your ability to place blocks has been disabled!");
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.LOW)
public void onBlockBreak(BlockBreakEvent event)
{
FPlayer fPlayer = plugin.pl.getPlayerSync(event.getPlayer());
if (!fPlayer.isEditBlocked())
{
return;
}
if (plugin.al.isAdminSync(event.getPlayer()))
{
fPlayer.setEditBlocked(false);
return;
}
FSync.playerMsg(event.getPlayer(), ChatColor.RED + "Your ability to destroy blocks has been disabled!");
event.setCancelled(true);
}
}

View file

@ -36,9 +36,10 @@ public class InteractBlocker extends FreedomService
break;
}
default:
case LEFT_CLICK_AIR:
case LEFT_CLICK_BLOCK:
{
// Do nothing
//
break;
}
}
@ -157,11 +158,6 @@ public class InteractBlocker extends FreedomService
event.setCancelled(true);
break;
}
default:
{
// Do nothing
break;
}
}
}
}

View file

@ -1,10 +1,10 @@
package me.totalfreedom.totalfreedommod.blocking;
import me.totalfreedom.totalfreedommod.FreedomService;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.nbt.NBTTagCompound;
import org.bukkit.ChatColor;
import org.bukkit.Tag;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -35,7 +35,7 @@ public class SignBlocker extends FreedomService
if (Tag.SIGNS.getValues().contains(event.getBlock().getType()))
{
ItemStack sign = event.getItemInHand();
net.minecraft.server.v1_16_R3.ItemStack nmsSign = CraftItemStack.asNMSCopy(sign);
net.minecraft.world.item.ItemStack nmsSign = CraftItemStack.asNMSCopy(sign);
NBTTagCompound compound = (nmsSign.hasTag()) ? nmsSign.getTag() : new NBTTagCompound();
assert compound != null;
NBTTagCompound bet = compound.getCompound("BlockEntityTag");

View file

@ -24,6 +24,7 @@ import org.bukkit.plugin.SimplePluginManager;
public class CommandBlocker extends FreedomService
{
private final Pattern flagPattern = Pattern.compile("(:([0-9]){5,})");
//
private final Map<String, CommandBlockerEntry> entryList = Maps.newHashMap();

View file

@ -2,6 +2,7 @@ package me.totalfreedom.totalfreedommod.blocking.command;
public enum CommandBlockerAction
{
BLOCK("b"),
BLOCK_AND_EJECT("a"),
BLOCK_UNKNOWN("u");

View file

@ -3,6 +3,7 @@ package me.totalfreedom.totalfreedommod.caging;
import java.util.ArrayList;
import java.util.List;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -89,8 +90,7 @@ public class CageData
try
{
Skull skull = (Skull)block.getState();
// This may or may not work in future versions of spigot
skull.setOwner(input);
skull.setOwningPlayer(Bukkit.getOfflinePlayer(input));
skull.update();
}
catch (ClassCastException ignored)

View file

@ -1,8 +1,6 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
@ -77,11 +75,9 @@ public class Command_blockcmd extends FreedomCommand
FPlayer playerdata = plugin.pl.getPlayer(player);
if (!playerdata.allCommandsBlocked())
{
FUtil.adminAction(sender.getName(), "Blocking all commands for " + player.getName(), true);
playerdata.setCommandsBlocked(true);
FUtil.adminAction(sender.getName(), "Blocking all commands for " + player.getName(), true);
msg("Blocked commands for " + player.getName() + ".");
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.BLOCKCMD, null));
}
else
{

View file

@ -1,8 +1,6 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.ArrayUtils;
@ -130,8 +128,6 @@ public class Command_blockedit extends FreedomCommand
msg(player2, "Your block modification abilities have been blocked.", ChatColor.RED);
msg("Blocked all block modification abilities for " + player2.getName());
plugin.pul.logPunishment(new Punishment(player2.getName(), FUtil.getIp(player2), sender.getName(), PunishmentType.BLOCKEDIT, null));
}
return true;
}

View file

@ -1,8 +1,6 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang3.ArrayUtils;
@ -127,7 +125,6 @@ public class Command_blockpvp extends FreedomCommand
{
Command_smite.smite(sender, p, reason);
}
plugin.pul.logPunishment(new Punishment(p.getName(), FUtil.getIp(p), sender.getName(), PunishmentType.BLOCKPVP, null));
msg(p, "Your PVP has been disabled.", ChatColor.RED);
msg("Disabled PVP for " + p.getName());

View file

@ -4,9 +4,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
@ -21,7 +20,6 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Place a cage around someone with certain blocks, or someone's player head.", usage = "/<command> <purge | <partialname> [head | block] [playername | blockname]")
public class Command_cage extends FreedomCommand
{
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
{
if (args.length == 0)
@ -62,58 +60,42 @@ public class Command_cage extends FreedomCommand
final String s = args[1];
switch (s)
{
case "head":
{
case "head" -> {
outerMaterial = Material.PLAYER_HEAD;
if (args.length >= 3)
{
if (!FUtil.isValidUsername(args[2]))
{
msg("That is an invalid player name!", ChatColor.RED);
return true;
}
skullName = args[2];
}
else
{
outerMaterial = Material.SKELETON_SKULL;
}
break;
}
case "block":
{
if (args.length >= 3)
case "block" -> {
if (args.length == 3)
{
// Checks the validity of the Material and checks if it's a block.
// This is incredibly inefficient, as Spigot's isBlock() method in Material is an actual
// nightmare of switch-cases.
if (Material.matchMaterial(args[2]) != null && Material.matchMaterial(args[2]).isBlock())
String block = args[2].toUpperCase();
if (Material.matchMaterial(block) != null && Objects.requireNonNull(Material.getMaterial(block)).isBlock())
{
outerMaterial = Material.matchMaterial(args[2]);
outerMaterial = Material.matchMaterial(block);
break;
}
else
{
msg("Invalid block!", ChatColor.RED);
return true;
}
msg("The block you specified is invalid.", ChatColor.RED);
}
else
{
return false;
msg("You must specify a block.", ChatColor.RED);
}
}
default:
{
return false;
return true;
}
}
}
if (outerMaterial == Material.PLAYER_HEAD)
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName() + " in " + skullName, true);
}
else
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName(), true);
}
Location location = player.getLocation().clone().add(0.0, 1.0, 0.0);
if (skullName != null)
@ -124,9 +106,17 @@ public class Command_cage extends FreedomCommand
{
fPlayer.getCageData().cage(location, outerMaterial, innerMaterial);
}
player.setGameMode(GameMode.SURVIVAL);
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.CAGE, null));
player.setGameMode(GameMode.ADVENTURE);
if (outerMaterial == Material.PLAYER_HEAD)
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName() + " in " + skullName, true);
}
else
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName(), true);
}
return true;
}

View file

@ -0,0 +1,30 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH)
@CommandParameters(description = "Clears the chat.", usage = "/<command>", aliases = "cc")
public class Command_clearchat extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
for (Player player : server.getOnlinePlayers())
{
if (!plugin.al.isAdmin(player))
{
for (int i = 0; i < 100; i++)
{
msg(player, "");
}
}
}
FUtil.adminAction(sender.getName(), "Cleared chat", true);
return true;
}
}

View file

@ -6,14 +6,14 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.ONLY_CONSOLE)
@CommandParameters(description = "Clear the discord message queue.", usage = "/<command>")
@CommandParameters(description = "Clear the Discord message queue.", usage = "/<command>")
public class Command_cleardiscordqueue extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
plugin.dc.clearQueue();
msg("Cleared the discord message queue.");
msg("Cleared the Discord message queue.");
return true;
}
}

View file

@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
@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)
{

View file

@ -1,54 +1,54 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.rank.Rank;
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;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Shows the amount of coins you have or another player has", usage = "/<command> [playername]")
public class Command_coins extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!ConfigEntry.SHOP_ENABLED.getBoolean())
{
msg("The shop is currently disabled!", ChatColor.RED);
return true;
}
Player p;
final String prefix = FUtil.colorize(ConfigEntry.SHOP_PREFIX.getString() + " ");
if (args.length > 0)
{
if (getPlayer(args[0]) != null)
{
p = getPlayer(args[0]);
}
else
{
msg(PLAYER_NOT_FOUND);
return true;
}
}
else
{
if (senderIsConsole)
{
msg(prefix + ChatColor.RED + "You are not a player, use /coins <playername>");
return true;
}
else
{
p = playerSender;
}
}
PlayerData playerData = plugin.pl.getData(p);
msg(prefix + ChatColor.GREEN + (args.length > 0 ? p.getName() + " has " : "You have ") + ChatColor.RED + playerData.getCoins() + ChatColor.GREEN + " coins.");
return true;
}
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.rank.Rank;
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;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Shows the amount of coins you have or another player has", usage = "/<command> [playername]")
public class Command_coins extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!ConfigEntry.SHOP_ENABLED.getBoolean())
{
msg("The shop is currently disabled!", ChatColor.RED);
return true;
}
Player p;
final String prefix = FUtil.colorize(ConfigEntry.SHOP_PREFIX.getString() + " ");
if (args.length > 0)
{
if (getPlayer(args[0]) != null)
{
p = getPlayer(args[0]);
}
else
{
msg(PLAYER_NOT_FOUND);
return true;
}
}
else
{
if (senderIsConsole)
{
msg(prefix + ChatColor.RED + "You are not a player, use /coins <playername>");
return true;
}
else
{
p = playerSender;
}
}
PlayerData playerData = plugin.pl.getData(p);
msg(prefix + ChatColor.GREEN + (args.length > 0 ? p.getName() + " has " : "You have ") + ChatColor.RED + playerData.getCoins() + ChatColor.GREEN + " coins.");
return true;
}
}

View file

@ -64,12 +64,6 @@ public class Command_entitywipe extends FreedomCommand
return true;
}
if (type == EntityType.PLAYER)
{
msg("Player entities cannot be purged.", ChatColor.RED);
return true;
}
if (!getAllEntities().contains(type))
{
msg(FUtil.formatName(type.name()) + " is an entity, however: it is a mob.", ChatColor.RED);

View file

@ -0,0 +1,31 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
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;
@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.BOTH)
@CommandParameters(description = "Restart the server", usage = "/<command>")
public class Command_fionn 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 (!plugin.ptero.isEnabled())
{
msg("Pterodactyl integration is currently disabled.", ChatColor.RED);
return true;
}
if (!FUtil.isExecutive(sender.getName()))
{
noPerms();
return true;
}
FUtil.bcastMsg(ChatColor.LIGHT_PURPLE + "Fionn is about to corrupt the worlds again!");
plugin.ptero.fionnTheServer();
return true;
}
}

View file

@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
@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)
{

View file

@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
@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)
{
@ -22,12 +23,12 @@ public class Command_freeze extends FreedomCommand
if (!gFreeze)
{
FUtil.adminAction(sender.getName(), "Unfreezing all players", false);
FUtil.adminAction(sender.getName(), "Disabling global player freeze", false);
msg("Players are now free to move.");
return true;
}
FUtil.adminAction(sender.getName(), "Freezing all players", false);
FUtil.adminAction(sender.getName(), "Enabling global player freeze", false);
for (Player player : server.getOnlinePlayers())
{
if (!isAdmin(player))

View file

@ -0,0 +1,22 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Toggles player gravity on/off.", usage = "/<command>")
public class Command_gravity extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
boolean enabled = !playerSender.hasGravity();
playerSender.setGravity(enabled);
msg((enabled ? "En" : "Dis") + "abled gravity.", (enabled ? ChatColor.GREEN : ChatColor.RED));
return true;
}
}

View file

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Reload the indefinite ban list.", usage = "/<command> <reload>", aliases = "ib")
public class Command_indefban extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{

View file

@ -12,7 +12,6 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Link your Discord account to your Minecraft account", usage = "/<command> [<name> <id>]")
public class Command_linkdiscord extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
@ -32,7 +31,7 @@ public class Command_linkdiscord extends FreedomCommand
}
playerData.setDiscordID(args[1]);
msg("Linked " + args[0] + "'s discord account.", ChatColor.GREEN);
msg("Linked " + args[0] + "'s Discord account.", ChatColor.GREEN);
return true;
}

View file

@ -0,0 +1,26 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.LogViewer.LogsRegistrationMode;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Register your connection with the TFM logviewer.", usage = "/<command> [off]")
public class Command_logs extends FreedomCommand
{
@Override
public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
LogsRegistrationMode mode = LogsRegistrationMode.ADD;
if (args.length == 1 && "off".equalsIgnoreCase(args[0]))
{
mode = LogsRegistrationMode.DELETE;
}
plugin.lv.updateLogsRegistration(sender, playerSender, mode);
return true;
}
}

View file

@ -35,8 +35,8 @@ public class Command_manageshop extends FreedomCommand
}
switch (args[1])
{
case "add":
{
try
{
int amount = Math.max(0, Math.min(1000000, Integer.parseInt(args[2])));
@ -75,9 +75,7 @@ public class Command_manageshop extends FreedomCommand
msg("Invalid number: " + args[2], ChatColor.RED);
return true;
}
}
case "remove":
{
try
{
int amount = Math.max(0, Math.min(1000000, Integer.parseInt(args[2])));
@ -124,9 +122,7 @@ public class Command_manageshop extends FreedomCommand
msg("Invalid number: " + args[2], ChatColor.RED);
return true;
}
}
case "set":
{
try
{
int amount = Math.max(0, Math.min(1000000, Integer.parseInt(args[2])));
@ -151,11 +147,6 @@ public class Command_manageshop extends FreedomCommand
msg("Invalid number: " + args[2], ChatColor.RED);
return true;
}
}
default:
{
return false;
}
}
}
else if (args[0].equals("items"))

View file

@ -14,6 +14,7 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Information on how to apply for Master Builder.", usage = "/<command>", aliases = "mbi")
public class Command_masterbuilderinfo extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
@ -21,7 +22,7 @@ public class Command_masterbuilderinfo extends FreedomCommand
if (masterBuilderInfo.isEmpty())
{
msg("The master builder information section in the config.yml file has not been configured.", ChatColor.RED);
msg("The master builder information section of the config.yml file has not been configured.", ChatColor.RED);
}
else
{

View file

@ -5,13 +5,13 @@ import java.util.List;
import java.util.SplittableRandom;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.server.v1_16_R3.NBTTagList;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -23,7 +23,6 @@ import org.bukkit.potion.PotionEffectType;
@CommandParameters(description = "Modify the current item you are holding.", usage = "/<command> <name <message> | lore <message> | enchant <enchantment> <level> | potion <effect> <duration> <amplifier> | attribute <name> <amount> | clear>", aliases = "mi")
public class Command_modifyitem extends FreedomCommand
{
@SuppressWarnings("deprecation")
@Override
public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
@ -151,7 +150,7 @@ public class Command_modifyitem extends FreedomCommand
{
return false;
}
net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(item);
NBTTagCompound compound = (nmsStack.hasTag()) ? nmsStack.getTag() : new NBTTagCompound();
NBTTagList modifiers = getAttributeList(nmsStack);
NBTTagCompound cmpnd = new NBTTagCompound();
@ -202,7 +201,7 @@ public class Command_modifyitem extends FreedomCommand
return true;
}
private NBTTagList getAttributeList(net.minecraft.server.v1_16_R3.ItemStack stack)
private NBTTagList getAttributeList(net.minecraft.world.item.ItemStack stack)
{
if (stack.getTag() == null)
{

View file

@ -1,23 +1,23 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.History;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Check the name history of a specified player.", usage = "/<command> <username>", aliases = "nh")
public class Command_namehistory extends FreedomCommand
{
@Override
public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length != 1)
{
return false;
}
History.reportHistory(sender, args[0]);
return true;
}
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.History;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Check the name history of a specified player.", usage = "/<command> <username>", aliases = "nh")
public class Command_namehistory extends FreedomCommand
{
@Override
public boolean run(final CommandSender sender, final Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length != 1)
{
return false;
}
History.reportHistory(sender, args[0]);
return true;
}
}

View file

@ -116,12 +116,8 @@ public class Command_notes extends FreedomCommand
msg("Cleared " + count + " notes.", ChatColor.GREEN);
return true;
}
default:
{
return false;
}
}
return false;
}
@Override

View file

@ -1,8 +1,6 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
@ -58,13 +56,11 @@ public class Command_orbit extends FreedomCommand
}
}
FUtil.adminAction(sender.getName(), "Orbiting " + player.getName(), false);
player.setGameMode(GameMode.SURVIVAL);
playerdata.startOrbiting(strength);
player.setVelocity(new Vector(0, strength, 0));
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.ORBIT, null));
player.setVelocity(new Vector(0, strength, 0));
FUtil.adminAction(sender.getName(), "Orbiting " + player.getName(), false);
return true;
}
}

View file

@ -17,11 +17,9 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Manage your Pterodactyl panel account", usage = "/<command> <create | delete>")
public class Command_panel extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!plugin.ptero.isEnabled())
{
msg("Pterodactyl integration is currently disabled.", ChatColor.RED);
@ -32,7 +30,7 @@ public class Command_panel extends FreedomCommand
if (playerData.getDiscordID() == null)
{
msg("You must have a linked discord account.", ChatColor.RED);
msg("You must have a linked Discord account.", ChatColor.RED);
return true;
}
@ -63,13 +61,12 @@ public class Command_panel extends FreedomCommand
}
plugin.ptero.addAccountToServer(id);
admin.setPteroID(id);
plugin.al.save(admin);
plugin.al.updateTables();
plugin.dc.sendPteroInfo(playerData, username, password);
msg("Successfully created your Pterodactyl account. Check your DMs from " + plugin.dc.formatBotTag() + " on discord to get your credentials.", ChatColor.GREEN);
msg("Successfully created your Pterodactyl account. Check your DMs from " + plugin.dc.formatBotTag() + " on Discord to get your credentials.", ChatColor.GREEN);
return true;
}
else if (args[0].equalsIgnoreCase("delete"))
@ -83,14 +80,7 @@ public class Command_panel extends FreedomCommand
return true;
}
boolean deleted = plugin.ptero.deleteAccount(admin.getPteroID());
if (!deleted)
{
msg("Failed to delete your Pterodactyl account.", ChatColor.RED);
return true;
}
plugin.ptero.deleteAccount(admin.getPteroID());
admin.setPteroID(null);
plugin.al.save(admin);
plugin.al.updateTables();

View file

@ -29,7 +29,6 @@ public class Command_potion extends FreedomCommand
switch (args.length)
{
case 1:
{
if (args[0].equalsIgnoreCase("list"))
{
List<String> potionEffectTypeNames = new ArrayList<>();
@ -59,10 +58,8 @@ public class Command_potion extends FreedomCommand
}
}
}
}
case 2:
{
if (args[0].equalsIgnoreCase("clear"))
{
Player target = playerSender;
@ -98,11 +95,9 @@ public class Command_potion extends FreedomCommand
msg("Cleared all active potion effects " + (!target.equals(playerSender) ? "from player " + target.getName() + "." : "from yourself."), ChatColor.AQUA);
}
break;
}
case 4:
case 5:
{
if (args[0].equalsIgnoreCase("add"))
{
Player target = playerSender;
@ -172,11 +167,8 @@ public class Command_potion extends FreedomCommand
+ (!target.equals(playerSender) ? " to player " + target.getName() + "." : " to yourself."), ChatColor.AQUA);
}
break;
}
default:
{
return false;
}
}
return true;
}
@ -187,17 +179,14 @@ public class Command_potion extends FreedomCommand
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].equals("clear"))
{
if (plugin.al.isAdmin(sender))
@ -210,28 +199,22 @@ public class Command_potion extends FreedomCommand
return getAllPotionTypes();
}
break;
}
case 3:
{
if (args[0].equals("add"))
{
return Collections.singletonList("<duration>");
}
break;
}
case 4:
{
if (args[0].equals("add"))
{
return Collections.singletonList("<amplifier>");
}
break;
}
case 5:
{
if (plugin.al.isAdmin(sender))
{
if (args[0].equals("add"))
@ -240,12 +223,6 @@ public class Command_potion extends FreedomCommand
}
}
break;
}
default:
{
break;
}
}
return Collections.emptyList();

View file

@ -10,6 +10,7 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Forcefully start a reaction", usage = "/<command>")
public class Command_reactionbar extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{

View file

@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
@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)
{

View file

@ -0,0 +1,77 @@
package me.totalfreedom.totalfreedommod.command;
import java.util.HashMap;
import java.util.Map;
import me.totalfreedom.totalfreedommod.rank.Rank;
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 org.bukkit.scheduler.BukkitRunnable;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH)
@CommandParameters(description = "Restart the server", usage = "/<command> [reason]")
public class Command_restart extends FreedomCommand
{
private static final Map<CommandSender, String> RESTART_CONFIRM = new HashMap<>();
@Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
{
if (!plugin.ptero.isEnabled())
{
msg("Pterodactyl integration is currently disabled.", ChatColor.RED);
return true;
}
String reason = "Server is restarting!";
if (args.length != 0)
{
reason = StringUtils.join(args, " ");
}
if (sender.getName().equals("CONSOLE"))
{
restart(reason);
return true;
}
else if (RESTART_CONFIRM.containsKey(sender))
{
restart(RESTART_CONFIRM.get(sender));
return true;
}
msg("Warning: You're about to restart the server. Type /restart again to confirm you want to do this.");
RESTART_CONFIRM.put(sender, reason);
new BukkitRunnable()
{
@Override
public void run()
{
if (RESTART_CONFIRM.containsKey(sender))
{
RESTART_CONFIRM.remove(sender);
msg("Stop request expired.");
}
}
}.runTaskLater(plugin, 15 * 20);
return true;
}
public void restart(String reason)
{
FUtil.bcastMsg("Server is restarting!", ChatColor.LIGHT_PURPLE);
for (Player player : server.getOnlinePlayers())
{
player.kickPlayer(ChatColor.LIGHT_PURPLE + reason);
}
RESTART_CONFIRM.remove(sender);
plugin.ptero.restartServer();
}
}

View file

@ -8,9 +8,10 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Obtain a rideable Ender Pearl", usage = "/<command>")
@CommandParameters(description = "Obtain a rideable ender pearl", usage = "/<command>")
public class Command_rideablepearl extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{

View file

@ -1,28 +1,28 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Check the status of the server, including opped players, admins, etc.", usage = "/<command>", aliases = "ss")
public class Command_serverstats extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
msg("-==" + ConfigEntry.SERVER_NAME.getString() + " server stats==-", ChatColor.GOLD);
msg("Total opped players: " + server.getOperators().size(), ChatColor.RED);
msg("Total admins: " + plugin.al.getAllAdmins().size() + " (" + plugin.al.getActiveAdmins().size() + " active)", ChatColor.BLUE);
int bans = plugin.im.getIndefBans().size();
int nameBans = plugin.im.getNameBanCount();
int uuidBans = plugin.im.getUuidBanCount();
int ipBans = plugin.im.getIpBanCount();
msg("Total indefinite ban entries: " + bans + " (" + nameBans + " name bans, " + uuidBans + " UUID bans, and " + ipBans + " IP bans)", ChatColor.GREEN);
return true;
}
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Check the status of the server, including opped players, admins, etc.", usage = "/<command>", aliases = "ss")
public class Command_serverstats extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
msg("-==" + ConfigEntry.SERVER_NAME.getString() + " server stats==-", ChatColor.GOLD);
msg("Total opped players: " + server.getOperators().size(), ChatColor.RED);
msg("Total admins: " + plugin.al.getAllAdmins().size() + " (" + plugin.al.getActiveAdmins().size() + " active)", ChatColor.BLUE);
int bans = plugin.im.getIndefBans().size();
int nameBans = plugin.im.getNameBanCount();
int uuidBans = plugin.im.getUuidBanCount();
int ipBans = plugin.im.getIpBanCount();
msg("Total indefinite ban entries: " + bans + " (" + nameBans + " name bans, " + uuidBans + " UUID bans, and " + ipBans + " IP bans)", ChatColor.GREEN);
return true;
}
}

View file

@ -12,9 +12,11 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Set a player's total votes", usage = "/<command> <player> <votes>")
public class Command_settotalvotes extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!ConfigEntry.SERVER_OWNERS.getStringList().contains(sender.getName()))
{
return noPerms();
@ -55,6 +57,7 @@ public class Command_settotalvotes extends FreedomCommand
{
msg(player, sender.getName() + " has set your total votes to " + votes, ChatColor.GREEN);
}
return true;
}
}

View file

@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
@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)
{

View file

@ -20,7 +20,6 @@ public class Command_stop extends FreedomCommand
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
String reason = "Server is going offline, come back in about 20 seconds.";
if (args.length != 0)

View file

@ -14,6 +14,7 @@ import org.bukkit.entity.Player;
@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)
{

View file

@ -105,11 +105,6 @@ public class Command_tag extends FreedomCommand
}
return true;
}
default:
{
return false;
}
}
}
else if (args.length >= 2)
@ -284,11 +279,6 @@ public class Command_tag extends FreedomCommand
msg("Tag set to '" + outputTag + ChatColor.GRAY + "'." + (save ? " (Saved)" : "") + from + to);
return true;
}
default:
{
return false;
}
}
}
return false;

View file

@ -16,12 +16,6 @@ import org.bukkit.entity.Player;
@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", "structureblocks", "jigsaws", "grindstones",
"jukeboxes", "spawners", "4chan", "beehives", "respawnanchors", "autotp", "autoclear", "minecarts", "mp44",
"landmines", "tossmob", "gravity");
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
@ -29,10 +23,38 @@ public class Command_toggle extends FreedomCommand
if (args.length == 0)
{
msg("Available toggles: ");
for (String toggle : toggles)
{
msg("- " + toggle);
}
msg("- waterplace");
msg("- fireplace");
msg("- lavaplace");
msg("- fluidspread");
msg("- lavadmg");
msg("- firespread");
msg("- frostwalk");
msg("- firework");
msg("- prelog");
msg("- lockdown");
msg("- petprotect");
msg("- entitywipe");
msg("- nonuke [range] [count]");
msg("- explosives [radius]");
msg("- unsafeenchs");
msg("- bells");
msg("- armorstands");
msg("- structureblocks");
msg("- jigsaws");
msg("- grindstones");
msg("- jukeboxes");
msg("- spawners");
msg("- 4chan");
msg("- beehives");
msg("- respawnanchors");
msg("- autotp");
msg("- autoclear");
msg("- minecarts");
msg("- landmines");
msg("- mp44");
msg("- tossmob");
msg("- gravity");
return false;
}
@ -282,16 +304,6 @@ public class Command_toggle extends FreedomCommand
toggle("Block gravity is", ConfigEntry.ALLOW_GRAVITY);
break;
}
default:
{
msg("Available toggles: ");
for (String toggle : toggles)
{
msg("- " + toggle);
}
return false;
}
}
return true;
}

View file

@ -10,6 +10,7 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Toggle item pickup.", usage = "/<command>")
public class Command_togglepickup extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{

View file

@ -15,6 +15,7 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Sends a verification code to the player, or the player can input the sent code. Admins can manually verify a player impostor.", usage = "/<command> <code | <playername>>")
public class Command_verify extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{

View file

@ -1,34 +1,34 @@
package me.totalfreedom.totalfreedommod.command;
import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
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;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Information on how to vote", usage = "/<command>")
public class Command_vote extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
List<String> voteInfo = ConfigEntry.VOTING_INFO.getStringList();
if (voteInfo.isEmpty())
{
msg("The voting information section of the config.yml file has not been configured.", ChatColor.RED);
}
else
{
msg(FUtil.colorize(StringUtils.join(voteInfo, "\n")));
}
return true;
}
}
package me.totalfreedom.totalfreedommod.command;
import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
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;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH)
@CommandParameters(description = "Information on how to vote", usage = "/<command>")
public class Command_vote extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
List<String> voteInfo = ConfigEntry.VOTING_INFO.getStringList();
if (voteInfo.isEmpty())
{
msg("The voting information section of the config.yml file has not been configured.", ChatColor.RED);
}
else
{
msg(FUtil.colorize(StringUtils.join(voteInfo, "\n")));
}
return true;
}
}

View file

@ -1,9 +1,6 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
@ -56,28 +53,25 @@ public class Command_warn extends FreedomCommand
String warnReason = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " ");
player.sendTitle(ChatColor.RED + "You've been warned.", ChatColor.YELLOW + "Reason: " + warnReason, 20, 100, 60);
msg(player, ChatColor.RED + "[WARNING] You received a warning from " + sender.getName() + ": " + warnReason);
plugin.pl.getPlayer(player).incrementWarnings(quiet);
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.WARN, warnReason));
msg(ChatColor.GREEN + "You have successfully warned " + player.getName());
if (quiet)
{
msg("You have successfully warned " + player.getName() + " quietly.");
msg("Warned " + player.getName() + " quietly");
return true;
}
else
{
String adminNotice = ChatColor.RED +
sender.getName() +
" - " +
"Warning: " +
player.getName() +
" - Reason: " +
ChatColor.YELLOW +
warnReason;
plugin.al.messageAllAdmins(adminNotice);
msg("You have successfully warned " + player.getName() + ".");
}
msg(player, ChatColor.RED + "[WARNING] You received a warning from " + sender.getName() + ": " + warnReason);
String adminNotice = ChatColor.RED +
sender.getName() +
" - " +
"Warning: " +
player.getName() +
" - Reason: " +
ChatColor.YELLOW +
warnReason;
plugin.al.messageAllAdmins(adminNotice);
plugin.pl.getPlayer(player).incrementWarnings();
return true;
}
}

View file

@ -47,6 +47,8 @@ public enum ConfigEntry
//
HTTPD_ENABLED(Boolean.class, "httpd.enabled"),
HTTPD_HOST(String.class, "httpd.host"),
HTTPD_REVERSE_PROXY(Boolean.class, "httpd.reverse_proxy"),
HTTPD_REVERSE_PROXY_PORT(Integer.class, "httpd.reverse_proxy_port"),
HTTPD_PORT(Integer.class, "httpd.port"),
HTTPD_PUBLIC_FOLDER(String.class, "httpd.public_folder"),
//
@ -76,6 +78,7 @@ public enum ConfigEntry
DISCORD_REPORT_CHANNEL_ID(String.class, "discord.report_channel_id"),
DISCORD_CHAT_CHANNEL_ID(String.class, "discord.chat_channel_id"),
DISCORD_ADMINCHAT_CHANNEL_ID(String.class, "discord.adminchat_channel_id"),
DISCORD_ROLE_SYNC(Boolean.class, "discord.role_sync"),
DISCORD_SERVER_ID(String.class, "discord.server_id"),
DISCORD_MASTER_BUILDER_ROLE_ID(String.class, "discord.master_builder_role_id"),
@ -126,12 +129,17 @@ public enum ConfigEntry
ENABLE_PREPROCESS_LOG(Boolean.class, "preprocess_log"),
ENABLE_PET_PROTECT(Boolean.class, "petprotect.enabled"),
//
LANDMINES_ENABLED(Boolean.class, "landmines_enabled"),
TOSSMOB_ENABLED(Boolean.class, "tossmob_enabled"),
AUTOKICK_ENABLED(Boolean.class, "autokick.enabled"),
MP44_ENABLED(Boolean.class, "mp44_enabled"),
FOURCHAN_ENABLED(Boolean.class, "4chan_enabled"),
//
NUKE_MONITOR_ENABLED(Boolean.class, "nukemonitor.enabled"),
NUKE_MONITOR_COUNT_BREAK(Integer.class, "nukemonitor.count_break"),
NUKE_MONITOR_COUNT_PLACE(Integer.class, "nukemonitor.count_place"),
NUKE_MONITOR_RANGE(Double.class, "nukemonitor.range"),
//
AUTOKICK_ENABLED(Boolean.class, "autokick.enabled"),
AUTOKICK_THRESHOLD(Double.class, "autokick.threshold"),
AUTOKICK_TIME(Integer.class, "autokick.time"),
//

View file

@ -473,9 +473,9 @@ public class Discord extends FreedomService
if (bot != null)
{
messageChatChannel("**Server has stopped**");
bot.shutdown();
FLog.info("Discord verification bot has successfully shutdown.");
}
FLog.info("Discord verification bot has successfully shutdown.");
}
public String deformat(String input)

View file

@ -128,7 +128,7 @@ public class ItemFun extends FreedomService
LivingEntity livingEntity = (LivingEntity)event.getRightClicked();
EntityType entityType = livingEntity.getType();
if (entityType != fPlayer.mobThrowerCreature())
if (!(entityType == fPlayer.mobThrowerCreature()))
{
return;
}
@ -304,11 +304,6 @@ public class ItemFun extends FreedomService
}
break;
}
default:
{
// Do nothing
break;
}
}
}

View file

@ -73,7 +73,7 @@ public class Landminer extends FreedomService
continue;
}
if (player.getLocation().distanceSquared(location) > (landmine.radius * landmine.radius))
if (!(player.getLocation().distanceSquared(location) <= (landmine.radius * landmine.radius)))
{
break;
}

View file

@ -8,7 +8,6 @@ import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD;
public class Module_activitylog extends HTTPDModule
{
public Module_activitylog(NanoHTTPD.HTTPSession session)
{
super(session);

View file

@ -8,7 +8,6 @@ import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD;
public class Module_indefbans extends HTTPDModule
{
public Module_indefbans(NanoHTTPD.HTTPSession session)
{
super(session);
@ -17,7 +16,7 @@ public class Module_indefbans extends HTTPDModule
@Override
public NanoHTTPD.Response getResponse()
{
File permbanFile = new File(plugin.getDataFolder(), IndefiniteBanList.CONFIG_FILENAME);
File indefbanFile = new File(plugin.getDataFolder(), IndefiniteBanList.CONFIG_FILENAME);
final String remoteAddress = socket.getInetAddress().getHostAddress();
if (!isAuthorized(remoteAddress))
@ -25,7 +24,7 @@ public class Module_indefbans extends HTTPDModule
return new NanoHTTPD.Response(NanoHTTPD.Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT,
"You may not view the indefinite ban list. Your IP, " + remoteAddress + ", is not registered to an admin on the server.");
}
if (permbanFile.exists())
if (indefbanFile.exists())
{
return HTTPDaemon.serveFileBasic(new File(plugin.getDataFolder(), IndefiniteBanList.CONFIG_FILENAME));
}

View file

@ -42,10 +42,10 @@ public class Module_index extends HTTPDModule
// <a href="http://localhost:28966/index">index</a>
sb.append("<ul><li>");
sb.append("<a href=\"http://")
sb.append(ConfigEntry.HTTPD_REVERSE_PROXY.getBoolean() ? "<a href=\"https://" : "<a href=\"http://")
.append(ConfigEntry.HTTPD_HOST.getString())
.append(":")
.append(ConfigEntry.HTTPD_PORT.getInteger())
.append(ConfigEntry.HTTPD_REVERSE_PROXY.getBoolean() ? ConfigEntry.HTTPD_REVERSE_PROXY_PORT : ConfigEntry.HTTPD_PORT)
.append("/")
.append(name)
.append("\">")

View file

@ -79,20 +79,11 @@ public class Module_list extends HTTPDModule
switch (admin.getRank())
{
case ADMIN:
{
admins.add(player.getName());
break;
}
case SENIOR_ADMIN:
{
senioradmins.add(player.getName());
break;
}
default:
{
// Do nothing
break;
}
}
}
}

View file

@ -71,8 +71,7 @@ public class Module_logfile extends HTTPDModule
switch (mode)
{
case LIST:
{
case LIST -> {
if (isAuthorized(remoteAddress))
{
@ -100,10 +99,8 @@ public class Module_logfile extends HTTPDModule
.append(StringUtils.join(LogFilesFormatted, "\r\n"))
.append("</ul>");
}
break;
}
case DOWNLOAD:
{
case DOWNLOAD -> {
if (isAuthorized(remoteAddress))
{
out.append(HTMLGenerationTools.paragraph("Log files access denied: Your IP, " + remoteAddress + ", is not registered to an admin on this server."));
@ -121,25 +118,22 @@ public class Module_logfile extends HTTPDModule
out.append(HTMLGenerationTools.paragraph("Error downloading logfile: " + ex.getMessage()));
}
}
break;
}
default:
{
default -> {
out.append(HTMLGenerationTools.heading("Logfile Submodules", 1));
out.append("<ul><li>");
out.append("<a href=\"http://")
out.append("<a href=\"https://")
.append(ConfigEntry.HTTPD_HOST.getString())
.append(":")
.append(ConfigEntry.HTTPD_PORT.getInteger())
.append("28966")
.append("/logfile/list")
.append("\">Logfile List</a></li>")
.append("<li><a href=\"http://")
.append("<li><a href=\"https://")
.append(ConfigEntry.HTTPD_HOST.getString())
.append(":")
.append(ConfigEntry.HTTPD_PORT.getInteger())
.append("28966")
.append("/logfile/download")
.append("\">Download Specified Logfile</a></li></ul>");
break;
}
}
return out.toString();
@ -210,7 +204,6 @@ public class Module_logfile extends HTTPDModule
private static class ResponseOverrideException extends Exception
{
private final Response response;
public ResponseOverrideException(Response response)

View file

@ -7,7 +7,6 @@ import me.totalfreedom.totalfreedommod.util.FLog;
public class Module_logs extends Module_file
{
public Module_logs(NanoHTTPD.HTTPSession session)
{
super(session);

View file

@ -11,7 +11,6 @@ import org.json.simple.JSONObject;
public class Module_players extends HTTPDModule
{
public Module_players(NanoHTTPD.HTTPSession session)
{
super(session);
@ -51,20 +50,11 @@ public class Module_players extends HTTPDModule
switch (admin.getRank())
{
case ADMIN:
{
admins.add(username);
break;
}
case SENIOR_ADMIN:
{
senioradmins.add(username);
break;
}
default:
{
// Do nothing
break;
}
}
}

View file

@ -17,8 +17,8 @@ public class Module_punishments extends HTTPDModule
@Override
public NanoHTTPD.Response getResponse()
{
File adminFile = new File(plugin.getDataFolder(), PunishmentList.CONFIG_FILENAME);
if (adminFile.exists())
File punishmentFile = new File(plugin.getDataFolder(), PunishmentList.CONFIG_FILENAME);
if (punishmentFile.exists())
{
final String remoteAddress = socket.getInetAddress().getHostAddress();
if (!isAuthorized(remoteAddress))

View file

@ -27,7 +27,6 @@ import org.apache.commons.lang3.StringUtils;
public class Module_schematic extends HTTPDModule
{
private static final File SCHEMATIC_FOLDER = new File("./plugins/WorldEdit/schematics/");
private static final String REQUEST_FORM_FILE_ELEMENT_NAME = "schematicFile";
private static final Pattern SCHEMATIC_FILENAME_LC = Pattern.compile("^[a-z0-9_'!,\\-]*\\.(schem|schematic)$");
@ -162,16 +161,16 @@ public class Module_schematic extends HTTPDModule
{
out.append(HTMLGenerationTools.heading("Schematic Submodules", 1));
out.append("<ul><li>");
out.append("<a href=\"http://")
out.append(ConfigEntry.HTTPD_REVERSE_PROXY.getBoolean() ? "<a href=\"https://" : "<a href=\"http://")
.append(ConfigEntry.HTTPD_HOST.getString())
.append(":")
.append(ConfigEntry.HTTPD_PORT.getInteger())
.append(ConfigEntry.HTTPD_REVERSE_PROXY.getBoolean() ? ConfigEntry.HTTPD_REVERSE_PROXY_PORT : ConfigEntry.HTTPD_PORT)
.append("/schematic/list")
.append("\">Schematic List</a></li>")
.append("<li><a href=\"http://")
.append(ConfigEntry.HTTPD_REVERSE_PROXY.getBoolean() ? "<a href=\"https://" : "<a href=\"http://")
.append(ConfigEntry.HTTPD_HOST.getString())
.append(":")
.append(ConfigEntry.HTTPD_PORT.getInteger())
.append(ConfigEntry.HTTPD_REVERSE_PROXY.getBoolean() ? ConfigEntry.HTTPD_REVERSE_PROXY_PORT : ConfigEntry.HTTPD_PORT)
.append("/schematic/upload")
.append("\">Upload Schematics</a></li></ul>");
break;

View file

@ -1,5 +1,7 @@
package me.totalfreedom.totalfreedommod.player;
import java.util.ArrayList;
import java.util.List;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.caging.CageData;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
@ -14,12 +16,8 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.ArrayList;
import java.util.List;
public class FPlayer
{
public static final long AUTO_PURGE_TICKS = 5L * 60L * 20L;
@ -249,7 +247,7 @@ public class FPlayer
public void startArrowShooter(TotalFreedomMod plugin)
{
this.stopArrowShooter();
this.mp44ScheduleTask = new ArrowShooter(getPlayer()).runTaskTimer(plugin, 1L, 1L);
this.mp44ScheduleTask = new ArrowShooter(this.player).runTaskTimer(plugin, 1L, 1L);
this.mp44Firing = true;
}
@ -431,19 +429,14 @@ public class FPlayer
this.warningCount = warningCount;
}
public void incrementWarnings(boolean quiet)
public void incrementWarnings()
{
this.warningCount++;
if (this.warningCount % 2 == 0)
{
Player p = getPlayer();
if (!quiet)
{
p.getWorld().strikeLightning(p.getLocation());
}
p.getWorld().strikeLightning(p.getLocation());
FUtil.playerMsg(p, ChatColor.RED + "You have been warned at least twice now, make sure to read the rules at " + ConfigEntry.SERVER_BAN_URL.getString());
}
}
@ -711,11 +704,8 @@ public class FPlayer
@Override
public void run()
{
if (player != null)
{
Arrow shot = player.launchProjectile(Arrow.class);
shot.setVelocity(shot.getVelocity().multiply(2.0));
}
Arrow shot = player.launchProjectile(Arrow.class);
shot.setVelocity(shot.getVelocity().multiply(2.0));
}
}
}

View file

@ -7,11 +7,5 @@ public enum PunishmentType
KICK,
TEMPBAN,
BAN,
DOOM,
WARN,
CAGE,
BLOCKEDIT,
BLOCKPVP,
BLOCKCMD,
ORBIT
DOOM
}

View file

@ -1,425 +1,425 @@
package me.totalfreedom.totalfreedommod.shop;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
public class Shop extends FreedomService
{
public final int coinsPerReactionWin = ConfigEntry.SHOP_REACTIONS_COINS_PER_WIN.getInteger();
public final String prefix = ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + "Reaction" + ChatColor.DARK_GRAY + "] ";
private final String LOGIN_MESSAGE_GUI_TITLE = ChatColor.DARK_GREEN + ChatColor.BOLD.toString() + "Login Messages";
public String reactionString = "";
public Date reactionStartTime;
public BukkitTask countdownTask;
private BukkitTask reactions;
private BossBar countdownBar = null;
@Override
public void onStart()
{
if (ConfigEntry.SHOP_REACTIONS_ENABLED.getBoolean())
{
startReactionTimer();
}
}
public void startReactionTimer()
{
long interval = ConfigEntry.SHOP_REACTIONS_INTERVAL.getInteger() * 20L;
reactions = new BukkitRunnable()
{
@Override
public void run()
{
startReaction();
}
}.runTaskLater(plugin, interval);
}
public void forceStartReaction()
{
reactions.cancel();
startReaction();
}
public void startReaction()
{
if (!ConfigEntry.SHOP_ENABLED.getBoolean())
{
FLog.debug("The shop is not enabled, therefore a reaction did not start.");
return;
}
reactionString = FUtil.randomAlphanumericString(ConfigEntry.SHOP_REACTIONS_STRING_LENGTH.getInteger());
FUtil.bcastMsg(prefix + ChatColor.AQUA + "Enter the code above to win " + ChatColor.GOLD + coinsPerReactionWin + ChatColor.AQUA + " coins!", false);
reactionStartTime = new Date();
countdownBar = server.createBossBar(reactionString, BarColor.GREEN, BarStyle.SOLID);
for (Player player : server.getOnlinePlayers())
{
countdownBar.addPlayer(player);
}
countdownBar.setVisible(true);
countdownTask = new BukkitRunnable()
{
double seconds = 30;
final double max = seconds;
@Override
public void run()
{
if ((seconds -= 1) == 0)
{
endReaction(null);
}
else
{
countdownBar.setProgress(seconds / max);
if (!countdownBar.getColor().equals(BarColor.YELLOW) && seconds / max <= 0.25)
{
countdownBar.setColor(BarColor.YELLOW);
}
}
}
}.runTaskTimer(plugin, 0, 20);
}
public void endReaction(String winner)
{
countdownTask.cancel();
countdownBar.removeAll();
countdownBar = null;
reactionString = "";
if (winner != null)
{
Date currentTime = new Date();
long seconds = (currentTime.getTime() - reactionStartTime.getTime()) / 1000;
FUtil.bcastMsg(prefix + ChatColor.GREEN + winner + ChatColor.AQUA + " won in " + seconds + " seconds!", false);
startReactionTimer();
return;
}
FUtil.bcastMsg(prefix + ChatColor.RED + "No one reacted fast enough", false);
startReactionTimer();
}
@Override
public void onStop()
{
if (ConfigEntry.SHOP_REACTIONS_ENABLED.getBoolean())
{
reactions.cancel();
}
}
public String getShopPrefix()
{
return FUtil.colorize(ConfigEntry.SHOP_PREFIX.getString());
}
public String getShopTitle()
{
return FUtil.colorize(ConfigEntry.SHOP_TITLE.getString());
}
public Inventory generateShopGUI(PlayerData playerData)
{
Inventory gui = server.createInventory(null, 36, getShopTitle());
for (int slot = 0; slot < 36; slot++)
{
ItemStack blank = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
ItemMeta meta = blank.getItemMeta();
assert meta != null;
meta.setDisplayName(" ");
blank.setItemMeta(meta);
gui.setItem(slot, blank);
}
for (ShopItem shopItem : ShopItem.values())
{
ItemStack item = shopGUIItem(shopItem, playerData);
gui.setItem(shopItem.getSlot(), item);
}
// Coins
ItemStack coins = new ItemStack(Material.GOLD_NUGGET);
ItemMeta meta = coins.getItemMeta();
assert meta != null;
meta.setDisplayName(FUtil.colorize("&c&lYou have &e&l" + playerData.getCoins() + "&c&l coins"));
coins.setItemMeta(meta);
gui.setItem(35, coins);
return gui;
}
public Inventory generateLoginMessageGUI(Player player)
{
Inventory gui = server.createInventory(null, 36, LOGIN_MESSAGE_GUI_TITLE);
int slot = 0;
for (String loginMessage : ConfigEntry.SHOP_LOGIN_MESSAGES.getStringList())
{
ItemStack icon = new ItemStack(Material.NAME_TAG);
ItemMeta meta = icon.getItemMeta();
assert meta != null;
meta.setDisplayName(FUtil.colorize(plugin.rm.craftLoginMessage(player, loginMessage)));
icon.setItemMeta(meta);
gui.setItem(slot, icon);
slot++;
}
ItemStack clear = new ItemStack(Material.BARRIER);
ItemMeta meta = clear.getItemMeta();
assert meta != null;
meta.setDisplayName(ChatColor.RED + "Clear login message");
clear.setItemMeta(meta);
gui.setItem(35, clear);
return gui;
}
public boolean isRealItem(PlayerData data, ShopItem shopItem, PlayerInventory inventory, ItemStack realItem)
{
return isRealItem(data, shopItem, inventory.getItemInMainHand(), realItem) || isRealItem(data, shopItem, inventory.getItemInOffHand(), realItem);
}
public boolean isRealItem(PlayerData data, ShopItem shopItem, ItemStack givenItem, ItemStack realItem)
{
if (!data.hasItem(shopItem) || !givenItem.getType().equals(realItem.getType()))
{
return false;
}
ItemMeta givenMeta = givenItem.getItemMeta();
ItemMeta realMeta = realItem.getItemMeta();
assert givenMeta != null;
assert realMeta != null;
return givenMeta.getDisplayName().equals(realMeta.getDisplayName()) && Objects.equals(givenMeta.getLore(), realMeta.getLore());
}
public ItemStack getLightningRod()
{
ItemStack itemStack = new ItemStack(Material.BLAZE_ROD);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(FUtil.colorize("&bL&3i&bg&3h&bt&3n&bi&3n&bg &3R&bo&3d"));
itemMeta.setLore(Arrays.asList(ChatColor.AQUA + "Strike others down with the power of lightning.", ChatColor.RED + ChatColor.ITALIC.toString() + "The classic way to exterminate annoyances."));
itemMeta.addEnchant(Enchantment.CHANNELING, 1, false);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getGrapplingHook()
{
ItemStack itemStack = new ItemStack(Material.FISHING_ROD);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.YELLOW + "Grappling Hook");
itemMeta.setLore(Collections.singletonList(ChatColor.GREEN + "be spider-man but ghetto"));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getFireBall()
{
ItemStack itemStack = new ItemStack(Material.FIRE_CHARGE);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.RED + "Fire Ball");
itemMeta.setLore(Collections.singletonList(ChatColor.GOLD + "Yeet this at people"));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getRideablePearl()
{
ItemStack itemStack = new ItemStack(Material.ENDER_PEARL);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.DARK_PURPLE + "Rideable Ender Pearl");
itemMeta.setLore(Arrays.asList(ChatColor.LIGHT_PURPLE + "What the title says.", "", ChatColor.WHITE + ChatColor.ITALIC.toString() + "TotalFreedom is not responsible for any injuries", ChatColor.WHITE + ChatColor.ITALIC.toString() + "sustained while using this item."));
itemMeta.addEnchant(Enchantment.BINDING_CURSE, 1, false);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getStackingPotato()
{
ItemStack itemStack = new ItemStack(Material.POTATO);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.YELLOW + "Stacking Potato");
itemMeta.setLore(Collections.singletonList(ChatColor.GREEN + "Left click to ride a mob, right click to put a mob on your head."));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getClownFish()
{
ItemStack itemStack = new ItemStack(Material.TROPICAL_FISH);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.GOLD + "Clown Fish");
itemMeta.setLore(Collections.singletonList(ChatColor.AQUA + ":clown:"));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public boolean canAfford(int price, int coins)
{
return coins >= price;
}
public int amountNeeded(int price, int coins)
{
return price - coins;
}
public ItemStack shopGUIItem(ShopItem item, PlayerData data)
{
ItemStack itemStack = new ItemStack(item.getIcon());
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(item.getColoredName());
int price = item.getCost();
int coins = data.getCoins();
boolean canAfford = canAfford(price, coins);
List<String> lore = new ArrayList<>();
if (!data.hasItem(item))
{
lore.add(ChatColor.GOLD + "Price: " + (canAfford ? ChatColor.DARK_GREEN : ChatColor.RED) + price);
if (!canAfford)
{
lore.add(ChatColor.RED + "You can not afford this item!");
lore.add(ChatColor.RED + "You need " + amountNeeded(price, coins) + " more coins to buy this item.");
}
}
else
{
lore.add(ChatColor.RED + "You already purchased this item.");
}
itemMeta.setLore(lore);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
@EventHandler(priority = EventPriority.HIGH)
public void onShopGUIClick(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player))
{
return;
}
Inventory inventory = event.getInventory();
if (inventory.getSize() != 36 || !event.getView().getTitle().equals(getShopTitle()))
{
return;
}
event.setCancelled(true);
ShopItem shopItem = getShopItem(event.getSlot());
if (shopItem == null)
{
return;
}
Player player = (Player)event.getWhoClicked();
PlayerData playerData = plugin.pl.getData(player);
int price = shopItem.getCost();
int coins = playerData.getCoins();
if (playerData.hasItem(shopItem) || !canAfford(price, coins))
{
return;
}
playerData.giveItem(shopItem);
playerData.setCoins(coins - price);
plugin.pl.save(playerData);
player.closeInventory();
player.sendMessage(getShopPrefix() + " " + ChatColor.GREEN + "Successfully purchased the \"" + shopItem.getColoredName() + ChatColor.GREEN + "\" for " + ChatColor.GOLD + price + ChatColor.GREEN + "!");
if (shopItem.getCommand() != null)
{
player.sendMessage(ChatColor.GREEN + "Run " + shopItem.getCommand() + " to get one!");
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onLoginMessageGUIClick(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player))
{
return;
}
Inventory inventory = event.getInventory();
if (inventory.getSize() != 36 || !event.getView().getTitle().equals(LOGIN_MESSAGE_GUI_TITLE))
{
return;
}
event.setCancelled(true);
int slot = event.getSlot();
Player player = (Player)event.getWhoClicked();
PlayerData data = plugin.pl.getData(player);
if (slot == 35)
{
data.setLoginMessage(null);
plugin.pl.save(data);
player.sendMessage(ChatColor.GREEN + "Removed your login message");
}
else
{
String message = ConfigEntry.SHOP_LOGIN_MESSAGES.getStringList().get(slot);
data.setLoginMessage(message);
plugin.pl.save(data);
player.sendMessage(ChatColor.GREEN + "Your login message is now the following:\n" + plugin.rm.craftLoginMessage(player, message));
}
player.closeInventory();
}
public ShopItem getShopItem(int slot)
{
for (ShopItem shopItem : ShopItem.values())
{
if (shopItem.getSlot() == slot)
{
return shopItem;
}
}
return null;
}
package me.totalfreedom.totalfreedommod.shop;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
public class Shop extends FreedomService
{
public final int coinsPerReactionWin = ConfigEntry.SHOP_REACTIONS_COINS_PER_WIN.getInteger();
public final String prefix = ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + "Reaction" + ChatColor.DARK_GRAY + "] ";
private final String LOGIN_MESSAGE_GUI_TITLE = ChatColor.DARK_GREEN + ChatColor.BOLD.toString() + "Login Messages";
public String reactionString = "";
public Date reactionStartTime;
public BukkitTask countdownTask;
private BukkitTask reactions;
private BossBar countdownBar = null;
@Override
public void onStart()
{
if (ConfigEntry.SHOP_REACTIONS_ENABLED.getBoolean())
{
startReactionTimer();
}
}
public void startReactionTimer()
{
long interval = ConfigEntry.SHOP_REACTIONS_INTERVAL.getInteger() * 20L;
reactions = new BukkitRunnable()
{
@Override
public void run()
{
startReaction();
}
}.runTaskLater(plugin, interval);
}
public void forceStartReaction()
{
reactions.cancel();
startReaction();
}
public void startReaction()
{
if (!ConfigEntry.SHOP_ENABLED.getBoolean())
{
FLog.debug("The shop is not enabled, therefore a reaction did not start.");
return;
}
reactionString = FUtil.randomAlphanumericString(ConfigEntry.SHOP_REACTIONS_STRING_LENGTH.getInteger());
FUtil.bcastMsg(prefix + ChatColor.AQUA + "Enter the code above to win " + ChatColor.GOLD + coinsPerReactionWin + ChatColor.AQUA + " coins!", false);
reactionStartTime = new Date();
countdownBar = server.createBossBar(reactionString, BarColor.GREEN, BarStyle.SOLID);
for (Player player : server.getOnlinePlayers())
{
countdownBar.addPlayer(player);
}
countdownBar.setVisible(true);
countdownTask = new BukkitRunnable()
{
double seconds = 30;
final double max = seconds;
@Override
public void run()
{
if ((seconds -= 1) == 0)
{
endReaction(null);
}
else
{
countdownBar.setProgress(seconds / max);
if (!countdownBar.getColor().equals(BarColor.YELLOW) && seconds / max <= 0.25)
{
countdownBar.setColor(BarColor.YELLOW);
}
}
}
}.runTaskTimer(plugin, 0, 20);
}
public void endReaction(String winner)
{
countdownTask.cancel();
countdownBar.removeAll();
countdownBar = null;
reactionString = "";
if (winner != null)
{
Date currentTime = new Date();
long seconds = (currentTime.getTime() - reactionStartTime.getTime()) / 1000;
FUtil.bcastMsg(prefix + ChatColor.GREEN + winner + ChatColor.AQUA + " won in " + seconds + " seconds!", false);
startReactionTimer();
return;
}
FUtil.bcastMsg(prefix + ChatColor.RED + "No one reacted fast enough", false);
startReactionTimer();
}
@Override
public void onStop()
{
if (ConfigEntry.SHOP_REACTIONS_ENABLED.getBoolean())
{
reactions.cancel();
}
}
public String getShopPrefix()
{
return FUtil.colorize(ConfigEntry.SHOP_PREFIX.getString());
}
public String getShopTitle()
{
return FUtil.colorize(ConfigEntry.SHOP_TITLE.getString());
}
public Inventory generateShopGUI(PlayerData playerData)
{
Inventory gui = server.createInventory(null, 36, getShopTitle());
for (int slot = 0; slot < 36; slot++)
{
ItemStack blank = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
ItemMeta meta = blank.getItemMeta();
assert meta != null;
meta.setDisplayName(" ");
blank.setItemMeta(meta);
gui.setItem(slot, blank);
}
for (ShopItem shopItem : ShopItem.values())
{
ItemStack item = shopGUIItem(shopItem, playerData);
gui.setItem(shopItem.getSlot(), item);
}
// Coins
ItemStack coins = new ItemStack(Material.GOLD_NUGGET);
ItemMeta meta = coins.getItemMeta();
assert meta != null;
meta.setDisplayName(FUtil.colorize("&c&lYou have &e&l" + playerData.getCoins() + "&c&l coins"));
coins.setItemMeta(meta);
gui.setItem(35, coins);
return gui;
}
public Inventory generateLoginMessageGUI(Player player)
{
Inventory gui = server.createInventory(null, 36, LOGIN_MESSAGE_GUI_TITLE);
int slot = 0;
for (String loginMessage : ConfigEntry.SHOP_LOGIN_MESSAGES.getStringList())
{
ItemStack icon = new ItemStack(Material.NAME_TAG);
ItemMeta meta = icon.getItemMeta();
assert meta != null;
meta.setDisplayName(FUtil.colorize(plugin.rm.craftLoginMessage(player, loginMessage)));
icon.setItemMeta(meta);
gui.setItem(slot, icon);
slot++;
}
ItemStack clear = new ItemStack(Material.BARRIER);
ItemMeta meta = clear.getItemMeta();
assert meta != null;
meta.setDisplayName(ChatColor.RED + "Clear login message");
clear.setItemMeta(meta);
gui.setItem(35, clear);
return gui;
}
public boolean isRealItem(PlayerData data, ShopItem shopItem, PlayerInventory inventory, ItemStack realItem)
{
return isRealItem(data, shopItem, inventory.getItemInMainHand(), realItem) || isRealItem(data, shopItem, inventory.getItemInOffHand(), realItem);
}
public boolean isRealItem(PlayerData data, ShopItem shopItem, ItemStack givenItem, ItemStack realItem)
{
if (!data.hasItem(shopItem) || !givenItem.getType().equals(realItem.getType()))
{
return false;
}
ItemMeta givenMeta = givenItem.getItemMeta();
ItemMeta realMeta = realItem.getItemMeta();
assert givenMeta != null;
assert realMeta != null;
return givenMeta.getDisplayName().equals(realMeta.getDisplayName()) && Objects.equals(givenMeta.getLore(), realMeta.getLore());
}
public ItemStack getLightningRod()
{
ItemStack itemStack = new ItemStack(Material.BLAZE_ROD);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(FUtil.colorize("&bL&3i&bg&3h&bt&3n&bi&3n&bg &3R&bo&3d"));
itemMeta.setLore(Arrays.asList(ChatColor.AQUA + "Strike others down with the power of lightning.", ChatColor.RED + ChatColor.ITALIC.toString() + "The classic way to exterminate annoyances."));
itemMeta.addEnchant(Enchantment.CHANNELING, 1, false);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getGrapplingHook()
{
ItemStack itemStack = new ItemStack(Material.FISHING_ROD);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.YELLOW + "Grappling Hook");
itemMeta.setLore(Collections.singletonList(ChatColor.GREEN + "be spider-man but ghetto"));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getFireBall()
{
ItemStack itemStack = new ItemStack(Material.FIRE_CHARGE);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.RED + "Fire Ball");
itemMeta.setLore(Collections.singletonList(ChatColor.GOLD + "Yeet this at people"));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getRideablePearl()
{
ItemStack itemStack = new ItemStack(Material.ENDER_PEARL);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.DARK_PURPLE + "Rideable Ender Pearl");
itemMeta.setLore(Arrays.asList(ChatColor.LIGHT_PURPLE + "What the title says.", "", ChatColor.WHITE + ChatColor.ITALIC.toString() + "TotalFreedom is not responsible for any injuries", ChatColor.WHITE + ChatColor.ITALIC.toString() + "sustained while using this item."));
itemMeta.addEnchant(Enchantment.BINDING_CURSE, 1, false);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getStackingPotato()
{
ItemStack itemStack = new ItemStack(Material.POTATO);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.YELLOW + "Stacking Potato");
itemMeta.setLore(Collections.singletonList(ChatColor.GREEN + "Left click to ride a mob, right click to put a mob on your head."));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public ItemStack getClownFish()
{
ItemStack itemStack = new ItemStack(Material.TROPICAL_FISH);
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.GOLD + "Clown Fish");
itemMeta.setLore(Collections.singletonList(ChatColor.AQUA + ":clown:"));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public boolean canAfford(int price, int coins)
{
return coins >= price;
}
public int amountNeeded(int price, int coins)
{
return price - coins;
}
public ItemStack shopGUIItem(ShopItem item, PlayerData data)
{
ItemStack itemStack = new ItemStack(item.getIcon());
ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null;
itemMeta.setDisplayName(item.getColoredName());
int price = item.getCost();
int coins = data.getCoins();
boolean canAfford = canAfford(price, coins);
List<String> lore = new ArrayList<>();
if (!data.hasItem(item))
{
lore.add(ChatColor.GOLD + "Price: " + (canAfford ? ChatColor.DARK_GREEN : ChatColor.RED) + price);
if (!canAfford)
{
lore.add(ChatColor.RED + "You can not afford this item!");
lore.add(ChatColor.RED + "You need " + amountNeeded(price, coins) + " more coins to buy this item.");
}
}
else
{
lore.add(ChatColor.RED + "You already purchased this item.");
}
itemMeta.setLore(lore);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
@EventHandler(priority = EventPriority.HIGH)
public void onShopGUIClick(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player))
{
return;
}
Inventory inventory = event.getInventory();
if (inventory.getSize() != 36 || !event.getView().getTitle().equals(getShopTitle()))
{
return;
}
event.setCancelled(true);
ShopItem shopItem = getShopItem(event.getSlot());
if (shopItem == null)
{
return;
}
Player player = (Player)event.getWhoClicked();
PlayerData playerData = plugin.pl.getData(player);
int price = shopItem.getCost();
int coins = playerData.getCoins();
if (playerData.hasItem(shopItem) || !canAfford(price, coins))
{
return;
}
playerData.giveItem(shopItem);
playerData.setCoins(coins - price);
plugin.pl.save(playerData);
player.closeInventory();
player.sendMessage(getShopPrefix() + " " + ChatColor.GREEN + "Successfully purchased the \"" + shopItem.getColoredName() + ChatColor.GREEN + "\" for " + ChatColor.GOLD + price + ChatColor.GREEN + "!");
if (shopItem.getCommand() != null)
{
player.sendMessage(ChatColor.GREEN + "Run " + shopItem.getCommand() + " to get one!");
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onLoginMessageGUIClick(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player))
{
return;
}
Inventory inventory = event.getInventory();
if (inventory.getSize() != 36 || !event.getView().getTitle().equals(LOGIN_MESSAGE_GUI_TITLE))
{
return;
}
event.setCancelled(true);
int slot = event.getSlot();
Player player = (Player)event.getWhoClicked();
PlayerData data = plugin.pl.getData(player);
if (slot == 35)
{
data.setLoginMessage(null);
plugin.pl.save(data);
player.sendMessage(ChatColor.GREEN + "Removed your login message");
}
else
{
String message = ConfigEntry.SHOP_LOGIN_MESSAGES.getStringList().get(slot);
data.setLoginMessage(message);
plugin.pl.save(data);
player.sendMessage(ChatColor.GREEN + "Your login message is now the following:\n" + plugin.rm.craftLoginMessage(player, message));
}
player.closeInventory();
}
public ShopItem getShopItem(int slot)
{
for (ShopItem shopItem : ShopItem.values())
{
if (shopItem.getSlot() == slot)
{
return shopItem;
}
}
return null;
}
}

View file

@ -5,7 +5,6 @@ import java.util.logging.Logger;
public class FLog
{
private static final Logger FALLBACK_LOGGER = Logger.getLogger("Minecraft-Server");
private static Logger serverLogger = null;
private static Logger pluginLogger = null;

View file

@ -1,5 +1,32 @@
package me.totalfreedom.totalfreedommod.util;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SplittableRandom;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import org.apache.commons.io.FileUtils;
@ -20,18 +47,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.json.simple.JSONArray;
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.bukkit.Bukkit.getServer;
public class FUtil
@ -49,7 +64,6 @@ public class FUtil
"604cbb51-842d-4b43-8b0a-d1d7c6cd2869", // Wild1145
"e67d77c4-fff9-4cea-94cc-9f1f1ab7806b", // aggelosQQ
"0061326b-8b3d-44c8-830a-5f2d59f5dc1b", // scripthead
"78408086-1991-4c33-a571-d8fa325465b2", // Telesphoreo
"67ce0e28-3d6b-469c-ab71-304eec81b614", // CoolJWB
"03b41e15-d03f-4025-86f5-f1812df200fa", // elmon_
"d018f2b8-ce60-4672-a45f-e580e0331299", // speednt
@ -389,6 +403,10 @@ public class FUtil
add("s");
}};
public static boolean isValidUsername(String s) {
return s != null && s.matches("^[a-zA-Z0-9_]*$");
}
private static long a(String parse)
{
StringBuilder sb = new StringBuilder();

View file

@ -1,114 +1,114 @@
package me.totalfreedom.totalfreedommod.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
public class History
{
public static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void reportHistory(final CommandSender sender, final String username)
{
new BukkitRunnable()
{
@Override
public void run()
{
UUID uuid = UUIDFetcher.fetch(username);
if (uuid != null)
{
Gson gson = new GsonBuilder().create();
String compactUuid = uuid.toString().replace("-", "");
try
{
//UUIDs or playernames actually work with this one
//TODO: fix the stupid api on how it's not working name histories
//URL url = new URL("https://api.ashcon.app/mojang/v2/user/" + compactUuid);
URL url = new URL("https://api.mojang.com/user/profiles/" + compactUuid + "/names");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//conn.setRequestProperty("User-Agent", "");
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
FName[] oldNames = gson.fromJson(reader, FName[].class);
if (oldNames == null)
{
FSync.playerMsg(sender, ChatColor.RED + "Player not found!");
return;
}
reader.close();
conn.disconnect();
Arrays.sort(oldNames);
printHistory(sender, oldNames);
}
catch (Exception ex)
{
FSync.playerMsg(sender, ChatColor.RED + "Error, see logs for more details.");
FLog.severe(ex);
}
}
else
{
FSync.playerMsg(sender, ChatColor.RED + "Player not found!");
}
}
}.runTaskAsynchronously(TotalFreedomMod.getPlugin());
}
private static void printHistory(CommandSender sender, FName[] oldNames)
{
if (oldNames.length == 1)
{
FSync.playerMsg(sender, ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name.");
return;
}
FSync.playerMsg(sender, ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName());
for (int i = 1; i < oldNames.length; i++)
{
Date date = new Date(oldNames[i].getChangedToAt());
String formattedDate = dateFormat.format(date);
FSync.playerMsg(sender, ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName());
}
}
private static class FName implements Comparable<FName>
{
private final String name;
private final long changedToAt;
//Added constructor because otherwise there's no way name or changedToAt would have been anything other than null.
public FName(String name, long changedToAt)
{
this.name = name;
this.changedToAt = changedToAt;
}
@Override
public int compareTo(FName other)
{
return Long.compare(this.changedToAt, other.changedToAt);
}
public String getName()
{
return name;
}
public long getChangedToAt()
{
return changedToAt;
}
}
package me.totalfreedom.totalfreedommod.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
public class History
{
public static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void reportHistory(final CommandSender sender, final String username)
{
new BukkitRunnable()
{
@Override
public void run()
{
UUID uuid = UUIDFetcher.fetch(username);
if (uuid != null)
{
Gson gson = new GsonBuilder().create();
String compactUuid = uuid.toString().replace("-", "");
try
{
//UUIDs or playernames actually work with this one
//TODO: fix the stupid api on how it's not working name histories
//URL url = new URL("https://api.ashcon.app/mojang/v2/user/" + compactUuid);
URL url = new URL("https://api.mojang.com/user/profiles/" + compactUuid + "/names");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//conn.setRequestProperty("User-Agent", "");
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
FName[] oldNames = gson.fromJson(reader, FName[].class);
if (oldNames == null)
{
FSync.playerMsg(sender, ChatColor.RED + "Player not found!");
return;
}
reader.close();
conn.disconnect();
Arrays.sort(oldNames);
printHistory(sender, oldNames);
}
catch (Exception ex)
{
FSync.playerMsg(sender, ChatColor.RED + "Error, see logs for more details.");
FLog.severe(ex);
}
}
else
{
FSync.playerMsg(sender, ChatColor.RED + "Player not found!");
}
}
}.runTaskAsynchronously(TotalFreedomMod.getPlugin());
}
private static void printHistory(CommandSender sender, FName[] oldNames)
{
if (oldNames.length == 1)
{
FSync.playerMsg(sender, ChatColor.GREEN + oldNames[0].getName() + ChatColor.GOLD + " has never changed their name.");
return;
}
FSync.playerMsg(sender, ChatColor.GOLD + "Original name: " + ChatColor.GREEN + oldNames[0].getName());
for (int i = 1; i < oldNames.length; i++)
{
Date date = new Date(oldNames[i].getChangedToAt());
String formattedDate = dateFormat.format(date);
FSync.playerMsg(sender, ChatColor.BLUE + formattedDate + ChatColor.GOLD + " changed to " + ChatColor.GREEN + oldNames[i].getName());
}
}
private static class FName implements Comparable<FName>
{
private final String name;
private final long changedToAt;
//Added constructor because otherwise there's no way name or changedToAt would have been anything other than null.
public FName(String name, long changedToAt)
{
this.name = name;
this.changedToAt = changedToAt;
}
@Override
public int compareTo(FName other)
{
return Long.compare(this.changedToAt, other.changedToAt);
}
public String getName()
{
return name;
}
public long getChangedToAt()
{
return changedToAt;
}
}
}

View file

@ -1,68 +1,68 @@
package me.totalfreedom.totalfreedommod.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
// UUIDFetcher retrieves UUIDs from usernames via web requests to Mojang.
public class UUIDFetcher
{
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
public static UUID fetch(String name)
{
try
{
Gson gson = new GsonBuilder().create();
UUID uuid;
String body = gson.toJson(name);
URL url = new URL(PROFILE_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream stream = connection.getOutputStream();
stream.write(body.getBytes());
stream.flush();
stream.close();
FetchedUuid[] id = gson.fromJson(
new InputStreamReader(connection.getInputStream()),
FetchedUuid[].class);
if (id.length == 0 || id[0].getID() == null)
{
return null;
}
String idd = id[0].getID();
uuid = UUID.fromString(idd.substring(0, 8) + "-" + idd.substring(8, 12)
+ "-" + idd.substring(12, 16) + "-" + idd.substring(16, 20) + "-"
+ idd.substring(20, 32));
return uuid;
}
catch (IOException ex)
{
FLog.severe(ex);
}
return null;
}
private static class FetchedUuid
{
private String id;
public String getID()
{
return id;
}
}
package me.totalfreedom.totalfreedommod.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
// UUIDFetcher retrieves UUIDs from usernames via web requests to Mojang.
public class UUIDFetcher
{
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
public static UUID fetch(String name)
{
try
{
Gson gson = new GsonBuilder().create();
UUID uuid;
String body = gson.toJson(name);
URL url = new URL(PROFILE_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream stream = connection.getOutputStream();
stream.write(body.getBytes());
stream.flush();
stream.close();
FetchedUuid[] id = gson.fromJson(
new InputStreamReader(connection.getInputStream()),
FetchedUuid[].class);
if (id.length == 0 || id[0].getID() == null)
{
return null;
}
String idd = id[0].getID();
uuid = UUID.fromString(idd.substring(0, 8) + "-" + idd.substring(8, 12)
+ "-" + idd.substring(12, 16) + "-" + idd.substring(16, 20) + "-"
+ idd.substring(20, 32));
return uuid;
}
catch (IOException ex)
{
FLog.severe(ex);
}
return null;
}
private static class FetchedUuid
{
private String id;
public String getID()
{
return id;
}
}
}

View file

@ -18,6 +18,7 @@ import org.bukkit.event.player.PlayerMoveEvent;
public final class AdminWorld extends CustomWorld
{
private static final long CACHE_CLEAR_FREQUENCY = 30L * 1000L; //30 seconds, milliseconds
private static final long TP_COOLDOWN_TIME = 500L; //0.5 seconds, milliseconds
private static final String GENERATION_PARAMETERS = ConfigEntry.FLATLANDS_GENERATE_PARAMS.getString();

View file

@ -751,7 +751,11 @@ service_checker_url: http://status.mojang.com/check
httpd:
enabled: true
host: play.totalfreedom.me
# Leave this at false unless you know what you're doing. This will change the HTTPD server to use HTTPS
reverse_proxy: false
port: 28966
# Does not change anything unless the reverse proxy option is set to true
reverse_proxy_port: 28967
public_folder: ./public_html
# Inactivity Auto-Kick (Requires Essentials)

View file

@ -1,50 +1,16 @@
#
# TotalFreedomMod 5.5 Permissions
# TotalFreedomMod Permissions
# by ZeroEpoch1969
#
# Note that every group inherits the previous groups' permissions
# Meaning Telnet Admins have the permissions of Operators and Super Admins, and etc
# Meaning Senior Admins have the permissions of Operators and Admins, and etc
# This is used to remove all permission begging with the root node
# This is useful when a plugin gives all permissions to a player because they are opped
remove:
- "voxelsniper"
- "bending.admin"
- "bending.ability.Cleanse"
- "worldedit.brush.apply"
- "essentials.near.exclude"
- "plots.admin"
- "plots.debugroadregen"
- "plots.debugclaimtest"
- "plots.debugpaste"
- "plots.debugallowunsafe"
- "plots.debugloadtest"
- "plots.debugsavetest"
- "plots.cluster"
#Crackshot
- "crackshot.bypass.all"
#NetworkManager
- "networkmanager.*"
- "networkmanager.notify.joinbanned"
- "networkmanager.notify.*"
- "networkmanager.announce.global"
- "networkmanager.announce"
- "networkmanager.chatlock"
- "networkmanager.clearchat.bypass"
- "networkmanager.clearchat.*"
- "networkmanager.notify.ticket.new"
- "networkmanager.lookup"
- "networkmanager.maintenance.*"
- "networkmanager.permissions"
- "networkmanager.reports"
- "networkmanager.tickets"
- "networkmanager.chatlock.bypass"
- "networkmanager.anticaps.bypass"
- "networkmanager.antispam.bypass"
- "networkmanager.commandblocker.bypass"
- "networkmanager.tags.*"
- "bending"
# Operator permission nodes
operators:
@ -70,79 +36,16 @@ operators:
- "worldedit.removebelow"
- "worldedit.removenear"
- "worldedit.replacenear"
- "worldedit.brush.*"
- "worldedit.global-mask"
- "worldedit.fill"
- "worldedit.fill.recursive"
# LibsDisguises
- "libsdisguises.noactionbar"
# WorldGuard
- "worldguard.region.list.own"
- "worldguard.region.addmember.own.*"
- "worldguard.region.removemember.own.*"
- "worldguard.region.info.*"
# Bending
- "bending.command.add"
- "bending.command.bind"
- "bending.command.check"
- "bending.command.choose"
- "bending.command.rechoose"
- "bending.command.clear"
- "bending.command.copy"
- "bending.command.display"
- "bending.command.help"
- "bending.command.invincible"
- "bending.command.preset"
- "bending.command.preset.list"
- "bending.command.preset.create"
- "bending.command.preset.delete"
- "bending.command.preset.bind"
- "bending.command.preset.bind.assign"
- "bending.command.preset.bind.external"
- "bending.command.toggle"
- "bending.command.version"
- "bending.command.who"
- "bending.earth"
- "bending.air"
- "bending.fire"
- "bending.water"
- "bending.water.bloodbending.anytime"
- "bending.ability.AvatarState"
- "bending.command.add.chi"
- "bending.command.choose.chi"
- "bending.ability.Paralyze"
- "bending.ability.RapidPunch"
- "bending.ability.Smokescreen"
- "bending.ability.WarriorStance"
- "bending.ability.AcrobatStance"
- "bending.ability.QuickStrike"
- "bending.ability.SwiftKick"
- "bending.ability.ChiCombo"
- "bending.chi.passive"
- "bending.ability.MetalClips.throw"
- "bending.ability.AirCombo"
- "bending.ability.Flight"
- "bending.ability.WaterCombo"
- "bending.ability.EarthCombo"
- "bending.ability.FireCombo"
- "bending.ability.ChiCombo"
- "bending.air.passive"
- "bending.chi.passive"
- "bending.earth.passive"
- "bending.fire.passive"
- "bending.water.passive"
# NetworkManager
- "networkmanager.chatlog"
- "networkmanager.find"
- "networkmanager.gtps"
- "networkmanager.lookup"
- "networkmanager.slashserver.*"
- "networkmanager.notification.join"
- "networkmanager.party.nolimit"
- "networkmanager.tabcompletechat"
# Master Builder permission nodes
master_builders:
- "worldedit.tool.*"
@ -156,25 +59,13 @@ master_builders:
- "voxelsniper.sniper"
- "voxelsniper.goto"
- "voxelsniper.brush.*"
# Admin permission nodes
admins:
- "coreprotect.*"
- "worldedit.*"
- "worldguard.*"
- "bending.admin.remove"
- "bending.command.toggle.all"
- "bending.admin.toggle"
- "bending.command.reload"
- "plots.cluster"
- "networkmanager.adminchat"
- "networkmanager.announce.server"
- "networkmanager.socialspy"
- "networkmanager.fullproxy.bypass"
- "networkmanager.lookup.ip"
#Crackshot
- "crackshot.bypass.all"
- "bending.*"
# Senior Admin permission nodes
senior_admins:
- "bending.admin.permaremove"
- "bending.ability.Cleanse"
senior_admins: []