From 8a6943f6880cdaf7870191b130afab8b541de6a1 Mon Sep 17 00:00:00 2001 From: TheTrouper <93684527+thetrouper@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:08:12 -0600 Subject: [PATCH] Plugin is litteraly just Sentinel's Core --- README.md | 26 +- build.gradle | 68 +++++ build.sh | 48 ++++ gradle.properties | 8 + gradlew | 248 +++++++++++++++++ gradlew.bat | 92 ++++++ libs/JDWebHooks-1.0.1.jar | Bin 0 -> 31281 bytes libs/PDK-1.3.4.jar | Bin 0 -> 89914 bytes settings.gradle | 1 + .../github/thetrouper/sssbliss/SSSBliss.java | 139 +++++++++ .../sssbliss/cmds/ChatClickCallback.java | 30 ++ .../sssbliss/cmds/SSSBlissCommand.java | 68 +++++ .../thetrouper/sssbliss/data/Emojis.java | 33 +++ .../sssbliss/data/config/LanguageFile.java | 63 +++++ .../sssbliss/data/config/MainConfig.java | 104 +++++++ .../sssbliss/events/CMDBlockExecute.java | 7 + .../sssbliss/server/sound/SoundPlayer.java | 263 ++++++++++++++++++ .../sssbliss/server/util/CipherUtils.java | 35 +++ .../sssbliss/server/util/FileUtils.java | 95 +++++++ .../server/util/FileValidationUtils.java | 20 ++ .../sssbliss/server/util/GPTUtils.java | 68 +++++ .../sssbliss/server/util/MathUtils.java | 58 ++++ .../sssbliss/server/util/Randomizer.java | 78 ++++++ .../sssbliss/server/util/ServerUtils.java | 105 +++++++ .../thetrouper/sssbliss/server/util/Text.java | 49 ++++ src/main/resources/config.yml | 111 ++++++++ src/main/resources/false-positives.yml | 55 ++++ src/main/resources/lang/en-us.json | 38 +++ src/main/resources/nbt-config.yml | 57 ++++ src/main/resources/plugin.yml | 96 +++++++ src/main/resources/strict.yml | 9 + src/main/resources/swears.yml | 79 ++++++ 32 files changed, 2150 insertions(+), 1 deletion(-) create mode 100644 build.gradle create mode 100644 build.sh create mode 100644 gradle.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 libs/JDWebHooks-1.0.1.jar create mode 100644 libs/PDK-1.3.4.jar create mode 100644 settings.gradle create mode 100644 src/main/java/io/github/thetrouper/sssbliss/SSSBliss.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/cmds/ChatClickCallback.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/cmds/SSSBlissCommand.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/data/Emojis.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/data/config/LanguageFile.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/data/config/MainConfig.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/events/CMDBlockExecute.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/sound/SoundPlayer.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/CipherUtils.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/FileUtils.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/FileValidationUtils.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/GPTUtils.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/MathUtils.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/Randomizer.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/ServerUtils.java create mode 100644 src/main/java/io/github/thetrouper/sssbliss/server/util/Text.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/false-positives.yml create mode 100644 src/main/resources/lang/en-us.json create mode 100644 src/main/resources/nbt-config.yml create mode 100644 src/main/resources/plugin.yml create mode 100644 src/main/resources/strict.yml create mode 100644 src/main/resources/swears.yml diff --git a/README.md b/README.md index 1cda64c..6f86c24 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ # SSSBliss -The "Bliss SMP" plugin described by Madness4Ever +Advanced Anti-Grief & Chat Filter +----------------------------------------------------- + +- Control access to dangerous commands +- Deny command blocks & minecart commands +- Prevent Malicious NBT +- Most Advanced Profanity Filter +- Advanced Anti-Spam +- Auto-punish system +- Webhook logging +- Quality Customer Supourt + +----------------------------------------------------- + +## How to use + +1. Download the plugin on spigot +2. Upload it to your /plugins/ folder +3. Use plugman to `/plugman load sssbliss` or restart your server +4. Open a ticket and send your server ID +5. Wait for a response from staff saying your license is verified +6. Use plugman to `/plugman load sssbliss` or restart your server +7. Configure sssbliss in /plugins/SSSBliss/config.yml + +----------------------------------------------------- diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..5592830 --- /dev/null +++ b/build.gradle @@ -0,0 +1,68 @@ +plugins { + id 'java' +} + +group = project.group +version = project.version + +jar { + from { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + configurations.runtimeClasspath.collect { + it.isDirectory() ? it : zipTree(it) + } + } +} + +repositories { + mavenCentral() + maven { + name = 'spigotmc-repo' + url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' + } + maven { + url = uri("https://repo.papermc.io/repository/maven-public/") + } + maven { + name = 'sonatype' + url = 'https://oss.sonatype.org/content/groups/public/' + } +} + +dependencies { + compileOnly 'io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT' + implementation 'com.google.code.gson:gson:2.10.1' + implementation files("libs/PDK-1.3.4.jar") +} + +def targetJavaVersion = 17 +java { + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + sourceCompatibility = javaVersion + targetCompatibility = javaVersion + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + if (JavaVersion.current() < javaVersion) { + toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) + } +} + +tasks.withType(JavaCompile).configureEach { + if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { + options.release = targetJavaVersion + } +} + +processResources { + def props = [version: version] + inputs.properties props + filteringCharset 'UTF-8' + filesMatching('plugin.yml') { + expand props + } +} + +compileJava.options.encoding("UTF-8") + +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +} \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..bec3843 --- /dev/null +++ b/build.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Run Gradle build +./gradlew build + +# Check if the build was successful +if [ $? -eq 0 ]; then + echo "Gradle build successful." + + # SFTP upload + SFTP_HOST="192.168.1.199" + SFTP_USER="trouper" + SFTP_PASSWORD="Trouper12()1" + SFTP_REMOTE_DIR="/home/trouper/docker/data/plugins/" + + # Create a temporary file with a unique name + TEMP_FILE=$(mktemp) + + # Specify the local file to upload + LOCAL_FILE="/run/media/trouper/'1TB drive'/IJ/IdeaProjects/SSSBliss/build/libs/SSSBliss-0.2.4.jar" + + # Write the SFTP commands to the temporary file + echo "put $LOCAL_FILE $SFTP_REMOTE_DIR" > "$TEMP_FILE" + echo "bye" >> "$TEMP_FILE" + + # Use sftp non-interactively with the specified commands + sftp -oStrictHostKeyChecking=no -oBatchMode=no -b "$TEMP_FILE" "$SFTP_USER@$SFTP_HOST" < '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + 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 +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 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! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/libs/JDWebHooks-1.0.1.jar b/libs/JDWebHooks-1.0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..b3a94cb19463410bc2326c32a28c8fbf4d63ad8a GIT binary patch literal 31281 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 $$NX$*d| zL0(xL$otNd0;W+x2PHMMR80-A!KI~0ajXyLw=%^YQ!YBFYMjxjia+JJzNZGuMp#+y zfd8V;Eh69jf;134JfLm{GNaDf`2D<(2cYb~=rElQZdwwxUyd1!A=JUPBq zFa?EFuV{v97*e=aA6+Tjt#8SSOIyZimQh4}fkScKr3D&Xz%!0lH}y1_1nZt!FBrg9 zjvKIH4N{>!HPP9gDPq#HC5CZXYs$iUGr~Aiti>}t0|_3{nHoWH9p1HsO0O{Dg3}Y| z{A$FE@|@4on?=y)yo3CRhVGiteQ4)f(6_+)MHpOBkCiV zM|T5}rDKIE{qA0M7makG$$r$dSI2h@TD6`M$tgkNY9XGdkh3=0qpVw~Kx@{GLXat_ z@C{|3*$-YcD<%by-((xJZ_o&Cr#l5)OSUFM1+g;WmV2n9w?WfD+nbw(D$uGjo7pXVOsG{&d|`{&Z;%ZEC_VrGJ}s(N{4C)mg- zTJ0XF(6)Y5c;c*BgRVCMsa3;2c)#_4w`bSJznUG*aIJ81JHRb3+s$uq&Tt(MXVD)2 zBI|-$3&U&6iGM*TMMe7<=6!2`ulBfttxf2-)Cs7pGAJ)!p{&g=a>DZQ&#sc~g)72; zm_! zkGCw@0oSuU^9lo{&{QeX)PXman%m72V1&c$<-x65xNN+&`P<(^4+r97nvODM- zef*Bl-)uT!jxdT)U#?s`db;4YQ+#aQ)9Dm$Rrd!Fv~uHe{6qa){1I|zG{1l_7zUUq z%3aJG+UzGn8A`WH`7xW@C<|(i17EkZ?qNbj?{CC6=f{`tA3wK#NZ-{@Z5e=_6mUXLh&7umI$eQmwv}@bej9~RENvgG)vYV-|nM&6U;-=L_0dlK}NLo zBHNG{7}&D}5Nf(AidauNhmK{Ii^C8WDKlX6zAVUR0IsYHA0qw={m)y=#F)~B{W|T4 zul4iaytV&w;tt08PXBV`UkqD*m~;FK;Hr_u1aO{X{v+D!pJH-|d10g*rYUWx$#7{W zvD>nH+wfl`6jKHtt@GS!bDh_hmycR+kY8BGg)?$?(kdy$bOg)9)%&U$7@VEyGApIsDm2b=E?2ks}#CtOT-ns$7HIfeOK4VSCQ(Z|K*)P|?&QME7L8=M}94H!Kf zFJBq6Qocw|mndJ6s6ty(A{!3sqBonF zOj&PM)0q@AiR3DC%!yTU=1z>Hs8%VX7A#XEbABo>agVAKViw>jGIK|j0{g66NTyxu z_$|pPR&c{P8B1<3SWBj*Rq1~>fdYMTns*omTZ+bDgzz(E=8jMY-VLzJnD()iqY*c7~upApq8VE)@0FBq8jFR(G zE2dWmm6&N*M0oDe%fa9^XUNm1NS-xdHRh_4QOTiInc21)v2f}E?CZfn+^p%o5h~yCkEeg()u8qg2M5@8XdRr;cM`DGR!Zu3d zNSb08TnaQ0ysc_=kb-Hu2Z9UZqJ#^U1iQU?$$pVfTSAf?8&#U7;M|>hv(m=^Gd@vM4hdEb?8INf(!Nb-?&OliNF9>yx^Id)sGQP-!ju zi%;U4WNH~Jm;Oki$%5#^~Q4ncmIML+kc(OESz!|^0_0ho46jL=ie9D^SV?D1}Dl^ZZaXQ@m- z?v{2;#NAH3f9jvg7-)jRloPt@sk=u#NVR}FYw{Iie{BpPDcW>UPq1pZVJjEN6&8PO zJfJg{i%igr7{Pu&8fu_+{+bLT{~(l=Q#V8Q8gml8W{8JL2tCFoVsu+|+!bXJ5tQ}h z;EdD_x$ZxjQfhbLZxNqD&QC5+Xw>E{F-Z}=g5~hwE84W}5gk2 zcs1C3l;8EyxTbT!LKX!i#YIzgmj%#F5y@m)q4xY~y90-9(T2Sk1N&ejaOnfDsG3l@ ztK`-AC^Q{6+}$-bwvrE55$Wv)`lT7Y3hxg?R_tS=7jH`Un518*aSoU=ru#h2Vpx6; z--4$@n~+f`^5r8mrvY5UQQKFUevb^w#va062pa?a)u5;>vsY$n{(~s_&#pLZ@5Z|e83F%*GE%9sd z{I3(5xQ)v{v0AMR@RwjL!VNrB!qV6EdEV%gyh-Pp?p$n*@2~ce=IOwE!l6M zo!vI&(Qk@TCk9G3S+N1^J9MMU969ZQV%JO%nix$CEJ{+({qw?7;e?=aT#85Ks^so> ztIoJpx^yEuwOm6=|8S1Ud0G4iK1GA z;Mx!p*k>c$YR>QNk!wRts$=#FUjL=QRpoB+JMzny-U8>_H>UsXdH;=w2h}09ke4w& z`A}U}Hi1wFK=?^Q+o+E%qR7OMkvB*50}WUv8L0ai>&~oPOr^!w?^0M70S~+luJa4H z=H;X%W*I|GYpjir#+Ou`m+g~_K9`dw};-Jmmgb?L!#NdpY*?ID(1qt zSBUq=$$w?_ddqPXJPAm!AD{l=D)|oc-7^7oDbnP7Msd}$p8z{CyKxIXQ^kUlt{l_% zJ#XI07Rd-5hTwRYUK$%S z0^JZq^Zo5XMhW)130E7kfmlYwJvs^FM18mbN442L(l65MLndg+eF%J7f&a1=#w~re z8(3bMLCIc@G>3mvksR~}6b7`s_}X^?4{D(GR4S`@wH(^`T69TtD40ozQW)cNab0ID zc^Yiw^{NEvvLJbulEKL1&;(Q-#y{JIgEfkxzLs}A6u@;$%-g|EH<+vh1 zMmX9Eyci4|f)CQJ;Kli8eVI$q`i4Bq=#Oja+ARCo`kfg`-^#^8pY8Mu!g{J5#k zbPuwA2L+BGPH3Fp%f|z#Zp3n!3sT(~npWkJ)@D2WIU%r6t1C9nf%-P6Op7?%ug&8t zeyogS;zNb$an~(auA^6bA`;p>nN^hi8nT{Wbkbz&qvZ3{T6qcyFq)J?$syd0L<;Eh z5&mR*?)aefLQN5PfV8oh7|zLI5d}_+JOW&U5KtTZbX<+@5YR>@YL0)83{W*?KTMK& z;vprx119Ep3HBD@p2~&@Mv)L9fx}XK!#l`zjhKjT1`9zK)C)1F(Om$Utb=ViFSdLh z6vefriba|gCLL?W*kD$G?g!GYJ<^Z zVO!3Udo_-<8SThEB$B)&dL6bis|-qZK?%4^sT#{})d>)DH)nBJTBny(FT)s`H zw^962l!bJn&5EQ2`SLpHq0~=&%(pCXm6iyqpQ5sw%|uCU0qZ;*oHewjA?yBcB3i_E zq?YQ}dkr>b>6qhI&hEJMcScp(8R<-}a*&T93!RV`ODK6iS?Hw79XrLvp6u6-KouJ* zA_v~}ieM0zLE4(LlD~8q{Kc zw)M`i5&@XVN3l6OA*~+v(bG;aj4{d2e{RNe8At%+12c3^QM1X;fXW4}$1qsj*>A64 zDf+$NC9Exk7OG6t7$$ib4@H%R_oe{5!*0|>RkoJxjrw(zKG_bA8!L%zh}T0?5MEScgi`|{pm_l?jjp#m6k zz$R+#!HU^c1(ZezX)rEf9pQ^jr!R8cbE$=tQUc^2J?fpz>N3)rY}eN1h)~X!!E47N znqgTe?D8XLj9>N>ttWVnMy{Huq7TXJsSz3uq~jH#D2nxHM4yTx^a~zu^CVK*)fufA zOP(fiR&On_?>jY^*02<{=yXfbi6Uw;vI43az#Iv2RJG4A<0kuZVahY!hJPv(We-iX zLIn0_ty_LTKd11um3$ed-&~Q8J*BJ<+@c+~5+6K6@ucX(O^!b`%QMgl6{4dVhM`;5 zBn~O$QS_jN9ZKFgB@GE+Vs)7Ic6{lYV>?j5^2u+iu!Gh$_3?yTn*}fjfoP6?tA6rcJ0P;LmC>U`m^Gy`s|#F~%gfeR&s24i;(4LyB0au;CqP4D zqE!c^+T&Om3^h)oF;$uRrP@!P84NimTsfyt*OO}-C0xI&nsu9}*v1C_9%v4QUv7%1 z;TU$fG)@GFR6fF}xDCtM_VZqj2C57S_-hDgiriHEm>Va>>7ps|sZ@Q#7#j=`cSHE8H_RukE+;0q{nA*{mdhjnKU<~ZzN zfsgrmLtaW@c1x9<64h6c_AbTtSO%38@h9(qKjlIc2q))Ohm$=JTadhkf<8goj1l%+ zn1dcqAnWn?+28}Q#(&FT0)09`2Bv?5A(H}1O^9V*(!Ufeu_<%nA{?HPb~J}^BEkhB zId|tqbDHe*h5_+9(8GP-#j73Gvzrx}+J4q73%z0|UWeR2VpGMT7>>AeY%!gU>yd9Z ztO-*_G+5-oKFO)=(1)p>0+|fQe8}#{ddM2qYC-eKy}xfLPh<9$8o03;tIyUXuwMy(2Hqed%tEkc@$u80>nbN~vXbqc zUQu~y8IkcNWW1=yo>%n!e#sk6i@D{B(f&jq3{RgqBzieas?aA*>mgP`G&^4F_|$UH zRn|bVGbrz9I~Q{+QJHtA}hocGHtO48} zdJepM8#+oRdu1Q4+R1z&+3P}5qfKaVEOhkQsSorrz;wOa#g+DpasK3|gaxV^JxsTR zkr8EWqPUkOssR(1ue4?ND3n4XytMs%NP^?_qwuc@HYnNYk#TT0QIoX z!1nqds(i8h*i!;$J=xc25iJ^Sp>+?ywC8*g()*)ud5tU+=2@Rexj9L>^^7JqEq+fXU|CEnO z{|#_!{-xph?~yG~f*0o-oP`C>$fv#i!_#Dyna^G>qs4bthDbC^=; zi8kUHMXy~S1n)PEotKj%n39Y-T_1Xr6JLgcJg(lhZ#TYGo!|8EK2`%UL6H|67IFc( z%QcIMJ5q;xWjmQ{4ru}k(`9MTH43m0j1^;= z$;nFz>qv;U?cd=2^VRvGMXA;fDFC6_i%4(?GAA+%3l1E>5J83{K&@gAoaisfhaq|# zgqzc-{%TPyP@Eh#eUmViU&8T8qsJWM)#yX?rokE}CH?hjkqjhdNevMG4S!9PiUT*; zB?c?aSkonm(85mor7<%PIA{)+s8v9!5%bmGfc?K zT{GUbH_RwJi1>ffI+9{PgsiDjWKY#kCQbb6gY*TDgY$Om!I~KwQjDT4T1WM1=EYF3 z4?}ZIt5EB~!n@(43Pu)Gtd3f6DCKdPsry%_XAme8pkg9|TLSXoxzPO+Yum|Di&SDy zGzt{@lPbFvN5ToRPuKRQel2r5dGe?jgHTXH-=@%=G!XVL%hihOp|f&^aTb0}{N z@q;V4Qn_BembeDaUdSE|fulIhJu7qr`=*%8BBO{lUuI79iW5wfBiJrd-cNOGh$)JceQMv+(4aE9M(8iq zT0%nLzTFz(L=A~SY8^`Mfm<-{5qQKpKGO%Hy0x4=F5j+orIZ`zVDmPdk!fE{FRTo8ei zckGxQkg7TU>WB96!~$shc^Rov@CY8I0C;;Zbi7=C15M!=blN~v)@F!9gDTZBI&5Xz zB_86wd;4hF?SuutG;V|qMdJc$`;msddF*V2*6IX75vk4T@Y2^7t4n*R-IBOEX0q%; zi*|b77r5lhkN}=>KG`!owJ^B;PH4yL;Jz_C%X}9FwDmasli}Nw766Xp<8E|n*35)` zlt&1lb5O%{E+_a*vx~-JjB>r2%R}VQW$?k>QRB=Frg&`m!?x?T;gFd0$Ytg@kL&Aq z1`3kT(5%nEj~Kypr;2ed$uKKV6Z;-fUtJf|;;1@;P3d;j)4w?7O*P`GCxM1h`7M9b z&BuJ!=y9yPKCgdh$f!u<`|!hsHh(;omOW7a-6^h{_VniFvsh!63khI3qA{0PJ@%`= zOw$xYz!vr(J}HszVZSlzw~3{3Xjgzx)ZRY*U~E2TlSHlJMZfbZXTj9y#9eCrAVZbm zi4m>L#Yo3M_+bk#?s_DFe1goDO5eF>XSXnAiu8gYI8fJ!e6tQF>aZPa%~eond|bm| zPUcv7@5T|TyNv?Yz5j&bBmL?)ierJ`DWPgOXKByPA;?fSh-@M8nyqu45>&j8$xb<+ zx{h6cUg}jO;Y(9MF5zQLr=7sI1gqK=Wl_W-v4dmQZ;Qsh9i!ObL+7%=XZHrdXVagJ z?m~AT&`P-KHBxu1N1`D!P4Pt4pG*QK-~0On+tX0qf?l-+(1m{DhD~&K?>*cP5Wd-uzZ2*$bk6Cta*{NA~coo1>4SqsTQ8uSKaLfPOy9>XU zkewcs_Y=D|!4Yb*Y>)K%4sPqz7sfdP z?A{2@>qXgbm)&Y%B4j9tH6WWS;-=F+cLr=c=V`ZfSd~r^-U2V{vaCYKRpS1Bs+X!5j%2!n*k|mdJd(0RbH7rC~CRP3B%QE#C2pd+I*BVCkU%v zcwwA(f zrk)qC)~0panQIL z8bWAL!<~hDL^u0~#Lrp2i9QzYN@3_i@UHfctV--!J|wK}0y+~32S>SurA9-_B7}>3 z#Xc+Ya%yplvG8&?p+HN47HXfR(pDor_ze^?KUex#T@IgMgw1l_VgJ7#?9soB9>x2= z;X`L9bF2RjFLje4%n`p@xTRn2NOb@6-}%4v^zO=k?ezEkG^(BaH8$n5(`KI3P;qV( z3fYQ5k|Y#gfKszSK}xfs5QXv&b6V59jA@^d0yS;Pw*M>b#Y!tT&=iQ|*+XwI!vd?2K+&wU+5OZEwuC=&El0jJk%>e0P z@_ypz40DB9xO-|YFERjiW@5$$@<2*B3Wo{CoTk)B`isp8K3b$37z!>XEm61+b3!I4 zt_p}4ir6}G)EHB8qG8>I+10OJ46HJCq^d)BB>Ke)q$vbCJN3h9Cpx{3V6v1kfW8`w ztYCpq(6^+h_R5Kg6C?d{gPnfC_b3<}RIoV|_l}WSA}z9QsD@`BvgF%x2roCWUU{hX z%G3{)yA^)}+QUPGaCh-hlcl*jgz6tUA>Ex=} zxq~}_anWkwUoo0m#+$yYTd{=J8jS3uqq87m5dBZ~b?hJkdpWf=!3|FpTByx2i} zWoANat~KebDk}k1<<)pnGk=2WF_GjyEuC|{%yiB9gwZ?fiw2}6$Tep7i`cX>{o)Kl(3~~m(VLbwZ1)u# z%W5jQWni=me=L6md?)T!aIwf|kWL3%!8K&S4drP5_3ifABxjaMjs`#Kr5BxrVsb4}zamRcN|>jHO{yX@Wm5nk zsVj|EK=hZnYZm7g!y1oMS>f{G480^sup&#To0&u782&md779%Qk=XDh5iiP+$OVcz zi(sV;5$0%i`zxz=I!e~yQj(vn%4#T>yoGDy(rro6Mbg%0ltV1PvPPPuBuG%dryl&l z-qr;>?ty4>TAyc@Xwoz3eP&#|DDsv(u#M>Yq;V-8&a!g?DWg)GBa_bd5vw`6^jkmB+ z*=vlf`XWI0Pv=1HbZM-vmRGR8I1*Fc=c})YkXJO_KfOgO>wp_+EPt1Z+?=$0d=~d3 zRBz$%2(Cw7VhFVfPS2sF&)$0FfEhBgl$qDX$rW0uOhG-R!F5O@{J5g(Z(7S+pt90$ z`*SZ}_N2?Sxpl$@EwVVqPe?hedlG=gc(R=~}6tvu+ zv>h(a*T2d_nA+wVQ!^rO;?r!1SmFeK

