mirror of
https://github.com/Nan1t/NanoLimbo.git
synced 2025-07-17 14:40:14 +02:00
Compare commits
No commits in common. "main" and "v1.4" have entirely different histories.
61
README.md
61
README.md
@ -1,20 +1,20 @@
|
||||
## NanoLimbo
|
||||
|
||||
This is a lightweight Minecraft limbo server, written in Java with Netty.
|
||||
The main goal of this project is maximum simplicity with a minimum number of sent and processed packets.
|
||||
The limbo is empty; there is no ability to set a schematic building since this is not necessary.
|
||||
You can send useful information via chat or boss bar.
|
||||
This is lightweight minecraft limbo server, written on Java with Netty.
|
||||
The main goal of the project is maximum simplicity with a minimum number of sent and processed packets.
|
||||
This limbo is empty, there are no ability to set schematic building since
|
||||
this is not necessary. You can send useful information in chat or BossBar.
|
||||
|
||||
The server is fully clear. It is only able to keep a lot of players while the main server is down.
|
||||
No plugins, no logs. The server is fully clear. It only able keep a lot of players while the main server is down.
|
||||
|
||||
General features:
|
||||
* High performance. The server doesn't save or cache any useless (for limbo) data.
|
||||
* Doesn't spawn threads per player. Use a fixed thread pool.
|
||||
The general features:
|
||||
* High performance. The server not saves and not cached any useless (for limbo) data.
|
||||
* Doesn't spawn threads per player. Uses fixed threads pool.
|
||||
* Support for **BungeeCord** and **Velocity** info forwarding.
|
||||
* Support for [BungeeGuard](https://www.spigotmc.org/resources/79601/) handshake format.
|
||||
* Multiple versions support.
|
||||
* Fully configurable.
|
||||
* Lightweight. App size around **3MB**.
|
||||
* Lightweight. App size around **2MB.**
|
||||
|
||||

|
||||
|
||||
@ -22,7 +22,6 @@ General features:
|
||||
|
||||
Symbol `X` means all minor versions.
|
||||
|
||||
- [x] 1.7.X
|
||||
- [x] 1.8.X
|
||||
- [x] 1.9.X
|
||||
- [x] 1.10.X
|
||||
@ -34,35 +33,31 @@ Symbol `X` means all minor versions.
|
||||
- [x] 1.16.X
|
||||
- [x] 1.17.X
|
||||
- [x] 1.18.X
|
||||
- [x] 1.19.X
|
||||
- [x] 1.20.X
|
||||
- [x] 1.21
|
||||
- [x] 1.19
|
||||
|
||||
The server **doesn't** support snapshots.
|
||||
|
||||
### Commands
|
||||
|
||||
* `help` - Show help message
|
||||
* `conn` - Display number of connections
|
||||
* `conn` - Display amount of connections
|
||||
* `mem` - Display memory usage stats
|
||||
* `stop` - Stop the server
|
||||
|
||||
Note that the server also will be closed correctly if you just press `Ctrl+C`.
|
||||
Note, that it also will be closed correctly if you just press `Ctrl+C`.
|
||||
|
||||
### Installation
|
||||
|
||||
Required software: JRE 11+
|
||||
|
||||
The installation process is simple.
|
||||
|
||||
1. Download the latest version of the program [**here**](https://github.com/Nan1t/NanoLimbo/releases).
|
||||
2. Put the jar file in the folder you want.
|
||||
3. Create a start script as you did for Bukkit or BungeeCord, with a command like this:
|
||||
`java -jar NanoLimbo-<version>.jar`
|
||||
4. The server will create `settings.yml` file, which is the server configuration.
|
||||
5. Configure it as you want and restart the server.
|
||||
1. Download the latest version of program **[here](https://github.com/Nan1t/NanoLimbo/releases)**
|
||||
2. Put jar file in the folder you want.
|
||||
3. Create a start script as you did it for Bukkit or BungeeCord with command like this:
|
||||
`java -jar NanoLimbo-<version>.jar`
|
||||
4. The server will create `settings.yml` file. It's a server configuration.
|
||||
5. Configure it as you want and restart server.
|
||||
|
||||
### Player info forwarding
|
||||
### About player info forwarding
|
||||
|
||||
The server supports player info forwarding from the proxy. There are several types of info forwarding:
|
||||
|
||||
@ -71,29 +66,29 @@ The server supports player info forwarding from the proxy. There are several typ
|
||||
* `BUNGEE_GUARD` - **BungeeGuard** forwarding type.
|
||||
|
||||
If you use BungeeCord, or Velocity with `LEGACY` forwarding, just set this type in the config.
|
||||
If you use Velocity with `MODERN` info forwarding, set this type and paste the secret key from
|
||||
Velocity config into `secret` field.
|
||||
If you use Velocity with `MODERN` info forwarding, set this type and paste secret key from Velocity
|
||||
config into `secret` field.
|
||||
If you installed BungeeGuard on your proxy, then use `BUNGEE_GUARD` forwarding type.
|
||||
Then add your tokens to `tokens` list.
|
||||
|
||||
### Contributing
|
||||
|
||||
Feel free to create a pull request if you find some bug or optimization opportunity, or if you want
|
||||
to add some functionality that is suitable for a limbo server and won't significantly load the server.
|
||||
You can create pull request, if you found some bug, optimization ability, or you want to add some functional,
|
||||
which is suitable for limbo server and won't significantly load the server.
|
||||
|
||||
### Building
|
||||
|
||||
Required software:
|
||||
|
||||
* JDK 11+
|
||||
* Gradle 7+ (optional)
|
||||
* JDK 1.8+
|
||||
* Gradle 7+
|
||||
|
||||
To build a minimized jar, go to the project root directory and run in the terminal:
|
||||
To build minimized .jar, go to project root and write in terminal:
|
||||
|
||||
```
|
||||
./gradlew shadowJar
|
||||
gradlew shadowJar
|
||||
```
|
||||
|
||||
### Contacts
|
||||
|
||||
If you have any questions or suggestions, join our [Discord server](https://discord.gg/4VGP3Gv)!
|
||||
If you have any question or suggestion, join to [Discord server](https://discord.gg/4VGP3Gv)
|
||||
|
33
build.gradle
33
build.gradle
@ -1,17 +1,16 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.2'
|
||||
id 'com.github.gmazzo.buildconfig' version '3.1.0'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
}
|
||||
|
||||
group 'ua.nanit'
|
||||
version '1.8.1'
|
||||
group 'ru.nanit'
|
||||
version '1.4'
|
||||
|
||||
compileJava {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
tasks.withType(JavaCompile) {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
@ -21,33 +20,23 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.3'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
||||
|
||||
implementation 'ch.qos.logback:logback-classic:1.5.6'
|
||||
implementation 'org.spongepowered:configurate-yaml:4.1.2'
|
||||
implementation 'io.netty:netty-all:4.1.101.Final'
|
||||
implementation 'net.kyori:adventure-nbt:4.14.0'
|
||||
implementation 'com.grack:nanojson:1.8'
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
}
|
||||
|
||||
buildConfig {
|
||||
className("BuildConfig")
|
||||
packageName("ua.nanit.limbo")
|
||||
buildConfigField('String', 'LIMBO_VERSION', "\"${project.version}\"")
|
||||
implementation 'io.netty:netty-all:4.1.77.Final'
|
||||
implementation 'net.kyori:adventure-nbt:4.10.1'
|
||||
implementation 'com.grack:nanojson:1.7'
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
from 'LICENSE'
|
||||
|
||||
manifest {
|
||||
attributes('Main-Class': 'ua.nanit.limbo.NanoLimbo')
|
||||
attributes('Main-Class': 'ru.nanit.limbo.NanoLimbo')
|
||||
}
|
||||
|
||||
minimize {
|
||||
exclude(dependency('ch.qos.logback:logback-classic:.*:.*'))
|
||||
}
|
||||
minimize()
|
||||
}
|
||||
|
||||
test {
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
257
gradlew
vendored
Executable file → Normal file
257
gradlew
vendored
Executable file → Normal file
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# 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.
|
||||
@ -17,101 +17,67 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
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
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
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
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
@ -121,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
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
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@ -132,7 +98,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
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
|
||||
@ -140,95 +106,80 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
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
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
# For 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" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
# 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=`expr $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
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
# 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"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo;
|
||||
package ru.nanit.limbo;
|
||||
|
||||
public final class LimboConstants {
|
||||
|
@ -15,10 +15,10 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo;
|
||||
package ru.nanit.limbo;
|
||||
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
public final class NanoLimbo {
|
||||
|
||||
@ -26,7 +26,7 @@ public final class NanoLimbo {
|
||||
try {
|
||||
new LimboServer().start();
|
||||
} catch (Exception e) {
|
||||
Log.error("Cannot start server: ", e);
|
||||
Logger.error("Cannot start server: ", e);
|
||||
}
|
||||
}
|
||||
|
@ -15,17 +15,15 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.configuration;
|
||||
package ru.nanit.limbo.configuration;
|
||||
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.ConfigurationOptions;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializerCollection;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
import ua.nanit.limbo.util.Colors;
|
||||
import ua.nanit.limbo.server.data.BossBar;
|
||||
import ua.nanit.limbo.server.data.InfoForwarding;
|
||||
import ua.nanit.limbo.server.data.PingData;
|
||||
import ua.nanit.limbo.server.data.Title;
|
||||
import ru.nanit.limbo.server.data.*;
|
||||
import ru.nanit.limbo.util.Colors;
|
||||
import ru.nanit.limbo.world.Location;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -45,6 +43,7 @@ public final class LimboConfig {
|
||||
private PingData pingData;
|
||||
|
||||
private String dimensionType;
|
||||
private Location spawnPosition;
|
||||
private int gameMode;
|
||||
|
||||
private boolean useBrandName;
|
||||
@ -71,11 +70,6 @@ public final class LimboConfig {
|
||||
private int bossGroupSize;
|
||||
private int workerGroupSize;
|
||||
|
||||
private boolean useTrafficLimits;
|
||||
private int maxPacketSize;
|
||||
private double interval;
|
||||
private double maxPacketRate;
|
||||
|
||||
public LimboConfig(Path root) {
|
||||
this.root = root;
|
||||
}
|
||||
@ -92,13 +86,14 @@ public final class LimboConfig {
|
||||
address = conf.node("bind").get(SocketAddress.class);
|
||||
maxPlayers = conf.node("maxPlayers").getInt();
|
||||
pingData = conf.node("ping").get(PingData.class);
|
||||
dimensionType = conf.node("dimension").getString("the_end");
|
||||
dimensionType = conf.node("dimension").getString();
|
||||
if (dimensionType.equalsIgnoreCase("nether")) {
|
||||
dimensionType = "the_nether";
|
||||
}
|
||||
if (dimensionType.equalsIgnoreCase("end")) {
|
||||
dimensionType = "the_end";
|
||||
}
|
||||
spawnPosition = conf.node("spawnPosition").get(Location.class);
|
||||
gameMode = conf.node("gameMode").getInt();
|
||||
useBrandName = conf.node("brandName", "enable").getBoolean();
|
||||
useJoinMessage = conf.node("joinMessage", "enable").getBoolean();
|
||||
@ -132,11 +127,6 @@ public final class LimboConfig {
|
||||
useEpoll = conf.node("netty", "useEpoll").getBoolean(true);
|
||||
bossGroupSize = conf.node("netty", "threads", "bossGroup").getInt(1);
|
||||
workerGroupSize = conf.node("netty", "threads", "workerGroup").getInt(4);
|
||||
|
||||
useTrafficLimits = conf.node("traffic", "enable").getBoolean(false);
|
||||
maxPacketSize = conf.node("traffic", "maxPacketSize").getInt(-1);
|
||||
interval = conf.node("traffic", "interval").getDouble(-1.0);
|
||||
maxPacketRate = conf.node("traffic", "maxPacketRate").getDouble(-1.0);
|
||||
}
|
||||
|
||||
private BufferedReader getReader() throws IOException {
|
||||
@ -162,6 +152,7 @@ public final class LimboConfig {
|
||||
.register(PingData.class, new PingData.Serializer())
|
||||
.register(BossBar.class, new BossBar.Serializer())
|
||||
.register(Title.class, new Title.Serializer())
|
||||
.register(Location.class, new Location.Serializer())
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -181,6 +172,10 @@ public final class LimboConfig {
|
||||
return dimensionType;
|
||||
}
|
||||
|
||||
public Location getSpawnPosition() {
|
||||
return spawnPosition;
|
||||
}
|
||||
|
||||
public int getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
@ -260,20 +255,4 @@ public final class LimboConfig {
|
||||
public int getWorkerGroupSize() {
|
||||
return workerGroupSize;
|
||||
}
|
||||
|
||||
public boolean isUseTrafficLimits() {
|
||||
return useTrafficLimits;
|
||||
}
|
||||
|
||||
public int getMaxPacketSize() {
|
||||
return maxPacketSize;
|
||||
}
|
||||
|
||||
public double getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public double getMaxPacketRate() {
|
||||
return maxPacketRate;
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.configuration;
|
||||
package ru.nanit.limbo.configuration;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
@ -15,14 +15,17 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection;
|
||||
package ru.nanit.limbo.connection;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import ua.nanit.limbo.connection.pipeline.*;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.pipeline.PacketDecoder;
|
||||
import ru.nanit.limbo.connection.pipeline.PacketEncoder;
|
||||
import ru.nanit.limbo.connection.pipeline.VarIntFrameDecoder;
|
||||
import ru.nanit.limbo.connection.pipeline.VarIntLengthEncoder;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -46,15 +49,6 @@ public class ClientChannelInitializer extends ChannelInitializer<Channel> {
|
||||
TimeUnit.MILLISECONDS));
|
||||
pipeline.addLast("frame_decoder", new VarIntFrameDecoder());
|
||||
pipeline.addLast("frame_encoder", new VarIntLengthEncoder());
|
||||
|
||||
if (server.getConfig().isUseTrafficLimits()) {
|
||||
pipeline.addLast("traffic_limit", new ChannelTrafficHandler(
|
||||
server.getConfig().getMaxPacketSize(),
|
||||
server.getConfig().getInterval(),
|
||||
server.getConfig().getMaxPacketRate()
|
||||
));
|
||||
}
|
||||
|
||||
pipeline.addLast("decoder", decoder);
|
||||
pipeline.addLast("encoder", encoder);
|
||||
pipeline.addLast("handler", connection);
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection;
|
||||
package ru.nanit.limbo.connection;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
@ -26,18 +26,17 @@ import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ua.nanit.limbo.connection.pipeline.PacketDecoder;
|
||||
import ua.nanit.limbo.connection.pipeline.PacketEncoder;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.Packet;
|
||||
import ua.nanit.limbo.protocol.PacketSnapshot;
|
||||
import ua.nanit.limbo.protocol.packets.login.PacketDisconnect;
|
||||
import ua.nanit.limbo.protocol.packets.play.PacketKeepAlive;
|
||||
import ua.nanit.limbo.protocol.registry.State;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ua.nanit.limbo.util.UuidUtil;
|
||||
import ru.nanit.limbo.connection.pipeline.PacketDecoder;
|
||||
import ru.nanit.limbo.connection.pipeline.PacketEncoder;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.Packet;
|
||||
import ru.nanit.limbo.protocol.packets.login.*;
|
||||
import ru.nanit.limbo.protocol.packets.play.*;
|
||||
import ru.nanit.limbo.protocol.registry.State;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
import ru.nanit.limbo.util.UuidUtil;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
@ -47,7 +46,6 @@ import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@ -95,7 +93,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelInactive(@NotNull ChannelHandlerContext ctx) throws Exception {
|
||||
if (state.equals(State.PLAY) || state.equals(State.CONFIGURATION)) {
|
||||
if (state.equals(State.PLAY)) {
|
||||
server.getConnections().removeConnection(this);
|
||||
}
|
||||
super.channelInactive(ctx);
|
||||
@ -104,7 +102,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
if (channel.isActive()) {
|
||||
Log.error("Unhandled exception: ", cause);
|
||||
Logger.error("Unhandled exception: ", cause);
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,7 +113,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
public void handlePacket(Object packet) {
|
||||
if (packet instanceof Packet) {
|
||||
((Packet) packet).handle(this, server);
|
||||
((Packet)packet).handle(this, server);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,34 +123,14 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
return;
|
||||
}
|
||||
|
||||
sendPacket(PacketSnapshots.PACKET_LOGIN_SUCCESS);
|
||||
writePacket(PacketSnapshots.PACKET_LOGIN_SUCCESS);
|
||||
updateState(State.PLAY);
|
||||
|
||||
server.getConnections().addConnection(this);
|
||||
|
||||
// Preparing for configuration mode
|
||||
if (clientVersion.moreOrEqual(Version.V1_20_2)) {
|
||||
updateEncoderState(State.CONFIGURATION);
|
||||
return;
|
||||
}
|
||||
|
||||
spawnPlayer();
|
||||
}
|
||||
|
||||
public void spawnPlayer() {
|
||||
updateState(State.PLAY);
|
||||
|
||||
Runnable sendPlayPackets = () -> {
|
||||
writePacket(PacketSnapshots.PACKET_JOIN_GAME);
|
||||
writePacket(PacketSnapshots.PACKET_PLAYER_ABILITIES);
|
||||
|
||||
if (clientVersion.less(Version.V1_9)) {
|
||||
writePacket(PacketSnapshots.PACKET_PLAYER_POS_AND_LOOK_LEGACY);
|
||||
} else {
|
||||
writePacket(PacketSnapshots.PACKET_PLAYER_POS_AND_LOOK);
|
||||
}
|
||||
|
||||
if (clientVersion.moreOrEqual(Version.V1_19_3))
|
||||
writePacket(PacketSnapshots.PACKET_SPAWN_POSITION);
|
||||
writePacket(PacketSnapshots.PACKET_PLAYER_POS);
|
||||
|
||||
if (server.getConfig().isUsePlayerList() || clientVersion.equals(Version.V1_16_4))
|
||||
writePacket(PacketSnapshots.PACKET_PLAYER_INFO);
|
||||
@ -170,45 +148,13 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
if (PacketSnapshots.PACKET_JOIN_MESSAGE != null)
|
||||
writePacket(PacketSnapshots.PACKET_JOIN_MESSAGE);
|
||||
|
||||
if (PacketSnapshots.PACKET_TITLE_TITLE != null && clientVersion.moreOrEqual(Version.V1_8))
|
||||
if (PacketSnapshots.PACKET_TITLE_TITLE != null)
|
||||
writeTitle();
|
||||
|
||||
if (PacketSnapshots.PACKET_HEADER_AND_FOOTER != null && clientVersion.moreOrEqual(Version.V1_8))
|
||||
if (PacketSnapshots.PACKET_HEADER_AND_FOOTER != null)
|
||||
writePacket(PacketSnapshots.PACKET_HEADER_AND_FOOTER);
|
||||
|
||||
if (clientVersion.moreOrEqual(Version.V1_20_3)) {
|
||||
writePacket(PacketSnapshots.PACKET_START_WAITING_CHUNKS);
|
||||
|
||||
for (PacketSnapshot chunk : PacketSnapshots.PACKETS_EMPTY_CHUNKS) {
|
||||
writePacket(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
sendKeepAlive();
|
||||
};
|
||||
|
||||
if (clientVersion.lessOrEqual(Version.V1_7_6)) {
|
||||
this.channel.eventLoop().schedule(sendPlayPackets, 100, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
sendPlayPackets.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoginAcknowledgedReceived() {
|
||||
updateState(State.CONFIGURATION);
|
||||
|
||||
if (PacketSnapshots.PACKET_PLUGIN_MESSAGE != null)
|
||||
writePacket(PacketSnapshots.PACKET_PLUGIN_MESSAGE);
|
||||
|
||||
if (clientVersion.moreOrEqual(Version.V1_20_5)) {
|
||||
for (PacketSnapshot packet : PacketSnapshots.PACKETS_REGISTRY_DATA) {
|
||||
writePacket(packet);
|
||||
}
|
||||
} else {
|
||||
writePacket(PacketSnapshots.PACKET_REGISTRY_DATA);
|
||||
}
|
||||
|
||||
sendPacket(PacketSnapshots.PACKET_FINISH_CONFIGURATION);
|
||||
}
|
||||
|
||||
public void disconnectLogin(String reason) {
|
||||
@ -264,10 +210,6 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
encoder.updateState(state);
|
||||
}
|
||||
|
||||
public void updateEncoderState(State state) {
|
||||
encoder.updateState(state);
|
||||
}
|
||||
|
||||
public void updateVersion(Version version) {
|
||||
clientVersion = version;
|
||||
decoder.updateVersion(version);
|
||||
@ -275,7 +217,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
|
||||
public void setAddress(String host) {
|
||||
this.address = new InetSocketAddress(host, ((InetSocketAddress) this.address).getPort());
|
||||
this.address = new InetSocketAddress(host, ((InetSocketAddress)this.address).getPort());
|
||||
}
|
||||
|
||||
boolean checkBungeeGuardHandshake(String handshake) {
|
||||
@ -312,7 +254,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
setAddress(socketAddressHostname);
|
||||
gameProfile.setUuid(uuid);
|
||||
|
||||
Log.debug("Successfully verified BungeeGuard token");
|
||||
Logger.debug("Successfully verified BungeeGuard token");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -336,7 +278,7 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
|
||||
byte[] mySignature = mac.doFinal(data);
|
||||
if (!MessageDigest.isEqual(signature, mySignature))
|
||||
return false;
|
||||
} catch (InvalidKeyException | java.security.NoSuchAlgorithmException e) {
|
||||
} catch (InvalidKeyException |java.security.NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
int version = buf.readVarInt();
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection;
|
||||
package ru.nanit.limbo.connection;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -15,22 +15,20 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection;
|
||||
package ru.nanit.limbo.connection;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import ua.nanit.limbo.LimboConstants;
|
||||
import ua.nanit.limbo.protocol.packets.PacketHandshake;
|
||||
import ua.nanit.limbo.protocol.packets.configuration.PacketFinishConfiguration;
|
||||
import ua.nanit.limbo.protocol.packets.login.PacketLoginAcknowledged;
|
||||
import ua.nanit.limbo.protocol.packets.login.PacketLoginPluginRequest;
|
||||
import ua.nanit.limbo.protocol.packets.login.PacketLoginPluginResponse;
|
||||
import ua.nanit.limbo.protocol.packets.login.PacketLoginStart;
|
||||
import ua.nanit.limbo.protocol.packets.status.PacketStatusPing;
|
||||
import ua.nanit.limbo.protocol.packets.status.PacketStatusRequest;
|
||||
import ua.nanit.limbo.protocol.packets.status.PacketStatusResponse;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ua.nanit.limbo.util.UuidUtil;
|
||||
import ru.nanit.limbo.LimboConstants;
|
||||
import ru.nanit.limbo.protocol.packets.PacketHandshake;
|
||||
import ru.nanit.limbo.protocol.packets.login.PacketLoginPluginRequest;
|
||||
import ru.nanit.limbo.protocol.packets.login.PacketLoginPluginResponse;
|
||||
import ru.nanit.limbo.protocol.packets.login.PacketLoginStart;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusPing;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusRequest;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusResponse;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
import ru.nanit.limbo.util.UuidUtil;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@ -46,7 +44,7 @@ public class PacketHandler {
|
||||
conn.updateVersion(packet.getVersion());
|
||||
conn.updateState(packet.getNextState());
|
||||
|
||||
Log.debug("Pinged from %s [%s]", conn.getAddress(),
|
||||
Logger.debug("Pinged from %s [%s]", conn.getAddress(),
|
||||
conn.getClientVersion().toString());
|
||||
|
||||
if (server.getConfig().getInfoForwarding().isLegacy()) {
|
||||
@ -129,12 +127,4 @@ public class PacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public void handle(ClientConnection conn, PacketLoginAcknowledged packet) {
|
||||
conn.onLoginAcknowledgedReceived();
|
||||
}
|
||||
|
||||
public void handle(ClientConnection conn, PacketFinishConfiguration packet) {
|
||||
conn.spawnPlayer();
|
||||
}
|
||||
|
||||
}
|
@ -15,26 +15,17 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection;
|
||||
package ru.nanit.limbo.connection;
|
||||
|
||||
import net.kyori.adventure.nbt.BinaryTag;
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
import net.kyori.adventure.nbt.ListBinaryTag;
|
||||
import ua.nanit.limbo.LimboConstants;
|
||||
import ua.nanit.limbo.protocol.PacketSnapshot;
|
||||
import ua.nanit.limbo.protocol.packets.configuration.PacketFinishConfiguration;
|
||||
import ua.nanit.limbo.protocol.packets.configuration.PacketRegistryData;
|
||||
import ua.nanit.limbo.protocol.packets.login.PacketLoginSuccess;
|
||||
import ua.nanit.limbo.protocol.packets.play.*;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.data.Title;
|
||||
import ua.nanit.limbo.util.NbtMessageUtil;
|
||||
import ua.nanit.limbo.util.UuidUtil;
|
||||
import ua.nanit.limbo.world.Dimension;
|
||||
import ru.nanit.limbo.LimboConstants;
|
||||
import ru.nanit.limbo.protocol.PacketSnapshot;
|
||||
import ru.nanit.limbo.protocol.packets.login.PacketLoginSuccess;
|
||||
import ru.nanit.limbo.protocol.packets.play.*;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.data.Title;
|
||||
import ru.nanit.limbo.util.UuidUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@ -42,19 +33,15 @@ public final class PacketSnapshots {
|
||||
|
||||
public static PacketSnapshot PACKET_LOGIN_SUCCESS;
|
||||
public static PacketSnapshot PACKET_JOIN_GAME;
|
||||
public static PacketSnapshot PACKET_SPAWN_POSITION;
|
||||
public static PacketSnapshot PACKET_PLUGIN_MESSAGE;
|
||||
public static PacketSnapshot PACKET_PLAYER_ABILITIES;
|
||||
public static PacketSnapshot PACKET_PLAYER_INFO;
|
||||
public static PacketSnapshot PACKET_DECLARE_COMMANDS;
|
||||
public static PacketSnapshot PACKET_PLAYER_POS;
|
||||
public static PacketSnapshot PACKET_JOIN_MESSAGE;
|
||||
public static PacketSnapshot PACKET_BOSS_BAR;
|
||||
public static PacketSnapshot PACKET_HEADER_AND_FOOTER;
|
||||
|
||||
public static PacketSnapshot PACKET_PLAYER_POS_AND_LOOK_LEGACY;
|
||||
// For 1.19 we need to spawn player outside the world to avoid stuck in terrain loading
|
||||
public static PacketSnapshot PACKET_PLAYER_POS_AND_LOOK;
|
||||
|
||||
public static PacketSnapshot PACKET_TITLE_TITLE;
|
||||
public static PacketSnapshot PACKET_TITLE_SUBTITLE;
|
||||
public static PacketSnapshot PACKET_TITLE_TIMES;
|
||||
@ -63,12 +50,6 @@ public final class PacketSnapshots {
|
||||
public static PacketSnapshot PACKET_TITLE_LEGACY_SUBTITLE;
|
||||
public static PacketSnapshot PACKET_TITLE_LEGACY_TIMES;
|
||||
|
||||
public static PacketSnapshot PACKET_REGISTRY_DATA;
|
||||
public static List<PacketSnapshot> PACKETS_REGISTRY_DATA;
|
||||
public static PacketSnapshot PACKET_FINISH_CONFIGURATION;
|
||||
|
||||
public static List<PacketSnapshot> PACKETS_EMPTY_CHUNKS;
|
||||
public static PacketSnapshot PACKET_START_WAITING_CHUNKS;
|
||||
|
||||
private PacketSnapshots() { }
|
||||
|
||||
@ -81,7 +62,6 @@ public final class PacketSnapshots {
|
||||
loginSuccess.setUuid(uuid);
|
||||
|
||||
PacketJoinGame joinGame = new PacketJoinGame();
|
||||
String worldName = "minecraft:" + server.getConfig().getDimensionType().toLowerCase();
|
||||
joinGame.setEntityId(0);
|
||||
joinGame.setEnableRespawnScreen(true);
|
||||
joinGame.setFlat(false);
|
||||
@ -92,6 +72,7 @@ public final class PacketSnapshots {
|
||||
joinGame.setReducedDebugInfo(true);
|
||||
joinGame.setDebug(false);
|
||||
joinGame.setViewDistance(0);
|
||||
String worldName = "minecraft:" + server.getConfig().getDimensionType().toLowerCase();
|
||||
joinGame.setWorldName(worldName);
|
||||
joinGame.setWorldNames(worldName);
|
||||
joinGame.setHashedSeed(0);
|
||||
@ -102,15 +83,13 @@ public final class PacketSnapshots {
|
||||
playerAbilities.setFlags(0x02);
|
||||
playerAbilities.setFieldOfView(0.1F);
|
||||
|
||||
int teleportId = ThreadLocalRandom.current().nextInt();
|
||||
|
||||
PacketPlayerPositionAndLook positionAndLookLegacy
|
||||
= new PacketPlayerPositionAndLook(0, 64, 0, 0, 0, teleportId);
|
||||
|
||||
PacketPlayerPositionAndLook positionAndLook
|
||||
= new PacketPlayerPositionAndLook(0, 400, 0, 0, 0, teleportId);
|
||||
|
||||
PacketSpawnPosition packetSpawnPosition = new PacketSpawnPosition(0, 400, 0);
|
||||
PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook();
|
||||
positionAndLook.setX(server.getConfig().getSpawnPosition().getX());
|
||||
positionAndLook.setY(server.getConfig().getSpawnPosition().getY());
|
||||
positionAndLook.setZ(server.getConfig().getSpawnPosition().getZ());
|
||||
positionAndLook.setYaw(server.getConfig().getSpawnPosition().getYaw());
|
||||
positionAndLook.setPitch(server.getConfig().getSpawnPosition().getPitch());
|
||||
positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt());
|
||||
|
||||
PacketDeclareCommands declareCommands = new PacketDeclareCommands();
|
||||
declareCommands.setCommands(Collections.emptyList());
|
||||
@ -122,18 +101,16 @@ public final class PacketSnapshots {
|
||||
|
||||
PACKET_LOGIN_SUCCESS = PacketSnapshot.of(loginSuccess);
|
||||
PACKET_JOIN_GAME = PacketSnapshot.of(joinGame);
|
||||
PACKET_PLAYER_POS_AND_LOOK_LEGACY = PacketSnapshot.of(positionAndLookLegacy);
|
||||
PACKET_PLAYER_POS_AND_LOOK = PacketSnapshot.of(positionAndLook);
|
||||
PACKET_SPAWN_POSITION = PacketSnapshot.of(packetSpawnPosition);
|
||||
PACKET_PLAYER_ABILITIES = PacketSnapshot.of(playerAbilities);
|
||||
PACKET_PLAYER_POS = PacketSnapshot.of(positionAndLook);
|
||||
PACKET_PLAYER_INFO = PacketSnapshot.of(info);
|
||||
|
||||
PACKET_DECLARE_COMMANDS = PacketSnapshot.of(declareCommands);
|
||||
|
||||
if (server.getConfig().isUseHeaderAndFooter()) {
|
||||
PacketPlayerListHeader header = new PacketPlayerListHeader();
|
||||
header.setHeader(NbtMessageUtil.create(server.getConfig().getPlayerListHeader()));
|
||||
header.setFooter(NbtMessageUtil.create(server.getConfig().getPlayerListFooter()));
|
||||
header.setHeader(server.getConfig().getPlayerListHeader());
|
||||
header.setFooter(server.getConfig().getPlayerListFooter());
|
||||
PACKET_HEADER_AND_FOOTER = PacketSnapshot.of(header);
|
||||
}
|
||||
|
||||
@ -146,7 +123,7 @@ public final class PacketSnapshots {
|
||||
|
||||
if (server.getConfig().isUseJoinMessage()) {
|
||||
PacketChatMessage joinMessage = new PacketChatMessage();
|
||||
joinMessage.setMessage(NbtMessageUtil.create(server.getConfig().getJoinMessage()));
|
||||
joinMessage.setJsonData(server.getConfig().getJoinMessage());
|
||||
joinMessage.setPosition(PacketChatMessage.PositionLegacy.SYSTEM_MESSAGE);
|
||||
joinMessage.setSender(UUID.randomUUID());
|
||||
PACKET_JOIN_MESSAGE = PacketSnapshot.of(joinMessage);
|
||||
@ -193,65 +170,5 @@ public final class PacketSnapshots {
|
||||
PACKET_TITLE_LEGACY_SUBTITLE = PacketSnapshot.of(legacySubtitle);
|
||||
PACKET_TITLE_LEGACY_TIMES = PacketSnapshot.of(legacyTimes);
|
||||
}
|
||||
|
||||
PacketRegistryData packetRegistryData = new PacketRegistryData();
|
||||
packetRegistryData.setDimensionRegistry(server.getDimensionRegistry());
|
||||
|
||||
PACKET_REGISTRY_DATA = PacketSnapshot.of(packetRegistryData);
|
||||
|
||||
Dimension dimension1_21 = server.getDimensionRegistry().getDimension_1_21();
|
||||
List<PacketSnapshot> packetRegistries = new ArrayList<>();
|
||||
CompoundBinaryTag dimensionTag = dimension1_21.getData();
|
||||
for (String registryType : dimensionTag.keySet()) {
|
||||
CompoundBinaryTag compoundRegistryType = dimensionTag.getCompound(registryType);
|
||||
|
||||
PacketRegistryData registryData = new PacketRegistryData();
|
||||
registryData.setDimensionRegistry(server.getDimensionRegistry());
|
||||
|
||||
ListBinaryTag values = compoundRegistryType.getList("value");
|
||||
registryData.setMetadataWriter((message, version) -> {
|
||||
message.writeString(registryType);
|
||||
|
||||
message.writeVarInt(values.size());
|
||||
for (BinaryTag entry : values) {
|
||||
CompoundBinaryTag entryTag = (CompoundBinaryTag) entry;
|
||||
|
||||
String name = entryTag.getString("name");
|
||||
CompoundBinaryTag element = entryTag.getCompound("element");
|
||||
|
||||
message.writeString(name);
|
||||
message.writeBoolean(true);
|
||||
message.writeNamelessCompoundTag(element);
|
||||
}
|
||||
});
|
||||
|
||||
packetRegistries.add(PacketSnapshot.of(registryData));
|
||||
}
|
||||
|
||||
PACKETS_REGISTRY_DATA = packetRegistries;
|
||||
|
||||
PACKET_FINISH_CONFIGURATION = PacketSnapshot.of(new PacketFinishConfiguration());
|
||||
|
||||
PacketGameEvent packetGameEvent = new PacketGameEvent();
|
||||
packetGameEvent.setType((byte) 13); // Waiting for chunks type
|
||||
packetGameEvent.setValue(0);
|
||||
PACKET_START_WAITING_CHUNKS = PacketSnapshot.of(packetGameEvent);
|
||||
|
||||
int chunkXOffset = (int) 0 >> 4; // Default x position is 0
|
||||
int chunkZOffset = (int) 0 >> 4; // Default z position is 0
|
||||
int chunkEdgeSize = 1; // TODO Make configurable?
|
||||
|
||||
List<PacketSnapshot> emptyChunks = new ArrayList<>();
|
||||
// Make multiple chunks for edges
|
||||
for (int chunkX = chunkXOffset - chunkEdgeSize; chunkX <= chunkXOffset + chunkEdgeSize; ++chunkX) {
|
||||
for (int chunkZ = chunkZOffset - chunkEdgeSize; chunkZ <= chunkZOffset + chunkEdgeSize; ++chunkZ) {
|
||||
PacketEmptyChunk packetEmptyChunk = new PacketEmptyChunk();
|
||||
packetEmptyChunk.setX(chunkX);
|
||||
packetEmptyChunk.setZ(chunkZ);
|
||||
|
||||
emptyChunks.add(PacketSnapshot.of(packetEmptyChunk));
|
||||
}
|
||||
}
|
||||
PACKETS_EMPTY_CHUNKS = emptyChunks;
|
||||
}
|
||||
}
|
@ -15,16 +15,16 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection.pipeline;
|
||||
package ru.nanit.limbo.connection.pipeline;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.Packet;
|
||||
import ua.nanit.limbo.protocol.registry.State;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.Packet;
|
||||
import ru.nanit.limbo.protocol.registry.State;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -47,20 +47,16 @@ public class PacketDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
Packet packet = mappings.getPacket(packetId);
|
||||
|
||||
if (packet != null) {
|
||||
Log.debug("Received packet %s[0x%s] (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes());
|
||||
Logger.debug("Received packet %s[0x%s]", packet.toString(), Integer.toHexString(packetId));
|
||||
try {
|
||||
packet.decode(msg, version);
|
||||
} catch (Exception e) {
|
||||
if (Log.isDebug()) {
|
||||
Log.warning("Cannot decode packet 0x%s", e, Integer.toHexString(packetId));
|
||||
} else {
|
||||
Log.warning("Cannot decode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage());
|
||||
}
|
||||
Logger.warning("Cannot decode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage());
|
||||
}
|
||||
|
||||
ctx.fireChannelRead(packet);
|
||||
} else {
|
||||
Log.debug("Undefined incoming packet: 0x" + Integer.toHexString(packetId));
|
||||
Logger.debug("Undefined incoming packet: 0x" + Integer.toHexString(packetId));
|
||||
}
|
||||
}
|
||||
|
@ -15,17 +15,17 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection.pipeline;
|
||||
package ru.nanit.limbo.connection.pipeline;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.Packet;
|
||||
import ua.nanit.limbo.protocol.PacketSnapshot;
|
||||
import ua.nanit.limbo.protocol.registry.State;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.Packet;
|
||||
import ru.nanit.limbo.protocol.PacketSnapshot;
|
||||
import ru.nanit.limbo.protocol.registry.State;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
public class PacketEncoder extends MessageToByteEncoder<Packet> {
|
||||
|
||||
@ -51,7 +51,7 @@ public class PacketEncoder extends MessageToByteEncoder<Packet> {
|
||||
}
|
||||
|
||||
if (packetId == -1) {
|
||||
Log.warning("Undefined packet class: %s[0x%s] (%d bytes)", packet.getClass().getName(), Integer.toHexString(packetId), msg.readableBytes());
|
||||
Logger.warning("Undefined packet class: %s[0x%s]", packet.getClass().getName(), Integer.toHexString(packetId));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -60,11 +60,11 @@ public class PacketEncoder extends MessageToByteEncoder<Packet> {
|
||||
try {
|
||||
packet.encode(msg, version);
|
||||
|
||||
if (Log.isDebug()) {
|
||||
Log.debug("Sending %s[0x%s] packet (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes());
|
||||
if (Logger.getLevel() >= Logger.Level.DEBUG.getIndex()) {
|
||||
Logger.debug("Sending %s[0x%s] packet (%d bytes)", packet.toString(), Integer.toHexString(packetId), msg.readableBytes());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.error("Cannot encode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage());
|
||||
Logger.error("Cannot encode packet 0x%s: %s", Integer.toHexString(packetId), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection.pipeline;
|
||||
package ru.nanit.limbo.connection.pipeline;
|
||||
|
||||
import io.netty.util.ByteProcessor;
|
||||
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection.pipeline;
|
||||
package ru.nanit.limbo.connection.pipeline;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -42,19 +42,18 @@ public class VarIntFrameDecoder extends ByteToMessageDecoder {
|
||||
int readVarInt = reader.getReadVarInt();
|
||||
int bytesRead = reader.getBytesRead();
|
||||
if (readVarInt < 0) {
|
||||
Log.error("[VarIntFrameDecoder] Bad data length");
|
||||
Logger.error("[VarIntFrameDecoder] Bad data length");
|
||||
} else if (readVarInt == 0) {
|
||||
in.readerIndex(varIntEnd + 1);
|
||||
} else {
|
||||
int minimumRead = bytesRead + readVarInt;
|
||||
|
||||
if (in.isReadable(minimumRead)) {
|
||||
out.add(in.retainedSlice(varIntEnd + 1, readVarInt));
|
||||
in.skipBytes(minimumRead);
|
||||
}
|
||||
}
|
||||
} else if (reader.getResult() == VarIntByteDecoder.DecodeResult.TOO_BIG) {
|
||||
Log.error("[VarIntFrameDecoder] Too big data");
|
||||
Logger.error("[VarIntFrameDecoder] Too big data");
|
||||
}
|
||||
}
|
||||
}
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.connection.pipeline;
|
||||
package ru.nanit.limbo.connection.pipeline;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class VarIntLengthEncoder extends MessageToByteEncoder<ByteBuf> {
|
@ -15,14 +15,14 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol;
|
||||
package ru.nanit.limbo.protocol;
|
||||
|
||||
import io.netty.buffer.*;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import io.netty.handler.codec.EncoderException;
|
||||
import io.netty.util.ByteProcessor;
|
||||
import net.kyori.adventure.nbt.*;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import net.kyori.adventure.nbt.BinaryTagIO;
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -34,9 +34,6 @@ import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ByteMessage extends ByteBuf {
|
||||
@ -73,37 +70,14 @@ public class ByteMessage extends ByteBuf {
|
||||
}
|
||||
|
||||
public void writeVarInt(int value) {
|
||||
// Peel the one and two byte count cases explicitly as they are the most common VarInt sizes
|
||||
// that the proxy will write, to improve inlining.
|
||||
if ((value & (0xFFFFFFFF << 7)) == 0) {
|
||||
while (true) {
|
||||
if ((value & 0xFFFFFF80) == 0) {
|
||||
buf.writeByte(value);
|
||||
} else if ((value & (0xFFFFFFFF << 14)) == 0) {
|
||||
int w = (value & 0x7F | 0x80) << 8 | (value >>> 7);
|
||||
buf.writeShort(w);
|
||||
} else {
|
||||
writeVarIntFull(value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private void writeVarIntFull(final int value) {
|
||||
// See https://steinborn.me/posts/performance/how-fast-can-you-write-a-varint/
|
||||
if ((value & (0xFFFFFFFF << 7)) == 0) {
|
||||
buf.writeByte(value);
|
||||
} else if ((value & (0xFFFFFFFF << 14)) == 0) {
|
||||
int w = (value & 0x7F | 0x80) << 8 | (value >>> 7);
|
||||
buf.writeShort(w);
|
||||
} else if ((value & (0xFFFFFFFF << 21)) == 0) {
|
||||
int w = (value & 0x7F | 0x80) << 16 | ((value >>> 7) & 0x7F | 0x80) << 8 | (value >>> 14);
|
||||
buf.writeMedium(w);
|
||||
} else if ((value & (0xFFFFFFFF << 28)) == 0) {
|
||||
int w = (value & 0x7F | 0x80) << 24 | (((value >>> 7) & 0x7F | 0x80) << 16)
|
||||
| ((value >>> 14) & 0x7F | 0x80) << 8 | (value >>> 21);
|
||||
buf.writeInt(w);
|
||||
} else {
|
||||
int w = (value & 0x7F | 0x80) << 24 | ((value >>> 7) & 0x7F | 0x80) << 16
|
||||
| ((value >>> 14) & 0x7F | 0x80) << 8 | ((value >>> 21) & 0x7F | 0x80);
|
||||
buf.writeInt(w);
|
||||
buf.writeByte(value >>> 28);
|
||||
buf.writeByte(value & 0x7F | 0x80);
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,81 +190,6 @@ public class ByteMessage extends ByteBuf {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeNamelessCompoundTag(BinaryTag binaryTag) {
|
||||
try (ByteBufOutputStream stream = new ByteBufOutputStream(buf)) {
|
||||
stream.writeByte(binaryTag.type().id());
|
||||
|
||||
// TODO Find a way to improve this...
|
||||
if (binaryTag instanceof CompoundBinaryTag) {
|
||||
CompoundBinaryTag tag = (CompoundBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof ByteBinaryTag) {
|
||||
ByteBinaryTag tag = (ByteBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof ShortBinaryTag) {
|
||||
ShortBinaryTag tag = (ShortBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof IntBinaryTag) {
|
||||
IntBinaryTag tag = (IntBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof LongBinaryTag) {
|
||||
LongBinaryTag tag = (LongBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof DoubleBinaryTag) {
|
||||
DoubleBinaryTag tag = (DoubleBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof StringBinaryTag) {
|
||||
StringBinaryTag tag = (StringBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof ListBinaryTag) {
|
||||
ListBinaryTag tag = (ListBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
else if (binaryTag instanceof EndBinaryTag) {
|
||||
EndBinaryTag tag = (EndBinaryTag) binaryTag;
|
||||
tag.type().write(tag, stream);
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new EncoderException("Cannot write NBT CompoundTag");
|
||||
}
|
||||
}
|
||||
|
||||
public void writeNbtMessage(NbtMessage nbtMessage, Version version) {
|
||||
if (version.moreOrEqual(Version.V1_20_3)) {
|
||||
writeNamelessCompoundTag(nbtMessage.getTag());
|
||||
}
|
||||
else {
|
||||
writeString(nbtMessage.getJson());
|
||||
}
|
||||
}
|
||||
|
||||
public <E extends Enum<E>> void writeEnumSet(EnumSet<E> enumset, Class<E> oclass) {
|
||||
E[] enums = oclass.getEnumConstants();
|
||||
BitSet bits = new BitSet(enums.length);
|
||||
|
||||
for (int i = 0; i < enums.length; ++i) {
|
||||
bits.set(i, enumset.contains(enums[i]));
|
||||
}
|
||||
|
||||
writeFixedBitSet(bits, enums.length, buf);
|
||||
}
|
||||
|
||||
private static void writeFixedBitSet(BitSet bits, int size, ByteBuf buf) {
|
||||
if (bits.length() > size) {
|
||||
throw new StackOverflowError("BitSet too large (expected " + size + " got " + bits.size() + ")");
|
||||
}
|
||||
buf.writeBytes(Arrays.copyOf(bits.toByteArray(), (size + 8) >> 3));
|
||||
}
|
||||
|
||||
/* Delegated methods */
|
||||
|
||||
@Override
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol;
|
||||
package ru.nanit.limbo.protocol;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
public interface Packet {
|
||||
|
@ -15,9 +15,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol;
|
||||
package ru.nanit.limbo.protocol;
|
||||
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public interface PacketIn extends Packet {
|
||||
|
@ -15,9 +15,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol;
|
||||
package ru.nanit.limbo.protocol;
|
||||
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public interface PacketOut extends Packet {
|
||||
|
@ -15,16 +15,16 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol;
|
||||
package ru.nanit.limbo.protocol;
|
||||
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PacketSnapshot encodes a packet to byte array for each MC version.
|
||||
* Some versions have the same snapshot, so there are mappings to avoid data copying
|
||||
* PacketSnapshot encodes packet to byte array for each MC version.
|
||||
* Some versions have same snapshot, so there are mappings to avoid data copying
|
||||
*/
|
||||
public class PacketSnapshot implements PacketOut {
|
||||
|
@ -15,14 +15,16 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets;
|
||||
package ru.nanit.limbo.protocol.packets;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketIn;
|
||||
import ua.nanit.limbo.protocol.registry.State;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketIn;
|
||||
import ru.nanit.limbo.protocol.registry.State;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
import ru.nanit.limbo.util.UuidUtil;
|
||||
|
||||
public class PacketHandshake implements PacketIn {
|
||||
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.login;
|
||||
package ru.nanit.limbo.protocol.packets.login;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketDisconnect implements PacketOut {
|
||||
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.login;
|
||||
package ru.nanit.limbo.protocol.packets.login;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketLoginPluginRequest implements PacketOut {
|
||||
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.login;
|
||||
package ru.nanit.limbo.protocol.packets.login;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketIn;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketIn;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketLoginPluginResponse implements PacketIn {
|
||||
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.login;
|
||||
package ru.nanit.limbo.protocol.packets.login;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketIn;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketIn;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketLoginStart implements PacketIn {
|
||||
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.login;
|
||||
package ru.nanit.limbo.protocol.packets.login;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -40,18 +40,13 @@ public class PacketLoginSuccess implements PacketOut {
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
if (version.moreOrEqual(Version.V1_16)) {
|
||||
msg.writeUuid(uuid);
|
||||
} else if (version.moreOrEqual(Version.V1_7_6)) {
|
||||
msg.writeString(uuid.toString());
|
||||
} else {
|
||||
msg.writeString(uuid.toString().replace("-", ""));
|
||||
msg.writeString(uuid.toString());
|
||||
}
|
||||
msg.writeString(username);
|
||||
if (version.moreOrEqual(Version.V1_19)) {
|
||||
msg.writeVarInt(0);
|
||||
}
|
||||
if (version.moreOrEqual(Version.V1_20_5)) {
|
||||
msg.writeBoolean(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.data.BossBar;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.data.BossBar;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -49,7 +49,7 @@ public class PacketBossBar implements PacketOut {
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeUuid(uuid);
|
||||
msg.writeVarInt(0); // Create bossbar
|
||||
msg.writeNbtMessage(bossBar.getText(), version);
|
||||
msg.writeString(bossBar.getText());
|
||||
msg.writeFloat(bossBar.getHealth());
|
||||
msg.writeVarInt(bossBar.getColor().getIndex());
|
||||
msg.writeVarInt(bossBar.getDivision().getIndex());
|
@ -15,23 +15,22 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PacketChatMessage implements PacketOut {
|
||||
|
||||
private NbtMessage message;
|
||||
private String jsonData;
|
||||
private PositionLegacy position;
|
||||
private UUID sender;
|
||||
|
||||
public void setMessage(NbtMessage message) {
|
||||
this.message = message;
|
||||
public void setJsonData(String jsonData) {
|
||||
this.jsonData = jsonData;
|
||||
}
|
||||
|
||||
public void setPosition(PositionLegacy position) {
|
||||
@ -44,12 +43,11 @@ public class PacketChatMessage implements PacketOut {
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeNbtMessage(message, version);
|
||||
if (version.moreOrEqual(Version.V1_19_1)) {
|
||||
msg.writeBoolean(position.index == PositionLegacy.ACTION_BAR.index);
|
||||
} else if (version.moreOrEqual(Version.V1_19)) {
|
||||
msg.writeString(jsonData);
|
||||
if (version.moreOrEqual(Version.V1_19)) {
|
||||
msg.writeVarInt(position.index);
|
||||
} else if (version.moreOrEqual(Version.V1_8)) {
|
||||
}
|
||||
else {
|
||||
msg.writeByte(position.index);
|
||||
}
|
||||
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.world.DimensionRegistry;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.world.dimension.DimensionRegistry;
|
||||
|
||||
public class PacketJoinGame implements PacketOut {
|
||||
|
||||
@ -38,8 +38,6 @@ public class PacketJoinGame implements PacketOut {
|
||||
private boolean enableRespawnScreen;
|
||||
private boolean isDebug;
|
||||
private boolean isFlat;
|
||||
private boolean limitedCrafting;
|
||||
private boolean secureProfile;
|
||||
|
||||
public void setEntityId(int entityId) {
|
||||
this.entityId = entityId;
|
||||
@ -97,27 +95,11 @@ public class PacketJoinGame implements PacketOut {
|
||||
isFlat = flat;
|
||||
}
|
||||
|
||||
public void setLimitedCrafting(boolean limitedCrafting) {
|
||||
this.limitedCrafting = limitedCrafting;
|
||||
}
|
||||
|
||||
public void setSecureProfile(boolean secureProfile) {
|
||||
this.secureProfile = secureProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeInt(entityId);
|
||||
|
||||
if (version.fromTo(Version.V1_7_2, Version.V1_7_6)) {
|
||||
msg.writeByte(gameMode == 3 ? 1 : gameMode);
|
||||
msg.writeByte(dimensionRegistry.getDefaultDimension_1_16().getId());
|
||||
msg.writeByte(0); // Difficulty
|
||||
msg.writeByte(maxPlayers);
|
||||
msg.writeString("flat"); // Level type
|
||||
}
|
||||
|
||||
if (version.fromTo(Version.V1_8, Version.V1_9)) {
|
||||
if (version.fromTo(Version.V1_8, Version.V1_9_1)) {
|
||||
msg.writeByte(gameMode);
|
||||
msg.writeByte(dimensionRegistry.getDefaultDimension_1_16().getId());
|
||||
msg.writeByte(0); // Difficulty
|
||||
@ -126,7 +108,7 @@ public class PacketJoinGame implements PacketOut {
|
||||
msg.writeBoolean(reducedDebugInfo);
|
||||
}
|
||||
|
||||
if (version.fromTo(Version.V1_9_1, Version.V1_13_2)) {
|
||||
if (version.fromTo(Version.V1_9_2, Version.V1_13_2)) {
|
||||
msg.writeByte(gameMode);
|
||||
msg.writeInt(dimensionRegistry.getDefaultDimension_1_16().getId());
|
||||
msg.writeByte(0); // Difficulty
|
||||
@ -211,22 +193,12 @@ public class PacketJoinGame implements PacketOut {
|
||||
msg.writeBoolean(isFlat);
|
||||
}
|
||||
|
||||
if (version.fromTo(Version.V1_19, Version.V1_19_4)) {
|
||||
if (version.moreOrEqual(Version.V1_19)) {
|
||||
msg.writeBoolean(isHardcore);
|
||||
msg.writeByte(gameMode);
|
||||
msg.writeByte(previousGameMode);
|
||||
msg.writeStringsArray(worldNames);
|
||||
if (version.moreOrEqual(Version.V1_19_1)) {
|
||||
if (version.moreOrEqual(Version.V1_19_4)) {
|
||||
msg.writeCompoundTag(dimensionRegistry.getCodec_1_19_4());
|
||||
}
|
||||
else {
|
||||
msg.writeCompoundTag(dimensionRegistry.getCodec_1_19_1());
|
||||
}
|
||||
}
|
||||
else {
|
||||
msg.writeCompoundTag(dimensionRegistry.getCodec_1_19());
|
||||
}
|
||||
msg.writeString(worldName); // World type
|
||||
msg.writeString(worldName);
|
||||
msg.writeLong(hashedSeed);
|
||||
@ -239,67 +211,6 @@ public class PacketJoinGame implements PacketOut {
|
||||
msg.writeBoolean(isFlat);
|
||||
msg.writeBoolean(false);
|
||||
}
|
||||
|
||||
if (version.equals(Version.V1_20)) {
|
||||
msg.writeBoolean(isHardcore);
|
||||
msg.writeByte(gameMode);
|
||||
msg.writeByte(previousGameMode);
|
||||
msg.writeStringsArray(worldNames);
|
||||
msg.writeCompoundTag(dimensionRegistry.getCodec_1_20());
|
||||
msg.writeString(worldName); // World type
|
||||
msg.writeString(worldName);
|
||||
msg.writeLong(hashedSeed);
|
||||
msg.writeVarInt(maxPlayers);
|
||||
msg.writeVarInt(viewDistance);
|
||||
msg.writeVarInt(viewDistance); // Simulation Distance
|
||||
msg.writeBoolean(reducedDebugInfo);
|
||||
msg.writeBoolean(enableRespawnScreen);
|
||||
msg.writeBoolean(isDebug);
|
||||
msg.writeBoolean(isFlat);
|
||||
msg.writeBoolean(false);
|
||||
msg.writeVarInt(0);
|
||||
}
|
||||
|
||||
if (version.fromTo(Version.V1_20_2, Version.V1_20_3)) {
|
||||
msg.writeBoolean(isHardcore);
|
||||
msg.writeStringsArray(worldNames);
|
||||
msg.writeVarInt(maxPlayers);
|
||||
msg.writeVarInt(viewDistance);
|
||||
msg.writeVarInt(viewDistance); // Simulation Distance
|
||||
msg.writeBoolean(reducedDebugInfo);
|
||||
msg.writeBoolean(enableRespawnScreen);
|
||||
msg.writeBoolean(limitedCrafting);
|
||||
msg.writeString(worldName);
|
||||
msg.writeString(worldName);
|
||||
msg.writeLong(hashedSeed);
|
||||
msg.writeByte(gameMode);
|
||||
msg.writeByte(previousGameMode);
|
||||
msg.writeBoolean(isDebug);
|
||||
msg.writeBoolean(isFlat);
|
||||
msg.writeBoolean(false);
|
||||
msg.writeVarInt(0);
|
||||
}
|
||||
|
||||
if (version.moreOrEqual(Version.V1_20_5)) {
|
||||
msg.writeBoolean(isHardcore);
|
||||
msg.writeStringsArray(worldNames);
|
||||
msg.writeVarInt(maxPlayers);
|
||||
msg.writeVarInt(viewDistance);
|
||||
msg.writeVarInt(viewDistance); // Simulation Distance
|
||||
msg.writeBoolean(reducedDebugInfo);
|
||||
msg.writeBoolean(enableRespawnScreen);
|
||||
msg.writeBoolean(limitedCrafting);
|
||||
msg.writeVarInt(dimensionRegistry.getDimension_1_20_5().getId());
|
||||
msg.writeString(worldName);
|
||||
msg.writeLong(hashedSeed);
|
||||
msg.writeByte(gameMode);
|
||||
msg.writeByte(previousGameMode);
|
||||
msg.writeBoolean(isDebug);
|
||||
msg.writeBoolean(isFlat);
|
||||
msg.writeBoolean(false);
|
||||
msg.writeVarInt(0);
|
||||
msg.writeBoolean(secureProfile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.Packet;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.Packet;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketKeepAlive implements Packet {
|
||||
|
||||
@ -37,10 +37,8 @@ public class PacketKeepAlive implements Packet {
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
if (version.moreOrEqual(Version.V1_12_2)) {
|
||||
msg.writeLong(id);
|
||||
} else if (version.moreOrEqual(Version.V1_8)) {
|
||||
msg.writeVarInt((int) id);
|
||||
} else {
|
||||
msg.writeInt((int) id);
|
||||
msg.writeVarInt((int) id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,10 +46,8 @@ public class PacketKeepAlive implements Packet {
|
||||
public void decode(ByteMessage msg, Version version) {
|
||||
if (version.moreOrEqual(Version.V1_12_2)) {
|
||||
this.id = msg.readLong();
|
||||
} else if (version.moreOrEqual(Version.V1_8)) {
|
||||
this.id = msg.readVarInt();
|
||||
} else {
|
||||
this.id = msg.readInt();
|
||||
this.id = msg.readVarInt();
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketPlayerAbilities implements PacketOut {
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Nan1t
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This packet was very simplified and using only for ADD_PLAYER action
|
||||
*/
|
||||
public class PacketPlayerInfo implements PacketOut {
|
||||
|
||||
private int gameMode = 3;
|
||||
private String username = "";
|
||||
private UUID uuid;
|
||||
|
||||
public void setGameMode(int gameMode) {
|
||||
this.gameMode = gameMode;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setUuid(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeVarInt(0); // Add player action
|
||||
msg.writeVarInt(1);
|
||||
msg.writeUuid(uuid);
|
||||
msg.writeString(username);
|
||||
msg.writeVarInt(0);
|
||||
msg.writeVarInt(gameMode);
|
||||
msg.writeVarInt(60);
|
||||
msg.writeBoolean(false);
|
||||
if (version.moreOrEqual(Version.V1_19)) {
|
||||
msg.writeBoolean(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -15,29 +15,28 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketPlayerListHeader implements PacketOut {
|
||||
|
||||
private NbtMessage header;
|
||||
private NbtMessage footer;
|
||||
private String header;
|
||||
private String footer;
|
||||
|
||||
public void setHeader(NbtMessage header) {
|
||||
public void setHeader(String header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public void setFooter(NbtMessage footer) {
|
||||
public void setFooter(String footer) {
|
||||
this.footer = footer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeNbtMessage(header, version);
|
||||
msg.writeNbtMessage(footer, version);
|
||||
msg.writeString(header);
|
||||
msg.writeString(footer);
|
||||
}
|
||||
}
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketPlayerPositionAndLook implements PacketOut {
|
||||
|
||||
@ -28,38 +28,53 @@ public class PacketPlayerPositionAndLook implements PacketOut {
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
private byte flags = 0x08;
|
||||
private int teleportId;
|
||||
|
||||
public PacketPlayerPositionAndLook() {}
|
||||
|
||||
public PacketPlayerPositionAndLook(double x, double y, double z, float yaw, float pitch, int teleportId) {
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public void setYaw(float yaw) {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
public void setPitch(float pitch) {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public void setFlags(byte flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public void setTeleportId(int teleportId) {
|
||||
this.teleportId = teleportId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeDouble(x);
|
||||
msg.writeDouble(y + (version.less(Version.V1_8) ? 1.62F : 0));
|
||||
msg.writeDouble(y);
|
||||
msg.writeDouble(z);
|
||||
msg.writeFloat(yaw);
|
||||
msg.writeFloat(pitch);
|
||||
|
||||
if (version.moreOrEqual(Version.V1_8)) {
|
||||
msg.writeByte(0x08);
|
||||
if (version.less(Version.V1_9)) {
|
||||
msg.writeBoolean(true); // On ground
|
||||
} else {
|
||||
msg.writeBoolean(true);
|
||||
}
|
||||
|
||||
if (version.moreOrEqual(Version.V1_9)) {
|
||||
msg.writeByte(flags);
|
||||
msg.writeVarInt(teleportId);
|
||||
}
|
||||
|
||||
if (version.fromTo(Version.V1_17, Version.V1_19_3)) {
|
||||
if (version.moreOrEqual(Version.V1_17)) {
|
||||
msg.writeBoolean(false); // Dismount vehicle
|
||||
}
|
||||
}
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketPluginMessage implements PacketOut {
|
||||
|
||||
@ -39,5 +39,4 @@ public class PacketPluginMessage implements PacketOut {
|
||||
msg.writeString(channel);
|
||||
msg.writeString(message);
|
||||
}
|
||||
|
||||
}
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.data.Title;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.data.Title;
|
||||
|
||||
public class PacketTitleLegacy implements PacketOut {
|
||||
|
@ -15,24 +15,23 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketTitleSetSubTitle implements PacketOut {
|
||||
|
||||
private NbtMessage subtitle;
|
||||
private String subtitle;
|
||||
|
||||
public void setSubtitle(NbtMessage subtitle) {
|
||||
public void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeNbtMessage(subtitle, version);
|
||||
msg.writeString(subtitle);
|
||||
}
|
||||
|
||||
}
|
@ -15,24 +15,23 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketTitleSetTitle implements PacketOut {
|
||||
|
||||
private NbtMessage title;
|
||||
private String title;
|
||||
|
||||
public void setTitle(NbtMessage title) {
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeNbtMessage(title, version);
|
||||
msg.writeString(title);
|
||||
}
|
||||
|
||||
}
|
@ -15,11 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
package ru.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketTitleTimes implements PacketOut {
|
||||
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.status;
|
||||
package ru.nanit.limbo.protocol.packets.status;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.Packet;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.Packet;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketStatusPing implements Packet {
|
||||
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.status;
|
||||
package ru.nanit.limbo.protocol.packets.status;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketIn;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketIn;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketStatusRequest implements PacketIn {
|
||||
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.status;
|
||||
package ru.nanit.limbo.protocol.packets.status;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.protocol.ByteMessage;
|
||||
import ru.nanit.limbo.protocol.PacketOut;
|
||||
import ru.nanit.limbo.protocol.registry.Version;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketStatusResponse implements PacketOut {
|
||||
|
||||
@ -36,16 +36,9 @@ public class PacketStatusResponse implements PacketOut {
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
int protocol;
|
||||
int staticProtocol = server.getConfig().getPingData().getProtocol();
|
||||
|
||||
if (staticProtocol > 0) {
|
||||
protocol = staticProtocol;
|
||||
} else {
|
||||
protocol = server.getConfig().getInfoForwarding().isNone()
|
||||
int protocol = server.getConfig().getInfoForwarding().isNone()
|
||||
? version.getProtocolNumber()
|
||||
: Version.getMax().getProtocolNumber();
|
||||
}
|
||||
|
||||
String ver = server.getConfig().getPingData().getVersion();
|
||||
String desc = server.getConfig().getPingData().getDescription();
|
@ -15,21 +15,20 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.registry;
|
||||
package ru.nanit.limbo.protocol.registry;
|
||||
|
||||
import ua.nanit.limbo.protocol.Packet;
|
||||
import ua.nanit.limbo.protocol.packets.PacketHandshake;
|
||||
import ua.nanit.limbo.protocol.packets.login.*;
|
||||
import ua.nanit.limbo.protocol.packets.play.*;
|
||||
import ua.nanit.limbo.protocol.packets.configuration.*;
|
||||
import ua.nanit.limbo.protocol.packets.status.PacketStatusPing;
|
||||
import ua.nanit.limbo.protocol.packets.status.PacketStatusRequest;
|
||||
import ua.nanit.limbo.protocol.packets.status.PacketStatusResponse;
|
||||
import ru.nanit.limbo.protocol.Packet;
|
||||
import ru.nanit.limbo.protocol.packets.PacketHandshake;
|
||||
import ru.nanit.limbo.protocol.packets.login.*;
|
||||
import ru.nanit.limbo.protocol.packets.play.*;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusPing;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusRequest;
|
||||
import ru.nanit.limbo.protocol.packets.status.PacketStatusResponse;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static ua.nanit.limbo.protocol.registry.Version.*;
|
||||
import static ru.nanit.limbo.protocol.registry.Version.*;
|
||||
|
||||
public enum State {
|
||||
|
||||
@ -64,10 +63,6 @@ public enum State {
|
||||
serverBound.register(PacketLoginPluginResponse::new,
|
||||
map(0x02, Version.getMin(), Version.getMax())
|
||||
);
|
||||
serverBound.register(
|
||||
PacketLoginAcknowledged::new,
|
||||
map(0x03, V1_20_2, Version.getMax())
|
||||
);
|
||||
clientBound.register(PacketDisconnect::new,
|
||||
map(0x00, Version.getMin(), Version.getMax())
|
||||
);
|
||||
@ -79,55 +74,10 @@ public enum State {
|
||||
);
|
||||
}
|
||||
},
|
||||
CONFIGURATION(3) {
|
||||
{
|
||||
clientBound.register(
|
||||
PacketPluginMessage::new,
|
||||
map(0x00, V1_20_2, V1_20_3),
|
||||
map(0x01, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(
|
||||
PacketDisconnect::new,
|
||||
map(0x01, V1_20_2, V1_20_3),
|
||||
map(0x02, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(
|
||||
PacketFinishConfiguration::new,
|
||||
map(0x02, V1_20_2, V1_20_3),
|
||||
map(0x03, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(
|
||||
PacketKeepAlive::new,
|
||||
map(0x03, V1_20_2, V1_20_3),
|
||||
map(0x04, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(
|
||||
PacketRegistryData::new,
|
||||
map(0x05, V1_20_2, V1_20_3),
|
||||
map(0x07, V1_20_5, V1_21)
|
||||
);
|
||||
|
||||
serverBound.register(
|
||||
PacketPluginMessage::new,
|
||||
map(0x01, V1_20_2, V1_20_3),
|
||||
map(0x02, V1_20_2, V1_21)
|
||||
);
|
||||
serverBound.register(
|
||||
PacketFinishConfiguration::new,
|
||||
map(0x02, V1_20_2, V1_20_3),
|
||||
map(0x03, V1_20_5, V1_21)
|
||||
);
|
||||
serverBound.register(
|
||||
PacketKeepAlive::new,
|
||||
map(0x03, V1_20_2, V1_20_3),
|
||||
map(0x04, V1_20_5, V1_21)
|
||||
);
|
||||
}
|
||||
},
|
||||
PLAY(4) {
|
||||
PLAY(3) {
|
||||
{
|
||||
serverBound.register(PacketKeepAlive::new,
|
||||
map(0x00, V1_7_2, V1_8),
|
||||
map(0x00, V1_8, V1_8),
|
||||
map(0x0B, V1_9, V1_11_1),
|
||||
map(0x0C, V1_12, V1_12),
|
||||
map(0x0B, V1_12_1, V1_12_2),
|
||||
@ -135,13 +85,7 @@ public enum State {
|
||||
map(0x0F, V1_14, V1_15_2),
|
||||
map(0x10, V1_16, V1_16_4),
|
||||
map(0x0F, V1_17, V1_18_2),
|
||||
map(0x11, V1_19, V1_19),
|
||||
map(0x12, V1_19_1, V1_19_1),
|
||||
map(0x11, V1_19_3, V1_19_3),
|
||||
map(0x12, V1_19_4, V1_20),
|
||||
map(0x14, V1_20_2, V1_20_2),
|
||||
map(0x15, V1_20_3, V1_20_3),
|
||||
map(0x18, V1_20_5, V1_21)
|
||||
map(0x11, V1_19, V1_19)
|
||||
);
|
||||
|
||||
clientBound.register(PacketDeclareCommands::new,
|
||||
@ -150,25 +94,17 @@ public enum State {
|
||||
map(0x11, V1_16, V1_16_1),
|
||||
map(0x10, V1_16_2, V1_16_4),
|
||||
map(0x12, V1_17, V1_18_2),
|
||||
map(0x0F, V1_19, V1_19_1),
|
||||
map(0x0E, V1_19_3, V1_19_3),
|
||||
map(0x10, V1_19_4, V1_20),
|
||||
map(0x11, V1_20_2, V1_21)
|
||||
map(0x0F, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketJoinGame::new,
|
||||
map(0x01, V1_7_2, V1_8),
|
||||
map(0x01, V1_8, V1_8),
|
||||
map(0x23, V1_9, V1_12_2),
|
||||
map(0x25, V1_13, V1_14_4),
|
||||
map(0x26, V1_15, V1_15_2),
|
||||
map(0x25, V1_16, V1_16_1),
|
||||
map(0x24, V1_16_2, V1_16_4),
|
||||
map(0x26, V1_17, V1_18_2),
|
||||
map(0x23, V1_19, V1_19),
|
||||
map(0x25, V1_19_1, V1_19_1),
|
||||
map(0x24, V1_19_3, V1_19_3),
|
||||
map(0x28, V1_19_4, V1_20),
|
||||
map(0x29, V1_20_2, V1_20_3),
|
||||
map(0x2B, V1_20_5, V1_21)
|
||||
map(0x23, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketPluginMessage::new,
|
||||
map(0x19, V1_13, V1_13_2),
|
||||
@ -177,15 +113,10 @@ public enum State {
|
||||
map(0x18, V1_16, V1_16_1),
|
||||
map(0x17, V1_16_2, V1_16_4),
|
||||
map(0x18, V1_17, V1_18_2),
|
||||
map(0x15, V1_19, V1_19),
|
||||
map(0x16, V1_19_1, V1_19_1),
|
||||
map(0x15, V1_19_3, V1_19_3),
|
||||
map(0x17, V1_19_4, V1_20),
|
||||
map(0x18, V1_20_2, V1_20_3),
|
||||
map(0x19, V1_20_5, V1_21)
|
||||
map(0x15, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketPlayerAbilities::new,
|
||||
map(0x39, V1_7_2, V1_8),
|
||||
map(0x39, V1_8, V1_8),
|
||||
map(0x2B, V1_9, V1_12),
|
||||
map(0x2C, V1_12_1, V1_12_2),
|
||||
map(0x2E, V1_13, V1_13_2),
|
||||
@ -194,15 +125,10 @@ public enum State {
|
||||
map(0x31, V1_16, V1_16_1),
|
||||
map(0x30, V1_16_2, V1_16_4),
|
||||
map(0x32, V1_17, V1_18_2),
|
||||
map(0x2F, V1_19, V1_19),
|
||||
map(0x31, V1_19_1, V1_19_1),
|
||||
map(0x30, V1_19_3, V1_19_3),
|
||||
map(0x34, V1_19_4, V1_20),
|
||||
map(0x36, V1_20_2, V1_20_3),
|
||||
map(0x38, V1_20_5, V1_21)
|
||||
map(0x2F, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketPlayerPositionAndLook::new,
|
||||
map(0x08, V1_7_2, V1_8),
|
||||
map(0x08, V1_8, V1_8),
|
||||
map(0x2E, V1_9, V1_12),
|
||||
map(0x2F, V1_12_1, V1_12_2),
|
||||
map(0x32, V1_13, V1_13_2),
|
||||
@ -211,15 +137,10 @@ public enum State {
|
||||
map(0x35, V1_16, V1_16_1),
|
||||
map(0x34, V1_16_2, V1_16_4),
|
||||
map(0x38, V1_17, V1_18_2),
|
||||
map(0x36, V1_19, V1_19),
|
||||
map(0x39, V1_19_1, V1_19_1),
|
||||
map(0x38, V1_19_3, V1_19_3),
|
||||
map(0x3C, V1_19_4, V1_20),
|
||||
map(0x3E, V1_20_2, V1_20_3),
|
||||
map(0x40, V1_20_5, V1_21)
|
||||
map(0x36, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketKeepAlive::new,
|
||||
map(0x00, V1_7_2, V1_8),
|
||||
map(0x00, V1_8, V1_8),
|
||||
map(0x1F, V1_9, V1_12_2),
|
||||
map(0x21, V1_13, V1_13_2),
|
||||
map(0x20, V1_14, V1_14_4),
|
||||
@ -227,39 +148,26 @@ public enum State {
|
||||
map(0x20, V1_16, V1_16_1),
|
||||
map(0x1F, V1_16_2, V1_16_4),
|
||||
map(0x21, V1_17, V1_18_2),
|
||||
map(0x1E, V1_19, V1_19),
|
||||
map(0x20, V1_19_1, V1_19_1),
|
||||
map(0x1F, V1_19_3, V1_19_3),
|
||||
map(0x23, V1_19_4, V1_20),
|
||||
map(0x24, V1_20_2, V1_20_3),
|
||||
map(0x26, V1_20_5, V1_21)
|
||||
map(0x1E, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketChatMessage::new,
|
||||
map(0x02, V1_7_2, V1_8),
|
||||
map(0x02, V1_8, V1_8),
|
||||
map(0x0F, V1_9, V1_12_2),
|
||||
map(0x0E, V1_13, V1_14_4),
|
||||
map(0x0F, V1_15, V1_15_2),
|
||||
map(0x0E, V1_16, V1_16_4),
|
||||
map(0x0F, V1_17, V1_18_2),
|
||||
map(0x5F, V1_19, V1_19),
|
||||
map(0x62, V1_19_1, V1_19_1),
|
||||
map(0x60, V1_19_3, V1_19_3),
|
||||
map(0x64, V1_19_4, V1_20),
|
||||
map(0x67, V1_20_2, V1_20_2),
|
||||
map(0x69, V1_20_3, V1_20_3),
|
||||
map(0x6C, V1_20_5, V1_21)
|
||||
map(0x5F, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketBossBar::new,
|
||||
map(0x0C, V1_9, V1_14_4),
|
||||
map(0x0D, V1_15, V1_15_2),
|
||||
map(0x0C, V1_16, V1_16_4),
|
||||
map(0x0D, V1_17, V1_18_2),
|
||||
map(0x0A, V1_19, V1_19_3),
|
||||
map(0x0B, V1_19_4, V1_20),
|
||||
map(0x0A, V1_20_2, V1_21)
|
||||
map(0x0A, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketPlayerInfo::new,
|
||||
map(0x38, V1_7_2, V1_8),
|
||||
map(0x38, V1_8, V1_8),
|
||||
map(0x2D, V1_9, V1_12),
|
||||
map(0x2E, V1_12_1, V1_12_2),
|
||||
map(0x30, V1_13, V1_13_2),
|
||||
@ -268,12 +176,7 @@ public enum State {
|
||||
map(0x33, V1_16, V1_16_1),
|
||||
map(0x32, V1_16_2, V1_16_4),
|
||||
map(0x36, V1_17, V1_18_2),
|
||||
map(0x34, V1_19, V1_19),
|
||||
map(0x37, V1_19_1, V1_19_1),
|
||||
map(0x36, V1_19_3, V1_19_3),
|
||||
map(0x3A, V1_19_4, V1_20),
|
||||
map(0x3C, V1_20_2, V1_20_3),
|
||||
map(0x3E, V1_20_5, V1_21)
|
||||
map(0x34, V1_19, V1_19)
|
||||
);
|
||||
clientBound.register(PacketTitleLegacy::new,
|
||||
map(0x45, V1_8, V1_11_1),
|
||||
@ -286,33 +189,15 @@ public enum State {
|
||||
);
|
||||
clientBound.register(PacketTitleSetTitle::new,
|
||||
map(0x59, V1_17, V1_17_1),
|
||||
map(0x5A, V1_18, V1_19),
|
||||
map(0x5D, V1_19_1, V1_19_1),
|
||||
map(0x5B, V1_19_3, V1_19_3),
|
||||
map(0x5F, V1_19_4, V1_20),
|
||||
map(0x61, V1_20_2, V1_20_2),
|
||||
map(0x63, V1_20_3, V1_20_3),
|
||||
map(0x65, V1_20_5, V1_21)
|
||||
map(0x5A, V1_18, V1_19)
|
||||
);
|
||||
clientBound.register(PacketTitleSetSubTitle::new,
|
||||
map(0x57, V1_17, V1_17_1),
|
||||
map(0x58, V1_18, V1_19),
|
||||
map(0x5B, V1_19_1, V1_19_1),
|
||||
map(0x59, V1_19_3, V1_19_3),
|
||||
map(0x5D, V1_19_4, V1_20),
|
||||
map(0x5F, V1_20_2, V1_20_2),
|
||||
map(0x61, V1_20_3, V1_20_3),
|
||||
map(0x63, V1_20_5, V1_21)
|
||||
map(0x58, V1_18, V1_19)
|
||||
);
|
||||
clientBound.register(PacketTitleTimes::new,
|
||||
map(0x5A, V1_17, V1_17_1),
|
||||
map(0x5B, V1_18, V1_19),
|
||||
map(0x5E, V1_19_1, V1_19_1),
|
||||
map(0x5C, V1_19_3, V1_19_3),
|
||||
map(0x60, V1_19_4, V1_20),
|
||||
map(0x62, V1_20_2, V1_20_2),
|
||||
map(0x64, V1_20_3, V1_20_3),
|
||||
map(0x66, V1_20_5, V1_21)
|
||||
map(0x5B, V1_18, V1_19)
|
||||
);
|
||||
clientBound.register(PacketPlayerListHeader::new,
|
||||
map(0x47, V1_8, V1_8),
|
||||
@ -326,28 +211,7 @@ public enum State {
|
||||
map(0x53, V1_16, V1_16_4),
|
||||
map(0x5E, V1_17, V1_17_1),
|
||||
map(0x5F, V1_18, V1_18_2),
|
||||
map(0x60, V1_19, V1_19),
|
||||
map(0x63, V1_19_1, V1_19_1),
|
||||
map(0x61, V1_19_3, V1_19_3),
|
||||
map(0x65, V1_19_4, V1_20),
|
||||
map(0x68, V1_20_2, V1_20_2),
|
||||
map(0x6A, V1_20_3, V1_20_3),
|
||||
map(0x6D, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(PacketSpawnPosition::new,
|
||||
map(0x4C, V1_19_3, V1_19_3),
|
||||
map(0x50, V1_19_4, V1_20),
|
||||
map(0x52, V1_20_2, V1_20_2),
|
||||
map(0x54, V1_20_3, V1_20_3),
|
||||
map(0x56, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(PacketGameEvent::new,
|
||||
map(0x20, V1_20_3, V1_20_3),
|
||||
map(0x22, V1_20_5, V1_21)
|
||||
);
|
||||
clientBound.register(PacketEmptyChunk::new,
|
||||
map(0x25, V1_20_3, V1_20_3),
|
||||
map(0x27, V1_20_5, V1_21)
|
||||
map(0x60, V1_19, V1_19)
|
||||
);
|
||||
}
|
||||
};
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.registry;
|
||||
package ru.nanit.limbo.protocol.registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -23,10 +23,6 @@ import java.util.Map;
|
||||
public enum Version {
|
||||
|
||||
UNDEFINED(-1),
|
||||
V1_7_2(4),
|
||||
// 1.7.2-1.7.5 has same protocol numbers
|
||||
V1_7_6(5),
|
||||
// 1.7.6-1.7.10 has same protocol numbers
|
||||
V1_8(47),
|
||||
// 1.8-1.8.8 has same protocol numbers
|
||||
V1_9(107),
|
||||
@ -63,18 +59,7 @@ public enum Version {
|
||||
V1_18(757),
|
||||
// 1.18.1 has same protocol number
|
||||
V1_18_2(758),
|
||||
V1_19(759),
|
||||
V1_19_1(760),
|
||||
// 1.19.2 has same protocol number
|
||||
V1_19_3(761),
|
||||
V1_19_4(762),
|
||||
V1_20(763),
|
||||
// 1.20.1 has same protocol number
|
||||
V1_20_2(764),
|
||||
V1_20_3(765),
|
||||
V1_20_5(766),
|
||||
// 1.20.6 has same protocol number
|
||||
V1_21(767);
|
||||
V1_19(759);
|
||||
|
||||
private static final Map<Integer, Version> VERSION_MAP;
|
||||
private static final Version MAX;
|
||||
@ -133,7 +118,7 @@ public enum Version {
|
||||
}
|
||||
|
||||
public static Version getMin() {
|
||||
return V1_7_2;
|
||||
return V1_8;
|
||||
}
|
||||
|
||||
public static Version getMax() {
|
@ -1,4 +1,4 @@
|
||||
package ua.nanit.limbo.server;
|
||||
package ru.nanit.limbo.server;
|
||||
|
||||
public interface Command {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package ua.nanit.limbo.server;
|
||||
package ru.nanit.limbo.server;
|
||||
|
||||
import ua.nanit.limbo.server.commands.*;
|
||||
import ru.nanit.limbo.server.commands.CmdConn;
|
||||
import ru.nanit.limbo.server.commands.CmdHelp;
|
||||
import ru.nanit.limbo.server.commands.CmdMem;
|
||||
import ru.nanit.limbo.server.commands.CmdStop;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -16,10 +19,8 @@ public final class CommandManager extends Thread {
|
||||
return commands.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
public void register(Command cmd, String... aliases) {
|
||||
for (String alias : aliases) {
|
||||
commands.put(alias.toLowerCase(), cmd);
|
||||
}
|
||||
public void register(String name, Command cmd) {
|
||||
commands.put(name.toLowerCase(), cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,20 +41,19 @@ public final class CommandManager extends Thread {
|
||||
try {
|
||||
handler.execute();
|
||||
} catch (Throwable t) {
|
||||
Log.error("Cannot execute command:", t);
|
||||
Logger.error("Cannot execute command:", t);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Log.info("Unknown command. Type \"help\" to get commands list");
|
||||
Logger.info("Unknown command. Type \"help\" to get commands list");
|
||||
}
|
||||
}
|
||||
|
||||
public void registerAll(LimboServer server) {
|
||||
register(new CmdHelp(server), "help");
|
||||
register(new CmdConn(server), "conn");
|
||||
register(new CmdMem(), "mem");
|
||||
register(new CmdStop(), "stop");
|
||||
register(new CmdVersion(), "version", "ver");
|
||||
register("help", new CmdHelp(server));
|
||||
register("conn", new CmdConn(server));
|
||||
register("mem", new CmdMem());
|
||||
register("stop", new CmdStop());
|
||||
}
|
||||
}
|
@ -15,9 +15,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server;
|
||||
package ru.nanit.limbo.server;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -43,12 +43,12 @@ public final class Connections {
|
||||
|
||||
public void addConnection(ClientConnection connection) {
|
||||
connections.put(connection.getUuid(), connection);
|
||||
Log.info("Player %s connected (%s) [%s]", connection.getUsername(),
|
||||
Logger.info("Player %s connected (%s) [%s]", connection.getUsername(),
|
||||
connection.getAddress(), connection.getClientVersion());
|
||||
}
|
||||
|
||||
public void removeConnection(ClientConnection connection) {
|
||||
connections.remove(connection.getUuid());
|
||||
Log.info("Player %s disconnected", connection.getUsername());
|
||||
Logger.info("Player %s disconnected", connection.getUsername());
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server;
|
||||
package ru.nanit.limbo.server;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelOption;
|
||||
@ -27,12 +27,12 @@ import io.netty.channel.epoll.EpollServerSocketChannel;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.util.ResourceLeakDetector;
|
||||
import ua.nanit.limbo.configuration.LimboConfig;
|
||||
import ua.nanit.limbo.connection.ClientChannelInitializer;
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.connection.PacketHandler;
|
||||
import ua.nanit.limbo.connection.PacketSnapshots;
|
||||
import ua.nanit.limbo.world.DimensionRegistry;
|
||||
import ru.nanit.limbo.configuration.LimboConfig;
|
||||
import ru.nanit.limbo.connection.ClientChannelInitializer;
|
||||
import ru.nanit.limbo.connection.ClientConnection;
|
||||
import ru.nanit.limbo.connection.PacketHandler;
|
||||
import ru.nanit.limbo.connection.PacketSnapshots;
|
||||
import ru.nanit.limbo.world.dimension.DimensionRegistry;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
@ -72,14 +72,13 @@ public final class LimboServer {
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
config = new LimboConfig(Paths.get("./"));
|
||||
config.load();
|
||||
|
||||
Log.setLevel(config.getDebugLevel());
|
||||
Log.info("Starting server...");
|
||||
Logger.info("Starting server...");
|
||||
|
||||
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED);
|
||||
|
||||
config = new LimboConfig(Paths.get("./"));
|
||||
config.load();
|
||||
|
||||
packetHandler = new PacketHandler(this);
|
||||
dimensionRegistry = new DimensionRegistry(this);
|
||||
dimensionRegistry.load(config.getDimensionType());
|
||||
@ -93,7 +92,9 @@ public final class LimboServer {
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "NanoLimbo shutdown thread"));
|
||||
|
||||
Log.info("Server started on %s", config.getAddress());
|
||||
Logger.info("Server started on %s", config.getAddress());
|
||||
|
||||
Logger.setLevel(config.getDebugLevel());
|
||||
|
||||
commandManager = new CommandManager();
|
||||
commandManager.registerAll(this);
|
||||
@ -109,12 +110,12 @@ public final class LimboServer {
|
||||
bossGroup = new EpollEventLoopGroup(config.getBossGroupSize());
|
||||
workerGroup = new EpollEventLoopGroup(config.getWorkerGroupSize());
|
||||
channelClass = EpollServerSocketChannel.class;
|
||||
Log.debug("Using Epoll transport type");
|
||||
Logger.debug("Using Epoll transport type");
|
||||
} else {
|
||||
bossGroup = new NioEventLoopGroup(config.getBossGroupSize());
|
||||
workerGroup = new NioEventLoopGroup(config.getWorkerGroupSize());
|
||||
channelClass = NioServerSocketChannel.class;
|
||||
Log.debug("Using Java NIO transport type");
|
||||
Logger.debug("Using Java NIO transport type");
|
||||
}
|
||||
|
||||
new ServerBootstrap()
|
||||
@ -131,7 +132,7 @@ public final class LimboServer {
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
Log.info("Stopping server...");
|
||||
Logger.info("Stopping server...");
|
||||
|
||||
if (keepAliveTask != null) {
|
||||
keepAliveTask.cancel(true);
|
||||
@ -145,7 +146,7 @@ public final class LimboServer {
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
|
||||
Log.info("Server stopped, Goodbye!");
|
||||
Logger.info("Server stopped, Goodbye!");
|
||||
}
|
||||
|
||||
}
|
@ -15,73 +15,63 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server;
|
||||
package ru.nanit.limbo.server;
|
||||
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public final class Log {
|
||||
public final class Logger {
|
||||
|
||||
private static final Logger LOGGER = (Logger) LoggerFactory.getLogger("Limbo");
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("hh:mm:ss");
|
||||
private static int debugLevel = Level.INFO.getIndex();
|
||||
|
||||
private Log() {}
|
||||
private Logger() {}
|
||||
|
||||
public static int getLevel() {
|
||||
return debugLevel;
|
||||
}
|
||||
|
||||
public static void info(Object msg, Object... args) {
|
||||
LOGGER.info(String.format(msg.toString(), args));
|
||||
print(Level.INFO, msg, null, args);
|
||||
}
|
||||
|
||||
public static void debug(Object msg, Object... args) {
|
||||
LOGGER.debug(String.format(msg.toString(), args));
|
||||
print(Level.DEBUG, msg, null, args);
|
||||
}
|
||||
|
||||
public static void warning(Object msg, Object... args) {
|
||||
LOGGER.warn(String.format(msg.toString(), args));
|
||||
print(Level.WARNING, msg, null, args);
|
||||
}
|
||||
|
||||
public static void warning(Object msg, Throwable t, Object... args) {
|
||||
LOGGER.warn(String.format(msg.toString(), args), t);
|
||||
print(Level.WARNING, msg, t, args);
|
||||
}
|
||||
|
||||
public static void error(Object msg, Object... args) {
|
||||
LOGGER.error(msg.toString(), args);
|
||||
print(Level.ERROR, msg, null, args);
|
||||
}
|
||||
|
||||
public static void error(Object msg, Throwable t, Object... args) {
|
||||
LOGGER.error(String.format(msg.toString(), args), t);
|
||||
print(Level.ERROR, msg, t, args);
|
||||
}
|
||||
|
||||
public static boolean isDebug() {
|
||||
return debugLevel >= Level.DEBUG.getIndex();
|
||||
public static void print(Level level, Object msg, Throwable t, Object... args) {
|
||||
if (debugLevel >= level.getIndex()) {
|
||||
System.out.printf("%s: %s%n", getPrefix(level), String.format(msg.toString(), args));
|
||||
if (t != null) t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getPrefix(Level level) {
|
||||
return String.format("[%s] [%s]", getTime(), level.getDisplay());
|
||||
}
|
||||
|
||||
private static String getTime() {
|
||||
return LocalTime.now().format(FORMATTER);
|
||||
}
|
||||
|
||||
static void setLevel(int level) {
|
||||
debugLevel = level;
|
||||
|
||||
Logger logback = getRootLogger();
|
||||
|
||||
if (logback != null) {
|
||||
logback.setLevel(convertLevel(level));
|
||||
}
|
||||
}
|
||||
|
||||
private static Logger getRootLogger() {
|
||||
return (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
||||
}
|
||||
|
||||
private static ch.qos.logback.classic.Level convertLevel(int level) {
|
||||
switch (level) {
|
||||
case 0:
|
||||
return ch.qos.logback.classic.Level.ERROR;
|
||||
case 1:
|
||||
return ch.qos.logback.classic.Level.WARN;
|
||||
case 2:
|
||||
return ch.qos.logback.classic.Level.INFO;
|
||||
case 3:
|
||||
return ch.qos.logback.classic.Level.DEBUG;
|
||||
default:
|
||||
throw new IllegalStateException("Undefined log level: " + level);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Level {
|
@ -1,8 +1,8 @@
|
||||
package ua.nanit.limbo.server.commands;
|
||||
package ru.nanit.limbo.server.commands;
|
||||
|
||||
import ua.nanit.limbo.server.Command;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.server.Command;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
public class CmdConn implements Command {
|
||||
|
||||
@ -14,7 +14,7 @@ public class CmdConn implements Command {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Log.info("Connections: %d", server.getConnections().getCount());
|
||||
Logger.info("Connections: %d", server.getConnections().getCount());
|
||||
}
|
||||
|
||||
@Override
|
@ -1,8 +1,8 @@
|
||||
package ua.nanit.limbo.server.commands;
|
||||
package ru.nanit.limbo.server.commands;
|
||||
|
||||
import ua.nanit.limbo.server.Command;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.server.Command;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -18,10 +18,10 @@ public class CmdHelp implements Command {
|
||||
public void execute() {
|
||||
Map<String, Command> commands = server.getCommandManager().getCommands();
|
||||
|
||||
Log.info("Available commands:");
|
||||
Logger.info("Available commands:");
|
||||
|
||||
for (Map.Entry<String, Command> entry : commands.entrySet()) {
|
||||
Log.info("%s - %s", entry.getKey(), entry.getValue().description());
|
||||
Logger.info("%s - %s", entry.getKey(), entry.getValue().description());
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ua.nanit.limbo.server.commands;
|
||||
package ru.nanit.limbo.server.commands;
|
||||
|
||||
import ua.nanit.limbo.server.Command;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.server.Command;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
public class CmdMem implements Command {
|
||||
|
||||
@ -14,11 +14,11 @@ public class CmdMem implements Command {
|
||||
long free = runtime.freeMemory() / mb;
|
||||
long max = runtime.maxMemory() / mb;
|
||||
|
||||
Log.info("Memory usage:");
|
||||
Log.info("Used: %d MB", used);
|
||||
Log.info("Total: %d MB", total);
|
||||
Log.info("Free: %d MB", free);
|
||||
Log.info("Max: %d MB", max);
|
||||
Logger.info("Memory usage:");
|
||||
Logger.info("Used: %d MB", used);
|
||||
Logger.info("Total: %d MB", total);
|
||||
Logger.info("Free: %d MB", free);
|
||||
Logger.info("Max: %d MB", max);
|
||||
}
|
||||
|
||||
@Override
|
@ -1,6 +1,6 @@
|
||||
package ua.nanit.limbo.server.commands;
|
||||
package ru.nanit.limbo.server.commands;
|
||||
|
||||
import ua.nanit.limbo.server.Command;
|
||||
import ru.nanit.limbo.server.Command;
|
||||
|
||||
public class CmdStop implements Command {
|
||||
|
@ -15,26 +15,24 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server.data;
|
||||
package ru.nanit.limbo.server.data;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
import ua.nanit.limbo.util.Colors;
|
||||
import ua.nanit.limbo.util.NbtMessageUtil;
|
||||
import ru.nanit.limbo.util.Colors;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class BossBar {
|
||||
|
||||
private NbtMessage text;
|
||||
private String text;
|
||||
private float health;
|
||||
private Color color;
|
||||
private Division division;
|
||||
|
||||
public NbtMessage getText() {
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@ -50,7 +48,7 @@ public class BossBar {
|
||||
return division;
|
||||
}
|
||||
|
||||
public void setText(NbtMessage text) {
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@ -112,7 +110,7 @@ public class BossBar {
|
||||
public BossBar deserialize(Type type, ConfigurationNode node) throws SerializationException {
|
||||
BossBar bossBar = new BossBar();
|
||||
|
||||
bossBar.setText(NbtMessageUtil.create(Colors.of(node.node("text").getString(""))));
|
||||
bossBar.setText(Colors.of(node.node("text").getString("")));
|
||||
bossBar.setHealth(node.node("health").getFloat());
|
||||
|
||||
if (bossBar.getHealth() < 0 || bossBar.getHealth() > 1)
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server.data;
|
||||
package ru.nanit.limbo.server.data;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server.data;
|
||||
package ru.nanit.limbo.server.data;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import ua.nanit.limbo.util.Colors;
|
||||
import ru.nanit.limbo.util.Colors;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@ -28,7 +28,6 @@ public class PingData {
|
||||
|
||||
private String version;
|
||||
private String description;
|
||||
private int protocol;
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
@ -46,14 +45,6 @@ public class PingData {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(int protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public static class Serializer implements TypeSerializer<PingData> {
|
||||
|
||||
@Override
|
||||
@ -61,7 +52,6 @@ public class PingData {
|
||||
PingData pingData = new PingData();
|
||||
pingData.setDescription(Colors.of(node.node("description").getString("")));
|
||||
pingData.setVersion(Colors.of(node.node("version").getString("")));
|
||||
pingData.setProtocol(node.node("protocol").getInt(-1));
|
||||
return pingData;
|
||||
}
|
||||
|
@ -15,30 +15,28 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.server.data;
|
||||
package ru.nanit.limbo.server.data;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
import ua.nanit.limbo.util.Colors;
|
||||
import ua.nanit.limbo.util.NbtMessageUtil;
|
||||
import ru.nanit.limbo.util.Colors;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class Title {
|
||||
|
||||
private NbtMessage title;
|
||||
private NbtMessage subtitle;
|
||||
private String title;
|
||||
private String subtitle;
|
||||
private int fadeIn;
|
||||
private int stay;
|
||||
private int fadeOut;
|
||||
|
||||
public NbtMessage getTitle() {
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public NbtMessage getSubtitle() {
|
||||
public String getSubtitle() {
|
||||
return subtitle;
|
||||
}
|
||||
|
||||
@ -54,11 +52,11 @@ public class Title {
|
||||
return fadeOut;
|
||||
}
|
||||
|
||||
public void setTitle(NbtMessage title) {
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setSubtitle(NbtMessage subtitle) {
|
||||
public void setSubtitle(String subtitle) {
|
||||
this.subtitle = subtitle;
|
||||
}
|
||||
|
||||
@ -79,8 +77,8 @@ public class Title {
|
||||
@Override
|
||||
public Title deserialize(Type type, ConfigurationNode node) {
|
||||
Title title = new Title();
|
||||
title.setTitle(NbtMessageUtil.create(Colors.of(node.node("title").getString(""))));
|
||||
title.setSubtitle(NbtMessageUtil.create(Colors.of(node.node("subtitle").getString(""))));
|
||||
title.setTitle(Colors.of(node.node("title").getString("")));
|
||||
title.setSubtitle(Colors.of(node.node("subtitle").getString("")));
|
||||
title.setFadeIn(node.node("fadeIn").getInt(10));
|
||||
title.setStay(node.node("stay").getInt(100));
|
||||
title.setFadeOut(node.node("fadeOut").getInt(10));
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.util;
|
||||
package ru.nanit.limbo.util;
|
||||
|
||||
public final class Colors {
|
||||
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.util;
|
||||
package ru.nanit.limbo.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
106
src/main/java/ru/nanit/limbo/world/Location.java
Normal file
106
src/main/java/ru/nanit/limbo/world/Location.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Nan1t
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ru.nanit.limbo.world;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class Location {
|
||||
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
private final float yaw;
|
||||
private final float pitch;
|
||||
|
||||
Location(double x, double y, double z, float yaw, float pitch) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
Location(double x, double y, double z) {
|
||||
this(x, y, z, 0.0F, 0.0F);
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getBlockX() {
|
||||
return (int) x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getBlockY() {
|
||||
return (int) y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public int getBlockZ() {
|
||||
return (int) z;
|
||||
}
|
||||
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public static Location of(double x, double y, double z) {
|
||||
return new Location(x, y, z);
|
||||
}
|
||||
|
||||
public static Location of(double x, double y, double z, float yaw, float pitch) {
|
||||
return new Location(x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
public static Location pos(int x, int y, int z) {
|
||||
return new Location(x, y, z);
|
||||
}
|
||||
|
||||
public static class Serializer implements TypeSerializer<Location> {
|
||||
|
||||
@Override
|
||||
public Location deserialize(Type type, ConfigurationNode node) {
|
||||
double x = node.node("x").getDouble(0);
|
||||
double y = node.node("y").getDouble(0);
|
||||
double z = node.node("z").getDouble(0);
|
||||
float yaw = node.node("yaw").getFloat(0.0F);
|
||||
float pitch = node.node("pitch").getFloat(0.0F);
|
||||
|
||||
return new Location(x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Type type, @Nullable Location obj, ConfigurationNode node) { }
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.world;
|
||||
package ru.nanit.limbo.world.dimension;
|
||||
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.world;
|
||||
package ru.nanit.limbo.world.dimension;
|
||||
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
import net.kyori.adventure.nbt.ListBinaryTag;
|
||||
import net.kyori.adventure.nbt.TagStringIO;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ru.nanit.limbo.server.LimboServer;
|
||||
import ru.nanit.limbo.server.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -33,16 +33,10 @@ public final class DimensionRegistry {
|
||||
|
||||
private Dimension defaultDimension_1_16;
|
||||
private Dimension defaultDimension_1_18_2;
|
||||
private Dimension dimension_1_20_5;
|
||||
private Dimension dimension_1_21;
|
||||
|
||||
private CompoundBinaryTag codec_1_16;
|
||||
private CompoundBinaryTag codec_1_18_2;
|
||||
private CompoundBinaryTag codec_1_19;
|
||||
private CompoundBinaryTag codec_1_19_1;
|
||||
private CompoundBinaryTag codec_1_19_4;
|
||||
private CompoundBinaryTag codec_1_20;
|
||||
private CompoundBinaryTag codec_1_21;
|
||||
private CompoundBinaryTag oldCodec;
|
||||
|
||||
public DimensionRegistry(LimboServer server) {
|
||||
@ -61,22 +55,6 @@ public final class DimensionRegistry {
|
||||
return codec_1_19;
|
||||
}
|
||||
|
||||
public CompoundBinaryTag getCodec_1_19_1() {
|
||||
return codec_1_19_1;
|
||||
}
|
||||
|
||||
public CompoundBinaryTag getCodec_1_19_4() {
|
||||
return codec_1_19_4;
|
||||
}
|
||||
|
||||
public CompoundBinaryTag getCodec_1_20() {
|
||||
return codec_1_20;
|
||||
}
|
||||
|
||||
public CompoundBinaryTag getCodec_1_21() {
|
||||
return codec_1_21;
|
||||
}
|
||||
|
||||
public CompoundBinaryTag getOldCodec() {
|
||||
return oldCodec;
|
||||
}
|
||||
@ -89,30 +67,15 @@ public final class DimensionRegistry {
|
||||
return defaultDimension_1_18_2;
|
||||
}
|
||||
|
||||
public Dimension getDimension_1_20_5() {
|
||||
return dimension_1_20_5;
|
||||
}
|
||||
|
||||
public Dimension getDimension_1_21() {
|
||||
return dimension_1_21;
|
||||
}
|
||||
|
||||
public void load(String def) throws IOException {
|
||||
// On 1.16-1.16.1 different codec format
|
||||
oldCodec = readCodecFile("/dimension/codec_old.snbt");
|
||||
codec_1_16 = readCodecFile("/dimension/codec_1_16.snbt");
|
||||
codec_1_18_2 = readCodecFile("/dimension/codec_1_18_2.snbt");
|
||||
codec_1_19 = readCodecFile("/dimension/codec_1_19.snbt");
|
||||
codec_1_19_1 = readCodecFile("/dimension/codec_1_19_1.snbt");
|
||||
codec_1_19_4 = readCodecFile("/dimension/codec_1_19_4.snbt");
|
||||
codec_1_20 = readCodecFile("/dimension/codec_1_20.snbt");
|
||||
codec_1_21 = readCodecFile("/dimension/codec_1_21.snbt");
|
||||
// On 1.16-1.16.1 different codec format
|
||||
oldCodec = readCodecFile("/dimension/codec_old.snbt");
|
||||
|
||||
defaultDimension_1_16 = getDefaultDimension(def, codec_1_16);
|
||||
defaultDimension_1_18_2 = getDefaultDimension(def, codec_1_18_2);
|
||||
|
||||
dimension_1_20_5 = getModernDimension(def, codec_1_20);
|
||||
dimension_1_21 = getModernDimension(def, codec_1_21);
|
||||
}
|
||||
|
||||
private Dimension getDefaultDimension(String def, CompoundBinaryTag tag) {
|
||||
@ -130,37 +93,29 @@ public final class DimensionRegistry {
|
||||
case "the_end":
|
||||
return new Dimension(1, "minecraft:the_end", theEnd);
|
||||
default:
|
||||
Log.warning("Undefined dimension type: '%s'. Using THE_END as default", def);
|
||||
Logger.warning("Undefined dimension type: '%s'. Using THE_END as default", def);
|
||||
return new Dimension(1, "minecraft:the_end", theEnd);
|
||||
}
|
||||
}
|
||||
|
||||
private Dimension getModernDimension(String def, CompoundBinaryTag tag) {
|
||||
switch (def.toLowerCase()) {
|
||||
case "overworld":
|
||||
return new Dimension(0, "minecraft:overworld", tag);
|
||||
case "the_nether":
|
||||
return new Dimension(2, "minecraft:nether", tag);
|
||||
case "the_end":
|
||||
return new Dimension(3, "minecraft:the_end", tag);
|
||||
default:
|
||||
Log.warning("Undefined dimension type: '%s'. Using THE_END as default", def);
|
||||
return new Dimension(3, "minecraft:the_end", tag);
|
||||
}
|
||||
}
|
||||
|
||||
private CompoundBinaryTag readCodecFile(String resPath) throws IOException {
|
||||
InputStream in = server.getClass().getResourceAsStream(resPath);
|
||||
|
||||
if (in == null)
|
||||
if(in == null)
|
||||
throw new FileNotFoundException("Cannot find dimension registry file");
|
||||
|
||||
return TagStringIO.get().asCompound(streamToString(in));
|
||||
}
|
||||
|
||||
private String streamToString(InputStream in) throws IOException {
|
||||
try (BufferedReader bufReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
|
||||
return bufReader.lines().collect(Collectors.joining("\n"));
|
||||
}
|
||||
InputStreamReader isReader = new InputStreamReader(in, StandardCharsets.UTF_8);
|
||||
BufferedReader bufReader = new BufferedReader(isReader);
|
||||
String content = bufReader.lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
isReader.close();
|
||||
bufReader.close();
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package ua.nanit.limbo.connection.pipeline;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ChannelTrafficHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private final int maxPacketSize;
|
||||
private final double maxPacketRate;
|
||||
private final PacketBucket packetBucket;
|
||||
|
||||
public ChannelTrafficHandler(int maxPacketSize, double interval, double maxPacketRate) {
|
||||
this.maxPacketSize = maxPacketSize;
|
||||
this.maxPacketRate = maxPacketRate;
|
||||
this.packetBucket = (interval > 0.0 && maxPacketRate > 0.0) ? new PacketBucket(interval * 1000.0, 150) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) throws Exception {
|
||||
if (msg instanceof ByteBuf) {
|
||||
ByteBuf in = (ByteBuf) msg;
|
||||
int bytes = in.readableBytes();
|
||||
|
||||
if (maxPacketSize > 0 && bytes > maxPacketSize) {
|
||||
closeConnection(ctx, "Closed %s due to large packet size (%d bytes)", ctx.channel().remoteAddress(), bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packetBucket != null) {
|
||||
packetBucket.incrementPackets(1);
|
||||
if (packetBucket.getCurrentPacketRate() > maxPacketRate) {
|
||||
closeConnection(ctx, "Closed %s due to many packets sent (%d in the last %.1f seconds)", ctx.channel().remoteAddress(), packetBucket.sum, (packetBucket.intervalTime / 1000.0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
private void closeConnection(ChannelHandlerContext ctx, String reason, Object... args) {
|
||||
ctx.close();
|
||||
Log.info(reason, args);
|
||||
}
|
||||
|
||||
private static class PacketBucket {
|
||||
private static final double NANOSECONDS_TO_MILLISECONDS = 1.0e-6;
|
||||
private static final int MILLISECONDS_TO_SECONDS = 1000;
|
||||
|
||||
private final double intervalTime;
|
||||
private final double intervalResolution;
|
||||
private final int[] data;
|
||||
private int newestData;
|
||||
private double lastBucketTime;
|
||||
private int sum;
|
||||
|
||||
public PacketBucket(final double intervalTime, final int totalBuckets) {
|
||||
this.intervalTime = intervalTime;
|
||||
this.intervalResolution = intervalTime / totalBuckets;
|
||||
this.data = new int[totalBuckets];
|
||||
}
|
||||
|
||||
public void incrementPackets(final int packets) {
|
||||
double timeMs = System.nanoTime() * NANOSECONDS_TO_MILLISECONDS;
|
||||
double timeDelta = timeMs - this.lastBucketTime;
|
||||
|
||||
if (timeDelta < 0.0) {
|
||||
timeDelta = 0.0;
|
||||
}
|
||||
|
||||
if (timeDelta < this.intervalResolution) {
|
||||
this.data[this.newestData] += packets;
|
||||
this.sum += packets;
|
||||
return;
|
||||
}
|
||||
|
||||
int bucketsToMove = (int)(timeDelta / this.intervalResolution);
|
||||
double nextBucketTime = this.lastBucketTime + bucketsToMove * this.intervalResolution;
|
||||
|
||||
if (bucketsToMove >= this.data.length) {
|
||||
Arrays.fill(this.data, 0);
|
||||
this.data[0] = packets;
|
||||
this.sum = packets;
|
||||
this.newestData = 0;
|
||||
this.lastBucketTime = timeMs;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i < bucketsToMove; ++i) {
|
||||
int index = (this.newestData + i) % this.data.length;
|
||||
this.sum -= this.data[index];
|
||||
this.data[index] = 0;
|
||||
}
|
||||
|
||||
int newestDataIndex = (this.newestData + bucketsToMove) % this.data.length;
|
||||
this.sum += packets - this.data[newestDataIndex];
|
||||
this.data[newestDataIndex] = packets;
|
||||
this.newestData = newestDataIndex;
|
||||
this.lastBucketTime = nextBucketTime;
|
||||
}
|
||||
|
||||
public double getCurrentPacketRate() {
|
||||
return this.sum / (this.intervalTime / MILLISECONDS_TO_SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package ua.nanit.limbo.protocol;
|
||||
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MetadataWriter {
|
||||
|
||||
void writeData(ByteMessage message, Version version);
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package ua.nanit.limbo.protocol;
|
||||
|
||||
import net.kyori.adventure.nbt.BinaryTag;
|
||||
|
||||
public class NbtMessage {
|
||||
|
||||
private String json;
|
||||
private BinaryTag tag;
|
||||
|
||||
public NbtMessage(String json, BinaryTag tag) {
|
||||
this.json = json;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getJson() {
|
||||
return json;
|
||||
}
|
||||
|
||||
public void setJson(String json) {
|
||||
this.json = json;
|
||||
}
|
||||
|
||||
public BinaryTag getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(BinaryTag tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package ua.nanit.limbo.protocol.packets.configuration;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.PacketIn;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketFinishConfiguration implements PacketIn, PacketOut {
|
||||
|
||||
@Override
|
||||
public void handle(ClientConnection conn, LimboServer server) {
|
||||
server.getPacketHandler().handle(conn, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package ua.nanit.limbo.protocol.packets.configuration;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.MetadataWriter;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
import ua.nanit.limbo.world.DimensionRegistry;
|
||||
|
||||
public class PacketRegistryData implements PacketOut {
|
||||
|
||||
private DimensionRegistry dimensionRegistry;
|
||||
private MetadataWriter metadataWriter;
|
||||
|
||||
public void setDimensionRegistry(DimensionRegistry dimensionRegistry) {
|
||||
this.dimensionRegistry = dimensionRegistry;
|
||||
}
|
||||
|
||||
public void setMetadataWriter(MetadataWriter metadataWriter) {
|
||||
this.metadataWriter = metadataWriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
if (metadataWriter != null) {
|
||||
if (version.moreOrEqual(Version.V1_20_5)) {
|
||||
metadataWriter.writeData(msg, version);
|
||||
return;
|
||||
}
|
||||
}
|
||||
msg.writeNamelessCompoundTag(dimensionRegistry.getCodec_1_20());
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package ua.nanit.limbo.protocol.packets.login;
|
||||
|
||||
import ua.nanit.limbo.connection.ClientConnection;
|
||||
import ua.nanit.limbo.protocol.PacketIn;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.server.LimboServer;
|
||||
|
||||
public class PacketLoginAcknowledged implements PacketIn, PacketOut {
|
||||
|
||||
@Override
|
||||
public void handle(ClientConnection conn, LimboServer server) {
|
||||
server.getPacketHandler().handle(conn, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
import net.kyori.adventure.nbt.LongArrayBinaryTag;
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketEmptyChunk implements PacketOut {
|
||||
|
||||
private int x;
|
||||
private int z;
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setZ(int z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeInt(x);
|
||||
msg.writeInt(z);
|
||||
|
||||
LongArrayBinaryTag longArrayTag = LongArrayBinaryTag.longArrayBinaryTag(new long[37]);
|
||||
CompoundBinaryTag tag = CompoundBinaryTag.builder()
|
||||
.put("MOTION_BLOCKING", longArrayTag).build();
|
||||
CompoundBinaryTag rootTag = CompoundBinaryTag.builder()
|
||||
.put("root", tag).build();
|
||||
msg.writeNamelessCompoundTag(rootTag);
|
||||
|
||||
byte[] sectionData = new byte[]{0, 0, 0, 0, 0, 0, 1, 0};
|
||||
msg.writeVarInt(sectionData.length * 16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
msg.writeBytes(sectionData);
|
||||
}
|
||||
|
||||
msg.writeVarInt(0);
|
||||
|
||||
byte[] lightData = new byte[]{1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, -1, -1, 0, 0};
|
||||
msg.ensureWritable(lightData.length);
|
||||
msg.writeBytes(lightData, 1, lightData.length - 1);
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketGameEvent implements PacketOut {
|
||||
|
||||
private byte type;
|
||||
private float value;
|
||||
|
||||
public void setType(byte type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setValue(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeByte(type);
|
||||
msg.writeFloat(value);
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Nan1t
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This packet was very simplified and using only for ADD_PLAYER action
|
||||
*/
|
||||
public class PacketPlayerInfo implements PacketOut {
|
||||
|
||||
private int gameMode = 3;
|
||||
private String username = "";
|
||||
private UUID uuid;
|
||||
|
||||
public void setGameMode(int gameMode) {
|
||||
this.gameMode = gameMode;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setUuid(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
if (version.less(Version.V1_8)) {
|
||||
msg.writeString(username);
|
||||
msg.writeBoolean(true); // Is online
|
||||
msg.writeShort(0);
|
||||
} else {
|
||||
if (version.moreOrEqual(Version.V1_19_3)) {
|
||||
EnumSet<Action> actions = EnumSet.noneOf(Action.class);
|
||||
actions.add(Action.ADD_PLAYER);
|
||||
actions.add(Action.UPDATE_LISTED);
|
||||
actions.add(Action.UPDATE_GAMEMODE);
|
||||
msg.writeEnumSet(actions, Action.class);
|
||||
|
||||
msg.writeVarInt(1); // Array length (1 element)
|
||||
msg.writeUuid(uuid); // UUID
|
||||
msg.writeString(username); //Username
|
||||
msg.writeVarInt(0); //Properties (0 is empty)
|
||||
|
||||
msg.writeBoolean(true); //Update listed
|
||||
msg.writeVarInt(gameMode); //Gamemode
|
||||
return;
|
||||
}
|
||||
|
||||
msg.writeVarInt(0); // Add player action
|
||||
msg.writeVarInt(1);
|
||||
msg.writeUuid(uuid);
|
||||
msg.writeString(username);
|
||||
msg.writeVarInt(0);
|
||||
msg.writeVarInt(gameMode);
|
||||
msg.writeVarInt(60);
|
||||
msg.writeBoolean(false);
|
||||
|
||||
if (version.moreOrEqual(Version.V1_19)) {
|
||||
msg.writeBoolean(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Action {
|
||||
ADD_PLAYER,
|
||||
INITIALIZE_CHAT,
|
||||
UPDATE_GAMEMODE,
|
||||
UPDATE_LISTED,
|
||||
UPDATE_LATENCY,
|
||||
UPDATE_DISPLAY_NAME;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package ua.nanit.limbo.protocol.packets.play;
|
||||
|
||||
import ua.nanit.limbo.protocol.ByteMessage;
|
||||
import ua.nanit.limbo.protocol.PacketOut;
|
||||
import ua.nanit.limbo.protocol.registry.Version;
|
||||
|
||||
public class PacketSpawnPosition implements PacketOut {
|
||||
|
||||
private long x;
|
||||
private long y;
|
||||
private long z;
|
||||
|
||||
public PacketSpawnPosition() { }
|
||||
|
||||
public PacketSpawnPosition(long x, long y, long z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteMessage msg, Version version) {
|
||||
msg.writeLong(encodePosition(x, y ,z));
|
||||
msg.writeFloat(0);
|
||||
}
|
||||
|
||||
private static long encodePosition(long x, long y, long z) {
|
||||
return ((x & 0x3FFFFFF) << 38) | ((z & 0x3FFFFFF) << 12) | (y & 0xFFF);
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package ua.nanit.limbo.server.commands;
|
||||
|
||||
import ua.nanit.limbo.server.Command;
|
||||
import ua.nanit.limbo.server.Log;
|
||||
import ua.nanit.limbo.BuildConfig;
|
||||
|
||||
public class CmdVersion implements Command {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Log.info("Version: %s", BuildConfig.LIMBO_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Display limbo version";
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package ua.nanit.limbo.util;
|
||||
|
||||
import com.google.gson.*;
|
||||
import net.kyori.adventure.nbt.*;
|
||||
import ua.nanit.limbo.protocol.NbtMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NbtMessageUtil {
|
||||
|
||||
public static NbtMessage create(String json) {
|
||||
BinaryTag compoundBinaryTag = fromJson(JsonParser.parseString(json));
|
||||
|
||||
return new NbtMessage(json, compoundBinaryTag);
|
||||
}
|
||||
|
||||
public static BinaryTag fromJson(JsonElement json) {
|
||||
if (json instanceof JsonPrimitive) {
|
||||
JsonPrimitive jsonPrimitive = (JsonPrimitive) json;
|
||||
if (jsonPrimitive.isNumber()) {
|
||||
Number number = json.getAsNumber();
|
||||
|
||||
if (number instanceof Byte) {
|
||||
return ByteBinaryTag.byteBinaryTag((Byte) number);
|
||||
} else if (number instanceof Short) {
|
||||
return ShortBinaryTag.shortBinaryTag((Short) number);
|
||||
} else if (number instanceof Integer) {
|
||||
return IntBinaryTag.intBinaryTag((Integer) number);
|
||||
} else if (number instanceof Long) {
|
||||
return LongBinaryTag.longBinaryTag((Long) number);
|
||||
} else if (number instanceof Float) {
|
||||
return FloatBinaryTag.floatBinaryTag((Float) number);
|
||||
} else if (number instanceof Double) {
|
||||
return DoubleBinaryTag.doubleBinaryTag((Double) number);
|
||||
}
|
||||
} else if (jsonPrimitive.isString()) {
|
||||
return StringBinaryTag.stringBinaryTag(jsonPrimitive.getAsString());
|
||||
} else if (jsonPrimitive.isBoolean()) {
|
||||
return ByteBinaryTag.byteBinaryTag(jsonPrimitive.getAsBoolean() ? (byte) 1 : (byte) 0);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown JSON primitive: " + jsonPrimitive);
|
||||
}
|
||||
} else if (json instanceof JsonObject) {
|
||||
CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder();
|
||||
for (Map.Entry<String, JsonElement> property : ((JsonObject) json).entrySet()) {
|
||||
builder.put(property.getKey(), fromJson(property.getValue()));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
} else if (json instanceof JsonArray) {
|
||||
List<JsonElement> jsonArray = ((JsonArray) json).asList();
|
||||
|
||||
if (jsonArray.isEmpty()) {
|
||||
return ListBinaryTag.listBinaryTag(EndBinaryTag.endBinaryTag().type(), Collections.emptyList());
|
||||
}
|
||||
|
||||
BinaryTagType tagByteType = ByteBinaryTag.ZERO.type();
|
||||
BinaryTagType tagIntType = IntBinaryTag.intBinaryTag(0).type();
|
||||
BinaryTagType tagLongType = LongBinaryTag.longBinaryTag(0).type();
|
||||
|
||||
BinaryTag listTag;
|
||||
BinaryTagType listType = fromJson(jsonArray.get(0)).type();
|
||||
if (listType.equals(tagByteType)) {
|
||||
byte[] bytes = new byte[jsonArray.size()];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = (Byte) ((JsonPrimitive) jsonArray.get(i)).getAsNumber();
|
||||
}
|
||||
|
||||
listTag = ByteArrayBinaryTag.byteArrayBinaryTag(bytes);
|
||||
} else if (listType.equals(tagIntType)) {
|
||||
int[] ints = new int[jsonArray.size()];
|
||||
for (int i = 0; i < ints.length; i++) {
|
||||
ints[i] = (Integer) ((JsonPrimitive) jsonArray.get(i)).getAsNumber();
|
||||
}
|
||||
|
||||
listTag = IntArrayBinaryTag.intArrayBinaryTag(ints);
|
||||
} else if (listType.equals(tagLongType)) {
|
||||
long[] longs = new long[jsonArray.size()];
|
||||
for (int i = 0; i < longs.length; i++) {
|
||||
longs[i] = (Long) ((JsonPrimitive) jsonArray.get(i)).getAsNumber();
|
||||
}
|
||||
|
||||
listTag = LongArrayBinaryTag.longArrayBinaryTag(longs);
|
||||
} else {
|
||||
List<BinaryTag> tagItems = new ArrayList<>(jsonArray.size());
|
||||
|
||||
for (JsonElement jsonEl : jsonArray) {
|
||||
BinaryTag subTag = fromJson(jsonEl);
|
||||
if (subTag.type() != listType) {
|
||||
throw new IllegalArgumentException("Cannot convert mixed JsonArray to Tag");
|
||||
}
|
||||
|
||||
tagItems.add(subTag);
|
||||
}
|
||||
|
||||
listTag = ListBinaryTag.listBinaryTag(listType, tagItems);
|
||||
}
|
||||
|
||||
return listTag;
|
||||
} else if (json instanceof JsonNull) {
|
||||
return EndBinaryTag.endBinaryTag();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown JSON element: " + json);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration>
|
||||
|
||||
<configuration>
|
||||
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
|
||||
<import class="ch.qos.logback.core.ConsoleAppender"/>
|
||||
<import class="ch.qos.logback.core.FileAppender"/>
|
||||
|
||||
<timestamp key="bySecond" datePattern="yyyy-MM-dd"/>
|
||||
|
||||
<appender name="STDOUT" class="ConsoleAppender">
|
||||
<encoder class="PatternLayoutEncoder">
|
||||
<pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} -%kvp- %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="FileAppender">
|
||||
<file>logs/log-${bySecond}.txt</file>
|
||||
<immediateFlush>true</immediateFlush>
|
||||
|
||||
<encoder class="PatternLayoutEncoder">
|
||||
<pattern>%d{HH:mm:ss.SSS} %-5level %logger{36} -%kvp- %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="FILE"/>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
@ -7,7 +7,7 @@ bind:
|
||||
ip: 'localhost'
|
||||
port: 65535
|
||||
|
||||
# Max number of players can join to server
|
||||
# Max amount of players can join to server
|
||||
# Set -1 to make it infinite
|
||||
maxPlayers: 100
|
||||
|
||||
@ -15,48 +15,49 @@ maxPlayers: 100
|
||||
ping:
|
||||
description: '{"text": "&9NanoLimbo"}'
|
||||
version: 'NanoLimbo'
|
||||
# Return static protocol version number in ping result
|
||||
# By default, its -1 to return the client version if it supported
|
||||
# https://wiki.vg/Protocol_version_numbers
|
||||
protocol: -1
|
||||
|
||||
# Available dimensions: OVERWORLD, NETHER, THE_END
|
||||
dimension: THE_END
|
||||
|
||||
# Whether to display the player in the player list
|
||||
# For 1.16.5 clients, the player list will be sent even if disabled, to avoid crash
|
||||
# For 1.16.5 clients player list will be sent even if disabled, to avoid crash
|
||||
playerList:
|
||||
enable: false
|
||||
username: 'NanoLimbo'
|
||||
|
||||
# Whether to display header and footer in player list
|
||||
# For 1.8+ clients
|
||||
headerAndFooter:
|
||||
enable: false
|
||||
header: '{"text": "&eWelcome!"}'
|
||||
footer: '{"text": "&9NanoLimbo"}'
|
||||
|
||||
# Spawn position in the world
|
||||
spawnPosition:
|
||||
x: 0.0
|
||||
y: 400.0
|
||||
z: 0.0
|
||||
yaw: 0.0
|
||||
pitch: 0.0
|
||||
|
||||
# Setup player's game mode
|
||||
# 0 - Survival
|
||||
# 1 - Creative (hide HP and food bar)
|
||||
# 2 - Adventure
|
||||
# 3 - Spectator (hide all UI bars)
|
||||
# Spectator works on 1.8+ clients
|
||||
gameMode: 3
|
||||
|
||||
# Server name which is shown under F3
|
||||
# For 1.13+ clients
|
||||
brandName:
|
||||
enable: true
|
||||
content: 'NanoLimbo'
|
||||
|
||||
# Message sends when player joins to the server
|
||||
# Message sends when player join to server
|
||||
joinMessage:
|
||||
enable: true
|
||||
text: '{"text": "&eWelcome to the Limbo!"}'
|
||||
|
||||
# BossBar displays when player joins to the server
|
||||
# For 1.9+ clients
|
||||
# BossBar displays when player join to server
|
||||
# Works on 1.9+ clients only
|
||||
bossBar:
|
||||
enable: true
|
||||
text: '{"text": "Welcome to the Limbo!"}'
|
||||
@ -67,7 +68,6 @@ bossBar:
|
||||
division: SOLID
|
||||
|
||||
# Display title and subtitle
|
||||
# For 1.8+ clients
|
||||
title:
|
||||
enable: true
|
||||
# Set title text value empty, if you need only subtitle
|
||||
@ -87,7 +87,7 @@ title:
|
||||
# - LEGACY
|
||||
# - MODERN
|
||||
# - BUNGEE_GUARD
|
||||
# Don't use secret if you do not use MODERN type
|
||||
# Don't use secret if you not use MODERN type
|
||||
infoForwarding:
|
||||
type: NONE
|
||||
secret: '<YOUR_SECRET_HERE>'
|
||||
@ -105,29 +105,11 @@ readTimeout: 30000
|
||||
# 3 - Display errors, warnings, info, debug
|
||||
debugLevel: 2
|
||||
|
||||
# Warning! Do not touch params of this block if you are not completely sure what is this!
|
||||
# Warning! Do not touch params of this block, if you not completely sure what is this!
|
||||
netty:
|
||||
# Use a Linux native transport type, if it possible
|
||||
# Use Linux native transport type, if it possible
|
||||
useEpoll: true
|
||||
# EventLoopGroup threads count
|
||||
threads:
|
||||
bossGroup: 1
|
||||
workerGroup: 4
|
||||
|
||||
# Options to check incoming traffic and kick potentially malicious connections.
|
||||
# Take into account that player can send many small packets, for example, just moving mouse.
|
||||
traffic:
|
||||
# If true, then additional handler will be added to the channel pipeline
|
||||
enable: true
|
||||
# Max packet size in bytes
|
||||
# Unlimited if -1
|
||||
maxPacketSize: 8192
|
||||
# The interval to measure packets over
|
||||
# Lowering this value will limit peak packets from players which would target people with bad connections
|
||||
# Raising this value will allow higher peak packet rates, which will help with people who have poor connections
|
||||
# Ignored if -1.0
|
||||
interval: 7.0
|
||||
# The maximum packets per second for players
|
||||
# It is measured over the configured interval
|
||||
# Ignored if -1.0
|
||||
maxPacketRate: 500.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user