This commit is contained in:
Pyr 2023-04-17 17:15:50 +01:00
commit 27b53217d7
92 changed files with 7072 additions and 0 deletions

42
.gitignore vendored Normal file

@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

3
.idea/.gitignore vendored Normal file

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

7
.idea/discord.xml Normal file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

18
.idea/gradle.xml Normal file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$PROJECT_DIR$/../../../../gradle" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,50 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="BooleanMethodIsAlwaysInverted" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ClassCanBeRecord" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="EditorConfigUnusedDeclaration" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
<inspection_tool class="GrazieInspection" enabled="false" level="TYPO" enabled_by_default="false" />
<inspection_tool class="GroovyUnusedAssignment" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="WARNING_ATTRIBUTES" />
<inspection_tool class="GroovyUnusedDeclaration" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
<inspection_tool class="IgnoreResultOfCall" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportAllNonLibraryCalls" value="false" />
<option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" />
</inspection_tool>
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NullableProblems" enabled="true" level="WARNING" enabled_by_default="true">
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="false" />
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="false" />
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool>
<inspection_tool class="PatternVariableHidesField" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
<inspection_tool class="UnusedReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="YAMLSchemaValidation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="unused" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" checkParameterExcludingHierarchy="false">
<option name="LOCAL_VARIABLE" value="true" />
<option name="FIELD" value="true" />
<option name="METHOD" value="true" />
<option name="CLASS" value="true" />
<option name="PARAMETER" value="true" />
<option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
<option name="ADD_MAINS_TO_ENTRIES" value="true" />
<option name="ADD_APPLET_TO_ENTRIES" value="true" />
<option name="ADD_SERVLET_TO_ENTRIES" value="true" />
<option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
<option name="selected" value="true" />
<option name="MIXIN_ENTRY_POINT" value="true" />
</inspection_tool>
</profile>
</component>

13
.idea/misc.xml Normal file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="2">
<item index="0" class="java.lang.String" itemvalue="io.github.znetworkw.znpcservers.commands.CommandInformation" />
<item index="1" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="corretto-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

124
.idea/uiDesigner.xml Normal file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml Normal file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

0
README.md Normal file

45
build.gradle Normal file

@ -0,0 +1,45 @@
plugins {
id "java"
id "com.github.johnrengelman.shadow" version "8.1.0"
}
group "lol.pyr"
version "1.0"
repositories {
mavenCentral()
maven {
url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
}
maven {
url "https://repo.extendedclip.com/content/repositories/placeholderapi/"
}
maven {
url "https://repo.pyr.lol/releases/"
}
}
dependencies {
compileOnly "org.spigotmc:spigot-api:1.19.2-R0.1-SNAPSHOT"
compileOnly "me.clip:placeholderapi:2.11.1"
}
group "net.boxpvpv"
version "1.0.0"
compileJava {
options.release.set(17)
}
shadowJar {
archiveClassifier.set ""
relocate "lol.pyr.extendedcommands", "lol.pyr.znpcsplus.lib.command"
minimize()
}
processResources {
expand("version": version)
}
tasks.compileJava.dependsOn clean
tasks.jar.finalizedBy shadowJar

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

Binary file not shown.

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

234
gradlew vendored Normal file

@ -0,0 +1,234 @@
#!/bin/sh
#
# Copyright © 2015-2021 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.
#
##############################################################################
#
# 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/master/subprojects/plugins/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
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file

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

2
settings.gradle Normal file

@ -0,0 +1,2 @@
rootProject.name = 'ZNPCsPlus'

@ -0,0 +1,7 @@
package io.github.znetworkw.znpcservers;
public class UnexpectedCallException extends RuntimeException {
public UnexpectedCallException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,42 @@
package io.github.znetworkw.znpcservers.cache;
public enum CacheCategory {
DEFAULT(""),
NETWORK("network"),
PROTOCOL("network.protocol"),
CHAT("network.chat"),
PACKET("network.protocol.game"),
SYNCHER("network.syncher"),
ENTITY("world.entity"),
WORLD_ENTITY_PLAYER("world.entity.player"),
ITEM("world.item"),
WORLD_LEVEL("world.level"),
WORLD_SCORES("world.scores"),
SERVER_LEVEL("server.level"),
SERVER_NETWORK("server.network"),
SERVER("server");
private static final String EMPTY_STRING = "";
private final String subPackageName;
private final String packageName;
CacheCategory(String subPackageName) {
this.subPackageName = subPackageName;
StringBuilder stringBuilder = new StringBuilder(CachePackage.MINECRAFT_SERVER.getFixedPackageName());
if (subPackageName.length() > 0) {
stringBuilder.append(".");
stringBuilder.append(subPackageName);
}
this.packageName = stringBuilder.toString();
}
public String getSubPackageName() {
return this.subPackageName;
}
public String getPackageName() {
return this.packageName;
}
}

@ -0,0 +1,35 @@
package io.github.znetworkw.znpcservers.cache;
import io.github.znetworkw.znpcservers.utility.Utils;
public enum CachePackage {
DEFAULT,
CRAFT_BUKKIT("org.bukkit.craftbukkit." + Utils.getBukkitPackage()),
MINECRAFT_SERVER("net.minecraft");
private static final String EMPTY_STRING = "";
private static final String DOT = ".";
private final String fixedPackageName;
CachePackage(String packageName) {
this
.fixedPackageName = Utils.versionNewer(17) ? packageName : (packageName + (packageName.contains("minecraft") ? (".server." + Utils.getBukkitPackage()) : ""));
}
CachePackage() {
this.fixedPackageName = "";
}
public String getForCategory(CacheCategory packetCategory, String extra) {
return Utils.versionNewer(17) ? (packetCategory
.getPackageName() + ((extra.length() > 0) ? ("." + extra) : "")) :
this.fixedPackageName;
}
public String getFixedPackageName() {
return this.fixedPackageName;
}
}

@ -0,0 +1,814 @@
package io.github.znetworkw.znpcservers.cache;
import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.utility.Utils;
import io.netty.channel.Channel;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
public final class CacheRegistry {
public static final Class<?> PACKET_PLAY_IN_USE_ENTITY_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayInUseEntity"))).load();
public static final Class<?> ENUM_PLAYER_INFO_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction")
.withClassName("ClientboundPlayerInfoUpdatePacket$a"))).load();
public static final Class<?> PACKET_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PROTOCOL)
.withClassName("Packet"))).load();
public static final Class<?> ENTITY_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withClassName("Entity"))).load();
public static final Class<?> ENTITY_LIVING = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withClassName("EntityLiving"))).load();
public static final Class<?> ENTITY_PLAYER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER_LEVEL)
.withClassName("EntityPlayer"))).load();
public static final Class<?> ENTITY_ARMOR_STAND_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("decoration")
.withClassName("EntityArmorStand"))).load();
public static final Class<?> ENTITY_BAT_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("ambient")
.withClassName("EntityBat"))).load();
public static final Class<?> ENTITY_BLAZE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityBlaze"))).load();
public static final Class<?> ENTITY_CAVE_SPIDER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityCaveSpider"))).load();
public static final Class<?> ENTITY_CHICKEN_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityChicken"))).load();
public static final Class<?> ENTITY_COW_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityCow"))).load();
public static final Class<?> ENTITY_CREEPER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityCreeper"))).load();
public static final Class<?> ENTITY_ENDER_DRAGON_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("boss.enderdragon")
.withClassName("EntityEnderDragon"))).load();
public static final Class<?> ENTITY_ENDERMAN_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityEnderman"))).load();
public static final Class<?> ENTITY_HUMAN_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("player")
.withClassName("EntityHuman"))).load();
public static final Class<?> ENTITY_ENDERMITE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityEndermite"))).load();
public static final Class<?> ENTITY_GHAST_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityGhast"))).load();
public static final Class<?> ENTITY_IRON_GOLEM_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityIronGolem"))).load();
public static final Class<?> ENTITY_GIANT_ZOMBIE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityGiantZombie"))).load();
public static final Class<?> ENTITY_GUARDIAN_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityGuardian"))).load();
public static final Class<?> ENTITY_HORSE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal.horse")
.withClassName("EntityHorse"))).load();
public static final Class<?> ENTITY_LLAMA_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal.horse")
.withClassName("EntityLlama"))).load();
public static final Class<?> ENTITY_MAGMA_CUBE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityMagmaCube"))).load();
public static final Class<?> ENTITY_MUSHROOM_COW_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityMushroomCow"))).load();
public static final Class<?> ENTITY_OCELOT_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityOcelot"))).load();
public static final Class<?> ENTITY_TURTLE = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityTurtle"))).load();
public static final Class<?> ENTITY_WARDEN = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster.warden")
.withClassName("EntityWarden"))).load();
public static final Class<?> ENTITY_BEE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityBee"))).load();
public static final Class<?> ENTITY_PARROT_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityParrot"))).load();
public static final Class<?> ENTITY_PIG_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityPig"))).load();
public static final Class<?> ENTITY_RABBIT_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityRabbit"))).load();
public static final Class<?> ENTITY_POLAR_BEAR_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityPolarBear"))).load();
public static final Class<?> ENTITY_PANDA_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityPanda"))).load();
public static final Class<?> ENTITY_SHEEP_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntitySheep"))).load();
public static final Class<?> ENTITY_SNOWMAN_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntitySnowman"))).load();
public static final Class<?> ENTITY_SHULKER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityShulker"))).load();
public static final Class<?> ENTITY_SILVERFISH_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntitySilverfish"))).load();
public static final Class<?> ENTITY_SKELETON_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntitySkeleton"))).load();
public static final Class<?> ENTITY_SLIME_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntitySlime"))).load();
public static final Class<?> ENTITY_SPIDER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntitySpider"))).load();
public static final Class<?> ENTITY_SQUID_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntitySquid"))).load();
public static final Class<?> ENTITY_VILLAGER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("npc")
.withClassName("EntityVillager"))).load();
public static final Class<?> ENTITY_WITCH_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityWitch"))).load();
public static final Class<?> ENTITY_WITHER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("boss.wither")
.withClassName("EntityWither"))).load();
public static final Class<?> ENTITY_ZOMBIE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("monster")
.withClassName("EntityZombie"))).load();
public static final Class<?> ENTITY_WOLF_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityWolf"))).load();
public static final Class<?> ENTITY_AXOLOTL_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal.axolotl")
.withClassName("Axolotl"))).load();
public static final Class<?> ENTITY_GOAT_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal.goat")
.withClassName("Goat"))).load();
public static final Class<?> ENTITY_FOX_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withAdditionalData("animal")
.withClassName("EntityFox"))).load();
public static final Class<?> ENTITY_TYPES_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withClassName("EntityTypes"))).load();
public static final Class<?> ENUM_CHAT_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withClassName("EnumChatFormat"))).load();
public static final Class<?> ENUM_ITEM_SLOT = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withClassName("EnumItemSlot"))).load();
public static final Class<?> I_CHAT_BASE_COMPONENT = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.CHAT)
.withClassName("IChatBaseComponent"))).load();
public static final Class<?> ITEM_STACK_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ITEM)
.withClassName("ItemStack"))).load();
public static final Class<?> DATA_WATCHER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SYNCHER)
.withClassName("DataWatcher"))).load();
public static final Class<?> DATA_WATCHER_OBJECT = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SYNCHER)
.withClassName("DataWatcherObject"))).load();
public static final Class<?> DATA_WATCHER_REGISTRY = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SYNCHER)
.withClassName("DataWatcherRegistry"))).load();
public static final Class<?> DATA_WATCHER_SERIALIZER = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SYNCHER)
.withClassName("DataWatcherSerializer"))).load();
public static final Class<?> WORLD_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.WORLD_LEVEL)
.withClassName("World"))).load();
public static final Class<?> CRAFT_ITEM_STACK_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("inventory.CraftItemStack"))).load();
public static final Class<?> WORLD_SERVER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER_LEVEL)
.withClassName("WorldServer"))).load();
public static final Class<?> MINECRAFT_SERVER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER)
.withClassName("MinecraftServer"))).load();
public static final Class<?> PLAYER_INTERACT_MANAGER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER_LEVEL)
.withClassName("PlayerInteractManager"))).load();
public static final Class<?> PLAYER_CONNECTION_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER_NETWORK)
.withClassName("PlayerConnection"))).load();
public static final Class<?> NETWORK_MANAGER_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.NETWORK)
.withClassName("NetworkManager"))).load();
public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutPlayerInfo")
.withClassName("ClientboundPlayerInfoUpdatePacket")))
.load();
public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("ClientboundPlayerInfoRemovePacket")))
.load();
public static final Class<?> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutScoreboardTeam"))).load();
public static final Class<?> PACKET_PLAY_OUT_ENTITY_DESTROY_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityDestroy"))).load();
public static final Class<?> SCOREBOARD_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.WORLD_SCORES)
.withClassName("Scoreboard"))).load();
public static final Class<?> SCOREBOARD_TEAM_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.WORLD_SCORES)
.withClassName("ScoreboardTeam"))).load();
public static final Class<?> ENUM_TAG_VISIBILITY = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.WORLD_SCORES)
.withClassName("ScoreboardTeamBase$EnumNameTagVisibility"))).load();
public static final Class<?> CRAFT_CHAT_MESSAGE_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("util.CraftChatMessage"))).load();
public static final Class<?> PROFILE_PUBLIC_KEY_CLASS = (new TypeCache.BaseCache.ClazzLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.WORLD_ENTITY_PLAYER)
.withClassName("ProfilePublicKey"))).load();
public static final TypeCache.BaseCache<Constructor<?>> SCOREBOARD_TEAM_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(SCOREBOARD_TEAM_CLASS)
.withParameterTypes(SCOREBOARD_CLASS, String.class));
public static final TypeCache.BaseCache<Constructor<?>> PLAYER_CONSTRUCTOR_OLD = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_PLAYER_CLASS)
.withParameterTypes(MINECRAFT_SERVER_CLASS, WORLD_SERVER_CLASS, GameProfile.class, PLAYER_INTERACT_MANAGER_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PLAYER_CONSTRUCTOR_NEW = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_PLAYER_CLASS)
.withParameterTypes(MINECRAFT_SERVER_CLASS, WORLD_SERVER_CLASS, GameProfile.class));
public static final TypeCache.BaseCache<Constructor<?>> PLAYER_CONSTRUCTOR_NEW_1 = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_PLAYER_CLASS)
.withParameterTypes(MINECRAFT_SERVER_CLASS, WORLD_SERVER_CLASS, GameProfile.class, PROFILE_PUBLIC_KEY_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PLAYER_CONSTRUCTOR_NEW_2 = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_PLAYER_CLASS)
.withParameterTypes(MINECRAFT_SERVER_CLASS, WORLD_SERVER_CLASS, GameProfile.class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_PLAYER_INFO_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PACKET_PLAY_OUT_PLAYER_INFO_CLASS)
.withParameterTypes(ENUM_PLAYER_INFO_CLASS, (Utils.BUKKIT_VERSION > 16) ? Collection.class : Iterable.class).withParameterTypes(ENUM_PLAYER_INFO_CLASS, ENTITY_PLAYER_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CLASS)
.withParameterTypes(List.class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_LOOK_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntity$PacketPlayOutEntityLook")
.withParameterTypes(int.class, byte.class, byte.class, boolean.class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_HEAD_ROTATION_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityHeadRotation")
.withParameterTypes(ENTITY_CLASS, byte.class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_TELEPORT_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityTeleport")
.withParameterTypes(ENTITY_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityMetadata")
.withParameterTypes(int.class, DATA_WATCHER_CLASS, boolean.class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR_V1 = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityMetadata")
.withParameterTypes(int.class, List.class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_NAMED_ENTITY_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutNamedEntitySpawn")
.withParameterTypes(ENTITY_HUMAN_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PACKET_PLAY_OUT_ENTITY_DESTROY_CLASS)
.withParameterTypes(int.class).withParameterTypes(int[].class));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_SPAWN_ENTITY_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutSpawnEntity")
.withClassName("PacketPlayOutSpawnEntityLiving")
.withParameterTypes(ENTITY_LIVING).withParameterTypes(ENTITY_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PLAYER_INTERACT_MANAGER_OLD_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PlayerInteractManager")
.withParameterTypes(WORLD_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PLAYER_INTERACT_MANAGER_NEW_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PlayerInteractManager")
.withParameterTypes(WORLD_SERVER_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CONSTRUCTOR_OLD = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_OLD = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityEquipment")
.withParameterTypes(int.class, int.class, ITEM_STACK_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_NEWEST_OLD = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityEquipment")
.withParameterTypes(int.class, ENUM_ITEM_SLOT, ITEM_STACK_CLASS));
public static final TypeCache.BaseCache<Constructor<?>> PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_V1 = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutEntityEquipment")
.withParameterTypes(int.class, List.class));
public static final TypeCache.BaseCache<Constructor<?>> I_CHAT_BASE_COMPONENT_A_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.CHAT)
.withClassName("ChatComponentText")
.withParameterTypes(String.class));
public static final TypeCache.BaseCache<Constructor<?>> ENTITY_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_ARMOR_STAND_CLASS)
.withParameterTypes(WORLD_CLASS, double.class, double.class, double.class));
public static final TypeCache.BaseCache<Constructor<?>> DATA_WATCHER_OBJECT_CONSTRUCTOR = new TypeCache.BaseCache.ConstructorLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(DATA_WATCHER_OBJECT)
.withParameterTypes(int.class, DATA_WATCHER_SERIALIZER));
public static final TypeCache.BaseCache<Method> AS_NMS_COPY_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("inventory.CraftItemStack")
.withMethodName("asNMSCopy")
.withParameterTypes(ItemStack.class));
public static final TypeCache.BaseCache<Method> GET_PROFILE_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withClassName(ENTITY_HUMAN_CLASS)
.withExpectResult(GameProfile.class));
public static final TypeCache.BaseCache<Method> GET_ENTITY_ID = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("getId")
.withMethodName("ae")
.withMethodName("ah")
.withExpectResult(int.class));
public static final TypeCache.BaseCache<Method> GET_HANDLE_PLAYER_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("entity.CraftPlayer").withClassName("entity.CraftHumanEntity")
.withMethodName("getHandle"));
public static final TypeCache.BaseCache<Method> GET_HANDLE_WORLD_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("CraftWorld")
.withMethodName("getHandle"));
public static final TypeCache.BaseCache<Method> GET_SERVER_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("CraftServer")
.withMethodName("getServer"));
public static final TypeCache.BaseCache<Method> SEND_PACKET_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PLAYER_CONNECTION_CLASS)
.withMethodName("sendPacket").withMethodName("a")
.withParameterTypes(PACKET_CLASS));
public static final TypeCache.BaseCache<Method> SET_CUSTOM_NAME_OLD_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("setCustomName")
.withParameterTypes(String.class));
public static final TypeCache.BaseCache<Method> SET_CUSTOM_NAME_NEW_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("setCustomName")
.withMethodName("a")
.withMethodName("b")
.withParameterTypes(I_CHAT_BASE_COMPONENT).withExpectResult(void.class));
public static final TypeCache.BaseCache<Method> SET_CUSTOM_NAME_VISIBLE_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("setCustomNameVisible")
.withMethodName("n")
.withParameterTypes(boolean.class));
public static final TypeCache.BaseCache<Method> SET_INVISIBLE_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_ARMOR_STAND_CLASS)
.withMethodName("setInvisible").withMethodName("j")
.withParameterTypes(boolean.class));
public static final TypeCache.BaseCache<Method> SET_LOCATION_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("setPositionRotation")
.withMethodName("a")
.withParameterTypes(double.class, double.class, double.class, float.class, float.class));
public static final TypeCache.BaseCache<Method> SET_DATA_WATCHER_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(DATA_WATCHER_CLASS)
.withMethodName("set").withMethodName("b")
.withParameterTypes(DATA_WATCHER_OBJECT, Object.class));
public static final TypeCache.BaseCache<Method> WATCH_DATA_WATCHER_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(DATA_WATCHER_CLASS)
.withMethodName("watch")
.withParameterTypes(int.class, Object.class));
public static final TypeCache.BaseCache<Method> GET_DATA_WATCHER_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("getDataWatcher")
.withMethodName("ai")
.withMethodName("al")
.withExpectResult(DATA_WATCHER_CLASS));
public static final TypeCache.BaseCache<Method> GET_BUKKIT_ENTITY_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENTITY_CLASS)
.withMethodName("getBukkitEntity"));
public static final TypeCache.BaseCache<Method> GET_ENUM_CHAT_ID_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENUM_CHAT_CLASS)
.withMethodName("b"));
public static final TypeCache.BaseCache<Method> ENUM_CHAT_TO_STRING_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENUM_CHAT_CLASS)
.withExpectResult(String.class)
.withMethodName("toString"));
public static final TypeCache.BaseCache<Method> ENTITY_TYPES_A_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.ENTITY)
.withClassName(ENTITY_TYPES_CLASS)
.withMethodName("a")
.withParameterTypes(String.class));
public static final TypeCache.BaseCache<Method> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CREATE_V1 = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS)
.withMethodName("a")
.withParameterTypes(SCOREBOARD_TEAM_CLASS));
public static final TypeCache.BaseCache<Method> PACKET_PLAY_OUT_SCOREBOARD_TEAM_CREATE = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PACKET_PLAY_OUT_SCOREBOARD_TEAM_CLASS)
.withMethodName("a")
.withParameterTypes(SCOREBOARD_TEAM_CLASS, boolean.class));
public static final TypeCache.BaseCache<Method> SCOREBOARD_PLAYER_LIST = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(SCOREBOARD_TEAM_CLASS)
.withMethodName("getPlayerNameSet").withMethodName("g"));
public static final TypeCache.BaseCache<Method> ENUM_CHAT_FORMAT_FIND = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withClassName(ENUM_CHAT_CLASS)
.withParameterTypes(String.class).withExpectResult(ENUM_CHAT_CLASS));
public static final TypeCache.BaseCache<Method> CRAFT_CHAT_MESSAGE_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName(CRAFT_CHAT_MESSAGE_CLASS)
.withMethodName("fromStringOrNull")
.withParameterTypes(String.class));
public static final TypeCache.BaseCache<Method> GET_UNIQUE_ID_METHOD = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withClassName(ENTITY_CLASS)
.withExpectResult(UUID.class));
public static final TypeCache.BaseCache<Method> GET_DATAWATCHER_B_LIST = new TypeCache.BaseCache.MethodLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withMethodName("c")
.withClassName(DATA_WATCHER_CLASS));
public static final TypeCache.BaseCache<Field> PLAYER_CONNECTION_FIELD = new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER_LEVEL)
.withClassName(ENTITY_PLAYER_CLASS)
.withFieldName((Utils.BUKKIT_VERSION > 16) ? "b" : "playerConnection"));
public static final TypeCache.BaseCache<Field> NETWORK_MANAGER_FIELD = new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(PLAYER_CONNECTION_CLASS)
.withFieldName((Utils.BUKKIT_VERSION > 16) ? "a" : "networkManager")
.withExpectResult(NETWORK_MANAGER_CLASS));
public static final TypeCache.BaseCache<Field> CHANNEL_FIELD = new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.SERVER_NETWORK)
.withClassName(NETWORK_MANAGER_CLASS)
.withExpectResult(Channel.class));
public static final TypeCache.BaseCache<Field> PACKET_IN_USE_ENTITY_ID_FIELD = new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayInUseEntity")
.withFieldName("a"));
public static final TypeCache.BaseCache<Field> BUKKIT_COMMAND_MAP = new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.CRAFT_BUKKIT))
.withClassName("CraftServer")
.withFieldName("commandMap"));
public static final TypeCache.BaseCache<Object> ADD_PLAYER_FIELD = (new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction")
.withClassName("ClientboundPlayerInfoUpdatePacket$a")
.withFieldName((Utils.BUKKIT_VERSION > 16) ? "a" : "ADD_PLAYER"))).asValueField();
public static final TypeCache.BaseCache<Object> UPDATE_LISTED_FIELD = (new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("ClientboundPlayerInfoUpdatePacket$a")
.withFieldName("d"))).asValueField();
public static final TypeCache.BaseCache<Object> REMOVE_PLAYER_FIELD = (new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction")
.withClassName("ClientboundPlayerInfoUpdatePacket$a")
.withFieldName((Utils.BUKKIT_VERSION > 16) ? "e" : "REMOVE_PLAYER"))).asValueField();
public static final TypeCache.BaseCache<Object> DATA_WATCHER_REGISTER_FIELD = (new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(DATA_WATCHER_REGISTRY)
.withFieldName("a"))).asValueField();
public static final TypeCache.BaseCache<Object> ENUM_TAG_VISIBILITY_NEVER_FIELD = (new TypeCache.BaseCache.FieldLoader((new TypeCache.CacheBuilder(CachePackage.MINECRAFT_SERVER))
.withCategory(CacheCategory.PACKET)
.withClassName(ENUM_TAG_VISIBILITY)
.withFieldName("b"))).asValueField();
}

