Fix bugs with plugin reloading

This commit is contained in:
kraftwerk28 2021-07-03 22:41:29 +03:00
parent 826c556ae9
commit eb65ba4f73
6 changed files with 73 additions and 58 deletions

View File

@ -6,9 +6,11 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://plugins.gradle.org/m2/")
} }
dependencies { dependencies {
classpath(group = "org.yaml", name = "snakeyaml", version = "1.26") classpath("org.yaml:snakeyaml:1.26")
classpath("org.jlleitschuh.gradle:ktlint-gradle:10.1.0")
} }
} }
@ -17,11 +19,12 @@ plugins {
id("com.github.johnrengelman.shadow") version "5.2.0" id("com.github.johnrengelman.shadow") version "5.2.0"
} }
apply(plugin = "org.jlleitschuh.gradle.ktlint")
group = "org.kraftwerk28" group = "org.kraftwerk28"
val cfg: Map<String, String> = Yaml().load( val cfg: Map<String, String> = Yaml()
FileInputStream("src/main/resources/plugin.yml") .load(FileInputStream("$projectDir/src/main/resources/plugin.yml"))
)
val pluginVersion = cfg.get("version") val pluginVersion = cfg.get("version")
val spigotApiVersion = cfg.get("api-version") val spigotApiVersion = cfg.get("api-version")
version = pluginVersion as Any version = pluginVersion as Any

View File

@ -57,11 +57,11 @@ interface TgApiService {
): TgResponse<Message> ): TgResponse<Message>
@GET("getUpdates") @GET("getUpdates")
fun getUpdates( suspend fun getUpdates(
@Query("offset") offset: Long, @Query("offset") offset: Long,
@Query("limit") limit: Int = 100, @Query("limit") limit: Int = 100,
@Query("timeout") timeout: Int = 0, @Query("timeout") timeout: Int = 0,
): Call<TgResponse<List<Update>>> ): TgResponse<List<Update>>
@GET("getMe") @GET("getMe")
suspend fun getMe(): TgResponse<User> suspend fun getMe(): TgResponse<User>

View File

