diff --git a/.github/dependabot.yml b/.github/dependabot.yml index cd5ece2..a1fdab7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,6 @@ version: 2 updates: - - package-ecosystem: "maven" + - package-ecosystem: "gradle" directory: "/" schedule: interval: "weekly" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 20b77a8..bf86293 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,46 +1,34 @@ -name: CI - -on: - push: - branches-ignore: - - dependabot/** - pull_request: - -jobs: - build: - name: Build with Maven - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Cache local Maven repository - id: cache-maven - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - - name: Setup JDK 21 - uses: actions/setup-java@v4 - with: - java-version: 21 - distribution: temurin - - - name: Set up Maven Wrapper - run: mvn --errors --batch-mode --show-version org.apache.maven.plugins:maven-wrapper-plugin:3.3.2:wrapper "-Dmaven=3.9.9" - - - name: Build with Maven - run: | - ./mvnw clean package --batch-mode --no-transfer-progress --show-version - echo "BUILD_NAME=$(./mvnw help:evaluate -Dexpression=project.build.finalName -pl dist -q -DforceStdout)" >> $GITHUB_ENV - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ env.BUILD_NAME }} - path: | - target/InteractiveChat-PacketEvents-*.jar \ No newline at end of file +name: CI + +on: + push: + branches-ignore: + - dependabot/** + pull_request: + +jobs: + build: + name: Build with Gradle + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: 'gradle' + + - name: Build with Gradle + run: | + ./gradlew clean build + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: InteractiveChat-PacketEvents-${{ github.run_number }} + path: | + libs/InteractiveChat-PacketEvents-*.jar \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2bf5ce1..8890f66 100644 --- a/.gitignore +++ b/.gitignore @@ -1,30 +1,30 @@ -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -replay_pid* - -# IDE -.idea/ -*.iml -dependency-reduced-pom.xml -target/ \ No newline at end of file +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +# IDE +.idea/ +.gradle/ +libs/ +build/ \ No newline at end of file diff --git a/README.md b/README.md index 9a9846b..d38fd64 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # InteractiveChat-PacketEvents (WIP) An addon plugin for InteractiveChat to support PacketEvents instead of ProtocolLib.\ -This is a very simple plugin that implements all the code seen [here](https://github.com/Skullians/InteractiveChatPacketEvents/tree/master/common/src/main/java/com/loohp/interactivechat/listeners/packet).\ +This is a very simple plugin that implements all the code seen [here](https://github.com/LOOHP/InteractiveChat/tree/master/common/src/main/java/com/loohp/interactivechat/platform).\ Very little modifications to code have been made, apart from making it support PacketEvents. > [!WARNING] -> This plugin **REQUIRES** v4.3.0.0 of InteractiveChat, or higher.\ +> This plugin **REQUIRES** v4.3.5.0 of InteractiveChat, or higher.\ > This plugin will NOT boot otherwise. @@ -27,5 +27,5 @@ You can see the corresponding PR here: https://github.com/LOOHP/InteractiveChat/ 1. Install the latest version of PacketEvents, and this plugin. 2. Start your server -## Permissions and Commands -`/interactivechatpacketevents checkupdate` - Requires the `interactivechatpacketevents.checkupdate` command (or OP). `/icpe checkupdate` also works. +## Permissions +Requires the `interactivechatpacketevents.checkupdate` permission to check for updates on join. diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..a3335e8 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,83 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + java + + alias(libs.plugins.shadow) + alias(libs.plugins.properties) +} + +group = "net.skullian" +version = "1.1.0" + +repositories { + mavenCentral() + mavenLocal() + + maven { + name = "spigotmc-repo" + url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + } + maven { + name = "sonatype" + url = uri("https://oss.sonatype.org/content/groups/public/") + } + maven { + name = "codemc" + url = uri("https://repo.codemc.org/repository/maven-public/") + } + maven { + name = "loohp-repo" + url = uri("https://repo.loohpjames.com/repository") + } +} + +dependencies { + compileOnly(libs.spigot) + + compileOnly(libs.interactivechat) + compileOnly(libs.packetevents) + compileOnly(libs.bytebuddy) + + compileOnly(libs.lombok) + annotationProcessor(libs.lombok) + + compileOnly(libs.bundles.adventure) +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} + +tasks { + withType().configureEach { + from(rootProject.projectDir.resolve("LICENSE")) { + rename("LICENSE", "META-INF/LICENSE_${rootProject.name}") + } + + destinationDirectory.set(file("$rootDir/libs")) + archiveFileName.set("${rootProject.name}-$version.jar") + } + + processResources { + filteringCharset = "UTF-8" + filesMatching(listOf("*.yml")) { + expand(project.properties) + } + } + + withType { + options.compilerArgs.add("-parameters") + options.isFork = true + options.encoding = "UTF-8" + options.release = 17 + } +} + +gitProperties { + gitPropertiesName = "version.properties" + dotGitDirectory = project.rootProject.layout.projectDirectory.dir(".git") + keys = listOf("git.branch", "git.build.version", "git.commit.id.abbrev") +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..c407ece --- /dev/null +++ b/gradle.properties @@ -0,0 +1,8 @@ +org.gradle.cache=true +org.gradle.caching=true +org.gradle.parallel=true +org.gradle.configuration-cache=false +org.gradle.configuration-cache-problems=warn +org.gradle.configureondemand=true +org.gradle.jvmargs=-Xmx4048m -Dfile.encoding=UTF-8 +org.gradle.vfs.watch=false \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..71244b4 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,34 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format + +[versions] +spigot-api="1.20.6-R0.1-SNAPSHOT" + +packetevents = "2.10.1" +interactivechat = "4.3.5.0" +bytebuddy = "1.17.6" + +adventure = "4.25.0" +adventure-platform = "4.4.1" + +lombok="1.18.38" +shadow="9.3.0" +properties = "2.5.4" + +[libraries] +packetevents = { module = "com.github.retrooper:packetevents-spigot", version.ref = "packetevents" } +interactivechat = { module = "com.loohp:InteractiveChat", version.ref = "interactivechat" } +bytebuddy = { module = "net.bytebuddy:byte-buddy", version.ref = "bytebuddy" } +adventure-platform-bukkit = { module = "net.kyori:adventure-platform-bukkit", version.ref = "adventure-platform" } +adventure-text-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure" } +adventure-text-serializer-legacy = { module = "net.kyori:adventure-text-serializer-legacy", version.ref = "adventure" } +adventure-text-serializer-plain = { module = "net.kyori:adventure-text-serializer-plain", version.ref = "adventure" } +lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } +spigot = { module = "org.spigotmc:spigot", version.ref = "spigot-api" } + +[bundles] +adventure = [ "adventure-platform-bukkit", "adventure-text-minimessage", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] + +[plugins] +shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } +properties = { id = "com.gorylenko.gradle-git-properties", version.ref = "properties" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..2e11132 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..adff685 --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e509b2d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@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 +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 9685755..0000000 --- a/pom.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - 4.0.0 - - net.skullian - InteractiveChat-PacketEvents - 1.1.0 - jar - - InteractiveChat-PacketEvents - - - 1.8 - UTF-8 - - - - clean package - - - org.apache.maven.plugins - maven-compiler-plugin - 3.14.0 - - ${java.version} - ${java.version} - - - org.projectlombok - lombok - 1.18.38 - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - package - - shade - - - - - - io.github.git-commit-id - git-commit-id-maven-plugin - - - get-the-git-infos - - revision - - initialize - - - - full - true - ${project.build.outputDirectory}/version.json - json - - git.branch - git.build.time - git.build.version - git.commit.id.abbrev - - - - - - - src/main/resources - true - - - - - - - spigotmc-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - sonatype - https://oss.sonatype.org/content/groups/public/ - - - CodeMC - https://repo.codemc.org/repository/maven-public/ - - - loohp-repo - https://repo.loohpjames.com/repository - - - - - - org.spigotmc - spigot-api - 1.20.4-R0.1-SNAPSHOT - provided - - - com.loohp - InteractiveChat - 4.3.1.0 - provided - - - com.github.retrooper - packetevents-spigot - 2.9.3 - provided - - - net.kyori - adventure-text-serializer-plain - 4.18.0 - provided - - - net.kyori - adventure-text-serializer-legacy - 4.18.0 - provided - - - net.kyori - adventure-platform-bukkit - 4.3.4 - provided - - - net.kyori - adventure-text-minimessage - 4.18.0 - provided - - - org.incendo - cloud-paper - 2.0.0-beta.10 - provided - - - org.incendo - cloud-annotations - 2.0.0 - provided - - - net.bytebuddy - byte-buddy - 1.17.6 - provided - - - - org.projectlombok - lombok - 1.18.38 - provided - - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..0eeeb3e --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "InteractiveChat-PacketEvents" diff --git a/src/main/java/net/skullian/InteractiveChatPacketEvents.java b/src/main/java/net/skullian/InteractiveChatPacketEvents.java index d4f3283..9ef428f 100644 --- a/src/main/java/net/skullian/InteractiveChatPacketEvents.java +++ b/src/main/java/net/skullian/InteractiveChatPacketEvents.java @@ -1,7 +1,6 @@ package net.skullian; import com.loohp.interactivechat.InteractiveChat; -import net.skullian.command.CommandHandler; import net.skullian.platform.PacketEventsPlatform; import net.skullian.updater.UpdateListener; import net.skullian.util.ChatUtils; @@ -26,11 +25,8 @@ public void onEnable() { debug = InteractiveChatPacketEvents.instance.getConfig().getBoolean("Debug"); ChatUtils.sendMessage("Initialising ProtocolProvider."); - InteractiveChat.protocolPlatform.initialize(); getServer().getPluginManager().registerEvents(new UpdateListener(), this); - - new CommandHandler(); } @Override diff --git a/src/main/java/net/skullian/command/CommandHandler.java b/src/main/java/net/skullian/command/CommandHandler.java deleted file mode 100644 index 8ebb4f5..0000000 --- a/src/main/java/net/skullian/command/CommandHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.skullian.command; - -import net.skullian.InteractiveChatPacketEvents; -import net.skullian.command.subcmd.CheckUpdateCommand; -import net.skullian.util.ChatUtils; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.incendo.cloud.annotations.AnnotationParser; -import org.incendo.cloud.bukkit.BukkitCommandManager; -import org.incendo.cloud.bukkit.CloudBukkitCapabilities; -import org.incendo.cloud.execution.ExecutionCoordinator; -import org.incendo.cloud.meta.SimpleCommandMeta; -import org.incendo.cloud.paper.LegacyPaperCommandManager; - -public class CommandHandler { - - private AnnotationParser parser; - public static LegacyPaperCommandManager manager; - - public CommandHandler() { - manager = LegacyPaperCommandManager.createNative( - InteractiveChatPacketEvents.instance, - ExecutionCoordinator.asyncCoordinator() - ); - - if (manager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { - manager.registerBrigadier(); - } else if (manager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { - manager.registerAsynchronousCompletions(); - } - - parser = new AnnotationParser<>( - manager, - CommandSender.class, - params -> SimpleCommandMeta.empty() - ); - - registerCommands(); - - ChatUtils.sendMessage("Registered commands.", Bukkit.getConsoleSender()); - } - - private void registerCommands() { - parser.parse(new CheckUpdateCommand()); - } -} diff --git a/src/main/java/net/skullian/command/subcmd/CheckUpdateCommand.java b/src/main/java/net/skullian/command/subcmd/CheckUpdateCommand.java deleted file mode 100644 index 49f74d9..0000000 --- a/src/main/java/net/skullian/command/subcmd/CheckUpdateCommand.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.skullian.command.subcmd; - -import net.skullian.InteractiveChatPacketEvents; -import net.skullian.updater.Updater; -import net.skullian.util.ChatUtils; -import org.bukkit.command.CommandSender; -import org.incendo.cloud.annotations.Command; -import org.incendo.cloud.annotations.CommandDescription; -import org.incendo.cloud.annotations.Permission; - -@Command("interactivechatpacketevents|icpe") -public class CheckUpdateCommand { - - @Command("checkupdate") - @CommandDescription("Check for updates") - @Permission(value = {"interactivechatpacketevents.checkupdate"}) - public void execute( - CommandSender sender - ) { - ChatUtils.sendMessage("Checking for updates, please wait...", sender); - - Updater.UpdateStatus updateStatus = Updater.checkUpdate(sender); - - if (updateStatus.isUpToDate() && !updateStatus.isFailed()) { - ChatUtils.sendMessage("You are running the latest version of InteractiveChat-PacketEvents! [" + InteractiveChatPacketEvents.instance.getDescription().getVersion() + "]", sender); - } - } -} diff --git a/src/main/java/net/skullian/listeners/PEClientSettingsPacket.java b/src/main/java/net/skullian/listeners/PEClientSettingsPacket.java deleted file mode 100644 index 55751e1..0000000 --- a/src/main/java/net/skullian/listeners/PEClientSettingsPacket.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.skullian.listeners; - -import com.github.retrooper.packetevents.event.PacketListener; -import com.github.retrooper.packetevents.event.PacketReceiveEvent; -import com.github.retrooper.packetevents.protocol.packettype.PacketType; -import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientSettings; -import com.loohp.interactivechat.InteractiveChat; -import com.loohp.interactivechat.listeners.packet.ClientSettingsHandler; -import com.loohp.interactivechat.utils.MCVersion; -import com.loohp.interactivechat.utils.PlayerUtils; -import net.skullian.InteractiveChatPacketEvents; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class PEClientSettingsPacket implements PacketListener, Listener { - - private final Map colorSettingsMap = new HashMap<>(); - - @Override - public void onPacketReceive(PacketReceiveEvent event) { - if (event.getPacketType() != PacketType.Configuration.Client.CLIENT_SETTINGS) return; - - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_20_2)) { - WrapperConfigClientSettings packet = new WrapperConfigClientSettings(event); - - UUID uuid = event.getUser().getUUID(); - boolean colorSettings = packet.isChatColors(); - - if (Bukkit.getPlayer(uuid) != null) { - Player player = Bukkit.getPlayer(uuid); - - boolean originalColorSettings = PlayerUtils.canChatColor(player); - ClientSettingsHandler.handlePacketReceiving(colorSettings, originalColorSettings, player); - } else { - colorSettingsMap.put(uuid, colorSettings); - } - } - } - - public PEClientSettingsPacket() { - Bukkit.getServer().getPluginManager().registerEvents(this, InteractiveChatPacketEvents.instance); - } - - // Why do we have to do this? - // Since PacketEvents injects directly into Netty, the above method is called BEFORE the server itself actually has time - // to create the CraftPlayer instance. This means that we can't call PlayerUtils.canChatColor as that directly fetches - // the CraftPlayer handle instance of the player, which results in an exception. - // Therefore, we wait for the PlayerJoinEvent which will ensure the CraftPlayer instance has been created. - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - - boolean originalColorSettings = PlayerUtils.canChatColor(player); - ClientSettingsHandler.handlePacketReceiving(colorSettingsMap.getOrDefault(player.getUniqueId(), true), originalColorSettings, player); - - colorSettingsMap.remove(player.getUniqueId()); - } -} diff --git a/src/main/java/net/skullian/listeners/PEOutMessagePacket.java b/src/main/java/net/skullian/listeners/PEOutMessagePacket.java deleted file mode 100644 index 61847bb..0000000 --- a/src/main/java/net/skullian/listeners/PEOutMessagePacket.java +++ /dev/null @@ -1,603 +0,0 @@ -package net.skullian.listeners; - -import com.github.retrooper.packetevents.event.PacketListener; -import com.github.retrooper.packetevents.event.PacketSendEvent; -import com.github.retrooper.packetevents.protocol.chat.ChatType; -import com.github.retrooper.packetevents.protocol.chat.ChatTypes; -import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_3; -import com.github.retrooper.packetevents.protocol.packettype.PacketType; -import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; -import com.github.retrooper.packetevents.wrapper.PacketWrapper; -import com.github.retrooper.packetevents.wrapper.play.server.*; -import com.loohp.interactivechat.InteractiveChat; -import com.loohp.interactivechat.api.events.PostPacketComponentProcessEvent; -import com.loohp.interactivechat.api.events.PreChatPacketSendEvent; -import com.loohp.interactivechat.api.events.PrePacketComponentProcessEvent; -import com.loohp.interactivechat.data.PlayerDataManager; -import com.loohp.interactivechat.hooks.triton.TritonHook; -import com.loohp.interactivechat.libs.net.kyori.adventure.text.Component; -import com.loohp.interactivechat.libs.net.kyori.adventure.text.TextReplacementConfig; -import com.loohp.interactivechat.libs.net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import com.loohp.interactivechat.libs.net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; -import com.loohp.interactivechat.modules.*; -import com.loohp.interactivechat.objectholders.ICPlayer; -import com.loohp.interactivechat.objectholders.ICPlayerFactory; -import com.loohp.interactivechat.objectholders.ProcessSenderResult; -import com.loohp.interactivechat.registry.Registry; -import com.loohp.interactivechat.utils.*; -import net.md_5.bungee.api.ChatColor; -import net.skullian.platform.PacketEventsAsyncChatSendingExecutor; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.*; -import java.util.function.Function; -import java.util.function.Predicate; - -import static com.loohp.interactivechat.listeners.packet.MessagePacketHandler.*; -import static net.skullian.InteractiveChatPacketEvents.sendDebug; - -public class PEOutMessagePacket implements PacketListener { - - private static final Map PACKET_HANDLERS = new HashMap<>(); - - public PEOutMessagePacket() { - initializePacketHandlers(); - SERVICE = new PacketEventsAsyncChatSendingExecutor( - () -> (long) (InteractiveChat.bungeecordMode ? InteractiveChat.remoteDelay : 0) + 2000, - 5000 - ); - } - - private void initializePacketHandlers() { - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19_3)) { - initializeModernPacketHandlers(); - } - initializeCommonPacketHandlers(); - } - - private void initializeModernPacketHandlers() { - PACKET_HANDLERS.put(PacketType.Play.Server.DISGUISED_CHAT, new PacketHandler( - event -> InteractiveChat.chatListener, - packet -> { - net.kyori.adventure.text.Component nativeComponment = ((WrapperPlayServerDisguisedChat) packet).getMessage(); - return new PacketAccessorResult( - nativeComponment != null ? NativeAdventureConverter.componentFromNative(nativeComponment) : Component.empty(), - ChatComponentType.NativeAdventureComponent, - 0, - false - ); - }, - (packet, component, type, field, sender) -> { - sendDebug("Processing DISGUISED_CHAT Packet:" + - "COMPONENT: " + PlainTextComponentSerializer.plainText().serialize(component) + - "SENDER: " + sender); - - boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); - - String json = legacyRGB ? - InteractiveChatComponentSerializer.legacyGson().serialize(component) : - InteractiveChatComponentSerializer.gson().serialize(component); - boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; - - WrapperPlayServerDisguisedChat chatPacket = (WrapperPlayServerDisguisedChat) packet; - chatPacket.setMessage((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); - - sendDebug("PROCESSED DISGUISED_CHAT Packet:" + - "NEW COMPONENT MESSAGE: " + PlainTextComponentSerializer.plainText().serialize(component) + - "SENDER: " + sender + - "LONGER THAN MAX LENGTH: " + longerThanMaxLength); - - return new PacketWriterResult(longerThanMaxLength, json.length(), sender); - } - )); - } - - private void initializeCommonPacketHandlers() { - PacketHandler modernTitleHandler = createModernTitleHandler(); - - PacketHandler chatHandler = new PacketHandler( - event -> { - if (event.getPacketType().equals(PacketType.Play.Server.CHAT_MESSAGE)) { - WrapperPlayServerChatMessage messagePacket = new WrapperPlayServerChatMessage(event); - - ChatType type = messagePacket.getMessage().getType(); - - sendDebug("Handling PacketSendEvent for CHAT_MESSAGE:" + - "TYPE: " + type); - - return type == null || type.equals(ChatTypes.GAME_INFO) ? - InteractiveChat.titleListener : - InteractiveChat.chatListener; - } - - WrapperPlayServerSystemChatMessage messagePacket = new WrapperPlayServerSystemChatMessage(event); - - sendDebug("Handling PacketSendEvent for SYSTEM_CHAT_MESSAGE:" + - "IS OVERLAY: " + messagePacket.isOverlay()); - - return messagePacket.isOverlay() ? - InteractiveChat.titleListener : - InteractiveChat.chatListener; - }, - packet -> { - net.kyori.adventure.text.Component nativeComponent = null; - - if (packet instanceof WrapperPlayServerSystemChatMessage) { - sendDebug("Handling SYSTEM_CHAT_MESSAGE Packet:" + - "MESSAGE: " + net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(((WrapperPlayServerSystemChatMessage) packet).getMessage())); - - nativeComponent = ((WrapperPlayServerSystemChatMessage) packet).getMessage(); - } else if (packet instanceof WrapperPlayServerChatMessage) { - sendDebug("Handling SERVER_CHAT Packet:" + - "MESSAGE: " + net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(((WrapperPlayServerChatMessage) packet).getMessage().getChatContent())); - - nativeComponent = ((WrapperPlayServerChatMessage) packet).getMessage().getChatContent(); - } - - return new PacketAccessorResult(NativeAdventureConverter.componentFromNative(nativeComponent), ChatComponentType.NativeAdventureComponent, 0, false); - }, - (packet, component, type, field, sender) -> { - boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); - - String json = legacyRGB ? - InteractiveChatComponentSerializer.legacyGson().serialize(component) : - InteractiveChatComponentSerializer.gson().serialize(component); - boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; - - try { - if (packet instanceof WrapperPlayServerChatMessage) { - WrapperPlayServerChatMessage chatMessage = (WrapperPlayServerChatMessage) packet; - - sendDebug("Processing SERVER_CHAT Packet:" + - "LEGACY RGB: " + legacyRGB + - "LONGER THAN MAX LENGTH: " + longerThanMaxLength + - "CURRENT MESSAGE: " + net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(chatMessage.getMessage().getChatContent())); - - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19_3)) { - ((ChatMessage_v1_19_3) chatMessage.getMessage()).setUnsignedChatContent((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); - } else { - chatMessage.getMessage().setChatContent((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); - } - - sendDebug("Processed SERVER_CHAT Packet:" + - "NEW COMPONENT: " + PlainTextComponentSerializer.plainText().serialize(component)); - } else { - WrapperPlayServerSystemChatMessage chatMessage = (WrapperPlayServerSystemChatMessage) packet; - - sendDebug("Processing SYSTEM_CHAT_MESSAGE Packet:" + - "LEGACY RGB: " + legacyRGB + - "LONGER THAN MAX LENGTH: " + longerThanMaxLength + - "CURRENT MESSAGE: " + net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(chatMessage.getMessage())); - - chatMessage.setMessage((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); - - sendDebug("Processed SYSTEM_CHAT_MESSAGE Packet:" + - "NEW COMPONENT: " + PlainTextComponentSerializer.plainText().serialize(component)); - } - } catch (Throwable e) { - e.printStackTrace(); - if (packet instanceof WrapperPlayServerChatMessage) { - WrapperPlayServerChatMessage chatMessage = (WrapperPlayServerChatMessage) packet; - - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19_3)) { - ((ChatMessage_v1_19_3) chatMessage.getMessage()) - .setUnsignedChatContent((net.kyori.adventure.text.Component) NativeAdventureConverter.componentToNative(component, legacyRGB)); - } else { - chatMessage.getMessage().setChatContent( - (net.kyori.adventure.text.Component) NativeAdventureConverter.componentToNative(component, legacyRGB) - ); - } - } else { - ((WrapperPlayServerSystemChatMessage) packet).setMessageJson(json); - } - } - - return new PacketWriterResult(longerThanMaxLength, json.length(), sender); - } - ); - - PACKET_HANDLERS.put(PacketType.Play.Server.SYSTEM_CHAT_MESSAGE, chatHandler); - PACKET_HANDLERS.put(PacketType.Play.Server.CHAT_MESSAGE, chatHandler); - - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_17)) { - PACKET_HANDLERS.put(PacketType.Play.Server.SET_TITLE_TEXT, modernTitleHandler); - PACKET_HANDLERS.put(PacketType.Play.Server.SET_TITLE_SUBTITLE, modernTitleHandler); - PACKET_HANDLERS.put(PacketType.Play.Server.ACTION_BAR, modernTitleHandler); - } else { - PACKET_HANDLERS.put( - PacketType.Play.Server.TITLE, - new PacketHandler( - event -> { - WrapperPlayServerTitle.TitleAction action = ((WrapperPlayServerTitle) event.getLastUsedWrapper()).getAction(); - - sendDebug("Processing PacketSendEvent for TITLE:" + - "ACTION: " + action); - - return action != null && !action.equals(WrapperPlayServerTitle.TitleAction.RESET) && - !action.equals(WrapperPlayServerTitle.TitleAction.HIDE) && !action.equals(WrapperPlayServerTitle.TitleAction.SET_TIMES_AND_DISPLAY) && InteractiveChat.titleListener; - }, - packet -> { - net.kyori.adventure.text.Component nativeComponent = ((WrapperPlayServerTitle) packet).getTitle(); - - return new PacketAccessorResult( NativeAdventureConverter.componentFromNative(nativeComponent), ChatComponentType.NativeAdventureComponent, 0, false); - }, - (packet, component, type, field, sender) -> { - boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); - - String json = legacyRGB ? - InteractiveChatComponentSerializer.legacyGson().serialize(component) : - InteractiveChatComponentSerializer.gson().serialize(component); - boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && - json.length() > InteractiveChat.packetStringMaxLength; - - WrapperPlayServerTitle titlePacket = (WrapperPlayServerTitle) packet; - sendDebug("Processing TITLE Packet: " + - "LEGACY RGB: " + legacyRGB + - "LONGER THAN MAX LENGTH: " + longerThanMaxLength + - "CURRENT TITLE: " + net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(titlePacket.getTitle())); - - titlePacket.setTitle((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); - - if (sender == null) sender = UUID_NIL; - - sendDebug("Processed TITLE Packet: " + - "NEW TITLE: " + PlainTextComponentSerializer.plainText().serialize(component)); - - return new PacketWriterResult(longerThanMaxLength, json.length(), sender); - } - ) - ); - } - } - - private PacketHandler createModernTitleHandler() { - return new PacketHandler( - event -> InteractiveChat.titleListener, - packet -> { - net.kyori.adventure.text.Component component = null; - - if (packet instanceof WrapperPlayServerSetTitleText) { - component = ((WrapperPlayServerSetTitleText) packet).getTitle(); - } else if (packet instanceof WrapperPlayServerSetTitleSubtitle) { - component = ((WrapperPlayServerSetTitleSubtitle) packet).getSubtitle(); - } else if (packet instanceof WrapperPlayServerActionBar) { - component = ((WrapperPlayServerActionBar) packet).getActionBarText(); - } - - return new PacketAccessorResult(NativeAdventureConverter.componentFromNative(component), ChatComponentType.NativeAdventureComponent, 0, false); - }, - (packet, component, type, field, sender) -> { - boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); - - String json = legacyRGB ? - InteractiveChatComponentSerializer.legacyGson().serialize(component) : - InteractiveChatComponentSerializer.gson().serialize(component); - boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; - - sendDebug("Handling packet [" + packet + "]:" + - "LEGACY RGB: " + legacyRGB + - "LONGER THAN MAX LENGTH: " + longerThanMaxLength + - "NEW COMPONENT: " + component); - - net.kyori.adventure.text.Component nativeComponent = (net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB); - if (packet instanceof WrapperPlayServerSetTitleText) { - ((WrapperPlayServerSetTitleText) packet).setTitle(nativeComponent); - } else if (packet instanceof WrapperPlayServerSetTitleSubtitle) { - ((WrapperPlayServerSetTitleSubtitle) packet).setSubtitle(nativeComponent); - } else if (packet instanceof WrapperPlayServerActionBar) { - ((WrapperPlayServerActionBar) packet).setActionBarText(nativeComponent); - } - - return new PacketWriterResult(longerThanMaxLength, json.length(), sender); - } - ); - } - - private int getChatFieldsSize() { - return InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_13) ? 262144 : 32767; - } - - public static List test = Arrays.asList( - PacketType.Play.Server.CHAT_MESSAGE, - PacketType.Play.Server.CHAT_PREVIEW_PACKET, - PacketType.Play.Server.SYSTEM_CHAT_MESSAGE, - PacketType.Play.Server.DELETE_CHAT, - PacketType.Play.Server.DISGUISED_CHAT, - PacketType.Play.Server.CUSTOM_CHAT_COMPLETIONS, - PacketType.Play.Server.DISPLAY_CHAT_PREVIEW, - PacketType.Play.Server.PLAYER_CHAT_HEADER - ); - - @Override - public void onPacketSend(PacketSendEvent event) { - System.out.println(event.getPacketType()); - - if (!PACKET_HANDLERS.containsKey(event.getPacketType())) return; - - handlePacketSending(event); - } - - private void handlePacketSending(PacketSendEvent event) { - try { - if (event.isCancelled()) return; - - PacketHandler packetHandler = PACKET_HANDLERS.get(event.getPacketType()); - if (!packetHandler.getPreFilter().test(event)) return; - - InteractiveChat.messagesCounter.getAndIncrement(); - - Player receiver = event.getPlayer(); - - if (!(event.getLastUsedWrapper() instanceof WrapperPlayServerSystemChatMessage)) { - event.setCancelled(true); - } - - event.markForReEncode(true); - UUID messageUUID = UUID.randomUUID(); - ICPlayer determinedSender = ICPlayerFactory.getICPlayer((Player) event.getPlayer()); - - PacketSendEvent originalEvent = event.clone(); - SCHEDULING_SERVICE.execute(() -> { - SERVICE.execute(() -> { - processPacket(receiver, determinedSender, event, messageUUID, false, packetHandler, originalEvent); - }, receiver, messageUUID); - }); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - private static void processPacket(Player receiver, ICPlayer determinedSender, PacketSendEvent event, UUID messageUUID, boolean isFiltered, PacketHandler packetHandler, PacketSendEvent originalEvent) { - PacketWrapper originalWrapper = originalEvent.getLastUsedWrapper(); - PacketWrapper packet = event.getLastUsedWrapper(); - - try { - if (packetHandler.getAccessor() == null) { - SERVICE.send(packet, receiver, messageUUID); - return; - } - - PacketAccessorResult packetAccessorResult = packetHandler.getAccessor().apply(packet); - Component component = packetAccessorResult.getComponent(); - ChatComponentType type = packetAccessorResult.getType(); - - if (type == null || component == null) { - SERVICE.send(packet, receiver, messageUUID); - return; - } - - component = ComponentModernizing.modernize(component); - String legacyText = LegacyComponentSerializer.legacySection().serializeOr(component, ""); - - try { - if (legacyText.isEmpty() || InteractiveChat.messageToIgnore.stream().anyMatch(legacyText::matches)) { - SERVICE.send(packet, receiver, messageUUID); - return; - } - } catch (Exception e) { - SERVICE.send(packet, receiver, messageUUID); - return; - } - - if (InteractiveChat.version.isOld() && JsonUtils.containsKey(InteractiveChatComponentSerializer.gson().serialize(component), "translate")) { - SERVICE.send(packet, receiver, messageUUID); - return; - } - - Optional sender = Optional.ofNullable(determinedSender); - String rawMessageKey = PlainTextComponentSerializer.plainText().serializeOr(component, ""); - InteractiveChat.keyTime.putIfAbsent(rawMessageKey, System.currentTimeMillis()); - Long timeKey = InteractiveChat.keyTime.get(rawMessageKey); - long unix = timeKey == null ? System.currentTimeMillis() : timeKey; - ProcessSenderResult commandSender = ProcessCommands.process(component); - - if (!sender.isPresent()) { - if (commandSender.getSender() != null) { - ICPlayer icPlayer = ICPlayerFactory.getICPlayer(commandSender.getSender()); - if (icPlayer != null) { - sender = Optional.of(icPlayer); - } - } - } - - ProcessSenderResult chatSender = null; - if (!sender.isPresent()) { - if (InteractiveChat.useAccurateSenderFinder) { - chatSender = ProcessAccurateSender.process(component); - if (chatSender.getSender() != null) { - ICPlayer icPlayer = ICPlayerFactory.getICPlayer(chatSender.getSender()); - if (icPlayer != null) { - sender = Optional.of(icPlayer); - } - } - } - } - - if (!sender.isPresent() && !InteractiveChat.useAccurateSenderFinder) { - sender = SenderFinder.getSender(component, rawMessageKey); - } - - if (sender.isPresent() && !sender.get().isLocal()) { - if (isFiltered) { - Bukkit.getScheduler().runTaskLaterAsynchronously(InteractiveChat.plugin, () -> { - SERVICE.execute(() -> { - processPacket(receiver, determinedSender, event, messageUUID, false, packetHandler, originalEvent); - }, receiver, messageUUID); - }, (int) Math.ceil((double) InteractiveChat.remoteDelay / 50) + InteractiveChat.extraProxiedPacketProcessingDelay); - - return; - } - } - - component = commandSender.getComponent(); - if (chatSender != null) { - component = chatSender.getComponent(); - } - - sender.ifPresent(icPlayer -> InteractiveChat.keyPlayer.put(rawMessageKey, icPlayer)); - component = ComponentReplacing.replace(component, Registry.ID_PATTERN.pattern(), Registry.ID_PATTERN_REPLACEMENT); - UUID preEventSenderUUID = sender.map(ICPlayer::getUniqueId).orElse(null); - - PrePacketComponentProcessEvent preEvent = new PrePacketComponentProcessEvent(!Bukkit.isPrimaryThread(), receiver, component, preEventSenderUUID); - Bukkit.getPluginManager().callEvent(preEvent); - - if (preEvent.getSender() != null) { - Player newSender = Bukkit.getPlayer(preEvent.getSender()); - if (newSender != null) { - sender = Optional.of(ICPlayerFactory.getICPlayer(newSender)); - } - } - component = preEvent.getComponent(); - - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_16) && InteractiveChat.fontTags) { - if (!sender.isPresent() || PlayerUtils.hasPermission(sender.get().getUniqueId(), "interactivechat.customfont.translate", true, 250)) { - component = ComponentFont.parseFont(component); - } - } - - if (InteractiveChat.translateHoverableItems && InteractiveChat.itemGUI) { - component = HoverableItemDisplay.process(component, receiver); - } - - if (InteractiveChat.usePlayerName) { - component = PlayernameDisplay.process(component, sender, receiver, unix); - } - - if (InteractiveChat.allowMention && sender.isPresent()) { - PlayerDataManager.PlayerData data = InteractiveChat.playerDataManager.getPlayerData(receiver); - if (data == null || !data.isMentionDisabled()) { - component = MentionDisplay.process(component, receiver, sender.get(), unix, true); - } - } - - component = ComponentReplacing.replace(component, Registry.MENTION_TAG_CONVERTER.getReversePattern().pattern(), true, (result, components) -> { - return LegacyComponentSerializer.legacySection().deserialize(ChatColorUtils.translateAlternateColorCodes('&', InteractiveChat.mentionHighlightOthers)).replaceText(TextReplacementConfig.builder().matchLiteral("{MentionedPlayer}").replacement(PlainTextComponentSerializer.plainText().deserialize(result.group(2))).build()); - }); - component = CustomPlaceholderDisplay.process(component, sender, receiver, InteractiveChat.placeholderList.values(), unix); - - if (InteractiveChat.useInventory) { - component = InventoryDisplay.process(component, sender, receiver, packetAccessorResult.isPreview(), unix); - } - if (InteractiveChat.useEnder) { - component = EnderchestDisplay.process(component, sender, receiver, packetAccessorResult.isPreview(), unix); - } - - if (InteractiveChat.clickableCommands) { - component = CommandsDisplay.process(component); - } - - if (InteractiveChat.useItem) { - component = ItemDisplay.process(component, sender, receiver, packetAccessorResult.isPreview(), unix); - } - - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_16) && InteractiveChat.fontTags) { - if (!sender.isPresent() || (sender.isPresent() && PlayerUtils.hasPermission(sender.get().getUniqueId(), "interactivechat.customfont.translate", true, 250))) { - component = ComponentFont.parseFont(component); - } - } - - if (!PlayerUtils.canChatColor(receiver)) { - component = ComponentStyling.stripColor(component); - } - - if (InteractiveChat.tritonHook) { - component = TritonHook.parseLanguageChat(sender.map(ICPlayer::getUniqueId).orElse(null), component); - } - - PostPacketComponentProcessEvent postEvent = new PostPacketComponentProcessEvent(true, receiver, component, preEventSenderUUID); - Bukkit.getPluginManager().callEvent(postEvent); - component = postEvent.getComponent(); - - PacketWriterResult packetWriterResult = packetHandler.getWriter().apply(packet, component, type, packetAccessorResult.getField(), sender.map(ICPlayer::getUniqueId).orElse(null)); - event.markForReEncode(true); - - boolean longerThanMaxLength = packetWriterResult.isTooLong(); - UUID postEventSenderUUID = packetWriterResult.getSender(); - int jsonLength = packetWriterResult.getJsonLength(); - - PreChatPacketSendEvent sendEvent = new PreChatPacketSendEvent(true, receiver, packet, component, postEventSenderUUID, originalWrapper, InteractiveChat.sendOriginalIfTooLong, longerThanMaxLength); - Bukkit.getPluginManager().callEvent(sendEvent); - - Bukkit.getScheduler().runTaskLater(InteractiveChat.plugin, () -> { - InteractiveChat.keyTime.remove(rawMessageKey); - InteractiveChat.keyPlayer.remove(rawMessageKey); - }, 10); - - if (sendEvent.isCancelled()) { - if (sendEvent.sendOriginalIfCancelled()) { - if (longerThanMaxLength && InteractiveChat.cancelledMessage) { - Bukkit.getConsoleSender().sendMessage(ChatColor.YELLOW + "[InteractiveChat] " + - ChatColor.RED + "Cancelled a chat packet bounded to " + receiver.getName() + - " that is " + jsonLength + " characters long (Longer than maximum allowed in a chat packet), " + - "sending original unmodified message instead! [THIS IS NOT A BUG]"); - } - PacketWrapper originalPacketModified = (PacketWrapper) sendEvent.getOriginal(); - SERVICE.send(originalPacketModified, receiver, messageUUID); - return; - } - - if (longerThanMaxLength && InteractiveChat.cancelledMessage) { - Bukkit.getConsoleSender().sendMessage(ChatColor.YELLOW + "[InteractiveChat] " + - ChatColor.RED + "Cancelled a chat packet bounded to " + receiver.getName() + - " that is " + jsonLength + " characters long (Longer than maximum allowed in a chat packet) " + - "[THIS IS NOT A BUG]"); - } - SERVICE.discard(receiver.getUniqueId(), messageUUID); - return; - } - - SERVICE.send(packet, receiver, messageUUID); - - } catch (Exception e) { - e.printStackTrace(); - SERVICE.send(originalWrapper, receiver, messageUUID); - } - } - - public static class PacketHandler { - private static final Function UNDETERMINED_SENDER = event -> null; - - private final Predicate preFilter; - private final Function determinedSenderFunction; - private final PacketAccessor accessor; - private final PacketWriter writer; - - public PacketHandler(Predicate preFilter, Function determinedSenderFunction, - PacketAccessor accessor, PacketWriter writer) { - this.preFilter = preFilter; - this.determinedSenderFunction = determinedSenderFunction; - this.accessor = accessor; - this.writer = writer; - } - - public PacketHandler(Predicate preFilter, PacketAccessor accessor, PacketWriter writer) { - this(preFilter, UNDETERMINED_SENDER, accessor, writer); - } - - public Predicate getPreFilter() { - return preFilter; - } - - public Function getDeterminedSenderFunction() { - return determinedSenderFunction; - } - - public PacketAccessor getAccessor() { - return accessor; - } - - public PacketWriter getWriter() { - return writer; - } - } - - public interface PacketAccessor extends Function, PacketAccessorResult> { - @Override - PacketAccessorResult apply(PacketWrapper packet); - } - - public interface PacketWriter { - PacketWriterResult apply(PacketWrapper packet, Component component, ChatComponentType type, int field, UUID sender); - } -} diff --git a/src/main/java/net/skullian/listeners/PEOutTabCompletePacket.java b/src/main/java/net/skullian/listeners/PEOutTabCompletePacket.java deleted file mode 100644 index 35f7273..0000000 --- a/src/main/java/net/skullian/listeners/PEOutTabCompletePacket.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.skullian.listeners; - -import com.github.retrooper.packetevents.event.PacketListener; -import com.github.retrooper.packetevents.event.PacketSendEvent; -import com.github.retrooper.packetevents.protocol.packettype.PacketType; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTabComplete; -import com.loohp.interactivechat.InteractiveChat; -import com.loohp.interactivechat.libs.net.kyori.adventure.text.Component; -import com.loohp.interactivechat.objectholders.ICPlayer; -import com.loohp.interactivechat.utils.NativeAdventureConverter; -import org.bukkit.entity.Player; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static com.loohp.interactivechat.listeners.packet.OutTabCompletePacketHandler.createComponent; -import static com.loohp.interactivechat.listeners.packet.OutTabCompletePacketHandler.findICPlayer; -import static net.skullian.InteractiveChatPacketEvents.sendDebug; - -public class PEOutTabCompletePacket implements PacketListener { - - @Override - public void onPacketSend(PacketSendEvent event) { - if (shouldProcessPacket(event)) { - processPacket(event); - } - } - - private static boolean shouldProcessPacket(PacketSendEvent event) { - return !event.isCancelled() && event.getPacketType().equals(PacketType.Play.Server.TAB_COMPLETE); - } - - private static void processPacket(PacketSendEvent event) { - sendDebug("PEOutTabCompletePacket PROCESSING PACKET TYPE: " + event.getPacketType()); - - WrapperPlayServerTabComplete packet = new WrapperPlayServerTabComplete(event); - Player tabCompleter = event.getPlayer(); - - List matches = packet.getCommandMatches(); - List newMatches = new ArrayList<>(); - for (WrapperPlayServerTabComplete.CommandMatch match : matches) { - newMatches.add(processMatch(match, tabCompleter)); - } - - packet.setCommandMatches(matches); - } - - private static WrapperPlayServerTabComplete.CommandMatch processMatch(WrapperPlayServerTabComplete.CommandMatch match, Player tabCompleter) { - String text = match.getText(); - int pos = text.indexOf("\0"); - if (pos < 0) { - sendDebug("PROCESSING TEXT MATCH"); - return processTextMatch(match, tabCompleter); - } else { - sendDebug("PROCESSING TOOLTIP MATCH"); - return processTooltipMatch(match, pos, text); - } - } - - private static WrapperPlayServerTabComplete.CommandMatch processTextMatch(WrapperPlayServerTabComplete.CommandMatch match, Player tabCompleter) { - if (InteractiveChat.useTooltipOnTab) { - try { - ICPlayer icPlayer = findICPlayer(match.getText()); - if (icPlayer != null) { - Component component = createComponent(icPlayer, tabCompleter); - Object nativeComponent = NativeAdventureConverter.componentToNative(component, false); - - sendDebug("NEW COMPONENT: " + component + "\nOLD COMPONENT: " + match.getTooltip()); - - match.setTooltip((net.kyori.adventure.text.Component) nativeComponent); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - return match; - } - - private static WrapperPlayServerTabComplete.CommandMatch processTooltipMatch(WrapperPlayServerTabComplete.CommandMatch match, int pos, String text) { - try { - - sendDebug("MATCH TEXT: " + match.getText() + "\nTEXT: " + text); - - String tooltip = text.substring(pos + 1); - text = text.substring(0, pos); - - match.setText(text); - - sendDebug("NEW MATCH TEXT: " + text); - - - Object nativeComponent = NativeAdventureConverter.componentToNative(Component.text(tooltip), false); - match.setTooltip((net.kyori.adventure.text.Component) nativeComponent); - } catch (Exception e) { - e.printStackTrace(); - } - - return match; - } -} diff --git a/src/main/java/net/skullian/listeners/PERedispatchSignedPacket.java b/src/main/java/net/skullian/listeners/PERedispatchSignedPacket.java deleted file mode 100644 index b20c042..0000000 --- a/src/main/java/net/skullian/listeners/PERedispatchSignedPacket.java +++ /dev/null @@ -1,125 +0,0 @@ -package net.skullian.listeners; - -import com.github.retrooper.packetevents.event.PacketListener; -import com.github.retrooper.packetevents.event.PacketSendEvent; -import com.github.retrooper.packetevents.protocol.chat.ChatTypes; -import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19; -import com.github.retrooper.packetevents.protocol.packettype.PacketType; -import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatMessage; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerServerData; -import com.loohp.interactivechat.InteractiveChat; -import com.loohp.interactivechat.listeners.packet.RedispatchedSignPacketHandler; -import com.loohp.interactivechat.utils.MCVersion; -import com.loohp.interactivechat.utils.ModernChatSigningUtils; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; -import org.bukkit.entity.Player; - -import java.util.Arrays; -import java.util.List; - -import static net.skullian.InteractiveChatPacketEvents.sendDebug; - -public class PERedispatchSignedPacket implements PacketListener { - - private static final List packetTypes = getPacketTypes(); - - @Override - public void onPacketSend(PacketSendEvent event) { - if (event.getPacketType().equals(PacketType.Play.Server.SERVER_DATA)) { - sendDebug("HANDLING SERVER DATA PACKET: " + event.getPacketType()); - - handleServerDataPacket(event); - } else { - if (shouldIgnoreEvent(event)) return; - - if (event.getPacketType().equals(PacketType.Play.Client.CHAT_MESSAGE)) { - sendDebug("HANDLING CHAT MESSAGE PACKET: " + event.getPacketType()); - - handleChatPacket(event); - } else { - sendDebug("HANDLING CHAT COMMAND PACKET: " + event.getPacketType()); - - handleChatCommandPacket(event); - } - - event.markForReEncode(true); - } - } - - private static boolean shouldIgnoreEvent(PacketSendEvent event) { - return event.isCancelled() || !InteractiveChat.protocolPlatform.hasChatSigning() || !packetTypes.contains(event.getPacketType()); - } - - private static List getPacketTypes() { - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_20_5)) { - return Arrays.asList( - PacketType.Play.Client.CHAT_COMMAND, - PacketType.Play.Client.CHAT_COMMAND_UNSIGNED, - PacketType.Play.Client.CHAT_MESSAGE - ); - } else { - return Arrays.asList( - PacketType.Play.Client.CHAT_COMMAND, - PacketType.Play.Client.CHAT_MESSAGE - ); - } - } - - private static void handleChatPacket(PacketSendEvent event) { - if (InteractiveChat.forceUnsignedChatPackets) { - Player player = event.getPlayer(); - WrapperPlayServerChatMessage packet = new WrapperPlayServerChatMessage(event); - - String message = PlainTextComponentSerializer.plainText().serialize(packet.getMessage().getChatContent()); - - sendDebug("PERedispatchSignedPacket HANDLING CHAT MESSAGE: " + message); - - if (message.startsWith("/")) { - redispatchCommand(event, player, message); - } else { - redispatchChatMessage(event, player, message); - } - } - } - - private static void handleChatCommandPacket(PacketSendEvent event) { - Player player = event.getPlayer(); - - if (InteractiveChat.forceUnsignedChatCommandPackets) { - if (event.getPacketType().equals(PacketType.Play.Server.CHAT_MESSAGE)) { - WrapperPlayServerChatMessage message = new WrapperPlayServerChatMessage(event); - if (message.getMessage().getType() != ChatTypes.MSG_COMMAND) return; - - ChatMessage_v1_19 messageV119 = (ChatMessage_v1_19) message.getMessage(); - if (messageV119.getSignature() != null) { - String command = "/" + PlainTextComponentSerializer.plainText().serialize(messageV119.getChatContent()); - redispatchCommand(event, player, command); - } - } - } - } - - private static void redispatchCommand(PacketSendEvent event, Player player, String command) { - event.setCancelled(true); - - RedispatchedSignPacketHandler.redispatchCommand(player, command); - } - - private static void redispatchChatMessage(PacketSendEvent event, Player player, String message) { - if (!ModernChatSigningUtils.isChatMessageIllegal(message)) { - event.setCancelled(true); - - RedispatchedSignPacketHandler.redispatchChatMessage(player, message); - } - } - - private static void handleServerDataPacket(PacketSendEvent event) { - if (event.getPacketType().equals(PacketType.Play.Server.SERVER_DATA)) { - WrapperPlayServerServerData packet = new WrapperPlayServerServerData(event); - - if (InteractiveChat.hideServerUnsignedStatus) packet.setEnforceSecureChat(true); - event.markForReEncode(true); - } - } -} diff --git a/src/main/java/net/skullian/listeners/PEServerPingListener.java b/src/main/java/net/skullian/listeners/PEServerPingListener.java deleted file mode 100644 index b37bfed..0000000 --- a/src/main/java/net/skullian/listeners/PEServerPingListener.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.skullian.listeners; - -import com.github.retrooper.packetevents.event.PacketListener; -import com.github.retrooper.packetevents.event.PacketReceiveEvent; -import com.github.retrooper.packetevents.event.PacketSendEvent; -import com.github.retrooper.packetevents.protocol.packettype.PacketType; -import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake; -import com.github.retrooper.packetevents.wrapper.status.server.WrapperStatusServerResponse; -import com.loohp.interactivechat.registry.Registry; - -import static com.loohp.interactivechat.bungeemessaging.ServerPingListenerUtils.REQUESTS; -import static com.loohp.interactivechat.bungeemessaging.ServerPingListenerUtils.json; - -public class PEServerPingListener implements PacketListener { - - @Override - public void onPacketReceive(PacketReceiveEvent event) { - if (!event.getPacketType().equals(PacketType.Handshaking.Client.HANDSHAKE)) return; - - WrapperHandshakingClientHandshake handshake = new WrapperHandshakingClientHandshake(event); - - String addr = handshake.getServerAddress(); - if (addr != null && addr.equals(Registry.PLUGIN_MESSAGING_PROTOCOL_IDENTIFIER)) { - REQUESTS.put(event.getPlayer(), System.currentTimeMillis() + 5000); - } - } - - @Override - public void onPacketSend(PacketSendEvent event) { - if (!event.getPacketType().equals(PacketType.Status.Server.RESPONSE)) return; - - WrapperStatusServerResponse response = new WrapperStatusServerResponse(event); - if (REQUESTS.remove(event.getPlayer()) != null) { - response.getComponent().addProperty("description", json); - } - - event.setLastUsedWrapper(response); - } - -} diff --git a/src/main/java/net/skullian/platform/PacketEventsAsyncChatSendingExecutor.java b/src/main/java/net/skullian/platform/PacketEventsAsyncChatSendingExecutor.java deleted file mode 100644 index 0bdd83f..0000000 --- a/src/main/java/net/skullian/platform/PacketEventsAsyncChatSendingExecutor.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.skullian.platform; - -import com.github.retrooper.packetevents.PacketEvents; -import com.github.retrooper.packetevents.wrapper.PacketWrapper; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage; -import com.loohp.interactivechat.InteractiveChat; -import com.loohp.interactivechat.libs.com.loohp.platformscheduler.ScheduledTask; -import com.loohp.interactivechat.libs.com.loohp.platformscheduler.Scheduler; -import com.loohp.interactivechat.objectholders.AsyncChatSendingExecutor; -import com.loohp.interactivechat.objectholders.OutboundPacket; -import org.bukkit.Bukkit; - -import java.util.function.LongSupplier; - -public class PacketEventsAsyncChatSendingExecutor extends AsyncChatSendingExecutor { - public PacketEventsAsyncChatSendingExecutor(LongSupplier executionWaitTime, long killThreadAfter) { - super(executionWaitTime, killThreadAfter); - } - - @Override - public ScheduledTask packetSender() { - return Scheduler.runTaskTimer(InteractiveChat.plugin, () -> { - while (!sendingQueue.isEmpty()) { - OutboundPacket out = sendingQueue.poll(); - try { - if (out.getReciever().isOnline() && out.getPacket() != null) { - PacketWrapper wrapper = (PacketWrapper) out.getPacket(); - if (wrapper instanceof WrapperPlayServerSystemChatMessage) return; - - PacketEvents.getAPI().getPlayerManager().sendPacketSilently(out.getReciever(), wrapper); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }, 0, 1); - } -} diff --git a/src/main/java/net/skullian/platform/PacketEventsOutMessagePacketHelper.java b/src/main/java/net/skullian/platform/PacketEventsOutMessagePacketHelper.java new file mode 100644 index 0000000..9f271c4 --- /dev/null +++ b/src/main/java/net/skullian/platform/PacketEventsOutMessagePacketHelper.java @@ -0,0 +1,306 @@ +package net.skullian.platform; + +import com.github.retrooper.packetevents.event.PacketSendEvent; +import com.github.retrooper.packetevents.event.ProtocolPacketEvent; +import com.github.retrooper.packetevents.protocol.chat.ChatTypes; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessageLegacy; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_16; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_1; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_3; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_21_5; +import com.github.retrooper.packetevents.protocol.packettype.PacketType; +import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerActionBar; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatMessage; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatPreview; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisguisedChat; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleSubtitle; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleText; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage; +import com.loohp.interactivechat.InteractiveChat; +import com.loohp.interactivechat.libs.net.kyori.adventure.text.Component; +import com.loohp.interactivechat.listeners.packet.MessagePacketHandler; +import com.loohp.interactivechat.objectholders.ICPlayerFactory; +import com.loohp.interactivechat.utils.ChatComponentType; +import com.loohp.interactivechat.utils.ComponentStyling; +import com.loohp.interactivechat.utils.InteractiveChatComponentSerializer; +import com.loohp.interactivechat.utils.MCVersion; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.UnaryOperator; + +import static com.loohp.interactivechat.listeners.packet.MessagePacketHandler.*; + +@SuppressWarnings("deprecation") +public class PacketEventsOutMessagePacketHelper { + protected static final Map> PACKET_HANDLERS = new HashMap<>(); + + static { + initializeMessagePacketHandlers(); + } + + private static void initializeMessagePacketHandlers() { + PACKET_HANDLERS.put(PacketType.Play.Server.DISGUISED_CHAT, new PacketEventsHandler<>(event -> { + return InteractiveChat.chatListener; + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + Component component = type.convertFrom(packet.getMessage(), player); + return new PacketAccessorResult(component, type, 0, false); + }, (packet, component, type, field, sender) -> { + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + + packet.setMessage((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerDisguisedChat::new, p -> new WrapperPlayServerDisguisedChat(p.getMessage(), p.getChatFormatting()))); + + PACKET_HANDLERS.put(PacketType.Play.Server.CHAT_MESSAGE, new PacketEventsHandler<>(event -> { + if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19_3)) { + return InteractiveChat.chatListener; + } + WrapperPlayServerChatMessage packet = (WrapperPlayServerChatMessage) event.getLastUsedWrapper(); + if (packet.getMessage().getType().equals(ChatTypes.GAME_INFO)) { + return InteractiveChat.titleListener; + } else { + return InteractiveChat.chatListener; + } + }, event -> { + WrapperPlayServerChatMessage packet = (WrapperPlayServerChatMessage) event.getLastUsedWrapper(); + ChatMessage chatMessage = packet.getMessage(); + if (chatMessage instanceof ChatMessage_v1_16) { + UUID uuid = ((ChatMessage_v1_16) chatMessage).getSenderUUID(); + if (uuid != null) { + return ICPlayerFactory.getICPlayer(uuid); + } + } + return null; + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + ChatMessage chatMessage = packet.getMessage(); + Component component; + if (chatMessage instanceof ChatMessage_v1_21_5) { + net.kyori.adventure.text.Component unsignedContent = ((ChatMessage_v1_21_5) chatMessage).getUnsignedChatContent().orElse(null); + if (unsignedContent == null) { + component = type.convertFrom(chatMessage.getChatContent(), player); + } else { + component = type.convertFrom(unsignedContent, player); + } + } else if (chatMessage instanceof ChatMessage_v1_19_3) { + net.kyori.adventure.text.Component unsignedContent = ((ChatMessage_v1_19_3) chatMessage).getUnsignedChatContent().orElse(null); + if (unsignedContent == null) { + component = type.convertFrom(chatMessage.getChatContent(), player); + } else { + component = type.convertFrom(unsignedContent, player); + } + } else if (chatMessage instanceof ChatMessage_v1_19_1) { + net.kyori.adventure.text.Component unsignedContent = ((ChatMessage_v1_19_1) chatMessage).getUnsignedChatContent(); + if (unsignedContent == null) { + component = type.convertFrom(chatMessage.getChatContent(), player); + } else { + component = type.convertFrom(unsignedContent, player); + } + } else if (chatMessage instanceof ChatMessage_v1_19) { + net.kyori.adventure.text.Component unsignedContent = ((ChatMessage_v1_19) chatMessage).getUnsignedChatContent(); + if (unsignedContent == null) { + component = type.convertFrom(chatMessage.getChatContent(), player); + } else { + component = type.convertFrom(unsignedContent, player); + } + } else { + component = type.convertFrom(chatMessage.getChatContent(), player); + } + return new PacketAccessorResult(component, type, 0, false); + }, (packet, component, type, field, sender) -> { + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + ChatMessage chatMessage = packet.getMessage(); + if (chatMessage instanceof ChatMessage_v1_16) { + if (sender != null) { + ((ChatMessage_v1_16) chatMessage).setSenderUUID(sender); + } + } + net.kyori.adventure.text.Component bukkitComponent = (net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB); + if (chatMessage instanceof ChatMessage_v1_21_5) { + ((ChatMessage_v1_21_5) chatMessage).setUnsignedChatContent(bukkitComponent); + } else if (chatMessage instanceof ChatMessage_v1_19_3) { + ((ChatMessage_v1_19_3) chatMessage).setUnsignedChatContent(bukkitComponent); + } else if (chatMessage instanceof ChatMessage_v1_19_1) { + ((ChatMessage_v1_19_1) chatMessage).setUnsignedChatContent(bukkitComponent); + } else if (chatMessage instanceof ChatMessage_v1_19) { + ((ChatMessage_v1_19) chatMessage).setUnsignedChatContent(bukkitComponent); + } else { + chatMessage.setChatContent(bukkitComponent); + } + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerChatMessage::new, p -> { + ChatMessage chatMessage = p.getMessage(); + ChatMessage clonedChatMessage; + if (chatMessage instanceof ChatMessage_v1_21_5) { + ChatMessage_v1_21_5 c = (ChatMessage_v1_21_5) chatMessage; + clonedChatMessage = new ChatMessage_v1_21_5(c.getGlobalIndex(), c.getSenderUUID(), c.getIndex(), Arrays.copyOf(c.getSignature(), c.getSignature().length), c.getPlainContent(), c.getTimestamp(), c.getSalt(), c.getLastSeenMessagesPacked(), c.getChatContent(), c.getFilterMask(), c.getChatFormatting()); + } else if (chatMessage instanceof ChatMessage_v1_19_3) { + ChatMessage_v1_19_3 c = (ChatMessage_v1_19_3) chatMessage; + clonedChatMessage = new ChatMessage_v1_19_3(c.getSenderUUID(), c.getIndex(), Arrays.copyOf(c.getSignature(), c.getSignature().length), c.getPlainContent(), c.getTimestamp(), c.getSalt(), c.getLastSeenMessagesPacked(), c.getChatContent(), c.getFilterMask(), c.getChatFormatting()); + } else if (chatMessage instanceof ChatMessage_v1_19_1) { + ChatMessage_v1_19_1 c = (ChatMessage_v1_19_1) chatMessage; + clonedChatMessage = new ChatMessage_v1_19_1(c.getPlainContent(), c.getChatContent(), c.getUnsignedChatContent(), c.getSenderUUID(), c.getChatFormatting(), Arrays.copyOf(c.getPreviousSignature(), c.getPreviousSignature().length), Arrays.copyOf(c.getSignature(), c.getSignature().length), c.getTimestamp(), c.getSalt(), c.getLastSeenMessages(), c.getFilterMask()); + } else if (chatMessage instanceof ChatMessage_v1_19) { + ChatMessage_v1_19 c = (ChatMessage_v1_19) chatMessage; + clonedChatMessage = new ChatMessage_v1_19(c.getChatContent(), c.getUnsignedChatContent(), c.getType(), c.getSenderUUID(), c.getSenderDisplayName(), c.getTeamName(), c.getTimestamp(), c.getSalt(), Arrays.copyOf(c.getSignature(), c.getSignature().length)); + } else if (chatMessage instanceof ChatMessage_v1_16) { + ChatMessage_v1_16 c = (ChatMessage_v1_16) chatMessage; + clonedChatMessage = new ChatMessage_v1_16(c.getChatContent(), c.getType(), c.getSenderUUID()); + } else { + clonedChatMessage = new ChatMessageLegacy(chatMessage.getChatContent(), chatMessage.getType()); + } + return new WrapperPlayServerChatMessage(clonedChatMessage); + })); + + PACKET_HANDLERS.put(PacketType.Play.Server.CHAT_PREVIEW_PACKET, new PacketEventsHandler<>(event -> { + return InteractiveChat.chatListener; + }, event -> { + return ICPlayerFactory.getICPlayer((Player) event.getPlayer()); + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + Component component = type.convertFrom(packet.getMessage().orElse(net.kyori.adventure.text.Component.empty()), player); + return new PacketAccessorResult(component, type, 0, true); + }, (packet, component, type, field, sender) -> { + if (InteractiveChat.chatPreviewRemoveClickAndHover) { + component = ComponentStyling.stripEvents(component); + } + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + packet.setMessage((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); + if (sender == null) { + sender = UUID_NIL; + } + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerChatPreview::new, p -> new WrapperPlayServerChatPreview(p.getQueryId(), p.getMessage().orElse(null)))); + + + PACKET_HANDLERS.put(PacketType.Play.Server.SYSTEM_CHAT_MESSAGE, new PacketEventsHandler<>(event -> { + return InteractiveChat.chatListener; + }, event -> { + return ICPlayerFactory.getICPlayer((Player) event.getPlayer()); + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + Component component = type.convertFrom(packet.getMessage(), player); + return new PacketAccessorResult(component, type, 0, true); + }, (packet, component, type, field, sender) -> { + if (InteractiveChat.chatPreviewRemoveClickAndHover) { + component = ComponentStyling.stripEvents(component); + } + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + packet.setMessage((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); + if (sender == null) { + sender = UUID_NIL; + } + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerSystemChatMessage::new, p -> { + if (p.getType() == null) { + return new WrapperPlayServerSystemChatMessage(p.isOverlay(), p.getMessage()); + } else { + return new WrapperPlayServerSystemChatMessage(p.getType(), p.getMessage()); + } + })); + + PACKET_HANDLERS.put(PacketType.Play.Server.SET_TITLE_TEXT, new PacketEventsHandler<>(event -> { + return InteractiveChat.titleListener; + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + Component component = type.convertFrom(packet.getTitle(), player); + return new PacketAccessorResult(component, type, 0, false); + }, (packet, component, type, field, sender) -> { + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + packet.setTitle((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); + if (sender == null) { + sender = UUID_NIL; + } + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerSetTitleText::new, p -> new WrapperPlayServerSetTitleText(p.getTitle()))); + + PACKET_HANDLERS.put(PacketType.Play.Server.SET_TITLE_SUBTITLE, new PacketEventsHandler<>(event -> { + return InteractiveChat.titleListener; + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + Component component = type.convertFrom(packet.getSubtitle(), player); + return new PacketAccessorResult(component, type, 0, false); + }, (packet, component, type, field, sender) -> { + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + packet.setSubtitle((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); + if (sender == null) { + sender = UUID_NIL; + } + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerSetTitleSubtitle::new, p -> new WrapperPlayServerSetTitleSubtitle(p.getSubtitle()))); + + PACKET_HANDLERS.put(PacketType.Play.Server.ACTION_BAR, new PacketEventsHandler<>(event -> { + return InteractiveChat.titleListener; + }, (packet, player) -> { + ChatComponentType type = ChatComponentType.NativeAdventureComponent; + Component component = type.convertFrom(packet.getActionBarText(), player); + return new PacketAccessorResult(component, type, 0, false); + }, (packet, component, type, field, sender) -> { + boolean legacyRGB = InteractiveChat.version.isLegacyRGB(); + String json = legacyRGB ? InteractiveChatComponentSerializer.legacyGson().serialize(component) : InteractiveChatComponentSerializer.gson().serialize(component); + boolean longerThanMaxLength = InteractiveChat.sendOriginalIfTooLong && json.length() > InteractiveChat.packetStringMaxLength; + packet.setActionBarText((net.kyori.adventure.text.Component) type.convertTo(component, legacyRGB)); + if (sender == null) { + sender = UUID_NIL; + } + return new PacketWriterResult(longerThanMaxLength, json.length(), sender); + }, WrapperPlayServerActionBar::new, p -> new WrapperPlayServerActionBar(p.getActionBarText()))); + } + + public static class PacketEventsHandler> { + + private final MessagePacketHandler> handler; + private final Function wrapper; + private final UnaryOperator> cloner; + + @SuppressWarnings("unchecked") + public PacketEventsHandler(PreFilter preFilter, PacketAccessor accessor, PacketWriter writer, Function wrapper, UnaryOperator cloner) { + this.handler = new MessagePacketHandler<>(preFilter, (PacketAccessor>) accessor, (PacketWriter>) writer); + this.wrapper = wrapper; + this.cloner = p -> cloner.apply((PacketTyped) p); + } + + @SuppressWarnings("unchecked") + public PacketEventsHandler(PreFilter preFilter, DeterminedSenderFinder determinedSenderFunction, PacketAccessor accessor, PacketWriter writer, Function wrapper, UnaryOperator cloner) { + this.handler = new MessagePacketHandler<>(preFilter, determinedSenderFunction, (PacketAccessor>) accessor, (PacketWriter>) writer); + this.wrapper = wrapper; + this.cloner = p -> cloner.apply((PacketTyped) p); + } + + public MessagePacketHandler> getHandler() { + return handler; + } + + public Function getWrapper() { + return wrapper; + } + + public UnaryOperator> getCloner() { + return cloner; + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/skullian/platform/PacketEventsPacketCreatorProvider.java b/src/main/java/net/skullian/platform/PacketEventsPacketCreatorProvider.java new file mode 100644 index 0000000..19a391c --- /dev/null +++ b/src/main/java/net/skullian/platform/PacketEventsPacketCreatorProvider.java @@ -0,0 +1,73 @@ +package net.skullian.platform; + +import com.github.retrooper.packetevents.protocol.chat.ChatCompletionAction; +import com.github.retrooper.packetevents.protocol.chat.ChatTypes; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessageLegacy; +import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_16; +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatMessage; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCustomChatCompletions; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTabComplete; +import com.loohp.interactivechat.InteractiveChat; +import com.loohp.interactivechat.libs.net.kyori.adventure.text.Component; +import com.loohp.interactivechat.objectholders.CustomTabCompletionAction; +import com.loohp.interactivechat.platform.PlatformPacketCreatorProvider; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerCustomChatCompletionPacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerSystemChatPacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerTabCompletePacket; +import com.loohp.interactivechat.utils.ChatComponentType; +import com.loohp.interactivechat.utils.MCVersion; +import com.mojang.brigadier.suggestion.Suggestions; +import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer; +import net.skullian.platform.packets.PacketEventsPlayServerCustomChatCompletionPacket; +import net.skullian.platform.packets.PacketEventsPlayServerSystemChatPacket; +import net.skullian.platform.packets.PacketEventsPlayServerTabCompletePacket; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public class PacketEventsPacketCreatorProvider implements PlatformPacketCreatorProvider> { + + @Override + public PlatformPlayServerTabCompletePacket> createPlayServerTabCompletePacket(int id, Object suggestions) { + Suggestions mojangSuggestions = (Suggestions) suggestions; + WrapperPlayServerTabComplete.CommandRange commandRange = new WrapperPlayServerTabComplete.CommandRange(mojangSuggestions.getRange().getStart(), mojangSuggestions.getRange().getEnd()); + + List commandMatches = mojangSuggestions.getList().stream() + .map((m) -> new WrapperPlayServerTabComplete.CommandMatch(m.getText(), m.getTooltip() == null ? null : BukkitComponentSerializer.gson().deserialize(ChatComponentType.IChatBaseComponent.toJsonString(m.getTooltip(), null)))).collect(Collectors.toList()); + + return new PacketEventsPlayServerTabCompletePacket(new WrapperPlayServerTabComplete(id, commandRange, commandMatches)); + } + + @Override + public PlatformPlayServerCustomChatCompletionPacket> createPlayServerCustomChatCompletionPacket(CustomTabCompletionAction action, List list) { + ChatCompletionAction packetEventsAction = ChatCompletionAction.valueOf(action.name()); + + return new PacketEventsPlayServerCustomChatCompletionPacket(new WrapperPlayServerCustomChatCompletions(packetEventsAction, list)); + } + + @SuppressWarnings("deprecation") + @Override + public PlatformPlayServerSystemChatPacket> createPlayServerSystemChatPacket(UUID uuid, Component component) { + String json = ChatComponentType.AdventureComponent.toJsonString(component, null); + + if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19)) { + return new PacketEventsPlayServerSystemChatPacket(new WrapperPlayServerSystemChatMessage(false, json)); + } else { + net.kyori.adventure.text.@NotNull Component nativeComponent = BukkitComponentSerializer.gson().deserialize(json); + ChatMessage message; + + if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_16)) { + message = new ChatMessage_v1_16(nativeComponent, ChatTypes.SYSTEM, uuid); + } else { + message = new ChatMessageLegacy(nativeComponent, ChatTypes.SYSTEM); + } + + return new PacketEventsPlayServerSystemChatPacket(new WrapperPlayServerChatMessage(message)); + } + } +} diff --git a/src/main/java/net/skullian/platform/PacketEventsPacketEvent.java b/src/main/java/net/skullian/platform/PacketEventsPacketEvent.java new file mode 100644 index 0000000..ceaabc7 --- /dev/null +++ b/src/main/java/net/skullian/platform/PacketEventsPacketEvent.java @@ -0,0 +1,80 @@ +package net.skullian.platform; + +import com.github.retrooper.packetevents.event.ProtocolPacketEvent; +import com.github.retrooper.packetevents.protocol.ConnectionState; +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.loohp.interactivechat.platform.PlatformPacketEvent; +import com.loohp.interactivechat.platform.packets.PlatformPacket; +import org.bukkit.entity.Player; + +import java.nio.charset.StandardCharsets; +import java.util.UUID; +import java.util.function.Function; + +public class PacketEventsPacketEvent>> implements PlatformPacketEvent, PlatformPacketTyped> { + + private final ProtocolPacketEvent handle; + private final PlatformPacketTyped packetTyped; + + public PacketEventsPacketEvent(ProtocolPacketEvent handle, Function converter) { + this.handle = handle; + this.packetTyped = converter.apply(handle); + } + + @Override + public ProtocolPacketEvent getHandle() { + return handle; + } + + @Override + public PlatformPacketTyped getPacket() { + return packetTyped; + } + + @Override + public Player getPlayer() { + return handle.getPlayer(); + } + + @Override + public boolean isPlayerTemporary() { + ConnectionState state = handle.getConnectionState(); + return state == ConnectionState.HANDSHAKING || state == ConnectionState.STATUS; + } + + @Override + public UUID getPlayerUniqueId() { + return handle.getUser().getUUID(); + } + + @Override + public Object getIdentityObject() { + return handle.getAddress(); + } + + @Override + public boolean isCancelled() { + return handle.isCancelled(); + } + + @Override + public void setCancelled(boolean cancelled) { + handle.setCancelled(cancelled); + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public void setReadOnly(boolean readOnly) { + //do nothing + } + + @Override + public boolean isFiltered() { + return true; + } + +} diff --git a/src/main/java/net/skullian/platform/PacketEventsPacketListenerProvider.java b/src/main/java/net/skullian/platform/PacketEventsPacketListenerProvider.java new file mode 100644 index 0000000..0eb729b --- /dev/null +++ b/src/main/java/net/skullian/platform/PacketEventsPacketListenerProvider.java @@ -0,0 +1,192 @@ +package net.skullian.platform; + +import com.github.retrooper.packetevents.event.PacketListener; +import com.github.retrooper.packetevents.event.PacketListenerPriority; +import com.github.retrooper.packetevents.event.PacketReceiveEvent; +import com.github.retrooper.packetevents.event.PacketSendEvent; +import com.github.retrooper.packetevents.event.ProtocolPacketEvent; +import com.github.retrooper.packetevents.protocol.packettype.PacketType; +import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientSettings; +import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatCommand; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatCommandUnsigned; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatMessage; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientSettings; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerServerData; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTabComplete; +import com.github.retrooper.packetevents.wrapper.status.server.WrapperStatusServerResponse; +import com.loohp.interactivechat.platform.PlatformPacketEventListener; +import com.loohp.interactivechat.platform.PlatformPacketListenerPriority; +import com.loohp.interactivechat.platform.PlatformPacketListenerProvider; +import com.loohp.interactivechat.platform.packets.PlatformConfigurationClientClientInformationPacket; +import com.loohp.interactivechat.platform.packets.PlatformHandshakeClientSetProtocolPacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayClientChatCommandPacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayClientChatPacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerServerDataPacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerTabCompletePacket; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerUnifiedChatMessagePacket; +import com.loohp.interactivechat.platform.packets.PlatformStatusServerServerInfoPacket; +import net.skullian.platform.packets.PacketEventsConfigurationClientClientInformationPacket; +import net.skullian.platform.packets.PacketEventsHandshakeClientSetProtocolPacket; +import net.skullian.platform.packets.PacketEventsPlayClientChatCommandPacket; +import net.skullian.platform.packets.PacketEventsPlayClientChatPacket; +import net.skullian.platform.packets.PacketEventsPlayServerServerDataPacket; +import net.skullian.platform.packets.PacketEventsPlayServerTabCompletePacket; +import net.skullian.platform.packets.PacketEventsPlayServerUnifiedChatMessagePacket; +import net.skullian.platform.packets.PacketEventsStatusServerServerInfoPacket; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +public class PacketEventsPacketListenerProvider implements PlatformPacketListenerProvider> { + + private static PacketListenerPriority c(PlatformPacketListenerPriority priority) { + return PacketListenerPriority.valueOf(priority.name()); + } + + private final PacketEventsPlatform platform; + + public PacketEventsPacketListenerProvider(PacketEventsPlatform platform) { + this.platform = platform; + } + + @Override + public void listenToHandshakeClientSetProtocol(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformHandshakeClientSetProtocolPacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketReceive(@NotNull PacketReceiveEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Handshaking.Client.HANDSHAKE) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperHandshakingClientHandshake wrapper = new WrapperHandshakingClientHandshake((PacketReceiveEvent) e); + return new PacketEventsHandshakeClientSetProtocolPacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToStatusServerServerInfo(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformStatusServerServerInfoPacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketSend(@NotNull PacketSendEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Status.Server.RESPONSE) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperStatusServerResponse wrapper = new WrapperStatusServerResponse((PacketSendEvent) e); + return new PacketEventsStatusServerServerInfoPacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToConfigurationClientClientInformation(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformConfigurationClientClientInformationPacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketReceive(@NotNull PacketReceiveEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Configuration.Client.CLIENT_SETTINGS) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperConfigClientSettings wrapper = new WrapperConfigClientSettings((PacketReceiveEvent) e); + return new PacketEventsConfigurationClientClientInformationPacket(wrapper); + })); + } else if (type == PacketType.Play.Client.CLIENT_SETTINGS) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperPlayClientSettings wrapper = new WrapperPlayClientSettings((PacketReceiveEvent) e); + return new PacketEventsConfigurationClientClientInformationPacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToPlayServerTabComplete(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformPlayServerTabCompletePacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketSend(@NotNull PacketSendEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Play.Server.TAB_COMPLETE) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperPlayServerTabComplete wrapper = new WrapperPlayServerTabComplete((PacketSendEvent) e); + return new PacketEventsPlayServerTabCompletePacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToPlayClientChat(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformPlayClientChatPacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketReceive(@NotNull PacketReceiveEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Play.Client.CHAT_MESSAGE) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperPlayClientChatMessage wrapper = new WrapperPlayClientChatMessage((PacketReceiveEvent) e); + return new PacketEventsPlayClientChatPacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToPlayChatCommand(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformPlayClientChatCommandPacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketReceive(@NotNull PacketReceiveEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Play.Client.CHAT_COMMAND) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperPlayClientChatCommand wrapper = new WrapperPlayClientChatCommand((PacketReceiveEvent) e); + return new PacketEventsPlayClientChatCommandPacket(wrapper); + })); + } else if (type == PacketType.Play.Client.CHAT_COMMAND_UNSIGNED) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperPlayClientChatCommandUnsigned wrapper = new WrapperPlayClientChatCommandUnsigned((PacketReceiveEvent) e); + return new PacketEventsPlayClientChatCommandPacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToPlayServerServerData(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformPlayServerServerDataPacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketSend(@NotNull PacketSendEvent event) { + PacketTypeCommon type = event.getPacketType(); + if (type == PacketType.Play.Server.SERVER_DATA) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + WrapperPlayServerServerData wrapper = new WrapperPlayServerServerData((PacketSendEvent) e); + return new PacketEventsPlayServerServerDataPacket(wrapper); + })); + } + } + }, c(priority)); + } + + @Override + public void listenToPlayServerUnifiedChatMessage(Plugin plugin, PlatformPacketListenerPriority priority, PlatformPacketEventListener, PlatformPlayServerUnifiedChatMessagePacket>> listener) { + platform.getPacketEventsAPI().getEventManager().registerListener(new PacketListener() { + @Override + public void onPacketSend(@NotNull PacketSendEvent event) { + PacketTypeCommon type = event.getPacketType(); + PacketEventsOutMessagePacketHelper.PacketEventsHandler handler = PacketEventsOutMessagePacketHelper.PACKET_HANDLERS.get(type); + if (handler != null) { + listener.handle(new PacketEventsPacketEvent<>(event, e -> { + PacketWrapper wrapper = handler.getWrapper().apply((PacketSendEvent) e); + return new PacketEventsPlayServerUnifiedChatMessagePacket(wrapper, handler.getHandler(), handler.getCloner()); + })); + } + } + }, c(priority)); + } +} diff --git a/src/main/java/net/skullian/platform/PacketEventsPlatform.java b/src/main/java/net/skullian/platform/PacketEventsPlatform.java index 433e7fb..436813a 100644 --- a/src/main/java/net/skullian/platform/PacketEventsPlatform.java +++ b/src/main/java/net/skullian/platform/PacketEventsPlatform.java @@ -1,121 +1,76 @@ package net.skullian.platform; import com.github.retrooper.packetevents.PacketEvents; -import com.github.retrooper.packetevents.event.PacketListenerPriority; -import com.github.retrooper.packetevents.protocol.chat.ChatCompletionAction; -import com.github.retrooper.packetevents.protocol.chat.ChatTypes; -import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage; -import com.github.retrooper.packetevents.protocol.chat.message.ChatMessageLegacy; -import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_16; +import com.github.retrooper.packetevents.PacketEventsAPI; +import com.github.retrooper.packetevents.event.ProtocolPacketEvent; +import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.wrapper.PacketWrapper; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatMessage; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCustomChatCompletions; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTabComplete; -import com.loohp.interactivechat.InteractiveChat; -import com.loohp.interactivechat.libs.net.kyori.adventure.text.Component; -import com.loohp.interactivechat.objectholders.CustomTabCompletionAction; import com.loohp.interactivechat.platform.ProtocolPlatform; -import com.loohp.interactivechat.utils.InteractiveChatComponentSerializer; -import com.loohp.interactivechat.utils.MCVersion; -import com.loohp.interactivechat.utils.NativeAdventureConverter; -import net.md_5.bungee.chat.ComponentSerializer; +import com.loohp.interactivechat.platform.packets.PlatformPacket; import net.skullian.InteractiveChatPacketEvents; -import net.skullian.listeners.*; import net.skullian.player.PacketEventsDummyPlayer; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; -import static com.loohp.interactivechat.InteractiveChat.version; -import static net.skullian.InteractiveChatPacketEvents.instance; +public class PacketEventsPlatform implements ProtocolPlatform> { -public class PacketEventsPlatform implements ProtocolPlatform { + private final PacketEventsPacketListenerProvider listenerProvider; + private final PacketEventsPacketCreatorProvider creatorProvider; - @Override - public void initialize() { - PacketEvents.getAPI().getEventManager().registerListener(new PEOutMessagePacket(), PacketListenerPriority.valueOf(instance.getConfig().getString("ChatListenerPriority"))); - PacketEvents.getAPI().getEventManager().registerListener(new PEClientSettingsPacket(), PacketListenerPriority.valueOf(instance.getConfig().getString("ClientSettingsPriority"))); - - if (version.isNewerOrEqualTo(MCVersion.V1_19)) { - PacketEvents.getAPI().getEventManager().registerListener(new PERedispatchSignedPacket(), PacketListenerPriority.valueOf(instance.getConfig().getString("SignedPacketPriority"))); - } + public PacketEventsPlatform() { + this.listenerProvider = new PacketEventsPacketListenerProvider(this); + this.creatorProvider = new PacketEventsPacketCreatorProvider(); + } - if (!version.isLegacy()) { - PacketEvents.getAPI().getEventManager().registerListener(new PEOutTabCompletePacket(), PacketListenerPriority.valueOf(instance.getConfig().getString("LegacyCommandPacketPriority"))); - } + public PacketEventsAPI getPacketEventsAPI() { + return PacketEvents.getAPI(); } @Override - public void onBungeecordModeEnabled() { - PacketEvents.getAPI().getEventManager().registerListener(new PEServerPingListener(), PacketListenerPriority.valueOf(instance.getConfig().getString("BungeecordPingPriority"))); + public boolean hasChatSigning() { + return getPacketEventsAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_19_1); } @Override - public void sendTabCompletionPacket(Player player, CustomTabCompletionAction action, List list) { - try { - WrapperPlayServerCustomChatCompletions packet = new WrapperPlayServerCustomChatCompletions( - ChatCompletionAction.ADD, - list - ); - PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet); - } catch (Exception e) { - e.printStackTrace(); - } + public int getProtocolVersion(Player player) { + return getPacketEventsAPI().getProtocolManager().getClientVersion(player).getProtocolVersion(); } @Override - public void sendUnprocessedChatMessage(CommandSender sender, UUID uuid, Component component) { - try { - if (sender instanceof Player) { - net.kyori.adventure.text.Component nativeComponent = (net.kyori.adventure.text.Component) NativeAdventureConverter.componentToNative(component, false); - - PacketWrapper packet; - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19)) { - packet = new WrapperPlayServerSystemChatMessage(false, nativeComponent); - } else { - ChatMessage message; - if (InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_16)) { - message = new ChatMessage_v1_16(nativeComponent, ChatTypes.SYSTEM, uuid); - } else { - message = new ChatMessageLegacy(nativeComponent, ChatTypes.SYSTEM); - } - - packet = new WrapperPlayServerChatMessage(message); - } - - PacketEvents.getAPI().getPlayerManager().sendPacketSilently(sender, packet); - } else { - String json = InteractiveChatComponentSerializer.gson().serialize(component); - sender.spigot().sendMessage(ComponentSerializer.parse(json)); - } - } catch (Exception e) { - e.printStackTrace(); - } + public Player newTemporaryPlayer(String name, UUID uuid) { + return PacketEventsDummyPlayer.newInstance(name, uuid); } @Override - public boolean hasChatSigning() { - return InteractiveChat.version.isNewerOrEqualTo(MCVersion.V1_19); + public void sendServerPacket(Player player, PlatformPacket platformPacket, boolean filtered) { + PacketWrapper packet = (PacketWrapper) platformPacket.shallowClone().getHandle(); + if (filtered) { + getPacketEventsAPI().getPlayerManager().sendPacket(player, packet); + } else { + getPacketEventsAPI().getPlayerManager().sendPacketSilently(player, packet); + } } @Override - public int getProtocolVersion(Player player) { - return PacketEvents.getAPI().getProtocolManager().getClientVersion(player).getProtocolVersion(); + public PacketEventsPacketListenerProvider getPlatformPacketListenerProvider() { + return listenerProvider; } @Override - public Player newTemporaryPlayer(String s, UUID uuid) { - return PacketEventsDummyPlayer.newInstance(s, uuid); + public PacketEventsPacketCreatorProvider getPlatformPacketCreatorProvider() { + return creatorProvider; } @Override public Plugin getRegisteredPlugin() { return InteractiveChatPacketEvents.instance; } + + @Override + public Plugin getProtocolPlatformPlugin() { + return (Plugin) getPacketEventsAPI().getPlugin(); + } } diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsConfigurationClientClientInformationPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsConfigurationClientClientInformationPacket.java new file mode 100644 index 0000000..83f9f91 --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsConfigurationClientClientInformationPacket.java @@ -0,0 +1,34 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientSettings; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientSettings; +import com.loohp.interactivechat.platform.packets.PlatformConfigurationClientClientInformationPacket; + +public class PacketEventsConfigurationClientClientInformationPacket extends PlatformConfigurationClientClientInformationPacket> { + + public PacketEventsConfigurationClientClientInformationPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsConfigurationClientClientInformationPacket shallowClone() { + if (handle instanceof WrapperConfigClientSettings) { + WrapperConfigClientSettings settings = (WrapperConfigClientSettings) handle; + return new PacketEventsConfigurationClientClientInformationPacket(new WrapperConfigClientSettings(settings.getLocale(), settings.getViewDistance(), settings.getChatVisibility(), settings.isChatColors(),settings.getSkinMask(), settings.getMainHand(), settings.isTextFilteringEnabled(), settings.isServerListingAllowed(), settings.getParticleStatus())); + } else { + WrapperPlayClientSettings settings = (WrapperPlayClientSettings) handle; + return new PacketEventsConfigurationClientClientInformationPacket(new WrapperPlayClientSettings(settings.getLocale(), settings.getViewDistance(), settings.getChatVisibility(), settings.isChatColors(),settings.getSkinMask(), settings.getMainHand(), settings.isTextFilteringEnabled(), settings.isServerListingAllowed(), settings.getParticleStatus())); + } + } + + @Override + public boolean getColorSettings() { + if (handle instanceof WrapperConfigClientSettings) { + return ((WrapperConfigClientSettings) handle).isChatColors(); + } else { + return ((WrapperPlayClientSettings) handle).isChatColors(); + } + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsHandshakeClientSetProtocolPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsHandshakeClientSetProtocolPacket.java new file mode 100644 index 0000000..948249f --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsHandshakeClientSetProtocolPacket.java @@ -0,0 +1,23 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake; +import com.loohp.interactivechat.platform.packets.PlatformHandshakeClientSetProtocolPacket; + +public class PacketEventsHandshakeClientSetProtocolPacket extends PlatformHandshakeClientSetProtocolPacket> { + + public PacketEventsHandshakeClientSetProtocolPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsHandshakeClientSetProtocolPacket shallowClone() { + WrapperHandshakingClientHandshake handshake = (WrapperHandshakingClientHandshake) handle; + return new PacketEventsHandshakeClientSetProtocolPacket(new WrapperHandshakingClientHandshake(handshake.getProtocolVersion(), handshake.getServerAddress(), handshake.getServerPort(), handshake.getIntention())); + } + + @Override + public String getServerAddress() { + return ((WrapperHandshakingClientHandshake) handle).getServerAddress(); + } +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayClientChatCommandPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayClientChatCommandPacket.java new file mode 100644 index 0000000..d3fda41 --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayClientChatCommandPacket.java @@ -0,0 +1,52 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.protocol.chat.SignedCommandArgument; +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatCommand; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatCommandUnsigned; +import com.loohp.interactivechat.platform.packets.PlatformPlayClientChatCommandPacket; + +import java.util.List; + +public class PacketEventsPlayClientChatCommandPacket extends PlatformPlayClientChatCommandPacket> { + + public PacketEventsPlayClientChatCommandPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsPlayClientChatCommandPacket shallowClone() { + if (handle instanceof WrapperPlayClientChatCommand) { + WrapperPlayClientChatCommand command = (WrapperPlayClientChatCommand) handle; + WrapperPlayClientChatCommand clone; + if (command.getLastSeenMessages() == null) { + clone = new WrapperPlayClientChatCommand(command.getCommand(), command.getMessageSignData(), command.getSignedArguments(), command.getLegacyLastSeenMessages()); + } else { + clone = new WrapperPlayClientChatCommand(command.getCommand(), command.getMessageSignData(), command.getSignedArguments(), command.getLastSeenMessages()); + } + return new PacketEventsPlayClientChatCommandPacket(clone); + } else { + WrapperPlayClientChatCommandUnsigned command = (WrapperPlayClientChatCommandUnsigned) handle; + return new PacketEventsPlayClientChatCommandPacket(new WrapperPlayClientChatCommandUnsigned(command.getCommand())); + } + } + + @Override + public boolean hasArgumentSignatureEntries() { + if (handle instanceof WrapperPlayClientChatCommand) { + List data = ((WrapperPlayClientChatCommand) handle).getSignedArguments(); + return !data.isEmpty(); + } + return false; + } + + @Override + public String getCommand() { + if (handle instanceof WrapperPlayClientChatCommand) { + return ((WrapperPlayClientChatCommand) handle).getCommand(); + } else { + return ((WrapperPlayClientChatCommandUnsigned) handle).getCommand(); + } + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayClientChatPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayClientChatPacket.java new file mode 100644 index 0000000..d64a6c3 --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayClientChatPacket.java @@ -0,0 +1,30 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatMessage; +import com.loohp.interactivechat.platform.packets.PlatformPlayClientChatPacket; + +public class PacketEventsPlayClientChatPacket extends PlatformPlayClientChatPacket> { + + public PacketEventsPlayClientChatPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsPlayClientChatPacket shallowClone() { + WrapperPlayClientChatMessage message = (WrapperPlayClientChatMessage) handle; + WrapperPlayClientChatMessage clone; + if (message.getLastSeenMessages() == null) { + clone = new WrapperPlayClientChatMessage(message.getMessage(), message.getMessageSignData().orElse(null), message.getLegacyLastSeenMessages()); + } else { + clone = new WrapperPlayClientChatMessage(message.getMessage(), message.getMessageSignData().orElse(null), message.getLastSeenMessages()); + } + return new PacketEventsPlayClientChatPacket(clone); + } + + @Override + public String getMessage() { + return ((WrapperPlayClientChatMessage) handle).getMessage(); + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerCustomChatCompletionPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerCustomChatCompletionPacket.java new file mode 100644 index 0000000..5b70d02 --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerCustomChatCompletionPacket.java @@ -0,0 +1,19 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCustomChatCompletions; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerCustomChatCompletionPacket; + +public class PacketEventsPlayServerCustomChatCompletionPacket extends PlatformPlayServerCustomChatCompletionPacket> { + + public PacketEventsPlayServerCustomChatCompletionPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsPlayServerCustomChatCompletionPacket shallowClone() { + WrapperPlayServerCustomChatCompletions completions = (WrapperPlayServerCustomChatCompletions) handle; + return new PacketEventsPlayServerCustomChatCompletionPacket(new WrapperPlayServerCustomChatCompletions(completions.getAction(), completions.getEntries())); + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerServerDataPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerServerDataPacket.java new file mode 100644 index 0000000..e0eaada --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerServerDataPacket.java @@ -0,0 +1,26 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerServerData; +import com.loohp.interactivechat.InteractiveChat; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerServerDataPacket; +import com.loohp.interactivechat.utils.MCVersion; + +public class PacketEventsPlayServerServerDataPacket extends PlatformPlayServerServerDataPacket> { + + public PacketEventsPlayServerServerDataPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsPlayServerServerDataPacket shallowClone() { + WrapperPlayServerServerData data = (WrapperPlayServerServerData) handle; + return new PacketEventsPlayServerServerDataPacket(new WrapperPlayServerServerData(data.getMOTD(), data.getIcon().orElse(null), data.isPreviewsChat(), data.isEnforceSecureChat())); + } + + @Override + public void setServerUnsignedStatus(boolean status) { + ((WrapperPlayServerServerData) handle).setEnforceSecureChat(status); + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerSystemChatPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerSystemChatPacket.java new file mode 100644 index 0000000..2a8a8eb --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerSystemChatPacket.java @@ -0,0 +1,31 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientChatMessage; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatMessage; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerSystemChatPacket; + +public class PacketEventsPlayServerSystemChatPacket extends PlatformPlayServerSystemChatPacket> { + + public PacketEventsPlayServerSystemChatPacket(PacketWrapper handle) { + super(handle); + } + + @SuppressWarnings("deprecation") + @Override + public PacketEventsPlayServerSystemChatPacket shallowClone() { + if (handle instanceof WrapperPlayServerSystemChatMessage) { + WrapperPlayServerSystemChatMessage message = (WrapperPlayServerSystemChatMessage) handle; + if (message.getType() == null) { + return new PacketEventsPlayServerSystemChatPacket(new WrapperPlayServerSystemChatMessage(message.isOverlay(), message.getMessageJson())); + } else { + return new PacketEventsPlayServerSystemChatPacket(new WrapperPlayServerSystemChatMessage(message.getType(), message.getMessageJson())); + } + } else { + WrapperPlayServerChatMessage message = (WrapperPlayServerChatMessage) handle; + return new PacketEventsPlayServerSystemChatPacket(new WrapperPlayServerChatMessage(message.getMessage())); + } + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerTabCompletePacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerTabCompletePacket.java new file mode 100644 index 0000000..fe5a126 --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerTabCompletePacket.java @@ -0,0 +1,51 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTabComplete; +import com.loohp.interactivechat.objectholders.CommandSuggestion; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerTabCompletePacket; +import com.loohp.interactivechat.utils.ChatComponentType; +import com.mojang.brigadier.Message; +import com.mojang.brigadier.context.StringRange; +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.Suggestions; +import net.kyori.adventure.text.Component; + +import java.util.stream.Collectors; + +public class PacketEventsPlayServerTabCompletePacket extends PlatformPlayServerTabCompletePacket> { + + public PacketEventsPlayServerTabCompletePacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsPlayServerTabCompletePacket shallowClone() { + WrapperPlayServerTabComplete tabComplete = (WrapperPlayServerTabComplete) handle; + return new PacketEventsPlayServerTabCompletePacket(new WrapperPlayServerTabComplete(tabComplete.getTransactionId().orElse(null), tabComplete.getCommandRange().orElseThrow(IllegalStateException::new), tabComplete.getCommandMatches())); + } + + @Override + public CommandSuggestion getCommandSuggestions() { + WrapperPlayServerTabComplete tabComplete = (WrapperPlayServerTabComplete) handle; + StringRange range = tabComplete.getCommandRange().map(r -> StringRange.between(r.getBegin(), r.getEnd())).orElseThrow(IllegalStateException::new); + Suggestions suggestion = new Suggestions(range, tabComplete.getCommandMatches().stream() + .map((m) -> new Suggestion(range, m.getText(), m.getTooltip().map(PacketEventsPlayServerTabCompletePacket::c).orElse(null))).collect(Collectors.toList())); + return CommandSuggestion.of(tabComplete.getTransactionId().orElse(-1), suggestion); + } + + private static Message c(Component component) { + com.loohp.interactivechat.libs.net.kyori.adventure.text.Component icComponent = ChatComponentType.NativeAdventureComponent.convertFrom(component, null); + return (Message) ChatComponentType.IChatBaseComponent.convertTo(icComponent, false); + } + + @Override + public void setPacket(PlatformPlayServerTabCompletePacket packet) { + WrapperPlayServerTabComplete other = (WrapperPlayServerTabComplete) packet.getHandle(); + WrapperPlayServerTabComplete tabComplete = (WrapperPlayServerTabComplete) handle; + tabComplete.setTransactionId(other.getTransactionId().orElse(null)); + tabComplete.setCommandRange(other.getCommandRange().orElse(null)); + tabComplete.setCommandMatches(other.getCommandMatches()); + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerUnifiedChatMessagePacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerUnifiedChatMessagePacket.java new file mode 100644 index 0000000..8e3fe9d --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsPlayServerUnifiedChatMessagePacket.java @@ -0,0 +1,39 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.loohp.interactivechat.libs.net.kyori.adventure.text.Component; +import com.loohp.interactivechat.listeners.packet.MessagePacketHandler; +import com.loohp.interactivechat.platform.packets.PlatformPlayServerUnifiedChatMessagePacket; +import com.loohp.interactivechat.utils.ChatComponentType; +import org.bukkit.entity.Player; + +import java.util.UUID; +import java.util.function.UnaryOperator; + +import static com.loohp.interactivechat.listeners.packet.MessagePacketHandler.PacketAccessorResult; + +public class PacketEventsPlayServerUnifiedChatMessagePacket extends PlatformPlayServerUnifiedChatMessagePacket> { + + private final UnaryOperator> cloner; + + public PacketEventsPlayServerUnifiedChatMessagePacket(PacketWrapper handle, MessagePacketHandler> messagePacketHandler, UnaryOperator> cloner) { + super(handle, messagePacketHandler); + this.cloner = cloner; + } + + @Override + public PacketEventsPlayServerUnifiedChatMessagePacket shallowClone() { + return new PacketEventsPlayServerUnifiedChatMessagePacket(cloner.apply(handle), messagePacketHandler, cloner); + } + + @Override + public PacketAccessorResult read(Player player) { + return messagePacketHandler.getAccessor().apply(handle, player); + } + + @Override + public void write(Component component, ChatComponentType type, int field, UUID sender) { + messagePacketHandler.getWriter().apply(handle, component, type, field, sender); + } + +} diff --git a/src/main/java/net/skullian/platform/packets/PacketEventsStatusServerServerInfoPacket.java b/src/main/java/net/skullian/platform/packets/PacketEventsStatusServerServerInfoPacket.java new file mode 100644 index 0000000..446971b --- /dev/null +++ b/src/main/java/net/skullian/platform/packets/PacketEventsStatusServerServerInfoPacket.java @@ -0,0 +1,35 @@ +package net.skullian.platform.packets; + +import com.github.retrooper.packetevents.wrapper.PacketWrapper; +import com.github.retrooper.packetevents.wrapper.status.server.WrapperStatusServerResponse; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.loohp.interactivechat.platform.packets.PlatformStatusServerServerInfoPacket; + +public class PacketEventsStatusServerServerInfoPacket extends PlatformStatusServerServerInfoPacket> { + + private static final Gson GSON = new Gson(); + + public PacketEventsStatusServerServerInfoPacket(PacketWrapper handle) { + super(handle); + } + + @Override + public PacketEventsStatusServerServerInfoPacket shallowClone() { + WrapperStatusServerResponse response = (WrapperStatusServerResponse) handle; + return new PacketEventsStatusServerServerInfoPacket(new WrapperStatusServerResponse(response.getComponentJson())); + } + + @Override + public String getMotd() { + return GSON.toJson(((WrapperStatusServerResponse) handle).getComponent().get("description")); + } + + @Override + public void setMotd(String message) { + WrapperStatusServerResponse response = (WrapperStatusServerResponse) handle; + JsonObject component = response.getComponent(); + component.add("description", GSON.toJsonTree(message)); + response.setComponent(component); + } +} diff --git a/src/main/java/net/skullian/updater/UpdateListener.java b/src/main/java/net/skullian/updater/UpdateListener.java index e6018a8..1ab06c6 100644 --- a/src/main/java/net/skullian/updater/UpdateListener.java +++ b/src/main/java/net/skullian/updater/UpdateListener.java @@ -1,29 +1,30 @@ -package net.skullian.updater; - -import net.skullian.InteractiveChatPacketEvents; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.server.ServerLoadEvent; - -import static net.skullian.updater.Updater.checkUpdate; - -public class UpdateListener implements Listener { - - @EventHandler - public void onJoin(PlayerJoinEvent event) { - Bukkit.getScheduler().runTaskLaterAsynchronously(InteractiveChatPacketEvents.instance, () -> { - Player player = event.getPlayer(); - if (player.hasPermission("interactivechatpacketevents.checkupdate")) { - checkUpdate(player); - } - }, 100); - } - - @EventHandler - public void onStart(ServerLoadEvent event) { - checkUpdate(Bukkit.getConsoleSender()); - } -} +package net.skullian.updater; + +import com.loohp.interactivechat.libs.com.loohp.platformscheduler.Scheduler; +import net.skullian.InteractiveChatPacketEvents; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.server.ServerLoadEvent; + +import static net.skullian.updater.Updater.checkUpdate; + +public class UpdateListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Scheduler.runTaskLaterAsynchronously(InteractiveChatPacketEvents.instance, () -> { + Player player = event.getPlayer(); + if (player.hasPermission("interactivechatpacketevents.checkupdate")) { + checkUpdate(player); + } + }, 100); + } + + @EventHandler + public void onStart(ServerLoadEvent event) { + checkUpdate(Bukkit.getConsoleSender()); + } +} diff --git a/src/main/java/net/skullian/updater/Updater.java b/src/main/java/net/skullian/updater/Updater.java index 50b04cb..e628d77 100644 --- a/src/main/java/net/skullian/updater/Updater.java +++ b/src/main/java/net/skullian/updater/Updater.java @@ -1,61 +1,61 @@ -package net.skullian.updater; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; -import net.skullian.util.ChatUtils; -import net.skullian.util.GithubBuildInfo; -import net.skullian.util.GithubUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.event.Listener; - -import java.io.IOException; -import java.util.Locale; - -public class Updater implements Listener { - - public static UpdateStatus checkUpdate(CommandSender... senders) { - GithubBuildInfo currentBuild = GithubBuildInfo.CURRENT; - GithubBuildInfo latestBuild; - GithubUtils.GitHubStatusLookup lookupStatus; - - UpdateStatus updateStatus = new UpdateStatus(false, false); - - try { - if (currentBuild.isStable()) { - latestBuild = GithubUtils.lookupLatestRelease(); - lookupStatus = GithubUtils.compare(latestBuild.getId(), currentBuild.getId()); - } else { - latestBuild = null; - lookupStatus = GithubUtils.compare(GithubUtils.MAIN_BRANCH, currentBuild.getId()); - } - } catch (IOException error) { - ChatUtils.sendMessage("Failed to fetch latest version: " + error, senders); - updateStatus.setFailed(true); - return updateStatus; - } - - if (lookupStatus.isBehind()) { - if (currentBuild.isStable()) { - String url = "https://github.com/TerraByteDev/InteractiveChat-PacketEvents/releases/tag/" + latestBuild.getId(); - - ChatUtils.sendMessage("A new version of InteractiveChat-PacketEvents is available: " + latestBuild.getId() + "!", senders); - ChatUtils.sendMessage("Download at: " + url + "", senders); - } else { - ChatUtils.sendMessage("You are running a development build of InteractiveChat-PacketEvents!\nThe latest available development build is " + String.format(Locale.ROOT, "%,d", lookupStatus.getDistance()) + " commits ahead.", senders); - } - } - - updateStatus.setUpToDate(!lookupStatus.isBehind()); - return updateStatus; - } - - @AllArgsConstructor - @Getter - @Setter - public static final class UpdateStatus { - private boolean isUpToDate; - private boolean failed; - } - -} +package net.skullian.updater; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import net.skullian.util.ChatUtils; +import net.skullian.util.GithubBuildInfo; +import net.skullian.util.GithubUtils; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Listener; + +import java.io.IOException; +import java.util.Locale; + +public class Updater implements Listener { + + public static UpdateStatus checkUpdate(CommandSender... senders) { + GithubBuildInfo currentBuild = GithubBuildInfo.CURRENT; + GithubBuildInfo latestBuild; + GithubUtils.GitHubStatusLookup lookupStatus; + + UpdateStatus updateStatus = new UpdateStatus(false, false); + + try { + if (currentBuild.stable()) { + latestBuild = GithubUtils.lookupLatestRelease(); + lookupStatus = GithubUtils.compare(latestBuild.id(), currentBuild.id()); + } else { + latestBuild = null; + lookupStatus = GithubUtils.compare(GithubUtils.MAIN_BRANCH, currentBuild.id()); + } + } catch (IOException error) { + ChatUtils.sendMessage("Failed to fetch latest version: " + error, senders); + updateStatus.setFailed(true); + return updateStatus; + } + + if (lookupStatus.isBehind()) { + if (currentBuild.stable()) { + String url = "https://github.com/TerraByteDev/InteractiveChat-PacketEvents/releases/tag/" + latestBuild.id(); + + ChatUtils.sendMessage("A new version of InteractiveChat-PacketEvents is available: " + latestBuild.id() + "!", senders); + ChatUtils.sendMessage("Download at: " + url + "", senders); + } else { + ChatUtils.sendMessage("You are running a development build of InteractiveChat-PacketEvents!\nThe latest available development build is " + String.format(Locale.ROOT, "%,d", lookupStatus.getDistance()) + " commits ahead.", senders); + } + } + + updateStatus.setUpToDate(!lookupStatus.isBehind()); + return updateStatus; + } + + @AllArgsConstructor + @Getter + @Setter + public static final class UpdateStatus { + private boolean isUpToDate; + private boolean failed; + } + +} diff --git a/src/main/java/net/skullian/util/ChatUtils.java b/src/main/java/net/skullian/util/ChatUtils.java index 3655772..1ab62e3 100644 --- a/src/main/java/net/skullian/util/ChatUtils.java +++ b/src/main/java/net/skullian/util/ChatUtils.java @@ -1,27 +1,28 @@ -package net.skullian.util; - -import net.kyori.adventure.platform.bukkit.BukkitAudiences; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.skullian.InteractiveChatPacketEvents; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; - -public class ChatUtils { - - public static BukkitAudiences audience; - public static final String PREFIX = "[InteractiveChat-PacketEvents]"; - - static { - audience = BukkitAudiences.create(InteractiveChatPacketEvents.instance); - } - - public static void sendMessage(Object message, CommandSender... senders) { - if (senders.length == 0) senders = new ConsoleCommandSender[]{Bukkit.getConsoleSender()}; - - for (CommandSender sender : senders) { - audience.sender(sender).sendMessage(message instanceof Component ? MiniMessage.miniMessage().deserialize(PREFIX).append(Component.text(" ")).append((Component) message) : MiniMessage.miniMessage().deserialize(PREFIX + " " + message)); - } - } -} +package net.skullian.util; + +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.skullian.InteractiveChatPacketEvents; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; + +// to be brutally honest, this is just bloat, but I can't actually be bothered to remove it +public class ChatUtils { + + public static BukkitAudiences audience; + public static final String PREFIX = "[InteractiveChat-PacketEvents]"; + + static { + audience = BukkitAudiences.create(InteractiveChatPacketEvents.instance); + } + + public static void sendMessage(Object message, CommandSender... senders) { + if (senders.length == 0) senders = new ConsoleCommandSender[]{Bukkit.getConsoleSender()}; + + for (CommandSender sender : senders) { + audience.sender(sender).sendMessage(message instanceof Component ? MiniMessage.miniMessage().deserialize(PREFIX).append(Component.text(" ")).append((Component) message) : MiniMessage.miniMessage().deserialize(PREFIX + " " + message)); + } + } +} diff --git a/src/main/java/net/skullian/util/GithubBuildInfo.java b/src/main/java/net/skullian/util/GithubBuildInfo.java index e73d1f9..da77ecd 100644 --- a/src/main/java/net/skullian/util/GithubBuildInfo.java +++ b/src/main/java/net/skullian/util/GithubBuildInfo.java @@ -1,74 +1,47 @@ -package net.skullian.util; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import lombok.Getter; -import net.skullian.InteractiveChatPacketEvents; -import org.jetbrains.annotations.NotNull; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.Objects; - -public class GithubBuildInfo { - public static final GithubBuildInfo CURRENT = readBuildInfo(); - - private final String id; - private final String name; - private final Instant buildTime; - @Getter - private final boolean stable; - - public GithubBuildInfo(String id, String name, Instant buildTime, boolean stable) { - this.id = Objects.requireNonNull(id); - this.name = Objects.requireNonNull(name); - this.buildTime = Objects.requireNonNull(buildTime); - this.stable = stable; - } - - public @NotNull String getId() { - return id; - } - - public @NotNull String getName() { - return name; - } - - public @NotNull Instant getBuildTime() { - return buildTime; - } - - @Override - public String toString() { - return "BuildInfo{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", buildTime=" + buildTime + ", stable=" + stable + '}'; - } - - private static GithubBuildInfo readBuildInfo() { - try (InputStream in = InteractiveChatPacketEvents.instance.getResource("version.json")) { - if (in == null) - throw new IOException("No input"); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { - return parseBuildInfo(reader); - } - } catch (IOException e) { - throw new AssertionError("Missing version information!", e); - } - } - - private static GithubBuildInfo parseBuildInfo(BufferedReader reader) { - JsonObject json = new JsonParser().parse(reader).getAsJsonObject(); - - String id = json.get("git.commit.id.abbrev").getAsString(); - String name = json.get("git.build.version").getAsString(); - Instant buildTime = Instant.parse(json.get("git.build.time").getAsString()); - // (1): "-" - // (2): "+" - boolean stable = name.indexOf('-') == -1 && name.indexOf('+') == -1; - - return new GithubBuildInfo(id, name, buildTime, stable); - } -} +package net.skullian.util; + +import net.skullian.InteractiveChatPacketEvents; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; +import java.util.Properties; + +public record GithubBuildInfo(String id, String name, String branch, boolean stable) { + public static final GithubBuildInfo CURRENT = readBuildInfo(); + + public GithubBuildInfo(String id, String name, String branch, boolean stable) { + this.id = Objects.requireNonNull(id); + this.name = Objects.requireNonNull(name); + this.branch = Objects.requireNonNull(branch); + this.stable = stable; + } + + @Override + public String toString() { + return "GithubBuildInfo{" + "id='" + id + "', name='" + name + "', branch='" + branch + ", stable=" + stable + '}'; + } + + private static GithubBuildInfo readBuildInfo() { + try (InputStream in = InteractiveChatPacketEvents.instance.getResource("version.properties")) { + if (in == null) + throw new IOException("No input"); + + Properties properties = new Properties(); + properties.load(in); + return parseBuildInfo(properties); + } catch (IOException e) { + throw new AssertionError("Missing version information!", e); + } + } + + private static GithubBuildInfo parseBuildInfo(Properties properties) { + String id = properties.getProperty("git.commit.id.abbrev"); + String name = properties.getProperty("git.build.version"); + String branch = properties.getProperty("git.branch"); + + boolean stable = name.indexOf('-') == -1 && name.indexOf('+') == -1; + + return new GithubBuildInfo(id, name, branch, stable); + } +} diff --git a/src/main/java/net/skullian/util/GithubUtils.java b/src/main/java/net/skullian/util/GithubUtils.java index 287b4a3..cea0ffd 100644 --- a/src/main/java/net/skullian/util/GithubUtils.java +++ b/src/main/java/net/skullian/util/GithubUtils.java @@ -1,138 +1,135 @@ -package net.skullian.util; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import javax.net.ssl.HttpsURLConnection; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.Locale; -import java.util.Objects; - -public class GithubUtils { - - public static final String MAIN_BRANCH = "main"; - - private static final String API_BASE = "https://api.github.com/repos/"; - - // https://docs.github.com/en/rest/releases/releases#get-the-latest-release - private static final String API_LATEST_RELEASE = API_BASE + "TerraByteDev/InteractiveChat-PacketEvents/releases/latest"; - - // https://docs.github.com/en/rest/commits/commits#compare-two-commits - private static final String API_COMPARE = API_BASE + "TerraByteDev/InteractiveChat-PacketEvents/compare/%s...%s"; - - private GithubUtils() { - } - - public static GithubBuildInfo lookupLatestRelease() throws IOException { - URL url = new URL(API_LATEST_RELEASE); - HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); - final int responseCode = https.getResponseCode(); - - if (isSuccessfulResponse(responseCode)) { - try (InputStream in = https.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { - return parseBuildInfo(reader); - } - } else { - throw new IOException("Bad response status: " + responseCode); - } - } - - private static GithubBuildInfo parseBuildInfo(BufferedReader reader) { - JsonObject json = new JsonParser().parse(reader).getAsJsonObject(); - String id = json.get("tag_name").getAsString(); - Instant buildTime = Instant.parse(json.get("published_at").getAsString()); - return new GithubBuildInfo(id, id, buildTime, true); - } - - public static GitHubStatusLookup compare(@NotNull String base, @NotNull String head) throws IOException { - URL url = new URL(String.format(API_COMPARE, base, head)); - HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); - final int responseCode = https.getResponseCode(); - - if (isSuccessfulResponse(responseCode)) { - try (InputStream in = https.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { - return parseComparison(reader); - } - } else if (responseCode == HttpsURLConnection.HTTP_NOT_FOUND) { - return new GitHubStatusLookup(GitHubStatus.UNKNOWN, 0); - } else { - return new GitHubStatusLookup(GitHubStatus.FAILURE, 0); - } - } - - private static GitHubStatusLookup parseComparison(@NotNull BufferedReader reader) { - JsonObject json = new JsonParser().parse(reader).getAsJsonObject(); - GitHubStatus status = GitHubStatus.fromString(json.get("status").getAsString()); - int aheadBy = json.get("ahead_by").getAsInt(); - int behindBy = json.get("behind_by").getAsInt(); - return new GitHubStatusLookup(status, status == GitHubStatus.AHEAD ? aheadBy : behindBy); - } - - private static boolean isSuccessfulResponse(int code) { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#successful_responses - return code >= 200 && code <= 299; - } - - @Getter - public static class GitHubStatusLookup { - private final GitHubStatus status; - private final int distance; - - private GitHubStatusLookup(@NotNull GitHubStatus status, int distance) { - this.status = Objects.requireNonNull(status); - this.distance = distance; - } - - public boolean isAhead() { - return status == GitHubStatus.AHEAD; - } - - public boolean isIdentical() { - return status == GitHubStatus.IDENTICAL; - } - - public boolean isBehind() { - return status == GitHubStatus.BEHIND; - } - - @Override - public String toString() { - return "GitHubStatusLookup{" + "status=" + status + ", distance=" + distance + '}'; - } - } - - public enum GitHubStatus { - // Valid GitHub status types - - DIVERGED, - AHEAD, - BEHIND, - IDENTICAL, - - // Internal types - - /** - * Represents the case when a BASEHEAD is unknown to GitHub, private builds, for example. - */ - UNKNOWN, - - /** - * Represents failure to determine the status due to external failures. - */ - FAILURE; - - public static GitHubStatus fromString(@NotNull String str) { - return GitHubStatus.valueOf(str.toUpperCase(Locale.ROOT)); - } - } -} +package net.skullian.util; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Locale; +import java.util.Objects; + +public class GithubUtils { + + public static final String MAIN_BRANCH = "main"; + + private static final String API_BASE = "https://api.github.com/repos/"; + + // https://docs.github.com/en/rest/releases/releases#get-the-latest-release + private static final String API_LATEST_RELEASE = API_BASE + "TerraByteDev/InteractiveChat-PacketEvents/releases/latest"; + + // https://docs.github.com/en/rest/commits/commits#compare-two-commits + private static final String API_COMPARE = API_BASE + "TerraByteDev/InteractiveChat-PacketEvents/compare/%s...%s"; + + private GithubUtils() {} + + public static GithubBuildInfo lookupLatestRelease() throws IOException { + URL url = new URL(API_LATEST_RELEASE); + HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); + final int responseCode = https.getResponseCode(); + + if (isSuccessfulResponse(responseCode)) { + try (InputStream in = https.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + return parseBuildInfo(reader); + } + } else { + throw new IOException("Bad response status: " + responseCode); + } + } + + private static GithubBuildInfo parseBuildInfo(BufferedReader reader) { + JsonObject json = JsonParser.parseReader(reader).getAsJsonObject(); + String id = json.get("tag_name").getAsString(); + return new GithubBuildInfo(id, id, MAIN_BRANCH, true); + } + + public static GitHubStatusLookup compare(@NotNull String base, @NotNull String head) throws IOException { + URL url = new URL(String.format(API_COMPARE, base, head)); + HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); + final int responseCode = https.getResponseCode(); + + if (isSuccessfulResponse(responseCode)) { + try (InputStream in = https.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + return parseComparison(reader); + } + } else if (responseCode == HttpsURLConnection.HTTP_NOT_FOUND) { + return new GitHubStatusLookup(GitHubStatus.UNKNOWN, 0); + } else { + return new GitHubStatusLookup(GitHubStatus.FAILURE, 0); + } + } + + private static GitHubStatusLookup parseComparison(@NotNull BufferedReader reader) { + JsonObject json = new JsonParser().parse(reader).getAsJsonObject(); + GitHubStatus status = GitHubStatus.fromString(json.get("status").getAsString()); + int aheadBy = json.get("ahead_by").getAsInt(); + int behindBy = json.get("behind_by").getAsInt(); + return new GitHubStatusLookup(status, status == GitHubStatus.AHEAD ? aheadBy : behindBy); + } + + private static boolean isSuccessfulResponse(int code) { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#successful_responses + return code >= 200 && code <= 299; + } + + @Getter + public static class GitHubStatusLookup { + private final GitHubStatus status; + private final int distance; + + private GitHubStatusLookup(@NotNull GitHubStatus status, int distance) { + this.status = Objects.requireNonNull(status); + this.distance = distance; + } + + public boolean isAhead() { + return status == GitHubStatus.AHEAD; + } + + public boolean isIdentical() { + return status == GitHubStatus.IDENTICAL; + } + + public boolean isBehind() { + return status == GitHubStatus.BEHIND; + } + + @Override + public String toString() { + return "GitHubStatusLookup{" + "status=" + status + ", distance=" + distance + '}'; + } + } + + public enum GitHubStatus { + // Valid GitHub status types + + DIVERGED, + AHEAD, + BEHIND, + IDENTICAL, + + // Internal types + + /** + * Represents the case when a BASEHEAD is unknown to GitHub, private builds, for example. + */ + UNKNOWN, + + /** + * Represents failure to determine the status due to external failures. + */ + FAILURE; + + public static GitHubStatus fromString(@NotNull String str) { + return GitHubStatus.valueOf(str.toUpperCase(Locale.ROOT)); + } + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 8455610..932dfb2 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,12 +1,4 @@ # Welcome to the ICPE Config. -# This config allows you to adjust the listener priorities on all packets. -# Support priorities (case-sensitive): LOWEST, LOW, NORMAL, HIGH, HIGHEST, MONITOR - -ChatListenerPriority: HIGHEST -ClientSettingsPriority: NORMAL -SignedPacketPriority: HIGHEST -LegacyCommandPacketPriority: HIGH -BungeecordPingPriority: NORMAL # Enable debug? Debug: true \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5ca2f68..4b4cdc2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,15 +1,15 @@ name: InteractiveChat-PacketEvents -version: '1.0.7' +version: '1.1.0' main: net.skullian.InteractiveChatPacketEvents api-version: 1.13 description: Add PacketEvents support to InteractiveChat depend: [InteractiveChat, packetevents] +authors: [Skullians, LOOHP] +folia-supported: true libraries: - net.kyori:adventure-text-serializer-plain:4.18.0 - net.kyori:adventure-text-serializer-legacy:4.18.0 - net.kyori:adventure-platform-bukkit:4.3.4 - net.kyori:adventure-text-minimessage:4.18.0 - - org.incendo:cloud-paper:2.0.0-beta.10 - - org.incendo:cloud-annotations:2.0.0 - net.bytebuddy:byte-buddy:1.17.6 \ No newline at end of file