update 1.12.2 with locations
This commit is contained in:
parent
6cdd7ade7c
commit
e30e8132ca
|
@ -102,3 +102,5 @@ run/
|
|||
|
||||
\.floo
|
||||
\.flooignore
|
||||
|
||||
test\.sh
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
[submodule "api"]
|
||||
path = api
|
||||
url = https://github.com/NikkyAI/MatterLinkApi.git
|
||||
[submodule "Jankson"]
|
||||
path = Jankson
|
||||
url = https://github.com/falkreon/Jankson.git
|
||||
url = https://github.com/falkreon/Jankson.git
|
|
@ -34,14 +34,17 @@ dependencies {
|
|||
shadowJar {
|
||||
classifier ''
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
|
||||
dependencies {
|
||||
include project(':core')
|
||||
include project(':api')
|
||||
include project(':Jankson')
|
||||
include project(":core")
|
||||
include project(":api")
|
||||
include project(":Jankson")
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-common', version: concrete_version)
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-rulesengine', version: concrete_version)
|
||||
}
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
relocate 'com.elytradev.concrete', 'matterlink.repack.com.elytradev.concrete'
|
||||
|
||||
exclude 'dummyThing'
|
||||
}
|
||||
|
||||
|
|
|
@ -39,14 +39,17 @@ dependencies {
|
|||
shadowJar {
|
||||
classifier = ''
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
|
||||
dependencies {
|
||||
include project(':core')
|
||||
include project(':api')
|
||||
include project(':Jankson')
|
||||
include project(":core")
|
||||
include project(":api")
|
||||
include project(":Jankson")
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-common', version: concrete_version)
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-rulesengine', version: concrete_version)
|
||||
}
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
relocate 'com.elytradev.concrete', 'matterlink.repack.com.elytradev.concrete'
|
||||
|
||||
exclude 'dummyThing'
|
||||
}
|
||||
|
||||
|
|
|
@ -37,14 +37,17 @@ dependencies {
|
|||
shadowJar {
|
||||
classifier = ''
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
|
||||
dependencies {
|
||||
include project(':core')
|
||||
include project(':api')
|
||||
include project(':Jankson')
|
||||
include project(":core")
|
||||
include project(":api")
|
||||
include project(":Jankson")
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-common', version: concrete_version)
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-rulesengine', version: concrete_version)
|
||||
}
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
relocate 'com.elytradev.concrete', 'matterlink.repack.com.elytradev.concrete'
|
||||
|
||||
exclude 'dummyThing'
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package matterlink
|
||||
|
||||
import matterlink.api.ApiMessage.Companion.USER_ACTION
|
||||
import matterlink.config.cfg
|
||||
import matterlink.handlers.*
|
||||
import net.minecraft.command.server.CommandBroadcast
|
||||
|
@ -28,7 +27,11 @@ object EventHandler {
|
|||
ProgressHandler.handleProgress(
|
||||
name = e.entityPlayer.displayName.unformattedText,
|
||||
message = "has made the advancement",
|
||||
display = e.advancement.displayText.unformattedText
|
||||
display = e.advancement.displayText.unformattedText,
|
||||
x = e.entityPlayer.posX.toInt(),
|
||||
y = e.entityPlayer.posY.toInt(),
|
||||
z = e.entityPlayer.posZ.toInt(),
|
||||
dimension = e.entityPlayer.dimension
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -36,11 +39,15 @@ object EventHandler {
|
|||
@SubscribeEvent
|
||||
@JvmStatic
|
||||
fun chatEvent(e: ServerChatEvent) {
|
||||
if(e.isCanceled) return
|
||||
if (e.isCanceled) return
|
||||
e.isCanceled = ChatProcessor.sendToBridge(
|
||||
user = e.player.displayName.unformattedText,
|
||||
msg = e.message,
|
||||
event = "",
|
||||
x = e.player.posX.toInt(),
|
||||
y = e.player.posY.toInt(),
|
||||
z = e.player.posZ.toInt(),
|
||||
dimension = e.player.dimension,
|
||||
event = ChatEvent.PLAIN,
|
||||
uuid = e.player.gameProfile.id
|
||||
)
|
||||
}
|
||||
|
@ -49,18 +56,31 @@ object EventHandler {
|
|||
@SubscribeEvent
|
||||
@JvmStatic
|
||||
fun commandEvent(e: CommandEvent) {
|
||||
|
||||
val sender = when {
|
||||
e.sender is DedicatedServer -> cfg.outgoing.systemUser
|
||||
else -> e.sender.displayName.unformattedText
|
||||
}
|
||||
val args = e.parameters.joinToString(" ")
|
||||
val type = when {
|
||||
e.command is CommandEmote -> USER_ACTION
|
||||
e.command.name.equals("me", true) -> USER_ACTION
|
||||
e.command is CommandBroadcast -> ""
|
||||
else -> return
|
||||
val type = with(e.command) {
|
||||
when {
|
||||
this is CommandEmote || name.equals("me", true) -> ChatEvent.ACTION
|
||||
this is CommandBroadcast || name.equals("say", true) -> ChatEvent.BROADCAST
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
ChatProcessor.sendToBridge(user = sender, msg = args, event = type)
|
||||
ChatProcessor.sendToBridge(
|
||||
user = sender,
|
||||
msg = args,
|
||||
event = type,
|
||||
x = e.sender.position.x,
|
||||
y = e.sender.position.y,
|
||||
z = e.sender.position.z,
|
||||
dimension = when {
|
||||
e.sender is DedicatedServer -> null
|
||||
else -> e.sender.commandSenderEntity?.dimension ?: e.sender.entityWorld.provider.dimension
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
//FORGE-DEPENDENT
|
||||
|
@ -71,7 +91,11 @@ object EventHandler {
|
|||
DeathHandler.handleDeath(
|
||||
player = e.entityLiving.displayName.unformattedText,
|
||||
deathMessage = e.entityLiving.combatTracker.deathMessage.unformattedText,
|
||||
damageType = e.source.damageType
|
||||
damageType = e.source.damageType,
|
||||
x = e.entityLiving.posX.toInt(),
|
||||
y = e.entityLiving.posY.toInt(),
|
||||
z = e.entityLiving.posZ.toInt(),
|
||||
dimension = e.entityLiving.dimension
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -80,14 +104,26 @@ object EventHandler {
|
|||
@SubscribeEvent
|
||||
@JvmStatic
|
||||
fun joinEvent(e: PlayerEvent.PlayerLoggedInEvent) {
|
||||
JoinLeaveHandler.handleJoin(e.player.displayName.unformattedText)
|
||||
JoinLeaveHandler.handleJoin(
|
||||
player = e.player.displayName.unformattedText,
|
||||
x = e.player.posX.toInt(),
|
||||
y = e.player.posY.toInt(),
|
||||
z = e.player.posZ.toInt(),
|
||||
dimension = e.player.dimension
|
||||
)
|
||||
}
|
||||
|
||||
//FORGE-DEPENDENT
|
||||
@SubscribeEvent
|
||||
@JvmStatic
|
||||
fun leaveEvent(e: PlayerEvent.PlayerLoggedOutEvent) {
|
||||
JoinLeaveHandler.handleLeave(e.player.displayName.unformattedText)
|
||||
JoinLeaveHandler.handleLeave(
|
||||
player = e.player.displayName.unformattedText,
|
||||
x = e.player.posX.toInt(),
|
||||
y = e.player.posY.toInt(),
|
||||
z = e.player.posZ.toInt(),
|
||||
dimension = e.player.dimension
|
||||
)
|
||||
}
|
||||
|
||||
//FORGE-DEPENDENT
|
||||
|
|
|
@ -9,7 +9,9 @@ import matterlink.command.MatterLinkCommandSender
|
|||
import matterlink.config.BaseConfig
|
||||
import matterlink.config.cfg
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.util.text.TextComponentString
|
||||
import net.minecraftforge.common.DimensionManager
|
||||
import net.minecraftforge.common.ForgeVersion
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
|
@ -111,6 +113,14 @@ object MatterLink : IMatterLink() {
|
|||
null
|
||||
}
|
||||
|
||||
override fun collectPlayers(area: Area): Set<UUID> {
|
||||
val players = FMLCommonHandler.instance().minecraftServerInstance.playerList.players.filter {
|
||||
( area.allDimensions || area.dimensions.contains(it.dimension) )
|
||||
&& area.testInBounds(it.posX.toInt(), it.posY.toInt(), it.posZ.toInt())
|
||||
}
|
||||
return players.map { it.uniqueID }.toSet()
|
||||
}
|
||||
|
||||
override fun nameToUUID(username: String): UUID? = profileByName(username)?.id
|
||||
|
||||
override fun uuidToName(uuid: UUID): String? = profileByUUID(uuid)?.name
|
||||
|
|
2
Jankson
2
Jankson
|
@ -1 +1 @@
|
|||
Subproject commit 93ab86ee821380584c22ac60d77737388976e531
|
||||
Subproject commit 69564c34e706f5243d8ae212fb58bb982db01a81
|
1
api
1
api
|
@ -1 +0,0 @@
|
|||
Subproject commit 75138cec00c66d479709f4b44d78ca3005993474
|
|
@ -0,0 +1,5 @@
|
|||
\.idea/
|
||||
\.gradle/
|
||||
out/
|
||||
build/
|
||||
run/
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1 @@
|
|||
MatterLinkApi
|
|
@ -0,0 +1,49 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.2.41'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
group 'moe.nikky'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'idea'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
languageVersion = "1.2"
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
compileTestKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '+'
|
||||
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '+'
|
||||
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
excludeDirs += [file("run")]
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
|
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
|
@ -0,0 +1,84 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
|
@ -0,0 +1,2 @@
|
|||
rootProject.name = 'MatterLinkApi'
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package matterlink.api
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
/**
|
||||
* Created by nikky on 07/05/18.
|
||||
*
|
||||
* @author Nikky
|
||||
* @version 1.0
|
||||
*/
|
||||
class ApiMessage (
|
||||
username: String? = null,
|
||||
text: String? = null,
|
||||
gateway: String? = null,
|
||||
channel: String? = null,
|
||||
userid: String? = null,
|
||||
avatar: String? = null,
|
||||
account: String? = null,
|
||||
protocol: String? = null,
|
||||
event: String? = null,
|
||||
id: String? = null
|
||||
) {
|
||||
@SerializedName("username") private var _username: String? = username
|
||||
@SerializedName("text") private var _text: String? = text
|
||||
@SerializedName("gateway") private var _gateway: String? = gateway
|
||||
@SerializedName("channel") private var _channel: String? = channel
|
||||
@SerializedName("userid") private var _userid: String? = userid
|
||||
@SerializedName("avatar") private var _avatar: String? = avatar
|
||||
@SerializedName("account") private var _account: String? = account
|
||||
@SerializedName("protocol") private var _protocol: String? = protocol
|
||||
@SerializedName("event") private var _event: String? = event
|
||||
@SerializedName("id") private var _id: String? = id
|
||||
|
||||
var username: String
|
||||
get() = _username ?: ""
|
||||
set(username) { this._username = username }
|
||||
|
||||
var text: String
|
||||
get() = _text ?: ""
|
||||
set(text) { this._text = text }
|
||||
|
||||
var gateway: String
|
||||
get() = _gateway ?: ""
|
||||
set(gateway) { this._gateway = gateway }
|
||||
|
||||
var channel: String
|
||||
get() = _channel ?: ""
|
||||
set(channel) { this._channel = channel }
|
||||
|
||||
var userid: String
|
||||
get() = _userid ?: ""
|
||||
set(userid) { this._userid = userid }
|
||||
|
||||
var avatar: String
|
||||
get() = _avatar ?: ""
|
||||
set(avatar) { this._avatar = avatar }
|
||||
|
||||
var account: String
|
||||
get() = _account ?: ""
|
||||
set(account) { this._account = account }
|
||||
|
||||
var protocol: String
|
||||
get() = _protocol ?: ""
|
||||
set(protocol) { this._protocol = protocol }
|
||||
|
||||
var event: String
|
||||
get() = _event ?: ""
|
||||
set(event) { this._event = event }
|
||||
|
||||
var id: String
|
||||
get() = _id ?: ""
|
||||
set(id) { this._id = id }
|
||||
|
||||
fun encode(): String {
|
||||
return gson.toJson(this)
|
||||
}
|
||||
|
||||
override fun toString(): String = encode()
|
||||
|
||||
companion object {
|
||||
val USER_ACTION = "user_action"
|
||||
val JOIN_LEAVE = "join_leave"
|
||||
|
||||
private val gson = GsonBuilder()
|
||||
.create()
|
||||
|
||||
fun decode(json: String): ApiMessage {
|
||||
return gson.fromJson(json, ApiMessage::class.java)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package matterlink.api
|
||||
|
||||
data class Config (
|
||||
var url: String = "",
|
||||
var token: String = "",
|
||||
var announceConnect: Boolean = true,
|
||||
var announceDisconnect: Boolean = true,
|
||||
var reconnectWait: Long = 500,
|
||||
var systemUser: String = "Server"
|
||||
)
|
||||
{
|
||||
fun sync(connection: StreamConnection) {
|
||||
connection.token = token
|
||||
connection.host = url
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
package matterlink.api
|
||||
|
||||
import org.apache.logging.log4j.Logger
|
||||
import java.io.BufferedReader
|
||||
import java.io.DataOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.MalformedURLException
|
||||
import java.net.ProtocolException
|
||||
import java.net.URL
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
/**
|
||||
* Created by nikky on 07/05/18.
|
||||
*
|
||||
* @author Nikky
|
||||
* @version 1.0
|
||||
*/
|
||||
open class MessageHandler {
|
||||
private var enabled = false
|
||||
|
||||
private var connectErrors = 0
|
||||
private var reconnectCooldown = 0
|
||||
private var sendErrors = 0
|
||||
|
||||
var config: Config = Config()
|
||||
set(value) {
|
||||
field = value.apply {
|
||||
sync(streamConnection)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: make callbacks: onConnect onDisconnect onError etc
|
||||
|
||||
var queue: ConcurrentLinkedQueue<ApiMessage> = ConcurrentLinkedQueue()
|
||||
private set
|
||||
private var streamConnection: StreamConnection = StreamConnection(queue)
|
||||
|
||||
var logger: Logger
|
||||
get() = streamConnection.logger
|
||||
set(l) {
|
||||
streamConnection.logger = l
|
||||
}
|
||||
|
||||
|
||||
private var nextCheck: Long = 0
|
||||
|
||||
init {
|
||||
streamConnection.addOnSuccess { success ->
|
||||
if (success) {
|
||||
logger.info("connected successfully")
|
||||
connectErrors = 0
|
||||
reconnectCooldown = 0
|
||||
} else {
|
||||
reconnectCooldown = connectErrors
|
||||
connectErrors++
|
||||
logger.error(String.format("connectErrors: %d", connectErrors))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stop(message: String? = null) {
|
||||
if (message != null && config.announceDisconnect) {
|
||||
sendStatusUpdate(message)
|
||||
}
|
||||
enabled = false
|
||||
streamConnection.close()
|
||||
}
|
||||
|
||||
|
||||
fun start(message: String?, clear: Boolean) {
|
||||
config.sync(streamConnection)
|
||||
if (clear) {
|
||||
clear()
|
||||
}
|
||||
|
||||
enabled = true
|
||||
streamConnection.open()
|
||||
|
||||
if (message != null && config.announceConnect) {
|
||||
sendStatusUpdate(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun clear() {
|
||||
try {
|
||||
val url = URL(config.url + "/api/messages")
|
||||
val conn = url.openConnection() as HttpURLConnection
|
||||
|
||||
if (!config.token.isEmpty()) {
|
||||
val bearerAuth = "Bearer " + config.token
|
||||
conn.setRequestProperty("Authorization", bearerAuth)
|
||||
}
|
||||
|
||||
conn.requestMethod = "GET"
|
||||
|
||||
BufferedReader(InputStreamReader(conn.inputStream)).forEachLine { line ->
|
||||
logger.trace("skipping $line")
|
||||
}
|
||||
} catch (e: MalformedURLException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: ProtocolException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open fun sendStatusUpdate(message: String) {
|
||||
transmit(ApiMessage(text = message))
|
||||
}
|
||||
|
||||
open fun transmit(msg: ApiMessage) {
|
||||
if (streamConnection.isConnected || streamConnection.isConnecting) {
|
||||
if (msg.username.isEmpty())
|
||||
msg.username = config.systemUser
|
||||
if (msg.gateway.isEmpty()) {
|
||||
logger.fatal("missing gateway on message: $msg")
|
||||
return
|
||||
}
|
||||
logger.debug("Transmitting: $msg")
|
||||
transmitMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transmitMessage(message: ApiMessage) {
|
||||
try {
|
||||
val url = URL(config.url + "/api/message")
|
||||
val conn = url.openConnection() as HttpURLConnection
|
||||
|
||||
if (!config.token.isEmpty()) {
|
||||
val bearerAuth = "Bearer " + config.token
|
||||
conn.setRequestProperty("Authorization", bearerAuth)
|
||||
}
|
||||
|
||||
val postData = message.encode()
|
||||
logger.trace(postData)
|
||||
|
||||
conn.requestMethod = "POST"
|
||||
conn.setRequestProperty("Content-Type", "application/json")
|
||||
conn.setRequestProperty("charset", "utf-8")
|
||||
conn.setRequestProperty("Content-Length", "" + postData.toByteArray().size)
|
||||
conn.doOutput = true
|
||||
conn.doInput = true
|
||||
|
||||
DataOutputStream(conn.outputStream).use { wr -> wr.write(postData.toByteArray()) }
|
||||
|
||||
// conn.getInputStream().close();
|
||||
conn.connect()
|
||||
val code = conn.responseCode
|
||||
if (code != 200) {
|
||||
logger.error("Server returned $code")
|
||||
sendErrors++
|
||||
if (sendErrors > 5) {
|
||||
logger.error("Interrupting Connection to matterbridge API due to status code $code")
|
||||
stop()
|
||||
}
|
||||
} else {
|
||||
sendErrors = 0
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
logger.error("sending message caused $e")
|
||||
sendErrors++
|
||||
if (sendErrors > 5) {
|
||||
logger.error("Caught too many errors, closing bridge")
|
||||
stop()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* clll this method every tick / cycle to make sure it is reconnecting
|
||||
*/
|
||||
fun checkConnection() {
|
||||
if (enabled && !streamConnection.isConnected && !streamConnection.isConnecting) {
|
||||
logger.trace("check connection")
|
||||
logger.trace("next: $nextCheck")
|
||||
logger.trace("now: " + System.currentTimeMillis())
|
||||
if (nextCheck > System.currentTimeMillis()) return
|
||||
nextCheck = System.currentTimeMillis() + config.reconnectWait
|
||||
|
||||
if (connectErrors >= 10) {
|
||||
logger.error("Caught too many errors, closing bridge")
|
||||
stop("Interrupting connection to matterbridge API due to accumulated connection errors")
|
||||
return
|
||||
}
|
||||
|
||||
if (reconnectCooldown <= 0) {
|
||||
logger.info("Trying to reconnect")
|
||||
start("Reconnecting to matterbridge API after connection error", false)
|
||||
} else {
|
||||
reconnectCooldown--
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package matterlink.api
|
||||
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.net.ConnectException
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
import java.util.Arrays
|
||||
import java.util.LinkedList
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
|
||||
/**
|
||||
* Created by nikky on 07/05/18.
|
||||
*
|
||||
* @author Nikky
|
||||
* @version 1.0
|
||||
*/
|
||||
class StreamConnection(private val rcvQueue: ConcurrentLinkedQueue<ApiMessage>) : Runnable {
|
||||
private var thread: Thread = createThread()
|
||||
private var urlConnection: HttpURLConnection? = null
|
||||
private val onSuccessCallbacks = LinkedList<(Boolean) -> Unit>()
|
||||
|
||||
var logger = LogManager.getLogger("matterlink.api")
|
||||
var host = ""
|
||||
var token = ""
|
||||
|
||||
var isConnected = false
|
||||
private set
|
||||
var isConnecting = false
|
||||
private set
|
||||
var isCancelled = false
|
||||
private set
|
||||
|
||||
private fun createThread(): Thread {
|
||||
val thread = Thread(this)
|
||||
thread.name = "RcvThread"
|
||||
return thread
|
||||
}
|
||||
|
||||
fun addOnSuccess(callback: (Boolean) -> Unit) {
|
||||
onSuccessCallbacks.add(callback)
|
||||
}
|
||||
|
||||
fun removeOnSuccess(callback: (Boolean) -> Unit) {
|
||||
onSuccessCallbacks.remove(callback)
|
||||
}
|
||||
|
||||
private fun onSuccess(success: Boolean) {
|
||||
isConnecting = false
|
||||
isConnected = success
|
||||
for (callback in onSuccessCallbacks) {
|
||||
callback(success)
|
||||
}
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
val serviceURL = "$host/api/stream"
|
||||
val myURL: URL
|
||||
|
||||
myURL = URL(serviceURL)
|
||||
urlConnection = myURL.openConnection() as HttpURLConnection
|
||||
urlConnection!!.requestMethod = "GET"
|
||||
if (!token.isEmpty()) {
|
||||
val bearerAuth = "Bearer $token"
|
||||
urlConnection!!.setRequestProperty("Authorization", bearerAuth)
|
||||
}
|
||||
try {
|
||||
urlConnection!!.inputStream.use { input ->
|
||||
logger.info("connection opened")
|
||||
onSuccess(true)
|
||||
// BufferedInputStream bufferedInput = new BufferedInputStream(input, 8 * 1024);
|
||||
val buffer = StringBuilder()
|
||||
while (!isCancelled) {
|
||||
val buf = ByteArray(1024)
|
||||
Thread.sleep(10)
|
||||
while (input.available() <= 0) {
|
||||
if (isCancelled) break
|
||||
Thread.sleep(10)
|
||||
}
|
||||
val chars = input.read(buf)
|
||||
|
||||
logger.trace( String.format("read %d chars", chars))
|
||||
if (chars > 0) {
|
||||
val added = String(Arrays.copyOfRange(buf, 0, chars))
|
||||
logger.debug("DEBUG", "json: $added")
|
||||
buffer.append(added)
|
||||
while (buffer.toString().contains("\n")) {
|
||||
val index = buffer.indexOf("\n")
|
||||
val line = buffer.substring(0, index)
|
||||
buffer.delete(0, index + 1)
|
||||
rcvQueue.add(ApiMessage.decode(line))
|
||||
}
|
||||
} else if (chars < 0) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
onClose()
|
||||
}
|
||||
} catch (e: MalformedURLException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: ConnectException) {
|
||||
e.printStackTrace()
|
||||
onSuccess(false)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
onSuccess(false)
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun onClose() {
|
||||
logger.info("Bridge connection closed!")
|
||||
isConnected = false
|
||||
isConnecting = false
|
||||
}
|
||||
|
||||
fun open() {
|
||||
if (!thread.isAlive) {
|
||||
thread = createThread()
|
||||
isConnecting = true
|
||||
isCancelled = false
|
||||
thread.start()
|
||||
logger.info("Starting Connection")
|
||||
}
|
||||
if (thread.isAlive) {
|
||||
logger.info("Bridge is connecting")
|
||||
}
|
||||
}
|
||||
|
||||
fun close() {
|
||||
try {
|
||||
isCancelled = true
|
||||
if (urlConnection != null) {
|
||||
urlConnection!!.disconnect()
|
||||
}
|
||||
thread.join()
|
||||
logger.info("Thread stopped")
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package matterlink.api
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.stream.JsonReader
|
||||
|
||||
import java.io.*
|
||||
import java.util.Scanner
|
||||
|
||||
/**
|
||||
* Created by nikky on 07/05/18.
|
||||
*
|
||||
* @author Nikky
|
||||
* @version 1.0
|
||||
*/
|
||||
object Main {
|
||||
@Throws(IOException::class)
|
||||
@JvmStatic
|
||||
fun main(vararg args: String) {
|
||||
|
||||
val handler = MessageHandler()
|
||||
val queue = handler.queue
|
||||
val config: Config
|
||||
|
||||
val gson = Gson()
|
||||
try {
|
||||
val reader = JsonReader(FileReader("config.json"))
|
||||
config = gson.fromJson(reader, Config::class.java)
|
||||
handler.config = config
|
||||
} catch (e: FileNotFoundException) {
|
||||
e.printStackTrace()
|
||||
FileWriter("config.json").use { writer -> gson.toJson(handler.config, writer) }
|
||||
}
|
||||
|
||||
// handler.logger = { level, msg -> System.out.printf("[%s] %s%n", level, msg) }
|
||||
handler.start("Connecting..", true)
|
||||
|
||||
Thread {
|
||||
while (true) {
|
||||
val next = queue.poll()
|
||||
if (next != null) {
|
||||
println(next)
|
||||
}
|
||||
try {
|
||||
Thread.sleep(200)
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
}.start()
|
||||
|
||||
Thread {
|
||||
while (true) {
|
||||
handler.checkConnection()
|
||||
try {
|
||||
Thread.sleep(100)
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
}.start()
|
||||
|
||||
val sc = Scanner(System.`in`)
|
||||
while (true) {
|
||||
val input = sc.nextLine()
|
||||
when (input) {
|
||||
"start" -> {
|
||||
handler.start("start", false)
|
||||
}
|
||||
"stop" -> {
|
||||
handler.stop("stop")
|
||||
}
|
||||
else -> {
|
||||
handler.transmit(ApiMessage(text = input))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,8 +36,9 @@ subprojects {
|
|||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
name = "unascribed"
|
||||
name = "elytradev"
|
||||
url = 'http://unascribed.com/maven/releases'
|
||||
url = 'https://repo.elytradev.com'
|
||||
}
|
||||
maven {
|
||||
name = "shadowfacts"
|
||||
|
|
|
@ -19,15 +19,15 @@ dependencies {
|
|||
|
||||
compile project(":Jankson")
|
||||
|
||||
// compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '+'
|
||||
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '+'
|
||||
// compile group: 'commons-logging', name: 'commons-logging', version: '1.1.3'
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '+'
|
||||
compile group: 'com.google.guava', name: 'guava', version: '+'
|
||||
|
||||
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '+'
|
||||
|
||||
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: project.kotlin_version
|
||||
// compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: project.kotlin_version
|
||||
|
||||
compile group: 'com.elytradev.concrete', name:'concrete-common', version: concrete_version
|
||||
compile group: 'com.elytradev.concrete', name:'concrete-rulesengine', version: concrete_version
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
|
@ -37,10 +37,15 @@ compileKotlin {
|
|||
}
|
||||
|
||||
shadowJar {
|
||||
classifier ''
|
||||
classifier = ''
|
||||
|
||||
dependencies {
|
||||
include project(":api")
|
||||
include project(":Jankson")
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-common', version: concrete_version)
|
||||
include dependency(group: 'com.elytradev.concrete', name: 'concrete-rulesengine', version: concrete_version)
|
||||
}
|
||||
|
||||
relocate 'blue.endless', 'matterlink.repack.blue.endless'
|
||||
relocate 'com.elytradev.concrete', 'matterlink.repack.com.elytradev.concrete'
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package matterlink
|
||||
|
||||
import blue.endless.jankson.JsonObject
|
||||
import blue.endless.jankson.impl.SyntaxError
|
||||
import kotlin.math.sqrt
|
||||
|
||||
fun JsonObject.parseDimensions(): List<Int> = getOrPutList("dimensions", emptyList(), "list of dimension ids")
|
||||
fun JsonObject.parseAllDimensions(): Boolean = getOrDefault("allDimensions", false, "ignores dimension list")
|
||||
|
||||
sealed class Area {
|
||||
abstract val type: String
|
||||
abstract val dimensions: List<Int>
|
||||
abstract val allDimensions: Boolean
|
||||
|
||||
abstract fun testInBounds(x: Int, y: Int, z: Int): Boolean
|
||||
|
||||
fun testForDim(dimension: Int?): Boolean {
|
||||
if (allDimensions) return true
|
||||
if(dimension == null) return false
|
||||
return dimensions.contains(dimension)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun parse(jsonObj: JsonObject): Area {
|
||||
val type: String = jsonObj.getOrDefault("type", "INFINITE", "Area type identifier")
|
||||
return when (type.toUpperCase()) {
|
||||
"INFINITE" -> Infinite.parse(jsonObj)
|
||||
"RADIUS" -> Radius.parse(jsonObj)
|
||||
"SPHERE" -> Sphere.parse(jsonObj)
|
||||
"BOX" -> Box.parse(jsonObj)
|
||||
"SQUARE" -> Square.parse(jsonObj)
|
||||
else -> throw SyntaxError("no Area type '$type' found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Infinite(
|
||||
override val dimensions: List<Int> = listOf(),
|
||||
override val allDimensions: Boolean = false
|
||||
) : Area() {
|
||||
override val type = "INFINITE"
|
||||
|
||||
override fun testInBounds(x: Int, y: Int, z: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun parse(jsonObj: JsonObject): Area {
|
||||
return Infinite(
|
||||
dimensions = jsonObj.parseDimensions(),
|
||||
allDimensions = jsonObj.parseAllDimensions()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class Radius(
|
||||
override val dimensions: List<Int> = listOf(),
|
||||
override val allDimensions: Boolean = false,
|
||||
val x: Int,
|
||||
val z: Int,
|
||||
val radius: Int?
|
||||
) : Area() {
|
||||
override val type = "RADIUS"
|
||||
|
||||
override fun testInBounds(x: Int, y: Int, z: Int): Boolean {
|
||||
if (radius == null) return true
|
||||
return sqrt(((this.x - x) * (this.x - x)) + ((this.z - z) * (this.z - z)).toFloat()) < this.radius
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun parse(jsonObj: JsonObject): Area {
|
||||
|
||||
return Radius(
|
||||
dimensions = jsonObj.parseDimensions(),
|
||||
allDimensions = jsonObj.parseAllDimensions(),
|
||||
x = jsonObj.getOrDefault("x", 0),
|
||||
z = jsonObj.getOrDefault("z", 0),
|
||||
radius = jsonObj.getReified("radius")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Sphere (
|
||||
override val dimensions: List<Int> = listOf(),
|
||||
override val allDimensions: Boolean = false,
|
||||
val x: Int,
|
||||
val y: Int,
|
||||
val z: Int,
|
||||
val radius: Int? = null
|
||||
): Area() {
|
||||
override val type = "SPHERE"
|
||||
|
||||
override fun testInBounds(x: Int, y: Int, z: Int): Boolean {
|
||||
if (radius == null) return true
|
||||
return sqrt(((this.x - x) * (this.x - x)) +((this.y - y) * (this.y - y)) + ((this.z - z) * (this.z - z)).toFloat()) < this.radius
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun parse(jsonObj: JsonObject): Area {
|
||||
|
||||
return Sphere(
|
||||
dimensions = jsonObj.parseDimensions(),
|
||||
allDimensions = jsonObj.parseAllDimensions(),
|
||||
x = jsonObj.getOrDefault("x", 0),
|
||||
y = jsonObj.getOrDefault("y", 0),
|
||||
z = jsonObj.getOrDefault("z", 0),
|
||||
radius = jsonObj.getReified("radius")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Box (
|
||||
override val dimensions: List<Int> = listOf(),
|
||||
override val allDimensions: Boolean = false,
|
||||
val x1: Int,
|
||||
val x2: Int,
|
||||
val y1: Int,
|
||||
val y2: Int,
|
||||
val z1: Int,
|
||||
val z2: Int
|
||||
): Area() {
|
||||
override val type = "BOX"
|
||||
|
||||
override fun testInBounds(x: Int, y: Int, z: Int): Boolean {
|
||||
return x in x1..x2 && y in y1..y2 && z in z1..z2
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun parse(jsonObj: JsonObject): Area {
|
||||
|
||||
return Box(
|
||||
dimensions = jsonObj.parseDimensions(),
|
||||
allDimensions = jsonObj.parseAllDimensions(),
|
||||
x1 = jsonObj.getOrDefault("x1", 0),
|
||||
x2 = jsonObj.getOrDefault("x2", 0),
|
||||
y1 = jsonObj.getOrDefault("y1", 0),
|
||||
y2 = jsonObj.getOrDefault("y2", 0),
|
||||
z1 = jsonObj.getOrDefault("z1", 0),
|
||||
z2 = jsonObj.getOrDefault("z2", 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Square (
|
||||
override val dimensions: List<Int> = listOf(),
|
||||
override val allDimensions: Boolean = false,
|
||||
val x1: Int,
|
||||
val x2: Int,
|
||||
val z1: Int,
|
||||
val z2: Int
|
||||
): Area() {
|
||||
override val type = "SQUARE"
|
||||
|
||||
override fun testInBounds(x: Int, y: Int, z: Int): Boolean {
|
||||
return x in x1..x2 && z in z1..z2
|
||||
}
|
||||
companion object {
|
||||
fun parse(jsonObj: JsonObject): Area {
|
||||
|
||||
return Square(
|
||||
dimensions = jsonObj.parseDimensions(),
|
||||
allDimensions = jsonObj.parseAllDimensions(),
|
||||
x1 = jsonObj.getOrDefault("x1", 0),
|
||||
x2 = jsonObj.getOrDefault("x2", 0),
|
||||
z1 = jsonObj.getOrDefault("z1", 0),
|
||||
z2 = jsonObj.getOrDefault("z2", 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
// class FakePlayer (
|
||||
// val x: Int,
|
||||
// val y: Int,
|
||||
// val z: Int,
|
||||
// val name: String
|
||||
// ): Area()
|
||||
}
|
|
@ -4,6 +4,7 @@ import matterlink.bridge.MessageHandlerInst
|
|||
import matterlink.bridge.command.BridgeCommandRegistry
|
||||
import matterlink.bridge.command.IBridgeCommand
|
||||
import matterlink.bridge.command.IMinecraftCommandSender
|
||||
import matterlink.config.BaseConfig
|
||||
import matterlink.config.cfg
|
||||
import matterlink.update.UpdateChecker
|
||||
import org.apache.logging.log4j.Logger
|
||||
|
@ -98,4 +99,6 @@ abstract class IMatterLink {
|
|||
BridgeCommandRegistry.reloadCommands()
|
||||
}
|
||||
|
||||
abstract fun collectPlayers(area: Area): Set<UUID>
|
||||
|
||||
}
|
|
@ -67,8 +67,10 @@ fun randomString(length: Int = 6): String =
|
|||
java.util.UUID.randomUUID().toString().replace("-", "").take(length)
|
||||
|
||||
fun <T : Any> JsonObject.getOrDefault(key: String, default: T, comment: String? = null): T {
|
||||
// logger.info("type: ${default.javaClass.name} key: $key json: >>>${this.getObject(key)?.toJson()}<<< default: $default")
|
||||
return putDefault(key, default, comment)!!
|
||||
logger.trace("type: ${default.javaClass.name} key: $key json: >>>${this.getObject(key)?.toJson()}<<< default: $default")
|
||||
return putDefault(key, default, comment)!!.also {
|
||||
setComment(key, comment)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> Jankson.fromJson(obj: JsonObject): T = this.fromJson(obj, T::class.java)
|
||||
|
@ -84,7 +86,15 @@ inline fun <reified T : Any> Marshaller.registerSerializer(noinline serializer:
|
|||
|
||||
inline fun <reified T : Any> Marshaller.registerSerializer(noinline serializer: (T, Marshaller) -> JsonElement) = this.registerSerializer(T::class.java, serializer)
|
||||
|
||||
inline fun <reified T : Any> JsonObject.getReified(key: String): T? = this.get(T::class.java, key)
|
||||
inline fun <reified T : Any> JsonObject.getReified(key: String, comment: String? = null): T? = this.get(T::class.java, key)
|
||||
?.also { setComment(key, comment) }
|
||||
|
||||
inline fun <reified T : Any> JsonObject.getReifiedOrDelete(key: String, comment: String? = null): T? = this.get(T::class.java, key)
|
||||
?.also { setComment(key, comment) }
|
||||
?: run {
|
||||
this.remove(key)
|
||||
null
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> JsonObject.getList(key: String): List<T>? {
|
||||
return this[key]?.let { array ->
|
||||
|
@ -97,4 +107,34 @@ inline fun <reified T : Any> JsonObject.getList(key: String): List<T>? {
|
|||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> JsonObject.getOrPutList(key: String, default: List<T>, comment: String?): List<T> {
|
||||
return this[key]?.let { array ->
|
||||
when (array) {
|
||||
is JsonArray -> {
|
||||
array.indices.map { i ->
|
||||
array.get(T::class.java, i) ?: throw NullPointerException("cannot parse ${array.get(i)}")
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}.also {
|
||||
setComment(key, comment)
|
||||
} ?: this.putDefault(key, default, comment) ?: default
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> JsonObject.getOrPutMap(key: String, default: Map<String, T>, comment: String?): Map<String, T> {
|
||||
return this[key]?.let { map ->
|
||||
when (map) {
|
||||
is JsonObject -> {
|
||||
map.mapValues { (key, element) ->
|
||||
map.get(T::class.java, key) ?: throw NullPointerException("cannot parse $element")
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}.also {
|
||||
setComment(key, comment)
|
||||
} ?: this.putDefault(key, default, comment) ?: default
|
||||
}
|
|
@ -4,12 +4,24 @@ import matterlink.*
|
|||
import matterlink.api.ApiMessage
|
||||
import matterlink.api.MessageHandler
|
||||
import matterlink.config.cfg
|
||||
import matterlink.handlers.ChatEvent
|
||||
import matterlink.handlers.LocationHandler
|
||||
|
||||
object MessageHandlerInst : MessageHandler() {
|
||||
override fun transmit(msg: ApiMessage) {
|
||||
transmit(msg, cause = "")
|
||||
}
|
||||
|
||||
override fun sendStatusUpdate(message: String) {
|
||||
LocationHandler.sendToLocations(
|
||||
msg = message,
|
||||
x = 0, y = 0, z = 0, dimension = null,
|
||||
systemuser = true,
|
||||
event = ChatEvent.STATUS,
|
||||
cause = "status update message"
|
||||
)
|
||||
}
|
||||
|
||||
fun transmit(msg: ApiMessage, cause: String, maxLines: Int = cfg.outgoing.inlineLimit) {
|
||||
if (msg.username.isEmpty()) {
|
||||
msg.username = cfg.outgoing.systemUser
|
||||
|
@ -18,8 +30,10 @@ object MessageHandlerInst : MessageHandler() {
|
|||
msg.avatar = cfg.outgoing.avatar.systemUserAvatar
|
||||
}
|
||||
}
|
||||
if (msg.gateway.isEmpty())
|
||||
msg.gateway = cfg.connect.gateway
|
||||
if (msg.gateway.isEmpty()) {
|
||||
logger.error("dropped message '$msg' due to missing gateway")
|
||||
return
|
||||
}
|
||||
|
||||
if (msg.text.lines().count() >= maxLines) {
|
||||
try {
|
||||
|
@ -38,6 +52,7 @@ object MessageHandlerInst : MessageHandler() {
|
|||
msg.text = msg.text.substringBefore('\n')
|
||||
.take(25) + "... " + response.link
|
||||
} catch(e: Exception) {
|
||||
logger.error(cause)
|
||||
logger.error(e.stackTraceString)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ object BridgeCommandRegistry {
|
|||
|
||||
val uuid = IdentitiesConfig.getUUID(input.account, input.userid)
|
||||
|
||||
val env = IBridgeCommand.CommandEnvironment.BridgeEnv(input.username, input.userid, input.account, uuid)
|
||||
val env = IBridgeCommand.CommandEnvironment.BridgeEnv(input.username, input.userid, input.account, input.gateway, uuid)
|
||||
return commandMap[cmd[0]]?.let {
|
||||
if (!it.reachedTimeout()) {
|
||||
logger.debug("dropped command ${it.alias}")
|
||||
|
|
|
@ -23,6 +23,7 @@ abstract class IBridgeCommand {
|
|||
val name: String,
|
||||
val userId: String,
|
||||
val platform: String,
|
||||
val gateway: String,
|
||||
override val uuid: UUID?
|
||||
) : CommandEnvironment() {
|
||||
override val username: String?
|
||||
|
@ -39,6 +40,7 @@ abstract class IBridgeCommand {
|
|||
is BridgeEnv -> {
|
||||
MessageHandlerInst.transmit(
|
||||
ApiMessage(
|
||||
gateway = this.gateway,
|
||||
text = text.stripColorOut
|
||||
),
|
||||
cause = cause
|
||||
|
|
|
@ -4,13 +4,12 @@ import blue.endless.jankson.Jankson
|
|||
import blue.endless.jankson.JsonObject
|
||||
import blue.endless.jankson.impl.Marshaller
|
||||
import blue.endless.jankson.impl.SyntaxError
|
||||
import matterlink.*
|
||||
import matterlink.bridge.MessageHandlerInst
|
||||
import matterlink.getOrDefault
|
||||
import matterlink.logger
|
||||
import matterlink.registerTypeAdapter
|
||||
import matterlink.stackTraceString
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.*
|
||||
import kotlin.collections.LinkedHashMap
|
||||
|
||||
lateinit var cfg: BaseConfig.MatterLinkConfig
|
||||
lateinit var baseCfg: BaseConfig
|
||||
|
@ -26,12 +25,82 @@ data class BaseConfig(val rootDir: File) {
|
|||
|
||||
data class MatterLinkConfig(
|
||||
val connect: ConnectOptions = ConnectOptions(),
|
||||
val outgoingDefaults: DefaultSettingsOutgoing = DefaultSettingsOutgoing(),
|
||||
val incomingDefaults: DefaultSettingsIncoming = DefaultSettingsIncoming(),
|
||||
val locations: List<Location> = listOf(
|
||||
Location(
|
||||
label = "default",
|
||||
gateway = "minecraft",
|
||||
area = Area.Infinite(dimensions = listOf(-1, 0, 1), allDimensions = true),
|
||||
outgoing = SettingsOutgoing(
|
||||
plain = true,
|
||||
action = true,
|
||||
join = true,
|
||||
leave = true,
|
||||
advancement = true,
|
||||
death = true,
|
||||
broadcast = true,
|
||||
status = true
|
||||
),
|
||||
incoming = SettingsIncoming(
|
||||
plain = true,
|
||||
action = true,
|
||||
join_leave = true,
|
||||
commands = true
|
||||
)
|
||||
)
|
||||
),
|
||||
val incoming: IncomingOptions = IncomingOptions(),
|
||||
val outgoing: OutgoingOptions = OutgoingOptions(),
|
||||
val command: CommandOptions = CommandOptions(),
|
||||
val update: UpdateOptions = UpdateOptions()
|
||||
)
|
||||
|
||||
data class DefaultSettingsOutgoing(
|
||||
val plain: Boolean = true,
|
||||
val action: Boolean = true,
|
||||
val join: Boolean = false,
|
||||
val leave: Boolean = false,
|
||||
val advancement: Boolean = false,
|
||||
val death: Boolean = false,
|
||||
val broadcast: Boolean = false,
|
||||
val status: Boolean = false
|
||||
)
|
||||
|
||||
data class SettingsOutgoing(
|
||||
val plain: Boolean? = null,
|
||||
val action: Boolean? = null,
|
||||
val join: Boolean? = null,
|
||||
val leave: Boolean? = null,
|
||||
val advancement: Boolean? = null,
|
||||
val death: Boolean? = null,
|
||||
val broadcast: Boolean? = null,
|
||||
val status: Boolean? = null,
|
||||
val skip: List<String> = listOf()
|
||||
)
|
||||
|
||||
data class DefaultSettingsIncoming(
|
||||
val plain: Boolean = true,
|
||||
val action: Boolean = true,
|
||||
val join_leave: Boolean = true,
|
||||
val commands: Boolean = true
|
||||
)
|
||||
|
||||
data class SettingsIncoming(
|
||||
val plain: Boolean? = null,
|
||||
val action: Boolean? = null,
|
||||
val join_leave: Boolean? = null,
|
||||
val commands: Boolean? = null,
|
||||
val skip: List<String> = listOf()
|
||||
)
|
||||
|
||||
data class Location(
|
||||
val label: String = "unlabeled",
|
||||
val gateway: String = "",
|
||||
val area: Area = Area.Infinite(),
|
||||
val outgoing: SettingsOutgoing = SettingsOutgoing(),
|
||||
val incoming: SettingsIncoming = SettingsIncoming()
|
||||
)
|
||||
|
||||
data class CommandOptions(
|
||||
val prefix: Char = '!',
|
||||
|
@ -45,7 +114,6 @@ data class BaseConfig(val rootDir: File) {
|
|||
data class ConnectOptions(
|
||||
val url: String = "http://localhost:4242",
|
||||
val authToken: String = "",
|
||||
val gateway: String = "minecraft",
|
||||
val autoConnect: Boolean = true,
|
||||
val reconnectWait: Long = 500
|
||||
)
|
||||
|
@ -104,7 +172,9 @@ data class BaseConfig(val rootDir: File) {
|
|||
"thrown" to arrayOf("彡°"),
|
||||
"thorns" to arrayOf("\uD83C\uDF39"), //🌹
|
||||
"explosion" to arrayOf("\uD83D\uDCA3", "\uD83D\uDCA5"), //💣 💥
|
||||
"explosion.player" to arrayOf("\uD83D\uDCA3", "\uD83D\uDCA5") //💣 💥
|
||||
"explosion.player" to arrayOf("\uD83D\uDCA3", "\uD83D\uDCA5"), //💣 💥
|
||||
"ieWireShock" to arrayOf("\uD83D\uDD0C", "\u26A1"), //🔌 ⚡
|
||||
"immersiverailroading:hitByTrain" to arrayOf("\uD83D\uDE82", "\uD83D\uDE83", "\uD83D\uDE84", "\uD83D\uDE85", "\uD83D\uDE87", "\uD83D\uDE88", "\uD83D\uDE8A") //🚂 🚃 🚄 🚅 🚇 🚈 🚊
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -117,8 +187,8 @@ data class BaseConfig(val rootDir: File) {
|
|||
|
||||
data class JoinPartOptions(
|
||||
val enable: Boolean = true,
|
||||
val joinServer: String = "{username:antiping} has connected to the platform",
|
||||
val partServer: String = "{username:antiping} has disconnected from the platform"
|
||||
val joinServer: String = "{username:antiping} has connected to the server",
|
||||
val partServer: String = "{username:antiping} has disconnected from the server"
|
||||
)
|
||||
|
||||
data class UpdateOptions(
|
||||
|
@ -129,41 +199,191 @@ data class BaseConfig(val rootDir: File) {
|
|||
val jankson = Jankson
|
||||
.builder()
|
||||
.registerTypeAdapter {
|
||||
MatterLinkConfig(
|
||||
command = it.getOrDefault(
|
||||
"command",
|
||||
CommandOptions(),
|
||||
"User commands"
|
||||
),
|
||||
connect = it.getOrDefault(
|
||||
"connect",
|
||||
ConnectOptions(),
|
||||
"Connection Settings"
|
||||
),
|
||||
incoming = it.getOrDefault(
|
||||
"incoming",
|
||||
IncomingOptions(),
|
||||
"""
|
||||
Gateway -> Server
|
||||
Options all about receiving messages from the API
|
||||
Formatting options:
|
||||
Available variables: {username}, {text}, {gateway}, {channel}, {protocol}, {username:antiping}
|
||||
""".trimIndent()
|
||||
),
|
||||
outgoing = it.getOrDefault(
|
||||
"outgoing",
|
||||
OutgoingOptions(),
|
||||
"""
|
||||
Server -> Gateway
|
||||
Options all about sending messages to the API
|
||||
""".trimIndent()
|
||||
),
|
||||
update = it.getOrDefault(
|
||||
"update",
|
||||
UpdateOptions(),
|
||||
"Update Settings"
|
||||
)
|
||||
)
|
||||
with(MatterLinkConfig()) {
|
||||
MatterLinkConfig(
|
||||
command = it.getOrDefault(
|
||||
"command",
|
||||
command,
|
||||
"User commands"
|
||||
),
|
||||
outgoingDefaults = it.getOrDefault(
|
||||
"outgoingDefaults",
|
||||
outgoingDefaults,
|
||||
"default settings for outgoing"
|
||||
),
|
||||
incomingDefaults = it.getOrDefault(
|
||||
"incomingDefaults",
|
||||
incomingDefaults,
|
||||
"default settings for incoming"
|
||||
),
|
||||
locations = it.getOrPutList(
|
||||
"locations",
|
||||
locations,
|
||||
"list of fixed chat locations"
|
||||
),
|
||||
connect = it.getOrDefault(
|
||||
"connect",
|
||||
connect,
|
||||
"Connection Settings"
|
||||
),
|
||||
incoming = it.getOrDefault(
|
||||
"incoming",
|
||||
incoming,
|
||||
"""
|
||||
Gateway -> Server
|
||||
Options all about receiving messages from the API
|
||||
Formatting options:
|
||||
Available variables: {username}, {text}, {gateway}, {channel}, {protocol}, {username:antiping}
|
||||
""".trimIndent()
|
||||
),
|
||||
outgoing = it.getOrDefault(
|
||||
"outgoing",
|
||||
outgoing,
|
||||
"""
|
||||
Server -> Gateway
|
||||
Options all about sending messages to the API
|
||||
""".trimIndent()
|
||||
),
|
||||
update = it.getOrDefault(
|
||||
"update",
|
||||
update,
|
||||
"Update Settings"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.registerTypeAdapter {
|
||||
with(DefaultSettingsOutgoing()) {
|
||||
DefaultSettingsOutgoing(
|
||||
plain = it.getOrDefault(
|
||||
"plain",
|
||||
plain,
|
||||
"plain text messages"
|
||||
),
|
||||
action = it.getOrDefault(
|
||||
"action",
|
||||
action,
|
||||
"action messages"
|
||||
),
|
||||
join = it.getOrDefault(
|
||||
"join",
|
||||
join,
|
||||
"handle join event"
|
||||
),
|
||||
leave = it.getOrDefault(
|
||||
"leave",
|
||||
leave,
|
||||
"handle leave events"
|
||||
),
|
||||
advancement = it.getOrDefault(
|
||||
"advancement",
|
||||
advancement,
|
||||
"handle advancement events"
|
||||
),
|
||||
death = it.getOrDefault(
|
||||
"death",
|
||||
death,
|
||||
"handle death events"
|
||||
),
|
||||
broadcast = it.getOrDefault(
|
||||
"broadcast",
|
||||
broadcast,
|
||||
"handle broadcast command"
|
||||
),
|
||||
status = it.getOrDefault(
|
||||
"status",
|
||||
status,
|
||||
"handles tatus updates"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.registerTypeAdapter {
|
||||
with(SettingsOutgoing()) {
|
||||
SettingsOutgoing(
|
||||
plain = it.getReifiedOrDelete("plain", "transmit join events"),
|
||||
action = it.getReifiedOrDelete("action", "transmit join events"),
|
||||
join = it.getReifiedOrDelete("join", "transmit join events"),
|
||||
leave = it.getReifiedOrDelete("leave", "transmit leave events"),
|
||||
advancement = it.getReifiedOrDelete("advancement", "transmit advancements"),
|
||||
death = it.getReifiedOrDelete("death", "transmit death messages"),
|
||||
broadcast = it.getReifiedOrDelete("say", "transmit broadcasts"),
|
||||
status = it.getReifiedOrDelete("status", "transmit status updates"),
|
||||
skip = it.getOrPutList(
|
||||
"skip",
|
||||
skip,
|
||||
"list of other locations to ignore after handling this"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
.registerTypeAdapter {
|
||||
with(DefaultSettingsIncoming()) {
|
||||
DefaultSettingsIncoming(
|
||||
plain = it.getOrDefault(
|
||||
"plain",
|
||||
plain,
|
||||
"plain text messages"
|
||||
),
|
||||
action = it.getOrDefault(
|
||||
"action",
|
||||
action,
|
||||
"action messages"
|
||||
),
|
||||
join_leave = it.getOrDefault(
|
||||
"join_leave",
|
||||
join_leave,
|
||||
"handle join/leave event"
|
||||
),
|
||||
commands = it.getOrDefault(
|
||||
"commands",
|
||||
join_leave,
|
||||
"receive commands"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.registerTypeAdapter {
|
||||
with(SettingsIncoming()) {
|
||||
SettingsIncoming(
|
||||
plain = it.getReifiedOrDelete("plain", "transmit join events"),
|
||||
action = it.getReifiedOrDelete("action", "transmit join events"),
|
||||
join_leave = it.getReifiedOrDelete("join_leave", "transmit join_leave events"),
|
||||
commands = it.getReifiedOrDelete("commands", "receive commands"),
|
||||
skip = it.getOrPutList(
|
||||
"skip",
|
||||
skip,
|
||||
"list of other locations to ignore after handling this"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.registerTypeAdapter {
|
||||
with(Location()) {
|
||||
Location(
|
||||
label = it.getOrDefault("label",
|
||||
label,
|
||||
"location label for identification"
|
||||
),
|
||||
gateway = it.getOrDefault(
|
||||
"gateway",
|
||||
gateway,
|
||||
"matterbridge gateway identifier"
|
||||
),
|
||||
area = Area.parse(it.getObject("area") ?: JsonObject()),
|
||||
outgoing = it.getOrDefault(
|
||||
"outgoing",
|
||||
outgoing,
|
||||
"Location outgoing settings"
|
||||
),
|
||||
incoming = it.getOrDefault(
|
||||
"incoming",
|
||||
incoming,
|
||||
"incoming settings"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
.registerTypeAdapter {
|
||||
with(CommandOptions()) {
|
||||
|
@ -214,15 +434,15 @@ data class BaseConfig(val rootDir: File) {
|
|||
authToken,
|
||||
"Auth token used to connect to the bridge platform"
|
||||
),
|
||||
gateway = it.getOrDefault(
|
||||
"gateway",
|
||||
gateway,
|
||||
"MatterBridge gateway"
|
||||
),
|
||||
autoConnect = it.getOrDefault(
|
||||
"autoConnect",
|
||||
autoConnect,
|
||||
"Connect the relay on startup"
|
||||
),
|
||||
reconnectWait = it.getOrDefault(
|
||||
"reconnectWait",
|
||||
reconnectWait,
|
||||
"base delay in milliseconds between attempting reconnects"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -389,6 +609,25 @@ data class BaseConfig(val rootDir: File) {
|
|||
)
|
||||
}
|
||||
}
|
||||
.registerSerializer { locationSettings: SettingsOutgoing, marshaller: Marshaller ->
|
||||
val jsonObject = JsonObject()
|
||||
locationSettings.advancement?.let {
|
||||
jsonObject["advancements"] = marshaller.serialize(it)
|
||||
}
|
||||
locationSettings.death?.let {
|
||||
jsonObject["death"] = marshaller.serialize(it)
|
||||
}
|
||||
locationSettings.join?.let {
|
||||
jsonObject["joins"] = marshaller.serialize(it)
|
||||
}
|
||||
locationSettings.leave?.let {
|
||||
jsonObject["leaves"] = marshaller.serialize(it)
|
||||
}
|
||||
locationSettings.broadcast?.let {
|
||||
jsonObject["say"] = marshaller.serialize(it)
|
||||
}
|
||||
jsonObject
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -417,15 +656,15 @@ data class BaseConfig(val rootDir: File) {
|
|||
logger.error("error parsing config: ${e.completeMessage} ")
|
||||
logger.error(e.stackTraceString)
|
||||
cfgDirectory.resolve("error.matterlink.hjson").writeText(jsonObject.toJson(false, true))
|
||||
MatterLinkConfig()
|
||||
if (::cfg.isInitialized) cfg else MatterLinkConfig()
|
||||
} catch (e: IllegalStateException) {
|
||||
logger.error(e.stackTraceString)
|
||||
cfgDirectory.resolve("error.matterlink.hjson").writeText(jsonObject.toJson(false, true))
|
||||
MatterLinkConfig()
|
||||
if (::cfg.isInitialized) cfg else MatterLinkConfig()
|
||||
} catch (e: NullPointerException) {
|
||||
logger.error("error loading config: ${e.stackTraceString}")
|
||||
cfgDirectory.resolve("error.matterlink.hjson").writeText(jsonObject.toJson(false, true))
|
||||
MatterLinkConfig()
|
||||
if (::cfg.isInitialized) cfg else MatterLinkConfig()
|
||||
}
|
||||
|
||||
// val defaultJsonObject = jankson.load("{}")
|
||||
|
@ -434,7 +673,6 @@ data class BaseConfig(val rootDir: File) {
|
|||
|
||||
MessageHandlerInst.config.url = tmpCfg.connect.url
|
||||
MessageHandlerInst.config.token = tmpCfg.connect.authToken
|
||||
MessageHandlerInst.config.gateway = tmpCfg.connect.gateway
|
||||
MessageHandlerInst.config.reconnectWait = tmpCfg.connect.reconnectWait
|
||||
|
||||
MessageHandlerInst.config.systemUser = tmpCfg.outgoing.systemUser
|
||||
|
|
|
@ -4,7 +4,6 @@ import matterlink.api.ApiMessage
|
|||
import matterlink.bridge.MessageHandlerInst
|
||||
import matterlink.bridge.command.BridgeCommandRegistry
|
||||
import matterlink.config.cfg
|
||||
import matterlink.instance
|
||||
import matterlink.logger
|
||||
import matterlink.stripColorOut
|
||||
import java.util.*
|
||||
|
@ -13,23 +12,21 @@ object ChatProcessor {
|
|||
/**
|
||||
* @return cancel message flag
|
||||
*/
|
||||
fun sendToBridge(user: String, msg: String, event: String, uuid: UUID? = null): Boolean {
|
||||
fun sendToBridge(user: String, msg: String, x: Int, y: Int, z: Int, dimension: Int?, event: ChatEvent, uuid: UUID? = null): Boolean {
|
||||
//TODO: pass message to Locations
|
||||
logger.info("position: $x $y $z dimension: $dimension")
|
||||
val message = msg.trim()
|
||||
if(uuid != null && BridgeCommandRegistry.handleCommand(message, user, uuid)) return true
|
||||
if (uuid != null && BridgeCommandRegistry.handleCommand(message, user, uuid)) return true
|
||||
when {
|
||||
message.isNotBlank() -> MessageHandlerInst.transmit(
|
||||
ApiMessage(
|
||||
username = user.stripColorOut,
|
||||
text = message.stripColorOut,
|
||||
event = event
|
||||
).apply {
|
||||
if(cfg.outgoing.avatar.enable) {
|
||||
if(uuid != null)
|
||||
avatar = cfg.outgoing.avatar.urlTemplate.replace("{uuid}", uuid.toString())
|
||||
}
|
||||
},
|
||||
message.isNotBlank() -> LocationHandler.sendToLocations(
|
||||
user = user,
|
||||
msg = message,
|
||||
x = x, y = y, z = z, dimension = dimension,
|
||||
event = event,
|
||||
cause = "Message from $user"
|
||||
)
|
||||
|
||||
|
||||
else -> logger.warn("WARN: dropped blank message by '$user'")
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -13,7 +13,9 @@ object DeathHandler {
|
|||
fun handleDeath(
|
||||
player: String,
|
||||
deathMessage: String,
|
||||
damageType: String
|
||||
damageType: String,
|
||||
x: Int, y: Int, z: Int,
|
||||
dimension: Int
|
||||
) {
|
||||
if (cfg.outgoing.death.enable) {
|
||||
var msg = deathMessage.stripColorOut.replace(player, player.stripColorOut.antiping)
|
||||
|
@ -23,7 +25,13 @@ object DeathHandler {
|
|||
val damageEmoji = emojis[random.nextInt(emojis.size)]
|
||||
msg += " $damageEmoji"
|
||||
}
|
||||
MessageHandlerInst.transmit(ApiMessage(text = msg), cause = "Death Event of $player")
|
||||
LocationHandler.sendToLocations(
|
||||
msg = msg,
|
||||
x = x, y = y, z = z, dimension = dimension,
|
||||
event = ChatEvent.DEATH,
|
||||
cause = "Death Event of $player",
|
||||
systemuser = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ import matterlink.mapFormat
|
|||
import matterlink.stripColorOut
|
||||
|
||||
object JoinLeaveHandler {
|
||||
fun handleJoin(player: String) {
|
||||
fun handleJoin(player: String,
|
||||
x: Int, y: Int, z: Int,
|
||||
dimension: Int) {
|
||||
if (cfg.outgoing.joinPart.enable) {
|
||||
val msg = cfg.outgoing.joinPart.joinServer.mapFormat(
|
||||
mapOf(
|
||||
|
@ -17,17 +19,19 @@ object JoinLeaveHandler {
|
|||
"{username:antiping}" to player.stripColorOut.antiping
|
||||
)
|
||||
)
|
||||
MessageHandlerInst.transmit(
|
||||
ApiMessage(
|
||||
text = msg,
|
||||
event = JOIN_LEAVE
|
||||
),
|
||||
LocationHandler.sendToLocations(
|
||||
msg = msg,
|
||||
x = x, y = y, z = z, dimension = dimension,
|
||||
event = ChatEvent.JOIN,
|
||||
systemuser = true,
|
||||
cause = "$player joined"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun handleLeave(player: String) {
|
||||
fun handleLeave(player: String,
|
||||
x: Int, y: Int, z: Int,
|
||||
dimension: Int) {
|
||||
if (cfg.outgoing.joinPart.enable) {
|
||||
val msg = cfg.outgoing.joinPart.partServer.mapFormat(
|
||||
mapOf(
|
||||
|
@ -35,11 +39,11 @@ object JoinLeaveHandler {
|
|||
"{username:antiping}" to player.stripColorOut.antiping
|
||||
)
|
||||
)
|
||||
MessageHandlerInst.transmit(
|
||||
ApiMessage(
|
||||
text = msg,
|
||||
event = JOIN_LEAVE
|
||||
),
|
||||
LocationHandler.sendToLocations(
|
||||
msg = msg,
|
||||
x = x, y = y, z = z, dimension = dimension,
|
||||
event = ChatEvent.JOIN,
|
||||
systemuser = true,
|
||||
cause = "$player left"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
package matterlink.handlers
|
||||
|
||||
import matterlink.api.ApiMessage
|
||||
import matterlink.bridge.MessageHandlerInst
|
||||
import matterlink.config.cfg
|
||||
import matterlink.logger
|
||||
import matterlink.stripColorOut
|
||||
import java.util.*
|
||||
|
||||
|
||||
enum class ChatEvent {
|
||||
PLAIN, ACTION, DEATH, JOIN, LEAVE, ADVANCEMENT, BROADCAST, STATUS
|
||||
}
|
||||
|
||||
object LocationHandler {
|
||||
|
||||
fun sendToLocations(
|
||||
user: String = cfg.outgoing.systemUser,
|
||||
msg: String,
|
||||
x: Int, y: Int, z: Int,
|
||||
dimension: Int?,
|
||||
event: ChatEvent,
|
||||
systemuser: Boolean = false,
|
||||
uuid: UUID? = null,
|
||||
cause: String
|
||||
): Boolean {
|
||||
val defaults = cfg.outgoingDefaults
|
||||
var handled = false
|
||||
val skips = mutableSetOf<String>()
|
||||
logger.info("locations: ${cfg.locations.map { it.label }}")
|
||||
for (location in cfg.locations) {
|
||||
val label = location.label
|
||||
if(skips.contains(label)) {
|
||||
logger.info("skipping $label (contained in in $skips)")
|
||||
continue
|
||||
}
|
||||
if(!location.area.testForDim(dimension)) {
|
||||
logger.info("location: $label dropped message '$msg' from $user due to mismatched dimension")
|
||||
continue
|
||||
}
|
||||
if(!location.area.testInBounds(x, y, z)) {
|
||||
logger.info("location: $label dropped message '$msg' from $user out of coordinate bounds")
|
||||
continue
|
||||
}
|
||||
val matchesEvent = when (event) {
|
||||
ChatEvent.PLAIN -> location.outgoing.plain ?: defaults.plain
|
||||
ChatEvent.ACTION -> location.outgoing.action ?: defaults.action
|
||||
ChatEvent.DEATH -> location.outgoing.death ?: defaults.death
|
||||
ChatEvent.JOIN -> location.outgoing.join ?: defaults.join
|
||||
ChatEvent.LEAVE -> location.outgoing.leave ?: defaults.leave
|
||||
ChatEvent.ADVANCEMENT -> location.outgoing.advancement ?: defaults.advancement
|
||||
ChatEvent.BROADCAST -> location.outgoing.broadcast ?: defaults.broadcast
|
||||
ChatEvent.STATUS -> location.outgoing.status ?: defaults.status
|
||||
}
|
||||
|
||||
if (!matchesEvent) {
|
||||
logger.info("location: $label dropped message '$msg' from user: '$user', event not enabled")
|
||||
continue
|
||||
}
|
||||
|
||||
skips.addAll(location.outgoing.skip)
|
||||
|
||||
val eventStr = when (event) {
|
||||
ChatEvent.PLAIN -> ""
|
||||
ChatEvent.ACTION -> ApiMessage.USER_ACTION
|
||||
ChatEvent.DEATH -> ""
|
||||
ChatEvent.JOIN -> ApiMessage.JOIN_LEAVE
|
||||
ChatEvent.LEAVE -> ApiMessage.JOIN_LEAVE
|
||||
ChatEvent.ADVANCEMENT -> ""
|
||||
ChatEvent.BROADCAST -> ""
|
||||
ChatEvent.STATUS -> ""
|
||||
}
|
||||
|
||||
val username = when {
|
||||
systemuser -> cfg.outgoing.systemUser
|
||||
else -> user
|
||||
}
|
||||
val avatar = when {
|
||||
systemuser ->
|
||||
cfg.outgoing.avatar.systemUserAvatar
|
||||
cfg.outgoing.avatar.enable && uuid != null ->
|
||||
cfg.outgoing.avatar.urlTemplate.replace("{uuid}", uuid.toString())
|
||||
else ->
|
||||
null
|
||||
}
|
||||
when {
|
||||
msg.isNotBlank() -> MessageHandlerInst.transmit(
|
||||
ApiMessage(
|
||||
username = username.stripColorOut,
|
||||
text = msg.stripColorOut,
|
||||
event = eventStr,
|
||||
gateway = location.gateway
|
||||
).apply {
|
||||
avatar?.let {
|
||||
this.avatar = it
|
||||
}
|
||||
},
|
||||
cause = cause
|
||||
)
|
||||
else -> logger.warn("WARN: dropped blank message by '$user'")
|
||||
}
|
||||
logger.info("sent message through location: $label, cause: $cause")
|
||||
handled = true
|
||||
}
|
||||
return handled
|
||||
}
|
||||
}
|
|
@ -8,14 +8,17 @@ import matterlink.stripColorOut
|
|||
|
||||
object ProgressHandler {
|
||||
|
||||
fun handleProgress(name: String, message: String, display: String) {
|
||||
fun handleProgress(name: String, message: String, display: String,
|
||||
x: Int, y: Int, z: Int,
|
||||
dimension: Int) {
|
||||
if (!cfg.outgoing.advancements) return
|
||||
val usr = name.stripColorOut.antiping
|
||||
MessageHandlerInst.transmit(
|
||||
ApiMessage(
|
||||
text = "$usr $message $display".stripColorOut
|
||||
),
|
||||
cause = "Progress Event by $usr"
|
||||
LocationHandler.sendToLocations(
|
||||
msg = "$usr $message $display".stripColorOut,
|
||||
x = x, y = y, z = z, dimension = dimension,
|
||||
event = ChatEvent.ADVANCEMENT,
|
||||
cause = "Progress Event by $usr",
|
||||
systemuser = true
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
package matterlink.handlers
|
||||
|
||||
import matterlink.api.ApiMessage
|
||||
import matterlink.bridge.MessageHandlerInst
|
||||
import matterlink.bridge.command.BridgeCommandRegistry
|
||||
import matterlink.bridge.format
|
||||
import matterlink.config.cfg
|
||||
import matterlink.instance
|
||||
import matterlink.logger
|
||||
import matterlink.stripColorIn
|
||||
import java.util.*
|
||||
|
||||
object ServerChatHandler {
|
||||
|
||||
|
@ -16,33 +17,116 @@ object ServerChatHandler {
|
|||
fun writeIncomingToChat() {
|
||||
if (MessageHandlerInst.queue.isNotEmpty())
|
||||
logger.debug("incoming: " + MessageHandlerInst.queue.toString())
|
||||
val nextMessage = MessageHandlerInst.queue.poll() ?: null
|
||||
val nextMessage = MessageHandlerInst.queue.poll() ?: return
|
||||
|
||||
if (nextMessage?.gateway == cfg.connect.gateway) {
|
||||
if (!nextMessage.text.isBlank()) {
|
||||
nextMessage.text = nextMessage.text.stripColorIn
|
||||
val message = when (nextMessage.event) {
|
||||
"user_action" -> nextMessage.format(cfg.incoming.action)
|
||||
"" -> {
|
||||
// try to handle command and do not handle as a chat message
|
||||
if (BridgeCommandRegistry.handleCommand(nextMessage)) return
|
||||
nextMessage.format(cfg.incoming.chat)
|
||||
}
|
||||
"join_leave" -> nextMessage.format(cfg.incoming.joinPart)
|
||||
else -> {
|
||||
val user = nextMessage.username
|
||||
val text = nextMessage.text
|
||||
val json = nextMessage.encode()
|
||||
logger.debug("Threw out message with unhandled event: ${nextMessage.event}")
|
||||
logger.debug(" Message contents:")
|
||||
logger.debug(" User: $user")
|
||||
logger.debug(" Text: $text")
|
||||
logger.debug(" JSON: $json")
|
||||
return
|
||||
}
|
||||
}
|
||||
instance.wrappedSendToPlayers(message)
|
||||
val defaults = cfg.incomingDefaults
|
||||
|
||||
val sourceGateway = nextMessage.gateway
|
||||
|
||||
// find all areas to send to
|
||||
|
||||
val targetUUIDs = mutableSetOf<UUID>()
|
||||
val skips = mutableSetOf<String>()
|
||||
|
||||
val locations = cfg.locations.filter {
|
||||
it.gateway == sourceGateway
|
||||
}
|
||||
|
||||
if(nextMessage.event.isEmpty()) {
|
||||
// filter command handlers
|
||||
val commandLocations = locations.filter {
|
||||
it.incoming.commands ?: cfg.incomingDefaults.commands
|
||||
}
|
||||
|
||||
// process potential command
|
||||
for (( label, location) in commandLocations) {
|
||||
if (BridgeCommandRegistry.handleCommand(nextMessage)) return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (location in locations) {
|
||||
val label = location.label
|
||||
if(skips.contains(label)) {
|
||||
logger.debug("skipping $label")
|
||||
continue
|
||||
}
|
||||
val matchesEvent = when (nextMessage.event) {
|
||||
"" -> {
|
||||
// if (location.incoming.commands ?: defaults.commands
|
||||
// && BridgeCommandRegistry.handleCommand(nextMessage)) return
|
||||
location.incoming.plain ?: defaults.plain
|
||||
}
|
||||
ApiMessage.JOIN_LEAVE -> location.incoming.join_leave ?: defaults.join_leave
|
||||
ApiMessage.USER_ACTION -> location.incoming.action ?: defaults.action
|
||||
else -> {
|
||||
logger.fatal("unknwon event type '${nextMessage.event}' on incoming message")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!matchesEvent) {
|
||||
logger.info("location: $label dropped message '$nextMessage' event not enabled")
|
||||
continue
|
||||
}
|
||||
|
||||
targetUUIDs.addAll(instance.collectPlayers(location.area))
|
||||
}
|
||||
|
||||
val message = when (nextMessage.event) {
|
||||
"user_action" -> nextMessage.format(cfg.incoming.action)
|
||||
"" -> {
|
||||
// try to handle command and do not handle as a chat message
|
||||
if (BridgeCommandRegistry.handleCommand(nextMessage)) return
|
||||
nextMessage.format(cfg.incoming.chat)
|
||||
}
|
||||
"join_leave" -> nextMessage.format(cfg.incoming.joinPart)
|
||||
else -> {
|
||||
val user = nextMessage.username
|
||||
val text = nextMessage.text
|
||||
val json = nextMessage.encode()
|
||||
logger.debug("Threw out message with unhandled event: ${nextMessage.event}")
|
||||
logger.debug(" Message contents:")
|
||||
logger.debug(" User: $user")
|
||||
logger.debug(" Text: $text")
|
||||
logger.debug(" JSON: $json")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
targetUUIDs.forEach {
|
||||
//TODO: optimize send to all at once
|
||||
instance.wrappedSendToPlayer(it, message)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if (nextMessage?.gateway == cfg.connect.gateway) {
|
||||
// if (!nextMessage.text.isBlank()) {
|
||||
// nextMessage.text = nextMessage.text.stripColorIn
|
||||
// val message = when (nextMessage.event) {
|
||||
// "user_action" -> nextMessage.format(cfg.incoming.action)
|
||||
// "" -> {
|
||||
// // try to handle command and do not handle as a chat message
|
||||
// if (BridgeCommandRegistry.handleCommand(nextMessage)) return
|
||||
// nextMessage.format(cfg.incoming.chat)
|
||||
// }
|
||||
// "join_leave" -> nextMessage.format(cfg.incoming.joinPart)
|
||||
// else -> {
|
||||
// val user = nextMessage.username
|
||||
// val text = nextMessage.text
|
||||
// val json = nextMessage.encode()
|
||||
// logger.debug("Threw out message with unhandled event: ${nextMessage.event}")
|
||||
// logger.debug(" Message contents:")
|
||||
// logger.debug(" User: $user")
|
||||
// logger.debug(" Text: $text")
|
||||
// logger.debug(" JSON: $json")
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// instance.wrappedSendToPlayers(message)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package matterlink.jenkins
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
/**
|
||||
* Created by nikky on 03/02/18.
|
||||
* @author Nikky
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package voodoo.util.jenkins
|
||||
package matterlink.jenkins
|
||||
|
||||
|
||||
import com.google.gson.Gson
|
||||
|
@ -6,7 +6,6 @@ import matterlink.Result
|
|||
import matterlink.header
|
||||
import matterlink.httpGet
|
||||
import matterlink.responseString
|
||||
import matterlink.jenkins.Job
|
||||
import matterlink.logger
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package matterlink.jenkins;
|
||||
package matterlink.jenkins
|
||||
|
||||
/**
|
||||
* Created by nikky on 03/02/18.
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package matterlink.update
|
||||
|
||||
import com.google.gson.FieldNamingPolicy
|
||||
import com.google.gson.GsonBuilder
|
||||
import matterlink.api.ApiMessage
|
||||
import matterlink.bridge.MessageHandlerInst
|
||||
import matterlink.config.cfg
|
||||
import matterlink.instance
|
||||
import matterlink.logger
|
||||
import voodoo.util.jenkins.JenkinsServer
|
||||
import matterlink.jenkins.JenkinsServer
|
||||
import java.io.BufferedReader
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
mod_name = MatterLink
|
||||
mod_version = 1.6.3
|
||||
forgelin_version = 1.6.0
|
||||
concrete_version = 0.3.8-SNAPSHOT
|
||||
kotlin_version = 1.2.41
|
||||
shadow_version = 2.0.2
|
||||
cursegradle_version = 1.0.10
|
||||
|
|
Loading…
Reference in New Issue