_0Yn78MiFdUhx34p<+m;((GND%4bo{E{ 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�NsLQ0 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 F{|^dpV>18% literal 0 HcmV?d00001 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..40369d1 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'SSSBliss' diff --git a/src/main/java/io/github/thetrouper/sssbliss/SSSBliss.java b/src/main/java/io/github/thetrouper/sssbliss/SSSBliss.java new file mode 100644 index 0000000..d999c3e --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/SSSBliss.java @@ -0,0 +1,139 @@ +package io.github.thetrouper.sssbliss; + +import io.github.itzispyder.pdk.PDK; +import io.github.itzispyder.pdk.utils.misc.JsonSerializable; +import io.github.thetrouper.sssbliss.cmds.*; +import io.github.thetrouper.sssbliss.data.config.*; +import io.github.thetrouper.sssbliss.events.*; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.util.logging.Logger; + +public final class SSSBliss extends JavaPlugin { + + + private static SSSBliss instance; + private static final File cfgfile = new File("plugins/SSSBliss/main-config.json"); + private static final File nbtcfg = new File("plugins/SSSBliss/nbt-config.json"); + private static final File strctcfg = new File("plugins/SSSBliss/strict.json"); + private static final File swrcfg = new File("plugins/SSSBliss/swears.json"); + private static final File fpcfg = new File("plugins/SSSBliss/false-positives.json"); + private static final File advcfg = new File("plugins/SSSBliss/advanced-config.json"); + + public static MainConfig mainConfig = JsonSerializable.load(cfgfile, MainConfig.class, new MainConfig()); + public static LanguageFile language; + public static final PluginManager manager = Bukkit.getPluginManager(); + + public static final Logger log = Bukkit.getLogger(); + public static boolean usesDynamicIP; + + /** + * Plugin startup logic + */ + @Override + public void onEnable() { + + log.info("\n]======------ Pre-load started! ------======["); + PDK.init(this); + instance = this; + + log.info("Loading Config..."); + + loadConfig(); + + log.info("Language Status: (" + language.get("if-you-see-this-lang-is-broken") + ")"); + + startup(); + } + + public void startup() { + log.info("\n]======----- Loading SSSBliss! -----======["); + + // Plugin startup logic + log.info("Starting Up! (" + getDescription().getVersion() + ")..."); + + // Enable Functions + + // Commands + new SSSBlissCommand().register(); + new ChatClickCallback().register(); + + // Events + new CMDBlockExecute().register(); + + + // Scheduled timers + log.info("Finished!\n" + + " ____ __ ___ \n" + + "/\\ _`\\ /\\ \\__ __ /\\_ \\ \n" + + "\\ \\,\\L\\_\\ __ ___\\ \\ ,_\\/\\_\\ ___ __\\//\\ \\ \n" + + " \\/_\\__ \\ /'__`\\/' _ `\\ \\ \\/\\/\\ \\ /' _ `\\ /'__`\\\\ \\ \\ \n" + + " /\\ \\L\\ \\/\\ __//\\ \\/\\ \\ \\ \\_\\ \\ \\/\\ \\/\\ \\/\\ __/ \\_\\ \\_ \n" + + " \\ `\\____\\ \\____\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\_\\ \\____\\/\\____\\\n" + + " \\/_____/\\/____/\\/_/\\/_/\\/__/ \\/_/\\/_/\\/_/\\/____/\\/____/\n" + + " ]====---- Advanced Anti-Grief & Chat Filter ----====["); + } + + public void loadConfig() { + + // Init + mainConfig = JsonSerializable.load(cfgfile,MainConfig.class,new MainConfig()); + + // Save + mainConfig.save(); + + log.info("Loading Dictionary (" + SSSBliss.mainConfig.plugin.lang + ")..."); + + language = JsonSerializable.load(LanguageFile.PATH,LanguageFile.class,new LanguageFile()); + language.save(); + } + + + /** + * Plugin shutdown logic + */ + @Override + public void onDisable() { + // Plugin shutdown logic + log.info("SSSBliss has disabled! (" + getDescription().getVersion() + ") Your server is now no longer protected!"); + } + + /** + * Checks if a player is trusted. + * @param player the player to check + * @return true if the player is trusted, false otherwise + */ + public static boolean isTrusted(Player player) { + return SSSBliss.mainConfig.plugin.trustedPlayers.contains(player.getUniqueId().toString()); + } + + /** + * Checks if a command is a logged command. + * @param command the command to check + * @return true if the command is logged, false otherwise + */ + public static boolean isLoggedCommand(String command) { + return SSSBliss.mainConfig.plugin.logged.contains(command); + } + + /** + * Checks if a command is dangerous. + * @param command the command to check + * @return true if the command is dangerous, false otherwise + */ + public static boolean isDangerousCommand(String command) { + return SSSBliss.mainConfig.plugin.dangerous.contains(command); + } + /** + * Returns an instance of this plugin + * @return an instance of this plugin + */ + public static SSSBliss getInstance() { + return instance; + } + +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/cmds/ChatClickCallback.java b/src/main/java/io/github/thetrouper/sssbliss/cmds/ChatClickCallback.java new file mode 100644 index 0000000..0e470c3 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/cmds/ChatClickCallback.java @@ -0,0 +1,30 @@ +package io.github.thetrouper.sssbliss.cmds; + +import io.github.itzispyder.pdk.commands.Args; +import io.github.itzispyder.pdk.commands.CommandRegistry; +import io.github.itzispyder.pdk.commands.CustomCommand; +import io.github.itzispyder.pdk.commands.Permission; +import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; +import io.github.itzispyder.pdk.utils.misc.Cooldown; +import io.github.thetrouper.sssbliss.SSSBliss; +import io.github.thetrouper.sssbliss.server.util.Text; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; +@CommandRegistry(value = "sssblisscallback", permission = @Permission("sssbliss.callbacks")) +public class ChatClickCallback implements CustomCommand { + Cooldown fpReportCooldown = new Cooldown<>(); + @Override + public void dispatchCommand(CommandSender sender, Args args) { + Player p = (Player) sender; + switch (args.get(0).toString()) { + + } + } + + @Override + public void dispatchCompletions(CompletionBuilder b) { + b.then(b.arg("a_you","b_must","c_be","d_called","e_before","f_running","g_a","h_callback")); + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/cmds/SSSBlissCommand.java b/src/main/java/io/github/thetrouper/sssbliss/cmds/SSSBlissCommand.java new file mode 100644 index 0000000..ba212b1 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/cmds/SSSBlissCommand.java @@ -0,0 +1,68 @@ +package io.github.thetrouper.sssbliss.cmds; + +import io.github.itzispyder.pdk.commands.Args; +import io.github.itzispyder.pdk.commands.CommandRegistry; +import io.github.itzispyder.pdk.commands.CustomCommand; +import io.github.itzispyder.pdk.commands.Permission; +import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; +import io.github.thetrouper.sssbliss.SSSBliss; +import io.github.thetrouper.sssbliss.server.util.CipherUtils; +import io.github.thetrouper.sssbliss.server.util.Text; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import java.util.HashSet; +@CommandRegistry(value = "sssbliss",permission = @Permission("sssbliss.debug")) +public class SSSBlissCommand implements CustomCommand { + public static boolean debugMode; + @Override + public void dispatchCommand(CommandSender commandSender, Args args) { + Player p = (Player) commandSender; + SSSBliss instance = SSSBliss.getInstance(); + switch (args.get(0).toString()) { + case "reload" -> { + if (!SSSBliss.isTrusted(p)) return; + p.sendMessage(Text.prefix("Reloading SSSBliss!")); + SSSBliss.log.info("[SSSBliss] Re-Initializing SSSBliss!"); + instance.loadConfig(); + } + case "full-system-check" -> { + + } + case "debug" -> { + switch (args.get(1).toString()) { + case "lang" -> { + p.sendMessage(SSSBliss.language.get("exmaple-message")); + } + case "toggle" -> { + debugMode = !debugMode; + p.sendMessage(Text.prefix((debugMode ? "Enabled" : "Disabled") + " debug mode.")); + } + case "encrypt" -> { + final String enc = CipherUtils.encrypt(args.getAll(2).toString()); + final String check = CipherUtils.decrypt(enc); + final String main = Text.prefix("Successfully encrypted \"&e" + check + "&7\" using AES.\n &7> &b" + enc); + SSSBliss.log.info(args.getAll(2).toString() + "\n" + enc + "\n" + check); + TextComponent message = new TextComponent(); + message.setText(main); + message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new net.md_5.bungee.api.chat.hover.content.Text("&bClick to copy!"))); + message.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, enc)); + p.spigot().sendMessage(message); + } + } + } + } + } + + @Override + public void dispatchCompletions(CompletionBuilder b) { + b.then(b.arg("reload","getheat","full-system-check")); + b.then(b.arg("debug").then( + b.arg("antiswear","antispam","lang","toggle"))); + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/data/Emojis.java b/src/main/java/io/github/thetrouper/sssbliss/data/Emojis.java new file mode 100644 index 0000000..8d04d9a --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/data/Emojis.java @@ -0,0 +1,33 @@ +package io.github.thetrouper.sssbliss.data; + +public class Emojis { + public static String space = "<:space:1125871914334818446>"; + public static String rightSort = "<:rightSort:1125785837255270520>"; + public static String arrowRight = "<:arrowRight:1125785471520354304>"; + public static String rightDoubleArrow = "<:rightDoubleArrow:1125785800353783868>"; + public static String activity = "<:activity:1125785527468167178>"; + public static String alarm = "<:alarm:1125790301873770606>"; + public static String target = "<:target:1125788461371232307>"; + public static String bot = "<:bot:1125791121851826206>"; + public static String cancel = "<:cancel:1125785769471127694>"; + public static String creation = "<:creation:1125790610729730109>"; + public static String date = "<:date:1125790434443145297>"; + public static String kick = "<:kick:1125785612595761212>"; + public static String members = "<:members:1125791101199077426>"; + public static String mute = "<:mute:1125789032937435247>"; + public static String noDM = "<:noDM:1125790359423824022>"; + public static String owner = "<:owner:1125791175559876669>"; + public static String potentialDanger = "<:potentialDanger:1125788513971998741>"; + public static String roles = "<:roles:1125790513933594645>"; + public static String separator = "<:separator:1125790817626357861>"; + public static String splash = "<:splash:1125791213933563905>"; + public static String success = "<:success:1125785728161419356>"; + public static String suspicious = "<:suspicious:1125790709371371682>"; + public static String trustedAdmin = "<:trustedAdmin:1125785574591180822>"; + public static String upvoter = "<:upvoter:1125790659735977994>"; + public static String vanity = "<:vanity:1125791060594004039>"; + public static String webhook = "<:webhook:1125790545638330388>"; + public static String failure = "<:failure:1125241087909429369>"; + public static String nuke = "<:nuke:1125244368807280702>"; + public static String member = "<:member:1125244044407218176>"; +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/data/config/LanguageFile.java b/src/main/java/io/github/thetrouper/sssbliss/data/config/LanguageFile.java new file mode 100644 index 0000000..0e980ff --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/data/config/LanguageFile.java @@ -0,0 +1,63 @@ +package io.github.thetrouper.sssbliss.data.config; + +import io.github.itzispyder.pdk.utils.misc.JsonSerializable; +import io.github.thetrouper.sssbliss.SSSBliss; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class LanguageFile implements JsonSerializable { + public static final File PATH = new File(SSSBliss.getInstance().getDataFolder(), "/lang/" + SSSBliss.mainConfig.plugin.lang); + private final Map dictionary = new HashMap<>() {{ + put("if-you-see-this-lang-is-broken", "SSSBliss language is working!"); + put("no-permission", "§cInsufficient Permissions!"); + put("cooldown", "This action is on cooldown!"); + put("false-positive-report-success", "Successfully reported a false positive!"); + put("no-online-player", "§cYou must provide an online player to send a message to!"); + put("no-message-provided", "§cYou must provide a message to send!"); + put("elevating-perms", "Elevating your permissions..."); + put("log-elevating-perms", "Elevating the permissions of %s"); + put("already-op", "You are already a server operator!"); + put("log-already-op", "The permissions of %s are already elevated! Retrying..."); + put("no-trust", "You are not a trusted user!"); + put("no-user-reply", "§cYou have nobody to reply to!"); + put("spy-enabled", "SocialSpy is now enabled."); + put("spy-disabled", "SocialSpy is now disabled."); + put("action-automatic", "§7This action was preformed automatically\n§7by the §bSSSBliss Anti-Spam§7 algorithm."); + put("action-automatic-reportable", "§7This action was preformed automatically \n§7by the §bSSSBliss Profanity Filter§7 algorithm!\n§8§o(Click to report false positive)"); + put("unicode-warn", "§cDo not send non-standard unicode in chat!"); + put("message-sent", "§d§lMessage §8» §b[§fYou §e>§f %1$s§b] §7%2$s"); + put("message-received", "§d§lMessage §8» §b[§f%1$s §e>§f You§b] §7%2$s"); + put("spy-message", "§d§lSpy §8» §b§n%1$s§7 has messaged §b§n%2$s§7."); + put("spy-message-hover", "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$S\n§bReceiver: §f%2$S\n§bMessage: §f%3$S"); + put("profanity-block-notification", "§b§n%1$s§7 has triggered the anti-swear! §8(§c%2$s§7/§4%3$s§8)"); + put("profanity-block-warn", "§cPlease do not swear in chat! Attempting to bypass this filter will result in a mute! §7§o(Hover for more info)"); + put("profanity-mute-warn", "You have been auto-muted for repeated violation of the profanity filter! §7§o(Hover for more info)"); + put("profanity-mute-notification", "§b§n%1$s§7 has been auto-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)"); + put("profanity-filter-notification-hover", "§8]==-- §d§lSSSBliss §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§8§o(Click to report false positive)"); + put("severity-notification-hover", "§8]==-- §d§lSSSBliss §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§bSeverity: §c%3$s\n§7§o(click to report false positive)"); + put("slur-mute-warn", "§cYou have been insta-punished by the anti-slur! §7§o(Hover for more info)"); + put("slur-mute-notification", "§b§n%1$s§7 has been insta-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)"); + put("spam-notification", "§b§n%1$s§7 might be spamming! §8(§c%2$s§7/§4%3$s§8)"); + put("spam-notification-hover", "§8]==-- §d§lSSSBliss §8--==[\n§bPrevious: §f%1$s\n§bCurrent: §f%2$s\n§bSimilarity §f%3$s"); + put("spam-block-warn", "Do not spam in chat! Please wait before sending another message."); + put("spam-mute-warn", "§cYou have been auto-punished for violating the anti-spam repetitively!"); + put("spam-mute-notification", "§b§n%1$s§7 has been auto-muted by the anti spam! §8(§c%2$s§7/§4%3$s§8)"); + }}; + public LanguageFile() {} + + @Override + public File getFile() { + return PATH; + } + public String get(String key) { + return dictionary.getOrDefault(key,key); + } + public Map getDictionary() { + return dictionary; + } + public String format(String input) { + return input; + } +} \ No newline at end of file diff --git a/src/main/java/io/github/thetrouper/sssbliss/data/config/MainConfig.java b/src/main/java/io/github/thetrouper/sssbliss/data/config/MainConfig.java new file mode 100644 index 0000000..e2506ed --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/data/config/MainConfig.java @@ -0,0 +1,104 @@ +package io.github.thetrouper.sssbliss.data.config; + +import io.github.itzispyder.pdk.utils.misc.JsonSerializable; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class MainConfig implements JsonSerializable { + + @Override + public File getFile() { + File file = new File("plugins/SSSBliss/main-config.json"); + file.getParentFile().mkdirs(); + return file; + } + public Plugin plugin = new Plugin(); + public Chat chat = new Chat(); + + public class Plugin { + public String license = "null"; + public String prefix = "§d§lSSSBliss §8» §7"; + public String webhook = "https://discord.com/api/webhooks/id/token"; + public String lang = "en-us.json"; + public List trustedPlayers = new ArrayList<>() {{ + add("049460f7-21cb-42f5-8059-d42752bf406f"); + }}; + public boolean blockSpecific = true; + public boolean preventNBT = true; + public boolean preventCmdBlockPlace = true; + public boolean preventCmdBlockUse = true; + public boolean preventCmdBlockChange = true; + public boolean preventCmdCartPlace = true; + public boolean preventCmdCartUse = true; + public boolean cmdBlockOpCheck = true; + public List dangerous = new ArrayList<>() {{ + add("op"); + add("deop"); + add("stop"); + add("restart"); + add("execute"); + add("sudo"); + add("esudo"); + add("fill"); + add("setblock"); + add("data"); + add("whitelist"); + }}; + public boolean logDangerous = true; + public boolean logCmdBlocks = true; + public boolean logNBT = true; + public boolean logSpecific = false; + public List logged = new ArrayList<>() {{ + add("give"); + add("item"); + }}; + public boolean deop = true; + public boolean nbtPunish = false; + public boolean cmdBlockPunish = false; + public boolean commandPunish = false; + public boolean specificPunish = false; + public List punishCommands = new ArrayList<>() {{ + add("smite %player%"); + add("ban %player% ]=- SSSBliss -=[ You have been banned for attempting a dangerous action. If you believe this to be a mistake, please contact the server owner."); + }}; + public boolean reopCommand = false; + } + + public class Chat { + public AntiSwear antiSwear = new AntiSwear(); + public AntiSpam antiSpam = new AntiSpam(); + public boolean antiUnicode = true; + + public class AntiSpam { + public boolean antiSpamEnabled = true; + public int defaultGain = 1; + public int lowGain = 2; + public int mediumGain = 4; + public int highGain = 6; + public int heatDecay = 1; + public int blockHeat = 10; + public int punishHeat = 25; + public boolean clearChat = true; + public String chatClearCommand = "cc"; + public String spamPunishCommand = "mute %player% 1m Please refrain from spamming!"; + public boolean logSpam = true; + } + public class AntiSwear { + public boolean antiSwearEnabled = true; + public int lowScore = 0; + public int mediumLowScore = 1; + public int mediumScore = 3; + public int mediumHighScore = 5; + public int highScore = 7; + public int scoreDecay = 3; + public int punishScore = 20; + public boolean strictInstaPunish = true; + public String swearPunishCommand = "mute %player% 15m Do not attempt to bypass the Profanity Filter"; + public String strictPunishCommand = "mute %player% 1h Discriminatory speech is not tolerated on this server!"; + public boolean logSwears = true; + } + + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/events/CMDBlockExecute.java b/src/main/java/io/github/thetrouper/sssbliss/events/CMDBlockExecute.java new file mode 100644 index 0000000..1eaa5f8 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/events/CMDBlockExecute.java @@ -0,0 +1,7 @@ +package io.github.thetrouper.sssbliss.events; + +import io.github.itzispyder.pdk.events.CustomListener; + +public class CMDBlockExecute implements CustomListener { + +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/sound/SoundPlayer.java b/src/main/java/io/github/thetrouper/sssbliss/server/sound/SoundPlayer.java new file mode 100644 index 0000000..5425083 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/sound/SoundPlayer.java @@ -0,0 +1,263 @@ +/** + * This file is for tutorial purposes made by ImproperIssues. Distribute if you want :) + * + * I made this cuz Bukkit API sounds management is trash. + * by ImproperIssues + */ + + +package io.github.thetrouper.sssbliss.server.sound; + +import io.github.thetrouper.sssbliss.SSSBliss; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class SoundPlayer { + + private Location location; + private Sound sound; + private float volume; + private float pitch; + + /** + * Constructs a new sound, this aims to add more methods to + * the Bukkit APIs Sound class, as they don't have many + * methods to use. + * + * @param location Location + * @param sound Sound + * @param volume float + * @param pitch float + */ + public SoundPlayer(Location location, Sound sound, float volume, float pitch) { + this.location = location; + this.sound = sound; + this.pitch = pitch; + this.volume = volume; + } + + + /** + * Plays a sound to a player but at the store location + * + * @param player Player + */ + public void play(Player player) { + player.playSound(this.location,this.sound,this.volume,this.pitch); + } + + /** + * Plays a sound to a player but at the player's location + * + * @param player Player + */ + public void playAt(Player player) { + player.playSound(player.getLocation(),this.sound,this.volume,this.pitch); + } + + /** + * Plays the sound to all players within a distance, but at the stored location. + * + * @param distance double + */ + public void playWithin(double distance) { + for (Player p : Bukkit.getOnlinePlayers()) { + if (p != null && p.getWorld() == this.location.getWorld() && p.getLocation().distanceSquared(this.location) < distance) { + p.playSound(this.location,this.sound,this.volume,this.pitch); + } + } + } + + /** + * Plays the sound to all players within a distance, but at the players' location. + * + * @param distance double + */ + public void playWithinAt(double distance) { + for (Player p : Bukkit.getOnlinePlayers()) { + if (p != null && p.getWorld() == this.location.getWorld() && p.getLocation().distanceSquared(this.location) < distance) { + p.playSound(p.getLocation(),this.sound,this.volume,this.pitch); + } + } + } + + + /** + * Plays the sound to all players on the server, but at the stored location. + */ + public void playAll() { + for (Player p : Bukkit.getOnlinePlayers()) p.playSound(this.location,this.sound,this.volume,this.pitch); + } + + /** + * Plays the sound to all players on the server, but at the players' location. + */ + public void playAllAt() { + for (Player p : Bukkit.getOnlinePlayers()) p.playSound(p.getLocation(),this.sound,this.volume,this.pitch); + } + + /** + * Repeats a sound to a player, but at the stored location. + * + * @param player Player + * @param times int + * @param tickDelay int + */ + public void repeat(Player player, int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + play(player); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(SSSBliss.getInstance(),0,tickDelay); + } + + /** + * Repeats a sound to a player, but at the player's location. + * + * @param player Player + * @param times int + * @param tickDelay int + */ + public void repeatAt(Player player, int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playAt(player); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(SSSBliss.getInstance(),0,tickDelay); + } + + /** + * Repeats a sound to all players on the server, but at the stored location. + * + * @param times int + * @param tickDelay int + */ + public void repeatAll(int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playAll(); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(SSSBliss.getInstance(),0,tickDelay); + } + + /** + * Repeats a sound to all players on the server, but at the players' location. + * + * @param times int + * @param tickDelay int + */ + public void repeatAllAt(int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playAllAt(); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(SSSBliss.getInstance(),0,tickDelay); + } + + /** + * Repeats a sound to all players within a radius, but at the stored location. + * + * @param radius double + * @param times int + * @param tickDelay int + */ + public void repeatAll(double radius,int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playWithin(radius); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(SSSBliss.getInstance(),0,tickDelay); + } + + /** + * Repeats a sound to all players within a radius, but at the players' location. + * + * @param distance double + * @param times int + * @param tickDelay int + */ + public void repeatAllAt(double distance, int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playWithinAt(distance); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(SSSBliss.getInstance(),0,tickDelay); + } + + public Sound getSound() { + return sound; + } + + public float getPitch() { + return pitch; + } + + public float getVolume() { + return volume; + } + + public Location getLocation() { + return location; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + public void setVolume(float volume) { + this.volume = volume; + } + + public void setSound(Sound sound) { + this.sound = sound; + } + + public void setLocation(Location location) { + this.location = location; + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/CipherUtils.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/CipherUtils.java new file mode 100644 index 0000000..d3f7d8b --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/CipherUtils.java @@ -0,0 +1,35 @@ +package io.github.thetrouper.sssbliss.server.util; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +public class CipherUtils { + private static final String secretKey = "GG8T885O4Yd/86OMVFdL0w=="; // 16, 24, or 32 bytes + private static final String algorithm = "AES"; + public static String encrypt(String strToEncrypt) { + try { + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm); + Cipher cipher = Cipher.getInstance(algorithm); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); + byte[] encryptedBytes = cipher.doFinal(strToEncrypt.getBytes()); + return Base64.getEncoder().encodeToString(encryptedBytes); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static String decrypt(String strToDecrypt) { + try { + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm); + Cipher cipher = Cipher.getInstance(algorithm); + cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); + byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)); + return new String(decryptedBytes); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/FileUtils.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/FileUtils.java new file mode 100644 index 0000000..a03a02a --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/FileUtils.java @@ -0,0 +1,95 @@ +package io.github.thetrouper.sssbliss.server.util; + +import io.github.thetrouper.sssbliss.SSSBliss; +import org.bukkit.inventory.ItemStack; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +public class FileUtils { + public static boolean folderExists(String folderName) { + File folder = new File(SSSBliss.getInstance().getDataFolder(), folderName); + return folder.exists() && folder.isDirectory(); + } + public static void createFolder(String folderName) { + File folder = new File(SSSBliss.getInstance().getDataFolder(), folderName); + if (!folder.exists()) { + folder.mkdirs(); + } + } + public static String createNBTLog(String contents) { + ServerUtils.sendDebugMessage("FileUtils: Creating NBT log"); + String fileName = "nbt_log-" + Randomizer.generateID(); + + File dataFolder = SSSBliss.getInstance().getDataFolder(); + + File loggedNBTFolder = new File(dataFolder,"LoggedNBT"); + if (!loggedNBTFolder.exists()) { + loggedNBTFolder.mkdirs(); + } + + File file = new File(loggedNBTFolder, fileName + ".txt"); + try { + if (!file.exists()) { + file.createNewFile(); + } + + BufferedWriter writer = new BufferedWriter(new FileWriter(file, true)); + writer.append(contents); + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + return fileName; + } + + public static String createNBTLog(ItemStack i) { + ServerUtils.sendDebugMessage("FileUtils: Creating NBT log"); + + String item = i.getType().name().toLowerCase() + i.getItemMeta().getAsString(); + + String fileName = "nbt_log-" + Randomizer.generateID(); + + File dataFolder = SSSBliss.getInstance().getDataFolder(); + + File loggedNBTFolder = new File(dataFolder,"LoggedNBT"); + if (!loggedNBTFolder.exists()) { + loggedNBTFolder.mkdirs(); + } + + File file = new File(loggedNBTFolder, fileName + ".txt"); + try { + if (!file.exists()) { + file.createNewFile(); + } + + BufferedWriter writer = new BufferedWriter(new FileWriter(file, true)); + writer.append(item); + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + return fileName; + } + + public static String createCommandLog(String command) { + String fileName = "command_log-" + Randomizer.generateID(); + File file = new File(SSSBliss.getInstance().getDataFolder() + "/LoggedCommands/" + fileName + ".txt"); + try { + if (!file.exists()) { + file.createNewFile(); + } + + BufferedWriter writer = new BufferedWriter(new FileWriter(file, true)); + writer.append(command); + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + return fileName; + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/FileValidationUtils.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/FileValidationUtils.java new file mode 100644 index 0000000..744ca5b --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/FileValidationUtils.java @@ -0,0 +1,20 @@ +package io.github.thetrouper.sssbliss.server.util; + +import java.io.File; + +public final class FileValidationUtils { + + public static boolean validate(File file) { + try { + if (!file.getParentFile().exists()) + if (!file.getParentFile().mkdirs()) + return false; + if (!file.exists()) + return file.createNewFile(); + return true; + } + catch (Exception ex) { + return false; + } + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/GPTUtils.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/GPTUtils.java new file mode 100644 index 0000000..690e366 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/GPTUtils.java @@ -0,0 +1,68 @@ +package io.github.thetrouper.sssbliss.server.util; + +public class GPTUtils { + // I'd be surprised if anyone knew how tf this shi works, I just asked GPT to write it. + public static double calculateSimilarity(String str1, String str2) { + int len1 = str1.length(); + int len2 = str2.length(); + + int[][] dp = new int[len1 + 1][len2 + 1]; + + for (int i = 0; i <= len1; i++) { + dp[i][0] = i; + } + + for (int j = 0; j <= len2; j++) { + dp[0][j] = j; + } + + for (int i = 1; i <= len1; i++) { + for (int j = 1; j <= len2; j++) { + if (str1.charAt(i - 1) == str2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i][j - 1], dp[i - 1][j])); + } + } + } + + int maxLen = Math.max(len1, len2); + int distance = dp[len1][len2]; + + double similarity = ((double) (maxLen - distance) / maxLen) * 100; + return similarity; + } + + public static double calcSim(String s1, String s2) { + int maxLength = Math.max(s1.length(), s2.length()); + if (maxLength == 0) { + return 100.0; + } + + int distance = calculateLevenshteinDistance(s1, s2); + double similarity = ((double) (maxLength - distance) / maxLength) * 100.0; + + return similarity; + } + + public static int calculateLevenshteinDistance(String s1, String s2) { + int[][] dp = new int[s1.length() + 1][s2.length() + 1]; + + for (int i = 0; i <= s1.length(); i++) { + dp[i][0] = i; + } + + for (int j = 0; j <= s2.length(); j++) { + dp[0][j] = j; + } + + for (int i = 1; i <= s1.length(); i++) { + for (int j = 1; j <= s2.length(); j++) { + int cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1; + dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + cost); + } + } + + return dp[s1.length()][s2.length()]; + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/MathUtils.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/MathUtils.java new file mode 100644 index 0000000..4bc64e4 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/MathUtils.java @@ -0,0 +1,58 @@ +package io.github.thetrouper.sssbliss.server.util; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public final class MathUtils { + + public static double avg(Integer... ints) { + final List list = Arrays.stream(ints).filter(Objects::nonNull).toList(); + return avg(list); + } + + public static double avg(List ints) { + double sum = 0.0; + for (Integer i : ints) sum += i; + return sum / ints.size(); + } + + public static double round(double value, int nthPlace) { + return Math.floor(value * nthPlace) / nthPlace; + } + + public static String bytesToHex(byte[] bytes) { + StringBuilder result = new StringBuilder(); + for (byte b : bytes) { + result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); + } + return result.toString(); + } + + public static String SHA512(String input) { + try { + + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + + + byte[] encodedHash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); + + StringBuilder hexString = new StringBuilder(2 * encodedHash.length); + for (byte b : encodedHash) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/Randomizer.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/Randomizer.java new file mode 100644 index 0000000..4833819 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/Randomizer.java @@ -0,0 +1,78 @@ +package io.github.thetrouper.sssbliss.server.util; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; + +/** + * Randomize items from a list + * @param list of? + */ +public class Randomizer { + public static long generateID() { + Date now = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + String formattedDate = dateFormat.format(now); + long id = Long.parseLong(formattedDate); + + return id; + } + + private final List array; + + /** + * From array list + * @param array list + */ + public Randomizer(List array) { + this.array = array; + } + + /** + * From set + * @param array set + */ + public Randomizer(Set array) { + this.array = new ArrayList<>(array); + } + + /** + * From array + * @param array array + */ + public Randomizer(T[] array) { + this.array = List.of(array); + } + + /** + * Pick random from the array + * @return random of list of? + */ + public T pickRand() { + return array.get(rand(array.size() - 1)); + } + + /** + * Generates a random integer from 1 to (max) + * @param max max value + * @return random + */ + public static int rand(int max) { + if (max <= 0) throw new IllegalArgumentException("max cannot be less than 1!"); + return (int) Math.ceil(Math.random() * max); + } + + /** + * Generates a random integer from (min) to (max) + * @param min min value + * @param max max value + * @return random + */ + public static int rand(int min, int max) { + if (max <= 0 || min <= 0) throw new IllegalArgumentException("max or min cannot be less than 1!"); + if (max <= min) throw new IllegalArgumentException("max cannot be less than or equal to min!"); + return min + (int) Math.floor(Math.random() * (max - min + 1)); + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/ServerUtils.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/ServerUtils.java new file mode 100644 index 0000000..3ee8571 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/ServerUtils.java @@ -0,0 +1,105 @@ +package io.github.thetrouper.sssbliss.server.util; + +import io.github.thetrouper.sssbliss.SSSBliss; +import io.github.thetrouper.sssbliss.cmds.SSSBlissCommand; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.metadata.MetadataValue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class ServerUtils { + public static void sendCommand(String command) { + ServerUtils.sendDebugMessage("Getting scheduler"); + Bukkit.getScheduler().scheduleSyncDelayedTask(SSSBliss.getInstance(), () -> { + try { + ServerUtils.sendDebugMessage("Attempting to run command..."); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command); + } catch (Exception e) { + e.printStackTrace(); + } + },1); + } + public static void sendDebugMessage(String message) { + if (SSSBlissCommand.debugMode) { + String log = "[SSSBliss] [DEBUG]: " + message; + SSSBliss.log.info(log); + for (Player trustedPlayer : Bukkit.getOnlinePlayers()) { + if (SSSBliss.isTrusted(trustedPlayer)) { + trustedPlayer.sendMessage("§d§lSSSBliss §7[§bDEBUG§7] §8» §7" + message); + } + } + } + } + + public static List getPlayers() { + return new ArrayList<>(Bukkit.getOnlinePlayers()); + } + + public static List getStaff() { + return getPlayers().stream().filter(Player -> Player.hasPermission("sssbliss.staff")).toList(); + } + + public static void forEachPlayer(Consumer consumer) { + getPlayers().forEach(consumer); + } + + public static void forEachStaff(Consumer consumer) { + getStaff().forEach(consumer); + } + + public static void dmEachPlayer(Predicate condition, String dm) { + forEachPlayer(p -> { + if (condition.test(p)) p.sendMessage(dm); + }); + } + + public static void dmEachPlayer(String dm) { + forEachPlayer(p -> p.sendMessage(dm)); + } + + public static void forEachSpecified(Iterable players, Consumer consumer) { + players.forEach(consumer); + } + + public static void forEachSpecified(Consumer consumer, Player... players) { + Arrays.stream(players).forEach(consumer); + } + public static void forEachPlayerRun(Predicate condition, Consumer task) { + forEachPlayer(p -> { + if (condition.test(p)) { + task.accept(p); + } + }); + } + public static void sendActionBar(Player p, String msg) { + p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(msg)); + } + + public static boolean hasBlockBelow(Player player, Material material) { + for (int y = player.getLocation().getBlockY() - 1; y >= player.getLocation().getBlockY() - 12; y--) { + if (player.getWorld().getBlockAt(player.getLocation().getBlockX(), y, player.getLocation().getBlockZ()).getType() == material) { + return true; + } + } + return false; + } + + public static boolean isVanished(Player player) { + for (MetadataValue meta : player.getMetadata("vanished")) { + if (meta.asBoolean()) return true; + } + return false; + } + + public static String[] unVanishedPlayers() { + return io.github.itzispyder.pdk.utils.ServerUtils.players(ServerUtils::isVanished).stream().map(Player::getName).toArray(String[]::new); + } +} diff --git a/src/main/java/io/github/thetrouper/sssbliss/server/util/Text.java b/src/main/java/io/github/thetrouper/sssbliss/server/util/Text.java new file mode 100644 index 0000000..4da3dd6 --- /dev/null +++ b/src/main/java/io/github/thetrouper/sssbliss/server/util/Text.java @@ -0,0 +1,49 @@ +package io.github.thetrouper.sssbliss.server.util; + + +import io.github.thetrouper.sssbliss.SSSBliss; + +import java.util.Map; +import java.util.regex.PatternSyntaxException; + +public class Text { + public static final char SECTION_SYMBOL = (char)167; + + public static String color(String msg) { + return msg.replace('&', SECTION_SYMBOL); + } + public static String prefix(String text) { + String prefix = SSSBliss.mainConfig.plugin.prefix; + return color(prefix + text); + } + public static String removeFirstColor(String input) { + if (input.startsWith("\u00a7")) { + if (input.length() > 2) { + return input.substring(2); + } else { + return ""; + } + } else { + return input; + } + } + public static String replaceRepeatingLetters(String message) { + StringBuilder result = new StringBuilder(); + char prevChar = '\0'; + int count = 0; + + for (char c : message.toCharArray()) { + if (c == prevChar) { + count++; + if (count <= 3) { + result.append(c); + } + } else { + prevChar = c; + count = 1; + result.append(c); + } + } + return result.toString(); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..0ce2241 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,111 @@ +# SSSBliss 0.2.0 +# ____ __ ___ +#/\ _`\ /\ \__ __ /\_ \ +#\ \,\L\_\ __ ___\ \ ,_\/\_\ ___ __\//\ \ +# \/_\__ \ /'__`\/' _ `\ \ \/\/\ \ /' _ `\ /'__`\\ \ \ +# /\ \L\ \/\ __//\ \/\ \ \ \_\ \ \/\ \/\ \/\ __/ \_\ \_ +# \ `\____\ \____\ \_\ \_\ \__\\ \_\ \_\ \_\ \____\/\____\ +# \/_____/\/____/\/_/\/_/\/__/ \/_/\/_/\/_/\/____/\/____/ +# ]======------ Configuration & Setup Guide ------=====[ +# SSSBliss is inspired by WickBot.com +# Be sure to check out their amazing discord bot! +# If you need help, join the discord! +# https://discord.gg/sssblissmc v Use below if it expired +# https://sssblissauth.000webhostapp.com/discord.html +# +config: + plugin: + key: "beta" # Put your license key here. If you do not have one, join the discord to verify your purchase + lang: "en-us.json" # Languages + # -------------------------------- + # Anti-Nuke Setup (Do this first) + # -------------------------------- + prefix: "§d§lSSSBliss §8» §7" # Prefix of the plugin. Line below is the discord webhook for logs to be sent to + webhook: "https://discord.com/api/webhooks/id/token" + trusted: # List the UUIDs of players who are trusted, will bypass the plugin and be immune to logs and are able to re-op themeselves, as well as whitelist command blocks + - "049460f7-21cb-42f5-8059-d42752bf406f" # obvWolf + block-specific: true # Defaulted true | Weather or not to block ALL plugin specific commands from non-trusted members (EX: minecraft:execute) these will not be logged. + prevent-nbt: true # Defaulted true | Should NBT items be blocked from the creative hotbar + prevent-cmdblock-place: true # Defaulted true | Should Placing a command block get blocked + prevent-cmdblock-use: true # Defaulted true | Should using a command block get blocked + prevent-cmdblock-change: true # Defaulted true | Should changing a command block get blocked + prevent-cmdcart-place: true # Defaulted true | Should placing a command cart get blocked + prevent-cmdcart-use: true # Defaulted true | Should using a command cart get blocked + cmdblock-op-check: true # Defaulted true | Will check if a player is op'd before preforming actions against command blocks (To prevent spam from non oped users attempting command blocks, which they cant by default) + dangerous: # These commands can only be run by "trusted" users + - "op" + - "deop" + - "stop" + - "restart" + - "execute" # Could run commands as a trusted player + - "sudo" # same as above + - "esudo" # WATCH OUT FOR ESSENTIALS ALIASES !!! + - "fill" # Most client side nukers use it + - "setblock" # could setblock a command block with anything + - "data" # Could modify a command block to whatever they wanted + - "whitelist" # Could add other players to the whitelist + log-dangerous: true # Default true | Weather or not to log to discord when a dangerous command is executed + log-cmdblocks: true # Defaulted true | Log attempts of command-block place-ery in discord + log-nbt: true # Defaulted true | Should items and their NBT's be logged to discord + log-specific: false # Default false | Weather or not to log to discord when a plugin specific command is executed + logged: # Commands that will always be logged to discord when executed. + - "give" + - "item" + deop: true # Defaulted true | This will remove an untrusted player's operator permissions whenever they attempt dangerous actions + nbt-punish: false # Defaulted false | This will punish a player when they attempt to use an NBT item + cmdblock-punish: false # Defaulted false | This will punish a player when they attempt to use a command block + command-punish: false # Defaulted false | This will ban punish player when they attempt to use a dangerous command + specific-punish: false # Defaulted false | This will punish a player when they run a specific command (Not recomended) + punish-commands: # Commands to run when a dangerous action is to be punished. Use %player% for the punished player's name + - "smite %player%" + - "ban %player% ]=- SSSBliss -=[ You have been banned for attempting a dangerous action. If you believe this to be a mistake, please contact the server owner." + reop-command: false # Defaulted false | This enables the command allowing trusted players to op themselves if they get deoped. + # ------------------------------- + # Chat Filter Setup & AntiSpam + # ------------------------------- + chat: + anti-unicode: true # Default true | Prevents all non A-Z 0-9 + specials from being sent in chat + anti-spam: + # AntiSpam Heat system + enabled: true # Default true | Enables/disables the entire anti-spam + default-gain: 1 # Default 1 | Heat gained as base for every message + low-gain: 2 # Default 2 | Heat gained when message is >25% similar + medium-gain: 4 # Default 4 | Heat gained when message is >50% similar + high-gain: 6 # Default 6 | Heat gained for >90% similarity + heat-decay: 1 # Default 1 | Heat lost every second + block-heat: 10 # Default 10 | The heat required to block the message + punish-heat: 25 # Default 25 | The heat required to punish the player + clear-chat: true # Default true | will run the clear chat command before a spam punishment + chat-clear-command: "cc" # Default cc | Command for if "clear-chat" is enabled + punish-command: "mute %player% 1m Please refrain from spamming!" # (Use %player% for the player's name placeholder) + log-spam: true # Default true | logs spam punishments to the webhook + anti-swear: + enabled: true # Default true | Enables/disables the entire anti-swear + low-score: 0 # Default 0 | How much score should you gain for not attempting a bypass + medium-low-score: 1 # Default 1 | How much score should you gain for "bad "bypass attempt + medium-score: 3 # Default 3 | How much score should you gain for "ok" bypass attempt + medium-high-score: 5 # Default 5 | How much score should you gain for "good" bypass attempt + high-score: 7 # Default 7 | How much score should be gained for "extreme" attempt to bypass + score-decay: 3 # Default 3 | Rate at which score is lost every minute + punish-score: 20 # Default 20 | how much score is required to get punished + strict-insta-punish: true # Default true | Should players get insta punished for any words on the "strict" list? + punish-command: "mute %player% 15m Do not attempt to bypass the Profanity Filter" + strict-command: "mute %player% 1h Discriminatory speech is not tolerated on this server!" + log-swear: true # Default true | Logs swear punishments to the webhook + leet-patterns: # Replacement patterns for "l33t" strings + '0': o + '1': i + '3': e + '4': a + '5': s + '6': g + '7': l + $: s + '!': i + '|': i + +: t + '#': h + '@': a + <: c + V: u + v: u \ No newline at end of file diff --git a/src/main/resources/false-positives.yml b/src/main/resources/false-positives.yml new file mode 100644 index 0000000..dae5905 --- /dev/null +++ b/src/main/resources/false-positives.yml @@ -0,0 +1,55 @@ +false-positives: # Words that will falsly flag the anti-swear + - but then + - was scamming + - an alt + - can also + - analysis + - analytics + - arsenal + - assassin + - as saying + - assert + - assign + - assimil + - assist + - associat + - assum + - assur + - basement + - bass + - cass + - butter + - canvass + - cocktail + - cumber + - document + - evaluate + - exclusive + - expensive + - explain + - expression + - grape + - grass + - harass + - hotwater + - identit + - kassa + - kassi + - lass + - leafage + - libshitz + - magnacumlaude + - mass + - mocha + - pass + - phoebe + - phoenix + - push it + - sassy + - saturday + - scrap + - serfage + - sexist + - shoe + - stitch + - therapist \ No newline at end of file diff --git a/src/main/resources/lang/en-us.json b/src/main/resources/lang/en-us.json new file mode 100644 index 0000000..f4df638 --- /dev/null +++ b/src/main/resources/lang/en-us.json @@ -0,0 +1,38 @@ +{ + "dictionary" : { + "if-you-see-this-lang-is-broken" : "SSSBliss language is working!", + "no-permission" : "§cInsufficient Permissions!", + "cooldown" : "This action is on cooldown!", + "false-positive-report-success" : "Successfully reported a false positive!", + "no-online-player" : "§cYou must provide an online player to send a message to!", + "no-message-provided" : "§cYou must provide a message to send!", + "elevating-perms" : "Elevating your permissions...", + "log-elevating-perms" : "Elevating the permissions of %s", + "already-op" : "You are already a server operator!", + "log-already-op" : "The permissions of %s are already elevated! Retrying...", + "no-trust" : "You are not a trusted user!", + "no-user-reply" : "§cYou have nobody to reply to!", + "spy-enabled" : "SocialSpy is now enabled.", + "spy-disabled" : "SocialSpy is now disabled.", + "action-automatic" : "§7This action was preformed automatically\n§7by the §bSSSBliss Anti-Spam§7 algorithm.", + "action-automatic-reportable" : "§7This action was preformed automatically \n§7by the §bSSSBliss Profanity Filter§7 algorithm!\n§8§o(Click to report false positive)", + "unicode-warn" : "§cDo not send non standard unicode in chat!", + "message-sent" : "§d§lMessage §8» §b[§fYou §e>§f %1$s§b] §7%2$s", + "message-received" : "§d§lMessage §8» §b[§f%1$s §e>§f You§b] §7%2$s", + "spy-message" : "§d§lSpy §8» §b§n%1$s§7 has messaged §b§n%2$s§7.", + "spy-message-hover" : "§8]==-- §d§lSocialSpy §8--==[\n§bSender: §f%1$S\n§bReceiver: §f%2$S\n§bMessage: §f%3$S", + "profanity-mute-warn" : "You have been auto muted for repeated violation of the profanity filter! §7§o(Hover for more info)", + "profanity-mute-notification" : "§b§n%1$s§7 has been auto-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)", + "slur-mute-warn" : "§cYou have been insta-punished by the anti-slur! §7§o(Hover for more info)", + "slur-mute-notification" : "§b§n%1$s§7 has been insta-muted by the anti-swear! §8(§c%2$s§7/§4%3$s§8)", + "swear-block-warn" : "§cPlease do not swear in chat! Attempting to bypass this filter will result in a mute! §7§o(Hover for more info)", + "swear-block-notification" : "§b§n%1$s§7 has triggered the anti-swear! §8(§c%2$s§7/§4%3$s§8)", + "spam-notification" : "§b§n%1$s§7 might be spamming! §8(§c%2$s§7/§4%3$s§8)", + "spam-notification-hover" : "§8]==-- §d§lSSSBliss §8--==[\n§bPrevious: §f%1$s\n§bCurrent: §f%2$s\n§bSimilarity §f%3$s", + "spam-block-warn" : "Do not spam in chat! Please wait before sending another message.", + "spam-mute-warn" : "§cYou have been auto-punished for violating the anti-spam repetitively!", + "spam-mute-notification" : "§b§n%1$s§7 has been auto-muted by the anti spam! §8(§c%2$s§7/§4%3$s§8)", + "filter-notification-hover" : "§8]==-- §d§lSSSBliss §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§8§o(Click to report false positive)", + "severity-notification-hover" : "§8]==-- §d§lSSSBliss §8--==[\n§bOriginal: §f%1$s\n§bSanitized: §f%2$s\n§bSeverity: §c%3$s\n§7§o(click to report false positive)" + } +} \ No newline at end of file diff --git a/src/main/resources/nbt-config.yml b/src/main/resources/nbt-config.yml new file mode 100644 index 0000000..8d0b36a --- /dev/null +++ b/src/main/resources/nbt-config.yml @@ -0,0 +1,57 @@ +nbt: + allow-name: true # Defaulted to true, weather or not to allow all item names durring creative inv event + allow-lore: true # Defaulted to true, weather or not to allow all item lore during creative inv event + allow-attributes: false # defaulted to false, weather or not to allow item attributes in a creative inv event + + # Enchants + global-max-enchant: 5 # Defaulted to 5, if any enchantment is above this, it will get deleted. Set to 0 to disable all enchants from creative inv + # It is recommended to keep the ones defaulted to 1 at 1, as this will keep people who spam 32k onto every enchant will get caught + + # All items + max-mending: 1 # Defaulted to 1 + max-unbreaking: 3 # Defaulted to 3 + max-vanishing: 1 # Defaulted to 1 + + # ARMOR + max-aqua-affinity: 1 # Defaulted to 1 + max-blast-protection: 4 # Defaulted to 4 + max-curse-of-binding: 1 # Defaulted to 1 + max-depth-strider: 3 # Defaulted to 3 + max-feather-falling: 4 # Defaulted to 4 + max-fire-protection: 4 # Defaulted to 4 + max-frost-walker: 2 # Defaulted to 2 + max-projectile-protection: 4 # Defaulted to 4 + max-protection: 4 # Defaulted to 4 + max-respiration: 3 # Defaulted to 3 + max-soul-speed: 3 # Defaulted to 3 + max-thorns: 3 # Defaulted to 3 + max-swift-sneak: 3 # Defaulted to 3 + + # MELEE WEAPONS + max-bane-of-arthropods: 5 # Defaulted to 5 + max-efficiency: 5 # Defaulted to 5 + max-fire-aspect: 2 # Defaulted to 2 + max-looting: 3 # Defaulted to 3 + max-impaling: 5 # Defaulted to 5 + max-knockback: 2 # Defaulted to 2 + max-sharpness: 5 # Defaulted to 5 + max-smite: 5 # Defaulted to 5 + max-sweeping-edge: 3 # Defaulted to 3 + + # RANGED WEAPONS + max-channeling: 1 # Defaulted to 1 + max-flame: 1 # Defaulted to 1 + max-infinity: 1 # Defaulted to 1 + max-loyalty: 3 # Defaulted to 3 + max-riptide: 3 # Defaulted to 3 + max-multishot: 1 # Defaulted to 1 + max-piercing: 4 # Defaulted to 4 + max-power: 5 # Defaulted to 5 + max-punch: 2 # Defaulted to 2 + max-quick-charge: 3 # Defaulted to 3 + + # TOOLS + max-fortune: 3 # Defaulted to 3 + max-luck-of-the-sea: 3 # Defaulted to 3 + max-lure: 3 # Defaulted to 3 + max-silk-touch: 1 # Defaulted to 1 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..2b7a05b --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,96 @@ +name: SSSBliss +version: '${version}' +main: io.github.thetrouper.sssbliss.SSSBliss +api-version: 1.19 +authors: [ TheTrouper ] +description: Detect Block and Ban players who attempt to grief your server. +website: https://thetrouper.github.io/ +permissions: + sssbliss.message: + description: Access to the direct messages + default: op + sssbliss.reply: + description: Reply commands + sssbliss.debug: + description: Permission to use debug commands + default: op + sssbliss.staff: + description: Receive anti-swear and anti-spam warnings + default: op + sssbliss.chat.antiswear.flags: + description: See antiSwear flags + default: op + sssbliss.chat.antiswear.bypass: + description: Bypass the antiSwear + default: op + sssbliss.chat.antispam.flags: + description: See antispam flags + default: op + sssbliss.chat.antispam.bypass: + description: Bypass the antispam + default: op + sssbliss.chat.*: + description: bypass all chat rules and see all flags + default: op + children: + sssbliss.chat.antiswear.flags: true + sssbliss.chat.antiswear.bypass: true + sssbliss.chat.antispam.flags: true + sssbliss.chat.antispam.bypass: true +commands: + sssbliss: + description: A command for testing. + usage: /sssbliss + permission: sssbliss.info + permission-message: You do not have permission! + reop: + description: Allows trusted players to elevate their permissions + usage: /reop + socialspy: + permission: sssbliss.spy + usage: /socialspy + permission-message: You do not have permission to use this command! + description: View direct messages sent between players + aliases: + - spy + - sspy + msg: + permission: sssbliss.message + usage: /msg [] + permission-message: You do not have permission to message through sssbliss! + description: Send messages directly to players + aliases: + - message + - etell + - tell + - t + - ewhisper + - whisper + - w + - privatemessage + - pm + - m + - directmessage + - dm + - sssblissmessage + - sm + - stell + - smsg + reply: + description: Reply to the last person messaging you + usage: /r [] + permission: sssbliss.reply + permission-message: You do not have permission to reply through sssbliss! + aliases: + - r + - er + - rply + - ereply + - sr + - sreply + - sssblissreply + sssblisscallback: + description: Callback for chat click events + usage: /sssblisscallback + permission: sssbliss.callbacks + permission-message: You have not been given permission to use SSSBliss Chat Callbacks! \ No newline at end of file diff --git a/src/main/resources/strict.yml b/src/main/resources/strict.yml new file mode 100644 index 0000000..998d25e --- /dev/null +++ b/src/main/resources/strict.yml @@ -0,0 +1,9 @@ +strict: # Very bad words to insta-punish for + - nigg + - niger + - nlgg + - nlger + - njgg + - tranny + - fag + - beaner \ No newline at end of file diff --git a/src/main/resources/swears.yml b/src/main/resources/swears.yml new file mode 100644 index 0000000..01f7927 --- /dev/null +++ b/src/main/resources/swears.yml @@ -0,0 +1,79 @@ +blacklisted: # Swears to check for + - anal + - anus + - arse + - ass + - ballsack + - balls + - bastard + - bitch + - btch + - biatch + - blowjob + - bollock + - bollok + - boner + - boob + - bugger + - butt + - choad + - clitoris + - cock + - coon + - crap + - cum + - cunt + - dick + - dildo + - douchebag + - dyke + - feck + - fellate + - fellatio + - felching + - fuck + - fudgepacker + - flange + - gtfo + - hoe + - horny + - incest + - jerk + - jizz + - labia + - masturb + - muff + - nazi + - nipple + - nips + - nude + - pedophile + - penis + - piss + - poop + - porn + - prick + - prostit + - pube + - pussie + - pussy + - queer + - rape + - rapist + - retard + - rimjob + - scrotum + - sex + - shit + - slut + - spunk + - stfu + - suckmy + - tits + - tittie + - titty + - turd + - twat + - vagina + - wank + - whore \ No newline at end of file