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