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 {
repositories {
mavenCentral()
maven("https://plugins.gradle.org/m2/")
}
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"
}
apply(plugin = "org.jlleitschuh.gradle.ktlint")
group = "org.kraftwerk28"
val cfg: Map<String, String> = Yaml().load(
FileInputStream("src/main/resources/plugin.yml")
)
val cfg: Map<String, String> = Yaml()
.load(FileInputStream("$projectDir/src/main/resources/plugin.yml"))
val pluginVersion = cfg.get("version")
val spigotApiVersion = cfg.get("api-version")
version = pluginVersion as Any

View File

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

View File

@ -36,8 +36,9 @@ class Configuration(plugin: Plugin) {
// plugin.saveResource(C.configFilename, false);
throw Exception(C.WARN.noConfigWarning)
}
val pluginConfig = plugin.getConfig()
pluginConfig.load(cfgFile)
pluginConfig.getString("minecraftMessageFormat")?.let {
plugin.logger.warning("""
Config option "minecraftMessageFormat" is deprecated.
@ -47,6 +48,7 @@ class Configuration(plugin: Plugin) {
pluginConfig.set("minecraftMessageFormat", null)
plugin.saveConfig()
}
pluginConfig.getString("telegramMessageFormat")?.let {
plugin.logger.warning("""
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.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.event.world.WorldLoadEvent
import org.bukkit.event.world.WorldUnloadEvent
class EventHandler(
private val tgBot: TgBot,
@ -17,9 +19,7 @@ class EventHandler(
fun onPlayerChat(event: AsyncPlayerChatEvent) {
if (!config.logFromMCtoTG) return
event.run {
tgBot.sendMessageToTelegram(
message, player.displayName
)
tgBot.sendMessageToTelegram(message, player.displayName)
}
}

View File

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

View File

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