@ -36,8 +36,9 @@ class Configuration(plugin: Plugin) {
// plugin.saveResource(C.configFilename, false); // plugin.saveResource(C.configFilename, false);
throw Exception(C.WARN.noConfigWarning) throw Exception(C.WARN.noConfigWarning)
} }
val pluginConfig = plugin.getConfig() val pluginConfig = plugin.getConfig()
pluginConfig.load(cfgFile)
pluginConfig.getString("minecraftMessageFormat")?.let { pluginConfig.getString("minecraftMessageFormat")?.let {
plugin.logger.warning(""" plugin.logger.warning("""
Config option "minecraftMessageFormat" is deprecated. Config option "minecraftMessageFormat" is deprecated.
@ -47,6 +48,7 @@ class Configuration(plugin: Plugin) {
pluginConfig.set("minecraftMessageFormat", null) pluginConfig.set("minecraftMessageFormat", null)
plugin.saveConfig() plugin.saveConfig()
} }
pluginConfig.getString("telegramMessageFormat")?.let { pluginConfig.getString("telegramMessageFormat")?.let {
plugin.logger.warning(""" plugin.logger.warning("""
Config option "telegramMessageFormat" is deprecated. Config option "telegramMessageFormat" is deprecated.

View File

@ -7,6 +7,8 @@ import org.bukkit.event.player.AsyncPlayerChatEvent
import org.bukkit.event.player.PlayerBedEnterEvent import org.bukkit.event.player.PlayerBedEnterEvent
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.event.world.WorldLoadEvent
import org.bukkit.event.world.WorldUnloadEvent
class EventHandler( class EventHandler(
private val tgBot: TgBot, private val tgBot: TgBot,
@ -17,9 +19,7 @@ class EventHandler(
fun onPlayerChat(event: AsyncPlayerChatEvent) { fun onPlayerChat(event: AsyncPlayerChatEvent) {
if (!config.logFromMCtoTG) return if (!config.logFromMCtoTG) return
event.run { event.run {
tgBot.sendMessageToTelegram( tgBot.sendMessageToTelegram(message, player.displayName)
message, player.displayName
)
} }
} }

View File

@ -29,25 +29,22 @@ class Plugin : JavaPlugin() {
} }
getCommand(C.COMMANDS.PLUGIN_RELOAD)?.setExecutor(cmdHandler) getCommand(C.COMMANDS.PLUGIN_RELOAD)?.setExecutor(cmdHandler)
// Notify Telegram groups about server start
config.serverStartMessage?.let { message -> config.serverStartMessage?.let { message ->
tgBot?.sendMessageToTelegram(message) tgBot?.sendMessageToTelegram(message)
} }
logger.info("Plugin started.")
} }
fun loadBot() { fun loadBot() {
tgBot?.let { it.stop() } tgBot?.run { stop() }
tgBot = TgBot(this, config) tgBot = TgBot(this, config)
} }
override fun onDisable() { override fun onDisable() {
if (!config.isEnabled) if (!config.isEnabled) return
return
config.serverStopMessage?.let { config.serverStopMessage?.let {
tgBot?.sendMessageToTelegram(it) tgBot?.sendMessageToTelegram(it, blocking = true)
} }
logger.info("Plugin stopped.") tgBot?.run { stop() }
} }
fun sendMessageToMinecraft( fun sendMessageToMinecraft(

View File

@ -10,6 +10,10 @@ import retrofit2.Call
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
import java.time.Duration import java.time.Duration
typealias UpdateRequest = Call<
TgApiService.TgResponse<List<TgApiService.Update>>
>?
class TgBot( class TgBot(
private val plugin: Plugin, private val plugin: Plugin,
private val config: Configuration, private val config: Configuration,
@ -66,40 +70,47 @@ class TgBot(
} }
private fun initPolling() = scope.launch { private fun initPolling() = scope.launch {
var request: loop@ while (true) {
Call<TgApiService.TgResponse<List<TgApiService.Update>>>? = null try {
try { api.getUpdates(offset = currentOffset, timeout = pollTimeout)
while (true) { .result?.let { updates ->
try {
request = api.getUpdates(
offset = currentOffset,
timeout = pollTimeout,
)
val response = request.execute().body()
response?.result?.let { updates ->
if (!updates.isEmpty()) { if (!updates.isEmpty()) {
updates.forEach { updateChan.send(it) } updates.forEach { updateChan.send(it) }
currentOffset = updates.last().updateId + 1 currentOffset = updates.last().updateId + 1
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() when (e) {
is CancellationException -> break@loop
else -> {
e.printStackTrace()
continue@loop
}
} }
} }
} catch (e: CancellationException) {
request?.cancel()
} }
} }
private fun initHandler() = scope.launch { private fun initHandler() = scope.launch {
try { loop@ while (true) {
while (true) { try {
handleUpdate(updateChan.receive()) handleUpdate(updateChan.receive())
} catch (e: Exception) {
when (e) {
is CancellationException -> break@loop
else -> {
e.printStackTrace()
continue@loop
}
}
} }
} catch (e: CancellationException) {} }
} }
suspend fun handleUpdate(update: TgApiService.Update) { suspend fun handleUpdate(update: TgApiService.Update) {
// Ignore PM or channel
if (listOf("private", "channel").contains(update.message?.chat?.type))
return
update.message?.text?.let { update.message?.text?.let {
commandRegex.matchEntire(it)?.groupValues?.let { commandRegex.matchEntire(it)?.groupValues?.let {
commandMap[it[1]]?.let { it(update) } commandMap[it[1]]?.let { it(update) }
@ -167,25 +178,16 @@ class TgBot(
val msg = update.message!! val msg = update.message!!
val chatId = msg.chat.id val chatId = msg.chat.id
val text = """ val text = """
Chat ID: |Chat ID: <code>${chatId}</code>.
<code>${chatId}</code> |Copy this id to <code>chats</code> section in your <b>config.yml</b> file so it will look like this:
paste this id to <code>chats:</code> section in you config.yml file so it will look like this: |
""".trimIndent() + |<pre>chats:
"\n\n<code>chats:\n # other ids...\n - ${chatId}</code>" | # other ids...
| - ${chatId}</pre>
""".trimMargin()
api.sendMessage(chatId, text, replyToMessageId = msg.messageId) api.sendMessage(chatId, text, replyToMessageId = msg.messageId)
} }
fun sendMessageToTelegram(text: String, username: String? = null) {
val messageText = username?.let {
formatMsgFromMinecraft(it, text)
} ?: text
config.allowedChats.forEach { chatId ->
scope.launch {
api.sendMessage(chatId, messageText)
}
}
}
private suspend fun onTextHandler(update: TgApiService.Update) { private suspend fun onTextHandler(update: TgApiService.Update) {
val msg = update.message!! val msg = update.message!!
if (!config.logFromTGtoMC || msg.from == null) if (!config.logFromTGtoMC || msg.from == null)
@ -197,11 +199,22 @@ class TgBot(
) )
} }
private fun formatMsgFromMinecraft( fun sendMessageToTelegram(
username: String, text: String,
text: String username: String? = null,
): String = blocking: Boolean = false,
config.telegramFormat ) {
.replace(C.USERNAME_PLACEHOLDER, username.fullEscape()) val formatted = username?.let {
.replace(C.MESSAGE_TEXT_PLACEHOLDER, text.escapeHtml()) config.telegramFormat
.replace(C.USERNAME_PLACEHOLDER, username.fullEscape())
.replace(C.MESSAGE_TEXT_PLACEHOLDER, text.escapeHtml())
} ?: text
scope.launch {
config.allowedChats.forEach { chatId ->
api.sendMessage(chatId, formatted)
}
}.also {
if (blocking) runBlocking { it.join() }
}
}
} }