@ -0,0 +1,311 @@
package io.github.znetworkw.znpcservers.cache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.UnmodifiableIterator;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public interface TypeCache {
class ClassCache {
protected static final ConcurrentMap<CacheKey, Object> CACHE = new ConcurrentHashMap<>();
public static Object find(String name, Class<?> objectClass) {
return CACHE.get(new CacheKey(name, objectClass));
}
public static void register(String name, Object object, Class<?> objectClass) {
CACHE.putIfAbsent(new CacheKey(name, objectClass), object);
}
private static class CacheKey {
private final Class<?> type;
private final String value;
public CacheKey(String value, Class<?> type) {
this.type = type;
this.value = value;
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
CacheKey classKey = (CacheKey) o;
return (Objects.equals(this.type, classKey.type) && Objects.equals(this.value, classKey.value));
}
public int hashCode() {
return Objects.hash(this.type, this.value);
}
}
}
class CacheBuilder {
private static final String EMPTY_STRING = "";
private final CachePackage cachePackage;
private final CacheCategory cacheCategory;
private final String fieldName;
private final List<String> className;
private final List<String> methods;
private final String additionalData;
private final Class<?> clazz;
private final ImmutableList<Class<?>[]> parameterTypes;
private final Class<?> expectType;
public CacheBuilder(CachePackage cachePackage) {
this(cachePackage, CacheCategory.DEFAULT, new ArrayList<>(), "", new ArrayList<>(), "",
ImmutableList.of(), null);
}
protected CacheBuilder(CachePackage cachePackage, CacheCategory cacheCategory, List<String> className, String fieldName, List<String> methods, String additionalData, ImmutableList<Class<?>[]> parameterTypes, Class<?> expectType) {
this.cachePackage = cachePackage;
this.cacheCategory = cacheCategory;
this.className = className;
this.methods = methods;
this.fieldName = fieldName;
this.additionalData = additionalData;
this.parameterTypes = parameterTypes;
this.clazz = null;
this.expectType = expectType;
}
public CacheBuilder withCategory(CacheCategory cacheCategory) {
return new CacheBuilder(this.cachePackage, cacheCategory, this.className, this.fieldName, this.methods, this.additionalData, this.parameterTypes, this.expectType);
}
public CacheBuilder withClassName(String className) {
return new CacheBuilder(this.cachePackage, this.cacheCategory,
(List<String>) ImmutableList.builder().addAll(this.className)
.add(formatClass(className)).build(), this.fieldName, this.methods, this.additionalData, this.parameterTypes, this.expectType);
}
public CacheBuilder withClassName(Class<?> clazz) {
return new CacheBuilder(this.cachePackage, this.cacheCategory,
(List<String>) ImmutableList.builder().addAll(this.className).add((clazz == null) ? "" : clazz.getName()).build(), this.fieldName, this.methods, this.additionalData, this.parameterTypes, this.expectType);
}
public CacheBuilder withMethodName(String methodName) {
return new CacheBuilder(this.cachePackage, this.cacheCategory, this.className, this.fieldName,
(List<String>) ImmutableList.builder().addAll(this.methods).add(methodName).build(), this.additionalData, this.parameterTypes, this.expectType);
}
public CacheBuilder withFieldName(String fieldName) {
return new CacheBuilder(this.cachePackage, this.cacheCategory, this.className, fieldName, this.methods, this.additionalData, this.parameterTypes, this.expectType);
}
public CacheBuilder withAdditionalData(String additionalData) {
return new CacheBuilder(this.cachePackage, this.cacheCategory, this.className, this.fieldName, this.methods, additionalData, this.parameterTypes, this.expectType);
}
public CacheBuilder withParameterTypes(Class<?>... types) {
return new CacheBuilder(this.cachePackage, this.cacheCategory, this.className, this.fieldName, this.methods, this.additionalData,
ImmutableList.copyOf(Iterables.concat((Iterable) this.parameterTypes, (Iterable) ImmutableList.of(types))), this.expectType);
}
public CacheBuilder withExpectResult(Class<?> expectType) {
return new CacheBuilder(this.cachePackage, this.cacheCategory, this.className, this.fieldName, this.methods, this.additionalData, this.parameterTypes, expectType);
}
protected String formatClass(String className) {
switch (this.cachePackage) {
case MINECRAFT_SERVER:
case CRAFT_BUKKIT:
return String.format(((this.cachePackage == CachePackage.CRAFT_BUKKIT) ?
this.cachePackage.getFixedPackageName() : this.cachePackage.getForCategory(this.cacheCategory, this.additionalData)) + ".%s", className);
case DEFAULT:
return className;
}
throw new IllegalArgumentException("Unexpected package " + this.cachePackage.name());
}
}
abstract class BaseCache<T> {
private static final Logger LOGGER = Logger.getLogger(BaseCache.class.getName());
protected final TypeCache.CacheBuilder cacheBuilder;
protected Class<?> BUILDER_CLASS;
private T cached;
private boolean loaded = false;
protected BaseCache(TypeCache.CacheBuilder cacheBuilder) {
this.cacheBuilder = cacheBuilder;
for (String classes : cacheBuilder.className) {
try {
this.BUILDER_CLASS = Class.forName(classes);
} catch (ClassNotFoundException classNotFoundException) {
}
}
}
public T load() {
if (this.loaded)
return this.cached;
try {
if (this.BUILDER_CLASS == null)
throw new IllegalStateException("can't find class for: " + this.cacheBuilder
.className);
T eval = (this.cached != null) ? this.cached : (this.cached = onLoad());
if (eval == null)
throw new NullPointerException();
} catch (Throwable throwable) {
if (throwable instanceof IllegalStateException)
log("No cache found for: " + this.cacheBuilder.className);
log("No cache found for: " + this.cacheBuilder.className + " : " + this.cacheBuilder.methods.toString());
log("Skipping cache for " + this.cacheBuilder.className);
}
this.loaded = true;
return this.cached;
}
private void log(String message) {
LOGGER.log(Level.WARNING, message);
}
protected abstract T onLoad() throws Exception;
public static class ClazzLoader extends BaseCache<Class<?>> {
public ClazzLoader(TypeCache.CacheBuilder cacheBuilder) {
super(cacheBuilder);
}
protected Class<?> onLoad() {
return this.BUILDER_CLASS;
}
}
public static class MethodLoader extends BaseCache<Method> {
public MethodLoader(TypeCache.CacheBuilder builder) {
super(builder);
}
protected Method onLoad() {
Method methodThis = null;
List<String> methods = this.cacheBuilder.methods;
boolean hasExpectedType = (this.cacheBuilder.expectType != null);
if (methods.isEmpty() && hasExpectedType)
for (Method method : this.BUILDER_CLASS.getDeclaredMethods()) {
if (method.getReturnType() == this.cacheBuilder.expectType)
return method;
}
for (String methodName : this.cacheBuilder.methods) {
try {
Method maybeGet;
if (!Iterables.isEmpty(this.cacheBuilder.parameterTypes)) {
maybeGet = this.BUILDER_CLASS.getDeclaredMethod(methodName, (Class[]) Iterables.get((Iterable) this.cacheBuilder.parameterTypes, 0));
} else {
maybeGet = this.BUILDER_CLASS.getDeclaredMethod(methodName);
}
if (this.cacheBuilder.expectType != null && this.cacheBuilder.expectType != maybeGet.getReturnType())
continue;
maybeGet.setAccessible(true);
methodThis = maybeGet;
} catch (NoSuchMethodException noSuchMethodException) {
}
}
return methodThis;
}
}
public static class FieldLoader extends BaseCache<Field> {
public FieldLoader(TypeCache.CacheBuilder cacheBuilder) {
super(cacheBuilder);
}
protected Field onLoad() throws NoSuchFieldException {
if (this.cacheBuilder.expectType != null)
for (Field field1 : this.BUILDER_CLASS.getDeclaredFields()) {
if (field1.getType() == this.cacheBuilder.expectType) {
field1.setAccessible(true);
return field1;
}
}
Field field = this.BUILDER_CLASS.getDeclaredField(this.cacheBuilder.fieldName);
field.setAccessible(true);
return field;
}
public AsValueField asValueField() {
return new AsValueField(this);
}
private static class AsValueField extends TypeCache.BaseCache<Object> {
private final TypeCache.BaseCache.FieldLoader fieldLoader;
public AsValueField(TypeCache.BaseCache.FieldLoader fieldLoader) {
super(fieldLoader.cacheBuilder);
this.fieldLoader = fieldLoader;
}
protected Object onLoad() throws IllegalAccessException, NoSuchFieldException {
Field field = this.fieldLoader.onLoad();
return field.get(null);
}
}
}
public static class ConstructorLoader extends BaseCache<Constructor<?>> {
public ConstructorLoader(TypeCache.CacheBuilder cacheBuilder) {
super(cacheBuilder);
}
protected Constructor<?> onLoad() throws NoSuchMethodException {
Constructor<?> constructor = null;
if (Iterables.size(this.cacheBuilder.parameterTypes) > 1) {
for (UnmodifiableIterator<Class<?>[]> unmodifiableIterator = this.cacheBuilder.parameterTypes.iterator(); unmodifiableIterator.hasNext(); ) {
Class<?>[] keyParameters = unmodifiableIterator.next();
try {
constructor = this.BUILDER_CLASS.getDeclaredConstructor(keyParameters);
} catch (NoSuchMethodException noSuchMethodException) {
}
}
} else {
constructor = (Iterables.size(this.cacheBuilder.parameterTypes) > 0) ? this.BUILDER_CLASS.getDeclaredConstructor((Class[]) Iterables.get((Iterable) this.cacheBuilder.parameterTypes, 0)) : this.BUILDER_CLASS.getDeclaredConstructor();
}
if (constructor != null)
constructor.setAccessible(true);
return constructor;
}
}
public static class EnumLoader extends BaseCache<Enum<?>[]> {
public EnumLoader(TypeCache.CacheBuilder cacheBuilder) {
super(cacheBuilder);
}
protected Enum<?>[] onLoad() {
Enum[] arrayOfEnum = (Enum[]) this.BUILDER_CLASS.getEnumConstants();
for (Enum<?> enumConstant : arrayOfEnum)
TypeCache.ClassCache.register(enumConstant.name(), enumConstant, this.BUILDER_CLASS);
return (Enum<?>[]) arrayOfEnum;
}
}
}
}

@ -0,0 +1,89 @@
package io.github.znetworkw.znpcservers.commands;
import com.google.common.collect.Iterables;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import java.lang.reflect.Method;
import java.util.*;
public class Command extends BukkitCommand {
private static final String WHITESPACE = " ";
private static final CommandMap COMMAND_MAP;
static {
try {
COMMAND_MAP = (CommandMap) CacheRegistry.BUKKIT_COMMAND_MAP.load().get(Bukkit.getServer());
} catch (IllegalAccessException exception) {
throw new IllegalStateException("can't access bukkit command map.");
}
}
private final Map<CommandInformation, CommandInvoker> subCommands;
public Command(String name) {
super(name);
this.subCommands = new HashMap<>();
load();
}
private void load() {
COMMAND_MAP.register(getName(), this);
for (Method method : getClass().getMethods()) {
if (method.isAnnotationPresent(CommandInformation.class)) {
CommandInformation cmdInfo = method.getAnnotation(CommandInformation.class);
this.subCommands.put(cmdInfo, new CommandInvoker(this, method, cmdInfo.permission()));
}
}
}
private Map<String, String> loadArgs(CommandInformation subCommand, Iterable<String> args) {
int size = Iterables.size(args);
int subCommandsSize = (subCommand.arguments()).length;
Map<String, String> argsMap = new HashMap<>();
if (size > 1)
if (subCommand.isMultiple()) {
argsMap.put(Iterables.get(args, 1), String.join(" ", Iterables.skip(args, 2)));
} else {
for (int i = 0; i < Math.min(subCommandsSize, size); i++) {
int fixedLength = i + 1;
if (size > fixedLength) {
String input = Iterables.get(args, fixedLength);
if (fixedLength == subCommandsSize)
input = String.join(" ", Iterables.skip(args, subCommandsSize));
argsMap.put(subCommand.arguments()[i], input);
}
}
}
return argsMap;
}
public Set<CommandInformation> getCommands() {
return this.subCommands.keySet();
}
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
Optional<Map.Entry<CommandInformation, CommandInvoker>> subCommandOptional = this.subCommands.entrySet().stream().filter(command -> command.getKey().name().contentEquals((args.length > 0) ? args[0] : "")).findFirst();
if (!subCommandOptional.isPresent()) {
sender.sendMessage(ChatColor.RED + "can't find command: " + commandLabel + ".");
return false;
}
try {
Map.Entry<CommandInformation, CommandInvoker> subCommand = subCommandOptional.get();
((CommandInvoker) subCommand.getValue()).execute(new CommandSender(sender),
loadArgs(subCommand.getKey(), Arrays.asList(args)));
} catch (CommandExecuteException e) {
sender.sendMessage(ChatColor.RED + "can't execute command.");
e.printStackTrace();
} catch (CommandPermissionException e) {
sender.sendMessage(ChatColor.RED + "no permission for run this command.");
}
return true;
}
}

@ -0,0 +1,7 @@
package io.github.znetworkw.znpcservers.commands;
public class CommandExecuteException extends Exception {
public CommandExecuteException(String message, Throwable cause) {
super(message, cause);
}
}

@ -0,0 +1,18 @@
package io.github.znetworkw.znpcservers.commands;
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CommandInformation {
String[] arguments();
String[] help() default {};
String name();
String permission();
boolean isMultiple() default false;
}

@ -0,0 +1,27 @@
package io.github.znetworkw.znpcservers.commands;
import java.lang.reflect.Method;
public class CommandInvoker {
private final Command command;
private final Method commandMethod;
private final String permission;
public CommandInvoker(Command command, Method commandMethod, String permission) {
this.command = command;
this.commandMethod = commandMethod;
this.permission = permission;
}
public void execute(CommandSender sender, Object command) throws CommandPermissionException, CommandExecuteException {
if (this.permission.length() > 0 && !sender.getCommandSender().hasPermission(this.permission))
throw new CommandPermissionException("Insufficient permission.");
try {
this.commandMethod.invoke(this.command, sender, command);
} catch (IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
throw new CommandExecuteException(e.getMessage(), e.getCause());
}
}
}

@ -0,0 +1,7 @@
package io.github.znetworkw.znpcservers.commands;
public class CommandNotFoundException extends Exception {
public CommandNotFoundException(String message) {
super(message);
}
}

@ -0,0 +1,7 @@
package io.github.znetworkw.znpcservers.commands;
public class CommandPermissionException extends Exception {
public CommandPermissionException(String message) {
super(message);
}
}

@ -0,0 +1,64 @@
package io.github.znetworkw.znpcservers.commands;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import io.github.znetworkw.znpcservers.utility.Utils;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.stream.Collectors;
public class CommandSender {
static final Joiner LINE_SEPARATOR_JOINER = Joiner.on("\n");
private static final ImmutableList<String> HELP_PREFIX = ImmutableList.of("&6&lEXAMPLES&r:");
private final org.bukkit.command.CommandSender commandSender;
private final SenderType type;
public CommandSender(org.bukkit.command.CommandSender commandSender) {
this.commandSender = commandSender;
this.type = (commandSender instanceof Player) ? SenderType.PLAYER : SenderType.CONSOLE;
}
public void sendMessage(String message) {
sendMessage(message, null);
}
public void sendMessage(CommandInformation subCommand) {
sendMessage(" &7» &6/&eznpcs " + subCommand.name() + " " +
Arrays.stream(subCommand.arguments())
.map(s -> "<" + s + ">")
.collect(Collectors.joining(" ")),
Arrays.asList(subCommand.help()));
}
public void sendMessage(String message, Iterable<String> hover) {
TextComponent textComponent = new TextComponent(TextComponent.fromLegacyText(Utils.toColor(message)));
if (hover != null)
textComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, (new ComponentBuilder(
Utils.toColor(LINE_SEPARATOR_JOINER
.join(Iterables.concat(HELP_PREFIX, hover)))))
.create()));
getPlayer().spigot().sendMessage(textComponent);
}
public Player getPlayer() {
if (this.type != SenderType.PLAYER)
throw new IllegalStateException("sender is not a player.");
return (Player) getCommandSender();
}
public org.bukkit.command.CommandSender getCommandSender() {
return this.commandSender;
}
enum SenderType {
PLAYER, CONSOLE
}
}

