Initial commit.
commit
37fc63ac94
|
@ -0,0 +1,118 @@
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Ignore Gradle GUI config
|
||||||
|
gradle-app.setting
|
||||||
|
|
||||||
|
# Cache of project
|
||||||
|
.gradletasknamecache
|
||||||
|
|
||||||
|
**/build/
|
||||||
|
|
||||||
|
# Common working directory
|
||||||
|
run/
|
||||||
|
|
||||||
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
|
!gradle-wrapper.jar
|
|
@ -0,0 +1,34 @@
|
||||||
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id "io.freefair.lombok" version "6.0.0-m2"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = 'nl.kallestruik'
|
||||||
|
version = '1.0'
|
||||||
|
|
||||||
|
sourceCompatibility = '1.8'
|
||||||
|
targetCompatibility = '1.8'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
name = 'papermc-repo'
|
||||||
|
url = 'https://papermc.io/repo/repository/maven-public/'
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
name = 'sonatype'
|
||||||
|
url = 'https://oss.sonatype.org/content/groups/public/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
filter ReplaceTokens, tokens: [version: version]
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,188 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or 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 UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
|
@ -0,0 +1,100 @@
|
||||||
|
@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 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 init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
|
@ -0,0 +1,70 @@
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
# A list of folders to check for icon_info.json files and sheets/ folders.
|
||||||
|
FOLDERS = ["mc_items"]
|
||||||
|
|
||||||
|
def to_symbol_string(number):
|
||||||
|
return "\\ue" + str(hex(number))[2:].zfill(3)
|
||||||
|
|
||||||
|
# The emotedb to store later.
|
||||||
|
emotedb = []
|
||||||
|
current_index = 0
|
||||||
|
|
||||||
|
# A map containing information about all texture sheets and where they belong.
|
||||||
|
# Format: {folder_name: [{icons: [[],[],[]]}]}
|
||||||
|
sheets = {}
|
||||||
|
|
||||||
|
|
||||||
|
for folder in FOLDERS:
|
||||||
|
with open(f"{folder}/icon_info.json", "r") as icon_info_file:
|
||||||
|
icon_info = json.load(icon_info_file)
|
||||||
|
sheet_array = []
|
||||||
|
for sheet in os.listdir(f"{folder}/sheets/"):
|
||||||
|
sheet_array.append({"icons": [['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000'], ['\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000', '\\u0000']]})
|
||||||
|
|
||||||
|
sheets[folder] = sheet_array
|
||||||
|
|
||||||
|
for icon in icon_info:
|
||||||
|
symbol = to_symbol_string(current_index)
|
||||||
|
sheets[folder][icon["sheet"]]["icons"][icon["pos"] // 16][icon["pos"] % 16] = symbol
|
||||||
|
emotedb.append({
|
||||||
|
"name": icon["name"],
|
||||||
|
"symbol": symbol,
|
||||||
|
"description": icon["description"]
|
||||||
|
})
|
||||||
|
|
||||||
|
current_index += 1
|
||||||
|
|
||||||
|
with open("emotedb.json", "w") as emotedb_file:
|
||||||
|
data = json.dumps(emotedb).encode().decode("unicode-escape")
|
||||||
|
emotedb_file.write(data)
|
||||||
|
|
||||||
|
providers = []
|
||||||
|
|
||||||
|
os.mkdir
|
||||||
|
|
||||||
|
pathlib.Path("pack/assets/dchat/textures/font/").mkdir(parents=True, exist_ok=True)
|
||||||
|
pathlib.Path("pack/assets/minecraft/font/").mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
for sheet_group in sheets:
|
||||||
|
sheet_array = sheets[sheet_group]
|
||||||
|
for index in range(len(sheet_array)):
|
||||||
|
sheet = sheet_array[index]
|
||||||
|
shutil.copy(f"{sheet_group}/sheets/sheet_{index}.png", f"pack/assets/dchat/textures/font/{sheet_group}_{index}.png")
|
||||||
|
chars = []
|
||||||
|
for row in sheet["icons"]:
|
||||||
|
chars.append("".join(row))
|
||||||
|
providers.append({
|
||||||
|
"type": "bitmap",
|
||||||
|
"file": f"dchat:font/{sheet_group}_{index}.png",
|
||||||
|
"ascent": 7,
|
||||||
|
"chars": chars
|
||||||
|
})
|
||||||
|
|
||||||
|
with open("pack/assets/minecraft/font/default.json", "w") as font_file:
|
||||||
|
data = json.dumps({"providers": providers}).encode().decode("unicode-escape")
|
||||||
|
font_file.write(data)
|
|
@ -0,0 +1,81 @@
|
||||||
|
from PIL import Image
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
# The size of each image in pixels.
|
||||||
|
IMAGE_SIZE = 16
|
||||||
|
# The directory containing the item image files.
|
||||||
|
ITEM_DIR = "item/"
|
||||||
|
# The directory that willcontain the texture sheet files.
|
||||||
|
SHEET_DIR = "sheets/"
|
||||||
|
|
||||||
|
# The size that the texture sheet will be. Should be 16 times the IMAGE_SIZE.
|
||||||
|
SHEET_SIZE = IMAGE_SIZE * 16
|
||||||
|
|
||||||
|
# Get a list of files in the item directory.
|
||||||
|
item_files = os.listdir(ITEM_DIR)
|
||||||
|
|
||||||
|
# Sort the list of items.
|
||||||
|
item_files = sorted(item_files)
|
||||||
|
|
||||||
|
# Create a new image of size SHEET_SIZE x SHEET_SIZE.
|
||||||
|
current_sheet = Image.new("RGBA", (SHEET_SIZE, SHEET_SIZE), (0, 0, 0, 0))
|
||||||
|
# Set the current position on the sheet to 0.
|
||||||
|
current_pos = 0
|
||||||
|
# Create an array to store finished sheets.
|
||||||
|
sheets = []
|
||||||
|
|
||||||
|
# Create an array to hold icon info.
|
||||||
|
icon_info = []
|
||||||
|
|
||||||
|
# Create the SHEET_DIR directory.
|
||||||
|
os.makedirs(SHEET_DIR)
|
||||||
|
|
||||||
|
# Loop over every item and add it to the texture sheet we are currently working on.
|
||||||
|
for item_file in item_files:
|
||||||
|
# Get the name of the item.
|
||||||
|
name = item_file.replace(".png", "")
|
||||||
|
|
||||||
|
# Load the image from disk.
|
||||||
|
image = Image.open(f"{ITEM_DIR}{item_file}")
|
||||||
|
|
||||||
|
# Calculate our position on the sheet.
|
||||||
|
x = current_pos % 16
|
||||||
|
y = current_pos // 16
|
||||||
|
|
||||||
|
# Paste the current item on the sheet.
|
||||||
|
current_sheet.paste(im=image, box=(x*16, y * 16))
|
||||||
|
|
||||||
|
icon_info.append({
|
||||||
|
"name": name,
|
||||||
|
"sheet": len(sheets),
|
||||||
|
"pos": current_pos,
|
||||||
|
"description": ["A default minecraft item."]
|
||||||
|
})
|
||||||
|
|
||||||
|
# Move one texture over on the sheet.
|
||||||
|
current_pos += 1
|
||||||
|
|
||||||
|
# Check if the current sheet is full.
|
||||||
|
if current_pos == 256:
|
||||||
|
# If it is add it to the array of finished sheets.
|
||||||
|
sheets.append(current_sheet)
|
||||||
|
# And create a new one.
|
||||||
|
current_sheet = Image.new("RGBA", (SHEET_SIZE, SHEET_SIZE), (0, 0, 0, 0))
|
||||||
|
# Move us back to the start of the current sheet.
|
||||||
|
current_pos = 0
|
||||||
|
|
||||||
|
# Check if the current sheet is partially filled.
|
||||||
|
if not current_pos == 0:
|
||||||
|
# If it is add it to the finished sheets.
|
||||||
|
sheets.append(current_sheet)
|
||||||
|
|
||||||
|
# Loop over all finished sheets.
|
||||||
|
for i in range(len(sheets)):
|
||||||
|
sheet = sheets[i]
|
||||||
|
# Save the sheet to disk.
|
||||||
|
sheet.save(f"{SHEET_DIR}sheet_{i}.png")
|
||||||
|
|
||||||
|
# Store icon_info into a json file.
|
||||||
|
with open("icon_info.json", "w") as icon_info_file:
|
||||||
|
json.dump(icon_info, icon_info_file, indent=4)
|
|
@ -0,0 +1 @@
|
||||||
|
rootProject.name = 'dchat'
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.kallestruik.dchat;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
|
||||||
|
public class Config {
|
||||||
|
public static final Component CHAT_FORMAT = GsonComponentSerializer.gson().deserialize("{\"text\": \"%USERNAME%: %MESSAGE%\"}");
|
||||||
|
public static final String RESOURCE_PACK_URL_BASE = "http://dchat.kallestruik.nl/downloads/pack/";
|
||||||
|
public static final String EMOTE_DB_URL = "http://dchat.kallestruik.nl/downloads/emotedb/emotedb.json";
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package nl.kallestruik.dchat;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
import nl.kallestruik.dchat.commands.CommandCAdmin;
|
||||||
|
import nl.kallestruik.dchat.commands.CommandChat;
|
||||||
|
import nl.kallestruik.dchat.commands.CommandChatsettings;
|
||||||
|
import nl.kallestruik.dchat.commands.CommandEmojitest;
|
||||||
|
import nl.kallestruik.dchat.gson.TextColorTypeAdapter;
|
||||||
|
import nl.kallestruik.dchat.listeners.ChatListener;
|
||||||
|
import nl.kallestruik.dchat.listeners.JoinListener;
|
||||||
|
import nl.kallestruik.dchat.managers.EmojiManager;
|
||||||
|
import nl.kallestruik.dchat.managers.PlayerDataManager;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public final class DChat extends JavaPlugin {
|
||||||
|
public static DChat instance;
|
||||||
|
public static Logger logger;
|
||||||
|
public static Gson gson = new GsonBuilder()
|
||||||
|
.registerTypeAdapter(TextColor.class, new TextColorTypeAdapter())
|
||||||
|
.create();
|
||||||
|
public static String packHash = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
logger = this.getLogger();
|
||||||
|
|
||||||
|
createDataFolderIfNotExists();
|
||||||
|
|
||||||
|
updateResourcePackHash();
|
||||||
|
|
||||||
|
EmojiManager.loadEmotesFromDisk();
|
||||||
|
|
||||||
|
// Load console player data.
|
||||||
|
PlayerDataManager.loadPlayerData(new UUID(0, 0));
|
||||||
|
|
||||||
|
getServer().getPluginManager().registerEvents(new ChatListener(),this);
|
||||||
|
getServer().getPluginManager().registerEvents(new JoinListener(), this);
|
||||||
|
|
||||||
|
getCommand("emojitest").setExecutor(new CommandEmojitest());
|
||||||
|
|
||||||
|
getCommand("chat").setExecutor(new CommandChat());
|
||||||
|
getCommand("chat").setTabCompleter(new CommandChat());
|
||||||
|
|
||||||
|
getCommand("chatsettings").setExecutor(new CommandChatsettings());
|
||||||
|
getCommand("chatsettings").setTabCompleter(new CommandChatsettings());
|
||||||
|
|
||||||
|
getCommand("cadmin").setExecutor(new CommandCAdmin());
|
||||||
|
getCommand("cadmin").setTabCompleter(new CommandCAdmin());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
// Plugin shutdown logic
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateResourcePackHash() {
|
||||||
|
packHash = Util.httpGET(Config.RESOURCE_PACK_URL_BASE + "get_hash.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDataFolderIfNotExists() {
|
||||||
|
File dataFolder = new File(this.getDataFolder(), "data");
|
||||||
|
dataFolder.mkdirs();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package nl.kallestruik.dchat;
|
||||||
|
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class Util {
|
||||||
|
|
||||||
|
public static UUID getUUID(CommandSender sender) {
|
||||||
|
// A UUID of all zero's is used as console.
|
||||||
|
return sender instanceof Player ? ((Player) sender).getUniqueId() : new UUID(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to export a file from the jar to an external folder.
|
||||||
|
*
|
||||||
|
* @param resourceName the name of the resource
|
||||||
|
* @param output file that will be outputted to
|
||||||
|
*/
|
||||||
|
public static void exportResource(String resourceName, File output) {
|
||||||
|
try (InputStream stream = Util.class.getResourceAsStream(resourceName); OutputStream resStreamOut = new FileOutputStream(output)) {
|
||||||
|
if (stream == null) {
|
||||||
|
throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int readBytes;
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
while ((readBytes = stream.read(buffer)) > 0) {
|
||||||
|
resStreamOut.write(buffer, 0, readBytes);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
//Fail silently
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String httpGET(String url) {
|
||||||
|
try {
|
||||||
|
HttpURLConnection connection = ((HttpURLConnection) new URL(url).openConnection());
|
||||||
|
connection.setRequestMethod("GET");
|
||||||
|
connection.setRequestProperty("User-Agent", "DChat");
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||||
|
return reader.lines().collect(Collectors.joining());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package nl.kallestruik.dchat.commands;
|
||||||
|
|
||||||
|
import nl.kallestruik.dchat.managers.EmojiManager;
|
||||||
|
import nl.kallestruik.dchat.managers.PlayerDataManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class CommandCAdmin implements CommandExecutor, TabCompleter {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
|
if (args.length == 1 && args[0].equalsIgnoreCase("update-emotes")) {
|
||||||
|
EmojiManager.updateEmotes();
|
||||||
|
return true;
|
||||||
|
} else if (args.length == 4 && args[0].equalsIgnoreCase("user")) {
|
||||||
|
UUID uuid = Bukkit.getPlayer(args[2]).getUniqueId();
|
||||||
|
switch (args[2]) {
|
||||||
|
case "pingSound":
|
||||||
|
if (PlayerDataManager.changePingSoundSettingForUUID(uuid, args[3]))
|
||||||
|
sender.sendMessage("Changed ping sound to: " + args[3]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
case "nameColor":
|
||||||
|
if (PlayerDataManager.changeNameColorSettingForUUID(uuid, args[3]))
|
||||||
|
sender.sendMessage("Changed name color to: " + args[3]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
case "prefixColor":
|
||||||
|
if (PlayerDataManager.changePrefixColorSettingForUUID(uuid, args[3]))
|
||||||
|
sender.sendMessage("Changed prefix color to: " + args[3]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
case "prefix":
|
||||||
|
String prefix = String.join(" ", Arrays.copyOfRange(args, 3, args.length));
|
||||||
|
if (PlayerDataManager.changePrefixSettingForUUID(uuid, prefix))
|
||||||
|
sender.sendMessage("Changed prefix to: " + prefix);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
|
if (args.length == 1)
|
||||||
|
return List.of("update-emotes", "user").stream().filter((option) -> option.startsWith(args[0])).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (args.length == 3) {
|
||||||
|
switch (args[0]) {
|
||||||
|
case "user": {
|
||||||
|
return List.of("pingSound", "nameColor", "prefixColor", "prefix").stream().filter((option) -> option.startsWith(args[1])).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length == 4)
|
||||||
|
switch (args[2]) {
|
||||||
|
case "pingSound":
|
||||||
|
return List.of("Yes", "No");
|
||||||
|
case "nameColor":
|
||||||
|
case "prefixColor":
|
||||||
|
return List.of("#");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package nl.kallestruik.dchat.commands;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import nl.kallestruik.dchat.managers.ChatManager;
|
||||||
|
import nl.kallestruik.dchat.managers.EmojiManager;
|
||||||
|
import nl.kallestruik.dchat.types.Emote;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class CommandChat implements CommandExecutor, TabCompleter {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
|
if (args.length < 1)
|
||||||
|
//TODO: Add warning that you need a chat message
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ChatManager.sendMessage(sender, Component.text(String.join(" ", args)));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
|
if (args.length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
String last = args[args.length - 1];
|
||||||
|
|
||||||
|
// Tab completion for @ mentions.
|
||||||
|
if (last.startsWith("@"))
|
||||||
|
return Bukkit.getOnlinePlayers().stream().map((player) -> "@" + player.getName()).filter((name) -> name.startsWith(last)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (last.startsWith(":"))
|
||||||
|
return EmojiManager.findMatches(last.substring(1)).stream().map(Map.Entry::getValue).map(Emote::getSymbol).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package nl.kallestruik.dchat.commands;
|
||||||
|
|
||||||
|
import nl.kallestruik.dchat.Util;
|
||||||
|
import nl.kallestruik.dchat.managers.PlayerDataManager;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class CommandChatsettings implements CommandExecutor, TabCompleter {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
|
if (args.length < 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UUID uuid = Util.getUUID(sender);
|
||||||
|
|
||||||
|
switch (args[0]) {
|
||||||
|
case "pingSound":
|
||||||
|
if (PlayerDataManager.changePingSoundSettingForUUID(uuid, args[1]))
|
||||||
|
sender.sendMessage("Changed ping sound to: " + args[1]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
case "nameColor":
|
||||||
|
if (PlayerDataManager.changeNameColorSettingForUUID(uuid, args[1]))
|
||||||
|
sender.sendMessage("Changed name color to: " + args[1]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
case "prefixColor":
|
||||||
|
if (PlayerDataManager.changePrefixColorSettingForUUID(uuid, args[1]))
|
||||||
|
sender.sendMessage("Changed prefix color to: " + args[1]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
case "prefix":
|
||||||
|
if (PlayerDataManager.changePrefixSettingForUUID(uuid, String.join(" ", Arrays.copyOfRange(args, 1, args.length))))
|
||||||
|
sender.sendMessage("Changed prefix to: " + args[1]);
|
||||||
|
else
|
||||||
|
sender.sendMessage("That is not a valid value!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
|
if (args.length == 1)
|
||||||
|
return List.of("pingSound", "nameColor", "prefixColor", "prefix").stream().filter((option) -> option.startsWith(args[0])).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (args.length == 2)
|
||||||
|
switch (args[0]) {
|
||||||
|
case "pingSound":
|
||||||
|
return List.of("Yes", "No");
|
||||||
|
case "nameColor":
|
||||||
|
case "prefixColor":
|
||||||
|
return List.of("#");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package nl.kallestruik.dchat.commands;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class CommandEmojitest implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
|
if (args.length < 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = Integer.parseInt(args[0]); i < Integer.parseInt(args[1]); i++) {
|
||||||
|
for (int j = 0; j < 16; j++) {
|
||||||
|
StringBuilder line = new StringBuilder("0xE" + Integer.toString(i, 16) + Integer.toString(j, 16) + "0 ");
|
||||||
|
for (int k = 0; k < 16; k++) {
|
||||||
|
byte[] bytes = new byte[2];
|
||||||
|
bytes[0] = (byte) (0xE0 + i);
|
||||||
|
bytes[1] = (byte) (j * 16 + k);
|
||||||
|
try {
|
||||||
|
line.append(new String(bytes, StandardCharsets.UTF_16));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sender.sendMessage(line.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package nl.kallestruik.dchat.gson;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class TextColorTypeAdapter extends TypeAdapter<TextColor> {
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, TextColor value) throws IOException {
|
||||||
|
out.value(value.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextColor read(JsonReader in) throws IOException {
|
||||||
|
return TextColor.color(in.nextInt());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package nl.kallestruik.dchat.listeners;
|
||||||
|
|
||||||
|
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||||
|
import nl.kallestruik.dchat.managers.ChatManager;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class ChatListener implements Listener {
|
||||||
|
@EventHandler
|
||||||
|
public void onChat(AsyncChatEvent event) {
|
||||||
|
ChatManager.sendMessage(event.getPlayer(), event.message());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package nl.kallestruik.dchat.listeners;
|
||||||
|
|
||||||
|
import nl.kallestruik.dchat.Config;
|
||||||
|
import nl.kallestruik.dchat.DChat;
|
||||||
|
import nl.kallestruik.dchat.managers.PlayerDataManager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
|
||||||
|
public class JoinListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
player.setResourcePack(Config.RESOURCE_PACK_URL_BASE + "pack.zip", DChat.packHash);
|
||||||
|
|
||||||
|
PlayerDataManager.loadPlayerData(player.getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package nl.kallestruik.dchat.managers;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.TextComponent;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
import nl.kallestruik.dchat.Config;
|
||||||
|
import nl.kallestruik.dchat.types.Emote;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ChatManager {
|
||||||
|
|
||||||
|
public static void sendMessage(CommandSender sender, Component message) {
|
||||||
|
message = mentions(message);
|
||||||
|
message = item(message, sender);
|
||||||
|
message = emoji(message);
|
||||||
|
|
||||||
|
message = populateTemplate(message, sender);
|
||||||
|
Bukkit.broadcast(message, "dchat.receive");
|
||||||
|
Bukkit.getConsoleSender().sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Component populateTemplate(Component message, CommandSender sender) {
|
||||||
|
UUID uuid = sender instanceof Player ? ((Player) sender).getUniqueId() : new UUID(0,0); // Console get UUID 0
|
||||||
|
|
||||||
|
return Config.CHAT_FORMAT
|
||||||
|
.replaceText((builder) -> builder.match("%PREFIX%")
|
||||||
|
.replacement(PlayerDataManager.getPrefixForUUID(uuid))
|
||||||
|
.times(1))
|
||||||
|
.replaceText((builder) -> builder.match("%USERNAME%")
|
||||||
|
.replacement(Component.text(sender.getName()).color(PlayerDataManager.getColorForUUID(uuid)))
|
||||||
|
.times(1))
|
||||||
|
.replaceText((builder) -> builder.match("%MESSAGE%")
|
||||||
|
.replacement(message)
|
||||||
|
.times(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Component mentions(Component message) {
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (!((TextComponent)message).content().matches(".*@" + player.getName() + "\\b.*"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (PlayerDataManager.getSettingsForUUID(player.getUniqueId()).isPingSound())
|
||||||
|
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1);
|
||||||
|
|
||||||
|
message = message.replaceText((builder) -> builder
|
||||||
|
.match("\\@" + player.getName() + "\\b")
|
||||||
|
.replacement(
|
||||||
|
Component.text("@" + player.getName())
|
||||||
|
.hoverEvent(player.asHoverEvent())
|
||||||
|
.clickEvent(ClickEvent.suggestCommand("/msg " + player.getName() + " "))
|
||||||
|
.color(PlayerDataManager.getColorForUUID(player.getUniqueId()))
|
||||||
|
).times(1));
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Component emoji(Component message) {
|
||||||
|
String messageText = ((TextComponent)message).content();
|
||||||
|
|
||||||
|
if (!messageText.contains(":"))
|
||||||
|
return message;
|
||||||
|
|
||||||
|
String[] parts = messageText.split(":");
|
||||||
|
for (int i = 1; i < parts.length; i++) {
|
||||||
|
String emojiName = parts[i].split(":")[0];
|
||||||
|
Emote emote = EmojiManager.getExact(emojiName);
|
||||||
|
if (emote != null)
|
||||||
|
message = message.replaceText((builder) -> builder
|
||||||
|
.match(":" + emojiName + ":")
|
||||||
|
.replacement(Component.text(emote.getSymbol())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Component item(Component message, CommandSender sender) {
|
||||||
|
if (!(sender instanceof Player))
|
||||||
|
return message;
|
||||||
|
|
||||||
|
Player player = (Player) sender;
|
||||||
|
ItemStack item = player.getInventory().getItemInMainHand();
|
||||||
|
|
||||||
|
Component itemName = Component.text(item.getI18NDisplayName());
|
||||||
|
if (item.hasItemMeta() && item.getItemMeta().hasDisplayName())
|
||||||
|
itemName = item.getItemMeta().displayName();
|
||||||
|
|
||||||
|
if (itemName == null)
|
||||||
|
return message;
|
||||||
|
|
||||||
|
//TODO: Better item color?
|
||||||
|
Component toShow = Component.text("[").append(itemName).append(Component.text("]")).color(TextColor.color(0xC3C3));
|
||||||
|
|
||||||
|
return message.replaceText((
|
||||||
|
builder -> builder.match("\\[item\\]")
|
||||||
|
.replacement(toShow.hoverEvent(item.asHoverEvent())))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package nl.kallestruik.dchat.managers;
|
||||||
|
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import nl.kallestruik.dchat.Config;
|
||||||
|
import nl.kallestruik.dchat.DChat;
|
||||||
|
import nl.kallestruik.dchat.Util;
|
||||||
|
import nl.kallestruik.dchat.types.Emote;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class EmojiManager {
|
||||||
|
private static final HashMap<String, Emote> emojiMap = new HashMap<>();
|
||||||
|
// static {
|
||||||
|
// emojiMap.put("ban_dream", new Emoji("ban_dream", "\ue000", "Just ban him already!"));
|
||||||
|
// emojiMap.put("wood_pickaxe", new Emoji("wood_pickaxe", "\ue001", "The most basic pickaxe."));
|
||||||
|
// emojiMap.put("wood_shovel", new Emoji("wood_shovel", "\ue002", "The most basic shovel."));
|
||||||
|
// emojiMap.put("wood_axe", new Emoji("wood_axe", "\ue003", "The most basic axe."));
|
||||||
|
// emojiMap.put("wood_hoe", new Emoji("wood_hoe", "\ue004", "The most basic hoe."));
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static Set<Map.Entry<String, Emote>> findMatches(String search) {
|
||||||
|
return emojiMap.entrySet().stream().filter((entry) -> entry.getKey().contains(search)).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Emote getExact(String emojiName) {
|
||||||
|
return emojiMap.getOrDefault(emojiName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadEmotesFromDisk() {
|
||||||
|
File emoteDB = new File(DChat.instance.getDataFolder(), "emotedb.json");
|
||||||
|
if (!emoteDB.exists()) {
|
||||||
|
DChat.logger.warning("Could not load emotes from disk. You should run /cadmin update-emotes");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<Emote> emotes = DChat.gson.fromJson(new FileReader(emoteDB), new TypeToken<List<Emote>>() {}.getType());
|
||||||
|
emotes.forEach((emote) -> {
|
||||||
|
emojiMap.put(emote.getName(), emote);
|
||||||
|
});
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateEmotes() {
|
||||||
|
String emoteDBJson = Util.httpGET(Config.EMOTE_DB_URL);
|
||||||
|
File emoteDB = new File(DChat.instance.getDataFolder(), "emotedb.json");
|
||||||
|
|
||||||
|
try (FileWriter writer = new FileWriter(emoteDB)) {
|
||||||
|
writer.write(emoteDBJson);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadEmotesFromDisk();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package nl.kallestruik.dchat.managers;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
import nl.kallestruik.dchat.DChat;
|
||||||
|
import nl.kallestruik.dchat.types.PlayerSettings;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerDataManager {
|
||||||
|
private static final HashMap<UUID, PlayerSettings> playerSettings = new HashMap<>();
|
||||||
|
|
||||||
|
public static Component getPrefixForUUID(UUID uuid) {
|
||||||
|
PlayerSettings settings = getSettingsForUUID(uuid);
|
||||||
|
|
||||||
|
return Component.text(settings.getPrefix()).color(TextColor.color(settings.getPrefixColor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TextColor getColorForUUID(UUID uuid) {
|
||||||
|
PlayerSettings settings = getSettingsForUUID(uuid);
|
||||||
|
|
||||||
|
return settings.getNameColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadPlayerData(UUID uuid) {
|
||||||
|
File dataFile = new File(DChat.instance.getDataFolder(), "/data/" + uuid.toString() + ".json");
|
||||||
|
PlayerSettings settings = PlayerSettings.loadFromFile(dataFile);
|
||||||
|
if (settings == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
playerSettings.put(uuid, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerSettings getSettingsForUUID(UUID uuid) {
|
||||||
|
return playerSettings.getOrDefault(uuid, new PlayerSettings(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean changePingSoundSettingForUUID(UUID uuid, String value) {
|
||||||
|
boolean enablePingSound;
|
||||||
|
switch (value.toLowerCase(Locale.ROOT)) {
|
||||||
|
case "true":
|
||||||
|
case "yes":
|
||||||
|
case "enable":
|
||||||
|
enablePingSound = true;
|
||||||
|
break;
|
||||||
|
case "false":
|
||||||
|
case "no":
|
||||||
|
case "disable":
|
||||||
|
enablePingSound = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerSettings settings = playerSettings.getOrDefault(uuid, new PlayerSettings(uuid));
|
||||||
|
settings.setPingSound(enablePingSound);
|
||||||
|
playerSettings.put(uuid, settings);
|
||||||
|
settings.save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean changeNameColorSettingForUUID(UUID uuid, String value) {
|
||||||
|
if (!value.startsWith("#"))
|
||||||
|
value = "#" + value;
|
||||||
|
|
||||||
|
TextColor nameColor = TextColor.fromCSSHexString(value);
|
||||||
|
if (nameColor == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PlayerSettings settings = playerSettings.getOrDefault(uuid, new PlayerSettings(uuid));
|
||||||
|
settings.setNameColor(nameColor);
|
||||||
|
playerSettings.put(uuid, settings);
|
||||||
|
settings.save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean changePrefixColorSettingForUUID(UUID uuid, String value) {
|
||||||
|
if (!value.startsWith("#"))
|
||||||
|
value = "#" + value;
|
||||||
|
|
||||||
|
TextColor prefixColor = TextColor.fromCSSHexString(value);
|
||||||
|
if (prefixColor == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PlayerSettings settings = playerSettings.getOrDefault(uuid, new PlayerSettings(uuid));
|
||||||
|
settings.setPrefixColor(prefixColor);
|
||||||
|
playerSettings.put(uuid, settings);
|
||||||
|
settings.save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean changePrefixSettingForUUID(UUID uuid, String value) {
|
||||||
|
if (value == null || value.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PlayerSettings settings = playerSettings.getOrDefault(uuid, new PlayerSettings(uuid));
|
||||||
|
settings.setPrefix(value);
|
||||||
|
playerSettings.put(uuid, settings);
|
||||||
|
settings.save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package nl.kallestruik.dchat.types;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent;
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Emote {
|
||||||
|
private String name;
|
||||||
|
private String symbol;
|
||||||
|
private List<String> description;
|
||||||
|
|
||||||
|
public HoverEvent<Component> getTooltip() {
|
||||||
|
return HoverEvent.showText(
|
||||||
|
Component.text(symbol)
|
||||||
|
.append(Component.text(":" + name + ":\n\n").decorate(TextDecoration.BOLD))
|
||||||
|
.append(Component.text(String.join("\n", description))));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package nl.kallestruik.dchat.types;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
import nl.kallestruik.dchat.DChat;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PlayerSettings {
|
||||||
|
private UUID owner;
|
||||||
|
private boolean pingSound = true;
|
||||||
|
private TextColor nameColor = TextColor.color(0xFFFFFF);
|
||||||
|
private TextColor prefixColor = TextColor.color(0xFFFFFF);
|
||||||
|
private String prefix = "default";
|
||||||
|
|
||||||
|
public PlayerSettings(UUID owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerSettings loadFromFile(File dataFile) {
|
||||||
|
if (!dataFile.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return DChat.gson.fromJson(new FileReader(dataFile), PlayerSettings.class);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
DChat.logger.warning("Could not load player data file: " + dataFile.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
File dataFile = new File(DChat.instance.getDataFolder(), "/data/" + owner.toString() + ".json");
|
||||||
|
try (FileWriter writer = new FileWriter(dataFile)) {
|
||||||
|
writer.write(DChat.gson.toJson(this));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
name: DChat
|
||||||
|
version: @version@
|
||||||
|
main: nl.kallestruik.dchat.DChat
|
||||||
|
api-version: 1.16
|
||||||
|
commands:
|
||||||
|
emojitest:
|
||||||
|
usage: "/emojitest <start> <end>"
|
||||||
|
description: "Debugging command to see all the emojis within the specified space."
|
||||||
|
chat:
|
||||||
|
description: "Send a chat message with tab completion."
|
||||||
|
aliases: [ "c" ]
|
||||||
|
chatsettings:
|
||||||
|
description: "Change your chat settings"
|
||||||
|
aliases: [ "csettings" ]
|
||||||
|
cadmin:
|
||||||
|
description: "Admin commands for DChat"
|
||||||
|
permission: "dchat.admin"
|
||||||
|
permissions:
|
||||||
|
dchat.admin:
|
||||||
|
default: op
|
||||||
|
dchat.receive:
|
||||||
|
default: true
|
Loading…
Reference in New Issue