mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-24 20:17:38 +08:00
refactor runtime context from class instance to using/given
This commit is contained in:
parent
92aa0e260e
commit
511036e2ce
@ -110,8 +110,6 @@ tasks.withType(ScalaCompile).configureEach {
|
|||||||
scalaCompileOptions.encoding = proj_file_encoding.name()
|
scalaCompileOptions.encoding = proj_file_encoding.name()
|
||||||
|
|
||||||
scalaCompileOptions.additionalParameters.add "-language:postfixOps"
|
scalaCompileOptions.additionalParameters.add "-language:postfixOps"
|
||||||
// scalaCompileOptions.additionalParameters.add("-Yexplicit-nulls")
|
|
||||||
// scalaCompileOptions.additionalParameters.add "-language:experimental.saferExceptions"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +194,15 @@ publishing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
publications {
|
publications {
|
||||||
|
//noinspection GroovyAssignabilityCheck
|
||||||
main (MavenPublication) {
|
main (MavenPublication) {
|
||||||
|
//noinspection GroovyAssignabilityCheck
|
||||||
from components.java
|
from components.java
|
||||||
|
//noinspection GroovyAssignabilityCheck
|
||||||
groupId = proj_group
|
groupId = proj_group
|
||||||
|
//noinspection GroovyAssignabilityCheck
|
||||||
artifactId = proj_archive_name
|
artifactId = proj_archive_name
|
||||||
|
//noinspection GroovyAssignabilityCheck
|
||||||
version = proj_version
|
version = proj_version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
|
|||||||
VERSION = 1.0.0-RC5
|
VERSION = 1.0.0-RC5
|
||||||
|
|
||||||
USE_DELTA = true
|
USE_DELTA = true
|
||||||
VERSION_DELTA = scala1
|
VERSION_DELTA = scala2
|
||||||
|
|
||||||
CODENAME = beiping
|
CODENAME = beiping
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import cc.sukazyo.restools.ResourcesPackage
|
|||||||
|
|
||||||
object MornyAssets {
|
object MornyAssets {
|
||||||
|
|
||||||
|
class AssetsException (caused: Throwable) extends Exception("Cannot read assets file.", caused)
|
||||||
|
|
||||||
val pack: ResourcesPackage = ResourcesPackage(MornyAssets.getClass, "assets_morny")
|
val pack: ResourcesPackage = ResourcesPackage(MornyAssets.getClass, "assets_morny")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ import cc.sukazyo.cono.morny.daemon.MornyDaemons
|
|||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur.THREAD_MORNY_EXIT
|
import cc.sukazyo.cono.morny.MornyCoeur.THREAD_MORNY_EXIT
|
||||||
import cc.sukazyo.cono.morny.bot.api.TelegramUpdatesListener
|
import cc.sukazyo.cono.morny.bot.api.TelegramUpdatesListener
|
||||||
import cc.sukazyo.cono.morny.bot.event.MornyEventListeners
|
import cc.sukazyo.cono.morny.bot.event.{MornyEventListeners, MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock}
|
||||||
|
import cc.sukazyo.cono.morny.bot.query.MornyQueries
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.ExtraAction
|
import cc.sukazyo.cono.morny.util.tgapi.ExtraAction
|
||||||
import com.pengrad.telegrambot.TelegramBot
|
import com.pengrad.telegrambot.TelegramBot
|
||||||
import com.pengrad.telegrambot.request.GetMe
|
import com.pengrad.telegrambot.request.GetMe
|
||||||
@ -17,53 +18,15 @@ object MornyCoeur {
|
|||||||
|
|
||||||
val THREAD_MORNY_EXIT = "morny-exiting"
|
val THREAD_MORNY_EXIT = "morny-exiting"
|
||||||
|
|
||||||
private var INSTANCE: MornyCoeur|Null = _
|
|
||||||
|
|
||||||
val coeurStartTimestamp: Long = ServerMain.systemStartupTime
|
|
||||||
|
|
||||||
def account: TelegramBot = INSTANCE.account
|
|
||||||
def username: String = INSTANCE.username
|
|
||||||
def userid: Long = INSTANCE.userid
|
|
||||||
def config: MornyConfig = INSTANCE.my_config
|
|
||||||
def trusted: MornyTrusted = INSTANCE.trusted
|
|
||||||
def extra: ExtraAction = INSTANCE.extra
|
|
||||||
|
|
||||||
def available: Boolean = INSTANCE != null
|
|
||||||
def callSaveData(): Unit = INSTANCE.saveDataAll()
|
|
||||||
|
|
||||||
def exitReason: AnyRef|Null = INSTANCE.whileExit_reason
|
|
||||||
|
|
||||||
def exit (status: Int, reason: AnyRef): Unit =
|
|
||||||
INSTANCE.whileExit_reason = reason
|
|
||||||
System exit status
|
|
||||||
|
|
||||||
def init (using config: MornyConfig): Unit = {
|
|
||||||
|
|
||||||
if (INSTANCE ne null)
|
|
||||||
logger error "Coeur already started!!!"
|
|
||||||
return;
|
|
||||||
|
|
||||||
logger info "Coeur starting..."
|
|
||||||
INSTANCE = MornyCoeur()
|
|
||||||
|
|
||||||
MornyDaemons.start()
|
|
||||||
|
|
||||||
logger info "start telegram event listening"
|
|
||||||
MornyEventListeners.registerAllEvents()
|
|
||||||
INSTANCE.account.setUpdatesListener(TelegramUpdatesListener)
|
|
||||||
|
|
||||||
if config.commandLoginRefresh then
|
|
||||||
logger info "resetting telegram command list"
|
|
||||||
MornyCommands.automaticTGListUpdate()
|
|
||||||
|
|
||||||
logger info "Coeur start complete."
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MornyCoeur (using config: MornyConfig) {
|
class MornyCoeur (using val config: MornyConfig) {
|
||||||
def my_config: MornyConfig = config
|
|
||||||
|
given MornyCoeur = this
|
||||||
|
|
||||||
|
///>>> BLOCK START instance configure & startup stage 1
|
||||||
|
|
||||||
|
logger info "Coeur starting..."
|
||||||
|
|
||||||
logger info s"args key:\n ${config.telegramBotKey}"
|
logger info s"args key:\n ${config.telegramBotKey}"
|
||||||
if config.telegramBotUsername ne null then
|
if config.telegramBotUsername ne null then
|
||||||
@ -76,13 +39,47 @@ class MornyCoeur (using config: MornyConfig) {
|
|||||||
|
|
||||||
configure_exitCleanup()
|
configure_exitCleanup()
|
||||||
|
|
||||||
|
///<<< BLOCK END instance configure & startup stage 1
|
||||||
|
|
||||||
|
/** [[TelegramBot]] account of this Morny */
|
||||||
val account: TelegramBot = __loginResult.account
|
val account: TelegramBot = __loginResult.account
|
||||||
|
/** [[account]]'s telegram username */
|
||||||
val username: String = __loginResult.username
|
val username: String = __loginResult.username
|
||||||
|
/** [[account]]'s telegram user id */
|
||||||
val userid: Long = __loginResult.userid
|
val userid: Long = __loginResult.userid
|
||||||
|
|
||||||
val trusted: MornyTrusted = MornyTrusted(using this)
|
/** current Morny's [[MornyTrusted]] instance */
|
||||||
|
val trusted: MornyTrusted = MornyTrusted()
|
||||||
|
/** current Morny's [[ExtraAction]] toolset */
|
||||||
val extra: ExtraAction = ExtraAction as __loginResult.account
|
val extra: ExtraAction = ExtraAction as __loginResult.account
|
||||||
var whileExit_reason: AnyRef|Null = _
|
private val updatesListener: TelegramUpdatesListener = TelegramUpdatesListener()
|
||||||
|
|
||||||
|
val daemons: MornyDaemons = MornyDaemons()
|
||||||
|
updatesListener.manager register MornyOnUpdateTimestampOffsetLock()
|
||||||
|
val commands: MornyCommands = MornyCommands()
|
||||||
|
//noinspection ScalaWeakerAccess
|
||||||
|
val queries: MornyQueries = MornyQueries()
|
||||||
|
updatesListener.manager register MornyOnTelegramCommand(using commands)
|
||||||
|
updatesListener.manager register MornyOnInlineQuery(using queries)
|
||||||
|
val events: MornyEventListeners = MornyEventListeners(using updatesListener.manager)
|
||||||
|
|
||||||
|
/** inner value: about why morny exit, used in [[daemon.MornyReport]]. */
|
||||||
|
private var whileExit_reason: AnyRef|Null = _
|
||||||
|
def exitReason: AnyRef|Null = whileExit_reason
|
||||||
|
val coeurStartTimestamp: Long = ServerMain.systemStartupTime
|
||||||
|
|
||||||
|
///>>> BLOCK START instance configure & startup stage 2
|
||||||
|
|
||||||
|
daemons.start()
|
||||||
|
logger info "start telegram event listening"
|
||||||
|
account setUpdatesListener updatesListener
|
||||||
|
if config.commandLoginRefresh then
|
||||||
|
logger info "resetting telegram command list"
|
||||||
|
commands.automaticTGListUpdate()
|
||||||
|
|
||||||
|
logger info "Coeur start complete."
|
||||||
|
|
||||||
|
///<<< BLOCK END instance configure & startup stage 2
|
||||||
|
|
||||||
def saveDataAll(): Unit = {
|
def saveDataAll(): Unit = {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
@ -90,15 +87,19 @@ class MornyCoeur (using config: MornyConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def exitCleanup (): Unit = {
|
private def exitCleanup (): Unit = {
|
||||||
MornyDaemons.stop()
|
daemons.stop()
|
||||||
if config.commandLogoutClear then
|
if config.commandLogoutClear then
|
||||||
MornyCommands.automaticTGListRemove()
|
commands.automaticTGListRemove()
|
||||||
}
|
}
|
||||||
|
|
||||||
private def configure_exitCleanup (): Unit = {
|
private def configure_exitCleanup (): Unit = {
|
||||||
Runtime.getRuntime.addShutdownHook(new Thread(() => exitCleanup(), THREAD_MORNY_EXIT))
|
Runtime.getRuntime.addShutdownHook(new Thread(() => exitCleanup(), THREAD_MORNY_EXIT))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def exit (status: Int, reason: AnyRef): Unit =
|
||||||
|
whileExit_reason = reason
|
||||||
|
System exit status
|
||||||
|
|
||||||
private case class LoginResult(account: TelegramBot, username: String, userid: Long)
|
private case class LoginResult(account: TelegramBot, username: String, userid: Long)
|
||||||
|
|
||||||
private def login (): LoginResult|Null = {
|
private def login (): LoginResult|Null = {
|
||||||
|
@ -86,7 +86,7 @@ public class MornyConfig {
|
|||||||
/**
|
/**
|
||||||
* morny 的事件忽略前缀时间<br>
|
* morny 的事件忽略前缀时间<br>
|
||||||
* <br>
|
* <br>
|
||||||
* {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
|
* {@link cc.sukazyo.cono.morny.bot.event.MornyOnUpdateTimestampOffsetLock}
|
||||||
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
||||||
*/
|
*/
|
||||||
public final long eventOutdatedTimestamp;
|
public final long eventOutdatedTimestamp;
|
||||||
|
@ -2,7 +2,6 @@ package cc.sukazyo.cono.morny
|
|||||||
|
|
||||||
import cc.sukazyo.cono.morny.internal.BuildConfigField
|
import cc.sukazyo.cono.morny.internal.BuildConfigField
|
||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.daemon.MornyReport
|
|
||||||
import cc.sukazyo.cono.morny.util.FileUtils
|
import cc.sukazyo.cono.morny.util.FileUtils
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -42,7 +41,7 @@ object MornySystem {
|
|||||||
"<non-jar-runtime>"
|
"<non-jar-runtime>"
|
||||||
case n: NoSuchAlgorithmException =>
|
case n: NoSuchAlgorithmException =>
|
||||||
logger error exceptionLog(n)
|
logger error exceptionLog(n)
|
||||||
MornyReport.exception(n, "<coeur-md5/calculation-error>")
|
// MornyReport.exception(n, "<coeur-md5/calculation-error>") // todo: will not implemented
|
||||||
"<calculation-error>"
|
"<calculation-error>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ object ServerMain {
|
|||||||
Thread.currentThread setName THREAD_MORNY_INIT
|
Thread.currentThread setName THREAD_MORNY_INIT
|
||||||
|
|
||||||
try
|
try
|
||||||
MornyCoeur.init(using config build)
|
MornyCoeur(using config build)
|
||||||
catch {
|
catch {
|
||||||
case _: CheckFailure.NullTelegramBotKey =>
|
case _: CheckFailure.NullTelegramBotKey =>
|
||||||
logger.info("Parameter required has no value:\n --token.")
|
logger.info("Parameter required has no value:\n --token.")
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.api
|
package cc.sukazyo.cono.morny.bot.api
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
trait EventListener {
|
trait EventListener (using MornyCoeur) {
|
||||||
|
|
||||||
def onMessage (using Update): Boolean = false
|
def onMessage (using Update): Boolean = false
|
||||||
def onEditedMessage (using Update): Boolean = false
|
def onEditedMessage (using Update): Boolean = false
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.api
|
package cc.sukazyo.cono.morny.bot.api
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.Log
|
import cc.sukazyo.cono.morny.{Log, MornyCoeur}
|
||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.daemon.MornyReport
|
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
|
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
@ -10,7 +9,7 @@ import com.pengrad.telegrambot.model.Update
|
|||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object EventListenerManager {
|
class EventListenerManager (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
private val listeners = mutable.Queue.empty[EventListener]
|
private val listeners = mutable.Queue.empty[EventListener]
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ object EventListenerManager {
|
|||||||
) indent 4) ++= "\n"
|
) indent 4) ++= "\n"
|
||||||
case _ =>
|
case _ =>
|
||||||
logger error errorMessage.toString
|
logger error errorMessage.toString
|
||||||
MornyReport.exception(e, "on event running")
|
coeur.daemons.reporter.exception(e, "on event running")
|
||||||
}
|
}
|
||||||
if (status isOk) return
|
if (status isOk) return
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.api
|
package cc.sukazyo.cono.morny.bot.api
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.UpdatesListener
|
import com.pengrad.telegrambot.UpdatesListener
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
import java.util
|
import java.util
|
||||||
import scala.jdk.CollectionConverters.*
|
import scala.jdk.CollectionConverters.*
|
||||||
|
|
||||||
object TelegramUpdatesListener extends UpdatesListener {
|
class TelegramUpdatesListener (using MornyCoeur) extends UpdatesListener {
|
||||||
|
|
||||||
|
val manager = EventListenerManager()
|
||||||
|
|
||||||
override def process (updates: util.List[Update]): Int = {
|
override def process (updates: util.List[Update]): Int = {
|
||||||
for (update <- updates.asScala)
|
for (update <- updates.asScala)
|
||||||
EventListenerManager.publishUpdate(using update)
|
manager.publishUpdate(using update)
|
||||||
UpdatesListener.CONFIRMED_UPDATES_ALL
|
UpdatesListener.CONFIRMED_UPDATES_ALL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import com.pengrad.telegrambot.request.{DeleteMessage, GetChatMember, SendSticke
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object DirectMsgClear extends ISimpleCommand {
|
class DirectMsgClear (using coeur: MornyCoeur) extends ISimpleCommand {
|
||||||
|
|
||||||
override val name: String = "r"
|
override val name: String = "r"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
@ -19,16 +19,16 @@ object DirectMsgClear extends ISimpleCommand {
|
|||||||
logger debug "executing command /r"
|
logger debug "executing command /r"
|
||||||
if (event.message.replyToMessage == null) return;
|
if (event.message.replyToMessage == null) return;
|
||||||
logger trace "message is a reply"
|
logger trace "message is a reply"
|
||||||
if (event.message.replyToMessage.from.id != MornyCoeur.userid) return;
|
if (event.message.replyToMessage.from.id != coeur.userid) return;
|
||||||
logger trace "message replied is from me"
|
logger trace "message replied is from me"
|
||||||
if (System.currentTimeMillis/1000 - event.message.replyToMessage.date > 48*60*60) return;
|
if (System.currentTimeMillis/1000 - event.message.replyToMessage.date > 48*60*60) return;
|
||||||
logger trace "message is not outdated(48 hrs ago)"
|
logger trace "message is not outdated(48 hrs ago)"
|
||||||
|
|
||||||
val isTrusted = MornyCoeur.trusted isTrusted event.message.from.id
|
val isTrusted = coeur.trusted isTrusted event.message.from.id
|
||||||
// todo:
|
// todo:
|
||||||
// it does not work. due to the Telegram Bot API doesn't provide
|
// it does not work. due to the Telegram Bot API doesn't provide
|
||||||
// nested replyToMessage, so currently the trusted check by
|
// nested replyToMessage, so currently the trusted check by
|
||||||
// replyToMessage.replyToMessage will not work!
|
// replyToMessage.replyToMessage will not work!
|
||||||
def _isReplyTrusted: Boolean =
|
def _isReplyTrusted: Boolean =
|
||||||
if (event.message.replyToMessage.replyToMessage == null) false
|
if (event.message.replyToMessage.replyToMessage == null) false
|
||||||
else if (event.message.replyToMessage.replyToMessage.from.id == event.message.from.id) true
|
else if (event.message.replyToMessage.replyToMessage.from.id == event.message.from.id) true
|
||||||
@ -36,19 +36,19 @@ object DirectMsgClear extends ISimpleCommand {
|
|||||||
|
|
||||||
if (isTrusted || _isReplyTrusted) {
|
if (isTrusted || _isReplyTrusted) {
|
||||||
|
|
||||||
MornyCoeur.extra exec DeleteMessage(
|
coeur.extra exec DeleteMessage(
|
||||||
event.message.chat.id, event.message.replyToMessage.messageId
|
event.message.chat.id, event.message.replyToMessage.messageId
|
||||||
)
|
)
|
||||||
|
|
||||||
def _isPrivate: Boolean = event.message.chat.`type` == Chat.Type.Private
|
def _isPrivate: Boolean = event.message.chat.`type` == Chat.Type.Private
|
||||||
def _isPermission: Boolean =
|
def _isPermission: Boolean =
|
||||||
(MornyCoeur.extra exec GetChatMember(event.message.chat.id, event.message.from.id))
|
(coeur.extra exec GetChatMember(event.message.chat.id, event.message.from.id))
|
||||||
.chatMember.canDeleteMessages
|
.chatMember.canDeleteMessages
|
||||||
if (_isPrivate || _isPermission) {
|
if (_isPrivate || _isPermission) {
|
||||||
MornyCoeur.extra exec DeleteMessage(event.message.chat.id, event.message.messageId)
|
coeur.extra exec DeleteMessage(event.message.chat.id, event.message.messageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else MornyCoeur.extra exec SendSticker(
|
} else coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_403
|
TelegramStickers ID_403
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
|
@ -2,7 +2,6 @@ package cc.sukazyo.cono.morny.bot.command
|
|||||||
|
|
||||||
import cc.sukazyo.cono.morny.Log.logger
|
import cc.sukazyo.cono.morny.Log.logger
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import cc.sukazyo.cono.morny.daemon.MornyReport
|
|
||||||
import cc.sukazyo.cono.morny.data.TelegramStickers
|
import cc.sukazyo.cono.morny.data.TelegramStickers
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import cc.sukazyo.cono.morny.util.CommonEncrypt
|
import cc.sukazyo.cono.morny.util.CommonEncrypt
|
||||||
@ -17,7 +16,7 @@ import java.util.Base64
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
/** Provides Telegram Command __`/encrypt`__. */
|
/** Provides Telegram Command __`/encrypt`__. */
|
||||||
object Encryptor extends ITelegramCommand {
|
class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
|
|
||||||
override val name: String = "encrypt"
|
override val name: String = "encrypt"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
@ -48,7 +47,7 @@ object Encryptor extends ITelegramCommand {
|
|||||||
val mod_uppercase = if (args.length > 1) {
|
val mod_uppercase = if (args.length > 1) {
|
||||||
if (args.length < 3 && _is_mod_u(args(1))) true
|
if (args.length < 3 && _is_mod_u(args(1))) true
|
||||||
else
|
else
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_404
|
TelegramStickers ID_404
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -74,11 +73,11 @@ object Encryptor extends ITelegramCommand {
|
|||||||
val _r = event.message.replyToMessage
|
val _r = event.message.replyToMessage
|
||||||
if ((_r ne null) && (_r.document ne null)) {
|
if ((_r ne null) && (_r.document ne null)) {
|
||||||
try {XFile(
|
try {XFile(
|
||||||
MornyCoeur.account getFileContent (MornyCoeur.extra exec GetFile(_r.document.fileId)).file,
|
coeur.account getFileContent (coeur.extra exec GetFile(_r.document.fileId)).file,
|
||||||
_r.document.fileName
|
_r.document.fileName
|
||||||
)} catch case e: IOException =>
|
)} catch case e: IOException =>
|
||||||
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
|
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
|
||||||
MornyReport.exception(e, "NetworkRequest error: TelegramFileAPI")
|
coeur.daemons.reporter.exception(e, "NetworkRequest error: TelegramFileAPI")
|
||||||
return
|
return
|
||||||
} else if ((_r ne null) && (_r.photo ne null)) {
|
} else if ((_r ne null) && (_r.photo ne null)) {
|
||||||
try {
|
try {
|
||||||
@ -92,22 +91,23 @@ object Encryptor extends ITelegramCommand {
|
|||||||
if (_photo_origin eq null) throw IllegalArgumentException("no photo from api.")
|
if (_photo_origin eq null) throw IllegalArgumentException("no photo from api.")
|
||||||
import cc.sukazyo.cono.morny.util.UseRandom.rand_id
|
import cc.sukazyo.cono.morny.util.UseRandom.rand_id
|
||||||
XFile(
|
XFile(
|
||||||
MornyCoeur.account getFileContent (MornyCoeur.extra exec GetFile(_photo_origin.fileId)).file,
|
coeur.account getFileContent (coeur.extra exec GetFile(_photo_origin.fileId)).file,
|
||||||
s"photo$rand_id.png"
|
s"photo$rand_id.png"
|
||||||
)
|
)
|
||||||
} catch
|
} catch
|
||||||
case e: IOException =>
|
case e: IOException =>
|
||||||
|
//noinspection DuplicatedCode
|
||||||
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
|
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
|
||||||
MornyReport.exception(e, "NetworkRequest error: TelegramFileAPI")
|
coeur.daemons.reporter.exception(e, "NetworkRequest error: TelegramFileAPI")
|
||||||
return
|
return
|
||||||
case e: IllegalArgumentException =>
|
case e: IllegalArgumentException =>
|
||||||
logger warn s"FileProcess error: PhotoSize:\n\t${e.getMessage}"
|
logger warn s"FileProcess error: PhotoSize:\n\t${e.getMessage}"
|
||||||
MornyReport.exception(e, "FileProcess error: PhotoSize")
|
coeur.daemons.reporter.exception(e, "FileProcess error: PhotoSize")
|
||||||
return
|
return
|
||||||
} else if ((_r ne null) && (_r.text ne null)) {
|
} else if ((_r ne null) && (_r.text ne null)) {
|
||||||
XText(_r.text)
|
XText(_r.text)
|
||||||
} else {
|
} else {
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
"<i><u>null</u></i>"
|
"<i><u>null</u></i>"
|
||||||
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
||||||
@ -153,7 +153,7 @@ object Encryptor extends ITelegramCommand {
|
|||||||
_tool_b64d.decode,
|
_tool_b64d.decode,
|
||||||
CommonEncrypt.lint_base64FileName
|
CommonEncrypt.lint_base64FileName
|
||||||
) } catch case _: IllegalArgumentException =>
|
) } catch case _: IllegalArgumentException =>
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_404 // todo: is here better erro notify?
|
TelegramStickers ID_404 // todo: is here better erro notify?
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -163,7 +163,7 @@ object Encryptor extends ITelegramCommand {
|
|||||||
case "sha256" => genResult_hash(input, SHA256)
|
case "sha256" => genResult_hash(input, SHA256)
|
||||||
case "sha512" => genResult_hash(input, SHA512)
|
case "sha512" => genResult_hash(input, SHA512)
|
||||||
case _ =>
|
case _ =>
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_404
|
TelegramStickers ID_404
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -173,13 +173,13 @@ object Encryptor extends ITelegramCommand {
|
|||||||
// output
|
// output
|
||||||
result match
|
result match
|
||||||
case _file: EXFile =>
|
case _file: EXFile =>
|
||||||
MornyCoeur.extra exec SendDocument(
|
coeur.extra exec SendDocument(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
_file.result
|
_file.result
|
||||||
).fileName(_file.resultName).replyToMessageId(event.message.messageId)
|
).fileName(_file.resultName).replyToMessageId(event.message.messageId)
|
||||||
case _text: EXTextLike =>
|
case _text: EXTextLike =>
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
s"<pre><code>${h(_text.text)}</code></pre>"
|
s"<pre><code>${h(_text.text)}</code></pre>"
|
||||||
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
||||||
@ -211,7 +211,7 @@ object Encryptor extends ITelegramCommand {
|
|||||||
* </blockquote>
|
* </blockquote>
|
||||||
*/
|
*/
|
||||||
private def echoHelp(chat: Long, replyTo: Int): Unit =
|
private def echoHelp(chat: Long, replyTo: Int): Unit =
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
chat,
|
chat,
|
||||||
s"""<b><u>base64</u></b>, b64
|
s"""<b><u>base64</u></b>, b64
|
||||||
|<b><u>base64url</u></b>, base64u, b64u
|
|<b><u>base64url</u></b>, base64u, b64u
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.command
|
package cc.sukazyo.cono.morny.bot.command
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import cc.sukazyo.cono.morny.bot.event.OnEventHackHandle
|
|
||||||
import cc.sukazyo.cono.morny.bot.event.OnEventHackHandle.{registerHack, HackType}
|
|
||||||
import cc.sukazyo.cono.morny.data.TelegramStickers
|
import cc.sukazyo.cono.morny.data.TelegramStickers
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
@ -9,7 +7,7 @@ import com.pengrad.telegrambot.request.SendSticker
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object EventHack extends ITelegramCommand {
|
class EventHack (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
|
|
||||||
override val name: String = "event_hack"
|
override val name: String = "event_hack"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
@ -18,15 +16,17 @@ object EventHack extends ITelegramCommand {
|
|||||||
|
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = {
|
override def execute (using command: InputCommand, event: Update): Unit = {
|
||||||
|
|
||||||
|
import coeur.daemons.eventHack.{registerHack, HackType}
|
||||||
|
|
||||||
val x_mode = if (command.args nonEmpty) command.args(0) else ""
|
val x_mode = if (command.args nonEmpty) command.args(0) else ""
|
||||||
|
|
||||||
def done_ok =
|
def done_ok =
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_WAITING
|
TelegramStickers ID_WAITING
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
def done_forbiddenForAny =
|
def done_forbiddenForAny =
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_403
|
TelegramStickers ID_403
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -40,7 +40,7 @@ object EventHack extends ITelegramCommand {
|
|||||||
)
|
)
|
||||||
x_mode match
|
x_mode match
|
||||||
case "any" =>
|
case "any" =>
|
||||||
if (MornyCoeur.trusted isTrusted event.message.from.id)
|
if (coeur.trusted isTrusted event.message.from.id)
|
||||||
doRegister(HackType ANY)
|
doRegister(HackType ANY)
|
||||||
done_ok
|
done_ok
|
||||||
else done_forbiddenForAny
|
else done_forbiddenForAny
|
||||||
|
@ -9,7 +9,7 @@ import com.pengrad.telegrambot.request.{GetChatMember, SendMessage}
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object GetUsernameAndId extends ITelegramCommand {
|
class GetUsernameAndId (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
|
|
||||||
override val name: String = "user"
|
override val name: String = "user"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
@ -21,7 +21,7 @@ object GetUsernameAndId extends ITelegramCommand {
|
|||||||
val args = command.args
|
val args = command.args
|
||||||
|
|
||||||
if (args.length > 1)
|
if (args.length > 1)
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
"[Unavailable] Too much arguments."
|
"[Unavailable] Too much arguments."
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -31,7 +31,7 @@ object GetUsernameAndId extends ITelegramCommand {
|
|||||||
if (args nonEmpty) {
|
if (args nonEmpty) {
|
||||||
try args(0) toLong
|
try args(0) toLong
|
||||||
catch case e: NumberFormatException =>
|
catch case e: NumberFormatException =>
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
s"[Unavailable] ${e.getMessage}"
|
s"[Unavailable] ${e.getMessage}"
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -39,10 +39,10 @@ object GetUsernameAndId extends ITelegramCommand {
|
|||||||
} else if (event.message.replyToMessage eq null) event.message.from.id
|
} else if (event.message.replyToMessage eq null) event.message.from.id
|
||||||
else event.message.replyToMessage.from.id
|
else event.message.replyToMessage.from.id
|
||||||
|
|
||||||
val response = MornyCoeur.account execute GetChatMember(event.message.chat.id, userId)
|
val response = coeur.account execute GetChatMember(event.message.chat.id, userId)
|
||||||
|
|
||||||
if (response.chatMember eq null)
|
if (response.chatMember eq null)
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
"[Unavailable] user not found."
|
"[Unavailable] user not found."
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -51,13 +51,13 @@ object GetUsernameAndId extends ITelegramCommand {
|
|||||||
val user = response.chatMember.user
|
val user = response.chatMember.user
|
||||||
|
|
||||||
if (user.id == Standardize.CHANNEL_SPEAKER_MAGIC_ID)
|
if (user.id == Standardize.CHANNEL_SPEAKER_MAGIC_ID)
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
"<code>$__channel_identify</code>"
|
"<code>$__channel_identify</code>"
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramUserInformation getFormattedInformation user
|
TelegramUserInformation getFormattedInformation user
|
||||||
).replyToMessageId(event.message.messageId()).parseMode(ParseMode HTML)
|
).replyToMessageId(event.message.messageId()).parseMode(ParseMode HTML)
|
||||||
|
@ -9,7 +9,7 @@ import com.pengrad.telegrambot.request.SendMessage
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object IP186Query {
|
class IP186Query (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
private enum Subs (val cmd: String):
|
private enum Subs (val cmd: String):
|
||||||
case IP extends Subs("ip")
|
case IP extends Subs("ip")
|
||||||
@ -34,7 +34,7 @@ object IP186Query {
|
|||||||
if (command.args isEmpty)
|
if (command.args isEmpty)
|
||||||
if event.message.replyToMessage eq null then null else event.message.replyToMessage.text
|
if event.message.replyToMessage eq null then null else event.message.replyToMessage.text
|
||||||
else if (command.args.length > 1)
|
else if (command.args.length > 1)
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
"[Unavailable] Too much arguments."
|
"[Unavailable] Too much arguments."
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -42,7 +42,7 @@ object IP186Query {
|
|||||||
else command.args(0)
|
else command.args(0)
|
||||||
|
|
||||||
if (target eq null)
|
if (target eq null)
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
"[Unavailable] No ip defined."
|
"[Unavailable] No ip defined."
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -57,7 +57,7 @@ object IP186Query {
|
|||||||
case Subs.WHOIS.cmd => IP186QueryHandler.query_whoisPretty(target)
|
case Subs.WHOIS.cmd => IP186QueryHandler.query_whoisPretty(target)
|
||||||
case _ => throw IllegalArgumentException(s"Unknown 186-IP query method ${command.command}")
|
case _ => throw IllegalArgumentException(s"Unknown 186-IP query method ${command.command}")
|
||||||
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
s"""${h(response.url)}
|
s"""${h(response.url)}
|
||||||
|<code>${h(response.body)}</code>"""
|
|<code>${h(response.body)}</code>"""
|
||||||
@ -65,7 +65,7 @@ object IP186Query {
|
|||||||
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
||||||
|
|
||||||
} catch case e: Exception =>
|
} catch case e: Exception =>
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
s"""[Exception] in query:
|
s"""[Exception] in query:
|
||||||
|<code>${h(e.getMessage)}</code>"""
|
|<code>${h(e.getMessage)}</code>"""
|
||||||
|
@ -11,7 +11,7 @@ import scala.collection.{mutable, SeqMap}
|
|||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object MornyCommands {
|
class MornyCommands (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
private type CommandMap = SeqMap[String, ISimpleCommand]
|
private type CommandMap = SeqMap[String, ISimpleCommand]
|
||||||
private def CommandMap (commands: ISimpleCommand*): CommandMap =
|
private def CommandMap (commands: ISimpleCommand*): CommandMap =
|
||||||
@ -22,41 +22,47 @@ object MornyCommands {
|
|||||||
stash += (alias.name -> i)
|
stash += (alias.name -> i)
|
||||||
stash
|
stash
|
||||||
|
|
||||||
|
private val $MornyHellos = MornyHellos()
|
||||||
|
private val $IP186Query = IP186Query()
|
||||||
|
private val $MornyInformation = MornyInformation()
|
||||||
|
private val $MornyInformationOlds = MornyInformationOlds(using $MornyInformation)
|
||||||
|
private val $MornyManagers = MornyManagers()
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
private val $喵呜 = 喵呜()
|
||||||
private val commands: CommandMap = CommandMap(
|
private val commands: CommandMap = CommandMap(
|
||||||
|
|
||||||
MornyHellos.On,
|
$MornyHellos.On,
|
||||||
MornyHellos.On,
|
$MornyHellos.Hello,
|
||||||
MornyHellos.Hello,
|
MornyInfoOnStart(),
|
||||||
MornyInfoOnStart,
|
GetUsernameAndId(),
|
||||||
GetUsernameAndId,
|
EventHack(),
|
||||||
EventHack,
|
Nbnhhsh(),
|
||||||
Nbnhhsh,
|
$IP186Query.IP,
|
||||||
IP186Query.IP,
|
$IP186Query.Whois,
|
||||||
IP186Query.Whois,
|
Encryptor(),
|
||||||
Encryptor,
|
$MornyManagers.SaveData,
|
||||||
MornyManagers.SaveData,
|
$MornyInformation,
|
||||||
MornyInformation,
|
$MornyInformationOlds.Version,
|
||||||
MornyInformationOlds.Version,
|
$MornyInformationOlds.Runtime,
|
||||||
MornyInformationOlds.Runtime,
|
MornyOldJrrp(),
|
||||||
MornyOldJrrp,
|
$MornyManagers.Exit,
|
||||||
MornyManagers.Exit,
|
|
||||||
|
|
||||||
Testing,
|
Testing(),
|
||||||
DirectMsgClear,
|
DirectMsgClear(),
|
||||||
|
|
||||||
//noinspection NonAsciiCharacters
|
//noinspection NonAsciiCharacters
|
||||||
私わね,
|
私わね(),
|
||||||
//noinspection NonAsciiCharacters
|
//noinspection NonAsciiCharacters
|
||||||
喵呜.Progynova
|
$喵呜.Progynova
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//noinspection NonAsciiCharacters
|
//noinspection NonAsciiCharacters
|
||||||
val commands_uni: CommandMap = CommandMap(
|
val commands_uni: CommandMap = CommandMap(
|
||||||
喵呜.抱抱,
|
$喵呜.抱抱,
|
||||||
喵呜.揉揉,
|
$喵呜.揉揉,
|
||||||
喵呜.贴贴,
|
$喵呜.贴贴,
|
||||||
喵呜.蹭蹭
|
$喵呜.蹭蹭
|
||||||
)
|
)
|
||||||
|
|
||||||
def execute (using command: InputCommand, event: Update): Boolean = {
|
def execute (using command: InputCommand, event: Update): Boolean = {
|
||||||
@ -69,7 +75,7 @@ object MornyCommands {
|
|||||||
private def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = {
|
private def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = {
|
||||||
if command.target eq null then false
|
if command.target eq null then false
|
||||||
else
|
else
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_404
|
TelegramStickers ID_404
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -79,14 +85,14 @@ object MornyCommands {
|
|||||||
def automaticTGListUpdate (): Unit = {
|
def automaticTGListUpdate (): Unit = {
|
||||||
val listing = commands_toTelegramList
|
val listing = commands_toTelegramList
|
||||||
automaticTGListRemove()
|
automaticTGListRemove()
|
||||||
MornyCoeur.extra exec SetMyCommands(listing:_*)
|
coeur.extra exec SetMyCommands(listing:_*)
|
||||||
logger info
|
logger info
|
||||||
s"""automatic updated telegram command list :
|
s"""automatic updated telegram command list :
|
||||||
|${commandsTelegramList_toString(listing)}""".stripMargin
|
|${commandsTelegramList_toString(listing)}""".stripMargin
|
||||||
}
|
}
|
||||||
|
|
||||||
def automaticTGListRemove (): Unit = {
|
def automaticTGListRemove (): Unit = {
|
||||||
MornyCoeur.extra exec DeleteMyCommands()
|
coeur.extra exec DeleteMyCommands()
|
||||||
logger info "cleaned up command list"
|
logger info "cleaned up command list"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import com.pengrad.telegrambot.request.SendSticker
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object MornyHellos {
|
class MornyHellos (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
object On extends ITelegramCommand {
|
object On extends ITelegramCommand {
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ object MornyHellos {
|
|||||||
override val description: String = "检查是否在线"
|
override val description: String = "检查是否在线"
|
||||||
|
|
||||||
override def execute (using command: InputCommand, event: Update): Unit =
|
override def execute (using command: InputCommand, event: Update): Unit =
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_ONLINE_STATUS_RETURN
|
TelegramStickers ID_ONLINE_STATUS_RETURN
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -33,7 +33,7 @@ object MornyHellos {
|
|||||||
override val description: String = "打招呼"
|
override val description: String = "打招呼"
|
||||||
|
|
||||||
override def execute (using command: InputCommand, event: Update): Unit =
|
override def execute (using command: InputCommand, event: Update): Unit =
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_HELLO
|
TelegramStickers ID_HELLO
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.command
|
package cc.sukazyo.cono.morny.bot.command
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
import cc.sukazyo.cono.morny.data.MornyInformation.{getAboutPic, getMornyAboutLinksHTML}
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
import com.pengrad.telegrambot.model.request.ParseMode
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
@ -8,22 +9,22 @@ import com.pengrad.telegrambot.request.SendPhoto
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object MornyInfoOnStart extends ISimpleCommand {
|
class MornyInfoOnStart (using coeur: MornyCoeur) extends ISimpleCommand {
|
||||||
|
|
||||||
override val name: String = "start"
|
override val name: String = "start"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
|
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = {
|
override def execute (using command: InputCommand, event: Update): Unit = {
|
||||||
|
|
||||||
MornyCoeur.extra exec new SendPhoto(
|
coeur.extra exec new SendPhoto(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
MornyInformation.getAboutPic
|
getAboutPic
|
||||||
).caption(
|
).caption(
|
||||||
s"""欢迎使用 <b>Morny Cono</b>,<i>来自安妮的侍从小鼠</i>。
|
s"""欢迎使用 <b>Morny Cono</b>,<i>来自安妮的侍从小鼠</i>。
|
||||||
|Morny 具有各种各样的功能。
|
|Morny 具有各种各样的功能。
|
||||||
|
|
|
|
||||||
|————————————————
|
|————————————————
|
||||||
|${MornyInformation.getMornyAboutLinksHTML}
|
|$getMornyAboutLinksHTML
|
||||||
|————————————————
|
|————————————————
|
||||||
|
|
|
|
||||||
|(你可以随时通过 /info 重新获得这些信息)"""
|
|(你可以随时通过 /info 重新获得这些信息)"""
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.command
|
package cc.sukazyo.cono.morny.bot.command
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.{BuildConfig, MornyAbout, MornyCoeur, MornySystem}
|
import cc.sukazyo.cono.morny.{BuildConfig, MornyCoeur, MornySystem}
|
||||||
import cc.sukazyo.cono.morny.data.{TelegramImages, TelegramStickers}
|
import cc.sukazyo.cono.morny.data.MornyInformation.*
|
||||||
|
import cc.sukazyo.cono.morny.data.TelegramStickers
|
||||||
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
|
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
@ -10,12 +11,10 @@ import com.pengrad.telegrambot.model.request.ParseMode
|
|||||||
import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker}
|
import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker}
|
||||||
|
|
||||||
import java.lang.System
|
import java.lang.System
|
||||||
import java.net.InetAddress
|
|
||||||
import java.rmi.UnknownHostException
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
// todo: maybe move some utils method outside
|
// todo: maybe move some utils method outside
|
||||||
object MornyInformation extends ITelegramCommand {
|
class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
|
|
||||||
private case object Subs {
|
private case object Subs {
|
||||||
val STICKERS = "stickers"
|
val STICKERS = "stickers"
|
||||||
@ -47,43 +46,8 @@ object MornyInformation extends ITelegramCommand {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection ScalaWeakerAccess
|
|
||||||
def getVersionGitTagHTML: String = {
|
|
||||||
if (!MornySystem.isGitBuild) return ""
|
|
||||||
val g = StringBuilder()
|
|
||||||
val cm = BuildConfig.COMMIT substring(0, 8)
|
|
||||||
val cp = MornySystem.currentCodePath
|
|
||||||
if (cp == null) g++= s"<code>$cm</code>"
|
|
||||||
else g++= s"<a href='$cp'>$cm</a>"
|
|
||||||
if (!MornySystem.isCleanBuild) g++= ".<code>δ</code>"
|
|
||||||
g toString
|
|
||||||
}
|
|
||||||
|
|
||||||
def getVersionAllFullTagHTML: String = {
|
|
||||||
val v = StringBuilder()
|
|
||||||
v ++= s"<code>${MornySystem VERSION_BASE}</code>"
|
|
||||||
if (MornySystem isUseDelta) v++=s"-δ<code>${MornySystem VERSION_DELTA}</code>"
|
|
||||||
if (MornySystem isGitBuild) v++="+git."++=getVersionGitTagHTML
|
|
||||||
v ++= s"*<code>${MornySystem.CODENAME toUpperCase}</code>"
|
|
||||||
v toString
|
|
||||||
}
|
|
||||||
|
|
||||||
//noinspection ScalaWeakerAccess
|
|
||||||
def getRuntimeHostname: String|Null = {
|
|
||||||
try InetAddress.getLocalHost.getHostName
|
|
||||||
catch case _:UnknownHostException => null
|
|
||||||
}
|
|
||||||
|
|
||||||
def getAboutPic: Array[Byte] = TelegramImages.IMG_ABOUT get
|
|
||||||
|
|
||||||
def getMornyAboutLinksHTML: String =
|
|
||||||
s"""<a href='${MornyAbout MORNY_SOURCECODE_LINK}'>source code</a> | <a href='${MornyAbout MORNY_SOURCECODE_SELF_HOSTED_MIRROR_LINK}'>backup</a>
|
|
||||||
|<a href='${MornyAbout MORNY_ISSUE_TRACKER_LINK}'>反馈 / issue tracker</a>
|
|
||||||
|<a href='${MornyAbout MORNY_USER_GUIDE_LINK}'>使用说明书 / user guide & docs</a>"""
|
|
||||||
.stripMargin
|
|
||||||
|
|
||||||
private def echoInfo (chatId: Long, replyTo: Int): Unit = {
|
private def echoInfo (chatId: Long, replyTo: Int): Unit = {
|
||||||
MornyCoeur.extra exec new SendPhoto(
|
coeur.extra exec new SendPhoto(
|
||||||
chatId,
|
chatId,
|
||||||
getAboutPic
|
getAboutPic
|
||||||
).caption(
|
).caption(
|
||||||
@ -128,15 +92,15 @@ object MornyInformation extends ITelegramCommand {
|
|||||||
val send_mid = SendMessage(send_chat, mid)
|
val send_mid = SendMessage(send_chat, mid)
|
||||||
val send_sticker = SendSticker(send_chat, file_id)
|
val send_sticker = SendSticker(send_chat, file_id)
|
||||||
if (send_replyTo != -1) send_mid.replyToMessageId(send_replyTo)
|
if (send_replyTo != -1) send_mid.replyToMessageId(send_replyTo)
|
||||||
val result_send_mid = MornyCoeur.extra exec send_mid
|
val result_send_mid = coeur.extra exec send_mid
|
||||||
send_sticker.replyToMessageId(result_send_mid.message.messageId)
|
send_sticker.replyToMessageId(result_send_mid.message.messageId)
|
||||||
MornyCoeur.extra exec send_sticker
|
coeur.extra exec send_sticker
|
||||||
}
|
}
|
||||||
|
|
||||||
private[command] def echoVersion (using event: Update): Unit = {
|
private[command] def echoVersion (using event: Update): Unit = {
|
||||||
val versionDeltaHTML = if (MornySystem.isUseDelta) s"-δ<code>${h(MornySystem.VERSION_DELTA)}</code>" else ""
|
val versionDeltaHTML = if (MornySystem.isUseDelta) s"-δ<code>${h(MornySystem.VERSION_DELTA)}</code>" else ""
|
||||||
val versionGitHTML = if (MornySystem.isGitBuild) s"git $getVersionGitTagHTML" else ""
|
val versionGitHTML = if (MornySystem.isGitBuild) s"git $getVersionGitTagHTML" else ""
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
s"""version:
|
s"""version:
|
||||||
@ -153,7 +117,7 @@ object MornyInformation extends ITelegramCommand {
|
|||||||
|
|
||||||
private[command] def echoRuntime (using event: Update): Unit = {
|
private[command] def echoRuntime (using event: Update): Unit = {
|
||||||
def sysprop (p: String): String = System.getProperty(p)
|
def sysprop (p: String): String = System.getProperty(p)
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
/* language=html */
|
/* language=html */
|
||||||
s"""system:
|
s"""system:
|
||||||
@ -171,16 +135,16 @@ object MornyInformation extends ITelegramCommand {
|
|||||||
|- <code>${h(formatDate(BuildConfig.CODE_TIMESTAMP, 0))} [UTC]</code>
|
|- <code>${h(formatDate(BuildConfig.CODE_TIMESTAMP, 0))} [UTC]</code>
|
||||||
|- [<code>${BuildConfig.CODE_TIMESTAMP}</code>]
|
|- [<code>${BuildConfig.CODE_TIMESTAMP}</code>]
|
||||||
|continuous:
|
|continuous:
|
||||||
|- <code>${h(formatDuration(System.currentTimeMillis - MornyCoeur.coeurStartTimestamp))}</code>
|
|- <code>${h(formatDuration(System.currentTimeMillis - coeur.coeurStartTimestamp))}</code>
|
||||||
|- [<code>${System.currentTimeMillis - MornyCoeur.coeurStartTimestamp}</code>]
|
|- [<code>${System.currentTimeMillis - coeur.coeurStartTimestamp}</code>]
|
||||||
|- <code>${h(formatDate(MornyCoeur.coeurStartTimestamp, 0))}</code>
|
|- <code>${h(formatDate(coeur.coeurStartTimestamp, 0))}</code>
|
||||||
|- [<code>${MornyCoeur.coeurStartTimestamp}</code>]"""
|
|- [<code>${coeur.coeurStartTimestamp}</code>]"""
|
||||||
.stripMargin
|
.stripMargin
|
||||||
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def echo404 (using event: Update): Unit =
|
private def echo404 (using event: Update): Unit =
|
||||||
MornyCoeur.extra exec new SendSticker(
|
coeur.extra exec new SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_404
|
TelegramStickers ID_404
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
|
@ -3,16 +3,16 @@ package cc.sukazyo.cono.morny.bot.command
|
|||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
object MornyInformationOlds {
|
class MornyInformationOlds (using base: MornyInformation) {
|
||||||
|
|
||||||
object Version extends ISimpleCommand:
|
object Version extends ISimpleCommand:
|
||||||
override val name: String = "version"
|
override val name: String = "version"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = MornyInformation.echoVersion
|
override def execute (using command: InputCommand, event: Update): Unit = base.echoVersion
|
||||||
|
|
||||||
object Runtime extends ISimpleCommand:
|
object Runtime extends ISimpleCommand:
|
||||||
override val name: String = "runtime"
|
override val name: String = "runtime"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = MornyInformation.echoRuntime
|
override def execute (using command: InputCommand, event: Update): Unit = base.echoRuntime
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.pengrad.telegrambot.request.SendSticker
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object MornyManagers {
|
class MornyManagers (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
object Exit extends ITelegramCommand {
|
object Exit extends ITelegramCommand {
|
||||||
|
|
||||||
@ -24,23 +24,23 @@ object MornyManagers {
|
|||||||
|
|
||||||
val user = event.message.from
|
val user = event.message.from
|
||||||
|
|
||||||
if (MornyCoeur.trusted isTrusted user.id) {
|
if (coeur.trusted isTrusted user.id) {
|
||||||
|
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_EXIT
|
TelegramStickers ID_EXIT
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
logger info s"Morny exited by user ${user toLogTag}"
|
logger info s"Morny exited by user ${user toLogTag}"
|
||||||
MornyCoeur.exit(0, user)
|
coeur.exit(0, user)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_403
|
TelegramStickers ID_403
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
logger info s"403 exit caught from user ${user toLogTag}"
|
logger info s"403 exit caught from user ${user toLogTag}"
|
||||||
MornyReport.unauthenticatedAction("/exit", user)
|
coeur.daemons.reporter.unauthenticatedAction("/exit", user)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,23 +59,23 @@ object MornyManagers {
|
|||||||
|
|
||||||
val user = event.message.from
|
val user = event.message.from
|
||||||
|
|
||||||
if (MornyCoeur.trusted isTrusted user.id) {
|
if (coeur.trusted isTrusted user.id) {
|
||||||
|
|
||||||
logger info s"call save from command by ${user toLogTag}"
|
logger info s"call save from command by ${user toLogTag}"
|
||||||
MornyCoeur.callSaveData()
|
coeur.saveDataAll()
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_SAVED
|
TelegramStickers ID_SAVED
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_403
|
TelegramStickers ID_403
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
logger info s"403 save caught from user ${user toLogTag}"
|
logger info s"403 save caught from user ${user toLogTag}"
|
||||||
MornyReport.unauthenticatedAction("/save", user)
|
coeur.daemons.reporter.unauthenticatedAction("/save", user)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@ import com.pengrad.telegrambot.model.Update
|
|||||||
import com.pengrad.telegrambot.model.request.ParseMode
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
import com.pengrad.telegrambot.request.SendMessage
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
import scala.language.postfixOps
|
class MornyOldJrrp (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
object MornyOldJrrp extends ITelegramCommand {
|
|
||||||
|
|
||||||
override val name: String = "jrrp"
|
override val name: String = "jrrp"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
@ -25,7 +24,7 @@ object MornyOldJrrp extends ITelegramCommand {
|
|||||||
case _ => "..."
|
case _ => "..."
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
f"${user.fullnameRefHTML} 在(utc的)今天的运气指数是———— <code>$jrrp%.2f%%</code> ${h(ending)}"
|
f"${user.fullnameRefHTML} 在(utc的)今天的运气指数是———— <code>$jrrp%.2f%%</code> ${h(ending)}"
|
||||||
|
@ -11,7 +11,7 @@ import com.pengrad.telegrambot.request.{SendMessage, SendSticker}
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object Nbnhhsh extends ITelegramCommand {
|
class Nbnhhsh (using coeur: MornyCoeur) extends ITelegramCommand {
|
||||||
|
|
||||||
private val NBNHHSH_RESULT_HEAD_HTML =
|
private val NBNHHSH_RESULT_HEAD_HTML =
|
||||||
// language=html
|
// language=html
|
||||||
@ -32,7 +32,7 @@ object Nbnhhsh extends ITelegramCommand {
|
|||||||
else null
|
else null
|
||||||
|
|
||||||
if (queryTarget == null)
|
if (queryTarget == null)
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_404
|
TelegramStickers ID_404
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -67,13 +67,13 @@ object Nbnhhsh extends ITelegramCommand {
|
|||||||
logger debug s"**exec as ${_word.name}"
|
logger debug s"**exec as ${_word.name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
message toString
|
message toString
|
||||||
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(event.message.messageId)
|
||||||
|
|
||||||
} catch case e: IOException => {
|
} catch case e: IOException => {
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
s"""[Exception] in query:
|
s"""[Exception] in query:
|
||||||
|${h(e.getMessage)}
|
|${h(e.getMessage)}
|
||||||
|
@ -6,18 +6,17 @@ import com.pengrad.telegrambot.model.Update
|
|||||||
import com.pengrad.telegrambot.model.request.ParseMode
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
import com.pengrad.telegrambot.request.SendMessage
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
import javax.annotation.Nonnull
|
import javax.annotation.{Nonnull, Nullable}
|
||||||
import javax.annotation.Nullable
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object Testing extends ISimpleCommand {
|
class Testing (using coeur: MornyCoeur) extends ISimpleCommand {
|
||||||
|
|
||||||
override val name: String = "test"
|
override val name: String = "test"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
|
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = {
|
override def execute (using command: InputCommand, event: Update): Unit = {
|
||||||
|
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
"<b>Just</b> a TEST command."
|
"<b>Just</b> a TEST command."
|
||||||
|
@ -12,7 +12,7 @@ import scala.annotation.unused
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
//noinspection NonAsciiCharacters
|
//noinspection NonAsciiCharacters
|
||||||
object 喵呜 {
|
class 喵呜 (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
object 抱抱 extends ISimpleCommand {
|
object 抱抱 extends ISimpleCommand {
|
||||||
override val name: String = "抱抱"
|
override val name: String = "抱抱"
|
||||||
@ -48,7 +48,7 @@ object 喵呜 {
|
|||||||
override val paramRule: String = ""
|
override val paramRule: String = ""
|
||||||
override val description: String = "抽取一个神秘盒子"
|
override val description: String = "抽取一个神秘盒子"
|
||||||
override def execute (using command: InputCommand, event: Update): Unit = {
|
override def execute (using command: InputCommand, event: Update): Unit = {
|
||||||
MornyCoeur.extra exec new SendSticker(
|
coeur.extra exec new SendSticker(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
TelegramStickers ID_PROGYNOVA
|
TelegramStickers ID_PROGYNOVA
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
@ -58,7 +58,7 @@ object 喵呜 {
|
|||||||
private def replyingSet (whileRec: String, whileNew: String)(using event: Update): Unit = {
|
private def replyingSet (whileRec: String, whileNew: String)(using event: Update): Unit = {
|
||||||
val isNew = event.message.replyToMessage == null
|
val isNew = event.message.replyToMessage == null
|
||||||
val target = if (isNew) event.message else event.message.replyToMessage
|
val target = if (isNew) event.message else event.message.replyToMessage
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
if (isNew) whileNew else whileRec
|
if (isNew) whileNew else whileRec
|
||||||
).replyToMessageId(target.messageId).parseMode(ParseMode HTML)
|
).replyToMessageId(target.messageId).parseMode(ParseMode HTML)
|
||||||
|
@ -8,7 +8,7 @@ import com.pengrad.telegrambot.model.Update
|
|||||||
import com.pengrad.telegrambot.request.SendMessage
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
//noinspection NonAsciiCharacters
|
//noinspection NonAsciiCharacters
|
||||||
object 私わね extends ISimpleCommand {
|
class 私わね (using coeur: MornyCoeur) extends ISimpleCommand {
|
||||||
|
|
||||||
override val name: String = "me"
|
override val name: String = "me"
|
||||||
override val aliases: Array[ICommandAlias] | Null = null
|
override val aliases: Array[ICommandAlias] | Null = null
|
||||||
@ -17,7 +17,7 @@ object 私わね extends ISimpleCommand {
|
|||||||
|
|
||||||
if ((1 over 521) chance_is true) {
|
if ((1 over 521) chance_is true) {
|
||||||
val text = "/打假"
|
val text = "/打假"
|
||||||
MornyCoeur.extra exec new SendMessage(
|
coeur.extra exec new SendMessage(
|
||||||
event.message.chat.id,
|
event.message.chat.id,
|
||||||
text
|
text
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.event
|
package cc.sukazyo.cono.morny.bot.event
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListenerManager
|
import cc.sukazyo.cono.morny.bot.api.EventListenerManager
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
|
||||||
object MornyEventListeners {
|
class MornyEventListeners (using manager: EventListenerManager) (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
def registerAllEvents(): Unit = {
|
manager.register(
|
||||||
|
// ACTIVITY_RECORDER
|
||||||
EventListenerManager.register(
|
// KUOHUANHUAN_NEED_SLEEP
|
||||||
// ACTIVITY_RECORDER
|
OnUniMeowTrigger(using coeur.commands),
|
||||||
OnUpdateTimestampOffsetLock,
|
OnUserRandom(),
|
||||||
// KUOHUANHUAN_NEED_SLEEP
|
OnQuestionMarkReply(),
|
||||||
OnTelegramCommand,
|
OnUserSlashAction(),
|
||||||
OnUniMeowTrigger,
|
OnCallMe(),
|
||||||
OnUserRandom,
|
OnCallMsgSend(),
|
||||||
OnQuestionMarkReply,
|
OnMedicationNotifyApply(),
|
||||||
OnUserSlashAction,
|
OnEventHackHandle()
|
||||||
OnInlineQuery,
|
)
|
||||||
OnCallMe,
|
|
||||||
OnCallMsgSend,
|
|
||||||
OnMedicationNotifyApply,
|
|
||||||
OnEventHackHandle
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ import scala.collection.mutable.ListBuffer
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.reflect.ClassTag
|
import scala.reflect.ClassTag
|
||||||
|
|
||||||
object OnInlineQuery extends EventListener {
|
class MornyOnInlineQuery (using queryManager: MornyQueries) (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
override def onInlineQuery (using update: Update): Boolean = {
|
override def onInlineQuery (using update: Update): Boolean = {
|
||||||
|
|
||||||
val results: List[InlineQueryUnit[_]] = MornyQueries query update
|
val results: List[InlineQueryUnit[_]] = queryManager query update
|
||||||
|
|
||||||
var cacheTime = Int.MaxValue
|
var cacheTime = Int.MaxValue
|
||||||
var isPersonal = InlineQueryUnit.defaults.IS_PERSONAL
|
var isPersonal = InlineQueryUnit.defaults.IS_PERSONAL
|
||||||
@ -28,7 +28,7 @@ object OnInlineQuery extends EventListener {
|
|||||||
|
|
||||||
if (results isEmpty) return false
|
if (results isEmpty) return false
|
||||||
|
|
||||||
MornyCoeur.extra exec AnswerInlineQuery(
|
coeur.extra exec AnswerInlineQuery(
|
||||||
update.inlineQuery.id, resultAnswers toArray:_*
|
update.inlineQuery.id, resultAnswers toArray:_*
|
||||||
).cacheTime(cacheTime).isPersonal(isPersonal)
|
).cacheTime(cacheTime).isPersonal(isPersonal)
|
||||||
true
|
true
|
@ -7,7 +7,7 @@ import cc.sukazyo.cono.morny.bot.command.MornyCommands
|
|||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import com.pengrad.telegrambot.model.{Message, Update}
|
import com.pengrad.telegrambot.model.{Message, Update}
|
||||||
|
|
||||||
object OnTelegramCommand extends EventListener {
|
class MornyOnTelegramCommand (using commandManager: MornyCommands) (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
override def onMessage (using update: Update): Boolean = {
|
override def onMessage (using update: Update): Boolean = {
|
||||||
|
|
||||||
@ -22,12 +22,12 @@ object OnTelegramCommand extends EventListener {
|
|||||||
if (!(inputCommand.command matches "^\\w+$"))
|
if (!(inputCommand.command matches "^\\w+$"))
|
||||||
logger debug "not command"
|
logger debug "not command"
|
||||||
false
|
false
|
||||||
else if ((inputCommand.target ne null) && (inputCommand.target != MornyCoeur.username))
|
else if ((inputCommand.target ne null) && (inputCommand.target != coeur.username))
|
||||||
logger debug "not morny command"
|
logger debug "not morny command"
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
logger debug "is command"
|
logger debug "is command"
|
||||||
MornyCommands.execute(using inputCommand)
|
commandManager.execute(using inputCommand)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,10 +4,10 @@ import cc.sukazyo.cono.morny.bot.api.EventListener
|
|||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
object OnUpdateTimestampOffsetLock extends EventListener {
|
class MornyOnUpdateTimestampOffsetLock (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private def isOutdated (timestamp: Int): Boolean =
|
private def isOutdated (timestamp: Int): Boolean =
|
||||||
timestamp < (MornyCoeur.config.eventOutdatedTimestamp/1000)
|
timestamp < (coeur.config.eventOutdatedTimestamp/1000)
|
||||||
|
|
||||||
override def onMessage (using update: Update): Boolean = isOutdated(update.message.date)
|
override def onMessage (using update: Update): Boolean = isOutdated(update.message.date)
|
||||||
override def onEditedMessage (using update: Update): Boolean = isOutdated(update.editedMessage.date)
|
override def onEditedMessage (using update: Update): Boolean = isOutdated(update.editedMessage.date)
|
@ -10,9 +10,9 @@ import com.pengrad.telegrambot.request.{ForwardMessage, GetChat, SendMessage, Se
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object OnCallMe extends EventListener {
|
class OnCallMe (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private val me = MornyCoeur.config.trustedMaster
|
private val me = coeur.config.trustedMaster
|
||||||
|
|
||||||
override def onMessage (using update: Update): Boolean = {
|
override def onMessage (using update: Update): Boolean = {
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ object OnCallMe extends EventListener {
|
|||||||
case _ =>
|
case _ =>
|
||||||
return false
|
return false
|
||||||
|
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
TelegramStickers ID_SENT
|
TelegramStickers ID_SENT
|
||||||
).replyToMessageId(update.message.messageId)
|
).replyToMessageId(update.message.messageId)
|
||||||
@ -41,7 +41,7 @@ object OnCallMe extends EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def requestItem (user: User, itemHTML: String, extra: String|Null = null): Unit =
|
private def requestItem (user: User, itemHTML: String, extra: String|Null = null): Unit =
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
me,
|
me,
|
||||||
s"""request $itemHTML
|
s"""request $itemHTML
|
||||||
|from ${user.fullnameRefHTML}${if extra == null then "" else "\n"+extra}"""
|
|from ${user.fullnameRefHTML}${if extra == null then "" else "\n"+extra}"""
|
||||||
@ -51,11 +51,11 @@ object OnCallMe extends EventListener {
|
|||||||
private def requestLastDinner (req: Message): Unit = {
|
private def requestLastDinner (req: Message): Unit = {
|
||||||
var isAllowed = false
|
var isAllowed = false
|
||||||
var lastDinnerData: Message|Null = null
|
var lastDinnerData: Message|Null = null
|
||||||
if (MornyCoeur.trusted isTrusted_dinnerReader req.from.id) {
|
if (coeur.trusted isTrusted_dinnerReader req.from.id) {
|
||||||
// todo: have issues
|
// todo: have issues
|
||||||
// i dont want to test it anymore... it might be deprecated soon
|
// i dont want to test it anymore... it might be deprecated soon
|
||||||
lastDinnerData = (MornyCoeur.extra exec GetChat(MornyCoeur.config.dinnerChatId)).chat.pinnedMessage
|
lastDinnerData = (coeur.extra exec GetChat(coeur.config.dinnerChatId)).chat.pinnedMessage
|
||||||
val sendResp = MornyCoeur.extra exec ForwardMessage(
|
val sendResp = coeur.extra exec ForwardMessage(
|
||||||
req.from.id,
|
req.from.id,
|
||||||
lastDinnerData.forwardFromChat.id,
|
lastDinnerData.forwardFromChat.id,
|
||||||
lastDinnerData.forwardFromMessageId
|
lastDinnerData.forwardFromMessageId
|
||||||
@ -63,7 +63,7 @@ object OnCallMe extends EventListener {
|
|||||||
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
|
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
def lastDinner_dateMillis: Long = lastDinnerData.forwardDate longValue;
|
def lastDinner_dateMillis: Long = lastDinnerData.forwardDate longValue;
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
req.from.id,
|
req.from.id,
|
||||||
"<i>on</i> <code>%s [UTC+8]</code>\n- <code>%s</code> <i>before</i>".formatted(
|
"<i>on</i> <code>%s [UTC+8]</code>\n- <code>%s</code> <i>before</i>".formatted(
|
||||||
h(formatDate(lastDinner_dateMillis, 8)),
|
h(formatDate(lastDinner_dateMillis, 8)),
|
||||||
@ -72,7 +72,7 @@ object OnCallMe extends EventListener {
|
|||||||
).parseMode(ParseMode HTML).replyToMessageId(sendResp.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(sendResp.message.messageId)
|
||||||
isAllowed = true
|
isAllowed = true
|
||||||
} else {
|
} else {
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
req.from.id,
|
req.from.id,
|
||||||
TelegramStickers ID_403
|
TelegramStickers ID_403
|
||||||
).replyToMessageId(req.messageId)
|
).replyToMessageId(req.messageId)
|
||||||
@ -87,6 +87,6 @@ object OnCallMe extends EventListener {
|
|||||||
|
|
||||||
private def requestCustom (message: Message): Unit =
|
private def requestCustom (message: Message): Unit =
|
||||||
requestItem(message.from, "<u>[???]</u>")
|
requestItem(message.from, "<u>[???]</u>")
|
||||||
MornyCoeur.extra exec ForwardMessage(me, message.chat.id, message.messageId)
|
coeur.extra exec ForwardMessage(me, message.chat.id, message.messageId)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import scala.collection.mutable.ArrayBuffer
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.util.matching.Regex
|
import scala.util.matching.Regex
|
||||||
|
|
||||||
object OnCallMsgSend extends EventListener {
|
class OnCallMsgSend (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private val REGEX_MSG_SENDREQ_DATA_HEAD: Regex = "^\\*msg(-?\\d+)(\\*\\S+)?(?:\\n([\\s\\S]+))?$"r
|
private val REGEX_MSG_SENDREQ_DATA_HEAD: Regex = "^\\*msg(-?\\d+)(\\*\\S+)?(?:\\n([\\s\\S]+))?$"r
|
||||||
|
|
||||||
@ -59,8 +59,8 @@ object OnCallMsgSend extends EventListener {
|
|||||||
if message.text eq null then return false
|
if message.text eq null then return false
|
||||||
if !(message.text startsWith "*msg") then return false
|
if !(message.text startsWith "*msg") then return false
|
||||||
|
|
||||||
if (!(MornyCoeur.trusted isTrusted message.from.id))
|
if (!(coeur.trusted isTrusted message.from.id))
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
TelegramStickers ID_403
|
TelegramStickers ID_403
|
||||||
).replyToMessageId(message.messageId)
|
).replyToMessageId(message.messageId)
|
||||||
@ -71,15 +71,15 @@ object OnCallMsgSend extends EventListener {
|
|||||||
if (message.replyToMessage eq null) return answer404
|
if (message.replyToMessage eq null) return answer404
|
||||||
val messageToSend = MessageToSend from message.replyToMessage
|
val messageToSend = MessageToSend from message.replyToMessage
|
||||||
if ((messageToSend eq null) || (messageToSend.message eq null)) return answer404
|
if ((messageToSend eq null) || (messageToSend.message eq null)) return answer404
|
||||||
val sendResponse = MornyCoeur.account execute messageToSend.toSendMessage()
|
val sendResponse = coeur.account execute messageToSend.toSendMessage()
|
||||||
|
|
||||||
if (sendResponse isOk) {
|
if (sendResponse isOk) {
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
TelegramStickers ID_SENT
|
TelegramStickers ID_SENT
|
||||||
).replyToMessageId(update.message.messageId)
|
).replyToMessageId(update.message.messageId)
|
||||||
} else {
|
} else {
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b><u>${sendResponse.errorCode} FAILED</u></b>
|
s"""<b><u>${sendResponse.errorCode} FAILED</u></b>
|
||||||
@ -104,7 +104,7 @@ object OnCallMsgSend extends EventListener {
|
|||||||
if _toSend eq null then return answer404
|
if _toSend eq null then return answer404
|
||||||
else _toSend
|
else _toSend
|
||||||
|
|
||||||
val targetChatResponse = MornyCoeur.account execute GetChat(messageToSend.targetId)
|
val targetChatResponse = coeur.account execute GetChat(messageToSend.targetId)
|
||||||
if (targetChatResponse isOk) {
|
if (targetChatResponse isOk) {
|
||||||
def getChatDescriptionHTML (chat: Chat): String =
|
def getChatDescriptionHTML (chat: Chat): String =
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
|
||||||
@ -113,12 +113,12 @@ object OnCallMsgSend extends EventListener {
|
|||||||
s"""<i><u>${h(chat.id toString)}</u>@${h(chat.`type`.name)}</i>${if (chat.`type` != Chat.Type.Private) ":::" else ""}
|
s"""<i><u>${h(chat.id toString)}</u>@${h(chat.`type`.name)}</i>${if (chat.`type` != Chat.Type.Private) ":::" else ""}
|
||||||
|${chat.typeTag} <b>${h(chat.safe_name)}</b> ${chat.safe_linkHTML}"""
|
|${chat.typeTag} <b>${h(chat.safe_name)}</b> ${chat.safe_linkHTML}"""
|
||||||
.stripMargin
|
.stripMargin
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
getChatDescriptionHTML(targetChatResponse.chat)
|
getChatDescriptionHTML(targetChatResponse.chat)
|
||||||
).parseMode(ParseMode HTML).replyToMessageId(update.message.messageId)
|
).parseMode(ParseMode HTML).replyToMessageId(update.message.messageId)
|
||||||
} else {
|
} else {
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b><u>${targetChatResponse.errorCode} FAILED</u></b>
|
s"""<b><u>${targetChatResponse.errorCode} FAILED</u></b>
|
||||||
@ -128,10 +128,10 @@ object OnCallMsgSend extends EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if messageToSend.message eq null then return true
|
if messageToSend.message eq null then return true
|
||||||
val testSendResponse = MornyCoeur.account execute messageToSend.toSendMessage(update.message.chat.id)
|
val testSendResponse = coeur.account execute messageToSend.toSendMessage(update.message.chat.id)
|
||||||
.replyToMessageId(update.message.messageId)
|
.replyToMessageId(update.message.messageId)
|
||||||
if (!(testSendResponse isOk))
|
if (!(testSendResponse isOk))
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b><u>${testSendResponse.errorCode}</u> FAILED</b>
|
s"""<b><u>${testSendResponse.errorCode}</u> FAILED</b>
|
||||||
@ -144,7 +144,7 @@ object OnCallMsgSend extends EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def answer404 (using update: Update): Boolean =
|
private def answer404 (using update: Update): Boolean =
|
||||||
MornyCoeur.extra exec SendSticker(
|
coeur.extra exec SendSticker(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
TelegramStickers ID_404
|
TelegramStickers ID_404
|
||||||
).replyToMessageId(update.message.messageId)
|
).replyToMessageId(update.message.messageId)
|
||||||
|
@ -11,69 +11,37 @@ import com.pengrad.telegrambot.request.SendMessage
|
|||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object OnEventHackHandle extends EventListener {
|
class OnEventHackHandle (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private case class Hacker (from_chat: Long, from_message: Long):
|
import coeur.daemons.eventHack.trigger
|
||||||
override def toString: String = s"$from_chat/$from_message"
|
|
||||||
enum HackType:
|
|
||||||
case USER
|
|
||||||
case GROUP
|
|
||||||
case ANY
|
|
||||||
|
|
||||||
private val hackers = mutable.HashMap.empty[String, Hacker]
|
|
||||||
|
|
||||||
def registerHack (from_message: Long, from_user: Long, from_chat: Long, t: HackType): Unit =
|
|
||||||
val record = t match
|
|
||||||
case HackType.USER => s"(($from_user))"
|
|
||||||
case HackType.GROUP => s"{{$from_chat}}"
|
|
||||||
case HackType.ANY => "[[]]"
|
|
||||||
hackers += (record -> Hacker(from_chat, from_message))
|
|
||||||
logger debug s"add hacker track $record"
|
|
||||||
|
|
||||||
private def onEventHacked (chat: Long, fromUser: Long)(using update: Update): Boolean = {
|
|
||||||
logger debug s"got event signed {{$chat}}(($fromUser))"
|
|
||||||
val x: Hacker =
|
|
||||||
if hackers contains s"(($fromUser))" then (hackers remove s"(($fromUser))")get
|
|
||||||
else if hackers contains s"{{$chat}}" then (hackers remove s"{{$chat}}")get
|
|
||||||
else if hackers contains "[[]]" then (hackers remove "[[]]")get
|
|
||||||
else return false
|
|
||||||
logger debug s"hacked event by $x"
|
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
|
||||||
x.from_chat,
|
|
||||||
// language=html
|
|
||||||
s"<code>${h(GsonBuilder().setPrettyPrinting().create.toJson(update))}</code>"
|
|
||||||
).parseMode(ParseMode HTML).replyToMessageId(x.from_message toInt)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onMessage (using update: Update): Boolean =
|
override def onMessage (using update: Update): Boolean =
|
||||||
onEventHacked(update.message.chat.id, update.message.from.id)
|
trigger(update.message.chat.id, update.message.from.id)
|
||||||
override def onEditedMessage (using update: Update): Boolean =
|
override def onEditedMessage (using update: Update): Boolean =
|
||||||
onEventHacked(update.editedMessage.chat.id, update.editedMessage.from.id)
|
trigger(update.editedMessage.chat.id, update.editedMessage.from.id)
|
||||||
override def onChannelPost (using update: Update): Boolean =
|
override def onChannelPost (using update: Update): Boolean =
|
||||||
onEventHacked(update.channelPost.chat.id, 0)
|
trigger(update.channelPost.chat.id, 0)
|
||||||
override def onEditedChannelPost (using update: Update): Boolean =
|
override def onEditedChannelPost (using update: Update): Boolean =
|
||||||
onEventHacked(update.editedChannelPost.chat.id, 0)
|
trigger(update.editedChannelPost.chat.id, 0)
|
||||||
override def onInlineQuery (using update: Update): Boolean =
|
override def onInlineQuery (using update: Update): Boolean =
|
||||||
onEventHacked(0, update.inlineQuery.from.id)
|
trigger(0, update.inlineQuery.from.id)
|
||||||
override def onChosenInlineResult (using update: Update): Boolean =
|
override def onChosenInlineResult (using update: Update): Boolean =
|
||||||
onEventHacked(0, update.chosenInlineResult.from.id)
|
trigger(0, update.chosenInlineResult.from.id)
|
||||||
override def onCallbackQuery (using update: Update): Boolean =
|
override def onCallbackQuery (using update: Update): Boolean =
|
||||||
onEventHacked(0, update.callbackQuery.from.id)
|
trigger(0, update.callbackQuery.from.id)
|
||||||
override def onShippingQuery (using update: Update): Boolean =
|
override def onShippingQuery (using update: Update): Boolean =
|
||||||
onEventHacked(0, update.shippingQuery.from.id)
|
trigger(0, update.shippingQuery.from.id)
|
||||||
override def onPreCheckoutQuery (using update: Update): Boolean =
|
override def onPreCheckoutQuery (using update: Update): Boolean =
|
||||||
onEventHacked(0, update.preCheckoutQuery.from.id)
|
trigger(0, update.preCheckoutQuery.from.id)
|
||||||
override def onPoll (using update: Update): Boolean =
|
override def onPoll (using update: Update): Boolean =
|
||||||
onEventHacked(0, 0)
|
trigger(0, 0)
|
||||||
override def onPollAnswer (using update: Update): Boolean =
|
override def onPollAnswer (using update: Update): Boolean =
|
||||||
onEventHacked(0, update.pollAnswer.user.id)
|
trigger(0, update.pollAnswer.user.id)
|
||||||
override def onMyChatMemberUpdated (using update: Update): Boolean =
|
override def onMyChatMemberUpdated (using update: Update): Boolean =
|
||||||
onEventHacked(update.myChatMember.chat.id, update.myChatMember.from.id)
|
trigger(update.myChatMember.chat.id, update.myChatMember.from.id)
|
||||||
override def onChatMemberUpdated (using update: Update): Boolean =
|
override def onChatMemberUpdated (using update: Update): Boolean =
|
||||||
onEventHacked(update.chatMember.chat.id, update.chatMember.from.id)
|
trigger(update.chatMember.chat.id, update.chatMember.from.id)
|
||||||
override def onChatJoinRequest (using update: Update): Boolean =
|
override def onChatJoinRequest (using update: Update): Boolean =
|
||||||
onEventHacked(update.chatJoinRequest.chat.id, update.chatJoinRequest.from.id)
|
trigger(update.chatJoinRequest.chat.id, update.chatJoinRequest.from.id)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
|
|||||||
import cc.sukazyo.cono.morny.daemon.{MedicationTimer, MornyDaemons}
|
import cc.sukazyo.cono.morny.daemon.{MedicationTimer, MornyDaemons}
|
||||||
import com.pengrad.telegrambot.model.{Message, Update}
|
import com.pengrad.telegrambot.model.{Message, Update}
|
||||||
|
|
||||||
object OnMedicationNotifyApply extends EventListener {
|
class OnMedicationNotifyApply (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
override def onEditedMessage (using event: Update): Boolean =
|
override def onEditedMessage (using event: Update): Boolean =
|
||||||
editedMessageProcess(event.editedMessage)
|
editedMessageProcess(event.editedMessage)
|
||||||
@ -13,8 +13,8 @@ object OnMedicationNotifyApply extends EventListener {
|
|||||||
editedMessageProcess(event.editedChannelPost)
|
editedMessageProcess(event.editedChannelPost)
|
||||||
|
|
||||||
private def editedMessageProcess (edited: Message): Boolean = {
|
private def editedMessageProcess (edited: Message): Boolean = {
|
||||||
if edited.chat.id != MornyCoeur.config.medicationNotifyToChat then return false
|
if edited.chat.id != coeur.config.medicationNotifyToChat then return false
|
||||||
MedicationTimer.refreshNotificationWrite(edited)
|
coeur.daemons.medicationTimer.refreshNotificationWrite(edited)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,21 +2,13 @@ package cc.sukazyo.cono.morny.bot.event
|
|||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListener
|
import cc.sukazyo.cono.morny.bot.api.EventListener
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
import cc.sukazyo.cono.morny.bot.event.OnQuestionMarkReply.isAllMessageMark
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
import com.pengrad.telegrambot.request.SendMessage
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object OnQuestionMarkReply extends EventListener {
|
class OnQuestionMarkReply (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private val QUESTION_MARKS = Set('?', '?', '¿', '⁈', '⁇', '‽', '❔', '❓')
|
|
||||||
|
|
||||||
def isAllMessageMark (using text: String): Boolean = {
|
|
||||||
var isAll = true
|
|
||||||
for (c <- text)
|
|
||||||
if !(QUESTION_MARKS contains c) then isAll = false
|
|
||||||
isAll
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onMessage (using event: Update): Boolean = {
|
override def onMessage (using event: Update): Boolean = {
|
||||||
|
|
||||||
@ -27,7 +19,7 @@ object OnQuestionMarkReply extends EventListener {
|
|||||||
if (1 over 8) chance_is false then return false
|
if (1 over 8) chance_is false then return false
|
||||||
if !isAllMessageMark(using event.message.text) then return false
|
if !isAllMessageMark(using event.message.text) then return false
|
||||||
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
event.message.chat.id, event.message.text
|
event.message.chat.id, event.message.text
|
||||||
).replyToMessageId(event.message.messageId)
|
).replyToMessageId(event.message.messageId)
|
||||||
true
|
true
|
||||||
@ -35,3 +27,16 @@ object OnQuestionMarkReply extends EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object OnQuestionMarkReply {
|
||||||
|
|
||||||
|
private val QUESTION_MARKS = Set('?', '?', '¿', '⁈', '⁇', '‽', '❔', '❓')
|
||||||
|
|
||||||
|
def isAllMessageMark (using text: String): Boolean = {
|
||||||
|
var isAll = true
|
||||||
|
for (c <- text)
|
||||||
|
if !(QUESTION_MARKS contains c) then isAll = false
|
||||||
|
isAll
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -3,15 +3,16 @@ package cc.sukazyo.cono.morny.bot.event
|
|||||||
import cc.sukazyo.cono.morny.bot.api.EventListener
|
import cc.sukazyo.cono.morny.bot.api.EventListener
|
||||||
import cc.sukazyo.cono.morny.bot.command.MornyCommands
|
import cc.sukazyo.cono.morny.bot.command.MornyCommands
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
object OnUniMeowTrigger extends EventListener {
|
class OnUniMeowTrigger (using commands: MornyCommands) (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
override def onMessage (using update: Update): Boolean = {
|
override def onMessage (using update: Update): Boolean = {
|
||||||
|
|
||||||
if update.message.text eq null then return false
|
if update.message.text eq null then return false
|
||||||
var ok = false
|
var ok = false
|
||||||
for ((name, command) <- MornyCommands.commands_uni)
|
for ((name, command) <- commands.commands_uni)
|
||||||
val _name = "/"+name
|
val _name = "/"+name
|
||||||
if (_name == update.message.text)
|
if (_name == update.message.text)
|
||||||
command.execute(using InputCommand(_name))
|
command.execute(using InputCommand(_name))
|
||||||
|
@ -7,7 +7,7 @@ import com.pengrad.telegrambot.request.SendMessage
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object OnUserRandom extends EventListener {
|
class OnUserRandom (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private val USER_OR_QUERY = "^(.+)(?:还是|or)(.+)$"r
|
private val USER_OR_QUERY = "^(.+)(?:还是|or)(.+)$"r
|
||||||
private val USER_IF_QUERY = "^(.+)(?:吗\\?|?|\\?|吗?)$"r
|
private val USER_IF_QUERY = "^(.+)(?:吗\\?|?|\\?|吗?)$"r
|
||||||
@ -30,7 +30,7 @@ object OnUserRandom extends EventListener {
|
|||||||
|
|
||||||
if result == null then return false
|
if result == null then return false
|
||||||
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
update.message.chat.id, result
|
update.message.chat.id, result
|
||||||
).replyToMessageId(update.message.messageId)
|
).replyToMessageId(update.message.messageId)
|
||||||
true
|
true
|
||||||
|
@ -11,7 +11,7 @@ import com.pengrad.telegrambot.request.SendMessage
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object OnUserSlashAction extends EventListener {
|
class OnUserSlashAction (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
private val TG_FORMAT = "^\\w+(@\\w+)?$"r
|
private val TG_FORMAT = "^\\w+(@\\w+)?$"r
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ object OnUserSlashAction extends EventListener {
|
|||||||
origin
|
origin
|
||||||
else update.message.replyToMessage
|
else update.message.replyToMessage
|
||||||
|
|
||||||
MornyCoeur.extra exec SendMessage(
|
coeur.extra exec SendMessage(
|
||||||
update.message.chat.id,
|
update.message.chat.id,
|
||||||
"%s %s%s %s %s!".format(
|
"%s %s%s %s %s!".format(
|
||||||
origin.sender_firstnameRefHTML,
|
origin.sender_firstnameRefHTML,
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.query
|
package cc.sukazyo.cono.morny.bot.query
|
||||||
|
|
||||||
import javax.annotation.Nullable
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
|
import javax.annotation.Nullable
|
||||||
|
|
||||||
trait ITelegramQuery {
|
trait ITelegramQuery {
|
||||||
|
|
||||||
def query (event: Update): List[InlineQueryUnit[_]] | Null
|
def query (event: Update): List[InlineQueryUnit[_]] | Null
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.query
|
package cc.sukazyo.cono.morny.bot.query
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.query
|
import cc.sukazyo.cono.morny.bot.query
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
object MornyQueries {
|
class MornyQueries (using MornyCoeur) {
|
||||||
|
|
||||||
private val queryInstances = Set[ITelegramQuery](
|
private val queryInstances = Set[ITelegramQuery](
|
||||||
RawText,
|
RawText(),
|
||||||
MyInformation,
|
MyInformation(),
|
||||||
ShareToolTwitter,
|
ShareToolTwitter(),
|
||||||
ShareToolBilibili
|
ShareToolBilibili()
|
||||||
)
|
)
|
||||||
|
|
||||||
def query (event: Update): List[InlineQueryUnit[_]] = {
|
def query (event: Update): List[InlineQueryUnit[_]] = {
|
||||||
|
@ -7,7 +7,7 @@ import com.pengrad.telegrambot.model.request.{InlineQueryResultArticle, InputTex
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object MyInformation extends ITelegramQuery {
|
class MyInformation extends ITelegramQuery {
|
||||||
|
|
||||||
private val ID_PREFIX = "[morny/info/me]"
|
private val ID_PREFIX = "[morny/info/me]"
|
||||||
private val TITLE = "My Account Information"
|
private val TITLE = "My Account Information"
|
||||||
|
@ -5,7 +5,7 @@ import com.pengrad.telegrambot.model.request.{InlineQueryResultArticle, InputTex
|
|||||||
|
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
object RawText extends ITelegramQuery {
|
class RawText extends ITelegramQuery {
|
||||||
|
|
||||||
private val ID_PREFIX = "[morny/r/text]"
|
private val ID_PREFIX = "[morny/r/text]"
|
||||||
private val TITLE = "Raw Text"
|
private val TITLE = "Raw Text"
|
||||||
|
@ -9,7 +9,7 @@ import com.pengrad.telegrambot.model.request.{InlineQueryResultArticle, InputTex
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.util.matching.Regex
|
import scala.util.matching.Regex
|
||||||
|
|
||||||
object ShareToolBilibili extends ITelegramQuery {
|
class ShareToolBilibili extends ITelegramQuery {
|
||||||
|
|
||||||
private val TITLE_BILI_AV = "[bilibili] Share video / av"
|
private val TITLE_BILI_AV = "[bilibili] Share video / av"
|
||||||
private val TITLE_BILI_BV = "[bilibili] Share video / BV"
|
private val TITLE_BILI_BV = "[bilibili] Share video / BV"
|
||||||
|
@ -7,7 +7,7 @@ import com.pengrad.telegrambot.model.request.InlineQueryResultArticle
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.util.matching.Regex
|
import scala.util.matching.Regex
|
||||||
|
|
||||||
object ShareToolTwitter extends ITelegramQuery {
|
class ShareToolTwitter extends ITelegramQuery {
|
||||||
|
|
||||||
private val TITLE_VX = "[tweet] Share as VxTwitter"
|
private val TITLE_VX = "[tweet] Share as VxTwitter"
|
||||||
private val TITLE_VX_COMBINED = "[tweet] Share as VxTwitter(combination)"
|
private val TITLE_VX_COMBINED = "[tweet] Share as VxTwitter(combination)"
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package cc.sukazyo.cono.morny.daemon
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.Log.logger
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
class EventHacker (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
|
private case class Hacker (from_chat: Long, from_message: Long):
|
||||||
|
override def toString: String = s"$from_chat/$from_message"
|
||||||
|
|
||||||
|
enum HackType:
|
||||||
|
case USER
|
||||||
|
case GROUP
|
||||||
|
case ANY
|
||||||
|
|
||||||
|
private val hackers = mutable.HashMap.empty[String, Hacker]
|
||||||
|
|
||||||
|
def registerHack (from_message: Long, from_user: Long, from_chat: Long, t: HackType): Unit =
|
||||||
|
val record = t match
|
||||||
|
case HackType.USER => s"(($from_user))"
|
||||||
|
case HackType.GROUP => s"{{$from_chat}}"
|
||||||
|
case HackType.ANY => "[[]]"
|
||||||
|
hackers += (record -> Hacker(from_chat, from_message))
|
||||||
|
logger debug s"add hacker track $record"
|
||||||
|
|
||||||
|
def trigger (chat: Long, fromUser: Long)(using update: Update): Boolean = {
|
||||||
|
logger debug s"got event signed {{$chat}}(($fromUser))"
|
||||||
|
val x: Hacker =
|
||||||
|
if hackers contains s"(($fromUser))" then (hackers remove s"(($fromUser))") get
|
||||||
|
else if hackers contains s"{{$chat}}" then (hackers remove s"{{$chat}}") get
|
||||||
|
else if hackers contains "[[]]" then (hackers remove "[[]]") get
|
||||||
|
else return false
|
||||||
|
logger debug s"hacked event by $x"
|
||||||
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
|
coeur.extra exec SendMessage(
|
||||||
|
x.from_chat,
|
||||||
|
// language=html
|
||||||
|
s"<code>${h(GsonBuilder().setPrettyPrinting().create.toJson(update))}</code>"
|
||||||
|
).parseMode(ParseMode HTML).replyToMessageId(x.from_message toInt)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
package cc.sukazyo.cono.morny.daemon
|
package cc.sukazyo.cono.morny.daemon
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
|
||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
import cc.sukazyo.cono.morny.daemon.MedicationTimer.calcNextRoutineTimestamp
|
||||||
import com.pengrad.telegrambot.model.{Message, MessageEntity}
|
import com.pengrad.telegrambot.model.{Message, MessageEntity}
|
||||||
import com.pengrad.telegrambot.request.{EditMessageText, SendMessage}
|
import com.pengrad.telegrambot.request.{EditMessageText, SendMessage}
|
||||||
import com.pengrad.telegrambot.response.SendResponse
|
import com.pengrad.telegrambot.response.SendResponse
|
||||||
@ -10,15 +11,15 @@ import java.time.{LocalDateTime, ZoneOffset}
|
|||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
import scala.language.implicitConversions
|
import scala.language.implicitConversions
|
||||||
|
|
||||||
object MedicationTimer extends Thread {
|
class MedicationTimer (using coeur: MornyCoeur) extends Thread {
|
||||||
|
|
||||||
private val NOTIFY_MESSAGE = "🍥⏲"
|
private val NOTIFY_MESSAGE = "🍥⏲"
|
||||||
private val DAEMON_THREAD_NAME_DEF = "MedicationTimer"
|
private val DAEMON_THREAD_NAME_DEF = "MedicationTimer"
|
||||||
|
|
||||||
private val use_timeZone = MornyCoeur.config.medicationTimerUseTimezone
|
private val use_timeZone = coeur.config.medicationTimerUseTimezone
|
||||||
import scala.jdk.CollectionConverters.SetHasAsScala
|
import scala.jdk.CollectionConverters.SetHasAsScala
|
||||||
private val notify_atHour: Set[Int] = MornyCoeur.config.medicationNotifyAt.asScala.toSet.map(_.intValue)
|
private val notify_atHour: Set[Int] = coeur.config.medicationNotifyAt.asScala.toSet.map(_.intValue)
|
||||||
private val notify_toChat = MornyCoeur.config.medicationNotifyToChat
|
private val notify_toChat = coeur.config.medicationNotifyToChat
|
||||||
|
|
||||||
this.setName(DAEMON_THREAD_NAME_DEF)
|
this.setName(DAEMON_THREAD_NAME_DEF)
|
||||||
|
|
||||||
@ -42,17 +43,22 @@ object MedicationTimer extends Thread {
|
|||||||
s"""unexpected error occurred on NotificationTimer
|
s"""unexpected error occurred on NotificationTimer
|
||||||
|${exceptionLog(e)}"""
|
|${exceptionLog(e)}"""
|
||||||
.stripMargin
|
.stripMargin
|
||||||
MornyReport.exception(e)
|
coeur.daemons.reporter.exception(e)
|
||||||
}
|
}
|
||||||
logger info "Medication Timer stopped."
|
logger info "Medication Timer stopped."
|
||||||
}
|
}
|
||||||
|
|
||||||
private def sendNotification(): Unit = {
|
private def sendNotification(): Unit = {
|
||||||
val sendResponse: SendResponse = MornyCoeur.extra exec SendMessage(notify_toChat, NOTIFY_MESSAGE)
|
val sendResponse: SendResponse = coeur.extra exec SendMessage(notify_toChat, NOTIFY_MESSAGE)
|
||||||
if sendResponse isOk then lastNotify_messageId = sendResponse.message.messageId
|
if sendResponse isOk then lastNotify_messageId = sendResponse.message.messageId
|
||||||
else lastNotify_messageId = null
|
else lastNotify_messageId = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@throws[InterruptedException | IllegalArgumentException]
|
||||||
|
private def waitToNextRoutine (): Unit = {
|
||||||
|
Thread sleep calcNextRoutineTimestamp(System.currentTimeMillis, use_timeZone, notify_atHour)
|
||||||
|
}
|
||||||
|
|
||||||
def refreshNotificationWrite (edited: Message): Unit = {
|
def refreshNotificationWrite (edited: Message): Unit = {
|
||||||
if lastNotify_messageId != (edited.messageId toInt) then return
|
if lastNotify_messageId != (edited.messageId toInt) then return
|
||||||
import cc.sukazyo.cono.morny.util.CommonFormat.formatDate
|
import cc.sukazyo.cono.morny.util.CommonFormat.formatDate
|
||||||
@ -60,7 +66,7 @@ object MedicationTimer extends Thread {
|
|||||||
val entities = ArrayBuffer.empty[MessageEntity]
|
val entities = ArrayBuffer.empty[MessageEntity]
|
||||||
if edited.entities ne null then entities ++= edited.entities
|
if edited.entities ne null then entities ++= edited.entities
|
||||||
entities += MessageEntity(MessageEntity.Type.italic, edited.text.length + "\n-- ".length, editTime.length)
|
entities += MessageEntity(MessageEntity.Type.italic, edited.text.length + "\n-- ".length, editTime.length)
|
||||||
MornyCoeur.extra exec EditMessageText(
|
coeur.extra exec EditMessageText(
|
||||||
notify_toChat,
|
notify_toChat,
|
||||||
edited.messageId,
|
edited.messageId,
|
||||||
edited.text + s"\n-- $editTime --"
|
edited.text + s"\n-- $editTime --"
|
||||||
@ -68,23 +74,22 @@ object MedicationTimer extends Thread {
|
|||||||
lastNotify_messageId = null
|
lastNotify_messageId = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object MedicationTimer {
|
||||||
|
|
||||||
@throws[IllegalArgumentException]
|
@throws[IllegalArgumentException]
|
||||||
private[daemon] def calcNextRoutineTimestamp (baseTimeMillis: Long, zone: ZoneOffset, notifyAt: Set[Int]): Long = {
|
private[daemon] def calcNextRoutineTimestamp (baseTimeMillis: Long, zone: ZoneOffset, notifyAt: Set[Int]): Long = {
|
||||||
if (notifyAt isEmpty) throw new IllegalArgumentException("notify time is not set")
|
if (notifyAt isEmpty) throw new IllegalArgumentException("notify time is not set")
|
||||||
var time = LocalDateTime.ofEpochSecond(
|
var time = LocalDateTime.ofEpochSecond(
|
||||||
baseTimeMillis/1000, ((baseTimeMillis%1000)*1000*1000) toInt,
|
baseTimeMillis / 1000, ((baseTimeMillis % 1000) * 1000 * 1000) toInt,
|
||||||
zone
|
zone
|
||||||
).withMinute(0).withSecond(0).withNano(0)
|
).withMinute(0).withSecond(0).withNano(0)
|
||||||
time = time plusHours 1
|
time = time plusHours 1
|
||||||
while (!(notifyAt contains (time getHour))) {
|
while (!(notifyAt contains(time getHour))) {
|
||||||
time = time plusHours 1
|
time = time plusHours 1
|
||||||
}
|
}
|
||||||
(time toInstant zone) toEpochMilli
|
(time toInstant zone) toEpochMilli
|
||||||
}
|
}
|
||||||
|
|
||||||
@throws[InterruptedException | IllegalArgumentException]
|
|
||||||
private def waitToNextRoutine (): Unit = {
|
|
||||||
Thread sleep calcNextRoutineTimestamp(System.currentTimeMillis, use_timeZone, notify_atHour)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,17 @@ package cc.sukazyo.cono.morny.daemon
|
|||||||
import cc.sukazyo.cono.morny.Log.logger
|
import cc.sukazyo.cono.morny.Log.logger
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
|
|
||||||
object MornyDaemons {
|
class MornyDaemons (using val coeur: MornyCoeur) {
|
||||||
|
|
||||||
|
val medicationTimer: MedicationTimer = MedicationTimer()
|
||||||
|
val reporter: MornyReport = MornyReport()
|
||||||
|
val eventHack: EventHacker = EventHacker()
|
||||||
|
|
||||||
def start (): Unit = {
|
def start (): Unit = {
|
||||||
logger info "ALL Morny Daemons starting..."
|
logger info "ALL Morny Daemons starting..."
|
||||||
// TrackerDataManager.init();
|
// TrackerDataManager.init();
|
||||||
MedicationTimer.start()
|
medicationTimer.start()
|
||||||
MornyReport.onMornyLogin()
|
reporter.onMornyLogin()
|
||||||
logger info "Morny Daemons started."
|
logger info "Morny Daemons started."
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -17,12 +21,12 @@ object MornyDaemons {
|
|||||||
def stop (): Unit = {
|
def stop (): Unit = {
|
||||||
logger.info("ALL Morny Daemons stopping...")
|
logger.info("ALL Morny Daemons stopping...")
|
||||||
// TrackerDataManager.DAEMON.interrupt();
|
// TrackerDataManager.DAEMON.interrupt();
|
||||||
MedicationTimer.interrupt()
|
medicationTimer.interrupt()
|
||||||
// TrackerDataManager.trackingLock.lock();
|
// TrackerDataManager.trackingLock.lock();
|
||||||
try { MedicationTimer.join() }
|
try { medicationTimer.join() }
|
||||||
catch case e: InterruptedException =>
|
catch case e: InterruptedException =>
|
||||||
e.printStackTrace(System.out)
|
e.printStackTrace(System.out)
|
||||||
MornyReport.onMornyExit(MornyCoeur.exitReason)
|
reporter.onMornyExit()
|
||||||
logger.info("ALL Morny Daemons STOPPED.")
|
logger.info("ALL Morny Daemons STOPPED.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.daemon
|
|||||||
import cc.sukazyo.cono.morny.{MornyCoeur, MornyConfig}
|
import cc.sukazyo.cono.morny.{MornyCoeur, MornyConfig}
|
||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.bot.command.MornyInformation
|
import cc.sukazyo.cono.morny.bot.command.MornyInformation
|
||||||
|
import cc.sukazyo.cono.morny.data.MornyInformation.getVersionAllFullTagHTML
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
|
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
|
||||||
@ -12,14 +13,11 @@ import com.pengrad.telegrambot.model.User
|
|||||||
import com.pengrad.telegrambot.request.{BaseRequest, SendMessage}
|
import com.pengrad.telegrambot.request.{BaseRequest, SendMessage}
|
||||||
import com.pengrad.telegrambot.response.BaseResponse
|
import com.pengrad.telegrambot.response.BaseResponse
|
||||||
|
|
||||||
object MornyReport {
|
class MornyReport (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
private def unsupported: Boolean = (!MornyCoeur.available) || (MornyCoeur.config.reportToChat == -1)
|
|
||||||
|
|
||||||
private def executeReport[T <: BaseRequest[T, R], R<: BaseResponse] (report: T): Unit = {
|
private def executeReport[T <: BaseRequest[T, R], R<: BaseResponse] (report: T): Unit = {
|
||||||
if unsupported then return
|
|
||||||
try {
|
try {
|
||||||
MornyCoeur.extra exec report
|
coeur.extra exec report
|
||||||
} catch case e: EventRuntimeException.ActionFailed => {
|
} catch case e: EventRuntimeException.ActionFailed => {
|
||||||
logger warn
|
logger warn
|
||||||
s"""cannot execute report to telegram:
|
s"""cannot execute report to telegram:
|
||||||
@ -31,7 +29,6 @@ object MornyReport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def exception (e: Throwable, description: String|Null = null): Unit = {
|
def exception (e: Throwable, description: String|Null = null): Unit = {
|
||||||
if unsupported then return
|
|
||||||
def _tgErrFormat: String = e match
|
def _tgErrFormat: String = e match
|
||||||
case api: EventRuntimeException.ActionFailed =>
|
case api: EventRuntimeException.ActionFailed =>
|
||||||
// language=html
|
// language=html
|
||||||
@ -39,7 +36,7 @@ object MornyReport {
|
|||||||
.formatted(GsonBuilder().setPrettyPrinting().create.toJson(api.response))
|
.formatted(GsonBuilder().setPrettyPrinting().create.toJson(api.response))
|
||||||
case _ => ""
|
case _ => ""
|
||||||
executeReport(SendMessage(
|
executeReport(SendMessage(
|
||||||
MornyCoeur.config.reportToChat,
|
coeur.config.reportToChat,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b>▌Coeur Unexpected Exception </b>
|
s"""<b>▌Coeur Unexpected Exception </b>
|
||||||
|${if description ne null then h(description)+"\n" else ""}
|
|${if description ne null then h(description)+"\n" else ""}
|
||||||
@ -49,9 +46,8 @@ object MornyReport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def unauthenticatedAction (action: String, user: User): Unit = {
|
def unauthenticatedAction (action: String, user: User): Unit = {
|
||||||
if unsupported then return
|
|
||||||
executeReport(SendMessage(
|
executeReport(SendMessage(
|
||||||
MornyCoeur.config.reportToChat,
|
coeur.config.reportToChat,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b>▌User unauthenticated action</b>
|
s"""<b>▌User unauthenticated action</b>
|
||||||
|action: ${h(action)}
|
|action: ${h(action)}
|
||||||
@ -62,14 +58,14 @@ object MornyReport {
|
|||||||
|
|
||||||
def onMornyLogin(): Unit = {
|
def onMornyLogin(): Unit = {
|
||||||
executeReport(SendMessage(
|
executeReport(SendMessage(
|
||||||
MornyCoeur.config.reportToChat,
|
coeur.config.reportToChat,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b>▌Morny Logged in</b>
|
s"""<b>▌Morny Logged in</b>
|
||||||
|-v ${MornyInformation.getVersionAllFullTagHTML}
|
|-v $getVersionAllFullTagHTML
|
||||||
|as user ${MornyCoeur.username}
|
|as user ${coeur.username}
|
||||||
|
|
|
|
||||||
|as config fields:
|
|as config fields:
|
||||||
|${sectionConfigFields(MornyCoeur.config)}"""
|
|${sectionConfigFields(coeur.config)}"""
|
||||||
.stripMargin
|
.stripMargin
|
||||||
).parseMode(ParseMode HTML))
|
).parseMode(ParseMode HTML))
|
||||||
}
|
}
|
||||||
@ -103,17 +99,16 @@ object MornyReport {
|
|||||||
echo dropRight 1 toString
|
echo dropRight 1 toString
|
||||||
}
|
}
|
||||||
|
|
||||||
def onMornyExit (causedBy: AnyRef|Null): Unit = {
|
def onMornyExit (): Unit = {
|
||||||
if unsupported then return
|
val causedTag = coeur.exitReason match
|
||||||
val causedTag = causedBy match
|
|
||||||
case u: User => u.fullnameRefHTML
|
case u: User => u.fullnameRefHTML
|
||||||
case n if n == null => "UNKNOWN reason"
|
case n if n == null => "UNKNOWN reason"
|
||||||
case a: AnyRef => /*language=html*/ s"<code>${h(a.toString)}</code>"
|
case a: AnyRef => /*language=html*/ s"<code>${h(a.toString)}</code>"
|
||||||
executeReport(SendMessage(
|
executeReport(SendMessage(
|
||||||
MornyCoeur.config.reportToChat,
|
coeur.config.reportToChat,
|
||||||
// language=html
|
// language=html
|
||||||
s"""<b>▌Morny Exited</b>
|
s"""<b>▌Morny Exited</b>
|
||||||
|from user @${MornyCoeur.username}
|
|from user @${coeur.username}
|
||||||
|
|
|
|
||||||
|by: $causedTag"""
|
|by: $causedTag"""
|
||||||
.stripMargin
|
.stripMargin
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package cc.sukazyo.cono.morny.data
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.{BuildConfig, MornyAbout, MornySystem}
|
||||||
|
|
||||||
|
import java.net.InetAddress
|
||||||
|
import java.rmi.UnknownHostException
|
||||||
|
|
||||||
|
object MornyInformation {
|
||||||
|
|
||||||
|
//noinspection ScalaWeakerAccess
|
||||||
|
def getVersionGitTagHTML: String = {
|
||||||
|
if (!MornySystem.isGitBuild) return ""
|
||||||
|
val g = StringBuilder()
|
||||||
|
val cm = BuildConfig.COMMIT substring(0, 8)
|
||||||
|
val cp = MornySystem.currentCodePath
|
||||||
|
if (cp == null) g ++= s"<code>$cm</code>"
|
||||||
|
else g ++= s"<a href='$cp'>$cm</a>"
|
||||||
|
if (!MornySystem.isCleanBuild) g ++= ".<code>δ</code>"
|
||||||
|
g toString
|
||||||
|
}
|
||||||
|
|
||||||
|
def getVersionAllFullTagHTML: String = {
|
||||||
|
val v = StringBuilder()
|
||||||
|
v ++= s"<code>${MornySystem VERSION_BASE}</code>"
|
||||||
|
if (MornySystem isUseDelta) v ++= s"-δ<code>${MornySystem VERSION_DELTA}</code>"
|
||||||
|
if (MornySystem isGitBuild) v ++= "+git." ++= getVersionGitTagHTML
|
||||||
|
v ++= s"*<code>${MornySystem.CODENAME toUpperCase}</code>"
|
||||||
|
v toString
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection ScalaWeakerAccess
|
||||||
|
def getRuntimeHostname: String | Null = {
|
||||||
|
try InetAddress.getLocalHost.getHostName
|
||||||
|
catch case _: UnknownHostException => null
|
||||||
|
}
|
||||||
|
|
||||||
|
def getAboutPic: Array[Byte] = TelegramImages.IMG_ABOUT get
|
||||||
|
|
||||||
|
def getMornyAboutLinksHTML: String =
|
||||||
|
s"""<a href='${MornyAbout MORNY_SOURCECODE_LINK}'>source code</a> | <a href='${MornyAbout MORNY_SOURCECODE_SELF_HOSTED_MIRROR_LINK}'>backup</a>
|
||||||
|
|<a href='${MornyAbout MORNY_ISSUE_TRACKER_LINK}'>反馈 / issue tracker</a>
|
||||||
|
|<a href='${MornyAbout MORNY_USER_GUIDE_LINK}'>使用说明书 / user guide & docs</a>"""
|
||||||
|
.stripMargin
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
package cc.sukazyo.cono.morny.data
|
package cc.sukazyo.cono.morny.data
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
||||||
import cc.sukazyo.cono.morny.MornyAssets
|
import cc.sukazyo.cono.morny.MornyAssets
|
||||||
|
import cc.sukazyo.cono.morny.daemon.MornyReport
|
||||||
|
import cc.sukazyo.cono.morny.MornyAssets.AssetsException
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.util.Using
|
import scala.util.Using
|
||||||
import java.io.IOException
|
|
||||||
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
|
|
||||||
import cc.sukazyo.cono.morny.daemon.MornyReport
|
|
||||||
|
|
||||||
object TelegramImages {
|
object TelegramImages {
|
||||||
|
|
||||||
@ -14,19 +15,17 @@ object TelegramImages {
|
|||||||
|
|
||||||
private var cache: Array[Byte]|Null = _
|
private var cache: Array[Byte]|Null = _
|
||||||
|
|
||||||
|
@throws[AssetsException]
|
||||||
def get:Array[Byte] =
|
def get:Array[Byte] =
|
||||||
if cache eq null then read()
|
if cache eq null then read()
|
||||||
if cache eq null then throw IllegalStateException("Failed to get assets file image.")
|
|
||||||
cache
|
cache
|
||||||
|
|
||||||
|
@throws[AssetsException]
|
||||||
private def read (): Unit = {
|
private def read (): Unit = {
|
||||||
Using ((MornyAssets.pack getResource assetsPath)read) { stream =>
|
Using ((MornyAssets.pack getResource assetsPath)read) { stream =>
|
||||||
try { this.cache = stream.readAllBytes() }
|
try { this.cache = stream.readAllBytes() }
|
||||||
catch case e: IOException => {
|
catch case e: IOException => {
|
||||||
logger error
|
throw AssetsException(e)
|
||||||
s"""Cannot read resource file:
|
|
||||||
|${exceptionLog(e)}""".stripMargin
|
|
||||||
MornyReport.exception(e, "Cannot read resource file.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user