From 555478599c4721f1b300e3a8d75d633fd7f6e235 Mon Sep 17 00:00:00 2001 From: kraftwerk28 Date: Sat, 26 Jun 2021 17:52:25 +0300 Subject: [PATCH] Rewrite build.gradle to kotlin DSL Remove bot username from config Fix lateinit property not initialized in `Plugin::onDisable()` --- .idea/.gitignore | 2 - .idea/artifacts/rzcraft_bridge_jar.xml | 69 ------------ .idea/caches/build_file_checksums.ser | Bin 454 -> 0 bytes .idea/codeStyles/Project.xml | 11 -- .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/compiler.xml | 6 -- .idea/gradle.xml | 21 ---- .idea/jarRepositories.xml | 40 ------- .idea/misc.xml | 18 ---- .idea/spigot-tg-bridge.iml | 2 - .idea/vcs.xml | 6 -- README.md | 5 +- build.gradle | 67 ------------ build.gradle.kts | 74 +++++++++++++ gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 53 +++++---- gradlew.bat | 43 ++++---- .../spigot_tg_bridge/BotCommands.kt | 2 +- .../spigot_tg_bridge/Configuration.kt | 16 +-- .../spigot_tg_bridge/EventHandler.kt | 27 ++--- .../kraftwerk28/spigot_tg_bridge/Plugin.kt | 46 ++++---- .../org/kraftwerk28/spigot_tg_bridge/TgBot.kt | 102 ++++++++---------- .../org/kraftwerk28/spigot_tg_bridge/Utils.kt | 35 ++++++ src/main/resources/config.yml | 1 - src/main/resources/plugin.yml | 2 +- 25 files changed, 256 insertions(+), 402 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/artifacts/rzcraft_bridge_jar.xml delete mode 100644 .idea/caches/build_file_checksums.ser delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/spigot-tg-bridge.iml delete mode 100644 .idea/vcs.xml delete mode 100644 build.gradle create mode 100644 build.gradle.kts create mode 100644 src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Utils.kt diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 5c98b42..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml \ No newline at end of file diff --git a/.idea/artifacts/rzcraft_bridge_jar.xml b/.idea/artifacts/rzcraft_bridge_jar.xml deleted file mode 100644 index a777726..0000000 --- a/.idea/artifacts/rzcraft_bridge_jar.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - $USER_HOME$/MinecraftServers/spigot_1.15.2/plugins/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser deleted file mode 100644 index 781ac28f6205013dd03320fdfbc3122e8a58bf8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 454 zcmZ4UmVvdnh`~NNKUXg?FQq6yGexf?KR>5fFEb@IQ7^qHF(oHeub?PDD>b=9F91S2 zm1gFoxMk*~I%lLNXBU^|7Q2L-Ts|(GuF1r}uGBYr_F>vMNC#JY1CYR(Fc`|U8WE7u2QWrs`)GC8m{>rxs-!S?EKJ&_{$%L26M+W@>S1AwwMl8_1k1vOPEZ88)%JY~Y;n z=7&>V34=gResW?CC@?V;-<{TS;XpyMYR$>6Ta8~O)|4;^;xT&lCFAr1_B$@jy`*-O JOCfMu1pp&To~i%< diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 56a1b18..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index ac216bc..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 28a465f..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index a724c00..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 9fd3e9a..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/spigot-tg-bridge.iml b/.idea/spigot-tg-bridge.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/.idea/spigot-tg-bridge.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 1cf6a49..cc3c1a0 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,9 @@ - Copy [config.yml](https://raw.githubusercontent.com/kraftwerk28/spigot-tg-bridge/master/src/main/resources/config.yml) to `plugins/SpigotTGBridge/` in your server directory. 4. A `config.yml` is just a [valid YAML](https://en.wikipedia.org/wiki/YAML) file, alternative for JSON, but more human-readable. - Now, take bot's __username__ and __token__ which you got in 2nd step and paste them into `config.yml`, so it looks like this: + Now, take bot's __token__ which you got in 2nd step and paste them into `config.yml`, so it looks like this: ```yaml botToken: abcdefghijklmnopq123123123 - botUsername: my_awesome_spigot_bot # other configuration values... ``` @@ -25,7 +24,6 @@ 6. Add you bot to chats, where you plan to use it. In each of them, run `/chat_id` command. The bot should respond and give special value - __chat id__. Now, open `config.yml` and paste this ID under `chats` section, so it will look like this: ```yaml botToken: abcdefghijklmnopq123123123 - botUsername: my_awesome_spigot_bot chats: # Note about doubling minus sign. This is not a mistake, first one means list element, the second one - actual minus - -123456789 @@ -47,7 +45,6 @@ P. S. You can always update plugin configuration without restarting the server. |:-----:|:------------|:----:|:--------:|:-------:| | enable | If plugin should be enabled | `boolean` | :x: | `true` | | botToken | Telegram bot token ([How to create bot](https://core.telegram.org/bots#3-how-do-i-create-a-bot)) | `string` | :heavy_check_mark: | - | -| botUsername | Telegram bot username | `string` | :heavy_check_mark: | - | | chats | Chats, where bot will work (to prevent using bot by unknown chats) | `number[] or string[]` | :heavy_check_mark: | `[]` | | serverStartMessage | What will be sent to chats when server starts | `string` | :x: | `'Server started.'` | | serverStopMessage | What will be sent to chats when server stops | `string` | :x: | `'Server stopped.'` | diff --git a/build.gradle b/build.gradle deleted file mode 100644 index cde8754..0000000 --- a/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -import org.yaml.snakeyaml.Yaml - -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath group: 'org.yaml', name: 'snakeyaml', version: '1.26' - } -} - -plugins { - id 'java' - id 'org.jetbrains.kotlin.jvm' version '1.3.60' - id 'com.github.johnrengelman.shadow' version '5.2.0' -} - -group 'org.kraftwerk28' -def pluginConfigFile = new File("src/main/resources/plugin.yml").newInputStream() -def cfg = (Map)new Yaml().load(pluginConfigFile) -version cfg.get("version") - -repositories { - maven { - url "https://hub.spigotmc.org/nexus/content/repositories/snapshots" - } - maven { - url "https://jitpack.io" - } - maven { - url "https://oss.sonatype.org/content/repositories/snapshots/" - } - mavenCentral() - jcenter() -} - -def plugDir = "MinecraftServers/spigot_1.15.2/plugins/" -def homeDir = System.properties['user.home'] - -task cpArtifacts(type: Copy) { - from shadowJar - into "$homeDir/$plugDir" -} - -shadowJar { - archiveClassifier = null -} -shadowJar.finalizedBy cpArtifacts - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - testImplementation group: 'junit', name: 'junit', version: '4.12' - compileOnly "org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT" - implementation 'com.vdurmont:emoji-java:5.1.1' - - def tgBotVer = '5.0.0' - implementation "io.github.kotlin-telegram-bot.kotlin-telegram-bot:telegram:$tgBotVer" -// def ktorVersion = '1.3.2' -// implementation "io.ktor:ktor-server-core:$ktorVersion" -} - -compileKotlin { - kotlinOptions.jvmTarget = "1.8" -} -compileTestKotlin { - kotlinOptions.jvmTarget = "1.8" -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..97e46a9 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,74 @@ +import org.yaml.snakeyaml.Yaml +import java.io.* +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath(group = "org.yaml", name = "snakeyaml", version = "1.26") + } +} + +plugins { + id("org.jetbrains.kotlin.jvm") version "1.4.31" + id("com.github.johnrengelman.shadow") version "5.2.0" +} + +group = "org.kraftwerk28" + +val cfg: Map = Yaml().load( + FileInputStream("src/main/resources/plugin.yml") +) +val pluginVersion = cfg.get("version") +val spigotApiVersion = cfg.get("api-version") +version = pluginVersion as Any + +repositories { + mavenCentral() + maven( + url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" + ) + maven(url = "https://jitpack.io") + maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") +} + +val tgBotVersion = "6.0.4" +val plugDir = "MinecraftServers/spigot_1.16.5/plugins/" +val homeDir = System.getProperty("user.home") + +tasks { + named("shadowJar") { + archiveBaseName.set( + "spigot-tg-bridge-${spigotApiVersion}-v${pluginVersion}.jar" + ) + } +} + +tasks.register("copyArtifacts") { + from(tasks.shadowJar) + into(File(homeDir, plugDir)) +} + +tasks.register("pack") { + dependsOn("shadowJar") + finalizedBy("copyArtifacts") +} + +defaultTasks("pack") + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + compileOnly("org.spigotmc:spigot-api:$spigotApiVersion-R0.1-SNAPSHOT") + implementation( + "io.github.kotlin-telegram-bot.kotlin-telegram-bot" + + ":telegram:$tgBotVersion" + ) + implementation("com.vdurmont:emoji-java:5.1.1") +} + +tasks.withType { + kotlinOptions.jvmTarget = "1.8" +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8490104..0f80bbf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Sat Feb 08 20:44:49 EET 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index af6708f..4f906e0 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -66,6 +82,7 @@ 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 @@ -109,10 +126,11 @@ 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 +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + 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" ;; + 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 @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +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" "$@" diff --git a/gradlew.bat b/gradlew.bat index 0f8d593..ac1b06f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ 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% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/BotCommands.kt b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/BotCommands.kt index 500ab08..51bb56c 100644 --- a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/BotCommands.kt +++ b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/BotCommands.kt @@ -14,4 +14,4 @@ class Commands(yamlCfg: YamlConfiguration) { chatID = getString("commands.chat_id") } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Configuration.kt b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Configuration.kt index 3d99a22..776eeaf 100644 --- a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Configuration.kt +++ b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Configuration.kt @@ -4,7 +4,7 @@ import org.bukkit.configuration.file.YamlConfiguration import java.io.File import org.kraftwerk28.spigot_tg_bridge.Constants as C -class Configuration(plugin: Plugin) { +class Configuration { private lateinit var yamlCfg: YamlConfiguration var isEnabled: Boolean = false @@ -16,7 +16,6 @@ class Configuration(plugin: Plugin) { // Telegram bot stuff var botToken: String = "" - var botUsername: String = "" var allowedChats: List = listOf() var logFromTGtoMC: Boolean = false var allowWebhook: Boolean = false @@ -32,16 +31,12 @@ class Configuration(plugin: Plugin) { lateinit var commands: Commands - init { - reload(plugin) - } - fun reload(plugin: Plugin) { val cfgFile = File(plugin.dataFolder, C.configFilename); if (!cfgFile.exists()) { cfgFile.parentFile.mkdirs() plugin.saveResource(C.configFilename, false); - throw Exception() + throw Exception(C.WARN.noConfigWarning) } yamlCfg = YamlConfiguration() @@ -56,10 +51,7 @@ class Configuration(plugin: Plugin) { allowedChats = getLongList("chats") serverStartMessage = getString("serverStartMessage") serverStopMessage = getString("serverStopMessage") - botToken = getString("botToken") ?: throw Exception(C.WARN.noToken) - botUsername = getString("botUsername") ?: throw Exception(C.WARN.noUsername) - allowWebhook = getBoolean("useWebhook", false) val whCfg = get("webhookConfig") if (whCfg is Map<*, *>) { @@ -79,4 +71,6 @@ class Configuration(plugin: Plugin) { commands = Commands(yamlCfg) } -} \ No newline at end of file + + fun load(plugin: Plugin) = reload(plugin) +} diff --git a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/EventHandler.kt b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/EventHandler.kt index ab364b7..712a9f3 100644 --- a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/EventHandler.kt +++ b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/EventHandler.kt @@ -9,42 +9,43 @@ import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerQuitEvent class EventHandler( - private val plugin: Plugin, + private val tgBot: TgBot, private val config: Configuration ) : Listener { @EventHandler fun onPlayerChat(event: AsyncPlayerChatEvent) { - if (config.logFromMCtoTG) { - plugin.tgBot.sendMessageToTGFrom( - event.player.displayName, event.message + if (!config.logFromMCtoTG) return + event.run { + tgBot.sendMessageToTelegram( + message, player.displayName ) } } @EventHandler fun onPlayerJoin(event: PlayerJoinEvent) { - if (!config.logJoinLeave || config.joinString == null) return - val username = TgBot.fullEscape(event.player.displayName) + if (!config.logJoinLeave || config.joinString == null) return + val username = fullEscape(event.player.displayName) val text = config.joinString!!.replace("%username%", username) - plugin.tgBot.broadcastToTG(text) + tgBot.sendMessageToTelegram(text) } @EventHandler fun onPlayerLeave(event: PlayerQuitEvent) { if (!config.logJoinLeave || config.leaveString == null) return - val username = TgBot.fullEscape(event.player.displayName) + val username = fullEscape(event.player.displayName) val text = config.leaveString!!.replace("%username%", username) - plugin.tgBot.broadcastToTG(text) + tgBot.sendMessageToTelegram(text) } @EventHandler fun onPlayerDied(event: PlayerDeathEvent) { if (!config.logDeath) return event.deathMessage?.let { - val username = TgBot.fullEscape(event.entity.displayName) + val username = fullEscape(event.entity.displayName) val text = it.replace(username, "$username") - plugin.tgBot.broadcastToTG(text) + tgBot.sendMessageToTelegram(text) } } @@ -53,6 +54,6 @@ class EventHandler( if (!config.logPlayerAsleep) return if (event.bedEnterResult != PlayerBedEnterEvent.BedEnterResult.OK) return val text = "${event.player.displayName} fell asleep." - plugin.tgBot.broadcastToTG(text) + tgBot.sendMessageToTelegram(text) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Plugin.kt b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Plugin.kt index d3ba557..88af9cd 100644 --- a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Plugin.kt +++ b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Plugin.kt @@ -7,60 +7,56 @@ import org.kraftwerk28.spigot_tg_bridge.Constants as C class Plugin : JavaPlugin() { - lateinit var tgBot: TgBot - lateinit var config: Configuration + var tgBot: TgBot? = null + val config: Configuration = Configuration() override fun onEnable() { try { - config = Configuration(this) + config.load(this) } catch (e: Exception) { - logger.warning(C.WARN.noConfigWarning) + logger.warning(e.message) return } - if (!config.isEnabled) return + if (!config.isEnabled) + return val cmdHandler = CommandHandler(this) - val eventHandler = EventHandler(this, config) - tgBot = TgBot(this, config) getCommand(C.COMMANDS.PLUGIN_RELOAD)?.setExecutor(cmdHandler) + val eventHandler = EventHandler(tgBot!!, config) server.pluginManager.registerEvents(eventHandler, this) // Notify Telegram groups about server start - config.serverStartMessage?.let { - tgBot.broadcastToTG(it) + config.serverStartMessage?.let { message -> + tgBot?.sendMessageToTelegram(message) } logger.info("Plugin started.") } override fun onDisable() { - if (!config?.isEnabled) return - config.serverStopMessage?.let { - tgBot.broadcastToTG(it) + if (!config.isEnabled) return + config.serverStopMessage?.let { message -> + tgBot?.sendMessageToTelegram(message) } logger.info("Plugin stopped.") } - fun sendMessageToMC(text: String) { - val prep = EmojiParser.parseToAliases(text) - server.broadcastMessage(prep) - } - - fun sendMessageToMCFrom(username: String, text: String) { - val prepared = config.telegramMessageFormat - .replace(C.USERNAME_PLACEHOLDER, emojiEsc(username)) - .replace(C.MESSAGE_TEXT_PLACEHOLDER, emojiEsc(text)) + fun sendMessageToMinecraft(text: String, username: String? = null) { + var prepared = config.telegramMessageFormat + .replace(C.MESSAGE_TEXT_PLACEHOLDER, escapeEmoji(text)) + username?.let { + prepared = prepared + .replace(C.USERNAME_PLACEHOLDER, escapeEmoji(it)) + } server.broadcastMessage(prepared) } - fun emojiEsc(text: String) = EmojiParser.parseToAliases(text) - fun reload() { logger.info(C.INFO.reloading) config.reload(this) - tgBot.stop() - tgBot.start(this, config) + tgBot?.stop() + tgBot?.start(this, config) logger.info(C.INFO.reloadComplete) } } diff --git a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/TgBot.kt b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/TgBot.kt index 66d5947..089b91d 100644 --- a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/TgBot.kt +++ b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/TgBot.kt @@ -6,20 +6,11 @@ import com.github.kotlintelegrambot.dispatcher.text import com.github.kotlintelegrambot.entities.BotCommand import com.github.kotlintelegrambot.entities.ParseMode import com.github.kotlintelegrambot.entities.Update -import com.github.kotlintelegrambot.entities.User +import com.github.kotlintelegrambot.logging.LogLevel +import com.github.kotlintelegrambot.entities.ChatId import okhttp3.logging.HttpLoggingInterceptor import org.kraftwerk28.spigot_tg_bridge.Constants as C -fun Bot.skipUpdates(lastUpdateID: Long = 0) { - val newUpdates = getUpdates(lastUpdateID) - - if (newUpdates.isNotEmpty()) { - val lastUpd = newUpdates.last() - if (lastUpd !is Update) return - return skipUpdates(lastUpd.updateId + 1) - } -} - class TgBot(private val plugin: Plugin, private val config: Configuration) { private lateinit var bot: Bot @@ -35,9 +26,9 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { skipUpdates() bot = bot { token = config.botToken - logLevel = HttpLoggingInterceptor.Level.NONE + logLevel = LogLevel.None - val cmdBinding = commands.let { + val commandBindings = commands.let { mapOf( it.time to ::time, it.online to ::online, @@ -46,10 +37,12 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { }.filterKeys { it != null } dispatch { - cmdBinding.forEach { (text, handler) -> - command(text!!.replace(slashRegex, ""), handler) + commandBindings.forEach { (text, handler) -> + command(text!!.replace(slashRegex, "")) { + handler(update) + } } - text(null, ::onText) + text { onText(update) } } } bot.setMyCommands(getBotCommands()) @@ -65,7 +58,7 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { bot.stopPolling() } - private fun time(bot: Bot, update: Update) { + private fun time(update: Update) { val msg = update.message!! if (!config.allowedChats.contains(msg.chat.id)) { return @@ -73,7 +66,7 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { if (plugin.server.worlds.isEmpty()) { bot.sendMessage( - msg.chat.id, + ChatId.fromId(msg.chat.id), "No worlds available", replyToMessageId = msg.messageId ) @@ -90,13 +83,14 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { } + " ($t)" bot.sendMessage( - msg.chat.id, text, + ChatId.fromId(msg.chat.id), + text, replyToMessageId = msg.messageId, parseMode = ParseMode.HTML ) } - private fun online(bot: Bot, update: Update) { + private fun online(update: Update) { val msg = update.message!! if (!config.allowedChats.contains(msg.chat.id)) { return @@ -111,13 +105,14 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { if (playerList.isNotEmpty()) "${config.onlineString}:\n$playerStr" else config.nobodyOnlineString bot.sendMessage( - msg.chat.id, text, + ChatId.fromId(msg.chat.id), + text, replyToMessageId = msg.messageId, parseMode = ParseMode.HTML ) } - private fun chatID(bot: Bot, update: Update) { + private fun chatID(update: Update) { val msg = update.message!! val chatID = msg.chat.id val text = """ @@ -127,46 +122,49 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { """.trimIndent() + "\n\nchats:\n # other ids...\n - ${chatID}" bot.sendMessage( - chatID, + ChatId.fromId(chatID), text, parseMode = ParseMode.HTML, replyToMessageId = msg.messageId ) } - fun broadcastToTG(text: String) { + fun sendMessageToTelegram(text: String, username: String? = null) { config.allowedChats.forEach { chatID -> - bot.sendMessage(chatID, text, parseMode = ParseMode.HTML) + username?.let { + bot.sendMessage( + ChatId.fromId(chatID), + formatMsgFromMinecraft(username, text), + parseMode = ParseMode.HTML, + ) + } ?: run { + bot.sendMessage( + ChatId.fromId(chatID), + text, + parseMode = ParseMode.HTML, + ) + } } } - fun sendMessageToTGFrom(username: String, text: String) { - config.allowedChats.forEach { chatID -> - bot.sendMessage( - chatID, - messageFromMinecraft(username, text), - parseMode = ParseMode.HTML - ) - } - } - - private fun onText(bot: Bot, update: Update) { + private fun onText(update: Update) { if (!config.logFromTGtoMC) return val msg = update.message!! - if (msg.text!!.startsWith("/")) return // Suppress command forwarding - plugin.sendMessageToMCFrom(rawUserMention(msg.from!!), msg.text!!) + + // Suppress commands to be sent to Minecraft + if (msg.text!!.startsWith("/")) return + + plugin.sendMessageToMinecraft(msg.text!!, rawUserMention(msg.from!!)) } - private fun messageFromMinecraft(username: String, text: String): String = + private fun formatMsgFromMinecraft( + username: String, + text: String + ): String = config.minecraftMessageFormat .replace("%username%", fullEscape(username)) .replace("%message%", escapeHTML(text)) - private fun rawUserMention(user: User): String = - (if (user.firstName.length < 2) null else user.firstName) - ?: user.username - ?: user.lastName!! - private fun getBotCommands(): List { val cmdList = config.commands.run { listOfNotNull(time, online, chatID) } val descList = C.COMMAND_DESC.run { listOf(timeDesc, onlineDesc, chatIDDesc) } @@ -174,21 +172,11 @@ class TgBot(private val plugin: Plugin, private val config: Configuration) { } private fun skipUpdates() { + // Creates a temporary bot w/ 0 timeout to skip updates bot { token = config.botToken timeout = 0 - logLevel = HttpLoggingInterceptor.Level.NONE + logLevel = LogLevel.None }.skipUpdates() } - - companion object { - fun escapeHTML(s: String) = s - .replace("&", "&") - .replace(">", ">") - .replace("<", "<") - - fun escapeColorCodes(s: String) = s.replace("\u00A7.".toRegex(), "") - - fun fullEscape(s: String) = escapeColorCodes(escapeHTML(s)) - } -} \ No newline at end of file +} diff --git a/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Utils.kt b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Utils.kt new file mode 100644 index 0000000..14f6aaf --- /dev/null +++ b/src/main/kotlin/org/kraftwerk28/spigot_tg_bridge/Utils.kt @@ -0,0 +1,35 @@ +package org.kraftwerk28.spigot_tg_bridge + +import com.github.kotlintelegrambot.Bot +import com.github.kotlintelegrambot.entities.Update +import com.github.kotlintelegrambot.entities.User +import com.vdurmont.emoji.EmojiParser + +fun Bot.skipUpdates(lastUpdateID: Long = 0) { + val newUpdates = getUpdates(lastUpdateID) + + if (newUpdates.isNotEmpty()) { + val lastUpd = newUpdates.last() + if (lastUpd !is Update) return + return skipUpdates(lastUpd.updateId + 1) + } +} + +fun String.escapeHtml() = + this.replace("&", "&").replace(">", ">").replace("<", "<") + +fun escapeHTML(s: String) = s + .replace("&", "&") + .replace(">", ">") + .replace("<", "<") + +fun escapeColorCodes(s: String) = s.replace("\u00A7.".toRegex(), "") + +fun fullEscape(s: String) = escapeColorCodes(escapeHTML(s)) + +fun escapeEmoji(text: String) = EmojiParser.parseToAliases(text) + +fun rawUserMention(user: User): String = + (if (user.firstName.length < 2) null else user.firstName) + ?: user.username + ?: user.lastName!! diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index d988f5b..e2306d7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,5 @@ enable: true botToken: abcdef123456789 -botUsername: sample_username chats: - -1234567890123 serverStartMessage: 'Server started.' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a9feb47..0085fb5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: SpigotTGBridge -version: 0.0.14 +version: 0.0.16 api-version: '1.15' main: org.kraftwerk28.spigot_tg_bridge.Plugin description: Telegram <-> Minecraft communication plugin for Spigot.