@ -0,0 +1,574 @@
package io.github.znetworkw.znpcservers.commands.list;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Ints;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.commands.Command;
import io.github.znetworkw.znpcservers.commands.CommandInformation;
import io.github.znetworkw.znpcservers.commands.CommandSender;
import io.github.znetworkw.znpcservers.commands.list.inventory.ConversationGUI;
import io.github.znetworkw.znpcservers.configuration.Configuration;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.configuration.ConfigurationValue;
import io.github.znetworkw.znpcservers.npc.*;
import io.github.znetworkw.znpcservers.npc.conversation.Conversation;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.location.ZLocation;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.*;
import org.bukkit.entity.Player;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class DefaultCommand extends Command {
private static final String WHITESPACE = " ";
private static final Splitter SPACE_SPLITTER = Splitter.on(" ");
private static final Joiner SPACE_JOINER = Joiner.on(" ");
private static final SkinFunction DO_APPLY_SKIN;
static {
DO_APPLY_SKIN = ((sender, npc, skin) -> NPCSkin.forName(skin, ()));
}
public DefaultCommand() {
super("znpcs");
}
@CommandInformation(arguments = {}, name = "", permission = "")
public void defaultCommand(CommandSender sender, Map<String, String> args) {
sender.sendMessage("&6&m------------------------------------------");
sender.sendMessage("&b&lZNPCS &8» &7ZNetwork");
sender.sendMessage("&6https://www.spigotmc.org/resources/znpcs.80940");
Objects.requireNonNull(sender);
Objects.requireNonNull(sender);
getCommands().forEach(sender::sendMessage);
sender.sendMessage(ChatColor.DARK_GRAY + "Hover over the commands to see help for the command.");
sender.sendMessage("&6&m------------------------------------------");
}
@CommandInformation(arguments = {"id", "type", "name"}, name = "create", permission = "znpcs.cmd.create", help = {" &f&l* &e/znpcs create <npc_id> PLAYER Qentin"})
public void createNPC(CommandSender sender, Map<String, String> args) {
if (args.size() < 3) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
boolean foundNPC = ConfigurationConstants.NPC_LIST.stream().anyMatch(npc -> (npc.getId() == id.intValue()));
if (foundNPC) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_FOUND);
return;
}
String name = args.get("name").trim();
if (name.length() < 3 || name.length() > 16) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NAME_LENGTH);
return;
}
NPCType npcType = NPCType.valueOf(args.get("type").toUpperCase());
NPC npc = ZNPCsPlus.createNPC(id.intValue(), npcType, sender.getPlayer().getLocation(), name);
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
if (npcType == NPCType.PLAYER) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.FETCHING_SKIN, name);
DO_APPLY_SKIN.apply(sender.getPlayer(), npc, name);
}
}
@CommandInformation(arguments = {"id"}, name = "delete", permission = "znpcs.cmd.delete", help = {" &f&l* &e/znpcs delete <npc_id>"})
public void deleteNPC(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
ZNPCsPlus.deleteNPC(id.intValue());
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {}, name = "list", permission = "znpcs.cmd.list")
public void list(CommandSender sender, Map<String, String> args) {
if (ConfigurationConstants.NPC_LIST.isEmpty()) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NO_NPC_FOUND);
} else {
sender.sendMessage(ChatColor.DARK_GREEN + "NPC list:");
for (NPCModel npcModel : ConfigurationConstants.NPC_LIST) {
List<BaseComponent> parts = new ArrayList<>();
String message = "- " + npcModel.getId() + " " + npcModel.getHologramLines().toString() + " (" + npcModel.getLocation().getWorldName() + " " + (int) npcModel.getLocation().getX() + " " + (int) npcModel.getLocation().getY() + " " + (int) npcModel.getLocation().getZ() + ") ";
TextComponent textComponent = new TextComponent(message);
textComponent.setColor(ChatColor.GREEN);
parts.add(textComponent);
TextComponent textComponent2 = new TextComponent("[TELEPORT]");
textComponent2.setBold(Boolean.valueOf(true));
textComponent2.setColor(ChatColor.DARK_GREEN);
textComponent2.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, (new ComponentBuilder("Click to teleport this npc!"))
.color(ChatColor.GREEN).create()));
textComponent2.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/znpcs teleport " + npcModel
.getId()));
parts.add(textComponent2);
parts.add(new TextComponent(" "));
TextComponent textComponent3 = new TextComponent("[DELETE]");
textComponent3.setBold(Boolean.valueOf(true));
textComponent3.setColor(ChatColor.DARK_RED);
textComponent3.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, (new ComponentBuilder("Click to delete this npc!"))
.color(ChatColor.RED).create()));
textComponent3.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/znpcs delete " + npcModel
.getId()));
parts.add(textComponent3);
sender.getPlayer().spigot().sendMessage(parts.toArray(new BaseComponent[0]));
}
}
}
@CommandInformation(arguments = {"id", "skin"}, name = "skin", permission = "znpcs.cmd.skin", help = {" &f&l* &e/znpcs skin <npc_id> Notch"})
public void setSkin(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
String skin = args.get("skin");
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.FETCHING_SKIN, skin);
DO_APPLY_SKIN.apply(sender.getPlayer(), foundNPC, args.get("skin"));
}
@CommandInformation(arguments = {"id", "slot"}, name = "equip", permission = "znpcs.cmd.equip", help = {" &f&l* &e/znpcs equip <npc_id> [HAND,OFFHAND,HELMET,CHESTPLATE,LEGGINGS,BOOTS]", "&8(You need to have the item in your hand.)"})
public void equip(CommandSender sender, Map<String, String> args) {
if (args.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
foundNPC.getNpcPojo().getNpcEquip().put(
ItemSlot.valueOf(args.get("slot").toUpperCase()), sender
.getPlayer().getInventory().getItemInHand());
foundNPC.getPackets().flushCache("equipPackets");
Objects.requireNonNull(foundNPC);
Objects.requireNonNull(foundNPC);
foundNPC.getViewers().forEach(foundNPC::sendEquipPackets);
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {"id", "lines"}, name = "lines", permission = "znpcs.cmd.lines", help = {" &f&l* &e/znpcs lines <npc_id> First Second Third-Space"})
public void changeLines(CommandSender sender, Map<String, String> args) {
if (args.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
foundNPC.getNpcPojo().setHologramLines(Lists.reverse(SPACE_SPLITTER.splitToList(args.get("lines"))));
foundNPC.getHologram().createHologram();
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {"id"}, name = "move", permission = "znpcs.cmd.move", help = {" &f&l* &e/znpcs move <npc_id>"})
public void move(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
foundNPC.getNpcPojo().setLocation(new ZLocation(sender.getPlayer().getLocation()));
foundNPC.changeType(foundNPC.getNpcPojo().getNpcType());
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {"id", "type"}, name = "type", permission = "znpcs.cmd.type", help = {" &f&l* &e/znpcs type <npc_id> ZOMBIE"})
public void changeType(CommandSender sender, Map<String, String> args) {
if (args.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
NPCType npcType = NPCType.valueOf(args.get("type").toUpperCase());
if (npcType != NPCType.PLAYER && npcType.getConstructor() == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.UNSUPPORTED_ENTITY);
return;
}
foundNPC.changeType(npcType);
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {"add", "remove", "cooldown", "list"}, name = "action", isMultiple = true, permission = "znpcs.cmd.action", help = {" &f&l* &e/znpcs action add <npc_id> SERVER skywars", " &f&l* &e/znpcs action add <npc_id> CMD spawn", " &f&l* &e/znpcs action remove <npc_id> <action_id>", " &f&l* &e/znpcs action cooldown <npc_id> <action_id> <delay_in_seconds>", " &f&l* &e/znpcs action list <npc_id>"})
public void action(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
if (args.containsKey("add")) {
List<String> split = SPACE_SPLITTER.splitToList(args.get("add"));
if (split.size() < 3) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.ACTION_ADD_INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(split.get(0));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
foundNPC.getNpcPojo().getClickActions().add(new NPCAction(split.get(1).toUpperCase(), SPACE_JOINER.join(Iterables.skip(split, 2))));
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
} else if (args.containsKey("remove")) {
List<String> split = SPACE_SPLITTER.splitToList(args.get("remove"));
Integer id = Ints.tryParse(split.get(0));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
Integer actionId = Ints.tryParse(split.get(1));
if (actionId == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
} else {
if (actionId.intValue() >= foundNPC.getNpcPojo().getClickActions().size()) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NO_ACTION_FOUND);
return;
}
foundNPC.getNpcPojo().getClickActions().remove(actionId.intValue());
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
} else if (args.containsKey("cooldown")) {
List<String> split = SPACE_SPLITTER.splitToList(args.get("cooldown"));
if (split.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.ACTION_DELAY_INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(split.get(0));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
Integer actionId = Ints.tryParse(split.get(1));
Integer actionDelay = Ints.tryParse(split.get(2));
if (actionId == null || id == null || actionDelay == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
} else {
if (actionId.intValue() >= foundNPC.getNpcPojo().getClickActions().size()) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NO_ACTION_FOUND);
return;
}
foundNPC.getNpcPojo().getClickActions().get(actionId.intValue()).setDelay(actionDelay.intValue());
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
} else if (args.containsKey("list")) {
Integer id = Ints.tryParse(args.get("list"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
if (foundNPC.getNpcPojo().getClickActions().isEmpty()) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NO_ACTION_FOUND);
} else {
foundNPC.getNpcPojo().getClickActions().forEach(s -> sender.sendMessage("&8(&a" + foundNPC.getNpcPojo().getClickActions().indexOf(s) + "&8) &6" + s.toString()));
}
}
}
@CommandInformation(arguments = {"id", "type", "value"}, name = "toggle", permission = "znpcs.cmd.toggle", help = {" &f&l* &e/znpcs toggle <npc_id> look"})
public void toggle(CommandSender sender, Map<String, String> args) {
if (args.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
NPCFunction npcFunction = FunctionFactory.findFunctionForName(args.get("type"));
if (npcFunction.getName().equalsIgnoreCase("glow")) {
npcFunction.doRunFunction(foundNPC, new FunctionContext.ContextWithValue(foundNPC, args.get("value")));
} else {
npcFunction.doRunFunction(foundNPC, new FunctionContext.DefaultContext(foundNPC));
}
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {"id", "customizeValues"}, name = "customize", permission = "znpcs.cmd.customize", help = {" &f&l* &e/znpcs customize <npc_id> <customization>"})
public void customize(CommandSender sender, Map<String, String> args) {
if (args.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
NPCType npcType = foundNPC.getNpcPojo().getNpcType();
List<String> customizeOptions = SPACE_SPLITTER.splitToList(args.get("customizeValues"));
String methodName = customizeOptions.get(0);
if (npcType.getCustomizationLoader().contains(methodName)) {
Method method = npcType.getCustomizationLoader().getMethods().get(methodName);
Iterable<String> split = Iterables.skip(customizeOptions, 1);
if (Iterables.size(split) < (method.getParameterTypes()).length) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.TOO_FEW_ARGUMENTS);
return;
}
String[] values = Iterables.toArray(split, String.class);
npcType.updateCustomization(foundNPC, methodName, values);
foundNPC.getNpcPojo().getCustomizationMap().put(methodName, values);
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
} else {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.METHOD_NOT_FOUND);
for (Map.Entry<String, Method> method : npcType.getCustomizationLoader().getMethods().entrySet())
sender.sendMessage(ChatColor.YELLOW + method.getKey() + " " + SPACE_JOINER.join(method.getValue().getParameterTypes()));
}
}
@CommandInformation(arguments = {"set", "create", "exit", "path", "list"}, name = "path", isMultiple = true, permission = "znpcs.cmd.path", help = {" &f&l* &e/znpcs path create name", " &f&l* &e/znpcs path set <npc_id> name"})
public void path(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
ZUser znpcUser = ZUser.find(sender.getPlayer());
if (znpcUser == null)
return;
if (args.containsKey("set")) {
List<String> split = SPACE_SPLITTER.splitToList(args.get("set"));
if (split.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.PATH_SET_INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(split.get(0));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
foundNPC.setPath(NPCPath.AbstractTypeWriter.find(split.get(1)));
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
} else if (args.containsKey("create")) {
String pathName = args.get("create");
if (pathName.length() < 3 || pathName.length() > 16) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NAME_LENGTH);
return;
}
if (NPCPath.AbstractTypeWriter.find(pathName) != null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.PATH_FOUND);
return;
}
if (znpcUser.isHasPath()) {
sender.getPlayer().sendMessage(ChatColor.RED + "You already have a path creator active, to remove it use /znpcs path exit.");
return;
}
NPCPath.AbstractTypeWriter.forCreation(pathName, znpcUser, NPCPath.AbstractTypeWriter.TypeWriter.MOVEMENT);
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.PATH_START);
} else if (args.containsKey("exit")) {
znpcUser.setHasPath(false);
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.EXIT_PATH);
} else if (args.containsKey("list")) {
if (NPCPath.AbstractTypeWriter.getPaths().isEmpty()) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NO_PATH_FOUND);
} else {
NPCPath.AbstractTypeWriter.getPaths().forEach(path -> sender.getPlayer().sendMessage(ChatColor.GREEN + path.getName()));
}
}
}
@CommandInformation(arguments = {"id"}, name = "teleport", permission = "znpcs.cmd.teleport", help = {" &f&l* &e/znpcs teleport <npc_id>"})
public void teleport(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
sender.getPlayer().teleport(foundNPC.getLocation());
}
@CommandInformation(arguments = {"id", "height"}, name = "height", permission = "znpcs.cmd.height", help = {" &f&l* &e/znpcs height <npc_id> 2", "&8Add more height to the hologram of the npc"})
public void changeHologramHeight(CommandSender sender, Map<String, String> args) {
if (args.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(args.get("id"));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
Double givenHeight = Doubles.tryParse(args.get("height"));
if (givenHeight == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
foundNPC.getNpcPojo().setHologramHeight(givenHeight.doubleValue());
foundNPC.getHologram().createHologram();
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
@CommandInformation(arguments = {"create", "remove", "gui", "set"}, name = "conversation", isMultiple = true, permission = "znpcs.cmd.conversation", help = {" &f&l* &e/znpcs conversation create first", " &f&l* &e/znpcs conversation remove first", " &f&l* &e/znpcs conversation set <npc_id> first [CLICK:RADIUS]", " &f&l* &e/znpcs conversation gui &8(&7Open a gui to manage the conversations&8)", "&8RADIUS: &7it is activated when the player is near the npc", "&8CLICK: &7it is activated when the player interacts with the npc"})
public void conversations(CommandSender sender, Map<String, String> args) {
if (args.size() < 1) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INCORRECT_USAGE);
return;
}
if (args.containsKey("create")) {
String conversationName = args.get("create");
if (Conversation.exists(conversationName)) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.CONVERSATION_FOUND);
return;
}
if (conversationName.length() < 3 || conversationName.length() > 16) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NAME_LENGTH);
return;
}
ConfigurationConstants.NPC_CONVERSATIONS.add(new Conversation(conversationName));
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
} else if (args.containsKey("remove")) {
String conversationName = args.get("remove");
if (!Conversation.exists(conversationName)) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NO_CONVERSATION_FOUND);
return;
}
ConfigurationConstants.NPC_CONVERSATIONS.remove(Conversation.forName(conversationName));
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
} else if (args.containsKey("gui")) {
sender.getPlayer().openInventory((new ConversationGUI(sender.getPlayer())).build());
} else if (args.containsKey("set")) {
List<String> split = SPACE_SPLITTER.splitToList(args.get("set"));
if (split.size() < 2) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.CONVERSATION_SET_INCORRECT_USAGE);
return;
}
Integer id = Ints.tryParse(split.get(0));
if (id == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.INVALID_NUMBER);
return;
}
NPC foundNPC = NPC.find(id.intValue());
if (foundNPC == null) {
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.NPC_NOT_FOUND);
return;
}
String conversationName = split.get(1);
if (Conversation.exists(conversationName)) {
foundNPC.getNpcPojo().setConversation(new ConversationModel(conversationName, (split.size() > 1) ? split.get(2) : "CLICK"));
} else {
foundNPC.getNpcPojo().setConversation(null);
}
Configuration.MESSAGES.sendMessage(sender.getCommandSender(), ConfigurationValue.SUCCESS);
}
}
interface SkinFunction {
void apply(Player param1Player, NPC param1NPC, String param1String);
}
}

