diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 67cd9d6..0000000 --- a/.gitignore +++ /dev/null @@ -1,143 +0,0 @@ -# Created by https://www.gitignore.io/api/java,linux,gradle,intellij -# Edit at https://www.gitignore.io/?templates=java,linux,gradle,intellij - -### Intellij ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/modules.xml -# .idea/*.iml -# .idea/modules - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Intellij Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 - -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr - -# Sonarlint plugin -.idea/sonarlint - -### Java ### -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -### Linux ### -*~ - -# temporary files which can be created if a process still has a handle open of a deleted file -.fuse_hidden* - -# KDE directory preferences -.directory - -# Linux trash folder which might appear on any partition or disk -.Trash-* - -# .nfs files are created when an open file is removed but is still being accessed -.nfs* - -### Gradle ### -.gradle -build/ -bin/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties - -### Gradle Patch ### -**/build/ - -# End of https://www.gitignore.io/api/java,linux,gradle,intellij \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 69ba39f..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index fba829b..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 15a15b2..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 3e68e4d..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - Manifest - - - Spelling - - - - - SpellCheckingInspection - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index aab47ff..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/ModuleLoader.main.iml b/.idea/modules/ModuleLoader.main.iml deleted file mode 100644 index 50a1428..0000000 --- a/.idea/modules/ModuleLoader.main.iml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/ModuleLoader.test.iml b/.idea/modules/ModuleLoader.test.iml deleted file mode 100644 index b9fa95c..0000000 --- a/.idea/modules/ModuleLoader.test.iml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ab48fcd..0000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: java - -jdk: - - openjdk8 - - oraclejdk8 diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 3bbbc1e..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,116 +0,0 @@ -CC0 1.0 Universal - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator and -subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for the -purpose of contributing to a commons of creative, cultural and scientific -works ("Commons") that the public can reliably and without fear of later -claims of infringement build upon, modify, incorporate in other works, reuse -and redistribute as freely as possible in any form whatsoever and for any -purposes, including without limitation commercial purposes. These owners may -contribute to the Commons to promote the ideal of a free culture and the -further production of creative, cultural and scientific works, or to gain -reputation or greater distribution for their Work in part through the use and -efforts of others. - -For these and/or other purposes and motivations, and without any expectation -of additional consideration or compensation, the person associating CC0 with a -Work (the "Affirmer"), to the extent that he or she is an owner of Copyright -and Related Rights in the Work, voluntarily elects to apply CC0 to the Work -and publicly distribute the Work under its terms, with knowledge of his or her -Copyright and Related Rights in the Work and the meaning and intended legal -effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not limited -to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, communicate, - and translate a Work; - - ii. moral rights retained by the original author(s) and/or performer(s); - - iii. publicity and privacy rights pertaining to a person's image or likeness - depicted in a Work; - - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - - v. rights protecting the extraction, dissemination, use and reuse of data in - a Work; - - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - - vii. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer's Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer's heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer's express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, -non transferable, non sublicensable, non exclusive, irrevocable and -unconditional license to exercise Affirmer's Copyright and Related Rights in -the Work (i) in all territories worldwide, (ii) for the maximum duration -provided by applicable law or treaty (including future time extensions), (iii) -in any current or future medium and for any number of copies, and (iv) for any -purpose whatsoever, including without limitation commercial, advertising or -promotional purposes (the "License"). The License shall be deemed effective as -of the date CC0 was applied by Affirmer to the Work. Should any part of the -License for any reason be judged legally invalid or ineffective under -applicable law, such partial invalidity or ineffectiveness shall not -invalidate the remainder of the License, and in such case Affirmer hereby -affirms that he or she will not (i) exercise any of his or her remaining -Copyright and Related Rights in the Work or (ii) assert any associated claims -and causes of action with respect to the Work, in either case contrary to -Affirmer's express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - - b. Affirmer offers the Work as-is and makes no representations or warranties - of any kind concerning the Work, express, implied, statutory or otherwise, - including without limitation warranties of title, merchantability, fitness - for a particular purpose, non infringement, or the absence of latent or - other defects, accuracy, or the present or absence of errors, whether or not - discoverable, all to the greatest extent permissible under applicable law. - - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without limitation - any person's Copyright and Related Rights in the Work. Further, Affirmer - disclaims responsibility for obtaining any necessary consents, permissions - or other rights required for any use of the Work. - - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to this - CC0 or use of the Work. - -For more information, please see - \ No newline at end of file diff --git a/ModuleLoader.iml b/ModuleLoader.iml deleted file mode 100644 index 558676c..0000000 --- a/ModuleLoader.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index a1ece9c..0000000 --- a/build.gradle +++ /dev/null @@ -1,51 +0,0 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - classpath "com.github.jengelman.gradle.plugins:shadow:4.0.2" - } -} - -apply plugin: "com.github.johnrengelman.shadow" -apply plugin: "java" - -repositories { - jcenter() - maven { url "https://jitpack.io" } - - maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" } - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } -} - -dependencies { - implementation "com.github.RedstonerServer:CommandManager:v1" - implementation "com.github.RedstonerServer:ChatAPI:v1" - - compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.11.1' - - compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' -} - -jar { - manifest { - attributes "Class-Path": "../lib/CommandManager.jar ../lib/ChatAPI.jar" - } -} - -task sourceJar(type: Jar, dependsOn: classes) { - classifier 'sources' - from sourceSets.main.allSource -} - -sourceSets { - main { - resources { - srcDir 'src/main/java' - include '**/*.cmd' - - srcDir 'src/main/resources' - include '**/*.yml' - } - } -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 28861d2..0000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 115e6ac..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100755 index cccdd3d..0000000 --- a/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## 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="" - -# 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 - ;; - 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, switch paths to Windows format before running java -if $cygwin ; 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=$((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" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index e95643d..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@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 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= - -@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 init - -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 init - -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 - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -: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 %CMD_LINE_ARGS% - -: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 diff --git a/plugin.yml b/plugin.yml new file mode 100644 index 0000000..f6362a2 --- /dev/null +++ b/plugin.yml @@ -0,0 +1,4 @@ +name: JavaUtils +version: 1.0.0 +authors: [pepich1851] +main: com.redstoner.misc.Main \ No newline at end of file diff --git a/src/com/redstoner/annotations/AutoRegisterListener.java b/src/com/redstoner/annotations/AutoRegisterListener.java new file mode 100644 index 0000000..fabdb5f --- /dev/null +++ b/src/com/redstoner/annotations/AutoRegisterListener.java @@ -0,0 +1,15 @@ +package com.redstoner.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** The auto register annotation, to be put onto Classes that implement listener when you are too lazy to register the events yourself. + * + * @author Pepich */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public @interface AutoRegisterListener +{} diff --git a/src/com/redstoner/annotations/Debugable.java b/src/com/redstoner/annotations/Debugable.java new file mode 100644 index 0000000..be6ec1c --- /dev/null +++ b/src/com/redstoner/annotations/Debugable.java @@ -0,0 +1,14 @@ +package com.redstoner.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Debugable annotation, to be added to methods that invoke the Debugger.notifyMethod method for debugging purposes. + * + * @author Pepich */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Debugable +{} diff --git a/src/com/redstoner/annotations/Version.java b/src/com/redstoner/annotations/Version.java new file mode 100644 index 0000000..52d5145 --- /dev/null +++ b/src/com/redstoner/annotations/Version.java @@ -0,0 +1,32 @@ +package com.redstoner.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** The Version annotation, to be applied to all Classes that are part of the project. + * + * @author Pepich */ +@Target(ElementType.TYPE) +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface Version +{ + /** The major indicator of the version. Will be used for compatibility detection. + * + * @return the major version as an int */ + int major(); + + int minor(); + + int revision(); + + /** The compatibility part of the version number. Will be used for compatibility detection.
+ * Set to -1 if it is supposed to be always compatible.
+ * Defaults to 1. + * + * @return the smallest compatible version as an int. */ + int compatible() default 1; +} diff --git a/src/com/redstoner/coremods/debugger/Debugger.java b/src/com/redstoner/coremods/debugger/Debugger.java new file mode 100644 index 0000000..8aa7ef9 --- /dev/null +++ b/src/com/redstoner/coremods/debugger/Debugger.java @@ -0,0 +1,172 @@ +package com.redstoner.coremods.debugger; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.CommandManager; +import com.redstoner.annotations.Debugable; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.CoreModule; + +/** The Debugger class, first Module to be loaded, responsible for debug interactions such as subscribing to method calls and getting field values on runtime. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 4, compatible = -1) +public final class Debugger implements CoreModule, Listener +{ + private static Debugger instance; + private static HashMap> subs; + + private Debugger() + { + subs = new HashMap<>(); + } + + public static void init() + { + if (instance == null) + instance = new Debugger(); + CommandManager.registerCommand(instance.getCommandString(), instance, Main.plugin); + } + + public static void notifyMethod(Object... params) + { + Exception e = new Exception(); + String method = e.getStackTrace()[1].getMethodName(); + String classname = e.getStackTrace()[1].getClassName(); + for (Player p : Bukkit.getOnlinePlayers()) + if (subs.containsKey(p)) + { + boolean subscribed = false; + for (String s : subs.get(p)) + { + if (s.equals(classname + "." + method)) + { + subscribed = true; + break; + } + } + if (subscribed) + { + StringBuilder sb = new StringBuilder(method); + sb.append("("); + if (params != null) + { + for (Object obj : params) + { + if (obj == null) + sb.append("NULL"); + else + sb.append(obj.toString()); + sb.append(", "); + } + sb.delete(sb.length() - 2, sb.length()); + } + sb.append(")\nTypes:\n"); + int i = 0; + for (Object obj : params) + sb.append(i++ + ": " + (obj == null ? "NULL" : obj.getClass().getName()) + "\n"); + p.sendMessage(sb.toString()); + } + } + CommandSender p = Bukkit.getConsoleSender(); + if (subs.containsKey(p)) + { + boolean subscribed = false; + for (String s : subs.get(p)) + { + if (s.equals(classname + "." + method)) + { + subscribed = true; + break; + } + } + if (subscribed) + { + StringBuilder sb = new StringBuilder(method); + sb.append("("); + if (params != null) + { + for (Object obj : params) + { + if (obj == null) + sb.append("NULL"); + else + sb.append(obj.toString()); + sb.append(", "); + } + sb.delete(sb.length() - 2, sb.length()); + } + sb.append(")\nTypes:\n"); + int i = 0; + for (Object obj : params) + sb.append(i++ + ": " + (obj == null ? "NULL" : obj.getClass().getName()) + "\n"); + p.sendMessage(sb.toString()); + } + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command debugger {\n" + + " subscribe [string:classname] [string:methodname] {\n" + + " help Subscribes to all calls of the corresponding debugable method.;\n" + + " perm jutils.debugger.subscribe;\n" + + " run subscribe classname methodname;\n" + + " }\n" + + "}"; + } + // @format + + @Command(hook = "subscribe") + @Debugable + public boolean subscribeCommand(CommandSender sender, String classname, String methodname) + { + Utils.sendMessage(sender, null, "Debugger is currently disabled!"); + return true; + // Class clazz = null; + // try + // { + // clazz = Class.forName(classname); + // } + // catch (ClassNotFoundException e) + // { + // e.printStackTrace(); + // // TODO: Add error message + // return true; + // } + // boolean found = false; + // for (Method m : clazz.getMethods()) + // { + // if (m.getName().matches(methodname)) + // { + // if (m.isAnnotationPresent(Debugable.class)) + // { + // found = true; + // if (!subs.containsKey(sender)) + // subs.put(sender, new ArrayList()); + // subs.get(sender).add(classname + "." + methodname); + // break; + // } + // } + // } + // if (!found) + // { + // System.err.println("2"); + // // TODO: Add error message + // return true; + // } + // Utils.sendMessage(sender, null, "YAY"); + // return true; + } +} diff --git a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java new file mode 100644 index 0000000..5a305b1 --- /dev/null +++ b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -0,0 +1,191 @@ +package com.redstoner.coremods.moduleLoader; + +import java.util.ArrayList; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Listener; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.nemez.cmdmgr.CommandManager; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Debugable; +import com.redstoner.annotations.Version; +import com.redstoner.coremods.debugger.Debugger; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.CoreModule; +import com.redstoner.modules.Module; + +/** The module loader, mother of all modules. Responsible for loading and taking care of all modules. + * + * @author Pepich */ +@Version(major = 1, minor = 3, revision = 2, compatible = -1) +public final class ModuleLoader implements CoreModule +{ + private static ModuleLoader instance; + private static final ArrayList modules = new ArrayList(); + + private ModuleLoader() + {} + + public static void init() + { + if (instance == null) + instance = new ModuleLoader(); + CommandManager.registerCommand(instance.getCommandString(), instance, Main.plugin); + } + + /** This method will add a module to the module list, without enabling it + * + * @param clazz The class of the module to be added. */ + @Debugable + public static final void addModule(Class clazz) + { + Debugger.notifyMethod(clazz); + try + { + Module module = clazz.newInstance(); + modules.add(module); + } + catch (InstantiationException | IllegalAccessException e) + { + Utils.error("Could not add " + clazz.getName() + " to the list, constructor not accessible."); + } + } + + /** Call this to enable all not-yet enabled modules that are known to the loader. */ + @Debugable + public static final void enableModules() + { + Debugger.notifyMethod(); + for (Module module : modules) + { + if (module.enabled()) + continue; + try + { + if (module.enable()) + { + CommandManager.registerCommand(module.getCommandString(), module, Main.plugin); + if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) + && (module instanceof Listener)) + { + Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); + } + Utils.log("Loaded module " + module.getClass().getName()); + } + else + Utils.error("Failed to load module " + module.getClass().getName()); + } + catch (Exception e) + { + Utils.error("Failed to load module " + module.getClass().getName()); + } + } + } + + /** This method enables a specific module. If no module with that name is known to the loader yet it will be added to the list. + * + * @param clazz The class of the module to be enabled. + * @return true, when the module was successfully enabled. */ + @Debugable + public static final boolean enableModule(Class clazz) + { + Debugger.notifyMethod(clazz); + for (Module m : modules) + { + if (m.getClass().equals(clazz)) + { + if (m.enable()) + { + if (m.getClass().isAnnotationPresent(AutoRegisterListener.class) && (m instanceof Listener)) + { + Bukkit.getPluginManager().registerEvents((Listener) m, Main.plugin); + } + Utils.log("Loaded module " + m.getClass().getName()); + return true; + } + else + { + Utils.error("Failed to load module " + m.getClass().getName()); + return false; + } + } + } + try + { + Module m = clazz.newInstance(); + modules.add(m); + m.onEnable(); + if (m.enabled()) + { + if (m.getClass().isAnnotationPresent(AutoRegisterListener.class) && (m instanceof Listener)) + { + Bukkit.getPluginManager().registerEvents((Listener) m, Main.plugin); + } + Utils.log("Loaded module " + m.getClass().getName()); + return true; + } + else + { + Utils.error("Failed to load module " + m.getClass().getName()); + return false; + } + } + catch (InstantiationException | IllegalAccessException e) + { + Utils.error("Could not add " + clazz.getName() + " to the list, constructor not accessible."); + return false; + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command modules {\n" + + " list{\n" + + " help Lists all modules. Color indicates status: §aENABLED §cDISABLED;\n" + + " perm jutils.admin;\n" + + " run list;\n" + + " }\n" + + "}"; + } + // @format + + /** This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. + * + * @param sender The person to send the info to, usually the issuer of the command or the console sender. + * @return true. */ + @Command(hook = "list", async = AsyncType.ALWAYS) + public boolean listModulesCommand(CommandSender sender) + { + Utils.sendModuleHeader(sender); + StringBuilder sb = new StringBuilder("Modules:\n"); + for (Module m : modules) + { + String[] classPath = m.getClass().getName().split("\\."); + String classname = classPath[classPath.length - 1]; + sb.append(m.enabled() ? "&a" : "&c"); + sb.append(classname); + sb.append(", "); + } + sb.delete(sb.length() - 2, sb.length()); + Utils.sendMessage(sender, " §e", sb.toString(), '&'); + Utils.sendMessage(sender, " §7", "For more detailed information, consult the debugger."); + return true; + } + + public static void disableModules() + { + for (Module module : modules) + { + if (module.enabled()) + { + module.onDisable(); + } + } + } +} diff --git a/src/com/redstoner/exceptions/MissingVersionException.java b/src/com/redstoner/exceptions/MissingVersionException.java new file mode 100644 index 0000000..62032b6 --- /dev/null +++ b/src/com/redstoner/exceptions/MissingVersionException.java @@ -0,0 +1,22 @@ +package com.redstoner.exceptions; + +import com.redstoner.annotations.Version; + +/** To be thrown when a module is not annotated with its version. If this gets thrown, then oh boy, you're in trouble now. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 0, compatible = -1) +public class MissingVersionException extends Exception +{ + private static final long serialVersionUID = 4940161335512222539L; + + public MissingVersionException() + { + super(); + } + + public MissingVersionException(String message) + { + super(message); + } +} diff --git a/src/com/redstoner/exceptions/NonSaveableConfigException.java b/src/com/redstoner/exceptions/NonSaveableConfigException.java new file mode 100644 index 0000000..df33bff --- /dev/null +++ b/src/com/redstoner/exceptions/NonSaveableConfigException.java @@ -0,0 +1,9 @@ +package com.redstoner.exceptions; + +public class NonSaveableConfigException extends Exception { + private static final long serialVersionUID = -7271481973389455510L; + + public NonSaveableConfigException() { + super("This config does not support saving!"); + } +} diff --git a/src/com/redstoner/misc/BroadcastFilter.java b/src/com/redstoner/misc/BroadcastFilter.java new file mode 100644 index 0000000..1f0ce04 --- /dev/null +++ b/src/com/redstoner/misc/BroadcastFilter.java @@ -0,0 +1,14 @@ +package com.redstoner.misc; + +import org.bukkit.command.CommandSender; + +import com.redstoner.annotations.Version; + +/** Classes implementing this interface can be used to define a filter for the Utils.broadcast method for sending a message to more than one, but less than all users. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public interface BroadcastFilter +{ + public boolean sendTo(CommandSender recipient); +} diff --git a/src/com/redstoner/misc/JsonManager.java b/src/com/redstoner/misc/JsonManager.java new file mode 100644 index 0000000..998d137 --- /dev/null +++ b/src/com/redstoner/misc/JsonManager.java @@ -0,0 +1,127 @@ +package com.redstoner.misc; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.redstoner.annotations.Version; + +/** This class provides simple JSON handling, like storing and loading from and to files. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 1, compatible = -1) +public class JsonManager +{ + private JsonManager() + {} + + /** Loads a JSONObject from a file. + * + * @param source the file to load from. + * @return the JSONObject or null if the source does not contain a valid JSONObject. */ + public static JSONObject getObject(File source) + { + if (!source.exists()) + return null; + JSONParser parser = new JSONParser(); + try + { + FileReader reader = new FileReader(source); + Object rawObject = parser.parse(reader); + reader.close(); + JSONObject jsonObject = (JSONObject) rawObject; + return jsonObject; + } + catch (IOException | ParseException e) + {} + return null; + } + + /** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
+ * Note that this operation will be run on a different thread and you do not need to take care of that yourself. + * + * @param object the JSONObject to save. + * @param destination the file to write to. */ + public static void save(JSONObject object, File destination) + { + Thread t = new Thread(new Runnable() + { + @Override + public void run() + { + if (destination.exists()) + destination.delete(); + else if (!destination.getParentFile().exists()) + destination.getParentFile().mkdirs(); + try + { + destination.createNewFile(); + FileWriter writer = new FileWriter(destination); + object.writeJSONString(writer); + writer.flush(); + writer.close(); + } + catch (IOException e) + {} + } + }); + t.start(); + } + + /** Loads a JSONArray from a file. + * + * @param source the file to load from. + * @return the JSONArray or null if the source does not contain a valid JSONArray. */ + public static JSONArray getArray(File source) + { + if (!source.exists()) + return null; + JSONParser parser = new JSONParser(); + try + { + Object rawObject = parser.parse(new FileReader(source)); + JSONArray jsonArray = (JSONArray) rawObject; + return jsonArray; + } + catch (IOException | ParseException e) + {} + return null; + } + + /** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
+ * Note that this operation will be run on a different thread and you do not need to take care of that yourself. + * + * @param object the JSONArray to save. + * @param destination the file to write to. */ + public static void save(JSONArray array, File destination) + { + Thread t = new Thread(new Runnable() + { + @Override + public void run() + { + if (destination.exists()) + destination.delete(); + else if (!destination.getParentFile().exists()) + destination.getParentFile().mkdirs(); + try + { + destination.createNewFile(); + FileWriter writer = new FileWriter(destination); + array.writeJSONString(writer); + writer.flush(); + writer.close(); + } + catch (IOException e) + {} + } + }); + t.start(); + } +} diff --git a/src/com/redstoner/misc/Main.java b/src/com/redstoner/misc/Main.java new file mode 100644 index 0000000..e7d4707 --- /dev/null +++ b/src/com/redstoner/misc/Main.java @@ -0,0 +1,90 @@ +package com.redstoner.misc; + +import org.bukkit.plugin.java.JavaPlugin; + +import com.redstoner.annotations.Version; +import com.redstoner.coremods.debugger.Debugger; +import com.redstoner.coremods.moduleLoader.ModuleLoader; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.modules.abot.Abot; +import com.redstoner.modules.adminchat.Adminchat; +import com.redstoner.modules.adminnotes.AdminNotes; +import com.redstoner.modules.chatalias.Chatalias; +import com.redstoner.modules.chatgroups.Chatgroups; +import com.redstoner.modules.check.Check; +import com.redstoner.modules.cycle.Cycle; +import com.redstoner.modules.damnspam.DamnSpam; +import com.redstoner.modules.illumination.Illumination; +import com.redstoner.modules.imout.Imout; +import com.redstoner.modules.lagchunks.LagChunks; +import com.redstoner.modules.loginsecurity.LoginSecurity; +import com.redstoner.modules.mentio.Mentio; +import com.redstoner.modules.misc.Misc; +import com.redstoner.modules.motd.Motd; +import com.redstoner.modules.nametags.Nametags; +import com.redstoner.modules.pmtoggle.Pmtoggle; +import com.redstoner.modules.reports.Reports; +import com.redstoner.modules.saylol.Saylol; +import com.redstoner.modules.scriptutils.Scriptutils; +import com.redstoner.modules.skullclick.SkullClick; +import com.redstoner.modules.tag.Tag; +import com.redstoner.modules.vanish.Vanish; +import com.redstoner.modules.warn.Warn; +import com.redstoner.modules.webtoken.WebToken; + +/** Main class. Duh. + * + * @author Pepich */ +@Version(major = 1, minor = 4, revision = 1, compatible = -1) +public class Main extends JavaPlugin +{ + public static JavaPlugin plugin; + + @Override + public void onEnable() + { + plugin = this; + Debugger.init(); + ModuleLoader.init(); + MysqlHandler.init(); + ModuleLoader.addModule(Abot.class); + ModuleLoader.addModule(Adminchat.class); + ModuleLoader.addModule(AdminNotes.class); + // TODO: ModuleLoader.addModule(BlockplaceMods.class); + // TODO: ModuleLoader.addModule(Calc.class); + ModuleLoader.addModule(Chatalias.class); + ModuleLoader.addModule(Cycle.class); + ModuleLoader.addModule(Chatgroups.class); + ModuleLoader.addModule(Check.class); + ModuleLoader.addModule(DamnSpam.class); + // TODO: ModuleLoader.addModule(Friends.class); + ModuleLoader.addModule(Illumination.class); + // TODO: ModuleLoader.addModule(Imbusy.class); + ModuleLoader.addModule(Imout.class); + ModuleLoader.addModule(LagChunks.class); + ModuleLoader.addModule(LoginSecurity.class); + ModuleLoader.addModule(Mentio.class); + ModuleLoader.addModule(Misc.class); + ModuleLoader.addModule(Motd.class); + ModuleLoader.addModule(Nametags.class); + ModuleLoader.addModule(Pmtoggle.class); + ModuleLoader.addModule(Reports.class); + ModuleLoader.addModule(Saylol.class); + ModuleLoader.addModule(Scriptutils.class); + // TODO: ModuleLoader.addModule(Serversigns.class); + // TODO: ModuleLoader.addModule(Signalstrength.class); + ModuleLoader.addModule(SkullClick.class); + ModuleLoader.addModule(Tag.class); + ModuleLoader.addModule(Vanish.class); + ModuleLoader.addModule(Warn.class); + ModuleLoader.addModule(WebToken.class); + // And enable them + ModuleLoader.enableModules(); + } + + @Override + public void onDisable() + { + ModuleLoader.disableModules(); + } +} diff --git a/src/com/redstoner/misc/Utils.java b/src/com/redstoner/misc/Utils.java new file mode 100644 index 0000000..8973b86 --- /dev/null +++ b/src/com/redstoner/misc/Utils.java @@ -0,0 +1,198 @@ +package com.redstoner.misc; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.redstoner.annotations.Debugable; +import com.redstoner.annotations.Version; +import com.redstoner.coremods.debugger.Debugger; + +import net.md_5.bungee.api.ChatColor; + +/** The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more. + * + * @author Pepich */ +@Version(major = 1, minor = 1, revision = 8, compatible = 1) +public final class Utils +{ + /** Hidden constructor. Do not instantiate UTILS classes! :) */ + private Utils() + {} + + /** This will send a message to the specified recipient. It will generate the module prefix if you want it to. + * + * @param recipient Whom to sent the message to. + * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&2MODULE&8] + * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. */ + @Debugable + public static void sendMessage(CommandSender recipient, String prefix, String message) + { + Debugger.notifyMethod(recipient, message, prefix); + if (prefix == null) + prefix = "§8[§2" + getCaller() + "§8]: "; + recipient.sendMessage(prefix + "§7" + message); + } + + /** This will send a message to the specified recipient. It will generate the module prefix if you want it to. Also, this will be logged to console as a warning. + * + * @param recipient Whom to sent the message to. + * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&cMODULE&8] + * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. */ + @Debugable + public static void sendErrorMessage(CommandSender recipient, String prefix, String message) + { + Debugger.notifyMethod(recipient, prefix, message); + if (prefix == null) + prefix = "§8[§c" + getCaller() + "§8]: "; + recipient.sendMessage(prefix + "§7" + message); + } + + /** Invokes sendMessage. This method will additionally translate alternate color codes for you. + * + * @param recipient Whom to sent the message to. + * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&cMODULE&8] + * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. + * @param alternateColorCode The alternate color code indicator to use. If set to '&' then "&7" would be translated to "§7". Works with any char. */ + public static void sendMessage(CommandSender recipient, String prefix, String message, char alternateColorCode) + { + if (prefix == null) + prefix = "§8[§2" + getCaller() + "§8]: "; + sendMessage(recipient, ChatColor.translateAlternateColorCodes(alternateColorCode, prefix), + ChatColor.translateAlternateColorCodes(alternateColorCode, message)); + } + + /** Invokes sendErrorMessage. This method will additionally translate alternate color codes for you. + * + * @param recipient Whom to sent the message to. + * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&cMODULE&8] + * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. + * @param alternateColorCode The alternate color code indicator to use. If set to '&' then "&7" would be translated to "§7". Works with any char. */ + public static void sendErrorMessage(CommandSender recipient, String prefix, String message, char alternateColorCode) + { + if (prefix == null) + prefix = "§8[§c" + getCaller() + "§8]: "; + sendErrorMessage(recipient, ChatColor.translateAlternateColorCodes(alternateColorCode, prefix), + ChatColor.translateAlternateColorCodes(alternateColorCode, message)); + } + + /** This method broadcasts a message to all players (and console) that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
+ * This will not be logged to console except when you return true in the filter. + * + * @param message the message to be sent around + * @param filter the BroadcastFilter to be applied.
+ * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. + * @return the amount of people that received the message. */ + public static int broadcast(String prefix, String message, BroadcastFilter filter) + { + return broadcast(prefix, message, filter, null); + } + + /** This method broadcasts a message to all players (and console) that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
+ * This will not be logged to console except when you return true in the filter. + * + * @param message the message to be sent around + * @param filter the BroadcastFilter to be applied.
+ * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. + * @param alternateColorCode The alternate color code indicator to use. If set to '&' then "&7" would be translated to "§7". Works with any char. + * @return the amount of people that received the message. */ + public static int broadcast(String prefix, String message, BroadcastFilter filter, char alternateColorCode) + { + if (prefix == null) + prefix = "§8[§2" + getCaller() + "§8]: "; + return broadcast(ChatColor.translateAlternateColorCodes(alternateColorCode, prefix), + ChatColor.translateAlternateColorCodes(alternateColorCode, message), filter, null); + } + + /** This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
+ * If you want to, you can set a message that will be logged to console. Set to null to not log anything.
+ * You can still allow console in the filter to log the original message. + * + * @param prefix The prefix for the message. Set to NULL to let it auto generate. + * @param message the message to be sent around + * @param filter the BroadcastFilter to be applied.
+ * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. + * @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter). + * @return the amount of people that received the message. */ + @Debugable + public static int broadcast(String prefix, String message, BroadcastFilter filter, String logmessage) + { + if (prefix == null) + prefix = "§8[§2" + getCaller() + "§8]: "; + Debugger.notifyMethod(message, filter, logmessage); + if (logmessage != null) + sendMessage(Bukkit.getConsoleSender(), prefix, logmessage); + if (filter == null) + { + for (Player p : Bukkit.getOnlinePlayers()) + p.sendMessage(prefix + message); + if (logmessage == null) + Bukkit.getConsoleSender().sendMessage(prefix + message); + return Bukkit.getOnlinePlayers().size(); + } + else + { + int count = 0; + for (Player p : Bukkit.getOnlinePlayers()) + if (filter.sendTo(p)) + { + p.sendMessage(prefix + message); + count++; + } + if (logmessage == null) + if (filter.sendTo(Bukkit.getConsoleSender())) + { + Bukkit.getConsoleSender().sendMessage(prefix + message); + count++; + } + return count; + } + } + + /** Used to make an info output to console. Supports &x color codes. + * + * @param message The message to be put into console. Prefixes are automatically generated. */ + @Debugable + public static void log(String message) + { + Debugger.notifyMethod(message); + String classname = getCaller(); + String prefix = "§8[§2" + classname + "§8]: "; + Bukkit.getConsoleSender().sendMessage(ChatColor.translateAlternateColorCodes('&', prefix + "§7" + message)); + } + + /** Used to make an error output to console. Supports &x color codes. + * + * @param message The message to be put into console. Prefixes are automatically generated. Color defaults to red if not specified otherwise. */ + @Debugable + public static void error(String message) + { + Debugger.notifyMethod(message); + String classname = getCaller(); + String prefix = "§c[ERROR]: §8[§c" + classname + "§8]: "; + Bukkit.getConsoleSender().sendMessage(ChatColor.translateAlternateColorCodes('&', prefix + "§7" + message)); + } + + /** This method will find the next parent caller and return their class name, omitting package names. + * + * @return */ + private static final String getCaller() + { + StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); + String classname = "Utils"; + for (int i = 0; classname.equals("Utils"); i++) + { + classname = stackTrace[i].getClassName().replaceAll(".*\\.", ""); + } + return classname; + } + + /** Displays the module header to the recipient.
+ * Format: &2--=[ %MODULE% ]=-- + * + * @param recipient Whom to display the header to. */ + public static void sendModuleHeader(CommandSender recipient) + { + recipient.sendMessage("§2--=[ " + getCaller() + " ]=--"); + } +} diff --git a/src/com/redstoner/misc/VersionHelper.java b/src/com/redstoner/misc/VersionHelper.java new file mode 100644 index 0000000..86a5381 --- /dev/null +++ b/src/com/redstoner/misc/VersionHelper.java @@ -0,0 +1,46 @@ +package com.redstoner.misc; + +import com.redstoner.annotations.Version; +import com.redstoner.exceptions.MissingVersionException; + +/** This class can be used to compare modules against the loader version or against each other to prevent dependency issues. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 0, compatible = -1) +public final class VersionHelper +{ + private VersionHelper() + {} + + /** Checks two modules versions for compatibility. + * + * @param base The base to compare to. + * @param module The module to compare. + * @return true, when the Major version of the base is bigger than the compatible version of the module, and the Version number of the base is smaller or equal to the Version number of the module. + * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ + public static boolean isCompatible(Class base, Class module) throws MissingVersionException + { + if (!base.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The base object is not annotated with a version."); + if (!module.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The module is not annotated with a version."); + Version baseVersion = base.getClass().getAnnotation(Version.class); + Version moduleVersion = module.getClass().getAnnotation(Version.class); + if (baseVersion.major() > moduleVersion.major()) + return false; + return baseVersion.major() >= moduleVersion.compatible(); + } + + /** Returns the version of a given class as a String. + * + * @param clazz The class to grab the version number from. + * @return The version number of the class in format major.minor.revision.compatible. + * @throws MissingVersionException If the class is not annotated with @Version. */ + public static String getVersion(Class clazz) throws MissingVersionException + { + if (!clazz.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The given class is not associated with a version."); + Version ver = clazz.getAnnotation(Version.class); + return ver.major() + "." + ver.minor() + "." + ver.revision() + "." + ver.compatible(); + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/Config.java b/src/com/redstoner/misc/mysql/Config.java similarity index 56% rename from src/main/java/com/redstoner/misc/mysql/Config.java rename to src/com/redstoner/misc/mysql/Config.java index b88b0c2..d403c7b 100644 --- a/src/main/java/com/redstoner/misc/mysql/Config.java +++ b/src/com/redstoner/misc/mysql/Config.java @@ -1,170 +1,213 @@ package com.redstoner.misc.mysql; -import com.redstoner.exceptions.NonSaveableConfigException; -import com.redstoner.misc.Main; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; -public class Config { - private File file; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.redstoner.exceptions.NonSaveableConfigException; +import com.redstoner.misc.Main; + +public class Config +{ + private File file; private JSONObject config; private JSONParser parser; - - public Config() { + + public Config() + { file = null; parser = new JSONParser(); config = new JSONObject(); } - - public Config(JSONObject config) { + + public Config(JSONObject config) + { this.file = null; this.parser = new JSONParser(); this.config = config; } - - private Config(File file) throws IOException, ParseException { + + private Config(File file) throws IOException, ParseException + { this.file = file; parser = new JSONParser(); - if (file.exists()) { + if (file.exists()) + { config = loadConfig(file); - } else { + } + else + { config = new JSONObject(); } } - - private JSONObject loadConfig(File file) throws IOException, ParseException { - FileReader reader = new FileReader(file); - JSONObject object = (JSONObject) parser.parse(reader); - reader.close(); - return object; - } - - public static final Config getConfig(String fileName) throws IOException, ParseException { + + public static final Config getConfig(String fileName) throws IOException, ParseException + { return new Config(new File(Main.plugin.getDataFolder(), fileName)); } - - public static final Config getConfig(File file) throws IOException, ParseException { + + public static final Config getConfig(File file) throws IOException, ParseException + { return new Config(file); } - + + private JSONObject loadConfig(File file) throws IOException, ParseException + { + FileReader reader = new FileReader(file); + return (JSONObject) parser.parse(reader); + } + @Override - public String toString() { + public String toString() + { return config.toJSONString(); } - - public JSONObject asObject() { + + public JSONObject asObject() + { return config; } - - public void save() throws IOException, NonSaveableConfigException { - if (file == null) { + + public void save() throws IOException, NonSaveableConfigException + { + if (file == null) + { throw new NonSaveableConfigException(); } PrintWriter writer = new PrintWriter(file); writer.write(config.toJSONString()); writer.close(); } - - public void refresh() throws IOException, ParseException, NonSaveableConfigException { - if (file == null) { + + public void refresh() throws IOException, ParseException, NonSaveableConfigException + { + if (file == null) + { throw new NonSaveableConfigException(); } loadConfig(file); } - - public void setFile(String fileName) { + + public void setFile(String fileName) + { file = new File(Main.plugin.getDataFolder(), fileName); } - - public void setFile(File file) { + + public void setFile(File file) + { this.file = file; } - - @SuppressWarnings ("unchecked") - public void put(String key, String value) { + + @SuppressWarnings("unchecked") + public void put(String key, String value) + { config.put(key, value); } - - @SuppressWarnings ("unchecked") - public void put(String key, List value) { + + @SuppressWarnings("unchecked") + public void put(String key, List value) + { JSONArray array = new JSONArray(); - for (String entry : value) { + for (String entry : value) + { array.add(entry); } config.put(key, array); } - - @SuppressWarnings ("unchecked") - public void putArray(String key, JSONArray value) { + + @SuppressWarnings("unchecked") + public void putArray(String key, JSONArray value) + { config.put(key, value); } - - @SuppressWarnings ("unchecked") - public void put(String key, Map value) { + + @SuppressWarnings("unchecked") + public void put(String key, Map value) + { JSONObject object = new JSONObject(); - for (String valKey : value.keySet()) { + for (String valKey : value.keySet()) + { String valVal = value.get(valKey); object.put(valKey, valVal); } config.put(key, object); } - - @SuppressWarnings ("unchecked") - public void put(String key, JSONObject value) { + + @SuppressWarnings("unchecked") + public void put(String key, JSONObject value) + { config.put(key, value); } - - @SuppressWarnings ("unchecked") - public void putAll(Map entry) { - for (String key : entry.keySet()) { + + @SuppressWarnings("unchecked") + public void putAll(Map entry) + { + for (String key : entry.keySet()) + { String value = entry.get(key); config.put(key, value); } } - - public String get(String key) { - if (containsKey(key)) { + + public boolean containsKey(String key) + { + return config.containsKey(key); + } + + public String get(String key) + { + if (containsKey(key)) + { Object value = config.get(key); - if (value instanceof String) { + if (value instanceof String) + { return (String) value; } } return null; } - - public boolean containsKey(String key) { - return config.containsKey(key); - } - - public String getOrDefault(String key, String defaultValue) { - if (containsKey(key)) { + + public String getOrDefault(String key, String defaultValue) + { + if (containsKey(key)) + { Object value = config.get(key); - if (value instanceof String) { + if (value instanceof String) + { return (String) value; } return null; - } else { + } + else + { return defaultValue; } } - - @SuppressWarnings ("unchecked") - public List getList(String key) { - if (containsKey(key)) { + + @SuppressWarnings("unchecked") + public List getList(String key) + { + if (containsKey(key)) + { Object value = config.get(key); - if (value instanceof JSONArray) { - JSONArray array = (JSONArray) value; + if (value instanceof JSONArray) + { + JSONArray array = (JSONArray) value; List output = new ArrayList(); - for (String entry : (String[]) array.toArray(new String[0])) { + for (String entry : (String[]) array.toArray(new String[0])) + { output.add(entry); } return output; @@ -172,27 +215,34 @@ public class Config { } return null; } - - public JSONArray getArray(String key) { - if (containsKey(key)) { + + public JSONArray getArray(String key) + { + if (containsKey(key)) + { Object value = config.get(key); - if (value instanceof JSONArray) { + if (value instanceof JSONArray) + { JSONArray array = (JSONArray) value; return array; } } return null; } - - public Map getMap(String key) { - if (containsKey(key)) { + + public Map getMap(String key) + { + if (containsKey(key)) + { Object value = config.get(key); - if (value instanceof JSONObject) { + if (value instanceof JSONObject) + { JSONObject object = (JSONObject) value; - @SuppressWarnings ("unchecked") + @SuppressWarnings("unchecked") Set> entrySet = object.entrySet(); Map output = new HashMap(); - for (Map.Entry entry : entrySet) { + for (Map.Entry entry : entrySet) + { output.put(entry.getKey(), entry.getValue()); } return output; @@ -200,24 +250,29 @@ public class Config { } return null; } - - public JSONObject getObject(String key) { - if (containsKey(key)) { + + public JSONObject getObject(String key) + { + if (containsKey(key)) + { Object value = config.get(key); - if (value instanceof JSONObject) { + if (value instanceof JSONObject) + { JSONObject object = (JSONObject) value; return object; } } return null; } - - public void remove(String key) { + + public void remove(String key) + { config.remove(key); } - - @SuppressWarnings ("unchecked") - public Set> getAll() { + + @SuppressWarnings("unchecked") + public Set> getAll() + { return config.entrySet(); } } diff --git a/src/main/java/com/redstoner/misc/mysql/JSONManager.java b/src/com/redstoner/misc/mysql/JSONManager.java similarity index 62% rename from src/main/java/com/redstoner/misc/mysql/JSONManager.java rename to src/com/redstoner/misc/mysql/JSONManager.java index 6084e8d..ae248d5 100644 --- a/src/main/java/com/redstoner/misc/mysql/JSONManager.java +++ b/src/com/redstoner/misc/mysql/JSONManager.java @@ -1,80 +1,107 @@ package com.redstoner.misc.mysql; -import com.redstoner.misc.Main; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import java.io.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -public class JSONManager { - public static Map getConfiguration(String fileName) { +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.redstoner.misc.Main; + +public class JSONManager +{ + public static Map getConfiguration(String fileName) + { File file = new File(Main.plugin.getDataFolder(), fileName); - if (!file.exists()) { - try { + if (!file.exists()) + { + try + { PrintWriter writer = new PrintWriter(file.getAbsolutePath(), "UTF-8"); writer.println("{}"); writer.close(); - } catch (FileNotFoundException | UnsupportedEncodingException e) { + } + catch (FileNotFoundException | UnsupportedEncodingException e) + { e.printStackTrace(); } } - try { + try + { return loadMap(file); - } catch (IOException | ParseException e) { + } + catch (IOException | ParseException e) + { e.printStackTrace(); return null; } } - - public static Map loadMap(File file) throws IOException, ParseException { - FileReader reader = new FileReader(file); - JSONObject map = (JSONObject) new JSONParser().parse(reader); - Map entries = new HashMap<>(); - for (Object o : map.keySet()) { - entries.put((Serializable) o, (Serializable) map.get(o)); - } - return entries; - } - - public static void saveConfiguration(Map config, String fileName) { - try { + + public static void saveConfiguration(Map config, String fileName) + { + try + { saveMap(new File(Main.plugin.getDataFolder(), fileName), config); - } catch (IOException e) { + } + catch (IOException e) + { e.printStackTrace(); } } - - @SuppressWarnings ("unchecked") - public static void saveMap(File file, Map entries) throws IOException { - JSONObject map = new JSONObject(); - map.putAll(entries); - FileWriter writer = new FileWriter(file); - writer.write(map.toJSONString()); - writer.close(); - } - - @SuppressWarnings ("unchecked") - public static void saveList(File file, List entries) throws IOException { + + @SuppressWarnings("unchecked") + public static void saveList(File file, List entries) throws IOException + { JSONArray array = new JSONArray(); array.addAll(entries); FileWriter writer = new FileWriter(file); writer.write(array.toJSONString()); writer.close(); } - - public static List loadList(File file) throws IOException, ParseException { - FileReader read = new FileReader(file); + + public static List loadList(File file) throws IOException, ParseException + { + FileReader read = new FileReader(file); List entries = new ArrayList<>(); - JSONArray array = (JSONArray) new JSONParser().parse(read); - for (Object o : array) { + JSONArray array = (JSONArray) new JSONParser().parse(read); + for (Object o : array) + { entries.add((Serializable) o); } return entries; } + + @SuppressWarnings("unchecked") + public static void saveMap(File file, Map entries) throws IOException + { + JSONObject map = new JSONObject(); + map.putAll(entries); + FileWriter writer = new FileWriter(file); + writer.write(map.toJSONString()); + writer.close(); + } + + public static Map loadMap(File file) throws IOException, ParseException + { + FileReader reader = new FileReader(file); + JSONObject map = (JSONObject) new JSONParser().parse(reader); + Map entries = new HashMap<>(); + for (Object o : map.keySet()) + { + entries.put((Serializable) o, (Serializable) map.get(o)); + } + return entries; + } } diff --git a/src/main/java/com/redstoner/misc/mysql/MysqlHandler.java b/src/com/redstoner/misc/mysql/MysqlHandler.java similarity index 62% rename from src/main/java/com/redstoner/misc/mysql/MysqlHandler.java rename to src/com/redstoner/misc/mysql/MysqlHandler.java index d76227a..909d276 100644 --- a/src/main/java/com/redstoner/misc/mysql/MysqlHandler.java +++ b/src/com/redstoner/misc/mysql/MysqlHandler.java @@ -1,86 +1,113 @@ package com.redstoner.misc.mysql; -import com.redstoner.misc.Main; -import com.redstoner.misc.mysql.elements.MysqlDatabase; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.json.simple.parser.ParseException; - import java.io.File; import java.io.IOException; import java.io.Serializable; -import java.sql.*; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -public class MysqlHandler { - public static MysqlHandler INSTANCE; - private String url, username, password; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.json.simple.parser.ParseException; - public MysqlHandler(String hostname, int port, String username, String password) { +import com.redstoner.misc.Main; +import com.redstoner.misc.mysql.elements.MysqlDatabase; + +public class MysqlHandler +{ + public static MysqlHandler INSTANCE; + private String url, username, password; + + public MysqlHandler(String hostname, int port, String username, String password) + { this.url = "jdbc:mysql://" + hostname + ":" + port + "/"; this.username = username; this.password = password; } - - public static void init() { - Map mysqlCredentials = new HashMap<>(); - File mysqlCredentialsFile = new File(Main.plugin.getDataFolder(), "mysqlCredentials.json"); - if (mysqlCredentialsFile.exists()) { - try { + + public static void init() + { + Map mysqlCredentials = new HashMap<>(); + File mysqlCredentialsFile = new File(Main.plugin.getDataFolder(), "mysqlCredentials.json"); + if (mysqlCredentialsFile.exists()) + { + try + { mysqlCredentials = JSONManager.loadMap(mysqlCredentialsFile); - } catch (IOException | ParseException e) { + } + catch (IOException | ParseException e) + { e.printStackTrace(); } - } else { + } + else + { Bukkit.getConsoleSender().sendMessage( ChatColor.RED + "MySQL config does not exist, creating an example one, things might (will) break!"); mysqlCredentials.put("hostname", "localhost"); mysqlCredentials.put("port", "3306"); mysqlCredentials.put("username", "your username here"); mysqlCredentials.put("password", "your password here"); - try { + try + { JSONManager.saveMap(mysqlCredentialsFile, mysqlCredentials); - } catch (IOException e) { + } + catch (IOException e) + { e.printStackTrace(); } } String hostname = (String) mysqlCredentials.get("hostname"); - int port = Integer.valueOf((String) mysqlCredentials.get("port")); + int port = Integer.valueOf((String) mysqlCredentials.get("port")); String username = (String) mysqlCredentials.get("username"); String password = (String) mysqlCredentials.get("password"); INSTANCE = new MysqlHandler(hostname, port, username, password); } - - public MysqlDatabase getDatabase(String databaseName) { - return new MysqlDatabase(getConnection(databaseName)); - } - - private Connection getConnection(String databaseName) throws IllegalStateException { + + private Connection getConnection(String databaseName) throws IllegalStateException + { Connection connection = null; - try { + try + { connection = DriverManager.getConnection(url + databaseName, username, password); - } catch (SQLException e) { + } + catch (SQLException e) + { throw new IllegalStateException("Cannot connect to the database!", e); } return connection; } - - public List getDatabases() { - try { - List databases = new ArrayList<>(); - Connection connection = DriverManager.getConnection(url.substring(0, url.length()), username, password); - DatabaseMetaData metadata = connection.getMetaData(); - ResultSet queryResults = metadata.getCatalogs(); - while (queryResults.next()) { + + public MysqlDatabase getDatabase(String databaseName) + { + return new MysqlDatabase(getConnection(databaseName)); + } + + public List getDatabases() + { + try + { + List databases = new ArrayList<>(); + Connection connection = DriverManager.getConnection(url.substring(0, url.length()), username, password); + DatabaseMetaData metadata = connection.getMetaData(); + ResultSet queryResults = metadata.getCatalogs(); + while (queryResults.next()) + { String databaseName = queryResults.getString("TABLE_CAT"); databases.add(new MysqlDatabase(getConnection(databaseName))); } connection.close(); return databases; - } catch (SQLException e) { + } + catch (SQLException e) + { e.printStackTrace(); return null; } diff --git a/src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java b/src/com/redstoner/misc/mysql/MysqlQueryHandler.java similarity index 72% rename from src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java rename to src/com/redstoner/misc/mysql/MysqlQueryHandler.java index df46cab..f89a08a 100644 --- a/src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java +++ b/src/com/redstoner/misc/mysql/MysqlQueryHandler.java @@ -1,25 +1,29 @@ package com.redstoner.misc.mysql; -import java.sql.*; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; public class MysqlQueryHandler { public static ResultSet queryResult(Connection connection, String query) { try { Statement statement = connection.createStatement(); - ResultSet results = statement.executeQuery(query); - + ResultSet results = statement.executeQuery(query); + return results; } catch (SQLException e) { e.printStackTrace(); return null; } } - + public static boolean queryNoResult(Connection connection, String query) { try { CallableStatement statement = connection.prepareCall(query); statement.execute(); - + return true; } catch (SQLException e) { e.printStackTrace(); diff --git a/src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java b/src/com/redstoner/misc/mysql/elements/ConstraintOperator.java similarity index 99% rename from src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java rename to src/com/redstoner/misc/mysql/elements/ConstraintOperator.java index 1e8d523..45cb33c 100644 --- a/src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java +++ b/src/com/redstoner/misc/mysql/elements/ConstraintOperator.java @@ -2,7 +2,7 @@ package com.redstoner.misc.mysql.elements; public enum ConstraintOperator { LESS_THAN, GREATER_THAN, EQUAL, NOT_EQUAL, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL; - + public String toString() { switch (this) { case LESS_THAN: diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java b/src/com/redstoner/misc/mysql/elements/MysqlConstraint.java similarity index 99% rename from src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java rename to src/com/redstoner/misc/mysql/elements/MysqlConstraint.java index 8b99d12..d651344 100644 --- a/src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java +++ b/src/com/redstoner/misc/mysql/elements/MysqlConstraint.java @@ -3,7 +3,7 @@ package com.redstoner.misc.mysql.elements; public class MysqlConstraint { private String fieldName, value; private ConstraintOperator operator; - + public MysqlConstraint(String fieldName, ConstraintOperator operator, String value) { this.fieldName = fieldName; this.operator = operator; diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java b/src/com/redstoner/misc/mysql/elements/MysqlDatabase.java similarity index 89% rename from src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java rename to src/com/redstoner/misc/mysql/elements/MysqlDatabase.java index 3f1c288..91c0fe4 100644 --- a/src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java +++ b/src/com/redstoner/misc/mysql/elements/MysqlDatabase.java @@ -1,7 +1,5 @@ package com.redstoner.misc.mysql.elements; -import com.redstoner.misc.mysql.MysqlQueryHandler; - import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; @@ -9,55 +7,15 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import com.redstoner.misc.mysql.MysqlQueryHandler; + public class MysqlDatabase { private Connection connection; - + public MysqlDatabase(Connection connection) { this.connection = connection; } - - public MysqlTable getTable(String name) { - return new MysqlTable(this, name); - } - - public boolean createTable(String name, MysqlField... description) { - return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE `" + name + "` " + getDescription(description) + ";"); - } - - private String getDescription(MysqlField... description) { - String desc = "("; - - for (int i = 0; i < description.length; i++) { - String nil = ""; - - if (description[i].canBeNull()) { - nil = " NOT NULL"; - } - - desc += "`" + description[i].getName() + "` " + description[i].getType().getName() + nil; - - if (i < description.length - 1) { - desc += ","; - } - } - - desc += ")"; - - return desc; - } - - public boolean createTableIfNotExists(String name, MysqlField... description) { - return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE IF NOT EXISTS `" + name + "` " + getDescription(description) + ";"); - } - - public boolean dropTable(String name) { - return MysqlQueryHandler.queryNoResult(connection, "DROP TABLE `" + name + "`;"); - } - - public boolean drop() { - return MysqlQueryHandler.queryNoResult(connection, "DROP DATABASE `" + getName() + "`;"); - } - + public String getName() { try { return connection.getCatalog(); @@ -66,25 +24,67 @@ public class MysqlDatabase { return null; } } - + + public MysqlTable getTable(String name) { + return new MysqlTable(this, name); + } + + public boolean createTable(String name, MysqlField... description) { + return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE `" + name + "` " + getDescription(description) + ";"); + } + + public boolean createTableIfNotExists(String name, MysqlField... description) { + return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE IF NOT EXISTS `" + name + "` " + getDescription(description) + ";"); + } + + public boolean dropTable(String name) { + return MysqlQueryHandler.queryNoResult(connection, "DROP TABLE `" + name + "`;"); + } + + public boolean drop() { + return MysqlQueryHandler.queryNoResult(connection, "DROP DATABASE `" + getName() + "`;"); + } + public List getTables() { try { - List tables = new ArrayList<>(); - DatabaseMetaData metadata = connection.getMetaData(); - ResultSet queryResults = metadata.getTables(null, null, "%", null); - + List tables = new ArrayList<>(); + DatabaseMetaData metadata = connection.getMetaData(); + ResultSet queryResults = metadata.getTables(null, null, "%", null); + while (queryResults.next()) { tables.add(new MysqlTable(this, queryResults.getString(3))); } - + return tables; } catch (SQLException e) { e.printStackTrace(); return null; } } - + protected Connection getConnection() { return connection; } + + private String getDescription(MysqlField... description) { + String desc = "("; + + for (int i = 0; i < description.length; i++) { + String nil = ""; + + if (description[i].canBeNull()) { + nil = " NOT NULL"; + } + + desc += "`" + description[i].getName() + "` " + description[i].getType().getName() + nil; + + if (i < description.length - 1) { + desc += ","; + } + } + + desc += ")"; + + return desc; + } } diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java b/src/com/redstoner/misc/mysql/elements/MysqlField.java similarity index 90% rename from src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java rename to src/com/redstoner/misc/mysql/elements/MysqlField.java index 68b6fcc..61cba2e 100644 --- a/src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java +++ b/src/com/redstoner/misc/mysql/elements/MysqlField.java @@ -3,30 +3,30 @@ package com.redstoner.misc.mysql.elements; import com.redstoner.misc.mysql.types.MysqlType; public class MysqlField { - private String name; + private String name; private MysqlType type; - private boolean canBeNull; - + private boolean canBeNull; + public MysqlField(String name, MysqlType type, boolean canBeNull) { this.name = name; this.type = type; this.canBeNull = canBeNull; } - + public MysqlField(String name, String type, boolean canBeNull) { this.name = name; this.type = MysqlType.getTypeFromString(type); this.canBeNull = canBeNull; } - + public String getName() { return name; } - + public MysqlType getType() { return type; } - + public boolean canBeNull() { return canBeNull; } diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java b/src/com/redstoner/misc/mysql/elements/MysqlResult.java similarity index 98% rename from src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java rename to src/com/redstoner/misc/mysql/elements/MysqlResult.java index 1b4f246..6db0769 100644 --- a/src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java +++ b/src/com/redstoner/misc/mysql/elements/MysqlResult.java @@ -5,11 +5,11 @@ import java.sql.SQLException; public class MysqlResult { private ResultSet results; - + public MysqlResult(ResultSet results) { this.results = results; } - + public Object getObject(int columnIndex, Class type) throws SQLException { return results.getObject(columnIndex, type); } diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java b/src/com/redstoner/misc/mysql/elements/MysqlTable.java similarity index 57% rename from src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java rename to src/com/redstoner/misc/mysql/elements/MysqlTable.java index e6a7617..fa0008e 100644 --- a/src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java +++ b/src/com/redstoner/misc/mysql/elements/MysqlTable.java @@ -1,63 +1,58 @@ package com.redstoner.misc.mysql.elements; -import com.redstoner.misc.mysql.MysqlQueryHandler; - import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import com.redstoner.misc.mysql.MysqlQueryHandler; + public class MysqlTable { private MysqlDatabase database; - private String name; - + private String name; + public MysqlTable(MysqlDatabase database, String name) { this.database = database; this.name = name; } - + public String getName() { return this.name; } - - public boolean insert(String... values) { - MysqlField[] description = describe(); - if (values.length > 0 && values.length == description.length) { - String val = "(\"" + String.join("\",\"", values) + "\")"; - return MysqlQueryHandler.queryNoResult( - database.getConnection(), - "INSERT INTO `" + name + "` VALUES " + val + ";" - ); - } else { - return false; - } - } - + public MysqlField[] describe() { try { - List description = new ArrayList<>(); - DatabaseMetaData metadata = database.getConnection().getMetaData(); - ResultSet queryResults = metadata.getColumns(null, null, name, null); + List description = new ArrayList<>(); + DatabaseMetaData metadata = database.getConnection().getMetaData(); + ResultSet queryResults = metadata.getColumns(null, null, name, null); + while (queryResults.next()) { - description.add(new MysqlField( - queryResults.getString(4), - queryResults.getString(6).split(" ")[0] + "(" + queryResults.getString(7) + ")", - queryResults.getBoolean(11) - )); + description.add(new MysqlField(queryResults.getString(4), queryResults.getString(6).split(" ")[0] + "(" + queryResults.getString(7) + ")", queryResults.getBoolean(11))); } + return description.toArray(new MysqlField[0]); } catch (SQLException e) { e.printStackTrace(); return null; } } - + + public boolean insert(String... values) { + MysqlField[] description = describe(); + + if (values.length > 0 && values.length == description.length) { + String val = "(\"" + String.join("\",\"", values) + "\")"; + + return MysqlQueryHandler.queryNoResult(database.getConnection(), "INSERT INTO `" + name + "` VALUES " + val + ";"); + } else { + return false; + } + } + public Object[] get(String fieldName, MysqlConstraint... constraints) { - ResultSet results = MysqlQueryHandler.queryResult( - database.getConnection(), - "SELECT " + fieldName + " FROM `" + name + "`" + getConstraints(constraints) + ";" - ); + ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), "SELECT " + fieldName + " FROM `" + name + "`" + getConstraints(constraints) + ";"); + List resObj = new ArrayList<>(); try { while (results.next()) { @@ -67,47 +62,35 @@ public class MysqlTable { e.printStackTrace(); return new Object[0]; } + return resObj.toArray(new Object[0]); } - + + public boolean delete(MysqlConstraint... constraints) { + return MysqlQueryHandler.queryNoResult(database.getConnection(), "DELETE FROM `" + name + "`" + getConstraints(constraints) + ";"); + } + + public boolean drop() { + return MysqlQueryHandler.queryNoResult(database.getConnection(), "DROP TABLE `" + name + "`;"); + } + private String getConstraints(MysqlConstraint... constraints) { String cons = ""; + if (constraints.length > 0) { cons += " WHERE "; + for (int i = 0; i < constraints.length; i++) { MysqlConstraint constraint = constraints[i]; - cons += constraint.getFieldName() + constraint.getOperator().toString() + "\"" + constraint.getValue() - + "\""; + + cons += constraint.getFieldName() + constraint.getOperator().toString() + "\"" + constraint.getValue() + "\""; + if (i < constraints.length - 1) { cons += " AND "; } } } + return cons; } - - public Object[] get(String statement) { - ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), statement); - List resObj = new ArrayList<>(); - try { - while (results.next()) { - resObj.add(results.getObject(1)); - } - } catch (SQLException e) { - e.printStackTrace(); - return new Object[0]; - } - return resObj.toArray(new Object[0]); - } - - public boolean delete(MysqlConstraint... constraints) { - return MysqlQueryHandler.queryNoResult( - database.getConnection(), - "DELETE FROM `" + name + "`" + getConstraints(constraints) + ";" - ); - } - - public boolean drop() { - return MysqlQueryHandler.queryNoResult(database.getConnection(), "DROP TABLE `" + name + "`;"); - } } diff --git a/src/main/java/com/redstoner/misc/mysql/types/MysqlType.java b/src/com/redstoner/misc/mysql/types/MysqlType.java similarity index 55% rename from src/main/java/com/redstoner/misc/mysql/types/MysqlType.java rename to src/com/redstoner/misc/mysql/types/MysqlType.java index 4a1c32f..86413f9 100644 --- a/src/main/java/com/redstoner/misc/mysql/types/MysqlType.java +++ b/src/com/redstoner/misc/mysql/types/MysqlType.java @@ -1,21 +1,45 @@ package com.redstoner.misc.mysql.types; -import com.redstoner.misc.mysql.types.date.*; +import com.redstoner.misc.mysql.types.date.Date; +import com.redstoner.misc.mysql.types.date.DateTime; +import com.redstoner.misc.mysql.types.date.Time; +import com.redstoner.misc.mysql.types.date.TimeStamp; +import com.redstoner.misc.mysql.types.date.Year; +import com.redstoner.misc.mysql.types.number.BigInt; +import com.redstoner.misc.mysql.types.number.Decimal; import com.redstoner.misc.mysql.types.number.Double; import com.redstoner.misc.mysql.types.number.Float; -import com.redstoner.misc.mysql.types.number.*; +import com.redstoner.misc.mysql.types.number.Int; +import com.redstoner.misc.mysql.types.number.MediumInt; +import com.redstoner.misc.mysql.types.number.SmallInt; +import com.redstoner.misc.mysql.types.number.TinyInt; +import com.redstoner.misc.mysql.types.text.Blob; +import com.redstoner.misc.mysql.types.text.Char; import com.redstoner.misc.mysql.types.text.Enum; -import com.redstoner.misc.mysql.types.text.*; +import com.redstoner.misc.mysql.types.text.LongBlob; +import com.redstoner.misc.mysql.types.text.LongText; +import com.redstoner.misc.mysql.types.text.MediumBlob; +import com.redstoner.misc.mysql.types.text.MediumText; +import com.redstoner.misc.mysql.types.text.Set; +import com.redstoner.misc.mysql.types.text.Text; +import com.redstoner.misc.mysql.types.text.TinyText; +import com.redstoner.misc.mysql.types.text.VarChar; -public abstract class MysqlType { - public static MysqlType getTypeFromString(String type) { +public abstract class MysqlType +{ + public abstract String getName(); + + public static MysqlType getTypeFromString(String type) + { String[] splitType = type.split("\\("); - String toSwitch = splitType[0].toUpperCase(); - String value = ""; - if (type.contains("(") && type.endsWith(")")) { + String toSwitch = splitType[0].toUpperCase(); + String value = ""; + if (type.contains("(") && type.endsWith(")")) + { value = splitType[1].substring(0, splitType[1].length() - 1); } - switch (toSwitch) { + switch (toSwitch) + { case "CHAR": return new Char(Integer.valueOf(value)); case "ENUM": @@ -69,6 +93,4 @@ public abstract class MysqlType { } return null; } - - public abstract String getName(); } diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/Date.java b/src/com/redstoner/misc/mysql/types/date/Date.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/date/Date.java rename to src/com/redstoner/misc/mysql/types/date/Date.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/DateTime.java b/src/com/redstoner/misc/mysql/types/date/DateTime.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/date/DateTime.java rename to src/com/redstoner/misc/mysql/types/date/DateTime.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/Time.java b/src/com/redstoner/misc/mysql/types/date/Time.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/date/Time.java rename to src/com/redstoner/misc/mysql/types/date/Time.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/TimeStamp.java b/src/com/redstoner/misc/mysql/types/date/TimeStamp.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/date/TimeStamp.java rename to src/com/redstoner/misc/mysql/types/date/TimeStamp.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/Year.java b/src/com/redstoner/misc/mysql/types/date/Year.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/date/Year.java rename to src/com/redstoner/misc/mysql/types/date/Year.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/BigInt.java b/src/com/redstoner/misc/mysql/types/number/BigInt.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/BigInt.java rename to src/com/redstoner/misc/mysql/types/number/BigInt.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Decimal.java b/src/com/redstoner/misc/mysql/types/number/Decimal.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/Decimal.java rename to src/com/redstoner/misc/mysql/types/number/Decimal.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Double.java b/src/com/redstoner/misc/mysql/types/number/Double.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/Double.java rename to src/com/redstoner/misc/mysql/types/number/Double.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Float.java b/src/com/redstoner/misc/mysql/types/number/Float.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/Float.java rename to src/com/redstoner/misc/mysql/types/number/Float.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Int.java b/src/com/redstoner/misc/mysql/types/number/Int.java similarity index 98% rename from src/main/java/com/redstoner/misc/mysql/types/number/Int.java rename to src/com/redstoner/misc/mysql/types/number/Int.java index 7b2fbfd..4256f7b 100644 --- a/src/main/java/com/redstoner/misc/mysql/types/number/Int.java +++ b/src/com/redstoner/misc/mysql/types/number/Int.java @@ -4,11 +4,11 @@ import com.redstoner.misc.mysql.types.MysqlType; public class Int extends MysqlType { private int maxSize; - + public Int(int maxSize) { this.maxSize = maxSize; } - + @Override public String getName() { return "INT(" + maxSize + ")"; diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/MediumInt.java b/src/com/redstoner/misc/mysql/types/number/MediumInt.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/MediumInt.java rename to src/com/redstoner/misc/mysql/types/number/MediumInt.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/SmallInt.java b/src/com/redstoner/misc/mysql/types/number/SmallInt.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/SmallInt.java rename to src/com/redstoner/misc/mysql/types/number/SmallInt.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/TinyInt.java b/src/com/redstoner/misc/mysql/types/number/TinyInt.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/number/TinyInt.java rename to src/com/redstoner/misc/mysql/types/number/TinyInt.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Blob.java b/src/com/redstoner/misc/mysql/types/text/Blob.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/Blob.java rename to src/com/redstoner/misc/mysql/types/text/Blob.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Char.java b/src/com/redstoner/misc/mysql/types/text/Char.java similarity index 98% rename from src/main/java/com/redstoner/misc/mysql/types/text/Char.java rename to src/com/redstoner/misc/mysql/types/text/Char.java index 4d4a938..ece068c 100644 --- a/src/main/java/com/redstoner/misc/mysql/types/text/Char.java +++ b/src/com/redstoner/misc/mysql/types/text/Char.java @@ -4,11 +4,11 @@ import com.redstoner.misc.mysql.types.MysqlType; public class Char extends MysqlType { private int size; - + public Char(int size) { this.size = size; } - + @Override public String getName() { return "CHAR(" + size + ")"; diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Enum.java b/src/com/redstoner/misc/mysql/types/text/Enum.java similarity index 96% rename from src/main/java/com/redstoner/misc/mysql/types/text/Enum.java rename to src/com/redstoner/misc/mysql/types/text/Enum.java index 6200292..e68476d 100644 --- a/src/main/java/com/redstoner/misc/mysql/types/text/Enum.java +++ b/src/com/redstoner/misc/mysql/types/text/Enum.java @@ -4,24 +4,24 @@ import com.redstoner.misc.mysql.types.MysqlType; public class Enum extends MysqlType { private String[] possibleValues; - + public Enum(String... possibleValues) { this.possibleValues = possibleValues; } - + @Override public String getName() { String name = "ENUM("; - + for (int i = 0; i < possibleValues.length; i++) { name += "'" + possibleValues[i] + "'"; - + if (i != possibleValues.length - 1) { name += ","; } } - + return name + ")"; } - + } diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/LongBlob.java b/src/com/redstoner/misc/mysql/types/text/LongBlob.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/LongBlob.java rename to src/com/redstoner/misc/mysql/types/text/LongBlob.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/LongText.java b/src/com/redstoner/misc/mysql/types/text/LongText.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/LongText.java rename to src/com/redstoner/misc/mysql/types/text/LongText.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/MediumBlob.java b/src/com/redstoner/misc/mysql/types/text/MediumBlob.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/MediumBlob.java rename to src/com/redstoner/misc/mysql/types/text/MediumBlob.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/MediumText.java b/src/com/redstoner/misc/mysql/types/text/MediumText.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/MediumText.java rename to src/com/redstoner/misc/mysql/types/text/MediumText.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Set.java b/src/com/redstoner/misc/mysql/types/text/Set.java similarity index 96% rename from src/main/java/com/redstoner/misc/mysql/types/text/Set.java rename to src/com/redstoner/misc/mysql/types/text/Set.java index f82f02b..4e12ce6 100644 --- a/src/main/java/com/redstoner/misc/mysql/types/text/Set.java +++ b/src/com/redstoner/misc/mysql/types/text/Set.java @@ -4,24 +4,24 @@ import com.redstoner.misc.mysql.types.MysqlType; public class Set extends MysqlType { private String[] possibleValues; - + public Set(String... possibleValues) { this.possibleValues = possibleValues; } - + @Override public String getName() { String name = "SET("; - + for (int i = 0; i < possibleValues.length; i++) { name += "'" + possibleValues[i] + "'"; - + if (i != possibleValues.length - 1) { name += ","; } } - + return name + ")"; } - + } diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Text.java b/src/com/redstoner/misc/mysql/types/text/Text.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/Text.java rename to src/com/redstoner/misc/mysql/types/text/Text.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/TinyText.java b/src/com/redstoner/misc/mysql/types/text/TinyText.java similarity index 100% rename from src/main/java/com/redstoner/misc/mysql/types/text/TinyText.java rename to src/com/redstoner/misc/mysql/types/text/TinyText.java diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java b/src/com/redstoner/misc/mysql/types/text/VarChar.java similarity index 98% rename from src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java rename to src/com/redstoner/misc/mysql/types/text/VarChar.java index 65b6416..cb28ad1 100644 --- a/src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java +++ b/src/com/redstoner/misc/mysql/types/text/VarChar.java @@ -4,11 +4,11 @@ import com.redstoner.misc.mysql.types.MysqlType; public class VarChar extends MysqlType { private int maxSize; - + public VarChar(int maxSize) { this.maxSize = maxSize; } - + @Override public String getName() { return "VARCHAR(" + maxSize + ")"; diff --git a/src/com/redstoner/modules/CoreModule.java b/src/com/redstoner/modules/CoreModule.java new file mode 100644 index 0000000..8c78308 --- /dev/null +++ b/src/com/redstoner/modules/CoreModule.java @@ -0,0 +1,29 @@ +package com.redstoner.modules; + +import com.redstoner.annotations.Version; + +/** This class shall be used for "CoreModules", which are acting on a lower level than modules and are also exempted from being disabled or reloaded on the go.
+ * Please note that CoreModules will not be known to the ModuleLoader itself!
+ * Examples are the ModuleLoader and the Debugger. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 1, compatible = -1) +public interface CoreModule extends Module +{ + /** Core modules should always be enabled. */ + @Override + public default boolean enabled() + { + return true; + } + + /** Core modules don't need to be enabled. */ + @Override + public default void onEnable() + {} + + /** Core modules don't need to be disabled. */ + @Override + public default void onDisable() + {} +} diff --git a/src/com/redstoner/modules/Module.java b/src/com/redstoner/modules/Module.java new file mode 100644 index 0000000..3ffba42 --- /dev/null +++ b/src/com/redstoner/modules/Module.java @@ -0,0 +1,35 @@ +package com.redstoner.modules; + +import com.redstoner.annotations.Version; + +/** Interface for the Module class. Modules must always have an empty constructor to be invoked by the ModuleLoader. + * + * @author Pepich */ +@Version(major = 1, minor = 1, revision = 1, compatible = 1) +public interface Module +{ + /** Will be called when the module gets enabled. */ + public void onEnable(); + + /** Will be called when the module gets disabled. */ + public void onDisable(); + + /** Will be called to check if a module is enabled or not. + * + * @return The status of the module, true when enabled, false when not. */ + public boolean enabled(); + + /** Default implementation for the enable() method, returning weather the module was enabled or not. + * + * @return */ + public default boolean enable() + { + onEnable(); + return enabled(); + } + + /** Gets called on registration of the module. + * + * @return The String used for the CommandManager to register the commands. */ + public String getCommandString(); +} diff --git a/src/com/redstoner/modules/abot/Abot.java b/src/com/redstoner/modules/abot/Abot.java new file mode 100644 index 0000000..428a7ea --- /dev/null +++ b/src/com/redstoner/modules/abot/Abot.java @@ -0,0 +1,93 @@ +package com.redstoner.modules.abot; + +import java.io.File; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public class Abot implements Module, Listener +{ + private boolean enabled = false; + private File answerFile = new File(Main.plugin.getDataFolder(), "abot.json"); + JSONArray answers; + + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + for (Object rawObject : answers) + { + JSONObject entry = (JSONObject) rawObject; + JSONArray regexes = (JSONArray) entry.get("regex"); + for (Object regex : regexes) + { + if (event.getMessage().toLowerCase().matches((String) regex)) + { + Object hideperm = entry.get("hide-perm"); + if (hideperm == null || !event.getPlayer().hasPermission((String) hideperm)) + { + event.setCancelled(true); + Utils.sendMessage(event.getPlayer(), null, (String) entry.get("message"), '&'); + return; + } + } + } + } + } + + @Command(hook = "abot_reload") + public void loadAnswers(CommandSender sender) + { + answers = JsonManager.getArray(answerFile); + if (answers == null) + answers = new JSONArray(); + Utils.sendMessage(sender, null, "Loaded the abot.json file!"); + } + + @Override + public void onEnable() + { + loadAnswers(Bukkit.getConsoleSender()); + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command abot {\n" + + " reload {" + + " help Reloads answes from the .json file.;\n" + + " run abot_reload;\n" + + " perm utils.abot.reload;" + + " }\n" + + "}"; + } + // format +} diff --git a/src/com/redstoner/modules/adminchat/Adminchat.java b/src/com/redstoner/modules/adminchat/Adminchat.java new file mode 100644 index 0000000..b179752 --- /dev/null +++ b/src/com/redstoner/modules/adminchat/Adminchat.java @@ -0,0 +1,248 @@ +package com.redstoner.modules.adminchat; + +import java.io.File; +import java.util.ArrayList; +import java.util.UUID; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.BroadcastFilter; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +/** AdminChat module. Allows staff to chat to other staff using /ac \ as well as a one char prefix or a toggle. + * + * @author Pepich */ +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 6, compatible = 1) +public class Adminchat implements Module, Listener +{ + private static final char defaultKey = ','; + private boolean enabled = false; + private static final File keysLocation = new File(Main.plugin.getDataFolder(), "adminchat_keys.json"); + private ArrayList actoggled; + private static JSONObject keys; + + @Override + public void onEnable() + { + keys = JsonManager.getObject(keysLocation); + if (keys == null) + { + keys = new JSONObject(); + saveKeys(); + } + actoggled = new ArrayList(); + this.enabled = true; + } + + @Override + public void onDisable() + { + this.enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command ac {\n" + + " [string:message...] {\n" + + " help Sends a message in Admin Chat;\n" + + " perm utils.ac;\n" + + " run ac_msg message;\n" + + " }\n" + + "}\n" + + " \n" + + "command ackey {\n" + + " [string:key] {\n" + + " help Sets your Admin Chat key;\n" + + " perm utils.ac;\n" + + " type player;\n" + + " run setackey key;\n" + + " }\n" + + "}\n" + + "\n" + + "command act {\n" + + " on {\n" + + " help Turns on act;\n" + + " perm utils.ac;\n" + + " run act_on;\n" + + " }\n" + + " off {\n" + + " help Turns off act;\n" + + " perm utils.ac;\n" + + " run act_off;\n" + + " }\n" + + " [empty] {\n" + + " help toggles Admin Chat;\n" + + " perm utils.ac;\n" + + " run act;\n" + + " }\n" + + "}"; + } + // @format + + @Command(hook = "ac_msg") + public boolean acSay(CommandSender sender, String message) + { + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = sender.getName(); + Utils.broadcast("§8[§cAC§8] §9" + name + "§8: §b", message, new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + return recipient.hasPermission("utils.ac"); + } + }, '&'); + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @param _void ignored. + * @return true. */ + @Command(hook = "act") + public boolean acToggleCommand(CommandSender sender) + { + if (actoggled.contains(((Player) sender).getUniqueId())) + { + actoggled.remove(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §cdisabled"); + } + else + { + actoggled.add(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §aenabled"); + } + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @return true. */ + @Command(hook = "act_on") + public boolean acToggleOnCommand(CommandSender sender) + { + if (!actoggled.contains(((Player) sender).getUniqueId())) + { + actoggled.add(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §aenabled"); + } + else + Utils.sendMessage(sender, null, "ACT was already enabled"); + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @return true. */ + @Command(hook = "act_off") + public boolean acToggleOffCommand(CommandSender sender) + { + if (actoggled.contains(((Player) sender).getUniqueId())) + { + actoggled.remove(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "ACT now §cdisabled"); + } + else + { + Utils.sendMessage(sender, null, "ACT was already disabled"); + } + return true; + } + + /** Deals with chat events to allow for cgkeys and cgtoggle. + * + * @param event the chat event containing the player and the message. */ + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + if (!player.hasPermission("utils.ac")) + return; + if (event.getMessage().startsWith(getKey(player))) + { + event.setCancelled(true); + acSay(event.getPlayer(), event.getMessage().replaceFirst(getKey(player), "")); + } + else if (actoggled.contains(event.getPlayer().getUniqueId())) + { + event.setCancelled(true); + acSay(event.getPlayer(), event.getMessage()); + } + } + + /** Sets the ackey of a Player. + * + * @param sender the issuer of the command. + * @param key the key to be set. Set to NULL or "" to get your current key. + * @return true. */ + @SuppressWarnings("unchecked") + @Command(hook = "setackey") + public boolean setAcKey(CommandSender sender, String key) + { + if (key.length() > 1) + { + Utils.sendErrorMessage(sender, null, + "Could not set your key to §6" + key + " §7, it can be at most one char."); + return true; + } + if (key == null || key.length() == 0) + { + getAcKey(sender); + return true; + } + Utils.sendMessage(sender, null, "Set your key to §6" + key); + keys.put(((Player) sender).getUniqueId().toString(), key + ""); + saveKeys(); + return true; + } + + /** This method will find the ChatgGroup key of any player. + * + * @param player the player to get the key from. + * @return the key. */ + public static String getKey(Player player) + { + String key = (String) keys.get(player.getUniqueId().toString()); + return (key == null ? "" + defaultKey : key); + } + + /** Prints a Players ackey to their chat. + * + * @param sender the issuer of the command. */ + public void getAcKey(CommandSender sender) + { + Utils.sendMessage(sender, null, "Your current ackey is §6" + getKey((Player) sender)); + } + + /** Saves the keys. */ + private void saveKeys() + { + JsonManager.save(keys, keysLocation); + } +} diff --git a/src/com/redstoner/modules/adminnotes/AdminNotes.java b/src/com/redstoner/modules/adminnotes/AdminNotes.java new file mode 100644 index 0000000..ba393e5 --- /dev/null +++ b/src/com/redstoner/modules/adminnotes/AdminNotes.java @@ -0,0 +1,139 @@ +package com.redstoner.modules.adminnotes; + +import java.io.File; +import java.text.SimpleDateFormat; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 3, compatible = 1) +public class AdminNotes implements Module, Listener +{ + private boolean enabled = false; + JSONArray notes; + File saveFile = new File(Main.plugin.getDataFolder(), "adminnotes.json"); + + @Override + public void onEnable() + { + notes = JsonManager.getArray(saveFile); + if (notes == null) + notes = new JSONArray(); + enabled = true; + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) + { + if (e.getPlayer().hasPermission("utils.adminnotes")) + { + if (notes.size() > 0) + { + Utils.sendMessage(e.getPlayer(), null, "§cThere are " + notes.size() + " open notes!"); + } + } + } + + @Override + public void onDisable() + { + saveNotes(); + enabled = false; + } + + @SuppressWarnings("unchecked") + @Command(hook = "an_create") + public void createNote(CommandSender sender, String note) + { + JSONArray temp = new JSONArray(); + temp.add(sender.getName()); + temp.add(note); + temp.add((double) System.currentTimeMillis() / 1000); + notes.add(temp); + Utils.sendMessage(sender, null, "§aNote added!"); + saveNotes(); + } + + @Command(hook = "an_del") + public void delNote(CommandSender sender, int id) + { + if (id < notes.size() && id >= 0 && notes.get(id) != null) + { + notes.remove(id); + Utils.sendMessage(sender, null, "§aNote " + id + " has been removed!"); + saveNotes(); + } + else + { + Utils.sendMessage(sender, null, "§cThat note does not exist!"); + } + } + + @Command(hook = "an_list") + public void list(CommandSender sender) + { + Utils.sendModuleHeader(sender); + for (Object note : notes) + { + String string = ChatColor.YELLOW + "" + notes.indexOf(note) + ": "; + string += "§a" + ((JSONArray) note).get(1); + string += "\n§e - " + ((JSONArray) note).get(0) + ", §6"; + SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy HH:mm"); + string += format.format((double) ((JSONArray) note).get(2) * 1000); + Utils.sendMessage(sender, "", string); + } + } + + public void saveNotes() + { + JsonManager.save(notes, saveFile); + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command an {\n" + + " perm utils.adminnotes;\n" + + " \n" + + " add [string:note...] {\n" + + " type player;\n" + + " help Creates a new admin note;\n" + + " run an_create note;\n" + + " perm utils.an;" + + " }\n" + + " \n" + + " del [int:id] {\n" + + " help Deletes an admin note;\n" + + " run an_del id;\n" + + " perm utils.an;" + + " }\n" + + " \n" + + " list {\n" + + " help Lists all notes;\n" + + " run an_list;\n" + + " perm utils.an;" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/chatalias/Chatalias.java b/src/com/redstoner/modules/chatalias/Chatalias.java new file mode 100644 index 0000000..0e5f0b3 --- /dev/null +++ b/src/com/redstoner/modules/chatalias/Chatalias.java @@ -0,0 +1,340 @@ +package com.redstoner.modules.chatalias; + +import java.io.File; +import java.util.Set; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 6, compatible = 1) +public class Chatalias implements Module, Listener +{ + // to export chatalias data to json: + // pyeval [save_json_file("aliases/" + uuid, shared['modules']['chatalias'].data[uuid]) for uuid in shared['modules']['chatalias'].data] + // HANDLE WITH CARE! This will create an array of null entries the size of len(data)! + private boolean enabled = false; + @SuppressWarnings("unused") + private final String[] commands = new String[] {"e?r", "e?m", "e?t", "e?w", "e?msg", "e?message", "e?whisper", + "e?me", "cg say", "ac"}; + private JSONObject defaults = new JSONObject(); + private JSONObject aliases = new JSONObject(); + + @SuppressWarnings("unchecked") + @Override + public void onEnable() + { + defaults.put("dataFormat", "v1"); + JSONObject data = new JSONObject(); + data.put("R: ^(([^\\w]|_)\\/|\\\\)", "\\/"); + defaults.put("data", data); + for (Player p : Bukkit.getOnlinePlayers()) + { + loadAliases(p.getUniqueId()); + } + enabled = true; + } + + @Override + public void onDisable() + { + for (Object key : aliases.keySet()) + { + UUID uuid = UUID.fromString((String) key); + saveAliases(uuid); + } + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + loadAliases(event.getPlayer().getUniqueId()); + } + + @EventHandler + public void onPlayerLeave(PlayerQuitEvent event) + { + aliases.remove(event.getPlayer().getUniqueId().toString()); + } + + @SuppressWarnings("unchecked") + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + JSONObject playerAliases = (JSONObject) aliases.get(uuid.toString()); + boolean changed = false; + for (Object key : playerAliases.keySet()) + { + String keyword = (String) key; + String replacement = (String) playerAliases.get(key); + if (keyword.startsWith("R: ")) + { + keyword = keyword.replace("R: ", ""); + event.setMessage(event.getMessage().replaceAll(keyword, replacement)); + } + else + { + if (keyword.startsWith("N: ")) + keyword = keyword.replace("N: ", ""); + else + { + changed = true; + playerAliases.put("N: " + key, replacement); + } + event.setMessage(event.getMessage().replace(keyword, replacement)); + } + int maxLength; + try + { + maxLength = Integer.valueOf(getPermissionContent(player, "utils.alias.length.")); + } + catch (NumberFormatException e) + { + maxLength = 255; + } + if (event.getMessage().length() > maxLength) + { + Utils.sendErrorMessage(player, null, "The generated message is too long!"); + event.setCancelled(true); + return; + } + } + if (changed) + saveAliases(uuid); + } + + // @EventHandler + // public void onPlayerCommand(PlayerCommandPreprocessEvent event) + // { + // if (event.isCancelled()) + // return; + // boolean listening = false; + // for (String s : commands) + // { + // if (event.getMessage().matches("^/.*:" + s)) + // { + // listening = true; + // break; + // } + // } + // if (!listening) + // return; + // Player player = event.getPlayer(); + // UUID uuid = player.getUniqueId(); + // JSONObject playerAliases = (JSONObject) aliases.get(uuid.toString()); + // String command = event.getMessage().split(" ")[0]; + // event.setMessage(event.getMessage().replace(command, "")); + // for (Object key : playerAliases.keySet()) + // { + // String keyword = (String) key; + // String replacement = (String) playerAliases.get(key); + // if (keyword.startsWith("R: ")) + // { + // keyword = keyword.replace("R: ", ""); + // event.setMessage(event.getMessage().replaceAll(keyword, replacement)); + // } + // else + // { + // if (keyword.startsWith("N: ")) + // keyword = keyword.replace("N: ", ""); + // event.setMessage(event.getMessage().replace(keyword, replacement)); + // } + // int maxLength; + // try + // { + // maxLength = Integer.valueOf(getPermissionContent(player, "utils.alias.length.")); + // } + // catch (NumberFormatException e) + // { + // maxLength = 255; + // } + // if (event.getMessage().length() > maxLength) + // { + // Utils.sendErrorMessage(player, null, "The generated message is too long!"); + // event.setCancelled(true); + // return; + // } + // } + // event.setMessage(command + event.getMessage()); + // } + @SuppressWarnings("unchecked") + @Command(hook = "addalias") + public boolean addAlias(CommandSender sender, boolean regex, String keyword, String replacement) + { + if (keyword.equals(".*")) + { + Utils.sendErrorMessage(sender, null, "You may not define the wildcard regex as an alias."); + return true; + } + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONObject data = (JSONObject) aliases.get(uuid.toString()); + keyword = (regex ? "R: " : "N: ") + keyword; + if (!data.containsKey(keyword)) + { + int maxAmount; + try + { + maxAmount = Integer.valueOf(getPermissionContent(player, "utils.alias.amount.")); + } + catch (NumberFormatException e) + { + maxAmount = 25; + } + if (data.size() == maxAmount) + { + Utils.sendErrorMessage(sender, null, "You already reached your maximum of aliases!"); + return true; + } + } + data.put(keyword, replacement); + if (sender.hasPermission("essentials.chat.color")) + Utils.sendMessage(sender, null, + "Successfully created alias " + keyword.substring(3) + " §7-> " + replacement + " §7for you.", '&'); + else + Utils.sendMessage(sender, null, + "Successfully created alias " + keyword.substring(3) + " §7-> " + replacement + " §7for you."); + saveAliases(uuid); + return true; + } + + @Command(hook = "delalias") + public boolean delAlias(CommandSender sender, boolean regex, String keyword) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONObject data = (JSONObject) aliases.get(uuid.toString()); + keyword = (regex ? "R: " : "N: ") + keyword; + if (data.remove(keyword) != null) + { + Utils.sendMessage(sender, null, "Successfully removed the alias!"); + saveAliases(uuid); + return true; + } + else + { + Utils.sendErrorMessage(sender, null, + "That alias doesn't exist! Hint: regex/no regex does matter for this."); + return true; + } + } + + @Command(hook = "listaliases") + public boolean listAliases(CommandSender sender) + { + Utils.sendModuleHeader(sender); + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONObject data = (JSONObject) aliases.get(uuid.toString()); + for (Object key : data.keySet()) + { + if (sender.hasPermission("essentials.chat.color")) + Utils.sendMessage(sender, "", (String) key + " §7-> " + data.get(key), '&'); + else + Utils.sendMessage(sender, "", (String) key + " §7-> " + data.get(key)); + } + return true; + } + + private String getPermissionContent(Player player, String permnode) + { + Set perms = player.getEffectivePermissions(); + for (PermissionAttachmentInfo perm : perms) + if (perm.getPermission().toString().startsWith(permnode)) + return perm.getPermission().replace(permnode, ""); + return null; + } + + @SuppressWarnings("unchecked") + private void loadAliases(UUID uuid) + { + JSONObject playerAliases = JsonManager + .getObject(new File(Main.plugin.getDataFolder(), "aliases/" + uuid.toString() + ".json")); + if (playerAliases == null) + { + playerAliases = (JSONObject) defaults.clone(); + } + String dataFormat = (String) playerAliases.get("dataFormat"); + if (dataFormat == null) + { + JSONObject temp = new JSONObject(); + temp.put("dataFormat", "v1"); + JSONObject tempAliases = new JSONObject(); + { + for (Object key : playerAliases.keySet()) + { + tempAliases.put(key, "N: " + playerAliases.get(key)); + } + } + temp.put("data", tempAliases); + aliases.put(uuid.toString(), temp.get("data")); + } + else if (dataFormat.equals("v1")) + aliases.put(uuid.toString(), playerAliases.get("data")); + else + { + Utils.error("Unknown data format for alias set of player " + uuid.toString()); + aliases.put(uuid.toString(), ((JSONObject) defaults.get("data")).clone()); + saveAliases(uuid); + } + } + + @SuppressWarnings("unchecked") + private void saveAliases(UUID uuid) + { + JSONObject temp = new JSONObject(); + temp.put("dataFormat", "v1"); + temp.put("data", aliases.get(uuid.toString())); + JsonManager.save(temp, new File(Main.plugin.getDataFolder(), "aliases/" + uuid.toString() + ".json")); + } + + // @noformat + @Override + public String getCommandString() + { + return "command alias {\n" + + " add [flag:-r] [string:keyword] [string:replacement...] {\n" + + " help Adds a new alias. Set -r to make it a regex-alias.;\n" + + " run addalias -r keyword replacement;\n" + + " }\n" + + " del [flag:-r] [string:keyword] {\n" + + " help Deletes an alias. -r indicates if it was a regex-alias.;\n" + + " run delalias -r keyword;\n" + + " }\n" + + " list {\n" + + " help Lists your aliases.;\n" + + " run listaliases;\n" + + " }\n" + + " perm utils.alias;\n" + + " type player;\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/chatgroups/Chatgroups.java b/src/com/redstoner/modules/chatgroups/Chatgroups.java new file mode 100644 index 0000000..2ee0ee0 --- /dev/null +++ b/src/com/redstoner/modules/chatgroups/Chatgroups.java @@ -0,0 +1,372 @@ +package com.redstoner.modules.chatgroups; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.BroadcastFilter; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +/** The ChatGroups module. Allows people to have private sub-chats that can be accessed via a single char prefix or a toggle. + * + * @author Pepich */ +@AutoRegisterListener +@Version(major = 1, minor = 2, revision = 1, compatible = 1) +public class Chatgroups implements Module, Listener +{ + private static final char defaultKey = ':'; + private static final File groupsLocation = new File(Main.plugin.getDataFolder(), "chatgroups.json"); + private static final File keysLocation = new File(Main.plugin.getDataFolder(), "chatgroup_keys.json"); + private ArrayList cgtoggled; + private static JSONObject groups, keys; + private boolean enabled = false; + + @Override + public void onEnable() + { + groups = JsonManager.getObject(groupsLocation); + if (groups == null) + { + groups = new JSONObject(); + saveGroups(); + } + keys = JsonManager.getObject(keysLocation); + if (keys == null) + { + keys = new JSONObject(); + saveKeys(); + } + cgtoggled = new ArrayList(); + enabled = true; + } + + @Override + public void onDisable() + { + saveKeys(); + saveGroups(); + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command cgt {\n" + + " [empty] {\n" + + " help Toggles your cgtoggle status.;\n"+ + " type player;\n" + + " run cgtoggle;\n" + + " }\n" + + "}\n" + + "command cgkey {\n" + + " [string:key] {\n" + + " help Sets your chatgroup key.;\n" + + " run setcgkey key;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "command cgsay {\n" + + " [string:message...] {\n" + + " help Chats in your chatgroup.;\n"+ + " run cgsay message;\n" + + " }\n" + + "}\n" + + "command cg {\n" + + " join [string:group] {\n" + + " help Joins a chatgroup.;\n" + + " run cgjoin group;\n" + + " }\n" + + " leave {\n" + + " help Leaves your chatgroup.;\n" + + " run cgleave;\n" + + " }\n" + + " info {\n" + + " help Displays info about your chatgroup.;\n" + + " run cginfo;\n" + + " }\n" + + + "}"; + } + // @format + + /** Prints chatgroup info (like players in the group, groupname) to the sender. + * + * @param sender the issuer of the command. + * @return true. */ + @SuppressWarnings("unchecked") + @Command(hook = "cginfo") + public boolean cgInfo(CommandSender sender) + { + String group = getGroup(sender); + if (group == null) + Utils.sendErrorMessage(sender, null, "You are not in a chatgroup!"); + else + { + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "Your current chatgroup is: §6" + group); + ArrayList players = new ArrayList(); + Iterator iter = groups.keySet().iterator(); + while (iter.hasNext()) + { + String id = iter.next(); + if (((String) groups.get(id)).equals(group)) + { + if (!id.equals("CONSOLE")) + { + UUID uuid = UUID.fromString(id); + Player p = Bukkit.getPlayer(uuid); + if (p != null) + players.add(p.getDisplayName()); + else + players.add(Bukkit.getOfflinePlayer(UUID.fromString(id)).getName()); + } + else + players.add(id); + } + } + StringBuilder sb = new StringBuilder("&6Other players in this group: &9"); + for (String player : players) + { + sb.append(player); + sb.append("&7, &9"); + } + sb.delete(sb.length() - 2, sb.length()); + Utils.sendMessage(sender, "", sb.toString(), '&'); + } + return true; + } + + /** Prints a Players cgkey to their chat. + * + * @param sender the issuer of the command. */ + public void getCgKey(CommandSender sender) + { + Utils.sendMessage(sender, null, "Your current cgkey is §6" + getKey((Player) sender)); + } + + /** Sets the cgkey of a Player. + * + * @param sender the issuer of the command. + * @param key the key to be set. Set to NULL or "" to get your current key. + * @return true. */ + @SuppressWarnings("unchecked") + @Command(hook = "setcgkey") + public boolean setCgKey(CommandSender sender, String key) + { + if (key.length() > 1) + { + Utils.sendErrorMessage(sender, null, + "Could not set your key to §6" + key + " §7, it can be at most one char."); + return true; + } + if (key == null || key.length() == 0) + { + getCgKey(sender); + return true; + } + Utils.sendMessage(sender, null, "Set your key to §6" + key); + keys.put(((Player) sender).getUniqueId().toString(), key + ""); + saveKeys(); + return true; + } + + /** Let's a Player toggle their auto-cg status to allow for automatically sending chat messages to their chatgroup. + * + * @param sender the issuer of the command. + * @return true. */ + @Command(hook = "cgtoggle") + public boolean cgToggleCommand(CommandSender sender) + { + if (getGroup(sender) != null) + if (cgtoggled.contains(((Player) sender).getUniqueId())) + { + cgtoggled.remove(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "CGT now §cdisabled"); + } + else + { + cgtoggled.add(((Player) sender).getUniqueId()); + Utils.sendMessage(sender, null, "CGT now §aenabled"); + } + else + Utils.sendErrorMessage(sender, null, "You are not in a chatgroup!"); + return true; + } + + /** Lets a CommandSender leave their group. + * + * @param sender the command issuer. + * @return true. */ + @Command(hook = "cgleave") + public boolean cgLeave(CommandSender sender) + { + removeGroup(sender); + Utils.sendMessage(sender, null, "Successfully removed you from your group!"); + cgtoggled.remove(((Player) sender).getUniqueId()); + return true; + } + + /** Lets a CommandSender join a group. + * + * @param sender the command issuer. + * @param name the name of the group. + * @return true. */ + @Command(hook = "cgjoin") + public boolean cgJoin(CommandSender sender, String name) + { + setGroup(sender, name); + Utils.sendMessage(sender, null, "Successfully joined group §6" + name); + return true; + } + + /** Sends a message to a group. + * + * @param sender the sender of the message - the message will be sent to the group of the sender. + * @param message the message to be sent. + * @return true. */ + @Command(hook = "cgsay") + public boolean cgSay(CommandSender sender, String message) + { + String group = getGroup(sender); + if (group != null) + sendToGroup(sender, message); + else + Utils.sendErrorMessage(sender, null, "You are not in a chatgroup right now!"); + return true; + } + + /** Deals with chat events to allow for cgkeys and cgtoggle. + * + * @param event the chat event containing the player and the message. */ + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + String group = getGroup(event.getPlayer()); + Player player = event.getPlayer(); + if (group != null) + { + if (event.getMessage().startsWith(getKey(player))) + { + event.setCancelled(true); + sendToGroup(event.getPlayer(), event.getMessage().replaceFirst(getKey(player), "")); + } + else if (cgtoggled.contains(event.getPlayer().getUniqueId())) + { + event.setCancelled(true); + sendToGroup(event.getPlayer(), event.getMessage()); + } + } + } + + /** Finds the group of a CommandSender. + * + * @param target the CommandSender to get the group of. + * @return the group of the target or NULL if he doesn't have one. */ + public static String getGroup(CommandSender target) + { + if (target instanceof Player) + return (String) groups.get(((Player) target).getUniqueId().toString()); + else + return (String) groups.get("CONSOLE"); + } + + /** Sets the group of the CommandSender. + * + * @param target the CommandSender to set the group of. + * @param group the name of the group to join. */ + @SuppressWarnings("unchecked") + private void setGroup(CommandSender target, String group) + { + if (target instanceof Player) + groups.put(((Player) target).getUniqueId().toString(), group); + else + groups.put("CONSOLE", group); + saveGroups(); + } + + /** Removes a CommandSender from their chatgroup. Will also save the groups after finishing + * + * @param target the CommandSender to get their group removed. */ + private void removeGroup(CommandSender target) + { + if (target instanceof Player) + groups.remove(((Player) target).getUniqueId().toString()); + else + groups.remove("CONSOLE"); + saveGroups(); + } + + /** This method will find the ChatgGroup key of any player. + * + * @param player the player to get the key from. + * @return the key. */ + public static String getKey(Player player) + { + String key = (String) keys.get(player.getUniqueId().toString()); + return (key == null ? "" + defaultKey : key); + } + + /** This method sends a message to a chatgroup. + * + * @param sender the sender of the message. Also defines which group the message will be sent to. + * @param message the message to be sent. */ + private void sendToGroup(CommandSender sender, String message) + { + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = sender.getName(); + String group = getGroup(sender); + Utils.broadcast("§8[§bCG§8] §9", name + "§8: §6" + message, new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + String rgroup = getGroup(recipient); + if (rgroup != null) + return rgroup.equals(group); + else + return false; + } + }); + if (!getGroup(Bukkit.getConsoleSender()).equals(group)) + { + Utils.log(name + " in " + group + ": " + message + " §8(hidden)"); + } + } + + /** Saves the groups. */ + private void saveGroups() + { + JsonManager.save(groups, groupsLocation); + } + + /** Saves the keys. */ + private void saveKeys() + { + JsonManager.save(keys, keysLocation); + } +} diff --git a/src/com/redstoner/modules/check/Check.java b/src/com/redstoner/modules/check/Check.java new file mode 100644 index 0000000..d0ccefb --- /dev/null +++ b/src/com/redstoner/modules/check/Check.java @@ -0,0 +1,253 @@ +package com.redstoner.modules.check; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.Scanner; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Listener; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.misc.mysql.JSONManager; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.misc.mysql.elements.ConstraintOperator; +import com.redstoner.misc.mysql.elements.MysqlConstraint; +import com.redstoner.misc.mysql.elements.MysqlDatabase; +import com.redstoner.misc.mysql.elements.MysqlTable; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 4, compatible = 1) +public class Check implements Module, Listener +{ + private boolean enabled = false; + MysqlTable table; + + @Override + public void onEnable() + { + Map config = JSONManager.getConfiguration("check.json"); + if (config == null || !config.containsKey("database") || !config.containsKey("table")) + { + Utils.error("Could not load the Check config file, disabling!"); + enabled = false; + return; + } + try + { + MysqlDatabase database = MysqlHandler.INSTANCE.getDatabase((String) config.get("database")); + table = database.getTable((String) config.get("table")); + } + catch (NullPointerException e) + { + Utils.error("Could not use the Check config, disabling!"); + enabled = false; + return; + } + enabled = true; + } + + @SuppressWarnings("deprecation") + @Command(hook = "checkCommand", async = AsyncType.ALWAYS) + public void checkCommand(final CommandSender sender, final String player) + { + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "&7Please notice that the data may not be fully accurate!"); + OfflinePlayer oPlayer = Bukkit.getServer().getOfflinePlayer(player); + sendData(sender, oPlayer); + } + + public String read(URL url) + { + String data = ""; + try + { + Scanner in = new Scanner(new InputStreamReader(url.openStream())); + while (in.hasNextLine()) + { + data += in.nextLine(); + } + in.close(); + return data; + } + catch (IOException e) + { + e.printStackTrace(); + } + return null; + } + + public JSONObject getIpInfo(OfflinePlayer player) + { + String ip = ""; + if (player.isOnline()) + { + ip = player.getPlayer().getAddress().getHostString(); + } + else + { + try + { + ip = (String) table.get("last_ip", new MysqlConstraint("uuid", ConstraintOperator.EQUAL, + player.getUniqueId().toString().replace("-", "")))[0]; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + try + { + URL ipinfo = new URL("http://ipinfo.io/" + ip + "/json"); + String rawJson = read(ipinfo); + return (JSONObject) new JSONParser().parse(rawJson); + } + catch (Exception e) + { + e.printStackTrace(); + } + return null; + } + + public String getFirstJoin(OfflinePlayer player) + { + Long firstJoin = player.getFirstPlayed(); + Date date = new Date(firstJoin); + SimpleDateFormat format = new SimpleDateFormat("y-M-d H:m"); + return format.format(date); + } + + public String getLastSeen(OfflinePlayer player) + { + Long lastSeen = player.getLastPlayed(); + Date date = new Date(lastSeen); + SimpleDateFormat format = new SimpleDateFormat("y-M-d H:m"); + return format.format(date); + } + + public Object[] getWebsiteData(OfflinePlayer player) + { + MysqlConstraint constraint = new MysqlConstraint("uuid", ConstraintOperator.EQUAL, + player.getUniqueId().toString().replace("-", "")); + try + { + int id = (int) table.get("id", constraint)[0]; + String email = (String) table.get("email", constraint)[0]; + boolean confirmed = (boolean) table.get("confirmed", constraint)[0]; + return new Object[] {"https://redstoner.com/users/" + id, email, confirmed}; + } + catch (Exception e) + { + return new Object[] {null}; + } + } + + public String getCountry(JSONObject data) + { + return (String) data.get("country"); + } + + public String getAllNames(OfflinePlayer player) + { + String uuid = player.getUniqueId().toString().replace("-", ""); + String nameString = ""; + try + { + String rawJson = read(new URL("https://api.mojang.com/user/profiles/" + uuid + "/names")); + System.out.println("name for " + uuid + " : " + rawJson); + JSONArray names = (JSONArray) new JSONParser().parse(rawJson); + for (Object obj : names) + { + nameString += ((JSONObject) obj).get("name") + ", "; + } + nameString = nameString.substring(0, nameString.length() - 2); + return nameString; + } + catch (MalformedURLException | ParseException e) + { + e.printStackTrace(); + } + return null; + } + + public void sendData(CommandSender sender, OfflinePlayer player) + { + JSONObject ipInfo = getIpInfo(player); + try + { + // data + String firstJoin = getFirstJoin(player); + String lastSeen = getFirstJoin(player); + firstJoin = (firstJoin.equals("1970-1-1 1:0")) ? "&eNever" : "&7(y-m-d h:m:s) &e" + firstJoin; + lastSeen = (lastSeen.equals("1970-1-1 1:0")) ? "&eNever" : "&7(y-m-d h:m:s) &e" + lastSeen; + Object[] websiteData = getWebsiteData(player); + String websiteUrl = (websiteData[0] == null) ? "None" : (String) websiteData[0]; + String email = (websiteData[0] == null) ? "Unknown" : (String) websiteData[1]; + boolean emailNotConfirmed = (websiteData[0] == null) ? false : !((boolean) websiteData[2]); + String country = (ipInfo == null) ? "Unknown" : getCountry(ipInfo); + String namesUsed = getAllNames(player); + if (namesUsed == null) + namesUsed = "None"; + // messages + Utils.sendMessage(sender, "", "&7Data provided by Redstoner:", '&'); + Utils.sendMessage(sender, "", "&6> UUID: &e" + player.getUniqueId(), '&'); + Utils.sendMessage(sender, "", "&6> First joined: " + firstJoin, '&'); + Utils.sendMessage(sender, "", "&6> Last seen: " + lastSeen, '&'); + Utils.sendMessage(sender, "", "&6> Website account: &e" + websiteUrl, '&'); + Utils.sendMessage(sender, "", "&6> email: &e" + email, '&'); + if (emailNotConfirmed) + Utils.sendMessage(sender, "", "&6> &4Email NOT Confirmed!", '&'); + Utils.sendMessage(sender, "", "&7Data provided by ipinfo:", '&'); + Utils.sendMessage(sender, "", "&6> Country: &e" + country, '&'); + Utils.sendMessage(sender, "", "&7Data provided by Mojang:", '&'); + Utils.sendMessage(sender, "", "&6> All ingame names used so far: &e" + namesUsed, '&'); + } + catch (Exception e) + { + e.printStackTrace(); + Utils.sendErrorMessage(sender, null, "&cSorry, something went wrong while fetching data", '&'); + } + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command check {\n" + + " perm utils.check;\n" + + " \n" + + " [string:player] {\n" + + " run checkCommand player;\n" + + " help Get info on a player;\n" + + " }\n" + + "}"; + } + // @format + + @Override + public void onDisable() + { + enabled = false; + } +} diff --git a/src/com/redstoner/modules/cycle/Cycle.java b/src/com/redstoner/modules/cycle/Cycle.java new file mode 100644 index 0000000..3295624 --- /dev/null +++ b/src/com/redstoner/modules/cycle/Cycle.java @@ -0,0 +1,167 @@ +package com.redstoner.modules.cycle; + +import java.io.File; +import java.util.UUID; + +import org.bukkit.GameMode; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class Cycle implements Module, Listener +{ + private boolean enabled = false; + private File cycleFile = new File(Main.plugin.getDataFolder(), "cycle.json"); + private JSONArray no_cyclers; + + @Override + public void onEnable() + { + no_cyclers = JsonManager.getArray(cycleFile); + if (no_cyclers == null) + no_cyclers = new JSONArray(); + enabled = true; + } + + @Override + public void onDisable() + { + saveCyclers(); + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + private void saveCyclers() + { + JsonManager.save(no_cyclers, cycleFile); + } + + @Command(hook = "cycle_on") + public boolean cycleOn(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (no_cyclers.remove(uid.toString())) + { + Utils.sendMessage(sender, null, "Cycle enabled!"); + saveCyclers(); + } + else + Utils.sendMessage(sender, null, "Cycle was already enabled!"); + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "cycle_off") + public boolean cycleOff(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (!no_cyclers.contains(uid.toString())) + { + Utils.sendMessage(sender, null, "Cycle disabled!"); + no_cyclers.add(uid.toString()); + saveCyclers(); + } + else + Utils.sendMessage(sender, null, "Cycle was already disabled!"); + return true; + } + + @EventHandler + public void onInventoryCycle(PlayerItemHeldEvent event) + { + Player player = event.getPlayer(); + UUID uid = player.getUniqueId(); + if (!player.getGameMode().equals(GameMode.CREATIVE) || player.isSneaking() + || no_cyclers.contains(uid.toString())) + return; + int prev_slot = event.getPreviousSlot(); + int new_slot = event.getNewSlot(); + if (prev_slot == 0 && new_slot == 8) + shift(player, true); + else if (prev_slot == 8 && new_slot == 0) + shift(player, false); + } + + private void shift(Player player, boolean down) + { + Inventory inv = player.getInventory(); + ItemStack[] items = inv.getStorageContents(); + int shift = down ? -9 : 9; + shift = (shift + items.length) % items.length; + for (int i = 0; i < 4; i++) + { + items = join(subset(items, shift, items.length), subset(items, 0, shift)); + ItemStack[] hotbar = subset(items, 0, 9); + boolean found = false; + for (ItemStack item : hotbar) + if (item != null) + { + found = true; + break; + } + if (found) + break; + } + inv.setStorageContents(items); + } + + private ItemStack[] subset(ItemStack[] items, int start, int end) + { + ItemStack[] result = new ItemStack[end - start]; + for (int i = start; i < end; i++) + { + result[i - start] = items[i]; + } + return result; + } + + private ItemStack[] join(ItemStack[] items1, ItemStack[] items2) + { + ItemStack[] result = new ItemStack[items1.length + items2.length]; + for (int i = 0; i < items1.length; i++) + result[i] = items1[i]; + int offset = items1.length; + for (int i = 0; i < items2.length; i++) + result[i + offset] = items2[i]; + return result; + } + + // @noformat + @Override + public String getCommandString() + { + return "command cycle {\n" + + " on {\n" + + " help Turns on cycle;\n" + + " type player;\n" + + " run cycle_on;\n" + + " }\n" + + " off {\n" + + " help Turns off cycle;\n" + + " type player;\n" + + " run cycle_off;\n" + + " }\n" + + "}"; + } + // format +} diff --git a/src/com/redstoner/modules/damnspam/DamnSpam.java b/src/com/redstoner/modules/damnspam/DamnSpam.java new file mode 100644 index 0000000..3f95443 --- /dev/null +++ b/src/com/redstoner/modules/damnspam/DamnSpam.java @@ -0,0 +1,380 @@ +package com.redstoner.modules.damnspam; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 1, revision = 1, compatible = 1) +public class DamnSpam implements Module, Listener +{ + private boolean enabled = false; + File configFile = new File(Main.plugin.getDataFolder(), "DamnSpam.json"); + Map inputs; + boolean changingInput = false; + List acceptedInputs; + HashMap attachedBlocks; + HashMap players; + int maxTimeout = 240; + String timeoutErrorString = "&cThe timeout must be -1 or within 0 and " + maxTimeout; + + @Override + public void onEnable() + { + loadInputs(); + acceptedInputs = new ArrayList(); + Collections.addAll(acceptedInputs, Material.WOOD_BUTTON, Material.STONE_BUTTON, Material.LEVER); + attachedBlocks = new HashMap(); + attachedBlocks.put(Material.LEVER, + new int[][] {{0, 7, 8, 15}, {5, 6, 13, 14}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + attachedBlocks.put(Material.STONE_BUTTON, + new int[][] {{0, 8}, {5, 6, 7, 13, 14, 15}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + attachedBlocks.put(Material.WOOD_BUTTON, + new int[][] {{0, 8}, {5, 6, 7, 13, 14, 15}, {4, 12}, {3, 11}, {2, 10}, {1, 9}}); + players = new HashMap(); + enabled = true; + } + + public void loadInputs() + { + inputs = new HashMap(); + try + { + FileReader reader = new FileReader(configFile); + JSONObject json = (JSONObject) new JSONParser().parse(reader); + for (Object key : json.keySet()) + { + JSONObject inputData = (JSONObject) json.get(key); + String uuid = (String) inputData.get("creator"); + Double timeoutOn = (Double) inputData.get("timeout_on"); + Double timeoutOff = (Double) inputData.get("timeout_off"); + Double lastTime = (Double) inputData.get("last_time"); + inputs.put((String) key, new SpamInput(uuid, timeoutOff, timeoutOn, lastTime)); + } + } + catch (IOException | ParseException e) + { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public void saveInputs() + { + JSONObject json = new JSONObject(); + for (String key : inputs.keySet()) + { + JSONObject jsonInput = new JSONObject(); + SpamInput input = inputs.get(key); + jsonInput.put("creator", input.player); + jsonInput.put("timeout_on", input.timeoutOn); + jsonInput.put("timeout_off", input.timeoutOff); + jsonInput.put("last_time", input.lastTime); + json.put(key, jsonInput); + } + try + { + PrintWriter writer = new PrintWriter(configFile); + writer.write(json.toJSONString()); + writer.close(); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + } + + public String locationString(Location loc) + { + return loc.getWorld().getName() + ";" + loc.getBlockX() + ";" + loc.getBlockY() + ";" + loc.getBlockZ(); + } + + public boolean isAcceptableTimeout(double timeout) + { + return (timeout > 0 && timeout <= maxTimeout) || timeout == -1; + } + + public boolean canBuild(Player player, Block block) + { + BlockBreakEvent event = new BlockBreakEvent(block, player); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } + + @Command(hook = "damnspamSingle") + public void damnspam(CommandSender sender, double seconds) + { + boolean destroyingInput = false; + seconds = (double) Math.round(seconds * 100) / 100; + if (seconds == 0) + destroyingInput = true; + else if (!isAcceptableTimeout(seconds)) + { + Utils.sendMessage(sender, null, "&cThe timeout must be -1 or within 0 and " + maxTimeout, '&'); + return; + } + Utils.sendMessage(sender, null, "&aPlease click the input you would like to set.", '&'); + setPlayer((Player) sender, destroyingInput, seconds, seconds); + } + + @Command(hook = "damnspamDouble") + public void damnspam(CommandSender sender, double secondsOff, double secondsOn) + { + boolean destroyingInput = false; + secondsOn = (double) Math.round(secondsOn * 100) / 100; + secondsOff = (double) Math.round(secondsOff * 100) / 100; + if (secondsOn == 0 && secondsOff == 0) + { + destroyingInput = true; + } + else if (!(isAcceptableTimeout(secondsOn) && isAcceptableTimeout(secondsOff))) + { + Utils.sendMessage(sender, null, "&cThe timeout must be -1 or within 0 and " + maxTimeout, '&'); + return; + } + Utils.sendMessage(sender, null, "&aPlease click the input you would like to set.", '&'); + setPlayer((Player) sender, destroyingInput, secondsOff, secondsOn); + } + + public void setPlayer(Player player, boolean destroying, double timeoutOff, double timeoutOn) + { + SpamInput input = null; + if (!destroying) + { + input = new SpamInput(player.getUniqueId().toString(), timeoutOff, timeoutOn, 0); + } + players.put(player, input); + } + + public boolean attemptInputRegister(Player player, Block block, Cancellable event) + { + if (players.containsKey(player)) + { + if (!acceptedInputs.contains(block.getType())) + { + Utils.sendMessage(player, null, "&cThat block is not an acceptable input!", '&'); + return true; + } + String typeStr = block.getType().toString().toLowerCase().replace("_", " "); + String locationStr = locationString(block.getLocation()); + changingInput = true; + boolean buildCheck = canBuild(player, block); + changingInput = false; + if (!buildCheck) + { + Utils.sendMessage(player, null, + "&cThere is no timeout to remove on this " + typeStr + "(by setting the timeout to 0)", '&'); + return true; + } + SpamInput input = players.get(player); + if (input == null) + { + if (!inputs.containsKey(locationStr)) + { + Utils.sendMessage(player, null, + "&cThere is no timeout to remove on this " + typeStr + "(by setting the timeout to 0)", + '&'); + return true; + } + inputs.remove(locationStr); + Utils.sendMessage(player, null, "&aSuccessfully removed the timeout for this " + typeStr, '&'); + } + else + { + inputs.put(locationStr, players.get(player)); + Utils.sendMessage(player, null, "&aSuccessfully set a timeout for this " + typeStr, '&'); + } + event.setCancelled(true); + players.remove(player); + saveInputs(); + return true; + } + return false; + } + + public void checkBlockBreak(BlockBreakEvent event, Block block) + { + if (!acceptedInputs.contains(block.getType())) + return; + String posStr = locationString(block.getLocation()); + if (!inputs.containsKey(posStr)) + return; + SpamInput input = inputs.get(posStr); + Player sender = event.getPlayer(); + String typeStr = block.getType().toString().toLowerCase().replace("_", " "); + String inputStr = (block.getLocation().equals(event.getBlock()) ? "this " + typeStr + : "the " + typeStr + " attached to that block"); + if (!sender.isSneaking()) + { + Utils.sendMessage(sender, null, "&cYou cannot destroy " + inputStr, '&'); + Utils.sendMessage(sender, "", "&c&nSneak&c and break or set the timeout to 0 if you want to remove it.", + '&'); + event.setCancelled(true); + return; + } + if (sender.hasPermission("damnspam.admin") || sender.getUniqueId().toString().equals(input.player)) + { + inputs.remove(posStr); + saveInputs(); + Utils.sendMessage(sender, null, "&aSuccesfully removed " + inputStr, '&'); + } + else + { + Utils.sendMessage(sender, null, "&cYou are not allowed to remove " + inputStr, '&'); + event.setCancelled(true); + } + } + + @SuppressWarnings("deprecation") + public List getAttachedBlocks(Block block) + { + List blocks = new ArrayList(); + BlockFace[] directions = {BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, + BlockFace.EAST}; + for (int i = 0; i < directions.length; i++) + { + Block side = block.getRelative(directions[i]); + int[][] dvalues = attachedBlocks.get(side.getType()); + if (dvalues != null) + { + boolean onSide = false; + for (int val : dvalues[i]) + { + if (side.getData() == (byte) val) + { + onSide = true; + break; + } + } + if (onSide) + blocks.add(side); + } + } + return blocks; + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onBreak(BlockBreakEvent event) + { + if (changingInput || event.isCancelled()) + return; + boolean register = attemptInputRegister(event.getPlayer(), event.getBlock(), event); + if (!register) + { + Block block = event.getBlock(); + checkBlockBreak(event, block); + for (Block affected : getAttachedBlocks(block)) + { + checkBlockBreak(event, affected); + } + } + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.HIGHEST) + public void onInteract(PlayerInteractEvent event) + { + boolean register = attemptInputRegister(event.getPlayer(), event.getClickedBlock(), event); + if (!register && event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && !event.isCancelled()) + { + Player sender = event.getPlayer(); + Block block = event.getClickedBlock(); + String posStr = locationString(block.getLocation()); + SpamInput data = inputs.get(posStr); + if (data != null) + { + String btype = block.getType().toString().toLowerCase().replace("_", " "); + double checktime = 0; + if (btype.equals("lever") && block.getData() < 8) + checktime = data.timeoutOff; + else + checktime = data.timeoutOn; + double timeLeft = (data.lastTime + checktime) + - ((double) Math.round((double) System.currentTimeMillis() / 10) / 100); + timeLeft = (double) Math.round(timeLeft * 100) / 100; + if (checktime == -1) + { + event.setCancelled(true); + Utils.sendMessage(sender, null, "&cThis " + btype + " is locked permanently by /damnspam.", '&'); + } + else if (timeLeft > 0) + { + event.setCancelled(true); + Utils.sendMessage(sender, null, "&cThis " + btype + " has a damnspam timeout of " + checktime + + ", with " + timeLeft + " left.", '&'); + } + else + { + data.lastTime = (double) Math.round((double) System.currentTimeMillis() / 10) / 100; + } + inputs.put(posStr, data); + } + } + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Override + public void onDisable() + { + enabled = false; + } + + // @noformat + @Override + public String getCommandString() + { + return "command damnspam {\n" + + " perm utils.damnspam;\n" + + " \n" + + " [double:seconds] {\n" + + " run damnspamSingle seconds;\n" + + " help Set single input cooldown for button or lever.;\n" + + " type player;\n" + + " }\n" + + " \n" + + " [double:secondsOff] [double:secondsOn] {\n" + + " run damnspamDouble secondsOff secondsOn;\n" + + " help Set input cooldown after it's been turned off and turned on (for lever only).;\n" + + " type player;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/damnspam/SpamInput.java b/src/com/redstoner/modules/damnspam/SpamInput.java new file mode 100644 index 0000000..9735dd9 --- /dev/null +++ b/src/com/redstoner/modules/damnspam/SpamInput.java @@ -0,0 +1,17 @@ +package com.redstoner.modules.damnspam; + +public class SpamInput { + + protected String player; + protected double timeoutOn; + protected double timeoutOff; + protected double lastTime; + + protected SpamInput(String player, double timeoutOff, double timeoutOn, double lastTime) { + this.player = player; + this.timeoutOff = timeoutOff; + this.timeoutOn = timeoutOn; + this.lastTime = lastTime; + } + +} diff --git a/src/com/redstoner/modules/illumination/Illumination.java b/src/com/redstoner/modules/illumination/Illumination.java new file mode 100644 index 0000000..5404a30 --- /dev/null +++ b/src/com/redstoner/modules/illumination/Illumination.java @@ -0,0 +1,62 @@ +package com.redstoner.modules.illumination; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class Illumination implements Module{ + + boolean enabled = false; + PotionEffect effect = new PotionEffect(PotionEffectType.NIGHT_VISION, Integer.MAX_VALUE, 0, false, false); + + @Command(hook = "illuminate") + public void illuminate(CommandSender sender) { + Player player = (Player) sender; + if(player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) { + player.removePotionEffect(PotionEffectType.NIGHT_VISION); + Utils.sendMessage(sender, null, "Night Vision Disabled."); + } + else { + player.addPotionEffect(effect, true); + Utils.sendMessage(sender, null, "Night Vision Enabled."); + } + } + + @Override + public void onEnable() { + enabled = true; + + } + + @Override + public void onDisable() { + enabled = false; + + } + + @Override + public boolean enabled() { + return enabled; + } + + @Override + public String getCommandString() { + return "command nightvision {\n" + + " [empty] {\n" + + " run illuminate;\n" + + " type player;\n" + + " help Gives the player infinte night vision;\n" + + " perm utils.illuminate;\n" + + " }\n" + + "}\n" + + "\n" + + "}"; + } +} diff --git a/src/com/redstoner/modules/imout/Imout.java b/src/com/redstoner/modules/imout/Imout.java new file mode 100644 index 0000000..b083fd1 --- /dev/null +++ b/src/com/redstoner/modules/imout/Imout.java @@ -0,0 +1,76 @@ +package com.redstoner.modules.imout; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +public class Imout implements Module +{ + private boolean enabled = false; + List imout_toggle_list = new ArrayList(); + + @Command(hook = "imout") + public void onImoutCommand(CommandSender sender) + { + String symbol; + Player s = (Player) sender; + String name = sender.getName(); + if (imout_toggle_list.contains(name)) + { + symbol = "§a§l+"; + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "§eWelcome back! You are no longer hidden"); + s.performCommand("vanish off"); + s.performCommand("act off"); + imout_toggle_list.remove(name); + } + else + { + symbol = "§c§l-"; + sender.sendMessage("§eYou just left... Or didn't you?"); + s.performCommand("vanish on"); + s.performCommand("act on"); + imout_toggle_list.add(name); + } + Utils.broadcast(symbol, " §7" + name, null); + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + // @noformat + @Override + public String getCommandString() + { + return "command imout {\n" + + " [empty] {\n" + + " help Makes you magically disappear;\n" + + " type player;\n" + + " perm utils.imout;\n" + + " run imout;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/lagchunks/LagChunks.java b/src/com/redstoner/modules/lagchunks/LagChunks.java new file mode 100644 index 0000000..52d772b --- /dev/null +++ b/src/com/redstoner/modules/lagchunks/LagChunks.java @@ -0,0 +1,125 @@ +package com.redstoner.modules.lagchunks; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class LagChunks implements Module +{ + private boolean enabled = false; + private List laggyChunks = new ArrayList(); + + private void scan(int amount) + { + laggyChunks.clear(); + for (World world : Bukkit.getServer().getWorlds()) + { + for (Chunk chunk : world.getLoadedChunks()) + { + if (chunk.getEntities().length > amount) + { + Location entLoc = chunk.getEntities()[0].getLocation(); + laggyChunks.add(new LaggyChunk(entLoc.getBlockX(), entLoc.getBlockY(), entLoc.getBlockZ(), world, + chunk.getEntities().length)); + } + } + } + } + + @Command(hook = "list_cmd") + public void list(CommandSender sender) + { + if (laggyChunks.size() > 0) + { + Utils.sendModuleHeader(sender); + for (LaggyChunk lc : laggyChunks) + { + Utils.sendMessage(sender, "", "§b[§a" + laggyChunks.indexOf(lc) + "§b]: §a" + lc.x + "§7, §a" + lc.y + + "§7, §a" + lc.z + " §7(" + lc.world.getName() + ") §a- §b" + lc.amount + " entities"); + } + Utils.sendMessage(sender, "", "§2-------------------"); + } + else + Utils.sendMessage(sender, null, "Couldn't find any chunks with that many entities."); + } + + @Command(hook = "scan_cmd", async = AsyncType.ALWAYS) + public void scan_cmd(CommandSender sender, int amount) + { + scan(amount); + list(sender); + } + + @Command(hook = "tp") + public void tp(CommandSender sender, int number) + { + Player player = (Player) sender; + if (number < laggyChunks.size()) + { + player.teleport(laggyChunks.get(number).getLocation()); + Utils.sendMessage(player, null, "§aTeleported to chunk " + number + "!"); + } + else + { + Utils.sendErrorMessage(sender, null, "§4Invalid chunk number! Use §e/lc list §4to show laggy chunks!"); + } + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + // @noformat + @Override + public String getCommandString() + { + return "command lc {\n" + + " perm utils.lagchunks;\n" + + " \n" + + " list {\n" + + " run list_cmd;\n" + + " help re-lists already scanned chunks;\n" + + " }\n" + + " \n" + + " [int:amount] {\n" + + " run scan_cmd amount;\n" + + " help scans for laggy chunks;\n" + + " }\n" + + " \n" + + " tp [int:number] {\n" + + " run tp number;\n" + + " help teleports to the specified chunk;\n" + + " type player;\n" + + " }\n" + + "}\n" + + " "; + } + // @format +} diff --git a/src/com/redstoner/modules/lagchunks/LaggyChunk.java b/src/com/redstoner/modules/lagchunks/LaggyChunk.java new file mode 100644 index 0000000..3ff4d6f --- /dev/null +++ b/src/com/redstoner/modules/lagchunks/LaggyChunk.java @@ -0,0 +1,21 @@ +package com.redstoner.modules.lagchunks; + +import org.bukkit.Location; +import org.bukkit.World; + +public class LaggyChunk { + public final int x, y, z, amount; + public final World world; + + public LaggyChunk(int x, int y, int z, World world, int amount) { + this.x = x; + this.y = y; + this.z = z; + this.world = world; + this.amount = amount; + } + + public Location getLocation() { + return new Location(world, x, y, z); + } +} diff --git a/src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java b/src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java new file mode 100644 index 0000000..e39d781 --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/CancelledEventsHandler.java @@ -0,0 +1,95 @@ +package com.redstoner.modules.loginsecurity; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupArrowEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +public class CancelledEventsHandler implements Listener { + private LoginSecurity mainClass; + + public CancelledEventsHandler(LoginSecurity mainClass) { + this.mainClass = mainClass; + } + + @EventHandler + public void onMove(PlayerMoveEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.getPlayer().teleport(LoginSecurity.loggingIn.get(e.getPlayer().getUniqueId())); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onChat(AsyncPlayerChatEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.getPlayer().sendMessage(ChatColor.RED + "You must login before you can chat!"); + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onCommand(PlayerCommandPreprocessEvent e) { + String command = e.getMessage(); + + if (!command.startsWith("/login") && isLoggingIn(e.getPlayer())) { + e.getPlayer().sendMessage(ChatColor.RED + "You must login before you can execute commands!"); + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemHold(PlayerItemHeldEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemPickup(PlayerPickupItemEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onItemDrop(PlayerDropItemEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onInteract(PlayerInteractEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onArrowPickup(PlayerPickupArrowEvent e) { + if (isLoggingIn(e.getPlayer())) { + e.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onInvClick(InventoryClickEvent e) { + if (e.getWhoClicked() instanceof Player && isLoggingIn((Player) e.getWhoClicked())) { + e.setCancelled(true); + } + } + + private boolean isLoggingIn(Player player) { + return mainClass.isLoggingIn(player); + } +} diff --git a/src/com/redstoner/modules/loginsecurity/CryptographyHandler.java b/src/com/redstoner/modules/loginsecurity/CryptographyHandler.java new file mode 100644 index 0000000..48e81a9 --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/CryptographyHandler.java @@ -0,0 +1,53 @@ +package com.redstoner.modules.loginsecurity; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Base64; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +public class CryptographyHandler { + public static String hash(String password, String salt) { + String algorithm = "PBKDF2WithHmacSHA256"; + int derivedKeyLength = 256; + int iterations = 200000; + byte[] decodedSalt = Base64.getDecoder().decode(salt.getBytes()); + + KeySpec spec = new PBEKeySpec(password.toCharArray(), decodedSalt, iterations, derivedKeyLength); + + byte[] hashed = null; + + try { + SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm); + + hashed = f.generateSecret(spec).getEncoded(); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + return Base64.getEncoder().encodeToString(hashed).substring(0, 43); + } + + public static boolean verify(String password, String salt, String hash) { + return hash(password, salt).equals(hash); + } + + public static boolean verify(String password, String stored) { + String[] split = stored.split("\\$"); + + return verify(password, split[3], split[4]); + } + + public static String generateSalt() throws NoSuchAlgorithmException, NoSuchProviderException { + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + + byte[] salt = new byte[16]; + random.nextBytes(salt); + + return Base64.getEncoder().encodeToString(salt).substring(0, 22); + } +} diff --git a/src/com/redstoner/modules/loginsecurity/LoginSecurity.java b/src/com/redstoner/modules/loginsecurity/LoginSecurity.java new file mode 100644 index 0000000..56f1ea7 --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/LoginSecurity.java @@ -0,0 +1,333 @@ +package com.redstoner.modules.loginsecurity; + +import java.io.Serializable; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitScheduler; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.misc.mysql.JSONManager; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.misc.mysql.elements.ConstraintOperator; +import com.redstoner.misc.mysql.elements.MysqlConstraint; +import com.redstoner.misc.mysql.elements.MysqlDatabase; +import com.redstoner.misc.mysql.elements.MysqlField; +import com.redstoner.misc.mysql.elements.MysqlTable; +import com.redstoner.misc.mysql.types.text.VarChar; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 3, compatible = 1) +public class LoginSecurity implements Module, Listener +{ + private boolean enabled = false; + protected static Map loggingIn; + private MysqlTable table; + + @Override + public void onEnable() + { + Map config = JSONManager.getConfiguration("loginsecurity.json"); + if (config == null || !config.containsKey("database") || !config.containsKey("table")) + { + Utils.sendErrorMessage(Bukkit.getConsoleSender(), null, + "Could not load the LoginSecurity config file, disabling!"); + enabled = false; + return; + } + try + { + MysqlDatabase database = MysqlHandler.INSTANCE.getDatabase((String) config.get("database")); + MysqlField uuid = new MysqlField("uuid", new VarChar(36), true); + MysqlField pass = new MysqlField("pass", new VarChar(88), true); + database.createTableIfNotExists((String) config.get("table"), uuid, pass); + table = database.getTable((String) config.get("table")); + } + catch (NullPointerException e) + { + Utils.sendErrorMessage(Bukkit.getConsoleSender(), null, + "Could not use the LoginSecurity config, disabling!"); + enabled = false; + return; + } + loggingIn = new HashMap<>(); + Bukkit.getServer().getPluginManager().registerEvents(new CancelledEventsHandler(this), Main.plugin); + enabled = true; + } + + public static Map getLoggingIn() + { + return loggingIn; + } + + @Command(hook = "register") + public void register(CommandSender sender, String password) + { + Player player = (Player) sender; + if (isRegistered(player)) + { + player.sendMessage(ChatColor.GREEN + "You are already registered!"); + return; + } + try + { + if (registerPlayer(player, password)) + { + player.sendMessage(ChatColor.GREEN + "Succesfully registered!"); + return; + } + } + catch (NoSuchAlgorithmException | NoSuchProviderException e) + { + e.printStackTrace(); + } + player.sendMessage(ChatColor.RED + "Failed to register, please contact an admin!"); + } + + @Command(hook = "login") + public void login(CommandSender sender, String password) + { + Player player = (Player) sender; + if (!isRegistered(player)) + { + player.sendMessage(ChatColor.RED + "You are not registered!"); + return; + } + if (CryptographyHandler.verify(password, getHash(player))) + { + loggingIn.remove(player.getUniqueId()); + } + else + { + player.sendMessage(ChatColor.RED + "Wrong password!"); + } + } + + @Command(hook = "cgpass") + public void cgpass(CommandSender sender, String oldPassword, String newPassword) + { + Player player = (Player) sender; + if (!isRegistered(player)) + { + player.sendMessage(ChatColor.RED + "You are not registered!"); + return; + } + if (!CryptographyHandler.verify(oldPassword, getHash(player))) + { + player.sendMessage(ChatColor.RED + "The old password you entered is wrong!"); + return; + } + if (oldPassword.equals(newPassword)) + { + player.sendMessage(ChatColor.RED + "You entered the same password!"); + return; + } + if (table.delete(getUuidConstraint(player))) + { + try + { + registerPlayer(player, newPassword); + player.sendMessage(ChatColor.GREEN + "Succesfully changed password!"); + } + catch (NoSuchAlgorithmException | NoSuchProviderException e) + { + e.printStackTrace(); + player.sendMessage(ChatColor.RED + "Failed to set new password!"); + } + } + else + { + player.sendMessage(ChatColor.RED + "Failed to remove old password from database!"); + } + } + + @Command(hook = "rmpass") + public void rmpass(CommandSender sender, String oldPassword) + { + Player player = (Player) sender; + if (!isRegistered(player)) + { + player.sendMessage(ChatColor.RED + "You are not registered!"); + return; + } + if (!CryptographyHandler.verify(oldPassword, getHash(player))) + { + player.sendMessage(ChatColor.RED + "The old password you entered is wrong!"); + return; + } + if (table.delete(getUuidConstraint(player))) + { + player.sendMessage(ChatColor.GREEN + "Succesfully removed password!"); + } + else + { + player.sendMessage(ChatColor.RED + "Failed to remove old password from database!"); + } + } + + @Command(hook = "rmotherpass") + public void rmotherpass(CommandSender sender, String playerName) + { + if (playerName.equals("")) + { + sender.sendMessage(ChatColor.RED + "That's not a valid player!"); + return; + } + @SuppressWarnings("deprecation") + OfflinePlayer player = Bukkit.getOfflinePlayer(playerName); + if (!isRegistered(player)) + { + sender.sendMessage(ChatColor.RED + "That player is not registered!"); + return; + } + if (table.delete(getUuidConstraint(player))) + { + sender.sendMessage(ChatColor.GREEN + "Successfully removed " + playerName + "'s password!"); + } + else + { + sender.sendMessage(ChatColor.RED + "Failed to remove " + playerName + "'s password!"); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) + { + Player player = e.getPlayer(); + if (!isRegistered(player)) + { + return; + } + Utils.sendMessage(player, null, "You'll have to log in within 60s or you'll be kicked!"); + loggingIn.put(player.getUniqueId(), player.getLocation()); + BukkitScheduler scheduler = Bukkit.getScheduler(); + RepeatingLoginRunnable repeatingRunnable = new RepeatingLoginRunnable(this, player); + repeatingRunnable.setId(scheduler.scheduleSyncRepeatingTask(Main.plugin, repeatingRunnable, 0L, 2L)); + scheduler.scheduleSyncDelayedTask(Main.plugin, new Runnable() + { + @Override + public void run() + { + if (isLoggingIn(player)) + { + scheduler.cancelTask(repeatingRunnable.getId()); + player.kickPlayer("You didn't login in time!"); + } + } + }, 1200L); + } + + public boolean isLoggingIn(Player player) + { + return loggingIn.containsKey(player.getUniqueId()); + } + + public MysqlConstraint getUuidConstraint(OfflinePlayer player) + { + return new MysqlConstraint("uuid", ConstraintOperator.EQUAL, player.getUniqueId().toString()); + } + + public boolean isRegistered(OfflinePlayer player) + { + return table.get("uuid", getUuidConstraint(player)).length > 0; + } + + public String getHash(OfflinePlayer player) + { + return (String) table.get("pass", getUuidConstraint(player))[0]; + } + + public boolean registerPlayer(Player player, String password) + throws NoSuchAlgorithmException, NoSuchProviderException + { + String salt = CryptographyHandler.generateSalt(); + String hash = CryptographyHandler.hash(password, salt); + String toInsert = "$pbkdf2-sha256$200000$" + salt + "$" + hash; + return table.insert(player.getUniqueId().toString(), toInsert); + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Override + public void onDisable() + { + enabled = false; + } + + // @noformat + @Override + public String getCommandString() + { + return "command register {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:password] {\n" + + " run register password;\n" + + " help Protects your account with a password;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command login {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:password] {\n" + + " run login password;\n" + + " help Logs you in;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command cgpass {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:oldPassword] [string:newPassword] {\n" + + " run cgpass oldPassword newPassword;\n" + + " help Changes your password to the specified one;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command rmpass {\n" + + " perm utils.loginsecurity;\n" + + " \n" + + " [string:oldPassword] {\n" + + " run rmpass oldPassword;\n" + + " help Removes the password of your account;\n" + + " type player;\n" + + " }\n" + + "}\n" + + "\n" + + "command rmotherpass {\n" + + " perm utils.loginsecurity.admin;\n" + + " \n" + + " [string:playerName] {\n" + + " run rmotherpass playerName;\n" + + " help removes the password of another player;\n" + + " perm utils.loginsecurity.admin;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java b/src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java new file mode 100644 index 0000000..4e8db6d --- /dev/null +++ b/src/com/redstoner/modules/loginsecurity/RepeatingLoginRunnable.java @@ -0,0 +1,37 @@ +package com.redstoner.modules.loginsecurity; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class RepeatingLoginRunnable implements Runnable { + private int id = -1; + private Player player; + private LoginSecurity mainClass; + + public RepeatingLoginRunnable(LoginSecurity mainClass, Player player) { + this.player = player; + this.mainClass = mainClass; + } + + @Override + public void run() { + if (!player.isOnline()) { + LoginSecurity.loggingIn.remove(player.getUniqueId()); + Bukkit.getScheduler().cancelTask(id); + } + + if (!mainClass.isLoggingIn(player)) { + player.sendMessage(ChatColor.GREEN + "Successfully logged in!"); + Bukkit.getScheduler().cancelTask(id); + } + } + + public void setId(int id) { + this.id = id; + } + + public int getId() { + return id; + } +} diff --git a/src/com/redstoner/modules/mentio/Mentio.java b/src/com/redstoner/modules/mentio/Mentio.java new file mode 100644 index 0000000..a063a6c --- /dev/null +++ b/src/com/redstoner/modules/mentio/Mentio.java @@ -0,0 +1,203 @@ +package com.redstoner.modules.mentio; + +import java.io.File; +import java.util.UUID; +import java.util.regex.Pattern; + +import org.bukkit.Sound; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 4, compatible = 1) +public class Mentio implements Module, Listener +{ + private boolean enabled = false; + private File mentioLocation = new File(Main.plugin.getDataFolder(), "mentio.json"); + private JSONObject mentios; + + @Override + public void onEnable() + { + loadMentios(); + enabled = true; + } + + @Override + public void onDisable() + { + saveMentios(); + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @SuppressWarnings("unchecked") + @Command(hook = "addmentio") + public boolean addMentio(CommandSender sender, String trigger) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-o]", "")); + } + if (playerMentios.contains(trigger)) + Utils.sendErrorMessage(sender, null, "You already had that as a mentio!"); + else + { + playerMentios.add(trigger); + Utils.sendMessage(sender, null, "Successfully added the trigger §e" + trigger + " §7for you!"); + mentios.put(uuid.toString(), playerMentios); + saveMentios(); + } + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "delmentio") + public boolean delMentio(CommandSender sender, String trigger) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-o]", "")); + } + if (!playerMentios.remove(trigger)) + Utils.sendErrorMessage(sender, null, "You didn't have that as a mentio!"); + else + { + Utils.sendMessage(sender, null, "Successfully removed the trigger §e" + trigger + " §7for you!"); + mentios.put(uuid.toString(), playerMentios); + saveMentios(); + } + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "listmentios") + public boolean listMentios(CommandSender sender) + { + Utils.sendModuleHeader(sender); + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-or]", "")); + } + for (Object raw : playerMentios) + { + String mentio = (String) raw; + Utils.sendMessage(sender, "&2 -> &e", mentio, '&'); + } + return true; + } + + @SuppressWarnings("unchecked") + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerChat(AsyncPlayerChatEvent event) + { + if (event.isCancelled()) + return; + for (Player player : event.getRecipients()) + { + UUID uuid = player.getUniqueId(); + JSONArray playerMentios = (JSONArray) mentios.get(uuid.toString()); + if (playerMentios == null) + { + playerMentios = new JSONArray(); + playerMentios.add(player.getName()); + playerMentios.add(player.getDisplayName().split(" ")[0].replaceAll("§[0-9a-fk-o]", "")); + } + for (Object raw : playerMentios) + { + String mentio = (String) raw; + if (event.getMessage().toLowerCase().contains(mentio.toLowerCase())) + { + event.getRecipients().remove(player); + String temp = event.getMessage().replaceAll("(?i)" + Pattern.quote(mentio), "§§"); + String lastColorCodes = "§r"; + char lastChar = ' '; + for (char c : temp.toCharArray()) + { + if (lastChar == '§' && c == '§') + break; + if (lastChar == '§') + lastColorCodes += "§" + c; + lastChar = c; + } + // Using §§ as a placeholder as it can't occur in minecraft chat message naturally. If another plugin is stupid enough to leave that in, fuck that plugin. + Utils.sendMessage(player, "", + event.getFormat().replace("%1$s", event.getPlayer().getDisplayName()).replace("%2$s", + temp.replaceFirst("§§([^ ]*) ", "§a§o" + mentio + "$1 " + lastColorCodes) + .replace("§§", mentio))); + player.playSound(player.getLocation(), Sound.ENTITY_CHICKEN_EGG, 1, 1); + return; + } + } + } + } + + private void loadMentios() + { + mentios = JsonManager.getObject(mentioLocation); + if (mentios == null) + mentios = new JSONObject(); + } + + private void saveMentios() + { + JsonManager.save(mentios, mentioLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command mentio {\n" + + " add [string:trigger] {\n" + + " help Triggers you when the trigger gets said.;\n" + + " run addmentio trigger;\n" + + " }\n" + + " delete [string:trigger] {\n" + + " help Deletes a mentio.;\n" + + " run delmentio trigger;\n" + + " }\n" + + " list {\n" + + " help Lists your mentios.;\n" + + " run listmentios;\n" + + " }\n" + + " perm utils.mentio;\n" + + " type player;\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/misc/Misc.java b/src/com/redstoner/modules/misc/Misc.java new file mode 100644 index 0000000..773ff7f --- /dev/null +++ b/src/com/redstoner/modules/misc/Misc.java @@ -0,0 +1,220 @@ +package com.redstoner.modules.misc; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 4, compatible = 1) +public class Misc implements Module, Listener +{ + private boolean enabled = false; + private final String[] sudoBlacklist = new String[] {".*:?esudo", ".*:?sudo", ".*:?script.*", ".*:?stop"}; + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @EventHandler + public void onFirstJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + if (!player.hasPlayedBefore()) + { + Utils.broadcast("", "\n&a&lPlease welcome &f" + player.getDisplayName() + " &a<o Redstoner!\n", null, + '&'); + Utils.sendMessage(player, "", " \n \n \n \n \n \n \n \n \n \n \n \n ", '&'); + Utils.sendMessage(player, "", " &4Welcome to the Redstoner Server!", '&'); + Utils.sendMessage(player, "", " &6Before you ask us things, take a quick", '&'); + Utils.sendMessage(player, "", " &6look at &a&nredstoner.com/info", '&'); + Utils.sendMessage(player, "", " \n&6thank you and happy playing ;)", '&'); + Utils.sendMessage(player, "", " \n \n", '&'); + } + Material spawnBlock = player.getLocation().getBlock().getType(); + if (spawnBlock == Material.PORTAL || spawnBlock == Material.ENDER_PORTAL) + { + Utils.sendMessage(player, "", "&4Looks like you spawned in a portal... Let me help you out", '&'); + Utils.sendMessage(player, "", "&6You can use /back if you &nreally&6 want to go back", '&'); + player.teleport(player.getWorld().getSpawnLocation()); + } + } + // Fixes /up 0 grief + // @EventHandler + // public void onPlayerCommand(PlayerCommandPreprocessEvent event) + // { + // String args[] = event.getMessage().split(" "); + // if (args[0].equals("/up") || args[0].equals("/worldedit:up")) + // event.setMessage("/" + event.getMessage()); + // } + + // Disables spectator teleportation + @EventHandler + public void onSpectatorTeleort(PlayerTeleportEvent event) + { + Player player = event.getPlayer(); + if (!event.isCancelled() && event.getCause() == TeleportCause.SPECTATE + && !player.hasPermission("utils.tp.spectate")) + { + event.setCancelled(true); + Utils.sendErrorMessage(event.getPlayer(), null, "Spectator teleportation is disabled!"); + } + } + + // Disables water and lava breaking stuff + @EventHandler + public void onLiquidFlow(BlockFromToEvent event) + { + if (event.getToBlock().getType() != Material.AIR) + event.setCancelled(true); + } + + @Command(hook = "tempadddef") + public boolean tempAddDef(CommandSender sender, String user, String group) + { + return tempAdd(sender, user, group, "604800"); + } + + @Command(hook = "tempadd") + public boolean tempAdd(CommandSender sender, String user, String group, String duration) + { + // Use it to make a proper duration output later. Too lazy rn. + @SuppressWarnings("unused") + int i = 0; + try + { + i = Integer.valueOf(duration); + } + catch (NumberFormatException e) + { + Utils.sendErrorMessage(sender, null, "That is not a valid number!"); + return true; + } + Bukkit.dispatchCommand(sender, "pex user " + user + " group add " + group + " * " + duration); + Utils.sendMessage(sender, null, "Added to group " + group + "for " + duration + " seconds."); + return true; + } + + @Command(hook = "echo") + public boolean echo(CommandSender sender, String text) + { + Utils.sendMessage(sender, "", "&f" + text, '&'); + return true; + } + + @Command(hook = "me") + public boolean me(CommandSender sender, String text) + { + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = "§9" + sender.getName(); + if (sender.hasPermission("essentials.chat.color")) + Utils.broadcast(" §7- " + name + " §7⇦ ", text, null, '&'); + else + Utils.broadcast(" §7- " + name + " §7⇦ ", text, null); + return true; + } + + @Command(hook = "sudo") + public boolean sudo(CommandSender sender, String name, String command) + { + CommandSender target; + if (name.equalsIgnoreCase("console")) + { + target = Bukkit.getConsoleSender(); + } + else + target = Bukkit.getPlayer(name); + if (target == null) + { + Utils.sendErrorMessage(sender, null, "That player couldn't be found!"); + return true; + } + if (command.startsWith("/") || target.equals(Bukkit.getConsoleSender())) + { + String[] args = command.split(" "); + for (String regex : sudoBlacklist) + { + if (args[0].matches(regex)) + { + Utils.sendErrorMessage(sender, null, "You can't sudo anyone into using that command!"); + return true; + } + } + Bukkit.dispatchCommand(target, command.replaceFirst("/", "")); + Utils.sendMessage(sender, null, "Sudoed " + name + " into running " + command); + } + else + { + ((Player) target).chat(command); + Utils.sendMessage(sender, null, "Sudoed " + name + " into saying " + command); + } + return true; + } + + // @noformat + @Override + public String getCommandString() + { + return "command tempadd {\n" + + " perm pex;\n" + + " [string:user] [string:group] {\n" + + " help Adds a user to a group for 1w.;\n" + + " run tempadddef user group;\n" + + " }\n" + + " [string:user] [string:group] [string:duration] {\n" + + " help Adds a user to a group for a specified duration.;\n" + + " run tempadd user group duration;\n" + + " }\n" + + "}\n" + + "command echo {\n" + + " [string:text...] {\n" + + " help Echoes back to you.;\n" + + " run echo text;\n" + + " }\n" + + "}\n" + + "command me {\n" + + " perm utils.me;\n" + + " [string:text...] {\n" + + " help /me's in chat.;\n" + + " run me text;\n" + + " }\n" + + "}\n" + + "command sudo {\n" + + " perm utils.sudo;\n" + + " [string:name] [string:command...] {\n" + + " help Sudo'es another user (or console);\n" + + " run sudo name command;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/motd/Motd.java b/src/com/redstoner/modules/motd/Motd.java new file mode 100644 index 0000000..cea9a9b --- /dev/null +++ b/src/com/redstoner/modules/motd/Motd.java @@ -0,0 +1,84 @@ +package com.redstoner.modules.motd; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; +import org.bukkit.event.server.ServerListPingEvent; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public class Motd implements Module +{ + private boolean enabled = false; + private String default_motd, motd; + + @Command(hook = "setmotd") + public boolean setMotd(CommandSender sender, String motd) + { + if (motd.equals("--reset")) + this.motd = default_motd; + else + this.motd = motd; + Utils.sendMessage(sender, null, "The new motd is:\n" + this.motd, '&'); + return true; + } + + @Command(hook = "getmotd") + public boolean getMotd(CommandSender sender) + { + Utils.sendMessage(sender, null, motd, '&'); + return true; + } + + @EventHandler + public void onServerPing(ServerListPingEvent event) + { + event.setMotd(motd); + } + + @Override + public void onEnable() + { + default_motd = Bukkit.getMotd(); + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command setmotd {\n" + + " [string:motd...] {\n" + + " help Sets the motd. Use --reset to reset to default;\n" + + " run setmotd motd;\n" + + " perm utils.setmotd;" + + " }\n" + + "}\n" + + "command getmotd {\n" + + " [empty] {\n" + + " help Returns the motd;\n" + + " run getmotd;\n" + + " perm utils.getmotd;" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/nametags/Nametags.java b/src/com/redstoner/modules/nametags/Nametags.java new file mode 100644 index 0000000..2ec8ee0 --- /dev/null +++ b/src/com/redstoner/modules/nametags/Nametags.java @@ -0,0 +1,142 @@ +package com.redstoner.modules.nametags; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.server.ServerCommandEvent; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public class Nametags implements Module, Listener +{ + private boolean enabled = false; + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + sortSpecific(event.getPlayer()); + } + + @EventHandler + public void commandPreprocessEvent(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().contains("promote") || event.getMessage().contains("demote") + || event.getMessage().matches("pex user .* group (set|add|leave)")) + { + String[] args = event.getMessage().split(" "); + for (String s : args) + { + Player p = Bukkit.getPlayer(s); + if (p != null) + sortSpecific(p); + } + } + } + + @EventHandler + public void consoleCommand(ServerCommandEvent event) + { + if (event.getCommand().contains("promote") || event.getCommand().contains("demote") + || event.getCommand().matches("pex user .* group (set|add|leave)")) + { + String[] args = event.getCommand().split(" "); + for (String s : args) + { + Player p = Bukkit.getPlayer(s); + if (p != null) + sortSpecific(p); + } + } + } + + @Command(hook = "sort") + public boolean sortAll(CommandSender sender) + { + for (Player p : Bukkit.getOnlinePlayers()) + sortSpecific(p); + Utils.sendMessage(sender, null, "Sorted tab for ya!"); + return true; + } + + @Command(hook = "sortspecific") + public boolean sortSpecific(CommandSender sender, String player) + { + Player p = Bukkit.getPlayer(player); + if (p == null) + { + Utils.sendErrorMessage(sender, null, "That player couldn't be found!"); + return true; + } + else + sortSpecific(p); + Utils.sendMessage(sender, null, "Sorted §e" + player + " §7for ya!"); + return true; + } + + public void sortSpecific(Player player) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), + "scoreboard teams join " + getTeam(player) + " " + player.getName()); + } + + private String getTeam(Player player) + { + String[] teams = new String[] {"admin", "mod", "trainingmod", "trusted", "builder", "member", "visitor"}; + char prefix = 'a'; + for (String team : teams) + { + if (player.hasPermission("group." + team)) + { + return prefix + "_" + team; + } + prefix++; + } + return "g_visitor"; + } + + // @noformat + @Override + public String getCommandString() + { + return "command tab {\n" + + " sort {\n" + + " help Resorts the entirety of tab.;\n" + + " run sort;\n" + + " }\n" + + " sort [string:player] {\n" + + " help Resorts one player.;\n" + + " run sortspecific player;\n" + + " }\n" + + " perm utils.tab.admin;\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/pmtoggle/Pmtoggle.java b/src/com/redstoner/modules/pmtoggle/Pmtoggle.java new file mode 100644 index 0000000..27b8835 --- /dev/null +++ b/src/com/redstoner/modules/pmtoggle/Pmtoggle.java @@ -0,0 +1,119 @@ +package com.redstoner.modules.pmtoggle; + +import java.util.HashMap; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public class Pmtoggle implements Module, Listener +{ + private boolean enabled; + HashMap toggles = new HashMap(); + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Command(hook = "pmtoggle_off", async = AsyncType.ALWAYS) + public boolean pmtoggle_off(CommandSender sender) + { + Player player = (Player) sender; + if (toggles.remove(player) != null) + Utils.sendMessage(player, null, "Your pmtoggle was removed!"); + else + Utils.sendMessage(player, null, "You didn't have pmtoggle enabled! Use /pmtoggle to enabled it."); + return true; + } + + @Command(hook = "pmtoggle", async = AsyncType.ALWAYS) + public boolean pmtoggle(CommandSender sender, String player) + { + Player p = Bukkit.getPlayer(player); + if (p == null && !player.equals("CONSOLE")) + { + Utils.sendMessage(sender, null, "§cThat player couldn't be found!"); + return true; + } + toggles.put((Player) sender, player); + Utils.sendMessage(sender, null, "Locked your pmtoggle onto §6" + player + "§7."); + return true; + } + + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) + { + Player player = event.getPlayer(); + if (toggles.containsKey(player)) + { + Bukkit.dispatchCommand(player, "m " + toggles.get(player) + " " + event.getMessage()); + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) + { + toggles.remove(event.getPlayer()); + String player = event.getPlayer().getName(); + if (toggles.containsValue(player)) + { + for (Entry entry : toggles.entrySet()) + { + if (entry.getValue().equals(player)) + { + toggles.remove(player); + Utils.sendMessage(entry.getKey(), null, + "We removed your pmtoggle for &6" + player + "&7, as they left the game.", '&'); + } + } + } + } + + // @noformat + @Override + public String getCommandString() + { + return "command pmtoggle {\n" + + " [empty] {\n" + + " help Turns off your toggle.;\n" + + " type player;\n" + + " run pmtoggle_off;\n" + + " }\n" + + " [string:player] {\n" + + " help Turns on your pmtoggle and locks onto .;\n" + + " type player;\n" + + " run pmtoggle player;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/reports/Reports.java b/src/com/redstoner/modules/reports/Reports.java new file mode 100644 index 0000000..1cbab38 --- /dev/null +++ b/src/com/redstoner/modules/reports/Reports.java @@ -0,0 +1,171 @@ +package com.redstoner.modules.reports; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.modules.Module; + +import net.md_5.bungee.api.ChatColor; + +/** Report module. Allows reports to be created and handled by staff + * + * @author Redempt */ +public class Reports implements Module { + + private boolean enabled = false; + private int task = 0; + + private JSONArray reports; + private JSONArray archived; + + private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd kk:mm"); + + @Override + public void onEnable() { + enabled = true; + //Load reports + reports = JsonManager.getArray(new File(Main.plugin.getDataFolder(), "reports.json")); + archived = JsonManager.getArray(new File(Main.plugin.getDataFolder(), "archived_reports.json")); + if (reports == null) { + reports = new JSONArray(); + } + if (archived == null) { + archived = new JSONArray(); + } + //Notify online staff of open reports + task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.plugin, () -> { + if (reports.size() <= 0) { + return; + } + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.hasPermission("utils.report")) { + player.sendMessage(ChatColor.RED + "There are " + ChatColor.YELLOW + reports.size() + ChatColor.RED + " open reports!"); + } + } + }, 2400, 2400); + } + + @Override + public void onDisable() { + enabled = false; + //Save reports, cancel notifier task + Bukkit.getScheduler().cancelTask(task); + JsonManager.save(reports, new File(Main.plugin.getDataFolder(), "reports.json")); + JsonManager.save(archived, new File(Main.plugin.getDataFolder(), "archived_reports.json")); + } + + @Override + public boolean enabled() { + return enabled; + } + + @Override + public String getCommandString() { + return "command report {" + + "[string:message...] {" + + "type player;" + + "help Report a player or incident;" + + "run report message;" + + "}" + + "}" + + "command rp {" + + "perm utils.report;" + + "open {" + + "help List all open reports;" + + "run report_open;" + + "}" + + "close [int:id] {" + + "help Close a report;" + + "run report_close id;" + + "}" + + "tp [int:id] {" + + "help Teleport to the location of a report;" + + "run report_tp id;" + + "type player;" + + "}" + + "}"; + } + + @Command(hook = "report_tp") + public void tpReport(CommandSender sender, int id) { + //Check for invalid ID + Player player = (Player) sender; + if (id > reports.size() - 1 || id < 0) { + sender.sendMessage(ChatColor.RED + "Invalid ID!"); + return; + } + JSONObject report = (JSONObject) reports.get(id); + String loc = (String) report.get("location"); + String[] split = loc.split(";"); + //Location from string + int x = Integer.parseInt(split[0]); + int y = Integer.parseInt(split[1]); + int z = Integer.parseInt(split[2]); + World world = Bukkit.getWorld(split[3]); + Location location = new Location(world, x, y, z); + player.teleport(location); + } + + @SuppressWarnings("unchecked") + @Command(hook = "report_close") + public void closeReport(CommandSender sender, int id) { + //Check for invalid ID + if (id > reports.size() - 1 || id < 0) { + sender.sendMessage(ChatColor.RED + "Invalid ID!"); + return; + } + //Move report to archived reports + JSONObject report = (JSONObject) reports.get(id); + reports.remove(id); + archived.add(report); + sender.sendMessage(ChatColor.GREEN + "Report #" + id + " closed!"); + } + + @Command(hook = "report_open") + public void listOpen(CommandSender sender) { + int i = 0; + for (Object object : reports) { + JSONObject report = (JSONObject) object; + String message = ""; + message += ChatColor.DARK_GRAY + "[" + ChatColor.YELLOW + i + ChatColor.DARK_GRAY + "]"; + message += "[" + ChatColor.YELLOW + report.get("time") + ChatColor.DARK_GRAY + "] "; + message += ChatColor.DARK_AQUA + "" + report.get("name"); + message += ChatColor.WHITE + ": " + ChatColor.YELLOW + report.get("message"); + sender.sendMessage(message); + i++; + } + if (i == 0) { + sender.sendMessage(ChatColor.GREEN + "There are no open reports."); + } + } + + @SuppressWarnings("unchecked") + @Command(hook = "report") + public void report(CommandSender sender, String message) { + Player player = (Player) sender; + //Create report JSONObject + JSONObject report = new JSONObject(); + report.put("name", player.getName()); + report.put("time", dateFormat.format(new Date())); + report.put("message", message); + String loc = ""; + //Location to string + loc += player.getLocation().getBlockX() + ";" + player.getLocation().getBlockY() + ";" + player.getLocation().getBlockZ() + ";" + player.getLocation().getWorld().getName(); + report.put("location", loc); + reports.add(report); + sender.sendMessage(ChatColor.GREEN + "Report created!"); + } + +} diff --git a/src/com/redstoner/modules/saylol/Saylol.java b/src/com/redstoner/modules/saylol/Saylol.java new file mode 100644 index 0000000..e85ebc4 --- /dev/null +++ b/src/com/redstoner/modules/saylol/Saylol.java @@ -0,0 +1,310 @@ +package com.redstoner.modules.saylol; + +import java.io.File; +import java.util.Random; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.simple.JSONArray; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.BroadcastFilter; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 3, compatible = 1) +public class Saylol implements Module +{ + private long lastLol = 0; + private boolean enabled = false; + private File lolLocation = new File(Main.plugin.getDataFolder(), "lol.json"); + private JSONArray lols; + + @Override + public void onEnable() + { + lols = JsonManager.getArray(lolLocation); + if (lols == null) + lols = new JSONArray(); + enabled = true; + } + + @Override + public void onDisable() + { + saveLols(); + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @SuppressWarnings("unchecked") + @Command(hook = "addlol") + public boolean addLol(CommandSender sender, String text) + { + if (lols.contains(text)) + Utils.sendErrorMessage(sender, null, "This lol already exists!"); + else + { + Utils.sendMessage(sender, null, "Successfully added a new lol!"); + lols.add("&e" + text); + saveLols(); + } + return true; + } + + @Command(hook = "dellol") + public boolean delLol(CommandSender sender, int id) + { + if (id < 0 || id >= lols.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + lols.size()); + return true; + } + Utils.sendMessage(sender, null, "Successfully deleted the lol: " + lols.remove(id), '&'); + saveLols(); + return true; + } + + @SuppressWarnings("unchecked") + @Command(hook = "setlol") + public boolean setLol(CommandSender sender, int id, String text) + { + if (id < 0 || id >= lols.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + lols.size()); + return true; + } + Utils.sendMessage(sender, null, "Successfully changed the lol: &e" + lols.get(id) + " &7to: &e" + text, '&'); + lols.set(id, text); + saveLols(); + return true; + } + + @Command(hook = "lolid") + public boolean lolId(CommandSender sender, int id) + { + long time = System.currentTimeMillis(); + if (time - lastLol < 15000) + { + Utils.sendErrorMessage(sender, null, + "You can't use saylol for another " + (14 - (int) Math.ceil((time - lastLol) / 1000)) + "s."); + return true; + } + if (id < 0 || id >= lols.size()) + { + Utils.sendErrorMessage(sender, null, "The ID must be at least 0 and at most " + lols.size()); + return true; + } + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = "&9" + sender.getName(); + Utils.broadcast("&8[&blol&8] ", name + "&8: &e" + lols.get(id), new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + return recipient.hasPermission("utils.lol.see"); + } + }, '&'); + lastLol = time; + return true; + } + + @Command(hook = "saylol") + public boolean saylol(CommandSender sender) + { + long time = System.currentTimeMillis(); + if (time - lastLol < 15000) + { + Utils.sendErrorMessage(sender, null, + "You can't use saylol for another " + (14 - (int) Math.ceil((time - lastLol) / 1000)) + "s."); + return true; + } + String name; + if (sender instanceof Player) + name = ((Player) sender).getDisplayName(); + else + name = "&9" + sender.getName(); + Random random = new Random(); + int id = random.nextInt(lols.size()); + Utils.broadcast("&8[&blol&8] ", name + "&8: &e" + lols.get(id), new BroadcastFilter() + { + @Override + public boolean sendTo(CommandSender recipient) + { + return recipient.hasPermission("utils.lol.see"); + } + }, '&'); + lastLol = time; + return true; + } + + @Command(hook = "listlols") + public boolean listLols(CommandSender sender, int page) + { + page = page - 1; + int start = page * 10; + int end = start + 10; + int pages = (int) Math.ceil(lols.size() / 10d); + if (start < 0) + { + Utils.sendErrorMessage(sender, null, "Page number too small, must be at least 0!"); + return true; + } + if (start > lols.size()) + { + Utils.sendErrorMessage(sender, null, "Page number too big, must be at most " + pages + "!"); + return true; + } + Utils.sendModuleHeader(sender); + Utils.sendMessage(sender, "", "&ePage " + (page + 1) + "/" + pages + ":", '&'); + for (int i = start; i < end && i < lols.size(); i++) + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + lols.get(i), '&'); + return true; + } + + @Command(hook = "listlolsdef") + public boolean listLolsDefault(CommandSender sender) + { + return listLols(sender, 1); + } + + @Command(hook = "searchlol") + public boolean search(CommandSender sender, boolean insensitive, String text) + { + Utils.sendModuleHeader(sender); + boolean found = false; + if (insensitive) + { + text = text.toLowerCase(); + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).toLowerCase().contains(text)) + { + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + lols.get(i), '&'); + found = true; + } + } + } + else + { + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).contains(text)) + { + Utils.sendMessage(sender, "", "&a" + i + "&8: &e" + lols.get(i), '&'); + found = true; + } + } + } + if (!found) + { + Utils.sendMessage(sender, "", "&cCouldn't find any matching lols.", '&'); + } + return true; + } + + @Command(hook = "matchlol") + public boolean match(CommandSender sender, boolean insensitive, String regex) + { + Utils.sendModuleHeader(sender); + boolean found = false; + if (insensitive) + { + regex = regex.toLowerCase(); + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).toLowerCase().matches(regex)) + { + Utils.sendMessage(sender, "", "&a" + i + ": " + lols.get(i), '&'); + found = true; + } + } + } + else + { + for (int i = 0; i < lols.size(); i++) + { + if (((String) lols.get(i)).matches(regex)) + { + Utils.sendMessage(sender, "", "&a" + i + ": " + lols.get(i), '&'); + found = true; + } + } + } + if (!found) + { + Utils.sendMessage(sender, "", "&cCouldn't find any matching lols.", '&'); + } + return true; + } + + public void saveLols() + { + JsonManager.save(lols, lolLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command lol {\n" + + " add [string:text...] {\n" + + " help Lols a text.;\n" + + " run addlol text;\n" + + " perm utils.lol.admin;\n" + + " }\n" + + " del [int:id] {\n" + + " help Unlols a lol.;\n" + + " run dellol id;\n" + + " perm utils.lol.admin;\n" + + " }\n" + + " set [int:id] [string:text...] {\n" + + " help Relols a lol.;\n" + + " run setlol id text;\n" + + " perm utils.lol.admin;\n" + + " }\n" + + " id [int:id] {\n" + + " help Lols specifically.;\n" + + " run lolid id;\n" + + " perm utils.lol.id;\n" + + " }\n" + + " list [int:page] {\n" + + " help Shows lols.;\n" + + " run listlols page;\n" + + " perm utils.lol.list;\n" + + " }\n" + + " list {\n" + + " help Shows lols.;\n" + + " run listlolsdef;\n" + + " perm utils.lol.list;\n" + + " }\n" + + " search [flag:-i] [string:text...] {\n" + + " help Search lols.;\n" + + " run searchlol -i text;\n" + + " perm utils.lol.search;\n" + + " }\n" + + " match [flag:-i] [string:regex...] {\n" + + " help Search lols. But better.;\n" + + " run matchlol -i regex;\n" + + " perm utils.lol.match;\n" + + " }\n" + + " [empty] {\n" + + " help Lols.;\n" + + " run saylol;\n" + + " perm utils.lol;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/scriptutils/Scriptutils.java b/src/com/redstoner/modules/scriptutils/Scriptutils.java new file mode 100644 index 0000000..434b830 --- /dev/null +++ b/src/com/redstoner/modules/scriptutils/Scriptutils.java @@ -0,0 +1,320 @@ +package com.redstoner.modules.scriptutils; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class Scriptutils implements Module +{ + private boolean enabled = false; + + /** Prints Bukkit restart message + * arg 0 timeout + * arg 1 $(whoami); + * arg 2: reason */ + @Command(hook = "script_restart") + public void print_restart(CommandSender sender, String timeout, String name, String reason) + { + Utils.broadcast("", "§2§l=============================================", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§9" + name + " is restarting the server.", null); + Utils.broadcast("", "§a§lServer is going to restart in " + timeout + " seconds.", null); + Utils.broadcast("", "§6§l%s" + reason, null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§2§l=============================================", null); + } + + /** Prints the Bukkit shut down message + * arg 0 timeout + * arg 1 $(whoami); + * arg 2: reason */ + @Command(hook = "script_stop") + public void print_stop(CommandSender sender, String timeout, String name, String reason) + { + Utils.broadcast("", "§2§l=============================================", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§9" + name + " is shutting down the server.", null); + Utils.broadcast("", "§a§lServer is going to shut down in " + timeout + " seconds.", null); + Utils.broadcast("", "§6§l" + reason, null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§r", null); + Utils.broadcast("", "§2§l=============================================", null); + } + + /** Prints the shut down abort message */ + @Command(hook = "script_stop_abort") + public void abort_stop(CommandSender sender) + { + Utils.broadcast("", "§4§oShut down has been aborted.", null); + } + + /** Prints the restart abort message */ + @Command(hook = "script_restart_abort") + public void abort_restart(CommandSender sender) + { + Utils.broadcast("", "§4§oRestart has been aborted.", null); + } + + /** Prints the backup started message, saves all worlds and turns off world saving */ + @Command(hook = "script_backup_begin") + public void print_backup_begin(CommandSender sender) + { + Utils.broadcast("", "§4 =§2 Starting backup now.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-off"); + } + + /** Prints the backup finished message and turns on world saving */ + @Command(hook = "script_backup_end") + public void print_backup_end(CommandSender sender) + { + Utils.broadcast("", "§4 =§2 Backup completed.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-on"); + } + + /** Prints the backup error message and turns on world saving */ + @Command(hook = "script_backup_error") + public void print_backup_error(CommandSender sender) + { + Utils.broadcast("", "§4 =§c§l Error while backing up!", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-on"); + } + + /** Prints the world trimming started message and starts trimming */ + @Command(hook = "script_trim") + public void print_backup_trim(CommandSender sender) + { + Utils.broadcast("", "§4 =§3 Deleting all chunks beyond border now.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "wb Creative trim 1000000 15"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "wb trim confirm"); + } + + /** Prints the trimming finished message + * arg 0 size difference of world + * arg 1: world border trim data */ + @Command(hook = "script_trim_result") + public void print_backup_trim_res(CommandSender sender, String size, String data) + { + Utils.broadcast("", "§4 =§3 Chunk deletion saved " + data + " (§a" + size + "MB§3)", null); + } + + /** Prints the database backup started message and admin-chat warning */ + @Command(hook = "script_backup_database_begin") + public void print_backup_db_begin(CommandSender sender) + { + Utils.broadcast("", "§6 =§2 Starting database backup now.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §aLogblock may be unavailable!"); + } + + /** Prints the database dumps compression started message */ + @Command(hook = "script_backup_database_dumps") + public void print_backup_db_dumps(CommandSender sender) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §aDumps completed, logblock available again."); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §aNow compressing dumps, will take a while..."); + } + + /** Prints the database finished message and backup size in admin-chat + * arg 0 size of backup */ + @Command(hook = "script_backup_database_end") + public void print_backup_db_end(CommandSender sender, String size) + { + Utils.broadcast("", "§6 =§2 Database backup completed.", null); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §abackup size: §2" + size + "MB§a."); + } + + /** Prints the database backup error message */ + @Command(hook = "script_backup_database_error") + public void print_backup_db_error(CommandSender sender) + { + Utils.broadcast("", "§6 =§c§l Error while backing up database!", null); + } + + /** Prints the database backup abort message */ + @Command(hook = "script_backup_database_abort") + public void print_backup_db_abort(CommandSender sender) + { + Utils.broadcast("", "§6 =§2 Database backup aborted.", null); + } + + /** Prints the spigot update message */ + @Command(hook = "script_spigot_update") + public void print_update(CommandSender sender) + { + Utils.broadcast("", "§9 =§2 A new Spigot version has been downloaded!", null); + Utils.broadcast("", "§9 =§2 Update will be applied after the next reboot.", null); + } + + /** Prints the admin-chat warning for disk is filled + * arg 0 fill percentage */ + @Command(hook = "script_disk_filled") + public void print_disk_filled(CommandSender sender, String percentage) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), + "ac §4§lWARNING:§6 Disk is filled > 96% (" + percentage + "%);"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §4 Server will shut down at 98%!"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ac §4 Contact an admin §nimmediately§4!"); + } + + /** Saves all worlds, kicks players and shuts down the server + * arg 0: reason */ + @Command(hook = "script_shutdown") + public void shutdown(CommandSender sender, String reason) + { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "kickall " + reason); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "stop"); + } + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command script_restart {\n" + + " [string:timeout] [string:name] [string:reason] {\n" + + " help Prints bukkit restart message;\n" + + " type console;\n" + + " run script_restart timeout name reason;\n" + + " }\n" + + "}\n" + + "command script_stop {\n" + + " [string:timeout] [string:name] [string:reason] {\n" + + " help Prints bukkit shut down message;\n" + + " type console;\n" + + " run script_stop timeout name reason;\n" + + " }\n" + + "}\n" + + "command script_restart_abort {\n" + + " [empty] {\n" + + " help Prints the restart abort message;\n" + + " type console;\n" + + " run script_restart_abort;\n" + + " }\n" + + "}\n" + + "command script_stop_abort {\n" + + " [empty] {\n" + + " help Prints the shut down abort message;\n" + + " type console;\n" + + " run script_stop_abort;\n" + + " }\n" + + "}\n" + + "command script_backup_begin {\n" + + " [empty] {\n" + + " help Prints the backup started message, saves all worlds and turns off world saving;\n" + + " type console;\n" + + " run script_backup_begin;\n" + + " }\n" + + "}\n" + + "command script_backup_end {\n" + + " [empty] {\n" + + " help Prints the backup finished message and turns on world saving;\n" + + " type console;\n" + + " run script_backup_end;\n" + + " }\n" + + "}\n" + + "command script_backup_error {\n" + + " [empty] {\n" + + " help Prints the backup error message and turns on world saving;\n" + + " type console;\n" + + " run script_backup_error;\n" + + " }\n" + + "}\n" + + "command script_trim {\n" + + " [empty] {\n" + + " help Prints the world trimming started message and starts trimming;\n" + + " type console;\n" + + " run script_trim;\n" + + " }\n" + + "}\n" + + "command script_trim_result {\n" + + " [string:size] [string:data...] {\n" + + " help Prints the trimming finished message;\n" + + " type console;\n" + + " run script_trim_result size data;\n" + + " }\n" + + "}\n" + + "command script_backup_database_begin {\n" + + " [empty] {\n" + + " help Prints the database backup started message and admin-chat warning;\n" + + " type console;\n" + + " run script_backup_database_begin;\n" + + " }\n" + + "}\n" + + "command script_backup_database_dumps {\n" + + " [empty] {\n" + + " help Prints the database dumps cmpression started message;\n" + + " type console;\n" + + " run script_backup_database_dumps;\n" + + " }\n" + + "}\n" + + "command script_backup_database_end {\n" + + " [string:size] {\n" + + " help Prints the database finished message and backup size in admin-chat;\n" + + " type console;\n" + + " run script_backup_database_end size;\n" + + " }\n" + + "}\n" + + "command script_backup_database_error {\n" + + " [empty] {\n" + + " help Prints the database backup error message;\n" + + " type console;\n" + + " run script_backup_database_error;\n" + + " }\n" + + "}\n" + + "command script_backup_database_abort {\n" + + " [empty] {\n" + + " help Prints the database backup abort message;\n" + + " type console;\n" + + " run script_backup_database_abort;\n" + + " }\n" + + "}\n" + + "command script_spigot_update {\n" + + " [empty] {\n" + + " help Prints the spigot update message;\n" + + " type console;\n" + + " run script_spigot_update;\n" + + " }\n" + + "}\n" + + "command script_disk_filled {\n" + + " [string:percentage] {\n" + + " help Prints the admin-chat warning for disk is filled;\n" + + " type console;\n" + + " run script_disk_filled percentage;\n" + + " }\n" + + "}\n" + + "command script_shutdown {\n" + + " [string:reason] {\n" + + " help Saves all worlds, kicks players and shuts down the server;\n" + + " type console;\n" + + " run script_shutdown reason;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/skullclick/SkullClick.java b/src/com/redstoner/modules/skullclick/SkullClick.java new file mode 100644 index 0000000..e05e404 --- /dev/null +++ b/src/com/redstoner/modules/skullclick/SkullClick.java @@ -0,0 +1,79 @@ +package com.redstoner.modules.skullclick; + +import org.bukkit.block.BlockState; +import org.bukkit.block.Skull; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +@AutoRegisterListener +public class SkullClick implements Module, Listener +{ + private boolean enabled = false; + private boolean seen = false; + + @SuppressWarnings("deprecation") + @EventHandler + public void onClick(PlayerInteractEvent e) + { + // For some reason the event gets fired twice, this fixes it. Lol. + if (seen) + { + seen = false; + return; + } + seen = true; + if (e.getAction() == Action.RIGHT_CLICK_BLOCK && !e.isCancelled()) + { + BlockState block = e.getClickedBlock().getState(); + if (block instanceof Skull) + { + Skull skull = (Skull) block; + String owner = skull.getOwner(); + if (owner == null || owner.equals("")) + { + Utils.sendMessage(e.getPlayer(), null, "§eThat skull has no owner."); + } + else + { + Utils.sendMessage(e.getPlayer(), null, "§eThat's " + owner + "."); + } + if (!e.getPlayer().isSneaking()) + { + e.setCancelled(true); + } + } + } + } + + @Override + public boolean enabled() + { + return enabled; + } + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public String getCommandString() + { + return null; + } +} diff --git a/src/com/redstoner/modules/tag/Tag.java b/src/com/redstoner/modules/tag/Tag.java new file mode 100644 index 0000000..3cec1fa --- /dev/null +++ b/src/com/redstoner/modules/tag/Tag.java @@ -0,0 +1,175 @@ +package com.redstoner.modules.tag; + +import java.io.File; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.redstoner.annotations.Version; +import com.redstoner.misc.JsonManager; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class Tag implements Module +{ + private boolean enabled; + private File tagLocation = new File(Main.plugin.getDataFolder(), "tag.json"); + private JSONObject tags; + + @Override + public void onEnable() + { + tags = JsonManager.getObject(tagLocation); + if (tags == null) + tags = new JSONObject(); + enabled = true; + } + + @Override + public void onDisable() + { + saveTags(); + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + @SuppressWarnings({"deprecation", "unchecked"}) + @Command(hook = "addtag", async = AsyncType.ALWAYS) + public boolean addTag(CommandSender sender, String name, String tag) + { + OfflinePlayer player = Bukkit.getOfflinePlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, "That player doesn't exist!"); + return true; + } + Utils.sendModuleHeader(sender); + UUID uuid = player.getUniqueId(); + JSONArray tagArray; + if (tags.containsKey(uuid.toString())) + tagArray = (JSONArray) tags.get(uuid.toString()); + else + tagArray = new JSONArray(); + tagArray.add(tag); + if (!tags.containsKey(uuid.toString())) + tags.put(uuid.toString(), tagArray); + Utils.sendMessage(sender, null, "Successfully added note &e" + tag + " &7to player &e" + name + "&7!", '&'); + saveTags(); + return true; + } + + @SuppressWarnings("deprecation") + @Command(hook = "deltag", async = AsyncType.ALWAYS) + public boolean delTag(CommandSender sender, String name, int id) + { + if (id < 1) + { + Utils.sendErrorMessage(sender, null, "The ID you entered is too small, it must be at least 1!"); + return true; + } + OfflinePlayer player = Bukkit.getOfflinePlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, "That player doesn't exist!"); + return true; + } + UUID uuid = player.getUniqueId(); + if (!tags.containsKey(uuid.toString())) + { + Utils.sendMessage(sender, null, "&eThere are no notes about that player.", '&'); + return true; + } + JSONArray tagArray = (JSONArray) tags.get(uuid.toString()); + int size = tagArray.size(); + if (size == 0) + { + Utils.sendErrorMessage(sender, null, + "Empty entry found! You might consider running a database cleanup, contact an admin to do this."); + Utils.log("Found empty tag entry. Database cleanup is recommended."); + return true; + } + if (id > size) + { + Utils.sendErrorMessage(sender, null, "The number you entered is too big! It must be at most " + size + "!"); + return true; + } + Utils.sendMessage(sender, null, "Successfully removed note: &e" + tagArray.remove(id - 1), '&'); + if (tagArray.size() == 0) + tags.remove(uuid.toString()); + saveTags(); + return true; + } + + @SuppressWarnings("deprecation") + @Command(hook = "checktag", async = AsyncType.ALWAYS) + public boolean checkTags(CommandSender sender, String name) + { + OfflinePlayer player = Bukkit.getOfflinePlayer(name); + if (player == null) + { + Utils.sendErrorMessage(sender, null, "That player doesn't exist!"); + return true; + } + Utils.sendModuleHeader(sender); + UUID uuid = player.getUniqueId(); + if (!tags.containsKey(uuid.toString())) + { + Utils.sendMessage(sender, "", "&eThere are no notes about that player.", '&'); + return true; + } + JSONArray tagArray = (JSONArray) tags.get(uuid.toString()); + int size = tagArray.size(); + Utils.sendMessage(sender, "", "There are " + size + " notes about this player:"); + if (size == 0) + { + tags.remove(uuid.toString()); + saveTags(); + return true; + } + for (int i = 0; i < size; i++) + Utils.sendMessage(sender, "", "&a" + (i + 1) + "&8: &e" + tagArray.get(i), '&'); + return true; + } + + public void saveTags() + { + JsonManager.save(tags, tagLocation); + } + + // @noformat + @Override + public String getCommandString() + { + return "command tag {\n" + + " add [string:player] [string:tag...] {\n" + + " help Tags a player.;\n" + + " run addtag player tag;\n" + + " perm utils.tag;\n" + + " }\n" + + " del [string:player] [int:id] {\n" + + " help Removes a tag.;\n" + + " run deltag player id;\n" + + " perm utils.tag;\n" + + " }\n" + + " check [string:player] {\n" + + " help Lists all tags of a player.;\n" + + " run checktag player;\n" + + " perm utils.tag;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/vanish/Vanish.java b/src/com/redstoner/modules/vanish/Vanish.java new file mode 100644 index 0000000..5567dcc --- /dev/null +++ b/src/com/redstoner/modules/vanish/Vanish.java @@ -0,0 +1,252 @@ +package com.redstoner.modules.vanish; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@AutoRegisterListener +@Version(major = 1, minor = 0, revision = 3, compatible = 1) +public class Vanish implements Module, Listener +{ + private boolean enabled = false; + private ArrayList vanished = new ArrayList(); + private HashMap> vanishOthers = new HashMap>(); + + @Command(hook = "vanish") + public boolean vanish(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (vanished.contains(uid)) + { + vanished.remove(uid); + Utils.sendMessage(sender, null, "You are no longer vanished!"); + unvanishPlayer((Player) sender); + } + else + { + vanished.add(uid); + Utils.sendMessage(sender, null, "You are now vanished!"); + vanishPlayer((Player) sender); + } + return true; + } + + @Command(hook = "vanish_on") + public boolean vanishOn(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (vanished.contains(uid)) + Utils.sendMessage(sender, null, + "You were already vanished, however we refreshed the vanish for you just to be sure!"); + else + { + vanished.add(uid); + Utils.sendMessage(sender, null, "You are now vanished!"); + } + vanishPlayer((Player) sender); + return true; + } + + @Command(hook = "vanish_off") + public boolean vanishOff(CommandSender sender) + { + UUID uid = ((Player) sender).getUniqueId(); + if (!vanished.contains(uid)) + Utils.sendMessage(sender, null, + "You were not vanished, however we refreshed the vanish for you just to be sure!"); + else + { + vanished.remove(uid); + Utils.sendMessage(sender, null, "You are no longer vanished!"); + } + unvanishPlayer((Player) sender); + return true; + } + + @Command(hook = "vanish_other") + public boolean vanishOther(CommandSender sender, String name) + { + Player player = Bukkit.getPlayer(name); + if (player == null) + { + Utils.sendMessage(sender, null, "&cPlayer &6" + name + " &ccould not be found!", '&'); + return true; + } + UUID uid = player.getUniqueId(); + if (player.hasPermission("utils.vanish")) + { + if (vanished.contains(uid)) + { + vanished.remove(uid); + Utils.sendMessage(sender, null, "Successfully unvanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are no longer vanished!"); + } + else + { + vanished.add(uid); + Utils.sendMessage(sender, null, "Successfully vanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are now vanished!"); + } + return true; + } + for (Entry> entry : vanishOthers.entrySet()) + { + if (entry.getValue().contains(uid)) + { + entry.getValue().remove(uid); + Utils.sendMessage(sender, null, "Successfully unvanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are no longer vanished!"); + if (entry.getValue().size() == 0) + vanishOthers.remove(entry.getKey()); + return true; + } + } + UUID uuid = ((Player) sender).getUniqueId(); + ArrayList toAddTo = vanishOthers.get(uuid); + if (toAddTo == null) + toAddTo = new ArrayList(); + toAddTo.add(uid); + vanishOthers.put(uuid, toAddTo); + Utils.sendMessage(sender, null, "Successfully vanished player &6" + name, '&'); + Utils.sendMessage(player, null, "You are now vanished!"); + return true; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + if (vanished.contains(player.getUniqueId())) + { + for (Player p : Bukkit.getOnlinePlayers()) + p.hidePlayer(player); + } + if (player.hasPermission("utils.vanish")) + return; + for (UUID uid : vanished) + { + Player p = Bukkit.getPlayer(uid); + if (p == null) + continue; + player.hidePlayer(p); + } + for (Entry> entry : vanishOthers.entrySet()) + { + for (UUID uid : entry.getValue()) + { + Player p = Bukkit.getPlayer(uid); + if (p == null) + continue; + player.hidePlayer(p); + } + } + } + + @EventHandler + public void onPlayerLeave(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + UUID uid = player.getUniqueId(); + if (vanishOthers.containsKey(uid)) + { + ArrayList toUnvanish = vanishOthers.remove(uid); + for (UUID uuid : toUnvanish) + { + Player p = Bukkit.getPlayer(uuid); + if (p != null) + unvanishPlayer(p); + } + } + boolean wasVanished = false; + for (Entry> entry : vanishOthers.entrySet()) + { + if (entry.getValue().contains(uid)) + { + entry.getValue().remove(uid); + wasVanished = true; + break; + } + } + if (wasVanished) + unvanishPlayer(player); + } + + private void vanishPlayer(Player player) + { + for (Player p : Bukkit.getOnlinePlayers()) + { + if (!p.hasPermission("utils.vanish")) + p.hidePlayer(player); + } + } + + private void unvanishPlayer(Player player) + { + for (Player p : Bukkit.getOnlinePlayers()) + p.showPlayer(player); + } + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command vanish {\n" + + " [empty] {\n" + + " help Toggles your vanish status.;\n" + + " type player;\n" + + " run vanish;\n" + + " perm utils.vanish;\n" + + " }\n" + + " on {\n" + + " help Turns your vanish on.;\n" + + " type player;\n" + + " run vanish_on;\n" + + " perm utils.vanish;\n" + + " }\n" + + " off {\n" + + " help Turns your vanish off.;\n" + + " type player;\n" + + " run vanish_off;\n" + + " perm utils.vanish;\n" + + " }\n" + + " [string:name] {\n" + + " help Toggles someone elses vanish;\n" + + " run vanish_other name;\n" + + " perm utils.vanishother;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/com/redstoner/modules/warn/Warn.java b/src/com/redstoner/modules/warn/Warn.java new file mode 100644 index 0000000..e4afa4f --- /dev/null +++ b/src/com/redstoner/modules/warn/Warn.java @@ -0,0 +1,71 @@ +package com.redstoner.modules.warn; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public class Warn implements Module +{ + private boolean enabled = false; + + @Command(hook = "warn") + public void warn_normal(CommandSender sender) + { + String name = ((Player) sender).getDisplayName(); + Utils.broadcast(null, "§2Lag incoming! - §9" + name, null); + } + + @Command(hook = "warnp") + public void warn_possible(CommandSender sender) + { + String name = ((Player) sender).getDisplayName(); + Utils.broadcast(null, "§2Possible lag incoming! - §9" + name, null); + } + + @Override + public void onEnable() + { + enabled = true; + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command warn {\n" + + " [empty] {\n" + + " run warn;\n" + + " type player;\n" + + " help Warns other players about definite lag;\n" + + " perm utils.warn;\n" + + " }\n" + + "}\n" + + "\n" + + "command warnp {\n" + + " [empty] {\n" + + " run warnp;\n" + + " type player;\n" + + " help Warns other players about possible lag;\n" + + " perm utils.warn;\n" + + " }\n" + + "}"; + } + //@format +} diff --git a/src/com/redstoner/modules/webtoken/WebToken.java b/src/com/redstoner/modules/webtoken/WebToken.java new file mode 100644 index 0000000..5ad6632 --- /dev/null +++ b/src/com/redstoner/modules/webtoken/WebToken.java @@ -0,0 +1,223 @@ +package com.redstoner.modules.webtoken; + +import java.io.IOException; +import java.util.Random; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.simple.parser.ParseException; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Utils; +import com.redstoner.misc.mysql.Config; +import com.redstoner.misc.mysql.MysqlHandler; +import com.redstoner.misc.mysql.elements.ConstraintOperator; +import com.redstoner.misc.mysql.elements.MysqlConstraint; +import com.redstoner.misc.mysql.elements.MysqlDatabase; +import com.redstoner.misc.mysql.elements.MysqlTable; +import com.redstoner.modules.Module; + +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public class WebToken implements Module +{ + private boolean enabled = false; + private static final int TOKEN_LENGTH = 6; + private static final String CONSONANTS = "bcdfghjklmnpqrstvwxyz"; + private static final String VOWELS = "aeiou"; + private MysqlTable table; + + @Override + public void onEnable() + { + Config config; + try + { + config = Config.getConfig("WebToken.json"); + } + catch (IOException | ParseException e1) + { + e1.printStackTrace(); + enabled = false; + return; + } + if (config == null || !config.containsKey("database") || !config.containsKey("table")) + { + Utils.error("Could not load the WebToken config file, disabling!"); + config.put("database", "redstoner"); + config.put("table", "webtoken"); + enabled = false; + return; + } + try + { + MysqlDatabase database = MysqlHandler.INSTANCE.getDatabase(config.get("database")); + table = database.getTable(config.get("table")); + } + catch (NullPointerException e) + { + Utils.error("Could not use the WebToken config, disabling!"); + enabled = false; + return; + } + enabled = true; + } + + private String query(String emailOrToken, UUID uuid) throws Exception + { + if (!(emailOrToken.equals("token") && emailOrToken.equals("email"))) + { + throw new Exception("Invalid database query: " + emailOrToken); + } + Object[] results = table.get(emailOrToken, + new MysqlConstraint("uuid", ConstraintOperator.EQUAL, uuid.toString().replaceAll("-", ""))); + if (results instanceof String[]) + { + String[] tokenResults = (String[]) results; + if (tokenResults.length == 1) + { + return tokenResults[0]; + } + else + { + return null; + } + } + else + { + throw new Exception("Token query returned invalid result!"); + } + } + + private boolean match(String string, String regex) + { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(string); + return matcher.find(); + } + + private void printToken(Player player, String email, String token) + { + Utils.sendModuleHeader(player); + Utils.sendMessage(player, "", "§aEmail: " + email); + Utils.sendMessage(player, "", "§aToken: " + token); + Utils.sendMessage(player, "", "§cIMPORTANT: never share the token with anyone!"); + Utils.sendMessage(player, "", "§cIt could be used to claim your website account!"); + } + + private String generateToken() + { + String token = ""; + Random random = new Random(); + int start = random.nextInt(2); + for (int i = 0; i < TOKEN_LENGTH; i++) + { + if (i % 2 == start) + { + token += CONSONANTS.charAt(random.nextInt(21)); + } + else + { + token += VOWELS.charAt(random.nextInt(5)); + } + } + return token; + } + + @Command(hook = "token") + public void token(CommandSender sender) + { + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + try + { + String token = query("token", uuid); + if (token == null) + { + Utils.sendErrorMessage(player, null, "§cYou don't have a token yet! Use " + ChatColor.YELLOW + + "/gettoken " + ChatColor.RED + " to get one."); + } + else + { + String email = query("email", uuid); + printToken(player, email, token); + } + } + catch (Exception e) + { + Utils.sendErrorMessage(player, null, "Error getting your token, please contact an admin!"); + e.printStackTrace(); + } + } + + @Command(hook = "gettoken") + public void token(CommandSender sender, String email) + { + Player player = (Player) sender; + if (match(email, "^.+@(.+\\..{2,}|\\[[0-9a-fA-F:.]+\\])$")) + { + String uuid = player.getUniqueId().toString().replaceAll("-", ""); + String token = generateToken(); + try + { + table.delete(new MysqlConstraint("uuid", ConstraintOperator.EQUAL, uuid)); + table.insert(uuid, token, email); + player.sendMessage(ChatColor.GREEN + "Token generated!"); + printToken(player, email, token); + } + catch (Exception e) + { + Utils.sendErrorMessage(player, null, "Error getting your token, please contact an admin!"); + e.printStackTrace(); + } + } + else + { + Utils.sendErrorMessage(player, null, "Hmm... That doesn't look like a valid email!"); + } + } + + @Override + public void onDisable() + { + enabled = false; + } + + @Override + public boolean enabled() + { + return enabled; + } + + // @noformat + @Override + public String getCommandString() + { + return "command token {\n" + + " perm utils.webtoken;\n" + + " \n" + + " [empty] {\n" + + " help Displays an already generated token;\n" + + " type player;\n" + + " perm utils.webtoken;\n" + + " run token;\n" + + " }\n" + + "}\n" + + "\n" + + "command gettoken {\n" + + " perm utils.webtoken;\n" + + " \n" + + " [string:email...] {\n" + + " help Generates a token used for website authentication;\n" + + " type player;\n" + + " perm utils.webtoken;\n" + + " run gettoken;\n" + + " }\n" + + "}"; + } + // @format +} diff --git a/src/main/java/com/redstoner/annotations/AutoRegisterListener.java b/src/main/java/com/redstoner/annotations/AutoRegisterListener.java deleted file mode 100644 index 7e36c9e..0000000 --- a/src/main/java/com/redstoner/annotations/AutoRegisterListener.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.redstoner.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The auto register annotation, to be put onto Classes that implement listener when you are too lazy to register the events yourself. - * - * @author Pepich - */ -@Target (ElementType.TYPE) -@Retention (RetentionPolicy.RUNTIME) -@Version (major = 1, minor = 0, revision = 1, compatible = 1) -public @interface AutoRegisterListener {} diff --git a/src/main/java/com/redstoner/annotations/Commands.java b/src/main/java/com/redstoner/annotations/Commands.java deleted file mode 100644 index d5ea130..0000000 --- a/src/main/java/com/redstoner/annotations/Commands.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.redstoner.annotations; - -import com.redstoner.misc.CommandHolderType; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target (ElementType.TYPE) -@Retention (RetentionPolicy.RUNTIME) -public @interface Commands { - CommandHolderType value(); -} diff --git a/src/main/java/com/redstoner/annotations/Version.java b/src/main/java/com/redstoner/annotations/Version.java deleted file mode 100644 index 2137c3f..0000000 --- a/src/main/java/com/redstoner/annotations/Version.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.redstoner.annotations; - -import java.lang.annotation.*; - -/** - * The Version annotation, to be applied to all Classes that are part of the project. - * - * @author Pepich - */ -@Target (ElementType.TYPE) -@Documented -@Retention (RetentionPolicy.RUNTIME) -public @interface Version { - /** - * The major indicator of the version. Will be used for compatibility detection. - * - * @return the major version as an int - */ - int major(); - - int minor(); - - int revision(); - - /** - * The compatibility part of the version number. Will be used for compatibility detection.
- * Set to -1 if it is supposed to be always compatible.
- * Defaults to 1. - * - * @return the smallest compatible version as an int. - */ - int compatible() default 1; -} diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd deleted file mode 100644 index 69dd38d..0000000 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd +++ /dev/null @@ -1,36 +0,0 @@ -command modules { - [empty] { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - -v { - help Lists all modules and their versions. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listversions; - } - - - list { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - list -v { - help Lists all modules and their versions. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listversions; - } - load [string:name...] { - help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run load name; - type console; - } - unload [string:name...] { - help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run unload name; - type console; - } -} \ No newline at end of file diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java deleted file mode 100644 index ec478a0..0000000 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ /dev/null @@ -1,634 +0,0 @@ -package com.redstoner.coremods.moduleLoader; - -import com.nemez.cmdmgr.Command; -import com.nemez.cmdmgr.Command.AsyncType; -import com.nemez.cmdmgr.CommandManager; -import com.redstoner.annotations.AutoRegisterListener; -import com.redstoner.annotations.Commands; -import com.redstoner.annotations.Version; -import com.redstoner.logging.PrivateLogManager; -import com.redstoner.misc.Main; -import com.redstoner.misc.ModuleInfo; -import com.redstoner.misc.VersionHelper; -import com.redstoner.modules.CoreModule; -import com.redstoner.modules.Module; -import com.redstoner.modules.ModuleLogger; -import net.nemez.chatapi.click.Message; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.plugin.java.JavaPlugin; - -import java.io.*; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -/** - * The module loader, mother of all modules. Responsible for loading and taking care of all modules. - * - * @author Pepich - */ -@Version (major = 5, minor = 2, revision = 1, compatible = 5) -public final class ModuleLoader implements CoreModule { - private static final HashMap modules = new HashMap<>(); - private static ModuleLoader instance; - private static HashMap moduleInfos = new HashMap<>(); - private static HashMap> categorizes = new HashMap<>(); - private static URL[] urls; - private static URLClassLoader mainLoader; - private static HashMap loaders = new HashMap<>(); - private static File configFile; - private static FileConfiguration config; - private static boolean debugMode = false; - private static HashMap loggers = new HashMap<>(); - - private ModuleLoader() { - try { - config = Main.plugin.getConfig(); - configFile = new File(Main.plugin.getDataFolder(), "config.yml"); - urls = new URL[] { (new File(Main.plugin.getDataFolder(), "classes")).toURI().toURL() }; - mainLoader = new URLClassLoader(urls, this.getClass().getClassLoader()); - } catch (MalformedURLException e) { - System.out.println("Sumtin is wong with ya filesüstem m8. Fix eeeet or I won't werk!"); - Bukkit.getPluginManager().disablePlugin(Main.plugin); - } - } - - public static void init() { - if (instance == null) - instance = new ModuleLoader(); - ModuleInfo info = new ModuleInfo(ModuleLoader.class.getResourceAsStream("module.info"), instance); - moduleInfos.put(instance, info); - loggers.put(instance, new ModuleLogger(info.getDisplayName())); - CommandManager.registerCommand(ModuleLoader.class.getResourceAsStream("ModuleLoader.cmd"), instance, - Main.plugin - ); - } - - public static final void loadFromConfig() { - try { - if (!configFile.exists()) { - configFile.getParentFile().mkdirs(); - configFile.createNewFile(); - } - config.load(configFile); - } catch (FileNotFoundException e) { - } catch (IOException e) { - e.printStackTrace(); - } catch (InvalidConfigurationException e) { - configFile.delete(); - try { - configFile.createNewFile(); - } catch (IOException e1) { - e1.printStackTrace(); - } - instance.getLogger().error("Invalid config file! Creating new, blank file!"); - } - List coremods = config.getStringList("coremods"); - if (coremods == null || coremods.isEmpty()) { - config.set("coremods", new String[] { "# Add the coremodules here!" }); - Main.plugin.saveConfig(); - try { - config.save(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - List autoload = config.getStringList("autoload"); - if (autoload == null || autoload.isEmpty()) { - config.set("autoload", new String[] { "# Add the modules here!" }); - Main.plugin.saveConfig(); - try { - config.save(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - if (!config.contains("debugMode")) { - config.set("debugMode", false); - try { - config.save(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - debugMode = config.getBoolean("debugMode"); - for (String s : coremods) { - if (!s.startsWith("#")) - if (!ModuleLoader.addDynamicModule(s)) { - instance.getLogger().error("Couldn't autocomplete path for module name: " + s - + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); - - } - } - for (String s : autoload) { - if (!s.startsWith("#")) - if (!ModuleLoader.addDynamicModule(s)) { - instance.getLogger().error("Couldn't autocomplete path for module name: " + s - + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); - - } - } - updateConfig(); - } - - /** - * This method enables a specific module. If no module with that name is known to the loader yet it will be added to the list.
- * This method is deprecated, use enableDynamicModule instead. When using this method, dynamic reloading of the module will not be supported. - * - * @param clazz The class of the module to be enabled. - * - * @return true, when the module was successfully enabled. - */ - @Deprecated - public static final boolean enableModule(Class clazz) { - for (Module module : modules.keySet()) { - if (module.getClass().equals(clazz)) { - if (modules.get(module)) { - instance.getLogger().info("Module was already enabled! Ignoring module.!"); - return true; - } - if (module.onEnable()) { - if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) - && (module instanceof Listener)) { - Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); - } - instance.getLogger().info("Enabled module " + module.getClass().getName()); - instance.getLogger().info("Loaded module " + module.getClass().getName()); - modules.put(module, true); - return true; - } else { - instance.getLogger().error("Failed to enable module " + module.getClass().getName()); - return false; - } - } - } - try { - Module m = clazz.newInstance(); - modules.put(m, false); - if (m.onEnable()) { - if (m.getClass().isAnnotationPresent(AutoRegisterListener.class) && (m instanceof Listener)) { - Bukkit.getPluginManager().registerEvents((Listener) m, Main.plugin); - } - instance.getLogger().info("Loaded and enabled module " + m.getClass().getName()); - instance.getLogger().info("Loaded module " + m.getClass().getName()); - return true; - } else { - instance.getLogger().error("Failed to enable module " + m.getClass().getName()); - return false; - } - } catch (InstantiationException | IllegalAccessException e) { - instance.getLogger() - .error("Could not add " + clazz.getName() + " to the list, constructor not accessible."); - return false; - } - } - - private static final void enableLoadedModule(Module module, Version oldVersion) { - try { - InputStream infoFile = null; - - if (VersionHelper.isCompatible(VersionHelper.create(5, 0, 0, 5), module.getClass())) { - String basePath = "plugins/ModuleLoader/classes/" + module.getClass().getName().replace(".", "/"); - - try { - infoFile = new FileInputStream( - new File(basePath.substring(0, basePath.lastIndexOf('/') + 1) + "module.info")); - } catch (Exception e) { - infoFile = null; - } - } - ModuleInfo info = new ModuleInfo(infoFile, module); - - moduleInfos.put(module, info); - - String category = info.getCategory(); - if (!categorizes.containsKey(category)) - categorizes.put(category, new ArrayList<>(Arrays.asList(module))); - else { - List modsInCat = categorizes.get(category); - modsInCat.add(module); - categorizes.put(category, modsInCat); - } - - loggers.put(module, new ModuleLogger(info.getDisplayName())); - - - if (module.onEnable()) { - modules.put(module, true); - if (VersionHelper.getString(oldVersion).equals("0.0.0.0")) - module.firstLoad(); - else if (!VersionHelper.getVersion(module.getClass()).equals(VersionHelper.getString(oldVersion))) - module.migrate(oldVersion); - if (VersionHelper.isCompatible(VersionHelper.create(5, 0, 0, 3), module.getClass())) - module.postEnable(); - if (VersionHelper.isCompatible(VersionHelper.create(5, 0, 0, 4), module.getClass())) { - Commands ann = module.getClass().getAnnotation(Commands.class); - if (ann != null) { - switch (ann.value()) { - case File: - File f = new File("plugins/ModuleLoader/classes/" - + module.getClass().getName().replace(".", "/") + ".cmd"); - CommandManager.registerCommand(f, module, Main.plugin); - break; - case Stream: - InputStream stream = module.getClass() - .getResourceAsStream(module.getClass().getSimpleName() + ".cmd"); - CommandManager.registerCommand(stream, module, Main.plugin); - case String: - CommandManager.registerCommand(module.getCommandString(), module, Main.plugin); - break; - case None: - break; - } - } - } - instance.getLogger().info("Loaded module " + module.getClass().getName()); - if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) && (module instanceof Listener)) - Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); - } else - instance.getLogger().error("Failed to load module " + module.getClass().getName()); - } catch (Exception e) { - instance.getLogger().error("Failed to load module " + module.getClass().getName()); - e.printStackTrace(); - } - } - - public static void disableModules() { - for (Module module : modules.keySet()) { - disableModule(module); - } - } - - public static void disableModule(Module module) { - if (modules.get(module)) { - module.onDisable(); - if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) && (module instanceof Listener)) { - HandlerList.unregisterAll((Listener) module); - } - CommandManager.unregisterAllWithFallback(module.getClass().getSimpleName()); - PrivateLogManager.unregister(module); - try { - URLClassLoader loader = loaders.get(module); - if (loader != null) - loader.close(); - } catch (IOException e) { - } finally { - loaders.remove(module); - } - } - } - - public static final boolean addDynamicModule(String raw_name) { - String[] raw = raw_name.split(" "); - String name = raw[0]; - Version oldVersion; - if (raw.length > 1) - oldVersion = VersionHelper.getVersion(raw[1]); - else - oldVersion = VersionHelper.create(0, 0, 0, 0); - for (Module m : modules.keySet()) { - if (m.getClass().getName().equals(name)) { - instance.getLogger().info( - "Found existing module, attempting override. WARNING! This operation will halt the main thread until it is completed."); - instance.getLogger() - .info("Attempting to load new class definition before disabling and removing the old module"); - boolean differs = false; - instance.getLogger().info("Old class definition: Class@" + m.getClass().hashCode()); - ClassLoader delegateParent = mainLoader.getParent(); - Class newClass = null; - URLClassLoader cl = new URLClassLoader(urls, delegateParent); - try { - newClass = cl.loadClass(m.getClass().getName()); - instance.getLogger().info("Found new class definition: Class@" + newClass.hashCode()); - differs = m.getClass() != newClass; - } catch (ClassNotFoundException e) { - instance.getLogger().error("Could not find a class definition, aborting now!"); - e.printStackTrace(); - try { - cl.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - return false; - } - if (!differs) { - if (!debugMode) { - instance.getLogger().warn( - "New class definition equals old definition, are you sure you did everything right?"); - instance.getLogger().info("Aborting now..."); - try { - cl.close(); - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } else - instance.getLogger().warn( - "New class definition equals old definition, but debugMode is enabled. Loading anyways."); - } else - instance.getLogger().info("Found new class definition, attempting to instantiate:"); - Module module = null; - try { - module = (Module) newClass.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - instance.getLogger().error("Could not instantiate the module, aborting!"); - e.printStackTrace(); - try { - cl.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - return false; - } - instance.getLogger().info("Instantiated new class definition, checking versions"); - oldVersion = m.getClass().getAnnotation(Version.class); - instance.getLogger().info("Current version: " + VersionHelper.getString(oldVersion)); - Version newVersion = module.getClass().getAnnotation(Version.class); - instance.getLogger().info("Version of remote class: " + VersionHelper.getString(newVersion)); - if (oldVersion.equals(newVersion)) { - if (!debugMode) { - instance.getLogger().error("Detected equal module versions, " + (debugMode - ? " aborting now... Set debugMode to true in your config if you want to continue!" - : " continueing anyways.")); - if (!debugMode) { - try { - cl.close(); - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - } else - instance.getLogger() - .warn("New version equals old version, but debugMode is enabled. Loading anyways."); - } else - instance.getLogger().info("Versions differ, disabling old module"); - disableModule(m); - instance.getLogger().info("Disabled module, overriding the implementation"); - modules.remove(m); - categorizes.get(moduleInfos.get(m).getCategory()).remove(m); - moduleInfos.remove(m); - - try { - if (loaders.containsKey(m)) - loaders.remove(m).close(); - } catch (IOException e) { - e.printStackTrace(); - } - modules.put(module, false); - loaders.put(module, cl); - instance.getLogger().info("Successfully updated class definition. Enabling new implementation:"); - enableLoadedModule(module, oldVersion); - return true; - } - } - ClassLoader delegateParent = mainLoader.getParent(); - URLClassLoader cl = new URLClassLoader(urls, delegateParent); - try { - Class clazz = cl.loadClass(name); - Module module = (Module) clazz.newInstance(); - modules.put(module, false); - loaders.put(module, cl); - enableLoadedModule(module, oldVersion); - return true; - } catch (NoClassDefFoundError | ClassNotFoundException | InstantiationException | IllegalAccessException e) { - try { - cl.close(); - } catch (IOException e1) { - } - if (e instanceof NoClassDefFoundError) { - NoClassDefFoundError exception = (NoClassDefFoundError) e; - String[] exMessage = exception.getMessage().split(" "); - String moduleName = exMessage[exMessage.length - 1] - .substring(0, exMessage[exMessage.length - 1].length() - - (exMessage[exMessage.length - 1].endsWith(")") ? 1 : 0)) - .replace("/", "."); - if (!moduleName.equalsIgnoreCase(name)) { - instance.getLogger() - .error("Class &e" + moduleName + "&r couldn't be found! Suspecting a missing dependency!"); - return false; - } else - instance.getLogger().warn( - "Couldn't find class definition, attempting to get proper classname from thrown Exception."); - if (addDynamicModule(moduleName)) - return true; - } - if (name.endsWith(".class")) { - instance.getLogger().warn( - "Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix."); - if (addDynamicModule(name.replaceAll(".class$", ""))) - return true; - } - if (!name.contains(".")) { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a package name and trying again."); - if (addDynamicModule(name.toLowerCase() + "." + name)) - return true; - } - if (!name.startsWith("com.redstoner.modules.") && name.contains(".")) { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of package name and trying again."); - if (addDynamicModule("com.redstoner.modules." + name)) - return true; - } - } - return false; - } - - public static final boolean removeDynamicModule(String name) { - for (Module m : modules.keySet()) { - if (m.getClass().getName().equals(name)) { - instance.getLogger().info( - "Found existing module, attempting unload. WARNING! This operation will halt the main thread until it is completed."); - instance.getLogger().info("Attempting to disable module properly:"); - disableModule(m); - modules.remove(m); - categorizes.get(moduleInfos.get(m).getCategory()).remove(m); - moduleInfos.remove(m); - instance.getLogger().info("Disabled module."); - return true; - } - } - if (!name.startsWith("com.redstoner.modules.")) { - if (name.endsWith(".class")) { - instance.getLogger().warn( - "Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix."); - if (removeDynamicModule(name.replaceAll(".class$", ""))) - return true; - } - if (!name.contains(".")) { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a package name and trying again."); - if (removeDynamicModule(name.toLowerCase() + "." + name)) - return true; - } - if (!name.startsWith("com.redstoner.modules.")) { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of package name and trying again."); - if (removeDynamicModule("com.redstoner.modules." + name)) - return true; - } - } - return false; - } - - /** - * Finds a module by name for other modules to reference it. - * - * @param name the name of the module. Use the full path if you are not sure about the module's SimpleClassName being unique. - * - * @return the instance of the module or @null it none could be found - */ - public static Module getModule(String name) { - for (Module m : modules.keySet()) { - if (m.getClass().getSimpleName().equalsIgnoreCase(name) || m.getClass().getName().equalsIgnoreCase(name)) - return m; - } - return null; - } - - /** - * Finds a module by name for other modules to reference it. - * - * @param name the name of the module. Use the full path if you are not sure about the module's SimpleClassName being unique. - * - * @return the instance of the module or @null it none could be found - */ - public static boolean exists(String name) { - for (Module m : modules.keySet()) { - if (m.getClass().getSimpleName().equals(name) || m.getClass().getName().equals(name)) - return true; - } - return false; - } - - public static ModuleLogger getModuleLogger(Module module) { - return loggers.get(module); - } - - public static void updateConfig() { - List coremods = config.getStringList("coremods"); - ArrayList new_coremods = new ArrayList<>(); - List autoload = config.getStringList("autoload"); - ArrayList new_autoload = new ArrayList<>(); - - for (String s : coremods) { - if (s.startsWith("#")) { - new_coremods.add(s); - } else { - s = s.split(" ")[0]; - try { - new_coremods.add(getModule(s).getClass().getName() + " " - + VersionHelper.getVersion(getModule(s).getClass())); - } catch (Exception e) { - new_coremods.add(s + " " + VersionHelper.getString(VersionHelper.create(0, 0, 0, 0))); - } - } - } - for (String s : autoload) { - if (s.startsWith("#")) { - new_autoload.add(s); - } else { - s = s.split(" ")[0]; - try { - new_autoload.add(getModule(s).getClass().getName() + " " - + VersionHelper.getVersion(getModule(s).getClass())); - } catch (Exception e) { - new_autoload.add(s + " " + VersionHelper.getString(VersionHelper.create(0, 0, 0, 0))); - } - } - } - - config.set("coremods", new_coremods); - config.set("autoload", new_autoload); - try { - config.save(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static JavaPlugin getPlugin() { - return Main.plugin; - } - - @Command (hook = "list", async = AsyncType.ALWAYS) - public boolean listModulesCommand(CommandSender sender) { - return listModules(sender, false); - } - - @Command (hook = "listversions", async = AsyncType.ALWAYS) - public boolean listModulesVerionsCommand(CommandSender sender) { - return listModules(sender, true); - } - - /** - * This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. - * - * @param sender The person to send the info to, usually the issuer of the command or the console sender. - * @param showVersions Should we show the versions directly in chat. - * - * @return true. - */ - public boolean listModules(CommandSender sender, boolean showVersions) { - boolean hasCategorys = hasCategories(); - Message m = new Message(sender, null); - ModuleInfo ml_info = moduleInfos.get(instance); - - m.appendText("§2--=[ ") - .appendTextHover("§2" + ml_info.getDisplayName(), ml_info.getModuleInfoHover()) - .appendText("§2 ]=--\nModules:\n"); - - for (String cat : categorizes.keySet()) { - if (hasCategorys) - m.appendText("\n&7" + cat + ":\n"); - - int curModule = 1; - List mods = categorizes.get(cat); - for (Module mod : mods) { - - ModuleInfo info = moduleInfos.get(mod); - m.appendTextHover((modules.get(mod) ? "§a" : "§c") + info.getDisplayName() + (showVersions ? " &e" + info.getVersion() : ""), info.getModuleInfoHover()); - - if (curModule != mods.size()) - m.appendText("&7, "); - curModule++; - } - m.appendText("\n"); - - } - m.send(); - return true; - } - - public static boolean hasCategories() { - return !(categorizes.size() == 1 && categorizes.containsKey("Other")); - } - - @Command (hook = "load") - public boolean loadModule(CommandSender sender, String name) { - if (!addDynamicModule(name)) { - instance.getLogger().message(sender, true, "Couldn't autocomplete path for module name: " + name - + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); - - } - updateConfig(); - return true; - } - - @Command (hook = "unload") - public boolean unloadModule(CommandSender sender, String name) { - if (!removeDynamicModule(name)) - instance.getLogger().error("Couldn't find module! Couldn't disable nonexisting module!"); - return true; - } -} diff --git a/src/main/java/com/redstoner/exceptions/MissingVersionException.java b/src/main/java/com/redstoner/exceptions/MissingVersionException.java deleted file mode 100644 index 3ea1f17..0000000 --- a/src/main/java/com/redstoner/exceptions/MissingVersionException.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.redstoner.exceptions; - -import com.redstoner.annotations.Version; - -/** - * To be thrown when a module is not annotated with its version. If this gets thrown, then oh boy, you're in trouble now. - * - * @author Pepich - */ -@Version (major = 1, minor = 0, revision = 0, compatible = -1) -public class MissingVersionException extends Exception { - private static final long serialVersionUID = 4940161335512222539L; - - public MissingVersionException() { - super(); - } - - public MissingVersionException(String message) { - super(message); - } -} diff --git a/src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java b/src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java deleted file mode 100644 index 926e9b2..0000000 --- a/src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.redstoner.exceptions; - -public class NonSaveableConfigException extends Exception { - private static final long serialVersionUID = -7271481973389455510L; - - public NonSaveableConfigException() { - super("This config does not support saving!"); - } -} diff --git a/src/main/java/com/redstoner/logging/Log4JFilter.java b/src/main/java/com/redstoner/logging/Log4JFilter.java deleted file mode 100644 index bdc94d4..0000000 --- a/src/main/java/com/redstoner/logging/Log4JFilter.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.redstoner.logging; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.Logger; -import org.apache.logging.log4j.core.filter.AbstractFilter; -import org.apache.logging.log4j.message.Message; - -public class Log4JFilter extends AbstractFilter { - - private static final long serialVersionUID = -5594073755007974254L; - - @Override - public Result filter(LogEvent event) { - Message candidate = null; - if (event != null) { - candidate = event.getMessage(); - } - return validateMessage(candidate); - } - - private static Result validateMessage(Message message) { - if (message == null) { - return Result.NEUTRAL; - } - return validateMessage(message.getFormattedMessage()); - } - - private static Result validateMessage(String message) { - return PrivateLogManager.isHidden(message) - ? Result.DENY - : Result.NEUTRAL; - } - - @Override - public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { - return validateMessage(msg); - } - - @Override - public Result filter(Logger logger, Level level, Marker marker, String msg, Object... params) { - return validateMessage(msg); - } - - @Override - public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { - String candidate = null; - if (msg != null) { - candidate = msg.toString(); - } - return validateMessage(candidate); - } -} \ No newline at end of file diff --git a/src/main/java/com/redstoner/logging/PrivateLogManager.java b/src/main/java/com/redstoner/logging/PrivateLogManager.java deleted file mode 100644 index ce6a68c..0000000 --- a/src/main/java/com/redstoner/logging/PrivateLogManager.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.redstoner.logging; - -import com.redstoner.misc.Utils; -import com.redstoner.modules.Module; -import com.redstoner.modules.ModuleLogger; -import org.apache.logging.log4j.LogManager; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -public class PrivateLogManager { - - private static final String ISSUED_COMMAND_TEXT = "issued server command: /"; - private static final int ISSUED_COMMAND_TEXT_LENGTH = ISSUED_COMMAND_TEXT.length(); - private static Map registrar = new HashMap<>(); - private static Map commands = new HashMap<>(); - private static ModuleLogger logger; - - public static void initialize() { - org.apache.logging.log4j.core.Logger logger; - logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); - logger.addFilter(new Log4JFilter()); - PrivateLogManager.logger = new ModuleLogger("PrivateLogManager"); - } - - public static void register(Module module, String command, String replacement) { - command = command.toLowerCase(); - registrar.put(command, module); - commands.put(command, replacement); - logger.info(module.getClass().getSimpleName() + " registered &e/" + command - + (replacement.equals("") ? "&7. Command will not be logged!" - : "&7, using replacement, &e" + replacement + "&7.")); - } - - public static void unregister(Module module) { - String unregestered = ""; - Iterator> i = registrar.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry entry = i.next(); - if (entry.getValue() == module) { - i.remove(); - commands.remove(entry.getKey()); - unregestered += "&e" + entry.getKey() + "&7, "; - } - } - if (!unregestered.equals("")) - logger.info("Unregistered " + unregestered.substring(0, unregestered.length() - 2) + "&7 for module, " + module.getClass().getSimpleName() + "."); - } - - public static void unregister(Module module, String... toRemove) { - String unregestered = ""; - for (int i = 0; i < toRemove.length; i++) { - String command = toRemove[i].toLowerCase(); - registrar.remove(command); - if (commands.remove(command) != null) - unregestered += "&e" + command + "&7, "; - } - if (!unregestered.equals("")) - logger.info(module.getClass().getSimpleName() + " unregistered " + unregestered.substring(0, unregestered.length() - 2) + "&7."); - } - - public static boolean isHidden(String message) { - if (message == null) - return false; - - int index = message.indexOf(ISSUED_COMMAND_TEXT); - if (index == -1) - return false; - - String command = message.substring(index + ISSUED_COMMAND_TEXT_LENGTH); - - int spaceIndex = command.indexOf(" "); - command = spaceIndex == -1 ? command.toLowerCase() : command.substring(0, spaceIndex).toLowerCase(); - - String replacement = commands.get(command); - if (replacement == null) - return false; - if (replacement.equals("")) - return true; - - String player = message.substring(0, message.indexOf(" ")); - Utils.run(() -> System.out.println(replacement.replace("$s", player))); - return true; - } -} diff --git a/src/main/java/com/redstoner/misc/BroadcastFilter.java b/src/main/java/com/redstoner/misc/BroadcastFilter.java deleted file mode 100644 index a0098b6..0000000 --- a/src/main/java/com/redstoner/misc/BroadcastFilter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; -import org.bukkit.command.CommandSender; - -/** - * Classes implementing this interface can be used to define a filter for the Utils.broadcast method for sending a message to more than one, but less than all users. - * - * @author Pepich - */ -@Version (major = 1, minor = 0, revision = 0, compatible = 1) -public interface BroadcastFilter { - public boolean sendTo(CommandSender recipient); -} diff --git a/src/main/java/com/redstoner/misc/CommandHolderType.java b/src/main/java/com/redstoner/misc/CommandHolderType.java deleted file mode 100644 index 3c64127..0000000 --- a/src/main/java/com/redstoner/misc/CommandHolderType.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; - -/** @author Pepich */ -@Version (major = 4, minor = 0, revision = 0, compatible = -1) -public enum CommandHolderType { - Stream, - File, - String, - None -} diff --git a/src/main/java/com/redstoner/misc/JsonManager.java b/src/main/java/com/redstoner/misc/JsonManager.java deleted file mode 100644 index 498933f..0000000 --- a/src/main/java/com/redstoner/misc/JsonManager.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -/** - * This class provides simple JSON handling, like storing and loading from and to files. - * - * @author Pepich - */ -@Version (major = 1, minor = 0, revision = 2, compatible = -1) -public class JsonManager { - private JsonManager() {} - - /** - * Loads a JSONObject from a file. - * - * @param source the file to load from. - * - * @return the JSONObject or null if the source does not contain a valid JSONObject. - */ - public static JSONObject getObject(File source) { - if (!source.exists()) - return null; - JSONParser parser = new JSONParser(); - try { - FileReader reader = new FileReader(source); - Object rawObject = parser.parse(reader); - reader.close(); - JSONObject jsonObject = (JSONObject) rawObject; - return jsonObject; - } catch (IOException | ParseException e) { - } - return null; - } - - /** - * Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on a different thread and you do not need to take care of that yourself. - * - * @param object the JSONObject to save. - * @param destination the file to write to. - */ - public static void save(JSONObject object, File destination) { - Thread t = new Thread(new Runnable() { - @Override - public void run() { - saveSync(object, destination); - } - }); - t.start(); - } - - /** - * Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on the same thread that you are calling it from! - * - * @param object the JSONObject to save. - * @param destination the file to write to. - */ - public static void saveSync(JSONObject object, File destination) { - if (destination.exists()) - destination.delete(); - else if (!destination.getParentFile().exists()) - destination.getParentFile().mkdirs(); - try { - destination.createNewFile(); - FileWriter writer = new FileWriter(destination); - String json_string = object.toJSONString(); - writer.write(json_string); - writer.flush(); - writer.close(); - } catch (IOException e) { - } - } - - /** - * Loads a JSONArray from a file. - * - * @param source the file to load from. - * - * @return the JSONArray or null if the source does not contain a valid JSONArray. - */ - public static JSONArray getArray(File source) { - if (!source.exists()) - return null; - JSONParser parser = new JSONParser(); - try { - Object rawObject = parser.parse(new FileReader(source)); - JSONArray jsonArray = (JSONArray) rawObject; - return jsonArray; - } catch (IOException | ParseException e) { - } - return null; - } - - /** - * Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on a different thread and you do not need to take care of that yourself. - * - * @param object the JSONArray to save. - * @param destination the file to write to. - */ - public static void save(JSONArray array, File destination) { - Thread t = new Thread(new Runnable() { - @Override - public void run() { - saveSync(array, destination); - } - }); - t.start(); - } - - /** - * Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on the same thread that you are calling it from! - * - * @param object the JSONArray to save. - * @param destination the file to write to. - */ - public static void saveSync(JSONArray array, File destination) { - if (destination.exists()) - destination.delete(); - else if (!destination.getParentFile().exists()) - destination.getParentFile().mkdirs(); - try { - destination.createNewFile(); - FileWriter writer = new FileWriter(destination); - String json_string = array.toJSONString(); - writer.write(json_string); - writer.flush(); - writer.close(); - } catch (IOException e) { - } - } -} diff --git a/src/main/java/com/redstoner/misc/Main.java b/src/main/java/com/redstoner/misc/Main.java deleted file mode 100644 index e6de0d0..0000000 --- a/src/main/java/com/redstoner/misc/Main.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; -import com.redstoner.coremods.moduleLoader.ModuleLoader; -import com.redstoner.logging.PrivateLogManager; -import com.redstoner.misc.mysql.MysqlHandler; -import net.nemez.chatapi.ChatAPI; -import org.bukkit.plugin.java.JavaPlugin; - -/** - * Main class. Duh. - * - * @author Pepich - */ -@Version (major = 5, minor = 1, revision = 0, compatible = -1) -public class Main extends JavaPlugin { - public static JavaPlugin plugin; - - @Override - public void onEnable() { - plugin = this; - - PrivateLogManager.initialize(); - - ChatAPI.initialize(this); - // Configger.init(); - MysqlHandler.init(); - ModuleLoader.init(); - // Load modules from config - ModuleLoader.loadFromConfig(); - } - - @Override - public void onDisable() { - ModuleLoader.disableModules(); - } -} diff --git a/src/main/java/com/redstoner/misc/ModuleInfo.java b/src/main/java/com/redstoner/misc/ModuleInfo.java deleted file mode 100644 index 0b670b9..0000000 --- a/src/main/java/com/redstoner/misc/ModuleInfo.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.coremods.moduleLoader.ModuleLoader; -import com.redstoner.exceptions.MissingVersionException; -import com.redstoner.modules.Module; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.InputStream; -import java.io.InputStreamReader; - -public class ModuleInfo { - - private String simpleName; - private String displayName; - private String category; - private String description; - private String version; - - private String warning; - - public ModuleInfo(InputStream descriptor, Module module) { - try { - InputStreamReader reader = new InputStreamReader(descriptor); - FileConfiguration config = YamlConfiguration.loadConfiguration(reader); - - displayName = config.getString("displayName"); - category = config.getString("category"); - description = config.getString("description"); - } catch (Exception e) { - warning = "Descriptor file could not be loaded, using the class's name."; - } - - simpleName = module.getClass().getSimpleName(); - - if (displayName == null) - displayName = simpleName; - - if (category == null) - category = "Other"; - - try { - version = VersionHelper.getVersion(module.getClass()); - } catch (MissingVersionException e) {} - } - - public String getDisplayName() { - return displayName; - } - - public String getWarning() { - return warning; - } - - public String getModuleInfoHover() { - return "&8&o" + getSimpleName() + "\n" - + "&r&e" + (getVersion() == null ? "&cVersion Missing" : getVersion()) - + "&r&9" + (ModuleLoader.hasCategories() ? "\n" + getCategory() : "") - + "&r&7" + (getDescription() == null ? "" : "\n\n" + getDescription()); - } - - public String getSimpleName() { - return simpleName; - } - - public String getVersion() { - return version; - } - - public String getCategory() { - return category; - } - - public String getDescription() { - return description; - } - - -} diff --git a/src/main/java/com/redstoner/misc/Utils.java b/src/main/java/com/redstoner/misc/Utils.java deleted file mode 100644 index d53a39e..0000000 --- a/src/main/java/com/redstoner/misc/Utils.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; -import com.redstoner.coremods.moduleLoader.ModuleLoader; -import net.nemez.chatapi.ChatAPI; -import net.nemez.chatapi.click.Message; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.regex.Pattern; - -/** - * The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more. - * - * @author Pepich - */ -@Version (major = 4, minor = 0, revision = 2, compatible = 1) -public final class Utils { - /** The Pattern for a UUID */ - private static final Pattern UUID_pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"); - private static final Pattern Class_pattern = Pattern.compile(".*\\."); - private static final Pattern NoDolarSign_pattern = Pattern.compile("\\$\\d*"); - /** The @SimpleDateFormat used for getting the current date. */ - public static SimpleDateFormat dateFormat = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]"); - - /** Hidden constructor. Do not instantiate UTILS classes! :) */ - private Utils() {} - - /** - * This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
- * If you want to, you can set a message that will be logged to console. Set to null to not log anything.
- * You can still allow console in the filter to log the original message. - * - * @param prefix The prefix for the message. Set to NULL to let it auto generate. - * @param message the message to be sent around - * @param filter the BroadcastFilter to be applied.
- * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. - * @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter). - * - * @return the amount of people that received the message. - */ - public static int broadcast(String prefix, String message, BroadcastFilter filter) { - if (prefix == null) - prefix = "§8[§2" + getCaller() + "§8]: "; - if (filter == null) { - for (Player p : Bukkit.getOnlinePlayers()) { p.sendMessage(prefix + message); } - Bukkit.getConsoleSender().sendMessage(prefix + message); - return Bukkit.getOnlinePlayers().size() + 1; - } else { - int count = 0; - for (Player p : Bukkit.getOnlinePlayers()) { - if (filter.sendTo(p)) { - p.sendMessage(prefix + message); - count++; - } - } - if (filter.sendTo(Bukkit.getConsoleSender())) { - Bukkit.getConsoleSender().sendMessage(prefix + message); - count++; - } - return count; - } - } - - /** - * This method will find the next parent caller and return their class name, omitting package names. - * - * @return the Name of the calling class. - */ - private static final String getCaller() { - StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); - String classname = "Utils"; - for (int i = 0; classname.equals("Utils"); i++) { - classname = Class_pattern.matcher(stackTrace[i].getClassName()).replaceAll(""); - } - return classname; - } - - /** - * This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
- * If you want to, you can set a message that will be logged to console. Set to null to not log anything.
- * You can still allow console in the filter to log the original message. - * - * @param prefix The prefix for the message. Set to NULL to let it auto generate. - * @param message the message to be sent around - * @param filter the BroadcastFilter to be applied.
- * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. - * @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter). - */ - public static int broadcast(String prefix, Message message, BroadcastFilter filter) { - if (prefix == null) - prefix = "§8[§2" + getCaller() + "§8]: "; - if (filter == null) { - for (Player p : Bukkit.getOnlinePlayers()) { ChatAPI.createMessage(p).appendText(prefix).appendMessage(message).send(); } - Bukkit.getConsoleSender().sendMessage(prefix + message.getRawMessage()); - return Bukkit.getOnlinePlayers().size() + 1; - } else { - int count = 0; - for (Player p : Bukkit.getOnlinePlayers()) { - if (filter.sendTo(p)) { - ChatAPI.createMessage(p).appendText(prefix).appendMessage(message).send(); - count++; - } - } - if (filter.sendTo(Bukkit.getConsoleSender())) { - Bukkit.getConsoleSender().sendMessage(prefix + message.getRawMessage()); - count++; - } - return count; - } - } - - /** - * This method will find the next parent caller and return their class name, omitting package names. - * - * @param directCaller used to prevent this method from returning the caller itself. Null if supposed to be ignored. - * - * @return the name of the calling class. - */ - public static final String getCaller(String... directCaller) { - if (directCaller == null || directCaller.length == 0) - return getCaller(); - StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); - String classname = "Utils"; - List callers = Arrays.asList(directCaller); - for (int i = 0; callers.contains(classname) || classname.equals("Utils"); i++) { - classname = Class_pattern.matcher(stackTrace[i].getClassName()).replaceAll(""); - } - classname = NoDolarSign_pattern.matcher(classname).replaceAll(""); - return classname; - } - - /** - * Provides a uniform way of getting the date for all modules. - * - * @return The current date in the format "[dd-mm-yyyy hh:mm:ss]" - */ - public static String getDate() { - Date date = new Date(System.currentTimeMillis()); - return dateFormat.format(date); - } - - /** - * Provides a uniform way of getting the (display)name of a @CommandSender. - * - * @param sender The @CommandSender to get the name of. - * - * @return The DisplayName of the @CommandSender or if not a @Player, the name in blue. - */ - public static String getName(CommandSender sender) { - if (sender instanceof Player) - return ((Player) sender).getDisplayName(); - else - return "§9" + sender.getName(); - } - - /** - * Provides a uniform way of getting the UUID of a @CommandSender. - * - * @param sender The @CommandSender to get the UUID of. - * - * @return The UUID of the @CommandSender or if not a player, "CONSOLE" in blue. - */ - public static String getID(CommandSender sender) { - String id; - if (sender instanceof Player) - id = ((Player) sender).getUniqueId().toString(); - else - id = "CONSOLE"; - return id; - } - - /** - * Checks if the string is a UUID. - * - * @param toCheck String to check. - * - * @return if the string is a UUID. - */ - public static boolean isUUID(String toCheck) { - return UUID_pattern.matcher(toCheck).matches(); - } - - public static void run(Runnable r) { - run(r, 0); - } - - public static void run(Runnable r, int delay) { - Bukkit.getScheduler().scheduleSyncDelayedTask(ModuleLoader.getPlugin(), r, delay); - } - - -} diff --git a/src/main/java/com/redstoner/misc/VersionHelper.java b/src/main/java/com/redstoner/misc/VersionHelper.java deleted file mode 100644 index 6cfc872..0000000 --- a/src/main/java/com/redstoner/misc/VersionHelper.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; -import com.redstoner.exceptions.MissingVersionException; - -import java.lang.annotation.Annotation; - -/** - * This class can be used to compare modules against the loader version or against each other to prevent dependency issues. - * - * @author Pepich - */ -@Version (major = 2, minor = 1, revision = 3, compatible = 0) -public final class VersionHelper { - private VersionHelper() {} - - /** - * Checks two classes versions for compatibility. - * - * @param base The API to compare to. - * @param module The module to compare. - * - * @return true, when the module is up to date with the API, or the API supports outdated modules. - * - * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. - */ - public static boolean isCompatible(Class api, Class module) throws MissingVersionException { - if (!api.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The API is not annotated with a version."); - if (!module.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The module is not annotated with a version."); - Version apiVersion = api.getAnnotation(Version.class); - Version moduleVersion = module.getAnnotation(Version.class); - return isCompatible(apiVersion, moduleVersion); - } - - /** - * Checks two versions for compatibility. - * - * @param base The API version to compare to. - * @param module The module version to compare. - * - * @return true, when the module is up to date with the API, or the API supports outdated modules. - */ - public static boolean isCompatible(Version apiVersion, Version moduleVersion) { - if (apiVersion.major() >= moduleVersion.compatible()) - return true; - if (apiVersion.compatible() == -1) - return false; - if (apiVersion.compatible() <= moduleVersion.major()) - return true; - return false; - } - - /** - * Checks two classes versions for compatibility. - * - * @param base The API to compare to. - * @param module The module to compare. - * - * @return true, when the module is up to date with the API, or the API supports outdated modules. - * - * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. - */ - public static boolean isCompatible(Version apiVersion, Class module) throws MissingVersionException { - if (!module.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The module is not annotated with a version."); - Version moduleVersion = module.getAnnotation(Version.class); - return isCompatible(apiVersion, moduleVersion); - } - - /** - * Checks two classes versions for compatibility. - * - * @param base The API to compare to. - * @param module The module to compare. - * - * @return true, when the module is up to date with the API, or the API supports outdated modules. - * - * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. - */ - public static boolean isCompatible(Class api, Version moduleVersion) throws MissingVersionException { - if (!api.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The API is not annotated with a version."); - Version apiVersion = api.getAnnotation(Version.class); - return isCompatible(apiVersion, moduleVersion); - } - - /** - * Returns the version of a given class as a String. - * - * @param clazz The class to grab the version number from. - * - * @return The version number of the class in format major.minor.revision.compatible. - * - * @throws MissingVersionException If the class is not annotated with @Version. - */ - public static String getVersion(Class clazz) throws MissingVersionException { - if (!clazz.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The given class is not associated with a version."); - Version ver = clazz.getAnnotation(Version.class); - return getString(ver); - } - - /** - * Returns the String representation of a version. - * - * @param ver The version to be represented. - * - * @return The String representation. - */ - public static String getString(Version ver) { - return ver.major() + "." + ver.minor() + "." + ver.revision() + "." + ver.compatible(); - } - - public static Version getVersion(String ver) { - String[] raw = ver.split("\\."); - if (raw.length != 4) - return null; - return VersionHelper.create(Integer.parseInt(raw[0]), Integer.parseInt(raw[1]), Integer.parseInt(raw[2]), - Integer.parseInt(raw[3]) - ); - } - - /** - * This method creates a new Version to use for compatibility checks. - * - * @param major The major version - * @param minor The minor version - * @param revision The revision - * @param compatible The compatibility tag - * - * @return - */ - public static Version create(int major, int minor, int revision, int compatible) { - return new Version() { - @Override - public Class annotationType() { - return Version.class; - } - - @Override - public int revision() { - return revision; - } - - @Override - public int minor() { - return minor; - } - - @Override - public int major() { - return major; - } - - @Override - public int compatible() { - return compatible; - } - }; - } -} diff --git a/src/main/java/com/redstoner/modules/CoreModule.java b/src/main/java/com/redstoner/modules/CoreModule.java deleted file mode 100644 index 77ca178..0000000 --- a/src/main/java/com/redstoner/modules/CoreModule.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.redstoner.modules; - -import com.redstoner.annotations.Version; - -/** - * This class shall be used for "CoreModules", which are acting on a lower level than modules and are also exempted from being disabled or reloaded on the go.
- * Please note that CoreModules will not be known to the ModuleLoader itself!
- * Examples are the ModuleLoader and the Debugger. - * - * @author Pepich - */ -@Version (major = 2, minor = 0, revision = 0, compatible = -1) -public interface CoreModule extends Module { - /** Core modules don't need to be enabled. */ - @Override - public default boolean onEnable() { - return true; - } - - /** Core modules don't need to be disabled. */ - @Override - public default void onDisable() {} -} diff --git a/src/main/java/com/redstoner/modules/Module.java b/src/main/java/com/redstoner/modules/Module.java deleted file mode 100644 index 67c1063..0000000 --- a/src/main/java/com/redstoner/modules/Module.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.redstoner.modules; - -import com.redstoner.annotations.Version; -import com.redstoner.coremods.moduleLoader.ModuleLoader; - -/** - * Interface for the Module class. Modules must always have an empty constructor to be invoked by the ModuleLoader. - * - * @author Pepich - */ -@Version (major = 4, minor = 0, revision = 0, compatible = 0) -public interface Module { - /** Will be called when the module gets enabled. */ - public default boolean onEnable() { - return true; - } - - /** - * This methods gets called after all modules were enabled, please use this method to register commands and similar.
- * It will only get called if and only if the module was successfully enabled. - */ - public default void postEnable() {} - - /** Will be called when the module gets disabled. */ - public default void onDisable() {} - - /** - * Gets called on registration of the module, when this option is selected for command registration - * - * @return The String used for the CommandManager to register the commands. - */ - public default String getCommandString() { - return null; - } - - /** This method gets run the very first time a module gets loaded. You can use this to set up file structures or background data. */ - public default void firstLoad() {} - - /** - * This method gets run every time a module gets loaded and its version has changed. - * - * @param old The version of the previous module. - */ - public default void migrate(Version old) {} - - default void setPrefix(final String name) { - getLogger().setName(name); - } - - public default ModuleLogger getLogger() { - return ModuleLoader.getModuleLogger(this); - } -} diff --git a/src/main/java/com/redstoner/modules/ModuleLogger.java b/src/main/java/com/redstoner/modules/ModuleLogger.java deleted file mode 100644 index b68343b..0000000 --- a/src/main/java/com/redstoner/modules/ModuleLogger.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.redstoner.modules; - -import com.redstoner.annotations.Version; -import net.nemez.chatapi.ChatAPI; -import net.nemez.chatapi.click.Message; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; - -@Version (major = 4, minor = 0, revision = 0, compatible = -1) -public class ModuleLogger { - public static final String PREFIX_WARN = "§8[§eWARN§8]:§7 "; - public static final String PREFIX_ERROR = "§8[§cERROR§8]:§7 "; - public static final String PREFIX_INFO = "§8[§fINFO§8]:§7 "; - - private String name; - - public ModuleLogger(final String name) { - this.name = name; - } - - public void info(final String message) { - Bukkit.getConsoleSender().sendMessage(PREFIX_INFO + getPrefix() + ChatAPI.colorify(null, message)); - } - - public String getPrefix() { - return getPrefix(false); - } - - public String getPrefix(final boolean error) { - return "§8[§" + (error ? 'c' : '2') + name + "§8]§7 "; - } - - public void warn(final String message) { - Bukkit.getConsoleSender().sendMessage(PREFIX_WARN + getPrefix() + ChatAPI.colorify(null, message)); - } - - public void error(final String message) { - Bukkit.getConsoleSender().sendMessage(PREFIX_ERROR + getPrefix() + ChatAPI.colorify(null, message)); - } - - public void message(final CommandSender recipient, final String... message) { - message(recipient, false, message); - } - - public void message(final CommandSender recipient, final boolean error, final String... message) { - Message m = new Message(recipient, null); - if (message.length == 1) - m.appendText(getPrefix(error) + message[0]); - else { - m.appendText(getHeader()); - m.appendText("&7" + String.join("\n&7", message)); - } - m.send(); - } - - public String getHeader() { - return "§2--=[ " + name + " ]=--\n"; - } - - protected final void setName(final String name) { - this.name = name; - } -} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml deleted file mode 100644 index fc576a8..0000000 --- a/src/main/resources/plugin.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: ModuleLoader -version: 5.2.2 -authors: [pepich1851, psrcek, LogalDeveloper, Minenash] -main: com.redstoner.misc.Main -softdepend: [Vault]