mirror of
https://github.com/amalthea-mc/spigot-tg-bridge.git
synced 2024-11-08 11:41:05 +00:00
Refactoring, 'cause I finally got IJ Idea
This commit is contained in:
parent
a8aa799b96
commit
4bcd274df4
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,3 +25,4 @@ hs_err_pid*
|
||||
build/
|
||||
.gradle/
|
||||
local.properties
|
||||
.idea/
|
||||
|
@ -2,7 +2,6 @@ package org.kraftwerk28.spigot_tg_bridge
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -37,7 +37,7 @@ class Configuration(plugin: Plugin) {
|
||||
// plugin.saveResource(C.configFilename, false);
|
||||
throw Exception(C.WARN.noConfigWarning)
|
||||
}
|
||||
val pluginConfig = plugin.getConfig()
|
||||
val pluginConfig = plugin.config
|
||||
pluginConfig.load(cfgFile)
|
||||
|
||||
pluginConfig.getString("minecraftMessageFormat")?.let {
|
||||
|
@ -18,8 +18,8 @@ create table if not exists user (
|
||||
|
||||
class IgnAuth(
|
||||
fileName: String,
|
||||
val plugin: Plugin,
|
||||
var conn: Connection? = null,
|
||||
private val plugin: Plugin,
|
||||
private var conn: Connection? = null,
|
||||
) {
|
||||
init {
|
||||
plugin.launch {
|
||||
@ -27,7 +27,7 @@ class IgnAuth(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun initializeConnection(fileName: String) = try {
|
||||
private fun initializeConnection(fileName: String) = try {
|
||||
DriverManager.getConnection("jdbc:sqlite:$fileName").apply {
|
||||
createStatement().execute(INIT_DB_QUERY)
|
||||
}.also {
|
||||
@ -37,11 +37,11 @@ class IgnAuth(
|
||||
plugin.logger.info(e.message)
|
||||
}
|
||||
|
||||
suspend fun close() = conn?.run {
|
||||
fun close() = conn?.run {
|
||||
close()
|
||||
}
|
||||
|
||||
suspend fun linkUser(
|
||||
fun linkUser(
|
||||
tgId: Long,
|
||||
tgUsername: String? = null,
|
||||
tgFirstName: String,
|
||||
@ -70,21 +70,21 @@ class IgnAuth(
|
||||
execute()
|
||||
} ?: false
|
||||
|
||||
suspend fun getLinkedUserByIgn(ign: String) =
|
||||
fun getLinkedUserByIgn(ign: String) =
|
||||
conn?.stmt("select * from user where mc_uuid = ?", ign)?.first {
|
||||
toLinkedUser()
|
||||
}
|
||||
|
||||
suspend fun getLinkedUserByTgId(id: Long) =
|
||||
fun getLinkedUserByTgId(id: Long) =
|
||||
conn?.stmt("select * from user where tg_id = ?", id)?.first {
|
||||
toLinkedUser()
|
||||
}
|
||||
|
||||
suspend fun unlinkUserByTgId(id: Long) =
|
||||
fun unlinkUserByTgId(id: Long) =
|
||||
conn?.stmt("delete from user where tg_id = ?", id)?.run {
|
||||
executeUpdate() > 0
|
||||
}
|
||||
|
||||
suspend fun getAllLinkedUsers() =
|
||||
fun getAllLinkedUsers() =
|
||||
conn?.stmt("select * from user")?.map { toLinkedUser() }
|
||||
}
|
||||
|
@ -1,45 +1,55 @@
|
||||
package org.kraftwerk28.spigot_tg_bridge
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import org.bukkit.event.HandlerList
|
||||
import java.lang.Exception
|
||||
import kotlin.system.measureTimeMillis
|
||||
import org.kraftwerk28.spigot_tg_bridge.Constants as C
|
||||
|
||||
class Plugin : AsyncJavaPlugin() {
|
||||
var tgBot: TgBot? = null
|
||||
private var tgBot: TgBot? = null
|
||||
private var eventHandler: EventHandler? = null
|
||||
var config: Configuration? = null
|
||||
private var config: Configuration? = null
|
||||
var ignAuth: IgnAuth? = null
|
||||
|
||||
override suspend fun onEnableAsync() = try {
|
||||
config = Configuration(this).also { config ->
|
||||
if (!config.isEnabled) return
|
||||
|
||||
if (config.enableIgnAuth) {
|
||||
val dbFilePath = dataFolder.resolve("spigot-tg-bridge.sqlite")
|
||||
ignAuth = IgnAuth(
|
||||
fileName = dbFilePath.absolutePath,
|
||||
plugin = this,
|
||||
)
|
||||
}
|
||||
|
||||
tgBot?.run { stop() }
|
||||
tgBot = TgBot(this, config).also { bot ->
|
||||
bot.startPolling()
|
||||
eventHandler = EventHandler(this, config, bot).also {
|
||||
server.pluginManager.registerEvents(it, this)
|
||||
override suspend fun onEnableAsync() {
|
||||
try {
|
||||
launch {
|
||||
config = Configuration(this).also {
|
||||
initializeWithConfig(it)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// Configuration file is missing or incomplete
|
||||
logger.warning(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
getCommand(C.COMMANDS.PLUGIN_RELOAD)?.run {
|
||||
setExecutor(CommandHandler(this@Plugin))
|
||||
}
|
||||
config.serverStartMessage?.let {
|
||||
tgBot?.sendMessageToTelegram(it)
|
||||
private suspend fun initializeWithConfig(config: Configuration) {
|
||||
if (!config.isEnabled) return
|
||||
|
||||
if (config.enableIgnAuth) {
|
||||
val dbFilePath = dataFolder.resolve("spigot-tg-bridge.sqlite")
|
||||
ignAuth = IgnAuth(
|
||||
fileName = dbFilePath.absolutePath,
|
||||
plugin = this,
|
||||
)
|
||||
}
|
||||
|
||||
tgBot?.run { stop() }
|
||||
tgBot = TgBot(this, config).also { bot ->
|
||||
bot.startPolling()
|
||||
eventHandler = EventHandler(this, config, bot).also {
|
||||
server.pluginManager.registerEvents(it, this)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// Configuration file is missing or incomplete
|
||||
logger.warning(e.message)
|
||||
|
||||
getCommand(C.COMMANDS.PLUGIN_RELOAD)?.run {
|
||||
setExecutor(CommandHandler(this@Plugin))
|
||||
}
|
||||
config.serverStartMessage?.let {
|
||||
tgBot?.sendMessageToTelegram(it)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun onDisableAsync() {
|
||||
@ -52,6 +62,7 @@ class Plugin : AsyncJavaPlugin() {
|
||||
eventHandler?.let { HandlerList.unregisterAll(it) }
|
||||
tgBot?.run { stop() }
|
||||
tgBot = null
|
||||
ignAuth?.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,30 +5,35 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Call
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.time.Duration
|
||||
import org.kraftwerk28.spigot_tg_bridge.Constants as C
|
||||
|
||||
typealias UpdateRequest = Call<TgResponse<List<Update>>>?
|
||||
typealias CmdHandler = suspend (HandlerContext) -> Unit
|
||||
|
||||
data class HandlerContext(
|
||||
val update: Update,
|
||||
val message: Message?,
|
||||
val chat: Chat?,
|
||||
val commandArgs: List<String>,
|
||||
val commandArgs: List<String> = listOf(),
|
||||
)
|
||||
|
||||
class TgBot(
|
||||
private val plugin: Plugin,
|
||||
private val config: Configuration,
|
||||
) {
|
||||
private val api: TgApiService
|
||||
private val client: OkHttpClient
|
||||
private val client: OkHttpClient = OkHttpClient
|
||||
.Builder()
|
||||
.readTimeout(Duration.ZERO)
|
||||
.build()
|
||||
private val api = Retrofit.Builder()
|
||||
.baseUrl("https://api.telegram.org/bot${config.botToken}/")
|
||||
.client(client)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
.create(TgApiService::class.java)
|
||||
private val updateChan = Channel<Update>()
|
||||
private var pollJob: Job? = null
|
||||
private var handlerJob: Job? = null
|
||||
@ -46,24 +51,11 @@ class TgBot(
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
client = OkHttpClient
|
||||
.Builder()
|
||||
.readTimeout(Duration.ZERO)
|
||||
.build()
|
||||
api = Retrofit.Builder()
|
||||
.baseUrl("https://api.telegram.org/bot${config.botToken}/")
|
||||
.client(client)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
.create(TgApiService::class.java)
|
||||
}
|
||||
|
||||
private suspend fun initialize() {
|
||||
me = api.getMe().result!!
|
||||
// I intentionally don't put optional @username in regex
|
||||
// since bot is only used in group chats
|
||||
commandRegex = """^\/(\w+)(?:@${me!!.username})(?:\s+(.+))?$""".toRegex()
|
||||
commandRegex = """^/(\w+)@${me!!.username}(?:\s+(.+))?$""".toRegex()
|
||||
val commands = config.commands.run { listOf(time, online, chatID) }
|
||||
.zip(
|
||||
C.COMMAND_DESC.run {
|
||||
@ -88,13 +80,13 @@ class TgBot(
|
||||
}
|
||||
|
||||
private fun initPolling() = plugin.launch {
|
||||
loop@ while (true) {
|
||||
loop@while (true) {
|
||||
try {
|
||||
api.getUpdates(
|
||||
offset = currentOffset,
|
||||
timeout = config.pollTimeout,
|
||||
).result?.let { updates ->
|
||||
if (!updates.isEmpty()) {
|
||||
if (updates.isNotEmpty()) {
|
||||
updates.forEach { updateChan.send(it) }
|
||||
currentOffset = updates.last().updateId + 1
|
||||
}
|
||||
@ -122,20 +114,19 @@ class TgBot(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun handleUpdate(update: Update) {
|
||||
// Ignore PM or channel
|
||||
private suspend fun handleUpdate(update: Update) {
|
||||
// Ignore private message or channel post
|
||||
if (listOf("private", "channel").contains(update.message?.chat?.type))
|
||||
return
|
||||
var ctx = HandlerContext(
|
||||
val ctx = HandlerContext(
|
||||
update,
|
||||
update.message,
|
||||
update.message?.chat,
|
||||
listOf(),
|
||||
)
|
||||
update.message?.text?.let {
|
||||
commandRegex?.matchEntire(it)?.groupValues?.let {
|
||||
commandMap.get(it[1])?.run {
|
||||
val args = it[2].split("\\s+".toRegex())
|
||||
commandRegex?.matchEntire(it)?.groupValues?.let { matchList ->
|
||||
commandMap[matchList[1]]?.run {
|
||||
val args = matchList[2].split("\\s+".toRegex())
|
||||
this(ctx.copy(commandArgs = args))
|
||||
}
|
||||
} ?: run {
|
||||
@ -204,7 +195,7 @@ class TgBot(
|
||||
private suspend fun linkIgnHandler(ctx: HandlerContext) {
|
||||
val tgUser = ctx.message!!.from!!
|
||||
val mcUuid = getMinecraftUuidByUsername(ctx.message.text!!)
|
||||
if (mcUuid == null || ctx.commandArgs.size < 1) {
|
||||
if (mcUuid == null || ctx.commandArgs.isEmpty()) {
|
||||
// Respond...
|
||||
return
|
||||
}
|
||||
@ -236,7 +227,7 @@ class TgBot(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onTextHandler(
|
||||
private fun onTextHandler(
|
||||
@Suppress("unused_parameter") ctx: HandlerContext
|
||||
) {
|
||||
val msg = ctx.message!!
|
||||
@ -258,10 +249,5 @@ class TgBot(
|
||||
config.allowedChats.forEach { chatId ->
|
||||
api.sendMessage(chatId, formatted)
|
||||
}
|
||||
// plugin.launch {
|
||||
// config.allowedChats.forEach { chatId ->
|
||||
// api.sendMessage(chatId, formatted)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user