@ -0,0 +1,127 @@
package io.github.znetworkw.znpcservers.commands.list.inventory;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import io.github.znetworkw.znpcservers.configuration.Configuration;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.configuration.ConfigurationValue;
import io.github.znetworkw.znpcservers.npc.NPCAction;
import io.github.znetworkw.znpcservers.npc.conversation.Conversation;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationKey;
import io.github.znetworkw.znpcservers.user.EventService;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils;
import io.github.znetworkw.znpcservers.utility.inventory.ZInventory;
import io.github.znetworkw.znpcservers.utility.inventory.ZInventoryPage;
import io.github.znetworkw.znpcservers.utility.itemstack.ItemStackBuilder;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.player.AsyncPlayerChatEvent;
public class ConversationGUI extends ZInventory {
private static final String WHITESPACE = " ";
private static final Splitter SPACE_SPLITTER = Splitter.on(" ");
private static final Joiner SPACE_JOINER = Joiner.on(" ");
public ConversationGUI(Player player) {
super(player);
setCurrentPage(new MainPage(this));
}
static class MainPage extends ZInventoryPage {
public MainPage(ZInventory inventory) {
super(inventory, "Conversations", 5);
}
public void update() {
for (int i = 0; i < ConfigurationConstants.NPC_CONVERSATIONS.size(); i++) {
Conversation conversation = ConfigurationConstants.NPC_CONVERSATIONS.get(i);
addItem(ItemStackBuilder.forMaterial(Material.PAPER).setName(ChatColor.GREEN + conversation.getName()).setLore(new String[]{"&7this conversation has &b" + conversation.getTexts().size() + " &7texts,", "&7it will activate when a player is on a &b" + conversation.getRadius() + "x" + conversation.getRadius() + " &7radius,", "&7or when a player interacts with an npc.", "&7when the conversation is finish, there is a &b" + conversation.getDelay() + "s &7delay to start again.", "&f&lUSES", " &bLeft-click &7to manage texts.", " &bRight-click &7to add a new text.", " &bQ &7to change the radius.", " &bMiddle-click &7to change the cooldown."}, ).build(), i, clickEvent -> {
if (clickEvent.getClick() == ClickType.DROP) {
Utils.sendTitle(getPlayer(), "&b&lCHANGE RADIUS", "&7Type the new radius...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
} else if (clickEvent.isRightClick()) {
Utils.sendTitle(getPlayer(), "&e&lADD LINE", "&7Type the new line...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
} else if (clickEvent.isLeftClick()) {
(new EditConversationPage(getInventory(), conversation)).openInventory();
} else if (clickEvent.getClick() == ClickType.MIDDLE) {
Utils.sendTitle(getPlayer(), "&6&lCHANGE COOLDOWN", "&7Type the new cooldown...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
}
});
}
}
static class EditConversationPage extends ZInventoryPage {
private final Conversation conversation;
public EditConversationPage(ZInventory inventory, Conversation conversation) {
super(inventory, "Editing conversation " + conversation.getName(), 5);
this.conversation = conversation;
}
public void update() {
for (int i = 0; i < this.conversation.getTexts().size(); i++) {
ConversationKey conversationKey = this.conversation.getTexts().get(i);
addItem(ItemStackBuilder.forMaterial(Material.NAME_TAG).setName(ChatColor.AQUA + conversationKey.getTextFormatted() + "....").setLore(new String[]{
"&7this conversation text has a delay of &b" + conversationKey.getDelay() + "s &7to be executed,", "&7the sound for the text is &b" + ((conversationKey.getSoundName() == null) ? "NONE" : conversationKey.getSoundName()) + "&7,", "&7before sending the text there is a delay of &b" + conversationKey.getDelay() + "s", "&7the index for the text is &b" + i + "&7,", "&7and the conversation has currently &b" + conversationKey.getActions().size() + " actions&7.", "&f&lUSES", " &bLeft-click &7to change the position.", " &bRight-click &7to remove text.", " &bLeft-Shift-click &7to change the sound.", " &bMiddle-click &7to change the delay.",
" &bRight-Shift-click &7to edit the text.", " &bQ &7to manage actions."}, ).build(), i, clickEvent -> {
if (clickEvent.getClick() == ClickType.SHIFT_LEFT) {
Utils.sendTitle(getPlayer(), "&c&lCHANGE SOUND", "&7Type the new sound...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
} else if (clickEvent.getClick() == ClickType.SHIFT_RIGHT) {
Utils.sendTitle(getPlayer(), "&a&lEDIT TEXT", "&7Type the new text...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
} else if (clickEvent.isLeftClick()) {
Utils.sendTitle(getPlayer(), "&e&lCHANGE POSITION &a>=0&c<=" + this.conversation.getTexts().size(), "&7Type the new position...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
} else if (clickEvent.isRightClick()) {
this.conversation.getTexts().remove(conversationKey);
Configuration.MESSAGES.sendMessage(getPlayer(), ConfigurationValue.SUCCESS);
openInventory();
} else if (clickEvent.getClick() == ClickType.MIDDLE) {
Utils.sendTitle(getPlayer(), "&d&lCHANGE DELAY", "&7Type the new delay...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
} else if (clickEvent.getClick() == ClickType.DROP) {
(new ConversationGUI.MainPage.ActionManagementPage(getInventory(), this.conversation, conversationKey)).openInventory();
}
});
}
}
}
static class ActionManagementPage extends ZInventoryPage {
private final Conversation conversation;
private final ConversationKey conversationKey;
public ActionManagementPage(ZInventory inventory, Conversation conversation, ConversationKey conversationKey) {
super(inventory, "Editing " + conversationKey.getTextFormatted(), 5);
this.conversation = conversation;
this.conversationKey = conversationKey;
}
public void update() {
for (int i = 0; i < this.conversationKey.getActions().size(); i++) {
NPCAction znpcAction = this.conversationKey.getActions().get(i);
addItem(ItemStackBuilder.forMaterial(Material.ANVIL).setName(ChatColor.AQUA + znpcAction.getAction().substring(0, Math.min(znpcAction.getAction().length(), 24)) + "....").setLore("&7this action type is &b" + znpcAction.getActionType(), "&f&lUSES", " &bRight-click &7to remove text.").build(), i, clickEvent -> {
if (clickEvent.isRightClick()) {
this.conversationKey.getActions().remove(znpcAction);
Configuration.MESSAGES.sendMessage(getPlayer(), ConfigurationValue.SUCCESS);
openInventory();
}
});
}
addItem(ItemStackBuilder.forMaterial(Material.EMERALD).setName(ChatColor.AQUA + "ADD A NEW ACTION").setLore(new String[]{"&7click here..."}, ).build(), getRows() - 5, clickEvent -> {
Utils.sendTitle(getPlayer(), "&d&lADD ACTION", "&7Type the action...");
EventService.addService(ZUser.find(getPlayer()), AsyncPlayerChatEvent.class).addConsumer(()).addConsumer(());
});
}
}
}
}

@ -0,0 +1,127 @@
package io.github.znetworkw.znpcservers.configuration;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.command.CommandSender;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Map;
import java.util.stream.Collectors;
public class Configuration {
public static final Configuration CONFIGURATION = new Configuration("config");
public static final Configuration MESSAGES = new Configuration("messages");
public static final Configuration CONVERSATIONS = new Configuration("conversations");
public static final Configuration DATA = new Configuration("data");
public static final ImmutableList<Configuration> SAVE_CONFIGURATIONS = ImmutableList.of(CONVERSATIONS, DATA);
static final String CONFIG_FORMAT = ".json";
private static final JsonParser JSON_PARSER = new JsonParser();
private static final Charset CHARSET = StandardCharsets.UTF_8;
private final String name;
private final Path path;
private final Map<ConfigurationValue, Object> configurationValues;
protected Configuration(String name) {
this(name, ZNPCsPlus.PLUGIN_FOLDER.toPath().resolve(name + ".json"));
}
private Configuration(String name, Path path) {
if (!path.getFileName().toString().endsWith(".json"))
throw new IllegalStateException("invalid configuration format for: " + path.getFileName());
this.name = name;
this.path = path;
this
.configurationValues = (Map<ConfigurationValue, Object>) ((ImmutableSet) ConfigurationValue.VALUES_BY_NAME.get(name)).stream().collect(Collectors.toMap(c -> c, ConfigurationValue::getValue));
onLoad();
}
protected void onLoad() {
synchronized (this.path) {
try {
Reader reader = Files.newBufferedReader(this.path, CHARSET);
try {
JsonElement data = JSON_PARSER.parse(reader);
if (data == null) {
if (reader != null)
reader.close();
return;
}
for (ConfigurationValue configValue : this.configurationValues.keySet()) {
boolean single = (this.configurationValues.size() == 1);
JsonElement jsonElement = single ? data : (data.isJsonObject() ? data.getAsJsonObject().get(configValue.name()) : null);
if (jsonElement != null && !jsonElement.isJsonNull()) {
if (!single && configValue.getPrimitiveType().isEnum()) {
this.configurationValues.put(configValue, ZNPCsPlus.GSON.fromJson(jsonElement, configValue.getPrimitiveType()));
continue;
}
this.configurationValues.put(configValue, ZNPCsPlus.GSON.fromJson(jsonElement,.Gson.Types.newParameterizedTypeWithOwner(null, configValue.getValue().getClass(), new Type[]{configValue.getPrimitiveType()})))
}
}
if (reader != null)
reader.close();
} catch (Throwable throwable) {
if (reader != null)
try {
reader.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (NoSuchFileException noSuchFileException) {
} catch (IOException e) {
throw new IllegalStateException("Failed to read config: " + this.name);
} finally {
save();
}
}
}
public void save() {
synchronized (this.path) {
try {
Writer writer = Files.newBufferedWriter(this.path, CHARSET);
try {
ZNPCsPlus.GSON.toJson((this.configurationValues.size() == 1) ?
this.configurationValues.values().iterator().next() : this.configurationValues, writer);
if (writer != null)
writer.close();
} catch (Throwable throwable) {
if (writer != null)
try {
writer.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (IOException e) {
throw new IllegalStateException("Failed to save config: " + this.name);
}
}
}
public <T> T getValue(ConfigurationValue configValue) {
synchronized (this.path) {
return (T) this.configurationValues.get(configValue);
}
}
public void sendMessage(CommandSender sender, ConfigurationValue configValue, Object... replaces) {
sender.sendMessage(Utils.toColor(String.format(getValue(configValue), replaces)));
}
}

@ -0,0 +1,26 @@
package io.github.znetworkw.znpcservers.configuration;
import io.github.znetworkw.znpcservers.npc.NPCModel;
import io.github.znetworkw.znpcservers.npc.conversation.Conversation;
import java.util.List;
public final class ConfigurationConstants {
public static final String SPACE_SYMBOL = Configuration.CONFIGURATION.getValue(ConfigurationValue.REPLACE_SYMBOL);
public static final int VIEW_DISTANCE = Configuration.CONFIGURATION.<Integer>getValue(ConfigurationValue.VIEW_DISTANCE).intValue();
public static final int SAVE_DELAY = Configuration.CONFIGURATION.<Integer>getValue(ConfigurationValue.SAVE_NPCS_DELAY_SECONDS).intValue();
public static final boolean RGB_ANIMATION = Configuration.CONFIGURATION.<Boolean>getValue(ConfigurationValue.ANIMATION_RGB).booleanValue();
public static final List<NPCModel> NPC_LIST = Configuration.DATA.getValue(ConfigurationValue.NPC_LIST);
public static final List<Conversation> NPC_CONVERSATIONS = Configuration.CONVERSATIONS.getValue(ConfigurationValue.CONVERSATION_LIST);
static {
NPC_LIST.stream()
.map(io.github.znetworkw.znpcservers.npc.NPC::new)
.forEach(io.github.znetworkw.znpcservers.npc.task.NPCLoadTask::new);
}
}

@ -0,0 +1,82 @@
package io.github.znetworkw.znpcservers.configuration;
import com.google.common.collect.ImmutableSet;
import io.github.znetworkw.znpcservers.npc.NPCModel;
import io.github.znetworkw.znpcservers.npc.NamingType;
import io.github.znetworkw.znpcservers.npc.conversation.Conversation;
import io.github.znetworkw.znpcservers.utility.GuavaCollectors;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public enum ConfigurationValue {
NPC_LIST("data", new ArrayList(), NPCModel.class),
VIEW_DISTANCE("config", Integer.valueOf(32), Integer.class),
REPLACE_SYMBOL("config", "-", String.class),
SAVE_NPCS_DELAY_SECONDS("config", Integer.valueOf(600), Integer.class),
MAX_PATH_LOCATIONS("config", Integer.valueOf(500), Integer.class),
NAMING_METHOD("config", NamingType.DEFAULT, NamingType.class),
DEBUG_ENABLED("config", Boolean.TRUE, Boolean.class),
LINE_SPACING("config", Double.valueOf(0.3D), Double.class),
ANIMATION_RGB("config", Boolean.FALSE, Boolean.class),
NO_PERMISSION("messages", "&cYou do not have permission to execute this command.", String.class),
SUCCESS("messages", "&aDone...", String.class),
INCORRECT_USAGE("messages", "&cIncorrect use of command.", String.class),
COMMAND_NOT_FOUND("messages", "&cThis command was not found.", String.class),
COMMAND_ERROR("messages", "&cThere was an error executing the command, see the console for more information.", String.class),
INVALID_NUMBER("messages", "&cHey!, The inserted number/id does not look like a number..", String.class),
NPC_NOT_FOUND("messages", "&cHey!, I couldnt find a npc with this id.", String.class),
TOO_FEW_ARGUMENTS("messages", "&cToo few arguments.", String.class),
PATH_START("messages", "&aDone, now walk where you want the npc to, when u finish type /znpcs path exit.", String.class),
EXIT_PATH("messages", "&cYou have exited the waypoint creation.", String.class),
PATH_FOUND("messages", "&cThere is already a path with this name.", String.class),
NPC_FOUND("messages", "&cThere is already a npc with this id.", String.class),
NO_PATH_FOUND("messages", "&cNo path found.", String.class),
NO_SKIN_FOUND("messages", "&cSkin not found.", String.class),
NO_NPC_FOUND("messages", "&cNo npc found.", String.class),
NO_ACTION_FOUND("messages", "&cNo action found.", String.class),
METHOD_NOT_FOUND("messages", "&cNo method found.", String.class),
INVALID_NAME_LENGTH("messages", "&cThe name is too short or long, it must be in the range of (3 to 16) characters.", String.class),
UNSUPPORTED_ENTITY("messages", "&cEntity type not available for your current version.", String.class),
PATH_SET_INCORRECT_USAGE("messages", "&eUsage: &aset <npc_id> <path_name>", String.class),
ACTION_ADD_INCORRECT_USAGE("messages", "&eUsage: &a<SERVER:CMD:MESSAGE:CONSOLE> <actionValue>", String.class),
ACTION_DELAY_INCORRECT_USAGE("messages", "&eUsage: &a<action_id> <delay>", String.class),
CONVERSATION_SET_INCORRECT_USAGE("messages", "&cUsage: <npc_id> <conversation_name> <RADIUS:CLICK>", String.class),
NO_CONVERSATION_FOUND("messages", "&cNo conversation found.", String.class),
CONVERSATION_FOUND("messages", "&cThere is already a conversation with this name.", String.class),
INVALID_SIZE("messages", "&cThe position cannot exceed the limit.", String.class),
FETCHING_SKIN("messages", "&aFetching skin for name: &f%s&a, wait...", String.class),
CANT_GET_SKIN("messages", "&ccan't fetch skin with name: %s.", String.class),
GET_SKIN("messages", "&aSkin fetched.", String.class),
CONVERSATION_LIST("conversations", new ArrayList(), Conversation.class);
public static final Map<String, ImmutableSet<ConfigurationValue>> VALUES_BY_NAME;
static {
VALUES_BY_NAME = Arrays.stream(values()).collect(Collectors.groupingBy(ConfigurationValue::getConfigName, GuavaCollectors.toImmutableSet()));
}
private final String configName;
private final Object value;
private final Class<?> primitiveType;
ConfigurationValue(String configName, Object value, Class<?> primitiveType) {
this.configName = configName;
this.value = value;
this.primitiveType = primitiveType;
}
public String getConfigName() {
return this.configName;
}
public Object getValue() {
return this.value;
}
public Class<?> getPrimitiveType() {
return this.primitiveType;
}
}

@ -0,0 +1,31 @@
package io.github.znetworkw.znpcservers.listeners;
import io.github.znetworkw.znpcservers.utility.inventory.ZInventory;
import io.github.znetworkw.znpcservers.utility.inventory.ZInventoryHolder;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.plugin.Plugin;
public class InventoryListener implements Listener {
public InventoryListener(Plugin serversNPC) {
serversNPC.getServer().getPluginManager().registerEvents(this, serversNPC);
}
@EventHandler
public void onClick(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player))
return;
if (event.getCurrentItem() == null)
return;
if (!(event.getInventory().getHolder() instanceof ZInventoryHolder))
return;
event.setCancelled(true);
ZInventory zInventory = ((ZInventoryHolder) event.getInventory().getHolder()).getzInventory();
if (!zInventory.getPage().containsItem(event.getRawSlot()))
return;
zInventory.getPage().findItem(event.getRawSlot()).getInventoryCallback().onClick(event);
((Player) event.getWhoClicked()).updateInventory();
}
}

@ -0,0 +1,48 @@
package io.github.znetworkw.znpcservers.listeners;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.npc.event.NPCInteractEvent;
import io.github.znetworkw.znpcservers.user.EventService;
import io.github.znetworkw.znpcservers.user.ZUser;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
public class PlayerListener implements Listener {
public PlayerListener(Plugin serversNPC) {
serversNPC.getServer().getPluginManager().registerEvents(this, serversNPC);
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
ZUser.find(event.getPlayer());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
ZUser.unregister(event.getPlayer());
}
@EventHandler(ignoreCancelled = true)
public void onTalk(AsyncPlayerChatEvent event) {
ZUser zUser = ZUser.find(event.getPlayer());
if (EventService.hasService(zUser, AsyncPlayerChatEvent.class)) {
event.setCancelled(true);
EventService<AsyncPlayerChatEvent> eventService = EventService.findService(zUser, AsyncPlayerChatEvent.class);
eventService.runAll(event);
zUser.getEventServices().remove(eventService);
}
}
@EventHandler
public void onConversation(NPCInteractEvent event) {
ConversationModel conversationStorage = event.getNpc().getNpcPojo().getConversation();
if (conversationStorage == null || conversationStorage
.getConversationType() != ConversationModel.ConversationType.CLICK)
return;
event.getNpc().tryStartConversation(event.getPlayer());
}
}

@ -0,0 +1,51 @@
package io.github.znetworkw.znpcservers.npc;
import com.google.common.collect.Iterables;
import io.github.znetworkw.znpcservers.cache.CachePackage;
import io.github.znetworkw.znpcservers.cache.TypeCache;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class CustomizationLoader {
private final Class<? extends Entity> entityClass;
private final Map<String, Method> methods;
public CustomizationLoader(EntityType entityType, Iterable<String> methodsName) {
this(entityType.getEntityClass(), methodsName);
}
protected CustomizationLoader(Class<? extends Entity> entityClass, Iterable<String> methodsName) {
this.entityClass = entityClass;
this.methods = loadMethods(methodsName);
}
protected Map<String, Method> loadMethods(Iterable<String> iterable) {
Map<String, Method> builder = new HashMap<>();
for (Method method : this.entityClass.getMethods()) {
if (!builder.containsKey(method.getName()) &&
Iterables.contains(iterable, method.getName())) {
for (Class<?> parameter : method.getParameterTypes()) {
TypeProperty typeProperty = TypeProperty.forType(parameter);
if (typeProperty == null && parameter.isEnum())
(new TypeCache.BaseCache.EnumLoader((new TypeCache.CacheBuilder(CachePackage.DEFAULT))
.withClassName(parameter.getTypeName()))).load();
}
builder.put(method.getName(), method);
}
}
return builder;
}
public boolean contains(String name) {
return this.methods.containsKey(name);
}
public Map<String, Method> getMethods() {
return this.methods;
}
}

@ -0,0 +1,34 @@
package io.github.znetworkw.znpcservers.npc;
public interface FunctionContext {
NPC getNPC();
interface WithValue extends FunctionContext {
String getValue();
}
class DefaultContext implements FunctionContext {
private final NPC npc;
public DefaultContext(NPC npc) {
this.npc = npc;
}
public NPC getNPC() {
return this.npc;
}
}
class ContextWithValue extends DefaultContext implements WithValue {
private final String value;
public ContextWithValue(NPC npc, String value) {
super(npc);
this.value = value;
}
public String getValue() {
return this.value;
}
}
}

@ -0,0 +1,41 @@
package io.github.znetworkw.znpcservers.npc;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.github.znetworkw.znpcservers.npc.function.GlowFunction;
import io.github.znetworkw.znpcservers.utility.GuavaCollectors;
public final class FunctionFactory {
public static ImmutableList<NPCFunction> WITHOUT_FUNCTION = ImmutableList.of(new NPCFunction.WithoutFunction("look"), new NPCFunction.WithoutFunctionSelfUpdate("holo"), new NPCFunction.WithoutFunctionSelfUpdate("mirror"));
public static ImmutableList<NPCFunction> WITH_FUNCTION = ImmutableList.of(new GlowFunction());
public static ImmutableList<NPCFunction> ALL = ImmutableList.builder()
.addAll(WITHOUT_FUNCTION)
.addAll(WITH_FUNCTION)
.build();
public static ImmutableMap<String, NPCFunction> BY_NAME;
static {
BY_NAME = ALL.stream().collect(GuavaCollectors.toImmutableMap(NPCFunction::getName, function -> function));
}
public static NPCFunction findFunctionForName(String name) {
return BY_NAME.get(name);
}
public static ImmutableList<NPCFunction> findFunctionsForNpc(NPC npc) {
return ALL.stream()
.filter(function -> isTrue(npc, function))
.collect(GuavaCollectors.toImmutableList());
}
public static boolean isTrue(NPC npc, NPCFunction function) {
return npc.getNpcPojo().getFunctions().getOrDefault(function.getName(), Boolean.FALSE).booleanValue();
}
public static boolean isTrue(NPC npc, String function) {
return isTrue(npc, findFunctionForName(function));
}
}

@ -0,0 +1,27 @@
package io.github.znetworkw.znpcservers.npc;
public enum ItemSlot {
HELMET(5),
CHESTPLATE(4),
LEGGINGS(3),
BOOTS(2),
OFFHAND(1),
HAND(0);
private final int slot;
private final int slotOld;
ItemSlot(int slot) {
this.slot = slot;
this.slotOld = (slot == 0) ? 0 : (slot - 1);
}
public int getSlot() {
return this.slot;
}
public int getSlotOld() {
return this.slotOld;
}
}

@ -0,0 +1,357 @@
package io.github.znetworkw.znpcservers.npc;
import com.google.common.collect.ImmutableList;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.UnexpectedCallException;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.npc.hologram.Hologram;
import io.github.znetworkw.znpcservers.npc.packet.PacketCache;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils;
import io.github.znetworkw.znpcservers.utility.location.ZLocation;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class NPC {
private static final ConcurrentMap<Integer, NPC> NPC_MAP = new ConcurrentHashMap<>();
private static final String PROFILE_TEXTURES = "textures";
private static final String START_PREFIX = "[ZNPC] ";
private final Set<ZUser> viewers = new HashSet<>();
private final PacketCache packets = new PacketCache();
private final NPCModel npcPojo;
private final Hologram hologram;
private final String npcName;
private final NPCSkin npcSkin;
private long lastMove = -1L;
private int entityID;
private Object glowColor;
private Object tabConstructor;
private Object updateTabConstructor;
private Object nmsEntity;
private Object bukkitEntity;
private UUID uuid;
private GameProfile gameProfile;
private NPCPath.PathInitializer npcPath;
public NPC(NPCModel npcModel, boolean load) {
this.npcPojo = npcModel;
this.hologram = new Hologram(this);
this.npcName = NamingType.DEFAULT.resolve(this);
this.npcSkin = NPCSkin.forValues(npcModel.getSkin(), npcModel.getSignature());
if (load)
onLoad();
}
public NPC(NPCModel npcModel) {
this(npcModel, false);
}
public static NPC find(int id) {
return NPC_MAP.get(Integer.valueOf(id));
}
public static void unregister(int id) {
NPC npc = find(id);
if (npc == null)
throw new IllegalStateException("can't find npc with id " + id);
NPC_MAP.remove(Integer.valueOf(id));
npc.deleteViewers();
}
public static Collection<NPC> all() {
return NPC_MAP.values();
}
public void onLoad() {
if (NPC_MAP.containsKey(Integer.valueOf(getNpcPojo().getId())))
throw new IllegalStateException("npc with id " + getNpcPojo().getId() + " already exists.");
this.gameProfile = new GameProfile(UUID.randomUUID(), "[ZNPC] " + this.npcName);
this.gameProfile.getProperties().put("textures", new Property("textures", this.npcPojo.getSkin(), this.npcPojo.getSignature()));
changeType(this.npcPojo.getNpcType());
updateProfile(this.gameProfile.getProperties());
setLocation(getNpcPojo().getLocation().bukkitLocation(), false);
this.hologram.createHologram();
if (this.npcPojo.getPathName() != null)
setPath(NPCPath.AbstractTypeWriter.find(this.npcPojo.getPathName()));
this.npcPojo.getCustomizationMap().forEach((key, value) -> this.npcPojo.getNpcType().updateCustomization(this, key, value));
NPC_MAP.put(Integer.valueOf(getNpcPojo().getId()), this);
}
public NPCModel getNpcPojo() {
return this.npcPojo;
}
public UUID getUUID() {
return this.uuid;
}
public int getEntityID() {
return this.entityID;
}
public Object getBukkitEntity() {
return this.bukkitEntity;
}
public Object getNmsEntity() {
return this.nmsEntity;
}
public Object getGlowColor() {
return this.glowColor;
}
public void setGlowColor(Object glowColor) {
this.glowColor = glowColor;
}
public GameProfile getGameProfile() {
return this.gameProfile;
}
public NPCPath.PathInitializer getNpcPath() {
return this.npcPath;
}
public Hologram getHologram() {
return this.hologram;
}
public Set<ZUser> getViewers() {
return this.viewers;
}
public PacketCache getPackets() {
return this.packets;
}
public void setLocation(Location location, boolean updateTime) {
try {
if (this.npcPath == null) {
lookAt(null, location, true);
if (updateTime)
this.lastMove = System.nanoTime();
this.npcPojo.setLocation(new ZLocation(location = new Location(location.getWorld(), location.getBlockX() + 0.5D, location.getY(), location.getBlockZ() + 0.5D, location.getYaw(), location.getPitch())));
}
CacheRegistry.SET_LOCATION_METHOD.load().invoke(this.nmsEntity, Double.valueOf(location.getX()), Double.valueOf(location.getY()), Double.valueOf(location.getZ()), Float.valueOf(location.getYaw()), Float.valueOf(location.getPitch()));
Object npcTeleportPacket = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_TELEPORT_CONSTRUCTOR.load()).newInstance(this.nmsEntity);
this.viewers.forEach(player -> Utils.sendPackets(player, npcTeleportPacket));
this.hologram.setLocation(location, this.npcPojo.getNpcType().getHoloHeight());
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public void changeSkin(NPCSkin skinFetch) {
this.npcPojo.setSkin(skinFetch.getTexture());
this.npcPojo.setSignature(skinFetch.getSignature());
this.gameProfile.getProperties().clear();
this.gameProfile.getProperties().put("textures", new Property("textures", this.npcPojo
.getSkin(), this.npcPojo.getSignature()));
updateProfile(this.gameProfile.getProperties());
deleteViewers();
}
public void setSecondLayerSkin() {
try {
Object dataWatcherObject = CacheRegistry.GET_DATA_WATCHER_METHOD.load().invoke(this.nmsEntity);
if (Utils.versionNewer(9)) {
CacheRegistry.SET_DATA_WATCHER_METHOD.load().invoke(dataWatcherObject, ((Constructor) CacheRegistry.DATA_WATCHER_OBJECT_CONSTRUCTOR
.load()).newInstance(Integer.valueOf(this.npcSkin.getLayerIndex()), CacheRegistry.DATA_WATCHER_REGISTER_FIELD
.load()), Byte.valueOf(127));
} else {
CacheRegistry.WATCH_DATA_WATCHER_METHOD.load().invoke(dataWatcherObject, Integer.valueOf(10), Byte.valueOf(127));
}
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public synchronized void changeType(NPCType npcType) {
deleteViewers();
try {
Object nmsWorld = CacheRegistry.GET_HANDLE_WORLD_METHOD.load().invoke(getLocation().getWorld());
boolean isPlayer = (npcType == NPCType.PLAYER);
this.nmsEntity = isPlayer ? this.packets.getProxyInstance().getPlayerPacket(nmsWorld, this.gameProfile) : (Utils.versionNewer(14) ? npcType.getConstructor().newInstance(npcType.getNmsEntityType(), nmsWorld) : npcType.getConstructor().newInstance(nmsWorld));
this.bukkitEntity = CacheRegistry.GET_BUKKIT_ENTITY_METHOD.load().invoke(this.nmsEntity);
this.uuid = (UUID) CacheRegistry.GET_UNIQUE_ID_METHOD.load().invoke(this.nmsEntity, new Object[0]);
if (isPlayer) {
try {
this.tabConstructor = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_CONSTRUCTOR.load()).newInstance(CacheRegistry.ADD_PLAYER_FIELD.load(), Collections.singletonList(this.nmsEntity));
} catch (Throwable e) {
this.tabConstructor = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_CONSTRUCTOR.load()).newInstance(CacheRegistry.ADD_PLAYER_FIELD.load(), this.nmsEntity);
this.updateTabConstructor = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_CONSTRUCTOR.load()).newInstance(CacheRegistry.UPDATE_LISTED_FIELD.load(), this.nmsEntity);
}
setSecondLayerSkin();
}
this.npcPojo.setNpcType(npcType);
setLocation(getLocation(), false);
this.packets.flushCache("spawnPacket", "removeTab");
this.entityID = ((Integer) CacheRegistry.GET_ENTITY_ID.load().invoke(this.nmsEntity, new Object[0])).intValue();
FunctionFactory.findFunctionsForNpc(this).forEach(function -> function.resolve(this));
getPackets().getProxyInstance().update(this.packets);
this.hologram.createHologram();
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public synchronized void spawn(ZUser user) {
if (this.viewers.contains(user))
throw new IllegalStateException(user.getUUID().toString() + " is already a viewer.");
try {
this.viewers.add(user);
boolean npcIsPlayer = (this.npcPojo.getNpcType() == NPCType.PLAYER);
if (FunctionFactory.isTrue(this, "glow") || npcIsPlayer) {
ImmutableList<Object> scoreboardPackets = this.packets.getProxyInstance().updateScoreboard(this);
scoreboardPackets.forEach(p -> Utils.sendPackets(user, p));
}
if (npcIsPlayer) {
if (FunctionFactory.isTrue(this, "mirror"))
updateProfile(user.getGameProfile().getProperties());
Utils.sendPackets(user, this.tabConstructor, this.updateTabConstructor);
}
Utils.sendPackets(user, this.packets.getProxyInstance().getSpawnPacket(this.nmsEntity, npcIsPlayer));
if (FunctionFactory.isTrue(this, "holo"))
this.hologram.spawn(user);
updateMetadata(Collections.singleton(user));
sendEquipPackets(user);
lookAt(user, getLocation(), true);
if (npcIsPlayer) {
Object removeTabPacket = this.packets.getProxyInstance().getTabRemovePacket(this.nmsEntity);
ZNPCsPlus.SCHEDULER.scheduleSyncDelayedTask(() -> Utils.sendPackets(user, removeTabPacket, this.updateTabConstructor), 60);
}
} catch (ReflectiveOperationException operationException) {
delete(user);
throw new UnexpectedCallException(operationException);
}
}
public synchronized void delete(ZUser user) {
if (!this.viewers.contains(user))
throw new IllegalStateException(user.getUUID().toString() + " is not a viewer.");
this.viewers.remove(user);
handleDelete(user);
}
private void handleDelete(ZUser user) {
try {
if (this.npcPojo.getNpcType() == NPCType.PLAYER)
this.packets.getProxyInstance().getTabRemovePacket(this.nmsEntity);
this.hologram.delete(user);
Utils.sendPackets(user, this.packets.getProxyInstance().getDestroyPacket(this.entityID));
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public void lookAt(ZUser player, Location location, boolean rotation) {
long lastMoveNanos = System.nanoTime() - this.lastMove;
if (this.lastMove > 1L && lastMoveNanos < 1000000000L)
return;
Location direction = rotation ? location : this.npcPojo.getLocation().bukkitLocation().clone().setDirection(location.clone().subtract(this.npcPojo.getLocation().bukkitLocation().clone()).toVector());
try {
Object lookPacket = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_LOOK_CONSTRUCTOR.load()).newInstance(Integer.valueOf(this.entityID), Byte.valueOf((byte) (int) (direction.getYaw() * 256.0F / 360.0F)), Byte.valueOf((byte) (int) (direction.getPitch() * 256.0F / 360.0F)), Boolean.TRUE);
Object headRotationPacket = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_HEAD_ROTATION_CONSTRUCTOR.load()).newInstance(this.nmsEntity, Byte.valueOf((byte) (int) (direction.getYaw() * 256.0F / 360.0F)));
if (player != null) {
Utils.sendPackets(player, lookPacket, headRotationPacket);
} else {
this.viewers.forEach(players -> Utils.sendPackets(players, headRotationPacket));
}
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public void deleteViewers() {
for (ZUser user : this.viewers)
handleDelete(user);
this.viewers.clear();
}
protected void updateMetadata(Iterable<ZUser> users) {
try {
Object metaData = this.packets.getProxyInstance().getMetadataPacket(this.entityID, this.nmsEntity);
for (ZUser user : users) {
Utils.sendPackets(user, metaData);
}
} catch (ReflectiveOperationException operationException) {
operationException.getCause().printStackTrace();
operationException.printStackTrace();
}
}
public void updateProfile(PropertyMap propertyMap) {
if (this.npcPojo.getNpcType() != NPCType.PLAYER)
return;
try {
Object gameProfileObj = CacheRegistry.GET_PROFILE_METHOD.load().invoke(this.nmsEntity);
Utils.setValue(gameProfileObj, "name", this.gameProfile.getName());
Utils.setValue(gameProfileObj, "id", this.gameProfile.getId());
Utils.setValue(gameProfileObj, "properties", propertyMap);
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public void sendEquipPackets(ZUser zUser) {
if (this.npcPojo.getNpcEquip().isEmpty())
return;
try {
ImmutableList<Object> equipPackets = this.packets.getProxyInstance().getEquipPackets(this);
equipPackets.forEach(o -> Utils.sendPackets(zUser, o));
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException.getCause());
}
}
public void setPath(NPCPath.AbstractTypeWriter typeWriter) {
if (typeWriter == null) {
this.npcPath = null;
this.npcPojo.setPathName("none");
} else {
this.npcPath = typeWriter.getPath(this);
this.npcPojo.setPathName(typeWriter.getName());
}
}
public void tryStartConversation(Player player) {
ConversationModel conversation = this.npcPojo.getConversation();
if (conversation == null)
throw new IllegalStateException("can't find conversation");
conversation.startConversation(this, player);
}
public Location getLocation() {
return (this.npcPath != null) ?
this.npcPath.getLocation().bukkitLocation() :
this.npcPojo.getLocation().bukkitLocation();
}
}

@ -0,0 +1,97 @@
package io.github.znetworkw.znpcservers.npc;
import com.google.common.base.MoreObjects;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.npc.event.ClickType;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
public class NPCAction {
private final ActionType actionType;
private final ClickType clickType;
private final String action;
private int delay;
public NPCAction(ActionType actionType, ClickType clickType, String action, int delay) {
this.actionType = actionType;
this.clickType = clickType;
this.action = action;
this.delay = delay;
}
public NPCAction(String actionType, String action) {
this(ActionType.valueOf(actionType), ClickType.DEFAULT, action, 0);
}
public ActionType getActionType() {
return this.actionType;
}
public ClickType getClickType() {
return this.clickType;
}
public String getAction() {
return this.action;
}
public int getDelay() {
return this.delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
public long getFixedDelay() {
return 1000000000L * this.delay;
}
public void run(ZUser user, String action) {
this.actionType.run(user, Utils.PLACEHOLDER_SUPPORT ? Utils.getWithPlaceholders(action, user.toPlayer()) : action);
}
public String toString() {
return MoreObjects.toStringHelper(this)
.add("actionType", this.actionType)
.add("clickType", this.clickType)
.add("action", this.action)
.add("delay", this.delay)
.toString();
}
enum ActionType {
CMD {
public void run(ZUser user, String actionValue) {
user.toPlayer().performCommand(actionValue);
}
},
CONSOLE {
public void run(ZUser user, String actionValue) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), actionValue);
}
},
CHAT {
public void run(ZUser user, String actionValue) {
user.toPlayer().chat(actionValue);
}
},
MESSAGE {
public void run(ZUser user, String actionValue) {
user.toPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', actionValue));
}
},
SERVER {
public void run(ZUser user, String actionValue) {
ZNPCsPlus.BUNGEE_UTILS.sendPlayerToServer(user.toPlayer(), actionValue);
}
};
public abstract void run(ZUser param1ZUser, String param1String);
}
}

@ -0,0 +1,66 @@
package io.github.znetworkw.znpcservers.npc;
public abstract class NPCFunction {
private final String name;
public NPCFunction(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
protected abstract boolean allow(NPC paramNPC);
protected abstract ResultType runFunction(NPC paramNPC, FunctionContext paramFunctionContext);
public void doRunFunction(NPC npc, FunctionContext functionContext) {
if (!allow(npc))
return;
ResultType resultType = runFunction(npc, functionContext);
if (resultType == ResultType.SUCCESS)
npc.getNpcPojo().getFunctions().put(getName(), Boolean.valueOf(!isTrue(npc)));
}
protected ResultType resolve(NPC npc) {
throw new IllegalStateException("resolve is not implemented.");
}
public boolean isTrue(NPC npc) {
return FunctionFactory.isTrue(npc, this);
}
public enum ResultType {
SUCCESS, FAIL
}
public static class WithoutFunction extends NPCFunction {
public WithoutFunction(String name) {
super(name);
}
protected NPCFunction.ResultType runFunction(NPC npc, FunctionContext functionContext) {
return NPCFunction.ResultType.SUCCESS;
}
protected boolean allow(NPC npc) {
return true;
}
protected NPCFunction.ResultType resolve(NPC npc) {
return NPCFunction.ResultType.SUCCESS;
}
}
public static class WithoutFunctionSelfUpdate extends WithoutFunction {
public WithoutFunctionSelfUpdate(String name) {
super(name);
}
protected NPCFunction.ResultType runFunction(NPC npc, FunctionContext functionContext) {
npc.deleteViewers();
return NPCFunction.ResultType.SUCCESS;
}
}
}

@ -0,0 +1,238 @@
package io.github.znetworkw.znpcservers.npc;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.utility.location.ZLocation;
import org.bukkit.inventory.ItemStack;
import java.util.*;
public class NPCModel {
private static final String EMPTY_STRING = "";
private int id;
private double hologramHeight;
private String skin;
private String signature = "";
private String pathName;
private String glowName;
private ConversationModel conversation;
private ZLocation location;
private NPCType npcType;
private List<String> hologramLines;
private List<NPCAction> clickActions;
private Map<ItemSlot, ItemStack> npcEquip;
private Map<String, Boolean> npcFunctions;
private Map<String, String[]> customizationMap;
public NPCModel(int id) {
this();
this.id = id;
this.skin = "";
this.signature = "";
this.npcType = NPCType.PLAYER;
}
private NPCModel() {
this.hologramLines = Collections.singletonList("/znpcs lines");
this.clickActions = new ArrayList<>();
this.npcEquip = new HashMap<>();
this.customizationMap = new HashMap<>();
this.npcFunctions = new HashMap<>();
this.npcFunctions.put("holo", Boolean.TRUE);
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public NPCModel withId(int id) {
setId(id);
return this;
}
public double getHologramHeight() {
return this.hologramHeight;
}
public void setHologramHeight(double hologramHeight) {
this.hologramHeight = hologramHeight;
}
public NPCModel withHologramHeight(double hologramHeight) {
setHologramHeight(hologramHeight);
return this;
}
public String getSkin() {
return this.skin;
}
public void setSkin(String skin) {
this.skin = skin;
}
public NPCModel withSkin(String skin) {
setSkin(skin);
return this;
}
public String getSignature() {
return this.signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public NPCModel withSignature(String signature) {
setSignature(signature);
return this;
}
public String getPathName() {
return this.pathName;
}
public void setPathName(String pathName) {
this.pathName = pathName;
}
public NPCModel withPathName(String pathName) {
setPathName(pathName);
return this;
}
public String getGlowName() {
return this.glowName;
}
public void setGlowName(String glowName) {
this.glowName = glowName;
}
public NPCModel withGlowName(String glowName) {
setGlowName(this.pathName);
return this;
}
public ConversationModel getConversation() {
return this.conversation;
}
public void setConversation(ConversationModel conversation) {
this.conversation = conversation;
}
public NPCModel withConversation(ConversationModel conversation) {
setConversation(conversation);
return this;
}
public List<String> getHologramLines() {
return this.hologramLines;
}
public void setHologramLines(List<String> hologramLines) {
this.hologramLines = hologramLines;
}
public NPCModel withHologramLines(List<String> hologramLines) {
setHologramLines(hologramLines);
return this;
}
public ZLocation getLocation() {
return this.location;
}
public void setLocation(ZLocation location) {
this.location = location;
}
public NPCModel withLocation(ZLocation location) {
setLocation(location);
return this;
}
public NPCType getNpcType() {
return this.npcType;
}
public void setNpcType(NPCType npcType) {
this.npcType = npcType;
}
public NPCModel withNpcType(NPCType npcType) {
setNpcType(npcType);
return this;
}
public List<NPCAction> getClickActions() {
return this.clickActions;
}
public void setClickActions(List<NPCAction> clickActions) {
this.clickActions = clickActions;
}
public NPCModel withClickActions(List<NPCAction> clickActions) {
setClickActions(clickActions);
return this;
}
public Map<ItemSlot, ItemStack> getNpcEquip() {
return this.npcEquip;
}
public void setNpcEquip(Map<ItemSlot, ItemStack> npcEquip) {
this.npcEquip = npcEquip;
}
public NPCModel withNpcEquip(Map<ItemSlot, ItemStack> npcEquip) {
setNpcEquip(npcEquip);
return this;
}
public Map<String, String[]> getCustomizationMap() {
return this.customizationMap;
}
public void setCustomizationMap(Map<String, String[]> customizationMap) {
this.customizationMap = customizationMap;
}
public NPCModel withCustomizationMap(Map<String, String[]> customizationMap) {
setCustomizationMap(customizationMap);
return this;
}
public Map<String, Boolean> getFunctions() {
return this.npcFunctions;
}
public void setFunctions(Map<String, Boolean> npcFunctions) {
this.npcFunctions = npcFunctions;
}
public NPCModel withFunctionValues(Map<String, Boolean> npcFunctions) {
setFunctions(npcFunctions);
return this;
}
}

@ -0,0 +1,306 @@
package io.github.znetworkw.znpcservers.npc;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.configuration.Configuration;
import io.github.znetworkw.znpcservers.configuration.ConfigurationValue;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.location.ZLocation;
import org.bukkit.Location;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public interface NPCPath {
void initialize(DataInputStream paramDataInputStream) throws IOException;
void write(DataOutputStream paramDataOutputStream) throws IOException;
void start();
PathInitializer getPath(NPC paramNPC);
interface PathInitializer {
void handle();
ZLocation getLocation();
abstract class AbstractPath implements PathInitializer {
private final NPC npc;
private final NPCPath.AbstractTypeWriter typeWriter;
private ZLocation location;
public AbstractPath(NPC npc, NPCPath.AbstractTypeWriter typeWriter) {
this.npc = npc;
this.typeWriter = typeWriter;
}
public NPC getNpc() {
return this.npc;
}
public NPCPath.AbstractTypeWriter getPath() {
return this.typeWriter;
}
public ZLocation getLocation() {
return this.location;
}
public void setLocation(ZLocation location) {
this.location = location;
}
}
}
class ZNPCPathDelegator {
private final File file;
protected ZNPCPathDelegator(File file) {
this.file = file;
}
public static ZNPCPathDelegator forFile(File file) {
return new ZNPCPathDelegator(file);
}
public static ZNPCPathDelegator forPath(NPCPath.AbstractTypeWriter pathAbstract) {
return new ZNPCPathDelegator(pathAbstract.getFile());
}
public DataOutputStream getOutputStream() throws IOException {
return new DataOutputStream(new FileOutputStream(this.file));
}
public DataInputStream getInputStream() throws IOException {
return new DataInputStream(new FileInputStream(this.file));
}
}
abstract class AbstractTypeWriter implements NPCPath {
private static final Logger LOGGER = Logger.getLogger(AbstractTypeWriter.class.getName());
private static final ConcurrentMap<String, AbstractTypeWriter> PATH_TYPES = new ConcurrentHashMap<>();
private static final int PATH_DELAY = 1;
private final TypeWriter typeWriter;
private final File file;
private final List<ZLocation> locationList;
public AbstractTypeWriter(TypeWriter typeWriter, File file) {
this.typeWriter = typeWriter;
this.file = file;
this.locationList = new ArrayList<>();
}
public AbstractTypeWriter(TypeWriter typeWriter, String pathName) {
this(typeWriter, new File(ZNPCsPlus.PATH_FOLDER, pathName + ".path"));
}
public static AbstractTypeWriter forCreation(String pathName, ZUser user, TypeWriter typeWriter) {
if (typeWriter == TypeWriter.MOVEMENT)
return new TypeMovement(pathName, user);
throw new IllegalStateException("can't find type writer for: " + typeWriter.name());
}
public static AbstractTypeWriter forFile(File file, TypeWriter typeWriter) {
if (typeWriter == TypeWriter.MOVEMENT)
return new TypeMovement(file);
throw new IllegalStateException("can't find type writer for: " + typeWriter.name());
}
public static void register(AbstractTypeWriter abstractZNPCPath) {
PATH_TYPES.put(abstractZNPCPath.getName(), abstractZNPCPath);
}
public static AbstractTypeWriter find(String name) {
return PATH_TYPES.get(name);
}
public static Collection<AbstractTypeWriter> getPaths() {
return PATH_TYPES.values();
}
public void load() {
try {
DataInputStream reader = NPCPath.ZNPCPathDelegator.forFile(this.file).getInputStream();
try {
initialize(reader);
register(this);
if (reader != null)
reader.close();
} catch (Throwable throwable) {
if (reader != null)
try {
reader.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, String.format("The path %s could not be loaded", this.file.getName()));
}
}
public void write() {
try {
DataOutputStream writer = NPCPath.ZNPCPathDelegator.forFile(getFile()).getOutputStream();
try {
write(writer);
if (writer != null)
writer.close();
} catch (Throwable throwable) {
if (writer != null)
try {
writer.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, String.format("Path %s could not be created", getName()), e);
}
}
public File getFile() {
return this.file;
}
public List<ZLocation> getLocationList() {
return this.locationList;
}
public String getName() {
return this.file.getName().substring(0, this.file.getName().lastIndexOf('.'));
}
public enum TypeWriter {
MOVEMENT
}
private static class TypeMovement extends AbstractTypeWriter {
private static final int MAX_LOCATIONS = ((Integer) Configuration.CONFIGURATION.getValue(ConfigurationValue.MAX_PATH_LOCATIONS)).intValue();
private ZUser npcUser;
private BukkitTask bukkitTask;
public TypeMovement(File file) {
super(NPCPath.AbstractTypeWriter.TypeWriter.MOVEMENT, file);
}
public TypeMovement(String fileName, ZUser npcUser) {
super(NPCPath.AbstractTypeWriter.TypeWriter.MOVEMENT, fileName);
this.npcUser = npcUser;
start();
}
public void initialize(DataInputStream dataInputStream) throws IOException {
while (dataInputStream.available() > 0) {
String worldName = dataInputStream.readUTF();
double x = dataInputStream.readDouble();
double y = dataInputStream.readDouble();
double z = dataInputStream.readDouble();
float yaw = dataInputStream.readFloat();
float pitch = dataInputStream.readFloat();
getLocationList().add(new ZLocation(worldName, x, y, z, yaw, pitch));
}
}
public void write(DataOutputStream dataOutputStream) throws IOException {
if (getLocationList().isEmpty())
return;
Iterator<ZLocation> locationIterator = getLocationList().iterator();
while (locationIterator.hasNext()) {
ZLocation location = locationIterator.next();
dataOutputStream.writeUTF(location.getWorldName());
dataOutputStream.writeDouble(location.getX());
dataOutputStream.writeDouble(location.getY());
dataOutputStream.writeDouble(location.getZ());
dataOutputStream.writeFloat(location.getYaw());
dataOutputStream.writeFloat(location.getPitch());
if (!locationIterator.hasNext())
register(this);
}
}
public void start() {
this.npcUser.setHasPath(true);
this.bukkitTask = ZNPCsPlus.SCHEDULER.runTaskTimerAsynchronously(() -> {
if (this.npcUser.toPlayer() != null && this.npcUser.isHasPath() && MAX_LOCATIONS > getLocationList().size()) {
Location location = this.npcUser.toPlayer().getLocation();
if (isValid(location))
getLocationList().add(new ZLocation(location));
} else {
this.bukkitTask.cancel();
this.npcUser.setHasPath(false);
write();
}
}1, 1);
}
public MovementPath getPath(NPC npc) {
return new MovementPath(npc, this);
}
protected boolean isValid(Location location) {
if (getLocationList().isEmpty())
return true;
ZLocation last = getLocationList().get(getLocationList().size() - 1);
double xDiff = Math.abs(last.getX() - location.getX());
double yDiff = Math.abs(last.getY() - location.getY());
double zDiff = Math.abs(last.getZ() - location.getZ());
return (xDiff + yDiff + zDiff > 0.01D);
}
protected static class MovementPath extends NPCPath.PathInitializer.AbstractPath {
private int currentEntryPath = 0;
private boolean pathReverse = false;
public MovementPath(NPC npc, NPCPath.AbstractTypeWriter.TypeMovement path) {
super(npc, path);
}
public void handle() {
updatePathLocation(getPath().getLocationList().get(this.currentEntryPath = getNextLocation()));
int nextIndex = getNextLocation();
if (nextIndex < 1) {
this.pathReverse = false;
} else if (nextIndex >= getPath().getLocationList().size() - 1) {
this.pathReverse = true;
}
}
private int getNextLocation() {
return this.pathReverse ? (this.currentEntryPath - 1) : (this.currentEntryPath + 1);
}
protected void updatePathLocation(ZLocation location) {
setLocation(location);
ZLocation next = getPath().getLocationList().get(getNextLocation());
Vector vector = next.toVector().add(new Vector(0.0D, location.getY() - next.getY(), 0.0D));
Location direction = next.bukkitLocation().clone().setDirection(location.toVector().subtract(vector)
.multiply(new Vector(-1, 0, -1)));
getNpc().setLocation(direction, false);
getNpc().lookAt(null, direction, true);
}
}
}
}
}

@ -0,0 +1,71 @@
package io.github.znetworkw.znpcservers.npc;
import io.github.znetworkw.znpcservers.skin.SkinFetcherBuilder;
import io.github.znetworkw.znpcservers.skin.SkinFetcherResult;
import io.github.znetworkw.znpcservers.utility.Utils;
public class NPCSkin {
private static final String EMPTY_STRING = "";
private static final String[] EMPTY_ARRAY = new String[]{"", ""};
private static final int LAYER_INDEX = SkinLayerValues.findLayerByVersion();
private final String texture;
private final String signature;
protected NPCSkin(String... values) {
if (values.length < 1)
throw new IllegalArgumentException("Length cannot be zero or negative.");
this.texture = values[0];
this.signature = values[1];
}
public static NPCSkin forValues(String... values) {
return new NPCSkin((values.length > 0) ? values : EMPTY_ARRAY);
}
public static void forName(String skin, SkinFetcherResult skinFetcherResult) {
SkinFetcherBuilder.withName(skin).toSkinFetcher().doReadSkin(skinFetcherResult);
}
public String getTexture() {
return this.texture;
}
public String getSignature() {
return this.signature;
}
public int getLayerIndex() {
return LAYER_INDEX;
}
enum SkinLayerValues {
V8(8, 12),
V9(10, 13),
V14(14, 15),
V16(15, 16),
V17(17, 17),
V18(18, 17);
final int minVersion;
final int layerValue;
SkinLayerValues(int minVersion, int layerValue) {
this.minVersion = minVersion;
this.layerValue = layerValue;
}
static int findLayerByVersion() {
int value = V8.layerValue;
for (SkinLayerValues skinLayerValue : values()) {
if (Utils.BUKKIT_VERSION >= skinLayerValue.minVersion)
value = skinLayerValue.layerValue;
}
return value;
}
}
}

@ -0,0 +1,135 @@
package io.github.znetworkw.znpcservers.npc;
import io.github.znetworkw.znpcservers.UnexpectedCallException;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.cache.TypeCache;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.entity.EntityType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;
public enum NPCType {
PLAYER(CacheRegistry.ENTITY_PLAYER_CLASS, 0.0D, new String[0]),
ARMOR_STAND(CacheRegistry.ENTITY_ARMOR_STAND_CLASS, 0.0D, new String[]{"setSmall", "setArms"}),
CREEPER(CacheRegistry.ENTITY_CREEPER_CLASS, -0.15D, new String[]{"setPowered"}),
BAT(CacheRegistry.ENTITY_BAT_CLASS, -0.5D, new String[]{"setAwake"}),
BLAZE(CacheRegistry.ENTITY_BLAZE_CLASS, 0.0D, new String[0]),
CAVE_SPIDER(CacheRegistry.ENTITY_CAVE_SPIDER_CLASS, -1.0D, new String[0]),
COW(CacheRegistry.ENTITY_COW_CLASS, -0.25D, new String[]{"setAge"}),
CHICKEN(CacheRegistry.ENTITY_CHICKEN_CLASS, -1.0D, new String[]{"setAge"}),
ENDER_DRAGON(CacheRegistry.ENTITY_ENDER_DRAGON_CLASS, 1.5D, new String[0]),
ENDERMAN(CacheRegistry.ENTITY_ENDERMAN_CLASS, 0.7D, new String[0]),
ENDERMITE(CacheRegistry.ENTITY_ENDERMITE_CLASS, -1.5D, new String[0]),
GHAST(CacheRegistry.ENTITY_GHAST_CLASS, 3.0D, new String[0]),
IRON_GOLEM(CacheRegistry.ENTITY_IRON_GOLEM_CLASS, 0.75D, new String[0]),
GIANT(CacheRegistry.ENTITY_GIANT_ZOMBIE_CLASS, 11.0D, new String[0]),
GUARDIAN(CacheRegistry.ENTITY_GUARDIAN_CLASS, -0.7D, new String[0]),
HORSE(CacheRegistry.ENTITY_HORSE_CLASS, 0.0D, new String[]{"setStyle", "setAge", "setColor", "setVariant"}),
LLAMA(CacheRegistry.ENTITY_LLAMA_CLASS, 0.0D, new String[]{"setAge"}),
MAGMA_CUBE(CacheRegistry.ENTITY_MAGMA_CUBE_CLASS, -1.25D, new String[]{"setSize"}),
MUSHROOM_COW(CacheRegistry.ENTITY_MUSHROOM_COW_CLASS, -0.25D, new String[]{"setAge"}),
OCELOT(CacheRegistry.ENTITY_OCELOT_CLASS, -1.0D, new String[]{"setCatType", "setAge"}),
PARROT(CacheRegistry.ENTITY_PARROT_CLASS, -1.5D, new String[]{"setVariant"}),
PIG(CacheRegistry.ENTITY_PIG_CLASS, -1.0D, new String[]{"setAge"}),
PANDA(CacheRegistry.ENTITY_PANDA_CLASS, -0.6D, new String[]{"setAge", "setMainGene", "setHiddenGene"}),
RABBIT(CacheRegistry.ENTITY_RABBIT_CLASS, -1.0D, new String[]{"setRabbitType"}),
POLAR_BEAR(CacheRegistry.ENTITY_POLAR_BEAR_CLASS, -0.5D, new String[0]),
SHEEP(CacheRegistry.ENTITY_SHEEP_CLASS, -0.5D, new String[]{"setAge", "setSheared", "setColor"}),
SILVERFISH(CacheRegistry.ENTITY_SILVERFISH_CLASS, -1.5D, new String[0]),
SNOWMAN(CacheRegistry.ENTITY_SNOWMAN_CLASS, 0.0D, new String[]{"setHasPumpkin", "setDerp"}),
SKELETON(CacheRegistry.ENTITY_SKELETON_CLASS, 0.0D, new String[0]),
SHULKER(CacheRegistry.ENTITY_SHULKER_CLASS, 0.0D, new String[0]),
SLIME(CacheRegistry.ENTITY_SLIME_CLASS, -1.25D, new String[]{"setSize"}),
SPIDER(CacheRegistry.ENTITY_SPIDER_CLASS, -1.0D, new String[0]),
SQUID(CacheRegistry.ENTITY_SQUID_CLASS, -1.0D, new String[0]),
VILLAGER(CacheRegistry.ENTITY_VILLAGER_CLASS, 0.0D, new String[]{"setProfession", "setVillagerType", "setAge"}),
WITCH(CacheRegistry.ENTITY_WITCH_CLASS, 0.5D, new String[0]),
WITHER(CacheRegistry.ENTITY_WITHER_CLASS, 1.75D, new String[0]),
ZOMBIE(CacheRegistry.ENTITY_ZOMBIE_CLASS, 0.0D, new String[]{"setBaby"}),
WOLF(CacheRegistry.ENTITY_WOLF_CLASS, -1.0D, new String[]{"setSitting", "setTamed", "setAngry", "setAge", "setCollarColor"}),
FOX(CacheRegistry.ENTITY_FOX_CLASS, -1.0D, new String[]{"setFoxType", "setSitting", "setSleeping", "setAge", "setCrouching"}),
BEE(CacheRegistry.ENTITY_BEE_CLASS, -1.0D, new String[]{"setAnger", "setHasNectar", "setHasStung"}),
TURTLE(CacheRegistry.ENTITY_TURTLE, -1.0D, new String[0]),
WARDEN(CacheRegistry.ENTITY_WARDEN, 1.0D, new String[0]),
AXOLOTL(CacheRegistry.ENTITY_AXOLOTL_CLASS, -1.0D, new String[]{"setVariant", "setAge"}),
GOAT(CacheRegistry.ENTITY_GOAT_CLASS, -0.5D, new String[]{"setScreamingGoat", "setAge"});
private static final String EMPTY_STRING = "";
private final double holoHeight;
private final CustomizationLoader customizationLoader;
private final Constructor<?> constructor;
private EntityType bukkitEntityType;
private Object nmsEntityType;
NPCType(Class<?> entityClass, String newName, double holoHeight, String... methods) {
this.holoHeight = holoHeight;
this
.customizationLoader = (entityClass == null) ? null : new CustomizationLoader(this.bukkitEntityType = EntityType.valueOf((newName.length() > 0) ? newName : name()), Arrays.asList(methods));
if (entityClass == null || entityClass
.isAssignableFrom(CacheRegistry.ENTITY_PLAYER_CLASS)) {
this.constructor = null;
return;
}
try {
if (Utils.versionNewer(14)) {
this.nmsEntityType = ((Optional) CacheRegistry.ENTITY_TYPES_A_METHOD.load().invoke(null, new Object[]{this.bukkitEntityType.getKey().getKey().toLowerCase()})).get();
this.constructor = entityClass.getConstructor(CacheRegistry.ENTITY_TYPES_CLASS, CacheRegistry.WORLD_CLASS);
} else {
this.constructor = entityClass.getConstructor(CacheRegistry.WORLD_CLASS);
}
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public static Object[] arrayToPrimitive(String[] strings, Method method) {
Class<?>[] methodParameterTypes = method.getParameterTypes();
Object[] newArray = new Object[methodParameterTypes.length];
for (int i = 0; i < methodParameterTypes.length; i++) {
TypeProperty typeProperty = TypeProperty.forType(methodParameterTypes[i]);
if (typeProperty != null) {
newArray[i] = typeProperty.getFunction().apply(strings[i]);
} else {
newArray[i] = TypeCache.ClassCache.find(strings[i], methodParameterTypes[i]);
}
}
return newArray;
}
public double getHoloHeight() {
return this.holoHeight;
}
public Constructor<?> getConstructor() {
return this.constructor;
}
public Object getNmsEntityType() {
return this.nmsEntityType;
}
public CustomizationLoader getCustomizationLoader() {
return this.customizationLoader;
}
public void updateCustomization(NPC npc, String name, String[] values) {
if (!this.customizationLoader.contains(name))
return;
try {
Method method = this.customizationLoader.getMethods().get(name);
method.invoke(npc.getBukkitEntity(), arrayToPrimitive(values, method));
npc.updateMetadata(npc.getViewers());
} catch (IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
throw new IllegalStateException("can't invoke method: " + name, e);
}
}
}

@ -0,0 +1,15 @@
package io.github.znetworkw.znpcservers.npc;
import io.github.znetworkw.znpcservers.utility.Utils;
public enum NamingType {
DEFAULT {
public String resolve(NPC npc) {
return Utils.randomString(6);
}
};
private static final int FIXED_LENGTH = 6;
public abstract String resolve(NPC paramNPC);
}

@ -0,0 +1,41 @@
package io.github.znetworkw.znpcservers.npc;
import java.util.function.Function;
public enum TypeProperty {
STRING(String::toString),
BOOLEAN(Boolean::parseBoolean),
INT(Integer::parseInt),
DOUBLE(Double::parseDouble),
FLOAT(Float::parseFloat),
SHORT(Short::parseShort),
LONG(Long::parseLong);
private final Function<String, ?> function;
TypeProperty(Function<String, ?> function) {
this.function = function;
}
public static TypeProperty forType(Class<?> primitiveType) {
if (primitiveType == String.class)
return STRING;
if (primitiveType == boolean.class)
return BOOLEAN;
if (primitiveType == int.class)
return INT;
if (primitiveType == double.class)
return DOUBLE;
if (primitiveType == float.class)
return FLOAT;
if (primitiveType == short.class)
return SHORT;
if (primitiveType == long.class)
return LONG;
return null;
}
public Function<String, ?> getFunction() {
return this.function;
}
}

@ -0,0 +1,61 @@
package io.github.znetworkw.znpcservers.npc.conversation;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import java.util.ArrayList;
import java.util.List;
public class Conversation {
private final String name;
private final List<ConversationKey> texts;
private int radius = 5;
private int delay = 10;
public Conversation(String name) {
this(name, new ArrayList<>());
}
protected Conversation(String name, List<ConversationKey> text) {
this.name = name;
this.texts = text;
}
public static Conversation forName(String name) {
return ConfigurationConstants.NPC_CONVERSATIONS.stream()
.filter(conversation -> conversation.getName().equalsIgnoreCase(name))
.findFirst()
.orElse(null);
}
public static boolean exists(String name) {
return ConfigurationConstants.NPC_CONVERSATIONS.stream()
.anyMatch(conversation -> conversation.getName().equalsIgnoreCase(name));
}
public String getName() {
return this.name;
}
public List<ConversationKey> getTexts() {
return this.texts;
}
public int getDelay() {
return this.delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
public int getRadius() {
return this.radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
}

@ -0,0 +1,63 @@
package io.github.znetworkw.znpcservers.npc.conversation;
import com.google.common.base.Splitter;
import io.github.znetworkw.znpcservers.npc.NPCAction;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class ConversationKey {
private static final Splitter SPACE_SPLITTER = Splitter.on(" ");
private final List<String> lines;
private final List<NPCAction> actions;
private int delay = 1;
private String soundName;
public ConversationKey(String line) {
this(SPACE_SPLITTER.split(line));
}
public ConversationKey(Iterable<String> line) {
this
.lines = StreamSupport.stream(line.spliterator(), false).map(String::toString).collect(Collectors.toList());
this.actions = new ArrayList<>();
}
public List<String> getLines() {
return this.lines;
}
public int getDelay() {
return this.delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
public String getSoundName() {
return this.soundName;
}
public void setSoundName(String soundName) {
this.soundName = soundName;
}
public List<NPCAction> getActions() {
return this.actions;
}
public String getTextFormatted() {
if (this.lines.isEmpty())
return "";
String text = this.lines.iterator().next();
int fixedLength = Math.min(text.length(), 28);
return text.substring(0, fixedLength);
}
}

@ -0,0 +1,76 @@
package io.github.znetworkw.znpcservers.npc.conversation;
import io.github.znetworkw.znpcservers.npc.NPC;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;
public class ConversationModel {
private final transient Map<UUID, Long> lastStarted = new HashMap<>();
private String conversationName;
private ConversationType conversationType;
public ConversationModel(String conversationName, String conversationType) {
this.conversationName = conversationName;
try {
this.conversationType = ConversationType.valueOf(conversationType.toUpperCase());
} catch (IllegalArgumentException exception) {
throw new IllegalStateException("can't find conversation type " + conversationType);
}
}
private ConversationModel() {
}
public String getConversationName() {
return this.conversationName;
}
public ConversationType getConversationType() {
return this.conversationType;
}
public Conversation getConversation() {
return Conversation.forName(this.conversationName);
}
public void startConversation(NPC npc, Player player) {
if (!Conversation.exists(this.conversationName))
throw new IllegalStateException("can't find conversation " + this.conversationName);
if (ConversationProcessor.isPlayerConversing(player.getUniqueId()))
return;
if (this.lastStarted.containsKey(player.getUniqueId())) {
long lastConversationNanos = System.nanoTime() - this.lastStarted.get(player.getUniqueId()).longValue();
if (lastConversationNanos < 1000000000L * getConversation().getDelay())
return;
}
this.lastStarted.remove(player.getUniqueId());
if (this.conversationType.canStart(npc, getConversation(), player)) {
new ConversationProcessor(npc, this, player);
this.lastStarted.put(player.getUniqueId(), Long.valueOf(System.nanoTime()));
}
}
public boolean canRun(NPC npc, Player player) {
return Stream.of(ConversationType.values()).anyMatch(conversationType1 -> !conversationType1.canStart(npc, getConversation(), player));
}
public enum ConversationType {
RADIUS {
public boolean canStart(NPC npc, Conversation conversation, Player player) {
return (player.getWorld() == npc.getLocation().getWorld() && player
.getLocation().distance(npc.getLocation()) <= conversation.getRadius());
}
},
CLICK {
public boolean canStart(NPC npc, Conversation conversation, Player player) {
return true;
}
};
abstract boolean canStart(NPC param1NPC, Conversation param1Conversation, Player param1Player);
}
}

@ -0,0 +1,79 @@
package io.github.znetworkw.znpcservers.npc.conversation;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.hologram.replacer.LineReplacer;
import io.github.znetworkw.znpcservers.user.ZUser;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class ConversationProcessor {
private static final Map<UUID, String> RUNNING_CONVERSATIONS = new HashMap<>();
private static final String WHITE_SPACE = " ";
private static final int CONVERSATION_DELAY = 20;
private final NPC npc;
private final ConversationModel conversationModel;
private final Player player;
private int conversationIndex = 0;
private long conversationIndexDelay = System.nanoTime();
public ConversationProcessor(NPC npc, ConversationModel conversationModel, Player player) {
if (conversationModel.getConversation().getTexts().isEmpty())
throw new IllegalStateException("conversation should have a text.");
this.npc = npc;
this.conversationModel = conversationModel;
this.player = player;
RUNNING_CONVERSATIONS.put(player.getUniqueId(), conversationModel.getConversationName());
start();
}
public static boolean isPlayerConversing(UUID uuid) {
return RUNNING_CONVERSATIONS.containsKey(uuid);
}
private void start() {
ZNPCsPlus.SCHEDULER.runTaskTimer(new BukkitRunnable() {
public void run() {
if (Bukkit.getPlayer(ConversationProcessor.this.player.getUniqueId()) == null || ConversationProcessor.this
.conversationIndex > ConversationProcessor.this.conversationModel.getConversation().getTexts().size() - 1 || ConversationProcessor.this
.conversationModel.canRun(ConversationProcessor.this.npc, ConversationProcessor.this.player)) {
ConversationProcessor.RUNNING_CONVERSATIONS.remove(ConversationProcessor.this.player.getUniqueId());
cancel();
return;
}
ConversationKey conversationKey = ConversationProcessor.this.conversationModel.getConversation().getTexts().get(ConversationProcessor.this.conversationIndex);
long conversationDelayNanos = System.nanoTime() - ConversationProcessor.this.conversationIndexDelay;
if (ConversationProcessor.this.conversationIndex != 0 && conversationDelayNanos < 1000000000L * conversationKey
.getDelay())
return;
ZUser user = ZUser.find(ConversationProcessor.this.player);
conversationKey.getLines().forEach(s -> ConversationProcessor.this.player.sendMessage(LineReplacer.makeAll(user, s).replace(ConfigurationConstants.SPACE_SYMBOL, " ")));
if (conversationKey.getActions().size() > 0)
conversationKey.getActions().forEach(action -> action.run(user, action.getAction()));
if (conversationKey.getSoundName() != null && conversationKey
.getSoundName().length() > 0)
try {
Sound sound = Sound.valueOf(conversationKey.getSoundName().toUpperCase());
ConversationProcessor.this.player.playSound(ConversationProcessor.this.player.getLocation(), sound, 0.2F, 1.0F);
} catch (IllegalArgumentException illegalArgumentException) {
}
ConversationProcessor.this.conversationIndexDelay = System.nanoTime();
ConversationProcessor.this.conversationIndex++;
}
}5, 20);
}
}

@ -0,0 +1,13 @@
package io.github.znetworkw.znpcservers.npc.event;
public enum ClickType {
RIGHT, LEFT, DEFAULT;
public static ClickType forName(String clickName) {
if (clickName.startsWith("INTERACT"))
return RIGHT;
if (clickName.startsWith("ATTACK"))
return LEFT;
return DEFAULT;
}
}

@ -0,0 +1,47 @@
package io.github.znetworkw.znpcservers.npc.event;
import io.github.znetworkw.znpcservers.npc.NPC;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class NPCInteractEvent extends Event {
private static final HandlerList handlerList = new HandlerList();
private final Player player;
private final ClickType clickType;
private final NPC npc;
public NPCInteractEvent(Player player, ClickType clickType, NPC npc) {
this.player = player;
this.clickType = clickType;
this.npc = npc;
}
public NPCInteractEvent(Player player, String clickType, NPC npc) {
this(player, ClickType.forName(clickType), npc);
}
public static HandlerList getHandlerList() {
return handlerList;
}
public Player getPlayer() {
return this.player;
}
public NPC getNpc() {
return this.npc;
}
public boolean isRightClick() {
return (this.clickType == ClickType.RIGHT);
}
public boolean isLeftClick() {
return (this.clickType == ClickType.LEFT);
}
public HandlerList getHandlers() {
return handlerList;
}
}

@ -0,0 +1,46 @@
package io.github.znetworkw.znpcservers.npc.function;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.FunctionContext;
import io.github.znetworkw.znpcservers.npc.FunctionFactory;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCFunction;
import java.lang.reflect.Constructor;
public class GlowFunction extends NPCFunction {
public GlowFunction() {
super("glow");
}
protected NPCFunction.ResultType runFunction(NPC npc, FunctionContext functionContext) {
if (!(functionContext instanceof FunctionContext.ContextWithValue))
throw new IllegalStateException("invalid context type, " + functionContext.getClass().getSimpleName() + ", expected ContextWithValue.");
String glowColorName = ((FunctionContext.ContextWithValue) functionContext).getValue();
try {
Object glowColor = CacheRegistry.ENUM_CHAT_FORMAT_FIND.load().invoke(null, (
glowColorName == null || glowColorName.length() == 0) ? "WHITE" : glowColorName);
if (glowColor == null)
return NPCFunction.ResultType.FAIL;
npc.getNpcPojo().setGlowName(glowColorName);
npc.setGlowColor(glowColor);
CacheRegistry.SET_DATA_WATCHER_METHOD.load().invoke(CacheRegistry.GET_DATA_WATCHER_METHOD
.load().invoke(npc.getNmsEntity()), ((Constructor) CacheRegistry.DATA_WATCHER_OBJECT_CONSTRUCTOR
.load()).newInstance(Integer.valueOf(0), CacheRegistry.DATA_WATCHER_REGISTER_FIELD
.load()), Byte.valueOf(!FunctionFactory.isTrue(npc, this) ? 64 : 0));
npc.getPackets().getProxyInstance().update(npc.getPackets());
npc.deleteViewers();
return NPCFunction.ResultType.SUCCESS;
} catch (ReflectiveOperationException operationException) {
return NPCFunction.ResultType.FAIL;
}
}
protected boolean allow(NPC npc) {
return npc.getPackets().getProxyInstance().allowGlowColor();
}
public NPCFunction.ResultType resolve(NPC npc) {
return runFunction(npc, new FunctionContext.ContextWithValue(npc, npc.getNpcPojo().getGlowName()));
}
}

@ -0,0 +1,142 @@
package io.github.znetworkw.znpcservers.npc.hologram;
import io.github.znetworkw.znpcservers.UnexpectedCallException;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.configuration.Configuration;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.configuration.ConfigurationValue;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.hologram.replacer.LineReplacer;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Location;
import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
public class Hologram {
private static final String WHITESPACE = " ";
private static final boolean NEW_METHOD = (Utils.BUKKIT_VERSION > 12);
private static final double LINE_SPACING = ((Double) Configuration.CONFIGURATION.getValue(ConfigurationValue.LINE_SPACING)).doubleValue();
private final List<HologramLine> hologramLines = new ArrayList<>();
private final NPC npc;
public Hologram(NPC npc) {
this.npc = npc;
}
public void createHologram() {
this.npc.getViewers().forEach(this::delete);
try {
this.hologramLines.clear();
double y = 0.0D;
Location location = this.npc.getLocation();
for (String line : this.npc.getNpcPojo().getHologramLines()) {
boolean visible = !line.equalsIgnoreCase("%space%");
Object armorStand = ((Constructor) CacheRegistry.ENTITY_CONSTRUCTOR.load()).newInstance(CacheRegistry.GET_HANDLE_WORLD_METHOD.load().invoke(location.getWorld()),
Double.valueOf(location.getX()), Double.valueOf(location.getY() - 0.15D + y), Double.valueOf(location.getZ()));
if (visible) {
CacheRegistry.SET_CUSTOM_NAME_VISIBLE_METHOD.load().invoke(armorStand, Boolean.valueOf(true));
updateLine(line, armorStand, null);
}
CacheRegistry.SET_INVISIBLE_METHOD.load().invoke(armorStand, Boolean.valueOf(true));
this.hologramLines.add(new HologramLine(line.replace(ConfigurationConstants.SPACE_SYMBOL, " "), armorStand, ((Integer) CacheRegistry.GET_ENTITY_ID
.load().invoke(armorStand, new Object[0])).intValue()));
y += LINE_SPACING;
}
setLocation(location, 0.0D);
this.npc.getPackets().flushCache("getHologramSpawnPacket");
this.npc.getViewers().forEach(this::spawn);
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
public void spawn(ZUser user) {
this.hologramLines.forEach(hologramLine -> {
try {
Object entityPlayerPacketSpawn = this.npc.getPackets().getProxyInstance().getHologramSpawnPacket(hologramLine.armorStand);
Utils.sendPackets(user, entityPlayerPacketSpawn);
} catch (ReflectiveOperationException operationException) {
delete(user);
}
});
}
public void delete(ZUser user) {
this.hologramLines.forEach(hologramLine -> {
try {
Utils.sendPackets(user, this.npc.getPackets().getProxyInstance().getDestroyPacket(HologramLine.access$200(hologramLine)));
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
});
}
public void updateNames(ZUser user) {
for (HologramLine hologramLine : this.hologramLines) {
try {
updateLine(hologramLine.line, hologramLine.armorStand, user);
Object metaData = this.npc.getPackets().getProxyInstance().getMetadataPacket(hologramLine.id, hologramLine.armorStand);
Utils.sendPackets(user, metaData);
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
}
public void updateLocation() {
this.hologramLines.forEach(hologramLine -> {
try {
Object packet = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_TELEPORT_CONSTRUCTOR.load()).newInstance(new Object[]{HologramLine.access$100(hologramLine)});
this.npc.getViewers().forEach(());
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
});
}
public void setLocation(Location location, double height) {
location = location.clone().add(0.0D, height, 0.0D);
try {
double y = this.npc.getNpcPojo().getHologramHeight();
for (HologramLine hologramLine : this.hologramLines) {
CacheRegistry.SET_LOCATION_METHOD.load().invoke(hologramLine.armorStand, Double.valueOf(location.getX()), Double.valueOf(location.getY() - 0.15D + y),
Double.valueOf(location.getZ()), Float.valueOf(location.getYaw()), Float.valueOf(location.getPitch()));
y += LINE_SPACING;
}
updateLocation();
} catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException);
}
}
private void updateLine(String line, Object armorStand, @Nullable ZUser user) throws InvocationTargetException, IllegalAccessException {
if (NEW_METHOD) {
CacheRegistry.SET_CUSTOM_NAME_NEW_METHOD.load().invoke(armorStand, CacheRegistry.CRAFT_CHAT_MESSAGE_METHOD.load().invoke(null, LineReplacer.makeAll(user, line)));
} else {
CacheRegistry.SET_CUSTOM_NAME_OLD_METHOD.load().invoke(armorStand, LineReplacer.makeAll(user, line));
}
}
private static class HologramLine {
private final String line;
private final Object armorStand;
private final int id;
protected HologramLine(String line, Object armorStand, int id) {
this.line = line;
this.armorStand = armorStand;
this.id = id;
}
}
}

@ -0,0 +1,26 @@
package io.github.znetworkw.znpcservers.npc.hologram.replacer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.UnmodifiableIterator;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils;
public interface LineReplacer {
ImmutableList<LineReplacer> LINE_REPLACERS = ImmutableList.of(new RGBLine());
static String makeAll(ZUser user, String string) {
for (UnmodifiableIterator<LineReplacer> unmodifiableIterator = LINE_REPLACERS.iterator(); unmodifiableIterator.hasNext(); ) {
LineReplacer lineReplacer = unmodifiableIterator.next();
if (!lineReplacer.isSupported())
continue;
string = lineReplacer.make(string);
}
return Utils.toColor((Utils.PLACEHOLDER_SUPPORT && user != null) ?
Utils.getWithPlaceholders(string, user.toPlayer()) :
string);
}
String make(String paramString);
boolean isSupported();
}

@ -0,0 +1,44 @@
package io.github.znetworkw.znpcservers.npc.hologram.replacer;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.utility.Utils;
import net.md_5.bungee.api.ChatColor;
import java.util.concurrent.ThreadLocalRandom;
public class RGBLine implements LineReplacer {
private static final char HEX_COLOR_CHAR = '#';
private static final int HEX_COLOR_LENGTH = 6;
public String make(String string) {
String rgbString = string;
for (int i = 0; i < rgbString.length(); i++) {
char charAt = rgbString.charAt(i);
if (charAt == '#') {
int endIndex = i + 6 + 1;
boolean success = true;
StringBuilder hexCodeStringBuilder = new StringBuilder();
for (int i2 = i; i2 < endIndex; i2++) {
if (rgbString.length() - 1 < i2) {
success = false;
break;
}
char hexCode = rgbString.charAt(i2);
hexCodeStringBuilder.append((ConfigurationConstants.RGB_ANIMATION && hexCode != '#') ?
Integer.toHexString(ThreadLocalRandom.current().nextInt(16)) : Character.valueOf(hexCode));
}
if (success)
try {
rgbString = rgbString.substring(0, i) + ChatColor.of(hexCodeStringBuilder.toString()) + rgbString.substring(endIndex);
} catch (Exception exception) {
}
}
}
return rgbString;
}
public boolean isSupported() {
return (Utils.BUKKIT_VERSION > 15);
}
}

@ -0,0 +1,112 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableList;
import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.FunctionFactory;
import io.github.znetworkw.znpcservers.npc.ItemSlot;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCType;
import io.github.znetworkw.znpcservers.utility.ReflectionUtils;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Collections;
public interface Packet {
int version();
@PacketValue(keyName = "playerPacket")
Object getPlayerPacket(Object paramObject, GameProfile paramGameProfile) throws ReflectiveOperationException;
@PacketValue(keyName = "spawnPacket")
Object getSpawnPacket(Object paramObject, boolean paramBoolean) throws ReflectiveOperationException;
Object convertItemStack(int paramInt, ItemSlot paramItemSlot, ItemStack paramItemStack) throws ReflectiveOperationException;
Object getClickType(Object paramObject) throws ReflectiveOperationException;
Object getMetadataPacket(int paramInt, Object paramObject) throws ReflectiveOperationException;
@PacketValue(keyName = "hologramSpawnPacket", valueType = ValueType.ARGUMENTS)
Object getHologramSpawnPacket(Object paramObject) throws ReflectiveOperationException;
@PacketValue(keyName = "destroyPacket", valueType = ValueType.ARGUMENTS)
default Object getDestroyPacket(int entityId) throws ReflectiveOperationException {
(new int[1])[0] = entityId;
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR.load()).newInstance(((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_DESTROY_CONSTRUCTOR.load()).getParameterTypes()[0].isArray() ? new int[1] : Integer.valueOf(entityId));
}
@PacketValue(keyName = "enumSlot", valueType = ValueType.ARGUMENTS)
default Object getItemSlot(int slot) {
return CacheRegistry.ENUM_ITEM_SLOT.getEnumConstants()[slot];
}
@PacketValue(keyName = "removeTab")
default Object getTabRemovePacket(Object nmsEntity) throws ReflectiveOperationException {
try {
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_CONSTRUCTOR.load()).newInstance(CacheRegistry.REMOVE_PLAYER_FIELD
.load(),
Collections.singletonList(nmsEntity));
} catch (Throwable throwable) {
boolean useOldMethod = (CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CLASS != null);
if (useOldMethod)
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_REMOVE_CONSTRUCTOR.load())
.newInstance(Collections.singletonList(CacheRegistry.GET_UNIQUE_ID_METHOD.load().invoke(nmsEntity)));
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_PLAYER_INFO_CONSTRUCTOR.load()).newInstance(CacheRegistry.REMOVE_PLAYER_FIELD
.load(), nmsEntity);
}
}
@PacketValue(keyName = "equipPackets")
ImmutableList<Object> getEquipPackets(NPC paramNPC) throws ReflectiveOperationException;
@PacketValue(keyName = "scoreboardPackets")
default ImmutableList<Object> updateScoreboard(NPC npc) throws ReflectiveOperationException {
ImmutableList.Builder<Object> builder = ImmutableList.builder();
boolean isVersion17 = (Utils.BUKKIT_VERSION > 16);
boolean isVersion9 = (Utils.BUKKIT_VERSION > 8);
Object scoreboardTeamPacket = isVersion17 ? ((Constructor) CacheRegistry.SCOREBOARD_TEAM_CONSTRUCTOR.load()).newInstance(new Object[]{null, npc.getGameProfile().getName()}) : ((Constructor) CacheRegistry.PACKET_PLAY_OUT_SCOREBOARD_TEAM_CONSTRUCTOR_OLD.load()).newInstance();
if (!isVersion17) {
Utils.setValue(scoreboardTeamPacket, "a", npc.getGameProfile().getName());
Utils.setValue(scoreboardTeamPacket, isVersion9 ? "i" : "h", Integer.valueOf(1));
}
builder.add(isVersion17 ? CacheRegistry.PACKET_PLAY_OUT_SCOREBOARD_TEAM_CREATE_V1.load().invoke(null, scoreboardTeamPacket) : scoreboardTeamPacket);
if (isVersion17) {
scoreboardTeamPacket = ((Constructor) CacheRegistry.SCOREBOARD_TEAM_CONSTRUCTOR.load()).newInstance(new Object[]{null, npc.getGameProfile().getName()});
if (Utils.BUKKIT_VERSION > 17) {
Utils.setValue(scoreboardTeamPacket, "d", npc.getGameProfile().getName());
ReflectionUtils.findFieldForClassAndSet(scoreboardTeamPacket, CacheRegistry.ENUM_TAG_VISIBILITY, CacheRegistry.ENUM_TAG_VISIBILITY_NEVER_FIELD.load());
Utils.setValue(scoreboardTeamPacket, "m", CacheRegistry.ENUM_CHAT_FORMAT_FIND.load().invoke(null, "DARK_GRAY"));
} else {
Utils.setValue(scoreboardTeamPacket, "e", npc.getGameProfile().getName());
Utils.setValue(scoreboardTeamPacket, "l", CacheRegistry.ENUM_TAG_VISIBILITY_NEVER_FIELD.load());
}
} else {
scoreboardTeamPacket = ((Constructor) CacheRegistry.PACKET_PLAY_OUT_SCOREBOARD_TEAM_CONSTRUCTOR_OLD.load()).newInstance();
Utils.setValue(scoreboardTeamPacket, "a", npc.getGameProfile().getName());
Utils.setValue(scoreboardTeamPacket, "e", "never");
Utils.setValue(scoreboardTeamPacket, isVersion9 ? "i" : "h", Integer.valueOf(0));
}
Collection<String> collection = isVersion17 ? (Collection<String>) CacheRegistry.SCOREBOARD_PLAYER_LIST.load().invoke(scoreboardTeamPacket, new Object[0]) : (Collection<String>) Utils.getValue(scoreboardTeamPacket, isVersion9 ? "h" : "g");
if (npc.getNpcPojo().getNpcType() == NPCType.PLAYER) {
collection.add(npc.getGameProfile().getName());
} else {
collection.add(npc.getUUID().toString());
}
if (allowGlowColor() && FunctionFactory.isTrue(npc, "glow"))
updateGlowPacket(npc, scoreboardTeamPacket);
builder.add(isVersion17 ? CacheRegistry.PACKET_PLAY_OUT_SCOREBOARD_TEAM_CREATE.load().invoke(null, scoreboardTeamPacket, Boolean.TRUE) : scoreboardTeamPacket);
return builder.build();
}
void updateGlowPacket(NPC paramNPC, Object paramObject) throws ReflectiveOperationException;
boolean allowGlowColor();
default void update(PacketCache packetCache) throws ReflectiveOperationException {
packetCache.flushCache("scoreboardPackets");
}
}

@ -0,0 +1,87 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class PacketCache {
protected static final ImmutableMap<Method, PacketValue> VALUE_LOOKUP_BY_NAME;
static {
ImmutableMap.Builder<Method, PacketValue> methodPacketValueBuilder = ImmutableMap.builder();
for (Method method : Packet.class.getMethods()) {
if (method.isAnnotationPresent(PacketValue.class))
methodPacketValueBuilder.put(method, method.getAnnotation(PacketValue.class));
}
VALUE_LOOKUP_BY_NAME = methodPacketValueBuilder.build();
}
private final Map<String, Object> packetResultCache = new ConcurrentHashMap<>();
private final Packet proxyInstance;
public PacketCache(Packet packet) {
this.proxyInstance = newProxyInstance(packet);
}
public PacketCache() {
this(PacketFactory.PACKET_FOR_CURRENT_VERSION);
}
public Packet getProxyInstance() {
return this.proxyInstance;
}
protected Packet newProxyInstance(Packet packet) {
return (Packet) Proxy.newProxyInstance(packet
.getClass().getClassLoader(), new Class[]{Packet.class}, new PacketHandler(this, packet));
}
private Object getOrCache(Packet instance, Method method, Object[] args) {
if (!VALUE_LOOKUP_BY_NAME.containsKey(method))
throw new IllegalStateException("value not found for method: " + method.getName());
PacketValue packetValue = VALUE_LOOKUP_BY_NAME.get(method);
String keyString = packetValue.valueType().resolve(packetValue.keyName(), args);
return this.packetResultCache.computeIfAbsent(keyString, o -> {
try {
return method.invoke(instance, args);
} catch (InvocationTargetException | IllegalAccessException operationException) {
throw new AssertionError("can't invoke method: " + method.getName(), operationException);
}
});
}
public void flushCache(String... strings) {
Set<Map.Entry<String, Object>> set = this.packetResultCache.entrySet();
for (String string : strings)
set.removeIf(entry -> entry.getKey().startsWith(string));
}
public void flushCache() {
flushCache(VALUE_LOOKUP_BY_NAME.values().stream()
.map(PacketValue::keyName).toArray(x$0 -> new String[x$0]));
}
private static class PacketHandler implements InvocationHandler {
private final PacketCache packetCache;
private final Packet packets;
public PacketHandler(PacketCache packetCache, Packet packets) {
this.packetCache = packetCache;
this.packets = packets;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (PacketCache.VALUE_LOOKUP_BY_NAME.containsKey(method))
return this.packetCache.getOrCache(this.packets, method, args);
return method.invoke(this.packets, args);
}
}
}

@ -0,0 +1,19 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableSet;
import io.github.znetworkw.znpcservers.utility.Utils;
import java.util.Comparator;
public final class PacketFactory {
public static final ImmutableSet<Packet> ALL = ImmutableSet.of(new PacketV8(), new PacketV9(), new PacketV16(), new PacketV17(), new PacketV18(), new PacketV19(), (Object[]) new Packet[0]);
public static final Packet PACKET_FOR_CURRENT_VERSION = findPacketForVersion(Utils.BUKKIT_VERSION);
public static Packet findPacketForVersion(int version) {
return ALL.stream()
.filter(packet -> (version >= packet.version()))
.max(Comparator.comparing(Packet::version))
.orElseThrow(() -> new IllegalArgumentException("No packet instance found for version: " + version));
}
}

@ -0,0 +1,28 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.ItemSlot;
import io.github.znetworkw.znpcservers.npc.NPC;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Map;
public class PacketV16 extends PacketV9 {
public int version() {
return 16;
}
public ImmutableList<Object> getEquipPackets(NPC npc) throws ReflectiveOperationException {
List<Pair<?, ?>> pairs = Lists.newArrayListWithCapacity((ItemSlot.values()).length);
for (Map.Entry<ItemSlot, ItemStack> entry : npc.getNpcPojo().getNpcEquip().entrySet())
pairs.add(new Pair(getItemSlot(entry
.getKey().getSlot()),
convertItemStack(npc.getEntityID(), entry.getKey(), entry.getValue())));
return ImmutableList.of(((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_V1.load()).newInstance(Integer.valueOf(npc.getEntityID()), pairs));
}
}

@ -0,0 +1,27 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Bukkit;
import java.lang.reflect.Constructor;
public class PacketV17 extends PacketV16 {
public int version() {
return 17;
}
public Object getPlayerPacket(Object nmsWorld, GameProfile gameProfile) throws ReflectiveOperationException {
return ((Constructor) CacheRegistry.PLAYER_CONSTRUCTOR_NEW.load()).newInstance(new Object[]{CacheRegistry.GET_SERVER_METHOD.load().invoke(Bukkit.getServer()), nmsWorld, gameProfile});
}
public void updateGlowPacket(NPC npc, Object packet) throws ReflectiveOperationException {
Utils.setValue(packet, "n", CacheRegistry.ENUM_CHAT_FORMAT_FIND.load().invoke(null, npc.getNpcPojo().getGlowName()));
}
public Object getClickType(Object interactPacket) {
return "INTERACT";
}
}

@ -0,0 +1,15 @@
package io.github.znetworkw.znpcservers.npc.packet;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.utility.Utils;
public class PacketV18 extends PacketV17 {
public int version() {
return 18;
}
public void updateGlowPacket(NPC npc, Object packet) throws ReflectiveOperationException {
Utils.setValue(packet, "m", CacheRegistry.ENUM_CHAT_FORMAT_FIND.load().invoke(null, npc.getNpcPojo().getGlowName()));
}
}

@ -0,0 +1,23 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import org.bukkit.Bukkit;
import java.lang.reflect.Constructor;
public class PacketV19 extends PacketV18 {
public int version() {
return 19;
}
public Object getPlayerPacket(Object nmsWorld, GameProfile gameProfile) throws ReflectiveOperationException {
try {
return ((Constructor) CacheRegistry.PLAYER_CONSTRUCTOR_NEW_1.load()).newInstance(new Object[]{CacheRegistry.GET_SERVER_METHOD
.load().invoke(Bukkit.getServer()), nmsWorld, gameProfile, null});
} catch (Throwable e) {
return ((Constructor) CacheRegistry.PLAYER_CONSTRUCTOR_NEW_2.load()).newInstance(new Object[]{CacheRegistry.GET_SERVER_METHOD
.load().invoke(Bukkit.getServer()), nmsWorld, gameProfile});
}
}
}

@ -0,0 +1,75 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableList;
import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.ItemSlot;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.util.Map;
public class PacketV8 implements Packet {
public int version() {
return 8;
}
public Object getPlayerPacket(Object nmsWorld, GameProfile gameProfile) throws ReflectiveOperationException {
Constructor<?> constructor = (Utils.BUKKIT_VERSION > 13) ? CacheRegistry.PLAYER_INTERACT_MANAGER_NEW_CONSTRUCTOR.load() : CacheRegistry.PLAYER_INTERACT_MANAGER_OLD_CONSTRUCTOR.load();
return ((Constructor) CacheRegistry.PLAYER_CONSTRUCTOR_OLD.load()).newInstance(new Object[]{CacheRegistry.GET_SERVER_METHOD
.load().invoke(Bukkit.getServer()), nmsWorld, gameProfile, constructor
.newInstance(nmsWorld)});
}
public Object getSpawnPacket(Object nmsEntity, boolean isPlayer) throws ReflectiveOperationException {
return isPlayer ? ((Constructor) CacheRegistry.PACKET_PLAY_OUT_NAMED_ENTITY_CONSTRUCTOR.load()).newInstance(nmsEntity) : ((Constructor) CacheRegistry.PACKET_PLAY_OUT_SPAWN_ENTITY_CONSTRUCTOR.load()).newInstance(nmsEntity);
}
public Object convertItemStack(int entityId, ItemSlot itemSlot, ItemStack itemStack) throws ReflectiveOperationException {
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_OLD.load()).newInstance(Integer.valueOf(entityId),
Integer.valueOf(itemSlot.getSlotOld()), CacheRegistry.AS_NMS_COPY_METHOD
.load().invoke(CacheRegistry.CRAFT_ITEM_STACK_CLASS, itemStack));
}
public Object getClickType(Object interactPacket) throws ReflectiveOperationException {
return Utils.getValue(interactPacket, "action");
}
public Object getMetadataPacket(int entityId, Object nmsEntity) throws ReflectiveOperationException {
Object dataWatcher = CacheRegistry.GET_DATA_WATCHER_METHOD.load().invoke(nmsEntity);
try {
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR.load()).newInstance(Integer.valueOf(entityId), dataWatcher, Boolean.valueOf(true));
} catch (Exception e2) {
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_META_DATA_CONSTRUCTOR_V1
.load())
.newInstance(Integer.valueOf(entityId), CacheRegistry.GET_DATAWATCHER_B_LIST
.load().invoke(dataWatcher));
}
}
public Object getHologramSpawnPacket(Object armorStand) throws ReflectiveOperationException {
return ((Constructor) CacheRegistry.PACKET_PLAY_OUT_SPAWN_ENTITY_CONSTRUCTOR.load()).newInstance(armorStand);
}
public ImmutableList<Object> getEquipPackets(NPC npc) throws ReflectiveOperationException {
ImmutableList.Builder<Object> builder = ImmutableList.builder();
for (Map.Entry<ItemSlot, ItemStack> stackEntry : npc.getNpcPojo().getNpcEquip().entrySet()) {
builder.add(((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_OLD.load()).newInstance(Integer.valueOf(npc.getEntityID()),
Integer.valueOf(stackEntry.getKey().getSlotOld()),
convertItemStack(npc.getEntityID(), stackEntry.getKey(), stackEntry.getValue())));
}
return builder.build();
}
public void updateGlowPacket(NPC npc, Object packet) throws ReflectiveOperationException {
throw new IllegalStateException("Glow color is not supported for 1.8 version.");
}
public boolean allowGlowColor() {
return false;
}
}

@ -0,0 +1,46 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableList;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.ItemSlot;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.util.Map;
public class PacketV9 extends PacketV8 {
public int version() {
return 9;
}
public Object convertItemStack(int entityId, ItemSlot itemSlot, ItemStack itemStack) throws ReflectiveOperationException {
return CacheRegistry.AS_NMS_COPY_METHOD.load().invoke(CacheRegistry.CRAFT_ITEM_STACK_CLASS, itemStack);
}
public ImmutableList<Object> getEquipPackets(NPC npc) throws ReflectiveOperationException {
ImmutableList.Builder<Object> builder = ImmutableList.builder();
for (Map.Entry<ItemSlot, ItemStack> stackEntry : npc.getNpcPojo().getNpcEquip().entrySet()) {
builder.add(((Constructor) CacheRegistry.PACKET_PLAY_OUT_ENTITY_EQUIPMENT_CONSTRUCTOR_NEWEST_OLD.load()).newInstance(Integer.valueOf(npc.getEntityID()),
getItemSlot(stackEntry.getKey().getSlot()),
convertItemStack(npc.getEntityID(), stackEntry.getKey(), stackEntry.getValue())));
}
return builder.build();
}
public void updateGlowPacket(NPC npc, Object packet) throws ReflectiveOperationException {
Object enumChatString = CacheRegistry.ENUM_CHAT_TO_STRING_METHOD.load().invoke(npc.getGlowColor());
if (Utils.BUKKIT_VERSION > 12) {
Utils.setValue(packet, npc.getGlowColor(), CacheRegistry.ENUM_CHAT_CLASS);
Utils.setValue(packet, "c", ((Constructor) CacheRegistry.I_CHAT_BASE_COMPONENT_A_CONSTRUCTOR.load()).newInstance(enumChatString));
} else {
Utils.setValue(packet, "g", CacheRegistry.GET_ENUM_CHAT_ID_METHOD.load().invoke(npc.getGlowColor()));
Utils.setValue(packet, "c", enumChatString);
}
}
public boolean allowGlowColor() {
return true;
}
}

@ -0,0 +1,14 @@
package io.github.znetworkw.znpcservers.npc.packet;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface PacketValue {
String keyName();
ValueType valueType() default ValueType.DEFAULT;
}

@ -0,0 +1,20 @@
package io.github.znetworkw.znpcservers.npc.packet;
import java.util.Arrays;
public enum ValueType {
ARGUMENTS {
String resolve(String keyName, Object[] args) {
if (args.length == 0)
throw new IllegalArgumentException("invalid size, must be > 0");
return keyName + Arrays.hashCode(args);
}
},
DEFAULT {
String resolve(String keyName, Object[] args) {
return keyName;
}
};
abstract String resolve(String paramString, Object[] paramArrayOfObject);
}

@ -0,0 +1,34 @@
package io.github.znetworkw.znpcservers.npc.task;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.npc.NPC;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitRunnable;
public class NPCLoadTask extends BukkitRunnable {
private static final int DELAY = 40;
private static final int MAX_TRIES = 10;
private final NPC npc;
private int tries = 0;
public NPCLoadTask(NPC npc) {
this.npc = npc;
ZNPCsPlus.SCHEDULER.runTaskTimer(this, 40);
}
public void run() {
if (this.tries++ > 10) {
cancel();
return;
}
World world = Bukkit.getWorld(this.npc.getNpcPojo().getLocation().getWorldName());
if (world == null)
return;
cancel();
this.npc.onLoad();
}
}

@ -0,0 +1,43 @@
package io.github.znetworkw.znpcservers.npc.task;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.npc.FunctionFactory;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.user.ZUser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
public class NPCManagerTask extends BukkitRunnable {
public NPCManagerTask(Plugin serversNPC) {
runTaskTimerAsynchronously(serversNPC, 60L, 1L);
}
public void run() {
for (NPC npc : NPC.all()) {
boolean hasPath = (npc.getNpcPath() != null);
if (hasPath)
npc.getNpcPath().handle();
for (Player player : Bukkit.getOnlinePlayers()) {
ZUser zUser = ZUser.find(player);
boolean canSeeNPC = (player.getWorld() == npc.getLocation().getWorld() && player.getLocation().distance(npc.getLocation()) <= ConfigurationConstants.VIEW_DISTANCE);
if (npc.getViewers().contains(zUser) && !canSeeNPC) {
npc.delete(zUser);
continue;
}
if (canSeeNPC) {
if (!npc.getViewers().contains(zUser))
npc.spawn(zUser);
if (FunctionFactory.isTrue(npc, "look") && !hasPath)
npc.lookAt(zUser, player.getLocation(), false);
npc.getHologram().updateNames(zUser);
ConversationModel conversationStorage = npc.getNpcPojo().getConversation();
if (conversationStorage != null && conversationStorage.getConversationType() == ConversationModel.ConversationType.RADIUS)
npc.tryStartConversation(player);
}
}
}
}
}

@ -0,0 +1,15 @@
package io.github.znetworkw.znpcservers.npc.task;
import io.github.znetworkw.znpcservers.configuration.Configuration;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
public class NPCSaveTask extends BukkitRunnable {
public NPCSaveTask(Plugin serversNPC, int seconds) {
runTaskTimer(serversNPC, 200L, seconds);
}
public void run() {
Configuration.SAVE_CONFIGURATIONS.forEach(Configuration::save);
}
}

@ -0,0 +1,89 @@
package io.github.znetworkw.znpcservers.skin;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SkinFetcher {
private static final String EMPTY_STRING = "";
private static final String DEFAULT_CHARSET = "UTF-8";
private static final ExecutorService SKIN_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
private static final JsonParser JSON_PARSER = new JsonParser();
private final SkinFetcherBuilder builder;
public SkinFetcher(SkinFetcherBuilder builder) {
this.builder = builder;
}
public CompletableFuture<JsonObject> doReadSkin(SkinFetcherResult skinFetcherResult) {
CompletableFuture<JsonObject> completableFuture = new CompletableFuture<>();
SKIN_EXECUTOR_SERVICE.submit(() -> {
try {
HttpURLConnection connection = (HttpURLConnection) (new URL(this.builder.getAPIServer().getURL() + getData())).openConnection();
connection.setRequestMethod(this.builder.getAPIServer().getMethod());
if (this.builder.isUrlType()) {
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
try {
outputStream.writeBytes("url=" + URLEncoder.encode(this.builder.getData(), StandardCharsets.UTF_8));
outputStream.close();
} catch (Throwable throwable) {
try {
outputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
}
try {
Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8);
try {
completableFuture.complete(JSON_PARSER.parse(reader).getAsJsonObject());
reader.close();
} catch (Throwable throwable) {
try {
reader.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} finally {
connection.disconnect();
}
} catch (Throwable throwable) {
throwable.printStackTrace();
completableFuture.completeExceptionally(throwable);
}
});
completableFuture.whenComplete((response, throwable) -> {
if (completableFuture.isCompletedExceptionally()) {
skinFetcherResult.onDone(null, throwable);
} else {
JsonObject jsonObject = response.getAsJsonObject(this.builder.getAPIServer().getValueKey());
JsonObject properties = jsonObject.getAsJsonObject(this.builder.getAPIServer().getSignatureKey());
skinFetcherResult.onDone(new String[]{properties.get("value").getAsString(), properties.get("signature").getAsString()}, null);
}
});
return completableFuture;
}
private String getData() {
return this.builder.isProfileType() ? ("/" + this.builder.getData()) : "";
}
}

@ -0,0 +1,76 @@
package io.github.znetworkw.znpcservers.skin;
public class SkinFetcherBuilder {
private final SkinServer apiServer;
private final String name;
protected SkinFetcherBuilder(SkinServer apiServer, String name) {
this.apiServer = apiServer;
this.name = name;
}
public static SkinFetcherBuilder create(SkinServer skinAPIURL, String name) {
return new SkinFetcherBuilder(skinAPIURL, name);
}
public static SkinFetcherBuilder withName(String name) {
return create(name.startsWith("http") ? SkinServer.GENERATE_API : SkinServer.PROFILE_API, name);
}
public SkinServer getAPIServer() {
return this.apiServer;
}
public String getData() {
return this.name;
}
public boolean isUrlType() {
return (this.apiServer == SkinServer.GENERATE_API);
}
public boolean isProfileType() {
return (this.apiServer == SkinServer.PROFILE_API);
}
public SkinFetcher toSkinFetcher() {
return new SkinFetcher(this);
}
public enum SkinServer {
PROFILE_API("GET", "https://api.ashcon.app/mojang/v2/user", "textures", "raw"),
GENERATE_API("POST", "https://api.mineskin.org/generate/url", "data", "texture");
private final String method;
private final String url;
private final String valueKey;
private final String signatureKey;
SkinServer(String method, String url, String valueKey, String signatureKey) {
this.method = method;
this.url = url;
this.valueKey = valueKey;
this.signatureKey = signatureKey;
}
public String getMethod() {
return this.method;
}
public String getURL() {
return this.url;
}
public String getValueKey() {
return this.valueKey;
}
public String getSignatureKey() {
return this.signatureKey;
}
}
}

@ -0,0 +1,5 @@
package io.github.znetworkw.znpcservers.skin;
public interface SkinFetcherResult {
void onDone(String[] paramArrayOfString, Throwable paramThrowable);
}

@ -0,0 +1,60 @@
package io.github.znetworkw.znpcservers.user;
import lol.pyr.znpcsplus.ZNPCsPlus;
import org.bukkit.event.Event;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
public class EventService<T extends Event> {
private final Class<T> eventClass;
private final List<Consumer<T>> eventConsumers;
protected EventService(Class<T> eventClass, List<Consumer<T>> eventConsumers) {
this.eventClass = eventClass;
this.eventConsumers = eventConsumers;
}
public static <T extends Event> EventService<T> addService(ZUser user, Class<T> eventClass) {
if (hasService(user, eventClass))
throw new IllegalStateException(eventClass.getSimpleName() + " is already register for " + user.getUUID().toString());
EventService<T> service = new EventService<>(eventClass, new ArrayList<>());
user.getEventServices().add(service);
user.toPlayer().closeInventory();
return service;
}
public static <T extends Event> EventService<T> findService(ZUser user, Class<T> eventClass) {
Objects.requireNonNull(EventService.class);
Objects.requireNonNull(EventService.class);
return user.getEventServices().stream().filter(eventService -> eventService.getEventClass().isAssignableFrom(eventClass)).map(EventService.class::cast)
.findFirst()
.orElse(null);
}
public static boolean hasService(ZUser user, Class<? extends Event> eventClass) {
return user.getEventServices()
.stream()
.anyMatch(eventService -> (eventService.getEventClass() == eventClass));
}
public Class<T> getEventClass() {
return this.eventClass;
}
public List<Consumer<T>> getEventConsumers() {
return this.eventConsumers;
}
public EventService<T> addConsumer(Consumer<T> consumer) {
getEventConsumers().add(consumer);
return this;
}
public void runAll(T event) {
ZNPCsPlus.SCHEDULER.runTask(() -> this.eventConsumers.forEach(()));
}
}

@ -0,0 +1,139 @@
package io.github.znetworkw.znpcservers.user;
import com.mojang.authlib.GameProfile;
import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCAction;
import io.github.znetworkw.znpcservers.npc.event.ClickType;
import io.github.znetworkw.znpcservers.npc.event.NPCInteractEvent;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.*;
public class ZUser {
private static final String CHANNEL_NAME = "npc_interact";
private static final int DEFAULT_DELAY = 1;
private static final Map<UUID, ZUser> USER_MAP = new HashMap<>();
private final Map<Integer, Long> lastClicked;
private final List<EventService<?>> eventServices;
private final UUID uuid;
private final GameProfile gameProfile;
private final Object playerConnection;
private boolean hasPath = false;
private long lastInteract = 0L;
public ZUser(UUID uuid) {
this.uuid = uuid;
this.lastClicked = new HashMap<>();
this.eventServices = new ArrayList<>();
try {
Object playerHandle = CacheRegistry.GET_HANDLE_PLAYER_METHOD.load().invoke(toPlayer());
this.gameProfile = (GameProfile) CacheRegistry.GET_PROFILE_METHOD.load().invoke(playerHandle, new Object[0]);
Channel channel = (Channel) CacheRegistry.CHANNEL_FIELD.load().get(CacheRegistry.NETWORK_MANAGER_FIELD.load()
.get(this.playerConnection = CacheRegistry.PLAYER_CONNECTION_FIELD.load().get(playerHandle)));
if (channel.pipeline().names().contains("npc_interact"))
channel.pipeline().remove("npc_interact");
channel.pipeline().addAfter("decoder", "npc_interact", (ChannelHandler) new ZNPCSocketDecoder());
} catch (IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
throw new IllegalStateException("can't create player " + uuid.toString(), e.getCause());
}
}
public static ZUser find(UUID uuid) {
return USER_MAP.computeIfAbsent(uuid, ZUser::new);
}
public static ZUser find(Player player) {
return find(player.getUniqueId());
}
public static void unregister(Player player) {
ZUser zUser = USER_MAP.get(player.getUniqueId());
if (zUser == null)
throw new IllegalStateException("can't find user " + player.getUniqueId());
USER_MAP.remove(player.getUniqueId());
NPC.all().stream()
.filter(npc -> npc.getViewers().contains(zUser))
.forEach(npc -> npc.delete(zUser));
}
public UUID getUUID() {
return this.uuid;
}
public GameProfile getGameProfile() {
return this.gameProfile;
}
public Object getPlayerConnection() {
return this.playerConnection;
}
public boolean isHasPath() {
return this.hasPath;
}
public void setHasPath(boolean hasPath) {
this.hasPath = hasPath;
}
public List<EventService<?>> getEventServices() {
return this.eventServices;
}
public Player toPlayer() {
return Bukkit.getPlayer(this.uuid);
}
class ZNPCSocketDecoder extends MessageToMessageDecoder<Object> {
protected void decode(ChannelHandlerContext channelHandlerContext, Object packet, List<Object> out) throws Exception {
out.add(packet);
if (packet.getClass() == CacheRegistry.PACKET_PLAY_IN_USE_ENTITY_CLASS) {
long lastInteractNanos = System.nanoTime() - ZUser.this.lastInteract;
if (ZUser.this.lastInteract != 0L && lastInteractNanos < 1000000000L)
return;
int entityId = CacheRegistry.PACKET_IN_USE_ENTITY_ID_FIELD.load().getInt(packet);
NPC npc = NPC.all().stream().filter(npc1 -> (npc1.getEntityID() == entityId)).findFirst().orElse(null);
if (npc == null)
return;
ClickType clickName = ClickType.forName(npc.getPackets().getProxyInstance().getClickType(packet).toString());
ZUser.this.lastInteract = System.nanoTime();
ZNPCsPlus.SCHEDULER.scheduleSyncDelayedTask(() -> {
Bukkit.getServer().getPluginManager().callEvent(new NPCInteractEvent(ZUser.this.toPlayer(), clickName, npc));
List<NPCAction> actions = npc.getNpcPojo().getClickActions();
if (actions == null || actions.isEmpty())
return;
for (NPCAction npcAction : actions) {
if (npcAction.getClickType() != ClickType.DEFAULT && clickName != npcAction.getClickType())
continue;
if (npcAction.getDelay() > 0) {
int actionId = npc.getNpcPojo().getClickActions().indexOf(npcAction);
if (ZUser.this.lastClicked.containsKey(Integer.valueOf(actionId))) {
long lastClickNanos = System.nanoTime() - ZUser.this.lastClicked.get(Integer.valueOf(actionId)).longValue();
if (lastClickNanos < npcAction.getFixedDelay())
continue;
}
ZUser.this.lastClicked.put(Integer.valueOf(actionId), Long.valueOf(System.nanoTime()));
}
npcAction.run(ZUser.this, npcAction.getAction());
}
}1);
}
}
}
}

@ -0,0 +1,28 @@
package io.github.znetworkw.znpcservers.utility;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class BungeeUtils {
private final Plugin plugin;
public BungeeUtils(Plugin plugin) {
this.plugin = plugin;
}
public void sendPlayerToServer(Player player, String server) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(b);
try {
out.writeUTF("Connect");
out.writeUTF(server);
} catch (IOException e) {
e.printStackTrace();
}
player.sendPluginMessage(this.plugin, "BungeeCord", b.toByteArray());
}
}

@ -0,0 +1,23 @@
package io.github.znetworkw.znpcservers.utility;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
public final class GuavaCollectors {
public static <E> Collector<E, ?, ImmutableList<E>> toImmutableList() {
return Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf);
}
public static <E> Collector<E, ?, ImmutableSet<E>> toImmutableSet() {
return Collectors.collectingAndThen(Collectors.toSet(), ImmutableSet::copyOf);
}
public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(Function<? super T, ? extends K> keyFunction, Function<? super T, ? extends V> valueFunction) {
return Collectors.collectingAndThen(Collectors.toMap(keyFunction, valueFunction), ImmutableMap::copyOf);
}
}

@ -0,0 +1,263 @@
package io.github.znetworkw.znpcservers.utility;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
public class MetricsLite {
public static final int B_STATS_VERSION = 1;
private static final String URL = "https://bStats.org/submitData/bukkit";
private static boolean logFailedRequests;
private static boolean logSentData;
private static boolean logResponseStatusText;
private static String serverUUID;
static {
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
String defaultPackage = new String(new byte[]{
111, 114, 103, 46, 98, 115, 116, 97, 116, 115,
46, 98, 117, 107, 107, 105, 116});
String examplePackage = new String(new byte[]{
121, 111, 117, 114, 46, 112, 97, 99, 107, 97,
103, 101});
if (MetricsLite.class.getPackage().getName().equals(defaultPackage) || MetricsLite.class.getPackage().getName().equals(examplePackage))
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
private final boolean enabled;
private final Plugin plugin;
private final int pluginId;
public MetricsLite(Plugin plugin, int pluginId) {
if (plugin == null)
throw new IllegalArgumentException("Plugin cannot be null!");
this.plugin = plugin;
this.pluginId = pluginId;
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
if (!config.isSet("serverUuid")) {
config.addDefault("enabled", Boolean.TRUE);
config.addDefault("serverUuid", UUID.randomUUID().toString());
config.addDefault("logFailedRequests", Boolean.FALSE);
config.addDefault("logSentData", Boolean.FALSE);
config.addDefault("logResponseStatusText", Boolean.FALSE);
config.options().header("bStats collects some data for plugin authors like how many servers are using their plugins.\nTo honor their work, you should not disable it.\nThis has nearly no effect on the server performance!\nCheck out https://bStats.org/ to learn more :)")
.copyDefaults(true);
try {
config.save(configFile);
} catch (IOException iOException) {
}
}
serverUUID = config.getString("serverUuid");
logFailedRequests = config.getBoolean("logFailedRequests", false);
this.enabled = config.getBoolean("enabled", true);
logSentData = config.getBoolean("logSentData", false);
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
if (this.enabled) {
boolean found = false;
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION");
found = true;
break;
} catch (NoSuchFieldException noSuchFieldException) {
}
}
Bukkit.getServicesManager().register(MetricsLite.class, this, plugin, ServicePriority.Normal);
if (!found)
startSubmitting();
}
}
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
if (data == null)
throw new IllegalArgumentException("Data cannot be null!");
if (Bukkit.isPrimaryThread())
throw new IllegalAccessException("This method must not be called from the main thread!");
if (logSentData)
plugin.getLogger().info("Sending data to bStats: " + data);
HttpsURLConnection connection = (HttpsURLConnection) (new URL("https://bStats.org/submitData/bukkit")).openConnection();
byte[] compressedData = compress(data.toString());
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "MC-Server/1");
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
try {
outputStream.write(compressedData);
outputStream.close();
} catch (Throwable throwable) {
try {
outputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
StringBuilder builder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
try {
String line;
while ((line = bufferedReader.readLine()) != null)
builder.append(line);
bufferedReader.close();
} catch (Throwable throwable) {
try {
bufferedReader.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
if (logResponseStatusText)
plugin.getLogger().info("Sent data to bStats and received response: " + builder);
}
private static byte[] compress(String str) throws IOException {
if (str == null)
return null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
try {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.close();
} catch (Throwable throwable) {
try {
gzip.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
return outputStream.toByteArray();
}
public boolean isEnabled() {
return this.enabled;
}
private void startSubmitting() {
final Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (!MetricsLite.this.plugin.isEnabled()) {
timer.cancel();
return;
}
Bukkit.getScheduler().runTask(MetricsLite.this.plugin, () -> MetricsLite.this.submitData());
}
} 300000L, 1800000L)
}
public JsonObject getPluginData() {
JsonObject data = new JsonObject();
String pluginName = this.plugin.getDescription().getName();
String pluginVersion = this.plugin.getDescription().getVersion();
data.addProperty("pluginName", pluginName);
data.addProperty("id", Integer.valueOf(this.pluginId));
data.addProperty("pluginVersion", pluginVersion);
data.add("customCharts", new JsonArray());
return data;
}
private JsonObject getServerData() {
int playerAmount;
try {
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer(), new Object[0])).size() : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer(), new Object[0])).length;
} catch (Exception e) {
playerAmount = Bukkit.getOnlinePlayers().size();
}
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
String bukkitVersion = Bukkit.getVersion();
String bukkitName = Bukkit.getName();
String javaVersion = System.getProperty("java.version");
String osName = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JsonObject data = new JsonObject();
data.addProperty("serverUUID", serverUUID);
data.addProperty("playerAmount", Integer.valueOf(playerAmount));
data.addProperty("onlineMode", Integer.valueOf(onlineMode));
data.addProperty("bukkitVersion", bukkitVersion);
data.addProperty("bukkitName", bukkitName);
data.addProperty("javaVersion", javaVersion);
data.addProperty("osName", osName);
data.addProperty("osArch", osArch);
data.addProperty("osVersion", osVersion);
data.addProperty("coreCount", Integer.valueOf(coreCount));
return data;
}
private void submitData() {
JsonObject data = getServerData();
JsonArray pluginData = new JsonArray();
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION");
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
if (plugin instanceof JsonObject) {
pluginData.add((JsonElement) plugin);
continue;
}
try {
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
jsonStringGetter.setAccessible(true);
String jsonString = (String) jsonStringGetter.invoke(plugin, new Object[0]);
JsonObject object = (new JsonParser()).parse(jsonString).getAsJsonObject();
pluginData.add(object);
}
} catch (ClassNotFoundException e) {
if (logFailedRequests)
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception ", e);
}
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException |
java.lang.reflect.InvocationTargetException nullPointerException) {
}
}
} catch (NoSuchFieldException noSuchFieldException) {
}
}
data.add("plugins", pluginData);
(new Thread(() -> {
try {
sendData(this.plugin, data);
} catch (Exception e) {
if (logFailedRequests)
this.plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + this.plugin.getName(), e);
}
})).start();
}
}

@ -0,0 +1,23 @@
package io.github.znetworkw.znpcservers.utility;
import java.lang.reflect.Field;
public final class ReflectionUtils {
public static Field findFieldForClass(Object instance, Class<?> type) {
for (Field field : instance.getClass().getDeclaredFields()) {
if (field.getType() == type) {
field.setAccessible(true);
return field;
}
}
return null;
}
public static Field findFieldForClassAndSet(Object instance, Class<?> type, Object value) throws ReflectiveOperationException {
Field field = findFieldForClass(instance, type);
if (field == null)
return null;
field.set(instance, value);
return field;
}
}

@ -0,0 +1,34 @@
package io.github.znetworkw.znpcservers.utility;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
public class SchedulerUtils {
private final Plugin plugin;
public SchedulerUtils(Plugin plugin) {
this.plugin = plugin;
}
public BukkitTask runTaskTimer(BukkitRunnable bukkitRunnable, int delay) {
return runTaskTimer(bukkitRunnable, delay, delay);
}
public BukkitTask runTaskTimer(BukkitRunnable bukkitRunnable, int delay, int continuousDelay) {
return bukkitRunnable.runTaskTimer(this.plugin, delay, continuousDelay);
}
public BukkitTask runTaskTimerAsynchronously(Runnable runnable, int delay, int continuousDelay) {
return Bukkit.getScheduler().runTaskTimerAsynchronously(this.plugin, runnable, delay, continuousDelay);
}
public void scheduleSyncDelayedTask(Runnable runnable, int delay) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, runnable, delay);
}
public BukkitTask runTask(Runnable runnable) {
return Bukkit.getScheduler().runTask(this.plugin, runnable);
}
}

@ -0,0 +1,86 @@
package io.github.znetworkw.znpcservers.utility;
import io.github.znetworkw.znpcservers.cache.CacheRegistry;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.user.ZUser;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.util.concurrent.ThreadLocalRandom;
public final class Utils {
public static final int BUKKIT_VERSION;
public static final long SECOND_INTERVAL_NANOS = 1000000000L;
public static boolean PLACEHOLDER_SUPPORT = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI");
static {
BUKKIT_VERSION = NumberUtils.toInt(getFormattedBukkitPackage());
}
public static boolean versionNewer(int version) {
return (BUKKIT_VERSION >= version);
}
public static String getBukkitPackage() {
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
}
public static String getFormattedBukkitPackage() {
String version = getBukkitPackage().replace("v", "").replace("R", "");
return version.substring(2, version.length() - 2);
}
public static String toColor(String string) {
return ChatColor.translateAlternateColorCodes('&', string);
}
public static String getWithPlaceholders(String string, Player player) {
return PlaceholderAPI.setPlaceholders(player, string).replace(ConfigurationConstants.SPACE_SYMBOL, " ");
}
public static String randomString(int length) {
StringBuilder stringBuilder = new StringBuilder();
for (int index = 0; index < length; index++)
stringBuilder.append(ThreadLocalRandom.current().nextInt(0, 9));
return stringBuilder.toString();
}
public static void sendTitle(Player player, String title, String subTitle) {
player.sendTitle(toColor(title), toColor(subTitle));
}
public static void setValue(Object fieldInstance, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field f = fieldInstance.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
f.set(fieldInstance, value);
}
public static void setValue(Object fieldInstance, Object value, Class<?> expectedType) throws NoSuchFieldException, IllegalAccessException {
for (Field field : fieldInstance.getClass().getDeclaredFields()) {
if (field.getType() == expectedType)
setValue(fieldInstance, field.getName(), value);
}
}
public static Object getValue(Object instance, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field f = instance.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(instance);
}
public static void sendPackets(ZUser user, Object... packets) {
try {
for (Object packet : packets) {
if (packet != null)
CacheRegistry.SEND_PACKET_METHOD.load().invoke(user.getPlayerConnection(), packet);
}
} catch (IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
}
}

@ -0,0 +1,51 @@
package io.github.znetworkw.znpcservers.utility.inventory;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
public class ZInventory {
private final Player player;
private ZInventoryPage page;
private Inventory inventory;
public ZInventory(Player player) {
this.player = player;
}
public Player getPlayer() {
return this.player;
}
public ZInventoryPage getPage() {
return this.page;
}
public Inventory getInventory() {
return this.inventory;
}
public void setCurrentPage(ZInventoryPage page) {
this.page = page;
}
public Inventory build(ZInventoryPage page) {
if (page == null)
throw new IllegalStateException("page is null");
if (page.getRows() / 9 > 6)
throw new IllegalArgumentException(String.format("Unexpected rows size. Has %d, max %d", Integer.valueOf(page.getRows()), Integer.valueOf(6)));
setCurrentPage(page);
page.getInventoryItems().removeIf(zInventoryItem -> !zInventoryItem.isDefault());
page.update();
this.inventory = Bukkit.createInventory(new ZInventoryHolder(this), page.getRows(), Utils.toColor(page.getPageName()));
page.getInventoryItems().forEach(zInventoryItem -> this.inventory.setItem(zInventoryItem.getSlot(), zInventoryItem.getItemStack()));
return this.inventory;
}
public Inventory build() {
return build(this.page);
}
}

@ -0,0 +1,7 @@
package io.github.znetworkw.znpcservers.utility.inventory;
import org.bukkit.event.inventory.InventoryClickEvent;
public interface ZInventoryCallback {
void onClick(InventoryClickEvent paramInventoryClickEvent);
}

@ -0,0 +1,20 @@
package io.github.znetworkw.znpcservers.utility.inventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public class ZInventoryHolder implements InventoryHolder {
private final ZInventory zInventory;
public ZInventoryHolder(ZInventory zInventory) {
this.zInventory = zInventory;
}
public ZInventory getzInventory() {
return this.zInventory;
}
public Inventory getInventory() {
return this.zInventory.getInventory();
}
}

@ -0,0 +1,36 @@
package io.github.znetworkw.znpcservers.utility.inventory;
import org.bukkit.inventory.ItemStack;
public class ZInventoryItem {
private final ItemStack itemStack;
private final int slot;
private final boolean isDefault;
private final ZInventoryCallback clickCallback;
public ZInventoryItem(ItemStack itemStack, int slot, boolean isDefault, ZInventoryCallback zInventoryCallback) {
this.itemStack = itemStack;
this.slot = slot;
this.isDefault = isDefault;
this.clickCallback = zInventoryCallback;
}
public ItemStack getItemStack() {
return this.itemStack;
}
public int getSlot() {
return this.slot;
}
public boolean isDefault() {
return this.isDefault;
}
public ZInventoryCallback getInventoryCallback() {
return this.clickCallback;
}
}

@ -0,0 +1,82 @@
package io.github.znetworkw.znpcservers.utility.inventory;
import io.github.znetworkw.znpcservers.utility.itemstack.ItemStackBuilder;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
public abstract class ZInventoryPage {
private final ZInventory zInventory;
private final String pageName;
private final int rows;
private final List<ZInventoryItem> inventoryItems;
public ZInventoryPage(ZInventory zInventory, String inventoryName, int rows) {
this.zInventory = zInventory;
this.pageName = inventoryName;
this.rows = rows * 9;
this.inventoryItems = new ArrayList<>();
if (zInventory.getInventory() != null) {
ZInventoryPage zInventoryPage = zInventory.getPage();
addItem(ItemStackBuilder.forMaterial(Material.ARROW)
.setName(ChatColor.GREEN + "Go back")
.setLore(new String[]{ChatColor.GRAY + "click here..."}, ).build(), this.rows - 9, true, event -> {
zInventory.setCurrentPage(zInventoryPage);
openInventory();
});
}
zInventory.setCurrentPage(this);
}
public ZInventory getInventory() {
return this.zInventory;
}
public String getPageName() {
return this.pageName;
}
public int getRows() {
return this.rows;
}
public List<ZInventoryItem> getInventoryItems() {
return this.inventoryItems;
}
public boolean containsItem(int slot) {
return this.inventoryItems.stream().anyMatch(zInventoryItem -> (zInventoryItem.getSlot() == slot));
}
public ZInventoryItem findItem(int slot) {
return this.inventoryItems.stream()
.filter(zInventoryItem -> (zInventoryItem.getSlot() == slot))
.findFirst()
.orElseThrow(() -> new IllegalStateException("can't find item for slot " + slot));
}
public void addItem(ItemStack itemStack, int slot, boolean isDefault, ZInventoryCallback callback) {
this.inventoryItems.add(new ZInventoryItem(itemStack, slot, isDefault, callback));
}
public void addItem(ItemStack itemStack, int slot, ZInventoryCallback callback) {
addItem(itemStack, slot, false, callback);
}
public Player getPlayer() {
return this.zInventory.getPlayer();
}
public void openInventory() {
this.zInventory.getPlayer().openInventory(this.zInventory.build());
}
public abstract void update();
}

@ -0,0 +1,53 @@
package io.github.znetworkw.znpcservers.utility.itemstack;
import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class ItemStackBuilder {
private final ItemStack itemStack;
private final ItemMeta itemMeta;
protected ItemStackBuilder(ItemStack stack) {
this.itemStack = stack;
this.itemMeta = stack.getItemMeta();
}
public static ItemStackBuilder forMaterial(Material material) {
if (material == null || material == Material.AIR)
throw new IllegalStateException("can't create builder for a NULL material.");
return new ItemStackBuilder(new ItemStack(material, 1));
}
public ItemStackBuilder setName(String name) {
this.itemMeta.setDisplayName(Utils.toColor(name));
return this;
}
public ItemStackBuilder setLore(Iterable<String> lore) {
this.itemMeta.setLore(StreamSupport.stream(lore.spliterator(), false)
.map(Utils::toColor).collect(Collectors.toList()));
this.itemStack.setItemMeta(this.itemMeta);
return this;
}
public ItemStackBuilder setLore(String... lore) {
return setLore(Arrays.asList(lore));
}
public ItemStackBuilder setAmount(int amount) {
this.itemStack.setAmount(amount);
return this;
}
public ItemStack build() {
this.itemStack.setItemMeta(this.itemMeta);
return this.itemStack;
}
}

@ -0,0 +1,80 @@
package io.github.znetworkw.znpcservers.utility.itemstack;
import com.google.gson.*;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Base64;
public class ItemStackSerializer implements JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> {
private static final ItemStack DEFAULT = new ItemStack(Material.AIR);
public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(Base64.getDecoder().decode(json.getAsString()));
try {
BukkitObjectInputStream bukkitObjectOutputStream = new BukkitObjectInputStream(byteArrayInputStream);
try {
ItemStack itemStack = (ItemStack) bukkitObjectOutputStream.readObject();
bukkitObjectOutputStream.close();
byteArrayInputStream.close();
return itemStack;
} catch (Throwable throwable) {
try {
bukkitObjectOutputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (Throwable throwable) {
try {
byteArrayInputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (IOException | ClassNotFoundException e) {
return DEFAULT;
}
}
public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
BukkitObjectOutputStream bukkitObjectOutputStream = new BukkitObjectOutputStream(byteArrayOutputStream);
try {
bukkitObjectOutputStream.writeObject(src);
JsonPrimitive jsonPrimitive = new JsonPrimitive(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
bukkitObjectOutputStream.close();
byteArrayOutputStream.close();
return jsonPrimitive;
} catch (Throwable throwable) {
try {
bukkitObjectOutputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (Throwable throwable) {
try {
byteArrayOutputStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (IOException e) {
throw new JsonParseException("Cannot serialize itemstack", e);
}
}
}

@ -0,0 +1,102 @@
package io.github.znetworkw.znpcservers.utility.location;
import com.google.gson.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import java.lang.reflect.Type;
public class ZLocation {
public static final ZLocationSerializer SERIALIZER = new ZLocationSerializer();
private final String worldName;
private final double x;
private final double y;
private final double z;
private final float yaw;
private final float pitch;
private Location bukkitLocation;
public ZLocation(String worldName, double x, double y, double z, float yaw, float pitch) {
this.worldName = worldName;
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
}
public ZLocation(Location location) {
this(location.getWorld().getName(), location
.getX(), location
.getY(), location
.getZ(), location
.getYaw(), location
.getPitch());
}
public String getWorldName() {
return this.worldName;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public double getZ() {
return this.z;
}
public float getYaw() {
return this.yaw;
}
public float getPitch() {
return this.pitch;
}
public Location bukkitLocation() {
if (this.bukkitLocation != null)
return this.bukkitLocation;
return this
.bukkitLocation = new Location(Bukkit.getWorld(this.worldName), this.x, this.y, this.z, this.yaw, this.pitch);
}
public Vector toVector() {
return bukkitLocation().toVector();
}
static class ZLocationSerializer implements JsonSerializer<ZLocation>, JsonDeserializer<ZLocation> {
public JsonElement serialize(ZLocation src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("world", src.getWorldName());
jsonObject.addProperty("x", Double.valueOf(src.getX()));
jsonObject.addProperty("y", Double.valueOf(src.getY()));
jsonObject.addProperty("z", Double.valueOf(src.getZ()));
jsonObject.addProperty("yaw", Float.valueOf(src.getYaw()));
jsonObject.addProperty("pitch", Float.valueOf(src.getPitch()));
return jsonObject;
}
public ZLocation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
return new ZLocation(jsonObject.get("world").getAsString(), jsonObject
.get("x").getAsDouble(), jsonObject
.get("y").getAsDouble(), jsonObject
.get("z").getAsDouble(), jsonObject
.get("yaw").getAsFloat(), jsonObject
.get("pitch").getAsFloat());
}
}
}

@ -0,0 +1,95 @@
package lol.pyr.znpcsplus;
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.github.znetworkw.znpcservers.commands.list.DefaultCommand;
import io.github.znetworkw.znpcservers.configuration.Configuration;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.listeners.InventoryListener;
import io.github.znetworkw.znpcservers.listeners.PlayerListener;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCModel;
import io.github.znetworkw.znpcservers.npc.NPCPath;
import io.github.znetworkw.znpcservers.npc.NPCType;
import io.github.znetworkw.znpcservers.npc.task.NPCManagerTask;
import io.github.znetworkw.znpcservers.npc.task.NPCSaveTask;
import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.BungeeUtils;
import io.github.znetworkw.znpcservers.utility.MetricsLite;
import io.github.znetworkw.znpcservers.utility.SchedulerUtils;
import io.github.znetworkw.znpcservers.utility.itemstack.ItemStackSerializer;
import io.github.znetworkw.znpcservers.utility.location.ZLocation;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.Collections;
public class ZNPCsPlus extends JavaPlugin {
public static final File PLUGIN_FOLDER = new File("plugins/ServersNPC");
public static final File PATH_FOLDER = new File("plugins/ServersNPC/paths");
public static final Gson GSON = (new GsonBuilder())
.registerTypeAdapter(ZLocation.class, ZLocation.SERIALIZER)
.registerTypeHierarchyAdapter(ItemStack.class, new ItemStackSerializer())
.setPrettyPrinting()
.disableHtmlEscaping()
.create();
private static final int PLUGIN_ID = 8054;
public static SchedulerUtils SCHEDULER;
public static BungeeUtils BUNGEE_UTILS;
public static NPC createNPC(int id, NPCType npcType, Location location, String name) {
NPC find = NPC.find(id);
if (find != null)
return find;
NPCModel pojo = (new NPCModel(id)).withHologramLines(Collections.singletonList(name)).withLocation(new ZLocation(location)).withNpcType(npcType);
ConfigurationConstants.NPC_LIST.add(pojo);
return new NPC(pojo, true);
}
public static void deleteNPC(int npcID) {
NPC npc = NPC.find(npcID);
if (npc == null)
throw new IllegalStateException("can't find npc: " + npcID);
NPC.unregister(npcID);
ConfigurationConstants.NPC_LIST.remove(npc.getNpcPojo());
}
public void onEnable() {
ImmutableList<File> files = ImmutableList.of(PLUGIN_FOLDER, PATH_FOLDER);
for (File file : files) file.mkdirs();
loadAllPaths();
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
new MetricsLite(this, PLUGIN_ID);
new DefaultCommand();
SCHEDULER = new SchedulerUtils(this);
BUNGEE_UTILS = new BungeeUtils(this);
Bukkit.getOnlinePlayers().forEach(ZUser::find);
new NPCManagerTask(this);
new NPCSaveTask(this, ConfigurationConstants.SAVE_DELAY);
new PlayerListener(this);
new InventoryListener(this);
}
public void onDisable() {
Configuration.SAVE_CONFIGURATIONS.forEach(Configuration::save);
Bukkit.getOnlinePlayers().forEach(ZUser::unregister);
}
public void loadAllPaths() {
File[] listFiles = PATH_FOLDER.listFiles();
if (listFiles == null)
return;
for (File file : listFiles) {
if (file.getName().endsWith(".path")) {
NPCPath.AbstractTypeWriter abstractTypeWriter = NPCPath.AbstractTypeWriter.forFile(file, NPCPath.AbstractTypeWriter.TypeWriter.MOVEMENT);
abstractTypeWriter.load();
}
}
}
}

@ -0,0 +1,5 @@
name: ZNPCsPlus
main: lol.pyr.znpcsplus.ZNPCsPlus
version: ${version}
api-version: 1.13
softdepend: [ PlaceholderAPI ]