From f23c44bbd2ef4a1e75f72b396fd547332952f9ca Mon Sep 17 00:00:00 2001 From: thetrouper Date: Sun, 1 Jun 2025 08:59:14 -0500 Subject: [PATCH] Initial Commit --- .gitignore | 42 +++ .idea/.gitignore | 5 + .idea/gradle.xml | 17 + .idea/misc.xml | 7 + .idea/vcs.xml | 6 + build.gradle | 59 +++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 234 ++++++++++++ gradlew.bat | 89 +++++ run/plugins/Guns-0.0.9.jar | Bin 0 -> 181562 bytes settings.gradle | 1 + src/main/java/me/trouper/alias/Alias.java | 46 +++ src/main/java/me/trouper/alias/data/IO.java | 37 ++ .../java/me/trouper/alias/data/io/Config.java | 34 ++ .../me/trouper/alias/data/io/Storage.java | 22 ++ .../java/me/trouper/alias/server/Main.java | 71 ++++ .../java/me/trouper/alias/server/Manager.java | 43 +++ .../alias/server/commands/ExampleCommand.java | 22 ++ .../alias/server/events/ExampleEvent.java | 11 + .../alias/server/events/QuickListener.java | 12 + .../server/systems/builders/ItemBuilder.java | 103 +++++ .../alias/server/systems/gui/CustomGui.java | 195 ++++++++++ .../server/systems/gui/RegistryListeners.java | 38 ++ .../server/systems/items/CustomItem.java | 71 ++++ .../server/systems/items/ItemManager.java | 160 ++++++++ .../server/systems/items/ItemRegistry.java | 13 + .../me/trouper/alias/utils/ItemUtils.java | 129 +++++++ .../me/trouper/alias/utils/PlayerUtils.java | 79 ++++ .../me/trouper/alias/utils/SoundPlayer.java | 266 +++++++++++++ .../trouper/alias/utils/TargetingUtils.java | 282 ++++++++++++++ .../java/me/trouper/alias/utils/Text.java | 312 ++++++++++++++++ .../java/me/trouper/alias/utils/Verbose.java | 70 ++++ .../me/trouper/alias/utils/command/Args.java | 115 ++++++ .../alias/utils/command/CommandRegistry.java | 17 + .../alias/utils/command/Permission.java | 14 + .../alias/utils/command/QuickCommand.java | 99 +++++ .../completions/CompletionBuilder.java | 123 ++++++ .../command/completions/CompletionNode.java | 88 +++++ .../trouper/alias/utils/misc/ArrayUtils.java | 71 ++++ .../me/trouper/alias/utils/misc/Cooldown.java | 42 +++ .../alias/utils/misc/FileValidationUtils.java | 21 ++ .../alias/utils/misc/JsonSerializable.java | 149 ++++++++ .../trouper/alias/utils/misc/Randomizer.java | 81 ++++ .../me/trouper/alias/utils/misc/Voidable.java | 59 +++ .../alias/utils/nbt/PersistentData.java | 59 +++ .../utils/nbt/PersistentDataSerializable.java | 17 + .../utils/visual/BlockDisplayRaytracer.java | 351 ++++++++++++++++++ .../utils/visual/CustomDisplayRaytracer.java | 317 ++++++++++++++++ .../alias/utils/visual/DisplayUtils.java | 247 ++++++++++++ .../me/trouper/alias/utils/visual/Point.java | 88 +++++ .../alias/utils/visual/ReflectionResult.java | 27 ++ src/main/resources/plugin.yml | 8 + 53 files changed, 4475 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 run/plugins/Guns-0.0.9.jar create mode 100644 settings.gradle create mode 100644 src/main/java/me/trouper/alias/Alias.java create mode 100755 src/main/java/me/trouper/alias/data/IO.java create mode 100755 src/main/java/me/trouper/alias/data/io/Config.java create mode 100755 src/main/java/me/trouper/alias/data/io/Storage.java create mode 100755 src/main/java/me/trouper/alias/server/Main.java create mode 100755 src/main/java/me/trouper/alias/server/Manager.java create mode 100644 src/main/java/me/trouper/alias/server/commands/ExampleCommand.java create mode 100644 src/main/java/me/trouper/alias/server/events/ExampleEvent.java create mode 100755 src/main/java/me/trouper/alias/server/events/QuickListener.java create mode 100644 src/main/java/me/trouper/alias/server/systems/builders/ItemBuilder.java create mode 100644 src/main/java/me/trouper/alias/server/systems/gui/CustomGui.java create mode 100644 src/main/java/me/trouper/alias/server/systems/gui/RegistryListeners.java create mode 100644 src/main/java/me/trouper/alias/server/systems/items/CustomItem.java create mode 100644 src/main/java/me/trouper/alias/server/systems/items/ItemManager.java create mode 100644 src/main/java/me/trouper/alias/server/systems/items/ItemRegistry.java create mode 100755 src/main/java/me/trouper/alias/utils/ItemUtils.java create mode 100755 src/main/java/me/trouper/alias/utils/PlayerUtils.java create mode 100755 src/main/java/me/trouper/alias/utils/SoundPlayer.java create mode 100755 src/main/java/me/trouper/alias/utils/TargetingUtils.java create mode 100755 src/main/java/me/trouper/alias/utils/Text.java create mode 100755 src/main/java/me/trouper/alias/utils/Verbose.java create mode 100755 src/main/java/me/trouper/alias/utils/command/Args.java create mode 100755 src/main/java/me/trouper/alias/utils/command/CommandRegistry.java create mode 100755 src/main/java/me/trouper/alias/utils/command/Permission.java create mode 100755 src/main/java/me/trouper/alias/utils/command/QuickCommand.java create mode 100755 src/main/java/me/trouper/alias/utils/command/completions/CompletionBuilder.java create mode 100755 src/main/java/me/trouper/alias/utils/command/completions/CompletionNode.java create mode 100755 src/main/java/me/trouper/alias/utils/misc/ArrayUtils.java create mode 100755 src/main/java/me/trouper/alias/utils/misc/Cooldown.java create mode 100755 src/main/java/me/trouper/alias/utils/misc/FileValidationUtils.java create mode 100755 src/main/java/me/trouper/alias/utils/misc/JsonSerializable.java create mode 100755 src/main/java/me/trouper/alias/utils/misc/Randomizer.java create mode 100755 src/main/java/me/trouper/alias/utils/misc/Voidable.java create mode 100644 src/main/java/me/trouper/alias/utils/nbt/PersistentData.java create mode 100644 src/main/java/me/trouper/alias/utils/nbt/PersistentDataSerializable.java create mode 100755 src/main/java/me/trouper/alias/utils/visual/BlockDisplayRaytracer.java create mode 100755 src/main/java/me/trouper/alias/utils/visual/CustomDisplayRaytracer.java create mode 100755 src/main/java/me/trouper/alias/utils/visual/DisplayUtils.java create mode 100755 src/main/java/me/trouper/alias/utils/visual/Point.java create mode 100755 src/main/java/me/trouper/alias/utils/visual/ReflectionResult.java create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..a0ccf77 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..d28243b --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5cd9a10 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..0f3a155 --- /dev/null +++ b/build.gradle @@ -0,0 +1,59 @@ +plugins { + id 'java' + id("xyz.jpenilla.run-paper") version "2.3.1" +} + +group = 'me.trouper' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() + maven { + name = "papermc-repo" + url = "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.21.5-R0.1-SNAPSHOT") +} + +tasks { + runServer { + // Configure the Minecraft version for our task. + // This is the only required configuration besides applying the plugin. + // Your plugin's jar (or shadowJar if present) will be used automatically. + minecraftVersion("1.21.5") + } +} + +def targetJavaVersion = 21 +java { + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + sourceCompatibility = javaVersion + targetCompatibility = javaVersion + if (JavaVersion.current() < javaVersion) { + toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + + if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { + options.release.set(targetJavaVersion) + } +} + +processResources { + def props = [version: version] + inputs.properties props + filteringCharset 'UTF-8' + filesMatching('plugin.yml') { + expand props + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196 GIT binary patch literal 60756 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&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 + 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" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + 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 + +# 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 \ + "$@" + +# 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..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/run/plugins/Guns-0.0.9.jar b/run/plugins/Guns-0.0.9.jar new file mode 100644 index 0000000000000000000000000000000000000000..e76211415e553366bb39ca2133633d2a22e1cf70 GIT binary patch literal 181562 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

#0hN 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Μz)*x^E8pIgKspaJ7B`o|kj%>cv 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 ^8za%<7q>kjE`ISu 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 { + + public boolean debugMode = false; + public List debuggerExclusions = new ArrayList<>(); + + @Override + public File getFile() { + return me.trouper.alias.Alias.getInstance().getManager().io.CONFIG_FILE; + } + + @Override + public void save() { + Verbose.send(1,"Saving Config..."); + JsonSerializable.super.save(); + } + + public Messages messages = new Messages(); + + public class Messages { + public String mainColor = "&#ffaaff"; + public String prefix = "&9Alias> &7"; + public String pluginName = "Alias"; + public boolean fancyAlerts = true; + } +} diff --git a/src/main/java/me/trouper/alias/data/io/Storage.java b/src/main/java/me/trouper/alias/data/io/Storage.java new file mode 100755 index 0000000..0995bb7 --- /dev/null +++ b/src/main/java/me/trouper/alias/data/io/Storage.java @@ -0,0 +1,22 @@ +package me.trouper.alias.data.io; + +import me.trouper.alias.utils.Verbose; +import me.trouper.alias.utils.misc.JsonSerializable; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class Storage implements JsonSerializable { + + @Override + public File getFile() { + return me.trouper.alias.Alias.getInstance().getManager().io.STORAGE_FILE; + } + + @Override + public void save() { + Verbose.send(1,"Saving Storage..."); + JsonSerializable.super.save(); + } +} diff --git a/src/main/java/me/trouper/alias/server/Main.java b/src/main/java/me/trouper/alias/server/Main.java new file mode 100755 index 0000000..372b12d --- /dev/null +++ b/src/main/java/me/trouper/alias/server/Main.java @@ -0,0 +1,71 @@ +package me.trouper.alias.server; + +import io.papermc.paper.registry.RegistryAccess; +import me.trouper.alias.data.IO; +import me.trouper.alias.data.io.Config; +import me.trouper.alias.data.io.Storage; +import me.trouper.alias.utils.Text; +import org.bukkit.command.CommandSender; + +import java.util.Random; +import java.util.function.BooleanSupplier; + +public interface Main { + Main main = new Main() {}; + + Random random = new Random(); + + default RegistryAccess getRegistryAccess() { + return RegistryAccess.registryAccess(); + } + + default me.trouper.alias.Alias getPlugin() { + return me.trouper.alias.Alias.getInstance(); + } + + default Manager man() { + return getPlugin().getManager(); + } + + default IO io() { + return man().io; + }; + + default Config config() { + return io().config; + } + + default Storage storage() { + return io().storage; + } + + default void info(CommandSender player, String message, Object... args) { + Text.sendMessage(Text.Pallet.INFO, player, message, args); + } + + default void error(CommandSender player, String message, Object... args) { + Text.sendMessage(Text.Pallet.ERROR, player, message, args); + } + + default void warning(CommandSender player, String message, Object... args) { + Text.sendMessage(Text.Pallet.WARNING, player, message, args); + } + + default void success(CommandSender player, String message, Object... args) { + Text.sendMessage(Text.Pallet.SUCCESS, player, message, args); + } + + default void message(CommandSender player, String message, Object... args) { + Text.sendMessage(Text.Pallet.NEUTRAL, player, message, args); + } + + default void checkPre(boolean check, String msg, Object... args) { + if (!check) { + throw new IllegalArgumentException(msg.formatted(args)); + } + } + + default void checkPre(BooleanSupplier check, String msg, Object... args) { + checkPre(check.getAsBoolean(), msg, args); + } +} diff --git a/src/main/java/me/trouper/alias/server/Manager.java b/src/main/java/me/trouper/alias/server/Manager.java new file mode 100755 index 0000000..a9d2f73 --- /dev/null +++ b/src/main/java/me/trouper/alias/server/Manager.java @@ -0,0 +1,43 @@ +package me.trouper.alias.server; + +import me.trouper.alias.data.IO; +import me.trouper.alias.server.commands.ExampleCommand; +import me.trouper.alias.server.events.ExampleEvent; +import me.trouper.alias.server.systems.gui.RegistryListeners; +import me.trouper.alias.utils.visual.BlockDisplayRaytracer; +import org.bukkit.Bukkit; + +public class Manager { + public IO io; + // Define backends here + + public Manager() { + io = new IO(); + // Instantiate backends here + } + + + public void init() { + io.loadAll(); + + registerEvents(); + registerCommands(); + + cleanup(); + } + + + private void registerCommands() { + new ExampleCommand().register(); + } + + private void registerEvents() { + new RegistryListeners().registerEvents(); // Must be called for any GUI to work! + new ExampleEvent().registerEvents(); + } + + private void cleanup() { + BlockDisplayRaytracer.cleanup(); + } + +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/server/commands/ExampleCommand.java b/src/main/java/me/trouper/alias/server/commands/ExampleCommand.java new file mode 100644 index 0000000..06694ae --- /dev/null +++ b/src/main/java/me/trouper/alias/server/commands/ExampleCommand.java @@ -0,0 +1,22 @@ +package me.trouper.alias.server.commands; + +import me.trouper.alias.utils.command.Args; +import me.trouper.alias.utils.command.CommandRegistry; +import me.trouper.alias.utils.command.QuickCommand; +import me.trouper.alias.utils.command.completions.CompletionBuilder; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +@CommandRegistry(value = "example") +public class ExampleCommand implements QuickCommand { + + @Override + public void dispatchCommand(CommandSender sender, Command command, String label, Args args) { + success(sender,"Hello, World!"); + } + + @Override + public void dispatchCompletions(CommandSender sender, Command command, String label, CompletionBuilder b) { + + } +} diff --git a/src/main/java/me/trouper/alias/server/events/ExampleEvent.java b/src/main/java/me/trouper/alias/server/events/ExampleEvent.java new file mode 100644 index 0000000..6793326 --- /dev/null +++ b/src/main/java/me/trouper/alias/server/events/ExampleEvent.java @@ -0,0 +1,11 @@ +package me.trouper.alias.server.events; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +public class ExampleEvent implements QuickListener { + @EventHandler + public void onJoin(PlayerJoinEvent e) { + info(e.getPlayer(),"This server is running Alias v{0}.",main.getPlugin().getDescription().getVersion()); + } +} diff --git a/src/main/java/me/trouper/alias/server/events/QuickListener.java b/src/main/java/me/trouper/alias/server/events/QuickListener.java new file mode 100755 index 0000000..1c41f3a --- /dev/null +++ b/src/main/java/me/trouper/alias/server/events/QuickListener.java @@ -0,0 +1,12 @@ +package me.trouper.alias.server.events; + +import me.trouper.alias.server.Main; +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; + +public interface QuickListener extends Listener, Main { + default QuickListener registerEvents() { + Bukkit.getPluginManager().registerEvents(this, this.getPlugin()); + return this; + } +} diff --git a/src/main/java/me/trouper/alias/server/systems/builders/ItemBuilder.java b/src/main/java/me/trouper/alias/server/systems/builders/ItemBuilder.java new file mode 100644 index 0000000..334cfe9 --- /dev/null +++ b/src/main/java/me/trouper/alias/server/systems/builders/ItemBuilder.java @@ -0,0 +1,103 @@ +package me.trouper.alias.server.systems.builders; + +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +public class ItemBuilder { + + private ItemStack stack; + private ItemMeta meta; + + public ItemBuilder() { + this(new ItemStack(Material.STONE)); + } + + public ItemBuilder(ItemStack stack) { + this.stack = stack; + this.meta = this.stack.getItemMeta(); + } + + public ItemBuilder material(Material m) { + stack.setType(m); + return this; + } + + public ItemBuilder name(String s) { + meta.setDisplayName(s); + return this; + } + + public ItemBuilder lore(String s) { + List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); + lore.add(s); + meta.setLore(lore); + return this; + } + + public ItemBuilder lore(Iterable s) { + s.forEach(this::lore); + return this; + } + + public ItemBuilder count(int c) { + stack.setAmount(c); + return this; + } + + public ItemBuilder enchant(Enchantment e, int level) { + meta.addEnchant(e,level,true); + return this; + } + + public ItemBuilder flag(ItemFlag... f) { + meta.addItemFlags(f); + return this; + } + + public ItemBuilder attribute(Attribute a, AttributeModifier am) { + meta.addAttributeModifier(a,am); + return this; + } + + public ItemBuilder unbreakable(boolean b) { + meta.setUnbreakable(b); + return this; + } + + public ItemBuilder customModelData(int d) { + meta.setCustomModelData(d); + return this; + } + + public ItemBuilder runTaskItem(Function task) { + this.stack = task.apply(build()); + return this; + } + + public ItemBuilder runTaskMeta(Function task) { + this.meta = task.apply(meta); + return this; + } + + public ItemStack build() { + stack.setItemMeta(meta); + return stack; + } + + public static ItemBuilder create() { + return new ItemBuilder(); + } + + public static ItemBuilder create(ItemStack item) { + return new ItemBuilder(item); + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/server/systems/gui/CustomGui.java b/src/main/java/me/trouper/alias/server/systems/gui/CustomGui.java new file mode 100644 index 0000000..5688d8b --- /dev/null +++ b/src/main/java/me/trouper/alias/server/systems/gui/CustomGui.java @@ -0,0 +1,195 @@ +package me.trouper.alias.server.systems.gui; + +import org.bukkit.Bukkit; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +public class CustomGui { + + private static final Map registry = new HashMap<>(); + private final Map slotActions; + private final Map slotDisplays; + private final InvAction mainAction; + private final CreateAction createAction; + private final CloseAction closeAction; + private final String title; + private final int size; + + public CustomGui(String title, int size, InvAction mainAction, Map slotActions, Map slotDisplays, CreateAction createAction, CloseAction closeAction) { + this.slotActions = slotActions; + this.slotDisplays = slotDisplays; + this.mainAction = mainAction; + this.createAction = createAction; + this.closeAction = closeAction; + this.title = title; + this.size = size; + } + + public static CustomGui register(CustomGui gui) { + if (gui != null) { + registry.put(gui.getTitle(), gui); + } + return gui; + } + + public static Map registries() { + return new HashMap<>(registry); + } + + public static void handleRegistriesClick(InventoryClickEvent event) { + String title = event.getView().getTitle(); + if (registry.containsKey(title)) { + registry.get(title).onInventoryClick(event); + } + } + + public static void handleRegistriesClose(InventoryCloseEvent event) { + String title = event.getView().getTitle(); + if (registry.containsKey(title)) { + registry.get(title).onInventoryClose(event); + } + } + + public Inventory getInventory() { + int size = this.size; + + if (size % 9 != 0) { + int max = slotActions.keySet().stream().sorted(Comparator.comparing(i -> (int)i).reversed()).toList().get(0); + int add = max % 9 == 0 ? 0 : 1; + size = (int)(Math.floor(max / 9.0) + add) * 9; + } + + Inventory inv = Bukkit.createInventory(null, size, title); + createAction.onCreate(inv); + slotDisplays.forEach(inv::setItem); + + return inv; + } + + public void onInventoryClick(InventoryClickEvent event) { + if (!event.isCancelled() && event.getClickedInventory() != null && event.getClickedInventory().getType() != InventoryType.PLAYER) { + mainAction.onClick(event); + if (slotActions.containsKey(event.getSlot())) { + slotActions.get(event.getSlot()).onClick(event); + } + } + } + + public void onInventoryClose(InventoryCloseEvent event) { + closeAction.onClose(event); + } + + public String getTitle() { + return title; + } + + public Map getSlotActions() { + return slotActions; + } + + public Map getSlotDisplays() { + return slotDisplays; + } + + public CreateAction getCreateAction() { + return createAction; + } + + public CloseAction getCloseAction() { + return closeAction; + } + + public int getInvSize() { + return size; + } + + + + public static GuiBuilder create() { + return new GuiBuilder(); + } + + public static class GuiBuilder { + private InvAction mainAction; + private CreateAction createAction; + private CloseAction closeAction; + private final Map slotActions; + private final Map slotDisplay; + private String title; + private int size; + + public GuiBuilder() { + this.title = "Untitled Inventory"; + this.size = -1; + this.mainAction = event -> {}; + this.createAction = inv -> {}; + this.closeAction = event -> {}; + this.slotActions = new HashMap<>(); + this.slotDisplay = new HashMap<>(); + } + + public GuiBuilder title(String text) { + title = text; + return this; + } + + public GuiBuilder size(int size) { + this.size = size; + return this; + } + + public GuiBuilder onDefine(CreateAction action) { + createAction = action; + return this; + } + + public GuiBuilder onClose(CloseAction action) { + closeAction = action; + return this; + } + + public GuiBuilder defineMain(InvAction mainAction) { + this.mainAction = mainAction; + return this; + } + + public GuiBuilder define(int slot, ItemStack display, InvAction action) { + if (slot < 0 || slot >= 54 || display == null || action == null) return this; + slotActions.put(slot, action); + slotDisplay.put(slot, display); + return this; + } + + public GuiBuilder define(int slot, ItemStack display) { + return define(slot, display, event -> {}); + } + + public CustomGui build() { + CustomGui gui = new CustomGui(title, size, mainAction, slotActions, slotDisplay, createAction, closeAction); + CustomGui.register(gui); + return gui; + } + } + + @FunctionalInterface + public interface InvAction { + void onClick(InventoryClickEvent event); + } + + @FunctionalInterface + public interface CloseAction { + void onClose(InventoryCloseEvent event); + } + + @FunctionalInterface + public interface CreateAction { + void onCreate(Inventory inv); + } +} diff --git a/src/main/java/me/trouper/alias/server/systems/gui/RegistryListeners.java b/src/main/java/me/trouper/alias/server/systems/gui/RegistryListeners.java new file mode 100644 index 0000000..9acaeb6 --- /dev/null +++ b/src/main/java/me/trouper/alias/server/systems/gui/RegistryListeners.java @@ -0,0 +1,38 @@ +package me.trouper.alias.server.systems.gui; + +import me.trouper.alias.server.events.QuickListener; +import me.trouper.alias.server.systems.items.CustomItem; +import me.trouper.alias.server.systems.items.ItemManager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public class RegistryListeners implements QuickListener { + + @EventHandler + private void onClick(InventoryClickEvent e) { + try { + CustomGui.handleRegistriesClick(e); + } + catch (Exception ignore) {} + } + + @EventHandler + private void onClose(InventoryCloseEvent e) { + try { + CustomGui.handleRegistriesClose(e); + } + catch (Exception ignore) {} + } + + @EventHandler + private void onInteract(PlayerInteractEvent e) { + try { + CustomItem context = ItemManager.getItemContext(e.getItem(), CustomItem.class); + if (context != null) + context.onInteract(e); + } + catch (Exception ignore) {} + } +} diff --git a/src/main/java/me/trouper/alias/server/systems/items/CustomItem.java b/src/main/java/me/trouper/alias/server/systems/items/CustomItem.java new file mode 100644 index 0000000..2fe9edd --- /dev/null +++ b/src/main/java/me/trouper/alias/server/systems/items/CustomItem.java @@ -0,0 +1,71 @@ +package me.trouper.alias.server.systems.items; + +import com.google.gson.Gson; +import me.trouper.alias.server.Main; +import me.trouper.alias.server.systems.builders.ItemBuilder; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +public abstract class CustomItem implements Main { + + public abstract void createItem(ItemBuilder item); + + public abstract void updateMeta(ItemMeta meta); + + public abstract void onInteract(PlayerInteractEvent e); + + public String serialize() { + try { + Gson gson = new Gson(); + return gson.toJson(this); + } + catch (Exception ex) { + return "{}"; + } + } + + public String getRegistryKey() { + ItemRegistry r = this.getClass().getAnnotation(ItemRegistry.class); + if (r == null) + throw new IllegalArgumentException("Custom items need to have @ItemRegistry annotation!"); + return r.value(); + } + + public void register(Object... initArgs) { + try { + Class[] signature = Arrays.stream(initArgs).map(Object::getClass).toArray(Class[]::new); + CustomItem item = this.getClass().getDeclaredConstructor(signature).newInstance(initArgs); + ItemManager.registerItem(getRegistryKey(), () -> item); + } + catch (Exception ex) { + throw new RuntimeException("Failed to register custom item: " + ex.getMessage()); + } + } + + public static String getDisplay(ItemStack item) { + if (item == null) { + return ""; + } + else if (item.hasItemMeta() && item.getItemMeta() != null && item.getItemMeta().hasDisplayName()) { + return item.getItemMeta().getDisplayName(); + } + else { + return item.getType().name().toLowerCase(); + } + } + + public static boolean matchDisplay(ItemStack a, ItemStack b) { + return getDisplay(a).equals(getDisplay(b)); + } + + public static boolean matchDisplay(String a, ItemStack b) { + return a.equals(getDisplay(b)); + } + + public static boolean matchDisplay(ItemStack a, String b) { + return getDisplay(a).equals(b); + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/server/systems/items/ItemManager.java b/src/main/java/me/trouper/alias/server/systems/items/ItemManager.java new file mode 100644 index 0000000..4890a92 --- /dev/null +++ b/src/main/java/me/trouper/alias/server/systems/items/ItemManager.java @@ -0,0 +1,160 @@ +package me.trouper.alias.server.systems.items; + +import com.google.gson.Gson; +import me.trouper.alias.server.Main; +import me.trouper.alias.server.systems.builders.ItemBuilder; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +public class ItemManager implements Main { + + private static final Gson gson = new Gson(); + private static final Map> itemRegistry = new HashMap<>(); + + public static NamespacedKey registerItem(String namespace, Supplier context) { + NamespacedKey key = new NamespacedKey(main.getPlugin(), "items/" + namespace); + itemRegistry.put(key, context); + return key; + } + + public static ItemStack createItemContext(String namespace) { + NamespacedKey key = new NamespacedKey(main.getPlugin(), "items/" + namespace); + Supplier registry = itemRegistry.get(key); + if (registry == null) + throw new IllegalArgumentException("context not found in item registry"); + + CustomItem context = registry.get(); + ItemBuilder builder = ItemBuilder.create(); + context.createItem(builder); + + ItemStack result = builder.build(); + if (result == null || !result.hasItemMeta()) + throw new IllegalArgumentException("the result item cannot be used as a custom item"); + + ItemMeta meta = result.getItemMeta(); + PersistentDataContainer data = meta.getPersistentDataContainer(); + + data.set(key, PersistentDataType.STRING, gson.toJson(context)); + context.updateMeta(meta); + result.setItemMeta(meta); + + return result; + } + + public static void setItemContext(ItemStack item, CustomItem context) { + if (item == null || !item.hasItemMeta()) + return; + + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer data = meta.getPersistentDataContainer(); + + for (NamespacedKey key : data.getKeys()) { + Supplier contextSupplier = itemRegistry.get(key); + if (contextSupplier == null) + continue; + + CustomItem customItem = contextSupplier.get(); + if (customItem != null && customItem.getClass() == context.getClass()) { + data.set(key, PersistentDataType.STRING, gson.toJson(context)); + context.updateMeta(meta); + item.setItemMeta(meta); + return; + } + } + } + + @SuppressWarnings({ "unchecked", "unused" }) + public static C getItemContext(ItemStack item, Class type) { + if (item == null || !item.hasItemMeta()) + return null; + + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer data = meta.getPersistentDataContainer(); + + for (NamespacedKey key : data.getKeys()) { + Supplier contextSupplier = itemRegistry.get(key); + if (contextSupplier == null) + continue; + + CustomItem customItem = contextSupplier.get(); + if (customItem != null) { + CustomItem parsed = gson.fromJson(data.get(key, PersistentDataType.STRING), customItem.getClass()); + if (parsed != null) + return (C)parsed; + } + } + + return null; + } + + public static C getOrDefItemContext(ItemStack item, Class type, C fallback) { + C context = getItemContext(item, type); + if (context != null) + return context; + + NamespacedKey key = getKeyOf(fallback); + if (key == null) + return fallback; + + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer data = meta.getPersistentDataContainer(); + + data.set(key, PersistentDataType.STRING, gson.toJson(fallback)); + fallback.updateMeta(meta); + item.setItemMeta(meta); + return fallback; + } + + public static NamespacedKey getKeyOf(CustomItem context) { + if (context == null) + return null; + + for (Map.Entry> entry : itemRegistry.entrySet()) + if (entry.getValue().get().getClass() == context.getClass()) + return entry.getKey(); + return null; + } + + public static CustomItem getItemContext(ItemStack item) { + return getItemContext(item, CustomItem.class); + } + + public static boolean isHolding(Player player, NamespacedKey item) { + ItemStack stack = player.getInventory().getItemInMainHand(); + return isItemMatching(item, stack); + } + + public static boolean isOffHolding(Player player, NamespacedKey item) { + ItemStack stack = player.getInventory().getItemInOffHand(); + return isItemMatching(item, stack); + } + + public static boolean isHoldingAny(Player player, NamespacedKey item) { + return isHolding(player, item) || isOffHolding(player, item); + } + + public static boolean isItemMatching(NamespacedKey key, ItemStack item) { + if (item == null || !item.hasItemMeta()) + return false; + + ItemMeta meta = item.getItemMeta(); + PersistentDataContainer data = meta.getPersistentDataContainer(); + return data.has(key); + } + + public static String[] collectNames() { + String[] str = new String[itemRegistry.size()]; + int i = 0; + for (NamespacedKey key : itemRegistry.keySet()) + str[i++] = key.getKey().replaceFirst("items/", ""); + return str; + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/server/systems/items/ItemRegistry.java b/src/main/java/me/trouper/alias/server/systems/items/ItemRegistry.java new file mode 100644 index 0000000..95f0380 --- /dev/null +++ b/src/main/java/me/trouper/alias/server/systems/items/ItemRegistry.java @@ -0,0 +1,13 @@ +package me.trouper.alias.server.systems.items; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ItemRegistry { + + String value(); +} diff --git a/src/main/java/me/trouper/alias/utils/ItemUtils.java b/src/main/java/me/trouper/alias/utils/ItemUtils.java new file mode 100755 index 0000000..a50730e --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/ItemUtils.java @@ -0,0 +1,129 @@ +package me.trouper.alias.utils; + +import com.google.common.collect.Multimap; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.List; +import java.util.Map; + +public class ItemUtils { + + public static boolean isArmor(ItemStack i) { + if (i == null || i.isEmpty()) return false; + + return isHelmet(i) || isChestplate(i) || isLeggings(i) || isBoots(i); + } + + public static boolean isHelmet(ItemStack i) { + if (i == null || i.isEmpty()) return false; + + Material m = i.getType(); + String n = m.name(); + return n.contains("HELMET"); + } + + public static boolean isChestplate(ItemStack i) { + if (i == null || i.isEmpty()) return false; + + Material m = i.getType(); + String n = m.name(); + return n.contains("CHESTPLATE"); + } + + public static boolean isLeggings(ItemStack i) { + if (i == null || i.isEmpty()) return false; + + Material m = i.getType(); + String n = m.name(); + return n.contains("LEGGINGS"); + } + + public static boolean isBoots(ItemStack i) { + if (i == null || i.isEmpty()) return false; + + Material m = i.getType(); + String n = m.name(); + return n.contains("BOOTS"); + } + + @SuppressWarnings("deprecation") + public static boolean isSimilar(ItemStack item1, ItemStack item2) { + if (item1 == null || item2 == null) { + Verbose.send("One of the items is null: item1: %s, item2: %s", item1, item2); + return false; + } + + Material type1 = item1.getType(); + Material type2 = item2.getType(); + boolean typeEqual = type1 == type2; + Verbose.send("Checking Material: item1 type: %s, item2 type: %s, equal: %s", type1, type2, typeEqual); + if (!typeEqual) return false; + + boolean hasMeta1 = item1.hasItemMeta(); + boolean hasMeta2 = item2.hasItemMeta(); + boolean metaExistEqual = (hasMeta1 == hasMeta2); + Verbose.send("Checking ItemMeta existence: item1 has meta: %s, item2 has meta: %s, equal: %s", hasMeta1, hasMeta2, metaExistEqual); + if (!metaExistEqual) return false; + + if (!hasMeta1 && !hasMeta2) { + return true; + } + + ItemMeta meta1 = item1.getItemMeta(); + ItemMeta meta2 = item2.getItemMeta(); + + String name1 = meta1.hasDisplayName() ? meta1.getDisplayName() : null; + String name2 = meta2.hasDisplayName() ? meta2.getDisplayName() : null; + if (name1 == null ^ name2 == null) { + Verbose.send("Custom Name mismatch: item1 name: %s, item2 name: %s", name1, name2); + return false; + } + boolean nameEqual = (name1 == null || name1.equals(name2)); + Verbose.send("Checking Custom Name: item1: %s, item2: %s, equal: %s", name1, name2, nameEqual); + if (!nameEqual) return false; + + List lore1 = meta1.hasLore() ? meta1.getLore() : null; + List lore2 = meta2.hasLore() ? meta2.getLore() : null; + if (lore1 == null ^ lore2 == null) { + Verbose.send("Lore mismatch: item1 lore: %s, item2 lore: %s", lore1, lore2); + return false; + } + boolean loreEqual = (lore1 == null || lore1.equals(lore2)); + Verbose.send("Checking Lore: item1: %s, item2: %s, equal: %s", lore1, lore2, loreEqual); + if (!loreEqual) return false; + + int cmd1 = meta1.hasCustomModelData() ? meta1.getCustomModelData() : -1; + int cmd2 = meta2.hasCustomModelData() ? meta2.getCustomModelData() : -1; + boolean cmdEqual = (cmd1 == cmd2); + Verbose.send("Checking Custom Model Data: item1: %d, item2: %d, equal: %s", cmd1, cmd2, cmdEqual); + if (!cmdEqual) return false; + + Map enchants1 = meta1.getEnchants(); + Map enchants2 = meta2.getEnchants(); + if (enchants1 == null ^ enchants2 == null) { + Verbose.send("Enchantments mismatch: item1 enchants: %s, item2 enchants: %s", enchants1, enchants2); + return false; + } + boolean enchantsEqual = (enchants1 == null || enchants1.equals(enchants2)); + Verbose.send("Checking Enchantments: item1: %s, item2: %s, equal: %s", enchants1, enchants2, enchantsEqual); + if (!enchantsEqual) return false; + + Multimap modifiers1 = meta1.getAttributeModifiers(); + Multimap modifiers2 = meta2.getAttributeModifiers(); + if (modifiers1 == null ^ modifiers2 == null) { + Verbose.send("Attribute Modifiers mismatch: item1 modifiers: %s, item2 modifiers: %s", modifiers1, modifiers2); + return false; + } + boolean modifiersEqual = (modifiers1 == null || modifiers1.equals(modifiers2)); + Verbose.send("Checking Attribute Modifiers: item1: %s, item2: %s, equal: %s", modifiers1, modifiers2, modifiersEqual); + if (!modifiersEqual) return false; + + return true; + } + +} diff --git a/src/main/java/me/trouper/alias/utils/PlayerUtils.java b/src/main/java/me/trouper/alias/utils/PlayerUtils.java new file mode 100755 index 0000000..f22205e --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/PlayerUtils.java @@ -0,0 +1,79 @@ +package me.trouper.alias.utils; + +import me.trouper.alias.server.Main; +import org.bukkit.Location; +import org.bukkit.damage.DamageSource; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class PlayerUtils implements Main { + + public static final int DEFAULT_NO_DAMAGE_TICKS = 9; + public static final int DEFAULT_MAX_NO_DAMAGE_TICKS = 10; + public static final int NO_DAMAGE_TICKS = 1; + public static final int MAX_NO_DAMAGE_TICKS = 2; + + private static float wrapYaw(float yaw) { + yaw = yaw % 360; + if (yaw < 0) yaw += 360; + return yaw; + } + + private static Vector getDirection(float yaw, float pitch) { + double radYaw = Math.toRadians(yaw); + double radPitch = Math.toRadians(pitch); + double x = -Math.cos(radPitch) * Math.sin(radYaw); + double y = -Math.sin(radPitch); + double z = Math.cos(radPitch) * Math.cos(radYaw); + return new Vector(x, y, z); + } + + public static Player playerClosestAngle(Player player, double range) { + Vector playerDirection = player.getEyeLocation().getDirection().normalize(); + Location eyeLoc = player.getEyeLocation(); + + return player.getNearbyEntities(range, range, range).stream() + .filter(entity -> entity instanceof Player && !entity.equals(player)) + .map(entity -> (Player) entity) + .min((p1, p2) -> { + Vector dirToP1 = p1.getEyeLocation().toVector().subtract(eyeLoc.toVector()).normalize(); + Vector dirToP2 = p2.getEyeLocation().toVector().subtract(eyeLoc.toVector()).normalize(); + + double angle1 = playerDirection.angle(dirToP1); + double angle2 = playerDirection.angle(dirToP2); + + return Double.compare(angle1, angle2); + }) + .orElse(null); + } + + public static void dealTrueDamage(LivingEntity target, DamageSource source, double amount) { + if (source.getDirectEntity() instanceof Player a && target instanceof Player t) return; + + target.damage(1, source); + + double newHealth = target.getHealth() - amount; + if (newHealth <= 0) { + target.setHealth(0); + } else { + target.setHealth(newHealth); + } + + Entity attacker = source.getDirectEntity(); + if (attacker instanceof LivingEntity) { + double dx = target.getX() - attacker.getX(); + double dz = target.getZ() - attacker.getZ(); + double magnitude = Math.sqrt(dx * dx + dz * dz); + + if (magnitude > 0) { + double strength = 0.4; + dx /= magnitude; + dz /= magnitude; + target.setVelocity(target.getVelocity().add(new Vector(dx * strength, 0.1, dz * strength))); + } + } + } + +} diff --git a/src/main/java/me/trouper/alias/utils/SoundPlayer.java b/src/main/java/me/trouper/alias/utils/SoundPlayer.java new file mode 100755 index 0000000..6e7919d --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/SoundPlayer.java @@ -0,0 +1,266 @@ +package me.trouper.alias.utils; + +import me.trouper.alias.server.Main; +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 implements Main { + + 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 playIndividually(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().distance(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 playWithinIndividually(double distance) { + for (Player p : Bukkit.getOnlinePlayers()) { + if (p != null && p.getWorld() == this.location.getWorld() && p.getLocation().distance(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 playAllIndividually() { + 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(getPlugin(),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 repeatIndividually(Player player, int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playIndividually(player); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(getPlugin(),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(getPlugin(),0,tickDelay); + } + + /** + * Repeats a sound to all players on the server, but at the players' location. + * + * @param times int + * @param tickDelay int + */ + public void repeatAllIndividually(int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playAllIndividually(); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(getPlugin(),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(getPlugin(),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 repeatAllIndividually(double distance, int times, int tickDelay) { + new BukkitRunnable() { + int i = 0; + @Override + public void run() { + if (i < times) { + playWithinIndividually(distance); + i ++; + } else { + this.cancel(); + } + } + }.runTaskTimer(getPlugin(),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; + } + + public void changePlayer(Location location, Sound sound, float volume, float pitch) { + this.location = location; + this.sound = sound; + this.volume = volume; + this.pitch = pitch; + } + + public void changePlayer(Sound sound, float volume, float pitch) { + changePlayer(location, sound, volume, pitch); + } +} diff --git a/src/main/java/me/trouper/alias/utils/TargetingUtils.java b/src/main/java/me/trouper/alias/utils/TargetingUtils.java new file mode 100755 index 0000000..9774464 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/TargetingUtils.java @@ -0,0 +1,282 @@ +package me.trouper.alias.utils; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class TargetingUtils { + + /** + * Applies an action to all living entities within a specified cuboid area that match a given filter. + * + * @param center The center of the cuboid area. + * @param xRadius The half-length of the cuboid along the X-axis. + * @param yRadius The half-length of the cuboid along the Y-axis. + * @param zRadius The half-length of the cuboid along the Z-axis. + * @param filter A predicate to filter which living entities are affected. + * @param action An action to perform on each targeted living entity. + * @return true if any targets were found, false if it missed. + */ + public static boolean areaAffect(Location center, double xRadius, double yRadius, double zRadius, Predicate filter, Consumer action) { + World world = center.getWorld(); + if (world == null) { + return false; + } + + List targets = new ArrayList<>(world.getNearbyLivingEntities(center, xRadius, yRadius, zRadius).stream().filter(filter).toList()); + targets.forEach(action); + return !targets.isEmpty(); + } + + /** + * Applies an action to all living entities within a specified spherical area (approximated by a cube) that match a given filter. + * + * @param center The center of the area. + * @param radius The radius of the spherical area. + * @param filter A predicate to filter which living entities are affected. + * @param action An action to perform on each targeted living entity. + * @return true if any targets were found, false if it missed. + */ + public static boolean areaAffect(Location center, double radius, Predicate filter, Consumer action) { + + World world = center.getWorld(); + if (world == null) { + return false; + } + + List targets = new ArrayList<>(world.getNearbyLivingEntities(center, radius).stream() + .filter(livingEntity -> livingEntity.getLocation().distanceSquared(center) <= radius*radius) + .filter(filter) + .toList()); + targets.forEach(action); + + return !targets.isEmpty(); + } + + /** + * Attempts to find a passable ground location based on the given initial location. + *

+ * This method checks if the current block is non-passable and searches upward (up to 10 blocks) + * until it finds a passable block. Then, it searches downward (up to 25 blocks) for the first + * non-passable block beneath it, which would be considered solid ground. + *

+ * If a valid ground location cannot be determined within the search bounds, + * the original location is returned. + * + * @param initialLocation The starting location to begin the ground-finding process. Must not be null. + * @return A new {@link Location} object representing the nearest solid ground position, + * or the original location if no valid position is found or world is null. + */ + public static Location findGroundLocation(Location initialLocation) { + if (initialLocation == null) { + return null; + } + World world = initialLocation.getWorld(); + if (world == null) return initialLocation; + + Location loc = initialLocation.clone(); + + int attempts = 0; + while (!world.getBlockAt(loc).isPassable() && attempts < 10) { + loc.add(0, 1, 0); + attempts++; + if (loc.getBlockY() >= world.getMaxHeight()) { + return initialLocation; + } + } + if (!world.getBlockAt(loc).isPassable()) return initialLocation; + + attempts = 0; + while (world.getBlockAt(loc).isPassable() && attempts < 25) { + Location belowLoc = loc.clone().subtract(0, 1, 0); + if (belowLoc.getBlockY() <= world.getMinHeight()) { + return world.getBlockAt(belowLoc).isPassable() ? initialLocation : loc; + } + if (!world.getBlockAt(belowLoc).isPassable()) { + return loc; + } + loc.subtract(0, 1, 0); + attempts++; + } + return initialLocation; + } + + /** + * Finds the closest living entity to a central location within a maximum distance. + * + * @param center The central location from which to search. Must not be null. + * @param maxDistance The maximum distance (radius of a sphere) to search for entities. + * @return An {@link Optional} containing the closest {@link LivingEntity}, or an empty Optional if no entity is found or world is null. + */ + public static Optional getClosestLivingEntity(Location center, double maxDistance) { + return getClosestLivingEntity(center, maxDistance, entity -> true); + } + + /** + * Finds the closest living entity to a central location within a maximum distance, matching a given filter. + * + * @param center The central location from which to search. Must not be null. + * @param maxDistance The maximum distance (radius of a sphere) to search for entities. + * @param filter A predicate to apply additional filtering criteria to the entities. Must not be null. + * @return An {@link Optional} containing the closest {@link LivingEntity} matching the criteria, + * or an empty Optional if no such entity is found or world is null. + */ + public static Optional getClosestLivingEntity(Location center, double maxDistance, Predicate filter) { + if (center == null || center.getWorld() == null || filter == null) { + return Optional.empty(); + } + World world = center.getWorld(); + double maxDistanceSquared = maxDistance * maxDistance; + + return world.getNearbyLivingEntities(center, maxDistance, maxDistance, maxDistance, filter).stream() + .filter(entity -> entity.getLocation().distanceSquared(center) <= maxDistanceSquared) + .min(Comparator.comparingDouble(entity -> entity.getLocation().distanceSquared(center))); + } + + /** + * Finds the closest player to a central location within a maximum distance. + * + * @param center The central location from which to search. Must not be null. + * @param maxDistance The maximum distance (radius of a sphere) to search for players. + * @return An {@link Optional} containing the closest {@link Player}, or an empty Optional if no player is found or world is null. + */ + public static Optional getClosestPlayer(Location center, double maxDistance) { + return getClosestPlayer(center, maxDistance, player -> true); + } + + /** + * Finds the closest player to a central location within a maximum distance, matching a given filter. + * + * @param center The central location from which to search. Must not be null. + * @param maxDistance The maximum distance (radius of a sphere) to search for players. + * @param filter A predicate to apply additional filtering criteria to the players. Must not be null. + * @return An {@link Optional} containing the closest {@link Player} matching the criteria, + * or an empty Optional if no such player is found or world is null. + */ + public static Optional getClosestPlayer(Location center, double maxDistance, Predicate filter) { + if (center == null || center.getWorld() == null || filter == null) { + return Optional.empty(); + } + World world = center.getWorld(); + double maxDistanceSquared = maxDistance * maxDistance; + + List nearbyPlayers = world.getPlayers().stream() + .filter(player -> player.getWorld().equals(world)) + .filter(player -> player.getLocation().distanceSquared(center) <= maxDistanceSquared) + .filter(filter) + .collect(Collectors.toList()); + + return nearbyPlayers.stream() + .min(Comparator.comparingDouble(player -> player.getLocation().distanceSquared(center))); + } + + /** + * Finds the living entity with the lowest health within a given radius of a central location. + * + * @param center The central location from which to search. Must not be null. + * @param radius The radius (sphere) to search for entities. + * @return An {@link Optional} containing the {@link LivingEntity} with the lowest health, + * or an empty Optional if no entity is found or world is null. + */ + public static Optional getLowestHealthLivingEntity(Location center, double radius) { + return getLowestHealthLivingEntity(center, radius, entity -> true); + } + + /** + * Finds the living entity with the lowest health within a given radius of a central location, matching a given filter. + * + * @param center The central location from which to search. Must not be null. + * @param radius The radius (sphere) to search for entities. + * @param filter A predicate to apply additional filtering criteria. Must not be null. + * @return An {@link Optional} containing the {@link LivingEntity} with the lowest health matching the criteria, + * or an empty Optional if no such entity is found or world is null. + */ + public static Optional getLowestHealthLivingEntity(Location center, double radius, Predicate filter) { + if (center == null || center.getWorld() == null || filter == null) { + return Optional.empty(); + } + World world = center.getWorld(); + double radiusSquared = radius * radius; + + return world.getNearbyLivingEntities(center, radius, radius, radius, filter).stream() + .filter(entity -> entity.getLocation().distanceSquared(center) <= radiusSquared) + .min(Comparator.comparingDouble(LivingEntity::getHealth)); + } + + /** + * Finds the living entity whose eye location is closest (by angle) to a given direction vector from an origin. + * This method is useful for simulating line-of-sight or aim-based targeting. + * + * @param originEyeLocation The starting location (e.g., an entity's eye location). Must not be null. + * @param direction The normalized direction vector of the search. Must not be null. + * @param maxDistance The maximum distance to search for entities. + * @param maxAngleRadians The maximum allowed angle (in radians) between the direction vector and the vector to the target's eye location. + * A smaller angle means the target is more directly in the line of sight. + * @return An {@link Optional} containing the {@link LivingEntity} closest to the aim vector, + * or an empty Optional if no suitable entity is found or world is null. + */ + public static Optional getLivingEntityClosestToVector(Location originEyeLocation, Vector direction, double maxDistance, double maxAngleRadians) { + return getLivingEntityClosestToVector(originEyeLocation, direction, maxDistance, maxAngleRadians, entity -> true); + } + + /** + * Finds the living entity whose eye location is closest (by angle) to a given direction vector from an origin, matching a filter. + * This method is useful for simulating line-of-sight or aim-based targeting. + * + * @param originEyeLocation The starting location (e.g., an entity's eye location). Must not be null. + * @param direction The normalized direction vector of the search. Must not be null. Its magnitude does not matter as it will be normalized. + * @param maxDistance The maximum distance to search for entities. + * @param maxAngleRadians The maximum allowed angle (in radians) between the direction vector and the vector to the target's eye location. + * A smaller angle means the target is more directly in the line of sight. + * @param filter A predicate to apply additional filtering criteria. Must not be null. + * @return An {@link Optional} containing the {@link LivingEntity} closest to the aim vector and matching the filter, + * or an empty Optional if no suitable entity is found or world is null. + */ + public static Optional getLivingEntityClosestToVector(Location originEyeLocation, Vector direction, double maxDistance, double maxAngleRadians, Predicate filter) { + if (originEyeLocation == null || originEyeLocation.getWorld() == null || direction == null || filter == null) { + return Optional.empty(); + } + World world = originEyeLocation.getWorld(); + Vector normalizedDirection = direction.clone().normalize(); + + List candidates = world.getNearbyLivingEntities(originEyeLocation, maxDistance, maxDistance, maxDistance, entity -> { + if (originEyeLocation.equals(entity.getEyeLocation())) { + return false; + } + return filter.test(entity); + }).stream().toList(); + + LivingEntity bestTarget = null; + double smallestAngle = maxAngleRadians + 1.0; + + for (LivingEntity entity : candidates) { + if (entity.getEyeLocation().distanceSquared(originEyeLocation) > maxDistance * maxDistance) { + continue; + } + + Vector vectorToTarget = entity.getEyeLocation().toVector().subtract(originEyeLocation.toVector()); + if (vectorToTarget.lengthSquared() == 0) { + continue; + } + vectorToTarget.normalize(); + + double angle = normalizedDirection.angle(vectorToTarget); + + if (angle <= maxAngleRadians && angle < smallestAngle) { + smallestAngle = angle; + bestTarget = entity; + } + } + return Optional.ofNullable(bestTarget); + } +} diff --git a/src/main/java/me/trouper/alias/utils/Text.java b/src/main/java/me/trouper/alias/utils/Text.java new file mode 100755 index 0000000..897b319 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/Text.java @@ -0,0 +1,312 @@ +package me.trouper.alias.utils; + +import me.trouper.alias.server.Main; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Text implements Main { + + public static String legacyColor(String msg) { + return msg.replaceAll("&","§"); + } + + public static Component color(String msg) { + return LegacyComponentSerializer.legacyAmpersand().deserialize(msg); + } + + public static void sendWarning(CommandSender sender, String warning, Object... args) { + sendMessage(Pallet.WARNING, sender, warning, args); + } + + public static void sendError(CommandSender sender, String error, Object... args) { + sendMessage(Pallet.ERROR, sender, error, args); + } + + public static void sendMessage(CommandSender sender, String text, Object... args) { + sendMessage(Pallet.NEUTRAL, sender, text, args); + } + + public static void sendMessage(Pallet pallet, CommandSender sender, String text, Object... args) { + text = formatArgsLegacy(pallet, text, args); + sendMessage(sender, text); + if (sender instanceof Player p) p.playSound(p.getLocation(),pallet.sound.sound, SoundCategory.VOICE,10f,pallet.sound.pitch); + } + + public static void sendMessage(CommandSender sender, String text) { + Component message = getMessage(text); + sender.sendMessage(message); + } + + public static Component getMessage(Pallet pallet, String text, Object... args) { + return getMessage(formatArgsLegacy(pallet, text, args)); + } + + public static Component getMessage(String text) { + if (main.config().messages.fancyAlerts) { + return formatFancyMessage(text); + } else { + return color(main.config().messages.prefix + text); + } + } + + public static String formatArgsLegacy(Pallet pallet, String format, Object... args) { + return LegacyComponentSerializer.legacyAmpersand().serialize(formatArgs(pallet,format,args)); + } + + public static Component formatArgs(Pallet pallet, String format, Object... args) { + Component message = Component.empty(); + Pattern pattern = Pattern.compile("\\{(\\d+)}"); + Matcher matcher = pattern.matcher(format); + int lastIndex = 0; + + while (matcher.find()) { + String prefix = format.substring(lastIndex, matcher.start()); + if (!prefix.isEmpty()) { + message = message.append(Component.text(prefix).color(pallet.mainText)); + } + + int argIndex = Integer.parseInt(matcher.group(1)); + TextColor argColor = getArgColor(pallet, argIndex); + + if (argIndex >= 0 && argIndex < args.length) { + String argText = args[argIndex].toString(); + message = message.append(Component.text(argText).color(argColor)); + } else { + message = message.append(Component.text(matcher.group()).color(pallet.mainText)); + } + + lastIndex = matcher.end(); + } + + String suffix = format.substring(lastIndex); + if (!suffix.isEmpty()) { + message = message.append(Component.text(suffix).color(pallet.mainText)); + } + + return message; + } + + public static Component formatFancyMessage(String text) { + Component message = Component.empty().appendNewline(); + + List wrappedLines = wrapText(text, 50, (int) Math.round((main.config().messages.pluginName.length() + 3) * 1.3)); + + message = message + .append(color(main.config().messages.mainColor + "| ").decorate(TextDecoration.BOLD)) + .append(Component.text(main.config().messages.pluginName + " ", NamedTextColor.WHITE, TextDecoration.BOLD)) + .append(color(wrappedLines.getFirst())); + + String active = getActiveFormatting(wrappedLines.getFirst()); + + wrappedLines.removeFirst(); + + for (String wrappedLine : wrappedLines) { + wrappedLine = active + wrappedLine; + + active = getActiveFormatting(wrappedLine); + message = message + .appendNewline() + .append(color(main.config().messages.mainColor + "| ").decorate(TextDecoration.BOLD)) + .append(color(wrappedLine)); + } + + return message.appendNewline(); + } + + public static List wrapText(String text, int maxLineLength, int offset) { + List lines = new ArrayList<>(); + + if (text == null || text.isEmpty() || maxLineLength <= 0) { + return lines; + } + + String[] words = text.split("\\s+"); + StringBuilder currentLine = new StringBuilder(); + int currentLineLength = offset; + + for (String word : words) { + if (currentLineLength + word.length() + 1 > maxLineLength) { + lines.add(currentLine.toString()); + currentLine = new StringBuilder(); + currentLineLength = 0; + } + + if (!currentLine.isEmpty()) { + currentLine.append(" "); + currentLineLength++; + } + + currentLine.append(word); + currentLineLength += word.length(); + } + + if (!currentLine.isEmpty()) { + lines.add(currentLine.toString()); + } + + return lines; + } + + public static String getActiveFormatting(String text) { + final Pattern pattern = Pattern.compile("&[0-9a-fk-or]"); + final Matcher matcher = pattern.matcher(text); + + String lastColor = ""; + Set activeFormats = new HashSet<>(); + + while (matcher.find()) { + String code = matcher.group(); + char identifier = code.charAt(1); + + if (identifier >= '0' && identifier <= '9' || identifier >= 'a' && identifier <= 'f') { + lastColor = code; + activeFormats.clear(); + } else if (identifier >= 'k' && identifier <= 'o') { + activeFormats.add(identifier); + } else if (identifier == 'r') { + lastColor = ""; + activeFormats.clear(); + } + } + + StringBuilder result = new StringBuilder(lastColor); + for (char format : activeFormats) { + result.append("&").append(format); + } + + return result.toString(); + } + + private static TextColor getArgColor(Pallet pallet, int argIndex) { + return switch (argIndex) { + case 1 -> pallet.arg2; + case 2 -> pallet.arg3; + default -> pallet.argDefault; + }; + } + + public enum Pallet { + ERROR( + NamedTextColor.RED, + NamedTextColor.YELLOW, + NamedTextColor.GOLD, + NamedTextColor.DARK_RED, + new SoundData(Sound.BLOCK_NOTE_BLOCK_BASS,1)), + WARNING( + NamedTextColor.YELLOW, + NamedTextColor.GOLD, + NamedTextColor.RED, + NamedTextColor.DARK_RED, + new SoundData(Sound.BLOCK_NOTE_BLOCK_BIT,0.5F)), + INFO( + NamedTextColor.GRAY, + NamedTextColor.WHITE, + NamedTextColor.AQUA, + NamedTextColor.DARK_AQUA, + new SoundData(Sound.BLOCK_NOTE_BLOCK_BELL,1)), + SUCCESS( + NamedTextColor.GREEN, + NamedTextColor.DARK_GREEN, + NamedTextColor.YELLOW, + NamedTextColor.GOLD, + new SoundData(Sound.BLOCK_NOTE_BLOCK_CHIME,1)), + NEUTRAL( + NamedTextColor.GRAY, + NamedTextColor.WHITE, + NamedTextColor.DARK_AQUA, + NamedTextColor.BLUE, + new SoundData(Sound.BLOCK_NOTE_BLOCK_BELL,1)); + + private final TextColor mainText; + private final TextColor argDefault; + private final TextColor arg2; + private final TextColor arg3; + private final SoundData sound; + + Pallet(TextColor mainText, TextColor argDefault, TextColor arg2, TextColor arg3, SoundData sound) { + this.mainText = mainText; + this.argDefault = argDefault; + this.arg2 = arg2; + this.arg3 = arg3; + this.sound = sound; + } + } + + public record SoundData(Sound sound, float pitch){}; + + public static String generateProgressBar(int length, int max, int current) { + if (max <= 0) { + throw new IllegalArgumentException("Max value must be greater than 0"); + } + + current = Math.max(0, Math.min(current, max)); + double percent = (double) current / max; + int filledBars = (int) Math.round(percent * length); + + StringBuilder progressBar = new StringBuilder(); + for (int i = 0; i < length; i++) { + if (i < filledBars) { + progressBar.append("&a|"); + } else { + progressBar.append("&7|"); + } + } + + return progressBar.toString(); + } + + public static String formatEnum(Enum obj) { + if (obj == null) return "Null"; + String name = obj.name(); + String[] words = name.toLowerCase().split("_"); + + StringBuilder formatted = new StringBuilder(); + + for (String word : words) { + if (!word.isEmpty()) { + formatted.append(Character.toUpperCase(word.charAt(0))) + .append(word.substring(1)) + .append(" "); + } + } + + return formatted.toString().trim(); + } + + public static int getLevel(String s) { + HashMap romanToInt = new HashMap(); + romanToInt.put(Character.valueOf('I'), 1); + romanToInt.put(Character.valueOf('V'), 5); + romanToInt.put(Character.valueOf('X'), 10); + romanToInt.put(Character.valueOf('L'), 50); + romanToInt.put(Character.valueOf('C'), 100); + romanToInt.put(Character.valueOf('D'), 500); + romanToInt.put(Character.valueOf('M'), 1000); + int result = 0; + for (int i = 0; i < s.length(); ++i) { + if (i > 0 && romanToInt.get(Character.valueOf(s.charAt(i))) > romanToInt.get(Character.valueOf(s.charAt(i - 1)))) { + result += romanToInt.get(Character.valueOf(s.charAt(i))) - 2 * romanToInt.get(Character.valueOf(s.charAt(i - 1))); + continue; + } + if (romanToInt.get(Character.valueOf(s.charAt(i))) == null) { + return 0; + } + result += (romanToInt.get(Character.valueOf(s.charAt(i)))).intValue(); + } + if (result > 255) { + result = 1; + } + return result; + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/Verbose.java b/src/main/java/me/trouper/alias/utils/Verbose.java new file mode 100755 index 0000000..f1f90e7 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/Verbose.java @@ -0,0 +1,70 @@ +package me.trouper.alias.utils; + +import me.trouper.alias.server.Main; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class Verbose implements Main { + + public static void send(int backtrace, String message, Object... args) { + if (!me.trouper.alias.Alias.getInstance().getManager().io.config.debugMode) return; + String callerInfo = "Unknown Caller"; + + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + if (stackTrace.length > 2 + backtrace) { + StackTraceElement caller = stackTrace[2 + backtrace]; + + String className = caller.getClassName(); + className = className.substring(className.lastIndexOf(".") + 1); + if (className.contains("-")) { + callerInfo = "Protected"; + } else { + callerInfo = className + "." + caller.getMethodName(); + } + + if (me.trouper.alias.Alias.getInstance().getManager().io.config.debuggerExclusions.contains(callerInfo)) { + return; + } + } + + String formattedMessage = message.formatted(args); + String log = "[DEBUG ^ %s] [%s]: %s".formatted(backtrace, callerInfo, formattedMessage); + me.trouper.alias.Alias.getInstance().getLogger().info(log); + + for (Player operator : Bukkit.getOnlinePlayers()) { + if (operator.isOp()) operator.sendMessage("§d§l%s §7[§bDEBUG ^ %s§7] §7[§e%s§7] §8» §7%s" + .formatted(main.config().messages.pluginName,backtrace, callerInfo, formattedMessage)); + } + } + + public static void send(String message, Object... args) { + if (!me.trouper.alias.Alias.getInstance().getManager().io.config.debugMode) return; + String callerInfo = "Unknown Caller"; + + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + if (stackTrace.length > 2) { + StackTraceElement caller = stackTrace[2]; + + String className = caller.getClassName(); + className = className.substring(className.lastIndexOf(".") + 1); + if (className.contains("-")) { + callerInfo = "Protected"; + } else { + callerInfo = className + "." + caller.getMethodName(); + } + + if (main.config().debuggerExclusions.contains(callerInfo)) { + return; + } + } + + String formattedMessage = message.formatted(args); + String log = "[DEBUG] [%s]: %s".formatted(callerInfo, formattedMessage); + me.trouper.alias.Alias.getInstance().getLogger().info(log); + + for (Player operator : Bukkit.getOnlinePlayers()) { + if (operator.isOp()) operator.sendMessage("§d§l%s §7[§bDEBUG§7] §7[§e%s§7] §8» §7%s" + .formatted(main.config().messages.pluginName,callerInfo, formattedMessage)); + } + } +} diff --git a/src/main/java/me/trouper/alias/utils/command/Args.java b/src/main/java/me/trouper/alias/utils/command/Args.java new file mode 100755 index 0000000..d533511 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/command/Args.java @@ -0,0 +1,115 @@ +package me.trouper.alias.utils.command; + +import java.util.function.Consumer; + +public record Args(String... args) { + + public Arg getAll() { + return getAll(0); + } + + public Arg getAll(int beginIndex) { + String str = ""; + for (int i = beginIndex; i < args.length; i++) { + str = str.concat(args[i] + " "); + } + return new Arg(str.trim()); + } + + public Arg get(int index) { + if (args.length == 0) + throw new IllegalArgumentException("not enough arguments: arguments are empty"); + if (index < 0 || index >= args.length) + throw new IllegalArgumentException("not enough arguments: argument %s is missing".formatted(index + 1)); + return new Arg(args[index]); + } + + public Arg first() { + return get(0); + } + + public Arg last() { + return get(args.length - 1); + } + + public boolean match(int index, String arg) { + if (index < 0 || index >= args.length) { + return false; + } + return get(index).toString().equalsIgnoreCase(arg); + } + + public void when(int index, String match, Consumer action) { + if (match(index, match)) { + action.accept(get(index)); + } + } + + public int getSize() { + return args.length; + } + + public boolean isEmpty() { + return args.length == 0; + } + + public static class Arg { + private final String arg; + + public Arg(String arg) { + this.arg = arg; + } + + public int toInt() { + return Integer.parseInt(arg); + } + + public long toLong() { + return Long.parseLong(arg); + } + + public byte toByte() { + return Byte.parseByte(arg); + } + + public short toShort() { + return Short.parseShort(arg); + } + + public double toDouble() { + return Double.parseDouble(arg); + } + + public float toFloat() { + return Float.parseFloat(arg); + } + + public boolean toBool() { + return Boolean.parseBoolean(arg); + } + + public char toChar() { + return arg.isEmpty() ? ' ' : arg.charAt(0); + } + + @Override + public String toString() { + return arg; + } + + public > T toEnum(Class enumType) { + return toEnum(enumType, null); + } + + public > T toEnum(Class enumType, T fallback) { + String arg = this.arg.replace('-', '_'); + for (T constant : enumType.getEnumConstants()) + if (arg.equalsIgnoreCase(constant.name())) + return constant; + + if (fallback == null) + throw new IllegalArgumentException("'%s' is not a value of %s".formatted(arg, enumType.getSimpleName())); + return fallback; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/command/CommandRegistry.java b/src/main/java/me/trouper/alias/utils/command/CommandRegistry.java new file mode 100755 index 0000000..f19dd89 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/command/CommandRegistry.java @@ -0,0 +1,17 @@ +package me.trouper.alias.utils.command; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface CommandRegistry { + + String value(); + String usage() default "none"; + Permission permission() default @Permission(""); + boolean printStackTrace() default false; + boolean playersOnly() default false; +} diff --git a/src/main/java/me/trouper/alias/utils/command/Permission.java b/src/main/java/me/trouper/alias/utils/command/Permission.java new file mode 100755 index 0000000..b7446e4 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/command/Permission.java @@ -0,0 +1,14 @@ +package me.trouper.alias.utils.command; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Permission { + + String value(); + String message() default "&cYou do not have permission for this command!"; +} diff --git a/src/main/java/me/trouper/alias/utils/command/QuickCommand.java b/src/main/java/me/trouper/alias/utils/command/QuickCommand.java new file mode 100755 index 0000000..f3abcae --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/command/QuickCommand.java @@ -0,0 +1,99 @@ +package me.trouper.alias.utils.command; + +import me.trouper.alias.server.Main; +import me.trouper.alias.utils.command.completions.CompletionBuilder; +import me.trouper.alias.utils.command.completions.CompletionNode; +import me.trouper.alias.utils.misc.Voidable; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public interface QuickCommand extends TabExecutor, Main { + + void dispatchCommand(CommandSender sender, Command command, String label, Args args); + + void dispatchCompletions(CommandSender sender, Command command, String label, CompletionBuilder b); + + default void register() { + CommandRegistry registry = this.getClass().getAnnotation(CommandRegistry.class); + PluginCommand command = getPlugin().getCommand(registry.value()); + + if (command != null) { + command.setExecutor(this); + command.setTabCompleter(this); + } + } + + @Override + default boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + CommandRegistry registry = this.getClass().getAnnotation(CommandRegistry.class); + if (registry == null) { + return true; + } + if (!(sender instanceof Player) && registry.playersOnly()) { + info(sender, "This command is for players only!"); + return true; + } + + try { + String perm = registry.permission().value(); + if (perm != null && !perm.isEmpty() && !sender.hasPermission(perm)) { + error(sender, registry.permission().message()); + return true; + } + dispatchCommand(sender, command, label, new Args(args)); + } + catch (Exception ex) { + if (registry.printStackTrace()) { + ex.printStackTrace(); + } + info(sender, "&cCorrect Usage: &7" + registry.usage()); + } + return true; + } + + @Override + default List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + try { + CompletionBuilder b = new CompletionBuilder(label); + dispatchCompletions(sender, command, label, b); + CompletionNode node = b.getRootNode(); + + if (args.length == 0) { + return node.getOptions(); + } + for (int i = 0; i < args.length - 1; i++) { + node = node.next(args[i]); + } + + String end = args[args.length - 1]; + List a = new ArrayList<>(node.getOptions()); + + if (node.isOptionsRegex()) { + List regexResult = new ArrayList<>(); + for (CompletionNode option : node.getNextOptions()) { + boolean regexMatches = CompletionNode.containsRegex(option, end) || end.isEmpty(); + for (String s : option.getValues()) + regexResult.add((regexMatches ? "§d" : "§c") + s + "§r"); + } + return regexResult; + } + else { + a.removeIf(s -> !s.toLowerCase().contains(end.toLowerCase())); + return a; + } + } + catch (Exception ex) { + return new ArrayList<>(); + } + } + + default Voidable getRegistry() { + return Voidable.of(this.getClass().getAnnotation(CommandRegistry.class)); + } +} diff --git a/src/main/java/me/trouper/alias/utils/command/completions/CompletionBuilder.java b/src/main/java/me/trouper/alias/utils/command/completions/CompletionBuilder.java new file mode 100755 index 0000000..2fe7e33 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/command/completions/CompletionBuilder.java @@ -0,0 +1,123 @@ +package me.trouper.alias.utils.command.completions; + +import me.trouper.alias.utils.misc.ArrayUtils; + +import java.util.*; +import java.util.function.Function; + +public class CompletionBuilder { + + private final CompletionNode root; + private final List options; + private boolean isBranch; + private String regex; + + CompletionBuilder(List names) { + this.root = new CompletionNode(names, new ArrayList<>(), null); + this.options = new ArrayList<>(); + this.isBranch = false; + } + + public CompletionBuilder(String names) { + this.root = new CompletionNode(names); + this.options = new ArrayList<>(); + this.isBranch = false; + } + + public CompletionBuilder(String regex, String details) { + this.root = new CompletionNode(Collections.singletonList(details), new ArrayList<>(), regex); + this.options = new ArrayList<>(); + this.isBranch = false; + this.regex = regex; + } + + public CompletionBuilder then(CompletionBuilder arg) { + options.add(arg); + root.nextOptions.add(arg.root); + return this; + } + + public CompletionBuilder arg(List name) { + CompletionBuilder b = new CompletionBuilder(name); + b.isBranch = true; + return b; + } + + public CompletionBuilder argRegex(String regex, String details) { + CompletionBuilder b = new CompletionBuilder(regex, details); + b.isBranch = true; + return b; + } + + public CompletionBuilder argInt(String details) { + return argRegex("^ *\\-?\\d+ *$", details); + } + + public CompletionBuilder argPosInt(String details) { + return argRegex("^ *\\d+ *$", details); + } + + public CompletionBuilder argDecimal(String details) { + return argRegex("^ *\\-?\\d*\\.?\\d+ *$", details); + } + + public CompletionBuilder argPosDecimal(String details) { + return argRegex("^ *\\d*\\.?\\d+ *$", details); + } + + public CompletionBuilder argBool() { + return arg("true", "false"); + } + + public CompletionBuilder argEnum(Class> type, boolean lowercase) { + return arg(ArrayUtils.enumNames(type, lowercase)); + } + + public CompletionBuilder argEnum(Class> type) { + return argEnum(type, true); + } + + public CompletionBuilder argOnlinePlayers() { + return arg(ArrayUtils.playerNames()); + } + + public CompletionBuilder arg(String... names) { + return arg(Arrays.asList(names)); + } + + public CompletionBuilder arg(String name) { + return arg(Collections.singletonList(name)); + } + + public CompletionBuilder arg(Collection input, Function toString) { + return arg(input.stream().map(toString).toList()); + } + + public CompletionBuilder next(String name) { + for (CompletionBuilder o : options) { + if (CompletionNode.strictContains(o.root, name)) { + return o; + } + } + return null; + } + + public CompletionNode getRootNode() { + return root; + } + + public CompletionNode build() { + if (this.isBranch) { + throw new IllegalArgumentException("build() cannot be called on branches!"); + } + return root; + } + + public boolean isBranch() { + return isBranch; + } + + public boolean isRegex() { + return regex != null; + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/command/completions/CompletionNode.java b/src/main/java/me/trouper/alias/utils/command/completions/CompletionNode.java new file mode 100755 index 0000000..4b8d238 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/command/completions/CompletionNode.java @@ -0,0 +1,88 @@ +package me.trouper.alias.utils.command.completions; + +import java.util.ArrayList; +import java.util.List; + +public class CompletionNode { + + final List values; + final List nextOptions; + final String regex; + + CompletionNode(List values, List nextOptions, String regex) { + this.values = values; + this.nextOptions = nextOptions; + this.regex = regex; + } + + CompletionNode(String values) { + this(List.of(values), new ArrayList<>(), null); + } + + public static boolean strictContains(CompletionNode parent, String subject) { + for (String value : parent.values) + if (value.equals(subject)) + return true; + return false; + } + + public static boolean contains(CompletionNode parent, String subject) { + for (String value : parent.values) + if (value.contains(subject)) + return true; + return false; + } + + public static boolean containsRegex(CompletionNode parent, String subject) { + if (parent.regex == null) + return false; + return subject.matches(parent.regex); + } + + public boolean optionsRegexMatchesArg(String argument) { + for (CompletionNode option : nextOptions) + if (containsRegex(option, argument)) + return true; + return false; + } + + public CompletionNode next(String argument) { + for (CompletionNode option : nextOptions) + if (containsRegex(option, argument)) + return option; + + for (CompletionNode option : nextOptions) + if (strictContains(option, argument)) + return option; + + for (CompletionNode option : nextOptions) + if (contains(option, argument)) + return option; + + return null; + } + + public List getOptions() { + List a = new ArrayList<>(); + for (CompletionNode o : nextOptions) { + a.addAll(o.values); + } + return a; + } + + public boolean isRegex() { + return regex != null; + } + + public boolean isOptionsRegex() { + return nextOptions.stream().anyMatch(CompletionNode::isRegex); + } + + public List getNextOptions() { + return nextOptions; + } + + public List getValues() { + return values; + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/misc/ArrayUtils.java b/src/main/java/me/trouper/alias/utils/misc/ArrayUtils.java new file mode 100755 index 0000000..849c668 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/misc/ArrayUtils.java @@ -0,0 +1,71 @@ +package me.trouper.alias.utils.misc; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +public final class ArrayUtils { + + /** + * Transforms an array to another one + * @param e iterable list + * @param a action + * @return new transformed list + * @param input + * @param output + */ + public static List map(Iterable e, Function a) { + List list = new ArrayList<>(); + e.forEach(i -> list.add(a.apply(i))); + return list; + } + + public static String toPrettyString(List list) { + return "§7[§e" + String.join("§7, §e", ArrayUtils.map(list, Object::toString)) + "§7]"; + } + + public static > List enumNames(Class type, boolean lowercase) { + List names = new ArrayList<>(); + for (E constant : type.getEnumConstants()) { + String name = constant.name(); + names.add(lowercase ? name.toLowerCase() : name); + } + return names; + } + + public static > List enumNames(Class type) { + return enumNames(type, true); + } + + public static List playerNames() { + return map(Bukkit.getOnlinePlayers(), Player::getName); + } + + @SafeVarargs + public static List bind(Iterable tList, T... ts) { + List list = Arrays.asList(ts); + tList.forEach(list::add); + return list; + } + + public static List reversed(List input) { + Collections.reverse(input); + return input; + } + + public static List reversed(Iterable input) { + List list = new ArrayList<>(); + input.forEach(list::add); + return reversed(list); + } + + public static void reverseForEach(Iterable input, Consumer action) { + reversed(input).forEach(action); + } +} diff --git a/src/main/java/me/trouper/alias/utils/misc/Cooldown.java b/src/main/java/me/trouper/alias/utils/misc/Cooldown.java new file mode 100755 index 0000000..391c910 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/misc/Cooldown.java @@ -0,0 +1,42 @@ +package me.trouper.alias.utils.misc; + +import java.util.HashMap; +import java.util.Map; + +public class Cooldown { + + private final Map timer; + + public Cooldown() { + this.timer = new HashMap<>(); + } + + private O getOrDefault(O value, O def) { + return value != null ? value : def; + } + + public long getCooldown(T obj) { + return Math.max(getOrDefault(timer.get(obj), 0L) - System.currentTimeMillis(), 0L); + } + + public double getCooldownSec(T obj) { + final long cooldown = this.getCooldown(obj); + return Math.floor(cooldown / 10.0) / 100.0; + } + + public boolean isOnCooldown(T obj) { + return getCooldown(obj) > 0L; + } + + public void setCooldown(T obj, long millis) { + timer.put(obj, System.currentTimeMillis() + millis); + } + + public void addCooldown(T obj, long millis) { + setCooldown(obj, getCooldown(obj) + millis); + } + + public void removeCooldown(T obj) { + timer.remove(obj); + } +} diff --git a/src/main/java/me/trouper/alias/utils/misc/FileValidationUtils.java b/src/main/java/me/trouper/alias/utils/misc/FileValidationUtils.java new file mode 100755 index 0000000..177cb19 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/misc/FileValidationUtils.java @@ -0,0 +1,21 @@ +package me.trouper.alias.utils.misc; + +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()) + if (!file.createNewFile()) + return false; + return true; + } + catch (Exception ex) { + return false; + } + } +} diff --git a/src/main/java/me/trouper/alias/utils/misc/JsonSerializable.java b/src/main/java/me/trouper/alias/utils/misc/JsonSerializable.java new file mode 100755 index 0000000..96ca146 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/misc/JsonSerializable.java @@ -0,0 +1,149 @@ +package me.trouper.alias.utils.misc; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.io.*; + +public interface JsonSerializable { + + Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().setLenient().create(); + File getFile(); + + default String serialize(boolean pretty) { + Gson gson; + if (pretty) { + gson = new GsonBuilder().setPrettyPrinting().setLenient().create(); + } + else { + gson = new Gson(); + } + + try { + String json = gson.toJson(this); + if (json == null) { + throw new IllegalStateException("json parse failed for " + this.getClass().getSimpleName()); + } + return json; + } + catch (Exception ex) { + return "{}"; + } + } + + @SuppressWarnings("unchecked") + default T deserialize(String json) { + try { + JsonSerializable v = gson.fromJson(json, this.getClass()); + if (v == null) { + throw new IllegalStateException("json parse failed"); + } + return (T)v; + } + catch (Exception ex) { + return null; + } + } + + default JsonObject getJson() { + return gson.toJsonTree(this).getAsJsonObject(); + } + + /** + * Gets a json element given the specified member path + * @param path Path separated by a period . between each member name + * @return the JsonElement at the end of the path, otherwise null + */ + default JsonElement get(String path) { + JsonElement root = gson.toJsonTree(this); + JsonElement json = root; + + for (String memberName : path.split("\\.")) { + JsonElement e = json.getAsJsonObject().get(memberName); + if (e != null) + json = e; + else + break; + } + + return json == root ? null : json; + } + + /** + * Gets a json element given the specified member path + * @param path Path separated by a period . between each member name + */ + default boolean set(String path, Object obj) { + JsonElement root = gson.toJsonTree(this); + JsonElement json = root; + String[] paths = path.split("\\."); + + if (paths.length == 0) + return false; + if (paths.length == 1) { + root.getAsJsonObject().add(path, gson.toJsonTree(obj)); + return true; + } + + for (int i = 0; i < paths.length - 1; i++) { + JsonElement e = json.getAsJsonObject().get(paths[i]); + if (e != null) + json = e; + else + break; + } + + if (json != root) { + json.getAsJsonObject().add(paths[paths.length - 1], gson.toJsonTree(obj)); + return true; + } + return false; + } + + default void save() { + String json = serialize(true); + File f = getFile(); + + if (FileValidationUtils.validate(f)) { + try { + FileWriter fw = new FileWriter(f); + BufferedWriter bw = new BufferedWriter(fw); + bw.write(json); + bw.close(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + default O getOrDef(O val, O def) { + return val != null ? val : def; + } + + static > T load(File file, Class jsonSerializable, T fallback) { + if (FileValidationUtils.validate(file)) { + try { + FileReader fr = new FileReader(file); + BufferedReader br = new BufferedReader(fr); + T t = gson.fromJson(br, jsonSerializable); + + if (t == null) { + throw new IllegalStateException("json parse failed!"); + } + + return t; + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + return fallback; + } + + static > T load(String path, Class jsonSerializable, T fallback) { + return load(new File(path), jsonSerializable, fallback); + } +} diff --git a/src/main/java/me/trouper/alias/utils/misc/Randomizer.java b/src/main/java/me/trouper/alias/utils/misc/Randomizer.java new file mode 100755 index 0000000..6beaa66 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/misc/Randomizer.java @@ -0,0 +1,81 @@ +package me.trouper.alias.utils.misc; + +import java.util.List; + +public class Randomizer { + + public Randomizer() { + + } + + public T getRandomElement(List list) { + if (list == null || list.isEmpty()) { + return null; + } + return list.get(getRandomIndex(list.size())); + } + + @SafeVarargs + public final T getRandomElement(T... list) { + if (list == null || list.length == 0) { + return null; + } + return list[getRandomIndex(list.length)]; + } + + private int getRandomIndex(int listSize) { + if (listSize < 0) { + listSize = 0; + } + return (int)(Math.ceil(Math.random() * listSize) - 1); + } + + public boolean getRandomBoolean() { + return Math.random() < 0.5; + } + + /** + * 'Percentage' means an integer from 0-100. You should not divide this value by 100, as this does it for you. + * @param percentage an integer 0-100 + * @return true if chance hit, false otherwise + */ + public boolean getRandomChance(int percentage) { + return Math.random() < percentage / 100.0; + } + + public int getRandomInt(int min, int max) { + if (min > max) { + throw new IllegalArgumentException("min cannot be greater than max!"); + } + int range = max - min + 1; + return min + (int)(Math.random() * range); + } + + public int getRandomInt(int max) { + return getRandomInt(0, max); + } + + public double getRandomDouble(double min, double max) { + if (min > max) { + throw new IllegalArgumentException("min cannot be greater than max!"); + } + double range = max - min; + return min + Math.random() * range; + } + + public double getRandomDouble(double max) { + return getRandomDouble(0.0, max); + } + + public float getRandomFloat(float min, float max) { + if (min > max) { + throw new IllegalArgumentException("min cannot be greater than max!"); + } + float range = max - min; + return (float)(min + Math.random() * range); + } + + public float getRandomFloat(float max) { + return getRandomFloat(0.0F, max); + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/misc/Voidable.java b/src/main/java/me/trouper/alias/utils/misc/Voidable.java new file mode 100755 index 0000000..beacdb9 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/misc/Voidable.java @@ -0,0 +1,59 @@ +package me.trouper.alias.utils.misc; + +import me.trouper.alias.server.Main; + +import java.util.function.Consumer; +import java.util.function.Function; + +public class Voidable implements Main { + + private final T value; + + private Voidable(T value) { + this.value = value; + } + + public T get() { + return value; + } + + public boolean isPresent() { + return value != null; + } + + public Voidable map(Function function) { + return isPresent() ? of(function.apply(value)) : of(null); + } + + public void accept(Consumer action) { + if (isPresent()) { + action.accept(value); + } + } + + public void accept(Consumer action, Runnable orElse) { + if (isPresent()) { + action.accept(value); + } + else { + orElse.run(); + } + } + + public T getOrDef(T fallback) { + return isPresent() ? value : fallback; + } + + public T getOrThrow(String msg, Object... args) { + checkPre(isPresent(), msg, args); + return value; + } + + public T getOrThrow() { + return getOrThrow("value is not present."); + } + + public static Voidable of(T value) { + return new Voidable<>(value); + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/nbt/PersistentData.java b/src/main/java/me/trouper/alias/utils/nbt/PersistentData.java new file mode 100644 index 0000000..65af718 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/nbt/PersistentData.java @@ -0,0 +1,59 @@ +package me.trouper.alias.utils.nbt; + +import me.trouper.alias.server.Main; +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public class PersistentData implements Main { + + private final PersistentDataContainer data; + + public PersistentData(PersistentDataContainer data) { + this.data = data; + } + + public void write(String namespace, PersistentDataSerializable obj) { + if (namespace == null || namespace.isEmpty()) + return; + if (obj == null) { + remove(namespace); + return; + } + + NamespacedKey key = new NamespacedKey(main.getPlugin(), namespace); + String json = obj.serialize(); + + data.set(key, PersistentDataType.STRING, json); + } + + public void remove(String namespace) { + NamespacedKey key = new NamespacedKey(main.getPlugin(), namespace); + data.remove(key); + } + + public T read(String namespace, Class type) { + return read(namespace, type, null); + } + + public T read(String namespace, Class type, T fallback) { + try { + NamespacedKey key = new NamespacedKey(main.getPlugin(), namespace); + String json = data.get(key, PersistentDataType.STRING); + T obj = PersistentDataSerializable.gson.fromJson(json, type); + return obj != null ? obj : fallback; + } + catch (Exception ex) { + return fallback; + } + } + + public boolean valid(String namespace, Class type) { + return read(namespace, type, null) != null; + } + + public boolean has(String namespace) { + NamespacedKey key = new NamespacedKey(main.getPlugin(), namespace); + return data.has(key); + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/nbt/PersistentDataSerializable.java b/src/main/java/me/trouper/alias/utils/nbt/PersistentDataSerializable.java new file mode 100644 index 0000000..7f9f8f2 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/nbt/PersistentDataSerializable.java @@ -0,0 +1,17 @@ +package me.trouper.alias.utils.nbt; + +import com.google.gson.Gson; + +public interface PersistentDataSerializable { + + Gson gson = new Gson(); + + default String serialize() { + try { + return gson.toJson(this); + } + catch (Exception ex) { + return "{}"; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/visual/BlockDisplayRaytracer.java b/src/main/java/me/trouper/alias/utils/visual/BlockDisplayRaytracer.java new file mode 100755 index 0000000..d156cb2 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/visual/BlockDisplayRaytracer.java @@ -0,0 +1,351 @@ +package me.trouper.alias.utils.visual; + +import me.trouper.alias.server.Main; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.BlockDisplay; +import org.bukkit.entity.Display; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.Transformation; +import org.bukkit.util.Vector; +import org.bukkit.util.VoxelShape; +import org.joml.AxisAngle4f; +import org.joml.Vector3f; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class BlockDisplayRaytracer implements Main { + + public static void cleanup() { + JavaPlugin plugin = main.getPlugin(); + List worlds = plugin.getServer().getWorlds(); + List entities = new ArrayList<>(); + for (World world : worlds) { + entities.addAll(world.getEntities().stream().filter(entity -> entity.getScoreboardTags().contains("$/TrimAlias/ Temp")).toList()); + entities.forEach(entity -> { + if (entity != null) entity.remove(); + }); + } + } + + public static void outline(Material display, Location location, long stayTime, List viewers) { + outline(display, location, 0.05, stayTime, viewers); + } + + public static void outline(Material display, Location corner1, Location corner2, double thickness, long stayTime, List viewers) { + World world = corner1.getWorld(); + + int minX = Math.min(corner1.getBlockX(), corner2.getBlockX()); + int minY = Math.min(corner1.getBlockY(), corner2.getBlockY()); + int minZ = Math.min(corner1.getBlockZ(), corner2.getBlockZ()); + int maxX = Math.max(corner1.getBlockX(), corner2.getBlockX()); + int maxY = Math.max(corner1.getBlockY(), corner2.getBlockY()); + int maxZ = Math.max(corner1.getBlockZ(), corner2.getBlockZ()); + + Location a1 = new Location(world, minX, minY, minZ); + Location a2 = new Location(world, maxX + 1, minY, minZ); + Location a3 = new Location(world, maxX + 1, minY, maxZ + 1); + Location a4 = new Location(world, minX, minY, maxZ + 1); + + Location b1 = new Location(world, minX, maxY + 1, minZ); + Location b2 = new Location(world, maxX + 1, maxY + 1, minZ); + Location b3 = new Location(world, maxX + 1, maxY + 1, maxZ + 1); + Location b4 = new Location(world, minX, maxY + 1, maxZ + 1); + + trace(display, a1, a2, thickness, stayTime, viewers); + trace(display, a2, a3, thickness, stayTime, viewers); + trace(display, a3, a4, thickness, stayTime, viewers); + trace(display, a4, a1, thickness, stayTime, viewers); + + trace(display, b1, b2, thickness, stayTime, viewers); + trace(display, b2, b3, thickness, stayTime, viewers); + trace(display, b3, b4, thickness, stayTime, viewers); + trace(display, b4, b1, thickness, stayTime, viewers); + + trace(display, a1, b1, thickness, stayTime, viewers); + trace(display, a2, b2, thickness, stayTime, viewers); + trace(display, a3, b3, thickness, stayTime, viewers); + trace(display, a4, b4, thickness, stayTime, viewers); + } + + + public static void outline(Material display, Location location, double thickness, long stayTime, List viewers) { + Location og = location.getBlock().getLocation(); + + Location a1 = og.clone().add(0, 0, 0); + Location a2 = og.clone().add(1, 0, 0); + Location a3 = og.clone().add(1, 0, 1); + Location a4 = og.clone().add(0, 0, 1); + + Location b1 = og.clone().add(0, 1, 0); + Location b2 = og.clone().add(1, 1, 0); + Location b3 = og.clone().add(1, 1, 1); + Location b4 = og.clone().add(0, 1, 1); + + trace(display, a1, a2, thickness, stayTime, viewers); + trace(display, a2, a3, thickness, stayTime, viewers); + trace(display, a3, a4, thickness, stayTime, viewers); + trace(display, a4, a1, thickness, stayTime, viewers); + + trace(display, b1, b2, thickness, stayTime, viewers); + trace(display, b2, b3, thickness, stayTime, viewers); + trace(display, b3, b4, thickness, stayTime, viewers); + trace(display, b4, b1, thickness, stayTime, viewers); + + trace(display, a1, b1, thickness, stayTime, viewers); + trace(display, a2, b2, thickness, stayTime, viewers); + trace(display, a3, b3, thickness, stayTime, viewers); + trace(display, a4, b4, thickness, stayTime, viewers); + } + + public static void trace(Material display, Location start, Location end, long stayTime, List viewers) { + trace(display, start, end.toVector().subtract(start.toVector()), 0.05, end.distance(start), stayTime, viewers); + } + + public static void trace(Material display, Location start, Location end, double thickness, long stayTime, List viewers) { + trace(display, start, end.toVector().subtract(start.toVector()), thickness, end.distance(start), stayTime, viewers); + } + + public static void trace(Material display, Location start, Vector direction, double thickness, double distance, long stayTime, List viewers) { + World world = start.getWorld(); + + BlockDisplay beam = world.spawn(start, BlockDisplay.class, entity -> { + AxisAngle4f angle = new AxisAngle4f(0, 0, 0, 1); + Vector3f transition = new Vector3f(-(float)(thickness / 2F)); + Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance); + Transformation trans = new Transformation(transition, angle, scale, angle); + Location vector = entity.getLocation(); + + vector.setDirection(direction); + entity.teleport(vector); + entity.setBlock(display.createBlockData()); + entity.setBrightness(new Display.Brightness(15, 15)); + entity.setInterpolationDelay(0); + entity.setTransformation(trans); + entity.addScoreboardTag("$/TrimAlias/ Temp"); + + for (Player player : Bukkit.getOnlinePlayers()) { + if (!viewers.contains(player)) { + player.hideEntity(main.getPlugin(), entity); + } + } + + Bukkit.getScheduler().runTaskLater(main.getPlugin(), entity::remove, stayTime); + }); + } + + public static void trace(Material display, Location start, Vector direction, double thickness, double distance, long stayTime, Consumer onEntitySpawn, List viewers) { + World world = start.getWorld(); + + BlockDisplay beam = world.spawn(start, BlockDisplay.class, entity -> { + AxisAngle4f angle = new AxisAngle4f(0, 0, 0, 1); + Vector3f transition = new Vector3f(-(float)(thickness / 2F)); + Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance); + Transformation trans = new Transformation(transition, angle, scale, angle); + Location vector = entity.getLocation(); + + vector.setDirection(direction); + entity.teleport(vector); + entity.setBlock(display.createBlockData()); + entity.setBrightness(new Display.Brightness(15, 15)); + entity.setInterpolationDelay(0); + entity.setTransformation(trans); + entity.addScoreboardTag("$/TrimAlias/ Temp"); + + + for (Player player : Bukkit.getOnlinePlayers()) { + if (!viewers.contains(player)) { + player.hideEntity(main.getPlugin(), entity); + } + } + + Bukkit.getScheduler().runTaskLater(main.getPlugin(), entity::remove, stayTime); + Bukkit.getScheduler().runTaskLater(main.getPlugin(), () -> onEntitySpawn.accept(entity), 5); + }); + } + + public static List outline(Material display, Location location, long stayTime) { + return outline(display, location, 0.05, stayTime); + } + + public static List outline(Material display, Location location, double thickness, long stayTime) { + Location og = location.getBlock().getLocation(); + + Location a1 = og.clone().add(0, 0, 0); + Location a2 = og.clone().add(1, 0, 0); + Location a3 = og.clone().add(1, 0, 1); + Location a4 = og.clone().add(0, 0, 1); + + Location b1 = og.clone().add(0, 1, 0); + Location b2 = og.clone().add(1, 1, 0); + Location b3 = og.clone().add(1, 1, 1); + Location b4 = og.clone().add(0, 1, 1); + + List a = new ArrayList<>(); + + a.add(trace(display, a1, a2, thickness, stayTime)); + a.add(trace(display, a2, a3, thickness, stayTime)); + a.add(trace(display, a3, a4, thickness, stayTime)); + a.add(trace(display, a4, a1, thickness, stayTime)); + + a.add(trace(display, b1, b2, thickness, stayTime)); + a.add(trace(display, b2, b3, thickness, stayTime)); + a.add(trace(display, b3, b4, thickness, stayTime)); + a.add(trace(display, b4, b1, thickness, stayTime)); + + a.add(trace(display, a1, b1, thickness, stayTime)); + a.add(trace(display, a2, b2, thickness, stayTime)); + a.add(trace(display, a3, b3, thickness, stayTime)); + a.add(trace(display, a4, b4, thickness, stayTime)); + + return a; + } + + public static void highlightCollisions(Block block, Color color, long stayTime) { + if (block == null || block.isEmpty() || !block.isCollidable()) + return; + + VoxelShape shape = block.getCollisionShape(); + World world = block.getWorld(); + Vector offset = block.getLocation().toVector(); + + for (BoundingBox box : shape.getBoundingBoxes()) { + highlight(box, offset, world, color, stayTime); + } + } + + public static void highlight(BoundingBox box, Vector offset, World world, Color color, long stayTime) { + double x1 = box.getMinX() + offset.getX(); + double y1 = box.getMinY() + offset.getY(); + double z1 = box.getMinZ() + offset.getZ(); + double x2 = box.getMaxX() + offset.getX(); + double y2 = box.getMaxY() + offset.getY(); + double z2 = box.getMaxZ() + offset.getZ(); + + traceGlowing(world, x1, y1, z1, x2, y1, z1, color, stayTime); + traceGlowing(world, x2, y1, z1, x2, y1, z2, color, stayTime); + traceGlowing(world, x2, y1, z2, x1, y1, z2, color, stayTime); + traceGlowing(world, x1, y1, z2, x1, y1, z1, color, stayTime); + + traceGlowing(world, x1, y2, z1, x2, y2, z1, color, stayTime); + traceGlowing(world, x2, y2, z1, x2, y2, z2, color, stayTime); + traceGlowing(world, x2, y2, z2, x1, y2, z2, color, stayTime); + traceGlowing(world, x1, y2, z2, x1, y2, z1, color, stayTime); + + traceGlowing(world, x1, y1, z1, x1, y2, z1, color, stayTime); + traceGlowing(world, x2, y1, z1, x2, y2, z1, color, stayTime); + traceGlowing(world, x2, y1, z2, x2, y2, z2, color, stayTime); + traceGlowing(world, x1, y1, z2, x1, y2, z2, color, stayTime); + } + + public static void traceGlowing(World world, double x1, double y1, double z1, double x2, double y2, double z2, Color color, long stayTime) { + Location loc1 = new Location(world, x1, y1, z1); + Location loc2 = new Location(world, x2, y2, z2); + BlockDisplay ent = trace(Material.WHITE_CONCRETE, loc1, loc2, 0.01, stayTime); + ent.setGlowColorOverride(color); + ent.setGlowing(true); + } + + public static BlockDisplay trace(Material display, Location start, Location end, long stayTime) { + return trace(display, start, end.toVector().subtract(start.toVector()), 0.05, end.distance(start), stayTime); + } + + public static BlockDisplay trace(Material display, Location start, Location end, double thickness, long stayTime) { + return trace(display, start, end.toVector().subtract(start.toVector()), thickness, end.distance(start), stayTime); + } + + public static BlockDisplay trace(Material display, Location start, Vector direction, double thickness, double distance, long stayTime) { + World world = start.getWorld(); + + BlockDisplay entity = world.spawn(start, BlockDisplay.class); + AxisAngle4f angle = new AxisAngle4f(0, 0, 0, 1); + Vector3f transition = new Vector3f(-(float)(thickness / 2F)); + Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance); + Transformation trans = new Transformation(transition, angle, scale, angle); + Location vector = entity.getLocation(); + + vector.setDirection(direction); + entity.teleport(vector); + entity.setBlock(display.createBlockData()); + entity.setBrightness(new Display.Brightness(15, 15)); + entity.setInterpolationDelay(0); + entity.setTransformation(trans); + entity.addScoreboardTag("$/TrimAlias/ Temp"); + + Bukkit.getScheduler().runTaskLater(main.getPlugin(), entity::remove, stayTime); + return entity; + } + + public static void transform(BlockDisplay display, Location start, Location end, double thickness) { + Vector direction = end.toVector().subtract(start.toVector()); + double distance = direction.length(); + + Location loc = start.clone(); + loc.setDirection(direction); + display.teleport(loc); + + Vector3f translation = new Vector3f(-(float)(thickness / 2F), 0, 0); // Centered + Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance); + AxisAngle4f rotation = new AxisAngle4f(0, 0, 0, 1); + Transformation transformation = new Transformation(translation, rotation, scale, rotation); + + display.setTransformation(transformation); + } + + public static void transform(BlockDisplay display, Location start, Vector direction, double distance, double thickness) { + Location loc = start.clone(); + loc.setDirection(direction); + display.teleport(loc); + + Vector3f translation = new Vector3f(-(float)(thickness / 2F), 0, 0); + Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance); + AxisAngle4f rotation = new AxisAngle4f(0, 0, 0, 1); + Transformation transformation = new Transformation(translation, rotation, scale, rotation); + + display.setTransformation(transformation); + } + + + public static void translate(BlockDisplay display, Vector3f offset) { + Transformation current = display.getTransformation(); + Vector3f translation = new Vector3f(current.getTranslation()).add(offset); + display.setTransformation(new Transformation( + translation, + current.getLeftRotation(), + current.getScale(), + current.getRightRotation() + )); + } + + public static void scale(BlockDisplay display, Vector3f scale) { + Transformation current = display.getTransformation(); + display.setTransformation(new Transformation( + current.getTranslation(), + current.getLeftRotation(), + scale, + current.getRightRotation() + )); + } + + public static void rotate(BlockDisplay display, AxisAngle4f rotation) { + Transformation current = display.getTransformation(); + display.setTransformation(new Transformation( + current.getTranslation(), + rotation, + current.getScale(), + rotation + )); + } + + public static void alignToDirection(BlockDisplay display, Vector direction) { + Location loc = display.getLocation().clone(); + loc.setDirection(direction); + display.teleport(loc); + } + +} diff --git a/src/main/java/me/trouper/alias/utils/visual/CustomDisplayRaytracer.java b/src/main/java/me/trouper/alias/utils/visual/CustomDisplayRaytracer.java new file mode 100755 index 0000000..000b53d --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/visual/CustomDisplayRaytracer.java @@ -0,0 +1,317 @@ +package me.trouper.alias.utils.visual; + +import me.trouper.alias.utils.Verbose; +import org.bukkit.FluidCollisionMode; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.RayTraceResult; +import org.bukkit.util.Vector; +import org.bukkit.util.VoxelShape; + +import java.util.List; +import java.util.Random; +import java.util.function.BiPredicate; +import java.util.function.Predicate; + +public class CustomDisplayRaytracer { + + public static final Predicate HIT_BLOCK = point -> { + Block b = point.getBlock(); + Location l = point.getLoc(); + + if (b == null || b.isEmpty() || !b.isCollidable()) + return false; + + Vector vec = l.toVector().subtract(b.getLocation().toVector()); + VoxelShape shape = b.getCollisionShape(); + + for (BoundingBox box : shape.getBoundingBoxes()) + if (box.contains(vec)) + return true; + return false; + }; + + public static final Predicate HIT_ENTITY = point -> { + return !point.getNearbyEntities(null, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty(); + }; + + public static final Predicate HIT_BLOCK_OR_ENTITY = point -> { + return HIT_BLOCK.test(point) || HIT_ENTITY.test(point); + }; + + public static final Predicate HIT_BLOCK_AND_ENTITY = point -> { + return HIT_BLOCK.test(point) && HIT_ENTITY.test(point); + }; + + public static Predicate hitEntityExclude(Entity exclude) { + return point -> !point.getNearbyEntities(exclude, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty(); + } + + public static Predicate hitAnythingExclude(Entity exclude) { + return point -> HIT_BLOCK.test(point) || !point.getNearbyEntities(exclude, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty(); + } + + public static Predicate hitEverythingExclude(Entity exclude) { + return point -> HIT_BLOCK.test(point) && !point.getNearbyEntities(exclude, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty(); + } + + public static Predicate hitEntityIf(Predicate condition) { + return point -> !point.getNearbyEntities(null, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead() && condition.test(e)).isEmpty(); + } + + public static Predicate hitBlockIf(Predicate condition) { + return point -> HIT_BLOCK.test(point) && condition.test(point.getBlock()); + } + + public static Predicate hitAnythingIf(Predicate condition) { + return point -> HIT_BLOCK.test(point) || !point.getNearbyEntities(null, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead() && condition.test(e)).isEmpty(); + } + + public static Predicate hitEverythingIf(Predicate condition) { + return point -> HIT_BLOCK.test(point) && !point.getNearbyEntities(null, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead() && condition.test(e)).isEmpty(); + } + + + public static Point trace(Location start, Location end, Predicate hitCondition) { + return trace(start, end, 0.5, hitCondition); + } + + public static Point trace(Location start, Location end, double interval, Predicate hitCondition) { + return trace(start, end.toVector().subtract(start.toVector()), end.distance(start), interval, hitCondition); + } + + public static Point trace(Location start, Vector direction, double distance, Predicate hitCondition) { + return trace(start, direction, distance, 0.5, hitCondition); + } + + public static Point trace(Location start, Vector direction, double distance, double interval, Predicate hitCondition) { + if (interval < 0) throw new IllegalArgumentException("interval cannot be zero!"); + if (distance < 0) throw new IllegalArgumentException("distance cannot be zero!"); + + for (double i = 0.0; i < distance; i += interval) { + Point point = blocksInFrontOf(start, direction, i, false); + if (hitCondition.test(point)) { + return point; + } + } + return blocksInFrontOf(start, direction, distance, true); + } + + + public static BukkitTask traceDelayed(Plugin plugin, Location start, Vector direction, double distance, double interval, long tickDelay, int pointsPerTick, Predicate hitCondition) { + + if (interval <= 0) throw new IllegalArgumentException("interval cannot be zero or negative!"); + if (distance <= 0) throw new IllegalArgumentException("distance cannot be zero or negative!"); + if (tickDelay < 0) throw new IllegalArgumentException("tickDelay cannot be negative!"); + + Vector normalizedDir = direction.clone().normalize(); + + + return new BukkitRunnable() { + private double currentDistance = 0.0; + private boolean hit = false; + + @Override + public void run() { + if (hit || currentDistance > distance) { + if (!hit) { + Point finalPoint = blocksInFrontOf(start, normalizedDir, distance, true); + hitCondition.test(finalPoint); + } + this.cancel(); + return; + } + + for (int i = 0; i < pointsPerTick && currentDistance <= distance; i++) { + Point point = blocksInFrontOf(start, normalizedDir, currentDistance, false); + if (hitCondition.test(point)) { + hit = true; + break; + } + currentDistance += interval; + } + } + }.runTaskTimer(plugin, 0, tickDelay); + } + + public static BukkitTask traceDelayed(Plugin plugin, Location start, Location end, double interval, long tickDelay, int pointsPerTick, Predicate hitCondition) { + Vector direction = end.toVector().subtract(start.toVector()).normalize(); + double distance = start.distance(end); + return traceDelayed(plugin, start, direction, distance, interval, tickDelay,pointsPerTick, hitCondition); + } + + public static BukkitTask traceDelayed(Plugin plugin, + Location start, + Location end, + long tickDelay, + Predicate hitCondition) { + return traceDelayed(plugin, start, end,0.5, tickDelay, 1, hitCondition); + } + + public static BukkitTask traceDelayed(Plugin plugin, + Location start, + Vector direction, + double distance, + long tickDelay, + Predicate hitCondition) { + return traceDelayed(plugin, start, direction, distance, 0.5, tickDelay,1, hitCondition); + } + + public static Point traceWithReflection(Location start, Vector direction, double distance, double interval, + int maxReflections, Predicate hitCondition, + BiPredicate blockReflectCondition, + BiPredicate entityReflectCondition) { + + + if (interval <= 0) throw new IllegalArgumentException("interval cannot be zero or negative!"); + if (distance <= 0) throw new IllegalArgumentException("distance cannot be zero or negative!"); + + Vector normalizedDir = direction.clone().normalize(); + Location currentLocation = start.clone(); + Vector currentDirection = normalizedDir.clone(); + double remainingDistance = distance; + int reflections = 0; + + while (remainingDistance > 0 && reflections <= maxReflections) { + for (double i = 0.0; i < remainingDistance; i += interval) { + Point point = blocksInFrontOf(currentLocation, currentDirection, i, false); + + if (hitCondition.test(point)) { + return point; + } + + boolean shouldReflect = false; + Vector newDirection = null; + + if (HIT_BLOCK.test(point) && point.getBlock() != null) { + Block hitBlock = point.getBlock(); + if (blockReflectCondition.test(point, hitBlock)) { + Point previousPoint = blocksInFrontOf(currentLocation, currentDirection, Math.max(0, i - interval), false); + + BlockFace hitFace = traceBlockFace(previousPoint.getLoc(), currentDirection, interval * 2); + + if (hitFace != null) { + Vector faceNormal = getFaceNormal(hitFace); + newDirection = calculateReflection(currentDirection, faceNormal); + shouldReflect = true; + } + } + } + + List nearbyEntities = point.getNearbyEntities(null, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()); + if (!nearbyEntities.isEmpty()) { + for (Entity entity : nearbyEntities) { + if (entityReflectCondition.test(point, entity)) { + Point previousPoint = blocksInFrontOf(currentLocation, currentDirection, Math.max(0, i - interval), false); + + newDirection = glanceReflect(currentDirection); + shouldReflect = true; + break; + } + } + } + + if (shouldReflect) { + double backStep = Math.max(0, i - interval); + currentLocation = blocksInFrontOf(currentLocation, currentDirection, backStep, false).getLoc(); + + currentDirection = newDirection; + + remainingDistance -= backStep; + + reflections++; + + currentLocation = currentLocation.add(currentDirection.clone().multiply(interval * 0.1)); + remainingDistance -= interval * 0.1; + + break; + } + + if (i + interval >= remainingDistance) { + Point finalPoint = blocksInFrontOf(currentLocation, currentDirection, remainingDistance, true); + return finalPoint; + } + } + + if (reflections > maxReflections) { + Point finalPoint = blocksInFrontOf(currentLocation, currentDirection, remainingDistance, true); + return finalPoint; + } + } + + return blocksInFrontOf(start, normalizedDir, distance, true); + } + + private static Vector glanceReflect(Vector incident) { + return offsetVector(incident,4).multiply(-1); + } + + private static BlockFace traceBlockFace(Location startLocation, Vector direction, double maxDistance) { + Predicate blockPredicate = block -> true; + Predicate entityPredicate = entity -> false; + + RayTraceResult result = startLocation.getWorld().rayTrace(startLocation, direction, maxDistance, FluidCollisionMode.NEVER,true,0.1,entityPredicate, blockPredicate); + + if (result != null && result.getHitBlock() != null && result.getHitBlockFace() != null) { + return result.getHitBlockFace(); + } + + return null; + } + + private static Vector calculateReflection(Vector incident, Vector normal) { + // r = i - 2(i dot n)n + double dot = incident.dot(normal); + Vector reflection = incident.clone().subtract(normal.clone().multiply(2 * dot)); + + return reflection.normalize(); + } + + private static Vector getFaceNormal(BlockFace face) { + Verbose.send("Getting normal for %s".formatted(face)); + return switch (face) { + case DOWN -> new Vector(0, -1, 0); + case NORTH -> new Vector(0, 0, -1); + case SOUTH -> new Vector(0, 0, 1); + case EAST -> new Vector(1, 0, 0); + case WEST -> new Vector(-1, 0, 0); + default -> new Vector(0, 1, 0); + }; + } + + public static Point blocksInFrontOf(Location loc, Vector dir, double blocks, boolean missed) { + return new Point(loc.clone().add(dir.getX() * blocks, dir.getY() * blocks, dir.getZ() * blocks), blocks, missed); + } + + public static Vector offsetVector(Vector original, double angleDegrees) { + Random random = new Random(); + original = original.clone().normalize(); + + double yaw = Math.toDegrees(Math.atan2(-original.getX(), original.getZ())); + double pitch = Math.toDegrees(Math.asin(-original.getY())); + + double yawOffset = (random.nextDouble() * 2 - 1) * angleDegrees; + double pitchOffset = (random.nextDouble() * 2 - 1) * angleDegrees; + + yaw += yawOffset; + pitch += pitchOffset; + + pitch = Math.max(-90, Math.min(90, pitch)); + + double pitchRad = Math.toRadians(pitch); + double yawRad = Math.toRadians(yaw); + + double x = -Math.sin(yawRad) * Math.cos(pitchRad); + double y = -Math.sin(pitchRad); + double z = Math.cos(yawRad) * Math.cos(pitchRad); + + return new Vector(x, y, z); + } +} diff --git a/src/main/java/me/trouper/alias/utils/visual/DisplayUtils.java b/src/main/java/me/trouper/alias/utils/visual/DisplayUtils.java new file mode 100755 index 0000000..a0dfdd9 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/visual/DisplayUtils.java @@ -0,0 +1,247 @@ +package me.trouper.alias.utils.visual; + +import me.trouper.alias.server.Main; +import me.trouper.alias.utils.misc.Randomizer; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +public class DisplayUtils implements Main { + + + public static void sphere(Location center, double radius, double pointDistance, Consumer action) { + double dPhi = pointDistance / radius; + + for (double phi = 0.0; phi <= Math.PI; phi += dPhi) { + double yOffset = radius * Math.cos(phi); + double ringRadius = radius * Math.sin(phi); + + if (ringRadius < 1e-6) { + Location loc = center.clone().add(0, yOffset, 0); + action.accept(loc); + } else { + double dTheta = pointDistance / ringRadius; + + for (double theta = 0.0; theta < 2 * Math.PI; theta += dTheta) { + double xOffset = ringRadius * Math.cos(theta); + double zOffset = ringRadius * Math.sin(theta); + + Location loc = center.clone().add(xOffset, yOffset, zOffset); + action.accept(loc); + } + } + } + } + + public static void sphereWave(Location center, double maxRadius, double radialStep, double maxDistanceBetweenPoints, Consumer action) { + AtomicReference currentRadius = new AtomicReference<>(radialStep); + + Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> { + double r = currentRadius.get(); + if (r > maxRadius) return; + + sphere(center, r, maxDistanceBetweenPoints, action); + currentRadius.set(r + radialStep); + }, 0L, 1L); + } + + + + public static final Function> PARTICLE_FACTORY = particle -> l -> l.getWorld().spawnParticle(particle, l, 1, 0, 0, 0, 0); + + public static final BiFunction> DUST_PARTICLE_FACTORY = (color, thickness) -> { + Particle.DustOptions dust = new Particle.DustOptions(color, thickness); + return l -> l.getWorld().spawnParticle(Particle.DUST, l, 1, 0, 0, 0, 0, dust); + }; + + public static final Function> FLAME_PARTICLE_FACTORY = soul -> { + Particle flame = soul ? Particle.SOUL_FIRE_FLAME : Particle.FLAME; + return l -> l.getWorld().spawnParticle(flame, l, 1, 0, 0, 0, 0); + }; + + public static void ring(Location loc, double radius, Color color, float thickness) { + ring(loc, radius, DUST_PARTICLE_FACTORY.apply(color, thickness)); + } + + public static void ring(Location loc, double radius, Consumer action) { + for (int theta = 0; theta < 360; theta += 10) { + double x = Math.cos(Math.toRadians(theta)) * radius; + double z = Math.sin(Math.toRadians(theta)) * radius; + Location newLoc = loc.clone().add(x, 0, z); + action.accept(newLoc); + } + } + + public static void ring(Location loc, double radius, double maxDistanceBetweenPoints, Consumer action) { + arc(loc, radius, 0, 360, maxDistanceBetweenPoints, action); + } + + public static void wave(Location loc, double radius, Color color, float thickness, double gap) { + wave(loc, radius, DUST_PARTICLE_FACTORY.apply(color, thickness), gap); + } + + public static void wave(Location loc, double radius, Consumer action, double gap) { + AtomicReference i = new AtomicReference<>(gap); + Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> { + if (i.get() >= radius) { + return; + } + ring(loc, i.get(), action); + i.set(i.get() + gap); + }, 0, 1); + } + + public static void wave(Location loc, double radius, double radialGap, double maxDistanceBetweenPoints, Consumer action) { + AtomicReference r = new AtomicReference<>(radialGap); + Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> { + if (r.get() > radius) return; + ring(loc, r.get(), maxDistanceBetweenPoints, action); + r.set(r.get() + radialGap); + }, 0, 1); + } + + public static void disc(Location loc, double radius, Consumer action, double gap) { + for (double i = gap; i < radius; i += gap) { + ring(loc, i, action); + } + } + + public static void disc(Location loc, double radius, double radialGap, double maxDistanceBetweenPoints, Consumer action) { + for (double r = radialGap; r <= radius; r += radialGap) { + ring(loc, r, maxDistanceBetweenPoints, action); + } + } + + public static void helix(Location loc, double radius, Consumer action, double gap, int height) { + int theta = 0; + for (double y = 0; y <= height; y += gap) { + double x = Math.cos(Math.toRadians(theta)) * radius; + double z = Math.sin(Math.toRadians(theta)) * radius; + + Location newLoc = loc.clone().add(x, y, z); + action.accept(newLoc); + theta += 10; + } + } + + public static void vortex(Location loc, double radius, Consumer action, double gapH, double gapV, int height) { + double r = radius; + int theta = 0; + for (double y = 0; y <= height; y += gapV) { + double x = Math.cos(Math.toRadians(theta)) * r; + double z = Math.sin(Math.toRadians(theta)) * r; + + Location newLoc = loc.clone().add(x, y, z); + action.accept(newLoc); + r += gapH; + theta += 10; + } + } + + public static void beam(Location loc, Consumer action, double gap, int height) { + for (double y = 0; y <= height; y += gap) { + Location newLoc = loc.clone().add(0, y, 0); + action.accept(newLoc); + } + } + + public static void arc(Location loc, double radius, int angleFrom, int angleTo, Consumer action) { + for (int theta = angleFrom; theta < angleTo; theta += 10) { + double x = Math.cos(Math.toRadians(theta)) * radius; + double z = Math.sin(Math.toRadians(theta)) * radius; + Location newLoc = loc.clone().add(x, 0, z); + action.accept(newLoc); + } + } + + public static void arc(Location loc, double radius, int angleFrom, int angleTo, double maxDistanceBetweenPoints, Consumer action) { + int angleSpan = angleTo - angleFrom; + if (angleSpan <= 0) return; + + int points = Math.max(2, (int) ((2 * Math.PI * radius * (angleSpan / 360.0)) / maxDistanceBetweenPoints)); + double angleStep = (double) angleSpan / points; + + for (int i = 0; i <= points; i++) { + double theta = angleFrom + (i * angleStep); + double x = Math.cos(Math.toRadians(theta)) * radius; + double z = Math.sin(Math.toRadians(theta)) * radius; + Location point = loc.clone().add(x, 0, z); + action.accept(point); + } + } + + + public static void fan(Location loc, double radius, int angleFrom, int angleTo, Consumer action, double gap) { + for (double i = gap; i < radius; i += gap) { + arc(loc, i, angleFrom, angleTo, action); + } + } + + public static void fan(Location loc, double radius, int angleFrom, int angleTo, double maxDistanceBetweenPoints, Consumer action, double radialGap) { + for (double r = radialGap; r < radius; r += radialGap) { + arc(loc, r, angleFrom, angleTo, maxDistanceBetweenPoints, action); + } + } + + + public static void fanWave(Location loc, double radius, int sections, Consumer action, double gap) { + double arcLength = 360.0 / sections; + AtomicReference i = new AtomicReference<>(0.0); + Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> { + if (i.get() >= 360) { + return; + } + double start = i.get(); + fan(loc, radius, (int)start, (int)(start + arcLength), action, gap); + i.set(i.get() + arcLength); + }, 0, 5); + } + + public static void fanWaveRandom(Location loc, double radius, int sections, Consumer action, double gap) { + double arcLength = 360.0 / sections; + List ints = new ArrayList<>(); + for (double start = 0; start < 360; start += arcLength) { + ints.add(start); + } + + AtomicInteger i = new AtomicInteger(0); + Randomizer random = new Randomizer(); + Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> { + if (i.get() >= sections) { + return; + } + double start = random.getRandomElement(ints); + ints.remove(start); + fan(loc, radius, (int)start, (int)(start + arcLength), action, gap); + i.getAndIncrement(); + }, 0, 5); + } + + public static void waveFan(Location loc, double radius, int angleFrom, int angleTo, double maxDistanceBetweenPoints, Consumer action, double radialGap) { + AtomicReference r = new AtomicReference<>(radialGap); + Bukkit.getScheduler().scheduleSyncRepeatingTask(main.getPlugin(), () -> { + if (r.get() >= radius) return; + arc(loc, r.get(), angleFrom, angleTo, maxDistanceBetweenPoints, action); + r.set(r.get() + radialGap); + }, 0, 1); + } + + public static void waveFan(Location loc, double radius, Vector direction, int angle, double maxDistanceBetweenPoints, Consumer action, double radialGap) { + double baseAngle = Math.toDegrees(Math.atan2(direction.getZ(), direction.getX())); + int angleFrom = (int) (baseAngle - angle / 2.0); + int angleTo = (int) (baseAngle + angle / 2.0); + waveFan(loc, radius, angleFrom, angleTo, maxDistanceBetweenPoints, action, radialGap); + } + + +} \ No newline at end of file diff --git a/src/main/java/me/trouper/alias/utils/visual/Point.java b/src/main/java/me/trouper/alias/utils/visual/Point.java new file mode 100755 index 0000000..e63e34e --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/visual/Point.java @@ -0,0 +1,88 @@ +package me.trouper.alias.utils.visual; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +public class Point { + private final Location loc; + private final World world; + private final Block block; + private final boolean missed; + private final double traveledDist; + private List rayPath; + + public Point(Location loc, double traveledDist, boolean missed) { + this.loc = loc; + this.world = loc.getWorld(); + this.block = loc.getBlock(); + this.missed = missed; + this.traveledDist = traveledDist; + + if (world == null) { + throw new IllegalArgumentException("point world cannot be null!"); + } + } + + public List getNearbyEntities(Entity exclude, int range, boolean requireContact, double expansionX, double expansionY, double expansionZ, Predicate filter) { + return new ArrayList<>(world.getNearbyEntities(loc, range, range, range, e -> { + if (requireContact && !e.getBoundingBox().expand(expansionX, expansionY, expansionZ).contains(loc.toVector())) { + return false; + } + return filter.test(e) && e != exclude; + })); + } + + public List getNearbyEntities(Entity exclude, int range, boolean requireContact, double expansion, Predicate filter) { + return getNearbyEntities(exclude, range, requireContact, expansion, expansion, expansion, filter); + } + + public List getNearbyEntities(Entity exclude, int range, boolean requireContact, Predicate filter) { + return getNearbyEntities(exclude, range, requireContact, 0, filter); + } + + public List getNearbyEntities(Entity exclude, int range, Predicate filter) { + return getNearbyEntities(exclude, range, false, filter); + } + + public double getTraveledDist() { + return traveledDist; + } + + public boolean wasMissed() { + return missed; + } + + public Block getBlock() { + return block; + } + + public Location getLoc() { + return loc; + } + + public World getWorld() { + return world; + } + + public double distance(Location other) { + return other.distance(loc); + } + + public Point addRayPoint(Point point) { + rayPath.add(point); + return point; + } + + public List setRayPath(List points) { + rayPath = points; + return rayPath; + } + + public List getRayPath = new ArrayList<>(); +} diff --git a/src/main/java/me/trouper/alias/utils/visual/ReflectionResult.java b/src/main/java/me/trouper/alias/utils/visual/ReflectionResult.java new file mode 100755 index 0000000..2f4bf79 --- /dev/null +++ b/src/main/java/me/trouper/alias/utils/visual/ReflectionResult.java @@ -0,0 +1,27 @@ +package me.trouper.alias.utils.visual; + +import org.bukkit.util.Vector; + +public class ReflectionResult { + private final Point hitPoint; + private final boolean shouldReflect; + private final Vector reflectedDirection; + + public ReflectionResult(Point hitPoint, boolean shouldReflect, Vector reflectedDirection) { + this.hitPoint = hitPoint; + this.shouldReflect = shouldReflect; + this.reflectedDirection = reflectedDirection; + } + + public Point getHitPoint() { + return hitPoint; + } + + public boolean shouldReflect() { + return shouldReflect; + } + + public Vector getReflectedDirection() { + return reflectedDirection; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..dcf42f6 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,8 @@ +name: Alias +main: me.trouper.alias.Alias +version: 1.0.0 +authors: [ obvWolf ] +api-version: 1.21 +commands: + example_command: + description: Hello world command \ No newline at end of file