mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 19:24:53 +08:00
add coeur lifecycles, add MornyCoeur.externalContext
This commit is contained in:
parent
341d4cd851
commit
6b961a3de3
@ -8,7 +8,7 @@ object MornyConfiguration {
|
|||||||
val MORNY_CODE_STORE = "https://github.com/Eyre-S/Coeur-Morny-Cono"
|
val MORNY_CODE_STORE = "https://github.com/Eyre-S/Coeur-Morny-Cono"
|
||||||
val MORNY_COMMIT_PATH = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s"
|
val MORNY_COMMIT_PATH = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s"
|
||||||
|
|
||||||
val VERSION = "2.0.0-alpha3"
|
val VERSION = "2.0.0-alpha5"
|
||||||
val VERSION_DELTA: Option[String] = None
|
val VERSION_DELTA: Option[String] = None
|
||||||
val CODENAME = "guanggu"
|
val CODENAME = "guanggu"
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
package cc.sukazyo.cono.morny
|
package cc.sukazyo.cono.morny
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.command.MornyCommands
|
import cc.sukazyo.cono.morny.bot.command.MornyCommandManager
|
||||||
import cc.sukazyo.cono.morny.daemon.MornyDaemons
|
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.{TestRun, THREAD_SERVER_EXIT}
|
import cc.sukazyo.cono.morny.MornyCoeur.*
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListenerManager
|
import cc.sukazyo.cono.morny.bot.api.EventListenerManager
|
||||||
import cc.sukazyo.cono.morny.bot.event.{MornyEventListeners, MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock}
|
import cc.sukazyo.cono.morny.bot.event.{MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock}
|
||||||
import cc.sukazyo.cono.morny.bot.query.MornyQueries
|
import cc.sukazyo.cono.morny.bot.query.MornyQueryManager
|
||||||
import cc.sukazyo.cono.morny.util.schedule.Scheduler
|
import cc.sukazyo.cono.morny.util.schedule.Scheduler
|
||||||
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
|
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
|
||||||
import cc.sukazyo.cono.morny.util.time.WatchDog
|
import cc.sukazyo.cono.morny.util.time.WatchDog
|
||||||
|
import cc.sukazyo.cono.morny.util.GivenContext
|
||||||
import com.pengrad.telegrambot.TelegramBot
|
import com.pengrad.telegrambot.TelegramBot
|
||||||
import com.pengrad.telegrambot.request.GetMe
|
import com.pengrad.telegrambot.request.GetMe
|
||||||
|
|
||||||
import scala.annotation.unused
|
|
||||||
import scala.util.boundary
|
import scala.util.boundary
|
||||||
import scala.util.boundary.break
|
import scala.util.boundary.break
|
||||||
|
|
||||||
@ -23,15 +23,65 @@ object MornyCoeur {
|
|||||||
|
|
||||||
object TestRun
|
object TestRun
|
||||||
|
|
||||||
|
case class OnInitializingPreContext (
|
||||||
|
externalContext: GivenContext,
|
||||||
|
coeurStartupTimes: EpochMillis,
|
||||||
|
account: TelegramBot,
|
||||||
|
username: String,
|
||||||
|
userid: Long,
|
||||||
|
tasks: Scheduler,
|
||||||
|
trusted: MornyTrusted,
|
||||||
|
givenCxt: GivenContext
|
||||||
|
)
|
||||||
|
|
||||||
|
case class OnInitializingContext (
|
||||||
|
externalContext: GivenContext,
|
||||||
|
coeurStartupTimes: EpochMillis,
|
||||||
|
account: TelegramBot,
|
||||||
|
username: String,
|
||||||
|
userid: Long,
|
||||||
|
tasks: Scheduler,
|
||||||
|
trusted: MornyTrusted,
|
||||||
|
eventManager: EventListenerManager,
|
||||||
|
commandManager: MornyCommandManager,
|
||||||
|
queryManager: MornyQueryManager,
|
||||||
|
givenCxt: GivenContext
|
||||||
|
)
|
||||||
|
|
||||||
|
case class OnInitializingPostContext (
|
||||||
|
externalContext: GivenContext,
|
||||||
|
coeurStartupTimes: EpochMillis,
|
||||||
|
account: TelegramBot,
|
||||||
|
username: String,
|
||||||
|
userid: Long,
|
||||||
|
tasks: Scheduler,
|
||||||
|
trusted: MornyTrusted,
|
||||||
|
eventManager: EventListenerManager,
|
||||||
|
commandManager: MornyCommandManager,
|
||||||
|
queryManager: MornyQueryManager,
|
||||||
|
givenCxt: GivenContext
|
||||||
|
)
|
||||||
|
|
||||||
|
case class OnStartingContext (
|
||||||
|
givenCxt: GivenContext
|
||||||
|
)
|
||||||
|
|
||||||
|
case class OnStartingPostContext (
|
||||||
|
givenCxt: GivenContext
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(testRun: Boolean = false) {
|
||||||
|
|
||||||
given MornyCoeur = this
|
given MornyCoeur = this
|
||||||
|
|
||||||
|
val externalContext: GivenContext = GivenContext()
|
||||||
|
|
||||||
///>>> BLOCK START instance configure & startup stage 1
|
///>>> BLOCK START instance configure & startup stage 1
|
||||||
|
|
||||||
logger info "Coeur starting..."
|
logger info "Coeur starting..."
|
||||||
|
private var initializeContext = GivenContext()
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.util.StringEnsure.deSensitive
|
import cc.sukazyo.cono.morny.util.StringEnsure.deSensitive
|
||||||
logger info s"args key:\n ${config.telegramBotKey deSensitive 4}"
|
logger info s"args key:\n ${config.telegramBotKey deSensitive 4}"
|
||||||
@ -44,6 +94,7 @@ class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
|||||||
logger error "Login to bot failed."
|
logger error "Login to bot failed."
|
||||||
System exit -1
|
System exit -1
|
||||||
throw RuntimeException()
|
throw RuntimeException()
|
||||||
|
initializeContext << __loginResult
|
||||||
|
|
||||||
///<<< BLOCK END instance configure & startup stage 1
|
///<<< BLOCK END instance configure & startup stage 1
|
||||||
|
|
||||||
@ -71,19 +122,29 @@ class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
|||||||
/** current Morny's [[MornyTrusted]] instance */
|
/** current Morny's [[MornyTrusted]] instance */
|
||||||
val trusted: MornyTrusted = MornyTrusted()
|
val trusted: MornyTrusted = MornyTrusted()
|
||||||
|
|
||||||
|
modules.foreach(it => it.onInitializingPre(OnInitializingPreContext(
|
||||||
|
externalContext,
|
||||||
|
coeurStartTimestamp, account, username, userid, tasks, trusted,
|
||||||
|
initializeContext)))
|
||||||
|
|
||||||
val daemons: MornyDaemons = MornyDaemons()
|
val daemons: MornyDaemons = MornyDaemons()
|
||||||
//noinspection ScalaWeakerAccess
|
initializeContext << daemons
|
||||||
val eventManager: EventListenerManager = EventListenerManager()
|
val eventManager: EventListenerManager = EventListenerManager()
|
||||||
eventManager register MornyOnUpdateTimestampOffsetLock()
|
eventManager register MornyOnUpdateTimestampOffsetLock()
|
||||||
val commands: MornyCommands = MornyCommands()
|
val commands: MornyCommandManager = MornyCommandManager()
|
||||||
//noinspection ScalaWeakerAccess
|
val queries: MornyQueryManager = MornyQueryManager()
|
||||||
val queries: MornyQueries = MornyQueries()
|
|
||||||
eventManager register MornyOnTelegramCommand(using commands)
|
eventManager register MornyOnTelegramCommand(using commands)
|
||||||
eventManager register MornyOnInlineQuery(using queries)
|
eventManager register MornyOnInlineQuery(using queries)
|
||||||
//noinspection ScalaUnusedSymbol
|
|
||||||
val events: MornyEventListeners = MornyEventListeners(using eventManager)
|
// Coeur Initializing Event
|
||||||
|
modules.foreach(it => it.onInitializing(OnInitializingContext(
|
||||||
|
externalContext,
|
||||||
|
coeurStartTimestamp, account, username, userid, tasks, trusted,
|
||||||
|
eventManager, commands, queries,
|
||||||
|
initializeContext)))
|
||||||
|
|
||||||
eventManager register daemons.reporter.EventStatistics.EventInfoCatcher
|
eventManager register daemons.reporter.EventStatistics.EventInfoCatcher
|
||||||
@unused
|
|
||||||
val watchDog: WatchDog = WatchDog("watch-dog", 1000, 1500, { (consumed, _) =>
|
val watchDog: WatchDog = WatchDog("watch-dog", 1000, 1500, { (consumed, _) =>
|
||||||
import cc.sukazyo.cono.morny.util.CommonFormat.formatDuration as f
|
import cc.sukazyo.cono.morny.util.CommonFormat.formatDuration as f
|
||||||
logger warn
|
logger warn
|
||||||
@ -91,6 +152,12 @@ class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
|||||||
| current tick takes ${f(consumed)} to complete.""".stripMargin
|
| current tick takes ${f(consumed)} to complete.""".stripMargin
|
||||||
tasks.notifyIt()
|
tasks.notifyIt()
|
||||||
})
|
})
|
||||||
|
initializeContext / this << watchDog
|
||||||
|
modules.foreach(it => it.onInitializingPost(OnInitializingPostContext(
|
||||||
|
externalContext,
|
||||||
|
coeurStartTimestamp, account, username, userid, tasks, trusted,
|
||||||
|
eventManager, commands, queries,
|
||||||
|
initializeContext)))
|
||||||
|
|
||||||
///>>> BLOCK START instance configure & startup stage 2
|
///>>> BLOCK START instance configure & startup stage 2
|
||||||
|
|
||||||
@ -102,6 +169,8 @@ class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
|||||||
configure_exitCleanup()
|
configure_exitCleanup()
|
||||||
// put things that need to cleanup when exit below
|
// put things that need to cleanup when exit below
|
||||||
// so that it will be correctly cleanup when normal run and will not execute in testRun.
|
// so that it will be correctly cleanup when normal run and will not execute in testRun.
|
||||||
|
modules.foreach(it => it.onStarting(OnStartingContext(
|
||||||
|
initializeContext)))
|
||||||
daemons.start()
|
daemons.start()
|
||||||
logger info "start telegram event listening"
|
logger info "start telegram event listening"
|
||||||
import com.pengrad.telegrambot.TelegramException
|
import com.pengrad.telegrambot.TelegramException
|
||||||
@ -150,18 +219,21 @@ class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
modules.foreach(it => it.onStartingPost(OnStartingPostContext(
|
||||||
|
initializeContext)))
|
||||||
|
|
||||||
if config.commandLoginRefresh then
|
if config.commandLoginRefresh then
|
||||||
logger info "resetting telegram command list"
|
logger info "resetting telegram command list"
|
||||||
commands.automaticTGListUpdate()
|
commands.automaticTGListUpdate()
|
||||||
|
|
||||||
daemons.reporter.reportCoeurMornyLogin()
|
daemons.reporter.reportCoeurMornyLogin()
|
||||||
|
initializeContext = null
|
||||||
logger info "Coeur start complete."
|
logger info "Coeur start complete."
|
||||||
|
|
||||||
///<<< BLOCK END instance configure & startup stage 2
|
///<<< BLOCK END instance configure & startup stage 2
|
||||||
|
|
||||||
def saveDataAll(): Unit = {
|
def saveDataAll(): Unit = {
|
||||||
// nothing to do
|
modules.foreach(it => it.onRoutineSavingData)
|
||||||
logger notice "done all save action."
|
logger notice "done all save action."
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +241,7 @@ class MornyCoeur (using val config: MornyConfig)(testRun: Boolean = false) {
|
|||||||
daemons.reporter.reportCoeurExit()
|
daemons.reporter.reportCoeurExit()
|
||||||
account.shutdown()
|
account.shutdown()
|
||||||
logger info "stopped bot account"
|
logger info "stopped bot account"
|
||||||
|
modules.foreach(it => it.onExit)
|
||||||
daemons.stop()
|
daemons.stop()
|
||||||
tasks.waitForStop()
|
tasks.waitForStop()
|
||||||
logger info s"morny tasks stopped: remains ${tasks.amount} tasks not be executed"
|
logger info s"morny tasks stopped: remains ${tasks.amount} tasks not be executed"
|
||||||
|
99
src/main/scala/cc/sukazyo/cono/morny/MornyCoreModule.scala
Normal file
99
src/main/scala/cc/sukazyo/cono/morny/MornyCoreModule.scala
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package cc.sukazyo.cono.morny
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur.OnInitializingContext
|
||||||
|
|
||||||
|
class MornyCoreModule extends MornyModule {
|
||||||
|
|
||||||
|
override val id: String = "cc.sukazyo.cono.morny.bot"
|
||||||
|
override val name: String = "Morny Coeur - Core (for refactor temporary)"
|
||||||
|
override val version: String = MornySystem.VERSION
|
||||||
|
|
||||||
|
override val description: String | Null =
|
||||||
|
"""Core module of Morny Coeur.
|
||||||
|
|
|
||||||
|
|Exists for temporary use, when refactor completed it should be replaced
|
||||||
|
|by all other small modules that provide different functionality.
|
||||||
|
|""".stripMargin
|
||||||
|
|
||||||
|
override def onInitializing (using MornyCoeur)(cxt: OnInitializingContext): Unit = {
|
||||||
|
import cc.sukazyo.cono.morny.bot.command.*
|
||||||
|
import cc.sukazyo.cono.morny.bot.event.*
|
||||||
|
import cc.sukazyo.cono.morny.bot.query.*
|
||||||
|
import cxt.*
|
||||||
|
|
||||||
|
val $OnUserRandom = OnUserRandom()
|
||||||
|
eventManager.register(
|
||||||
|
// ACTIVITY_RECORDER
|
||||||
|
// KUOHUANHUAN_NEED_SLEEP
|
||||||
|
OnUniMeowTrigger(using commandManager),
|
||||||
|
$OnUserRandom.RandomSelect,
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
$OnUserRandom.尊嘟假嘟,
|
||||||
|
OnQuestionMarkReply(),
|
||||||
|
OnUserSlashAction(),
|
||||||
|
OnCallMe(),
|
||||||
|
OnCallMsgSend(),
|
||||||
|
OnGetSocial(),
|
||||||
|
OnMedicationNotifyApply(),
|
||||||
|
OnEventHackHandle()
|
||||||
|
)
|
||||||
|
|
||||||
|
val $MornyHellos = MornyHellos()
|
||||||
|
val $IP186Query = IP186Query()
|
||||||
|
val $MornyInformation = MornyInformation()
|
||||||
|
val $MornyInformationOlds = MornyInformationOlds(using $MornyInformation)
|
||||||
|
val $MornyManagers = MornyManagers()
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
val $喵呜 = 喵呜()
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
val $创 = 创()
|
||||||
|
commandManager.register(
|
||||||
|
|
||||||
|
$MornyHellos.On,
|
||||||
|
$MornyHellos.Hello,
|
||||||
|
MornyInfoOnStart(),
|
||||||
|
GetUsernameAndId(),
|
||||||
|
EventHack(),
|
||||||
|
Nbnhhsh(),
|
||||||
|
$IP186Query.IP,
|
||||||
|
$IP186Query.Whois,
|
||||||
|
Encryptor(),
|
||||||
|
MornyOldJrrp(),
|
||||||
|
GetSocial(),
|
||||||
|
|
||||||
|
$MornyManagers.SaveData,
|
||||||
|
$MornyInformation,
|
||||||
|
$MornyInformationOlds.Version,
|
||||||
|
$MornyInformationOlds.Runtime,
|
||||||
|
$MornyManagers.Exit,
|
||||||
|
|
||||||
|
Testing(),
|
||||||
|
DirectMsgClear(),
|
||||||
|
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
私わね(),
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
$喵呜.Progynova,
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
$创.Chuang
|
||||||
|
|
||||||
|
)
|
||||||
|
//noinspection NonAsciiCharacters
|
||||||
|
commandManager.registerForUni(
|
||||||
|
$喵呜.抱抱,
|
||||||
|
$喵呜.揉揉,
|
||||||
|
$喵呜.贴贴,
|
||||||
|
$喵呜.蹭蹭
|
||||||
|
)
|
||||||
|
|
||||||
|
queryManager.register(
|
||||||
|
RawText(),
|
||||||
|
MyInformation(),
|
||||||
|
ShareToolTwitter(),
|
||||||
|
ShareToolBilibili(),
|
||||||
|
ShareToolSocialContent()
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
src/main/scala/cc/sukazyo/cono/morny/MornyModule.scala
Normal file
24
src/main/scala/cc/sukazyo/cono/morny/MornyModule.scala
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package cc.sukazyo.cono.morny
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur.*
|
||||||
|
|
||||||
|
trait MornyModule {
|
||||||
|
|
||||||
|
val id: String
|
||||||
|
val name: String
|
||||||
|
val version: String
|
||||||
|
|
||||||
|
val description: String|Null
|
||||||
|
|
||||||
|
def onInitializingPre (using MornyCoeur)(cxt: OnInitializingPreContext): Unit = {}
|
||||||
|
def onInitializing (using MornyCoeur)(cxt: OnInitializingContext): Unit = {}
|
||||||
|
def onInitializingPost (using MornyCoeur)(cxt: OnInitializingPostContext): Unit = {}
|
||||||
|
|
||||||
|
def onStarting (using MornyCoeur)(cxt: OnStartingContext): Unit = {}
|
||||||
|
def onStartingPost (using MornyCoeur)(cxt: OnStartingPostContext): Unit = {}
|
||||||
|
|
||||||
|
def onRoutineSavingData (using MornyCoeur): Unit = {}
|
||||||
|
|
||||||
|
def onExit (using MornyCoeur): Unit = {}
|
||||||
|
|
||||||
|
}
|
@ -158,7 +158,9 @@ object ServerMain {
|
|||||||
Thread.currentThread setName THREAD_MORNY_INIT
|
Thread.currentThread setName THREAD_MORNY_INIT
|
||||||
|
|
||||||
try
|
try
|
||||||
MornyCoeur(using config build)(
|
MornyCoeur(
|
||||||
|
MornyCoreModule() :: Nil
|
||||||
|
)(using config build)(
|
||||||
testRun = mode_testRun
|
testRun = mode_testRun
|
||||||
)
|
)
|
||||||
catch {
|
catch {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.api
|
package cc.sukazyo.cono.morny.bot.api
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
|
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
|
||||||
|
import cc.sukazyo.cono.morny.util.GivenContext
|
||||||
import cc.sukazyo.messiva.utils.StackUtils
|
import cc.sukazyo.messiva.utils.StackUtils
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ class EventEnv (
|
|||||||
case CANCELED (_from: StackTraceElement) extends State with StateSource(_from)
|
case CANCELED (_from: StackTraceElement) extends State with StateSource(_from)
|
||||||
|
|
||||||
private val _status: mutable.ListBuffer[State] = mutable.ListBuffer.empty
|
private val _status: mutable.ListBuffer[State] = mutable.ListBuffer.empty
|
||||||
private val variables: mutable.HashMap[Class[?], Any] = mutable.HashMap.empty
|
val givenCxt: GivenContext = GivenContext()
|
||||||
val timeStartup: EpochMillis = System.currentTimeMillis
|
val timeStartup: EpochMillis = System.currentTimeMillis
|
||||||
|
|
||||||
def isEventOk: Boolean = _status.lastOption match
|
def isEventOk: Boolean = _status.lastOption match
|
||||||
@ -42,24 +43,4 @@ class EventEnv (
|
|||||||
def status: List[State] =
|
def status: List[State] =
|
||||||
_status.toList
|
_status.toList
|
||||||
|
|
||||||
def provide (i: Any): Unit =
|
|
||||||
variables += (i.getClass -> i)
|
|
||||||
|
|
||||||
def consume [T] (t: Class[T]) (consumer: T => Unit): ConsumeResult = {
|
|
||||||
variables get t match
|
|
||||||
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
|
|
||||||
case None => ConsumeResult(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
def consume [T: ClassTag] (consumer: T => Unit): ConsumeResult =
|
|
||||||
variables get classTag[T].runtimeClass match
|
|
||||||
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
|
|
||||||
case None => ConsumeResult(false)
|
|
||||||
|
|
||||||
class ConsumeResult (success: Boolean) {
|
|
||||||
def onfail (processor: => Unit): Unit = {
|
|
||||||
if !success then processor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,69 +8,26 @@ import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
|||||||
import com.pengrad.telegrambot.model.{BotCommand, DeleteMyCommands, Update}
|
import com.pengrad.telegrambot.model.{BotCommand, DeleteMyCommands, Update}
|
||||||
import com.pengrad.telegrambot.request.{SendSticker, SetMyCommands}
|
import com.pengrad.telegrambot.request.{SendSticker, SetMyCommands}
|
||||||
|
|
||||||
import scala.collection.{mutable, SeqMap}
|
import scala.collection.mutable
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
|
|
||||||
class MornyCommands (using coeur: MornyCoeur) {
|
class MornyCommandManager (using coeur: MornyCoeur) {
|
||||||
|
|
||||||
private type CommandMap = SeqMap[String, ISimpleCommand]
|
private type CommandMap = mutable.SeqMap[String, ISimpleCommand]
|
||||||
private def CommandMap (commands: ISimpleCommand*): CommandMap =
|
private val commands: CommandMap = mutable.SeqMap.empty
|
||||||
val stash = mutable.SeqMap.empty[String, ISimpleCommand]
|
def register [T <: ISimpleCommand] (commands: T*): Unit =
|
||||||
for (i <- commands)
|
for (i <- commands)
|
||||||
stash += (i.name -> i)
|
this.commands += (i.name -> i)
|
||||||
for (alias <- i.aliases)
|
for (alias <- i.aliases)
|
||||||
stash += (alias.name -> i)
|
this.commands += (alias.name -> i)
|
||||||
stash
|
|
||||||
|
|
||||||
private val $MornyHellos = MornyHellos()
|
private[bot] val commands_uni: CommandMap = mutable.SeqMap.empty
|
||||||
private val $IP186Query = IP186Query()
|
def registerForUni [T <: ISimpleCommand] (commands: T*): Unit =
|
||||||
private val $MornyInformation = MornyInformation()
|
for (i <- commands)
|
||||||
private val $MornyInformationOlds = MornyInformationOlds(using $MornyInformation)
|
this.commands_uni += (i.name -> i)
|
||||||
private val $MornyManagers = MornyManagers()
|
for (alias <- i.aliases)
|
||||||
//noinspection NonAsciiCharacters
|
this.commands_uni += (alias.name -> i)
|
||||||
private val $喵呜 = 喵呜()
|
|
||||||
//noinspection NonAsciiCharacters
|
|
||||||
private val $创 = 创()
|
|
||||||
private val commands: CommandMap = CommandMap(
|
|
||||||
|
|
||||||
$MornyHellos.On,
|
|
||||||
$MornyHellos.Hello,
|
|
||||||
MornyInfoOnStart(),
|
|
||||||
GetUsernameAndId(),
|
|
||||||
EventHack(),
|
|
||||||
Nbnhhsh(),
|
|
||||||
$IP186Query.IP,
|
|
||||||
$IP186Query.Whois,
|
|
||||||
Encryptor(),
|
|
||||||
MornyOldJrrp(),
|
|
||||||
GetSocial(),
|
|
||||||
|
|
||||||
$MornyManagers.SaveData,
|
|
||||||
$MornyInformation,
|
|
||||||
$MornyInformationOlds.Version,
|
|
||||||
$MornyInformationOlds.Runtime,
|
|
||||||
$MornyManagers.Exit,
|
|
||||||
|
|
||||||
Testing(),
|
|
||||||
DirectMsgClear(),
|
|
||||||
|
|
||||||
//noinspection NonAsciiCharacters
|
|
||||||
私わね(),
|
|
||||||
//noinspection NonAsciiCharacters
|
|
||||||
$喵呜.Progynova,
|
|
||||||
//noinspection NonAsciiCharacters
|
|
||||||
$创.Chuang
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
//noinspection NonAsciiCharacters
|
|
||||||
val commands_uni: CommandMap = CommandMap(
|
|
||||||
$喵呜.抱抱,
|
|
||||||
$喵呜.揉揉,
|
|
||||||
$喵呜.贴贴,
|
|
||||||
$喵呜.蹭蹭
|
|
||||||
)
|
|
||||||
|
|
||||||
def execute (using command: InputCommand, event: Update): Boolean = {
|
def execute (using command: InputCommand, event: Update): Boolean = {
|
||||||
if (commands contains command.command)
|
if (commands contains command.command)
|
@ -1,25 +0,0 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.event
|
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListenerManager
|
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
|
||||||
|
|
||||||
class MornyEventListeners (using manager: EventListenerManager) (using coeur: MornyCoeur) {
|
|
||||||
|
|
||||||
private val $OnUserRandom = OnUserRandom()
|
|
||||||
manager.register(
|
|
||||||
// ACTIVITY_RECORDER
|
|
||||||
// KUOHUANHUAN_NEED_SLEEP
|
|
||||||
OnUniMeowTrigger(using coeur.commands),
|
|
||||||
$OnUserRandom.RandomSelect,
|
|
||||||
//noinspection NonAsciiCharacters
|
|
||||||
$OnUserRandom.尊嘟假嘟,
|
|
||||||
OnQuestionMarkReply(),
|
|
||||||
OnUserSlashAction(),
|
|
||||||
OnCallMe(),
|
|
||||||
OnCallMsgSend(),
|
|
||||||
OnGetSocial(),
|
|
||||||
OnMedicationNotifyApply(),
|
|
||||||
OnEventHackHandle()
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
@ -2,9 +2,8 @@ package cc.sukazyo.cono.morny.bot.event
|
|||||||
|
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
||||||
import cc.sukazyo.cono.morny.bot.query.{InlineQueryUnit, MornyQueries}
|
import cc.sukazyo.cono.morny.bot.query.{InlineQueryUnit, MornyQueryManager}
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
|
||||||
import com.pengrad.telegrambot.model.Update
|
|
||||||
import com.pengrad.telegrambot.model.request.InlineQueryResult
|
import com.pengrad.telegrambot.model.request.InlineQueryResult
|
||||||
import com.pengrad.telegrambot.request.AnswerInlineQuery
|
import com.pengrad.telegrambot.request.AnswerInlineQuery
|
||||||
|
|
||||||
@ -12,7 +11,7 @@ import scala.collection.mutable.ListBuffer
|
|||||||
import scala.language.postfixOps
|
import scala.language.postfixOps
|
||||||
import scala.reflect.ClassTag
|
import scala.reflect.ClassTag
|
||||||
|
|
||||||
class MornyOnInlineQuery (using queryManager: MornyQueries) (using coeur: MornyCoeur) extends EventListener {
|
class MornyOnInlineQuery (using queryManager: MornyQueryManager) (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
override def onInlineQuery (using event: EventEnv): Unit = {
|
override def onInlineQuery (using event: EventEnv): Unit = {
|
||||||
import event.update
|
import event.update
|
||||||
|
@ -3,14 +3,15 @@ package cc.sukazyo.cono.morny.bot.event
|
|||||||
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
||||||
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.bot.command.MornyCommands
|
import cc.sukazyo.cono.morny.bot.command.MornyCommandManager
|
||||||
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}
|
||||||
|
|
||||||
class MornyOnTelegramCommand (using commandManager: MornyCommands) (using coeur: MornyCoeur) extends EventListener {
|
class MornyOnTelegramCommand (using commandManager: MornyCommandManager) (using coeur: MornyCoeur) extends EventListener {
|
||||||
|
|
||||||
override def onMessage (using event: EventEnv): Unit = {
|
override def onMessage (using event: EventEnv): Unit = {
|
||||||
given update: Update = event.update
|
import event.*
|
||||||
|
given Update = update
|
||||||
|
|
||||||
def _isCommandMessage(message: Message): Boolean =
|
def _isCommandMessage(message: Message): Boolean =
|
||||||
if message.text eq null then false
|
if message.text eq null then false
|
||||||
@ -20,7 +21,7 @@ class MornyOnTelegramCommand (using commandManager: MornyCommands) (using coeur:
|
|||||||
|
|
||||||
if !_isCommandMessage(update.message) then return
|
if !_isCommandMessage(update.message) then return
|
||||||
val inputCommand = InputCommand(update.message.text drop 1)
|
val inputCommand = InputCommand(update.message.text drop 1)
|
||||||
event provide inputCommand
|
givenCxt << inputCommand
|
||||||
logger trace ":provided InputCommand for event"
|
logger trace ":provided InputCommand for event"
|
||||||
|
|
||||||
if (!(inputCommand.command matches "^\\w+$"))
|
if (!(inputCommand.command matches "^\\w+$"))
|
||||||
@ -30,7 +31,7 @@ class MornyOnTelegramCommand (using commandManager: MornyCommands) (using coeur:
|
|||||||
else
|
else
|
||||||
logger debug "is command"
|
logger debug "is command"
|
||||||
if commandManager.execute(using inputCommand) then
|
if commandManager.execute(using inputCommand) then
|
||||||
event.setEventOk
|
setEventOk
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.event
|
package cc.sukazyo.cono.morny.bot.event
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener}
|
||||||
import cc.sukazyo.cono.morny.bot.command.MornyCommands
|
import cc.sukazyo.cono.morny.bot.command.MornyCommandManager
|
||||||
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
|
||||||
import cc.sukazyo.cono.morny.Log.logger
|
import cc.sukazyo.cono.morny.Log.logger
|
||||||
|
|
||||||
class OnUniMeowTrigger (using commands: MornyCommands) extends EventListener {
|
class OnUniMeowTrigger (using commands: MornyCommandManager) extends EventListener {
|
||||||
|
|
||||||
override def onMessage (using event: EventEnv): Unit = {
|
override def onMessage (using event: EventEnv): Unit = {
|
||||||
|
import event.*
|
||||||
|
|
||||||
event.consume[InputCommand] { input =>
|
givenCxt >> { (input: InputCommand) =>
|
||||||
logger trace s"got input command {$input} from event-context"
|
logger trace s"got input command {$input} from event-context"
|
||||||
|
|
||||||
for ((name, command_instance) <- commands.commands_uni) {
|
for ((name, command_instance) <- commands.commands_uni) {
|
||||||
@ -20,7 +21,7 @@ class OnUniMeowTrigger (using commands: MornyCommands) extends EventListener {
|
|||||||
event.setEventOk
|
event.setEventOk
|
||||||
}
|
}
|
||||||
|
|
||||||
} onfail { logger trace "not command (for uni-meow)" }
|
} || { logger trace "not command (for uni-meow)" }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,21 +4,19 @@ import cc.sukazyo.cono.morny.bot.query
|
|||||||
import cc.sukazyo.cono.morny.MornyCoeur
|
import cc.sukazyo.cono.morny.MornyCoeur
|
||||||
import com.pengrad.telegrambot.model.Update
|
import com.pengrad.telegrambot.model.Update
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
|
|
||||||
class MornyQueries (using MornyCoeur) {
|
class MornyQueryManager (using MornyCoeur) {
|
||||||
|
|
||||||
private val queryInstances = Set[ITelegramQuery](
|
private val queries = mutable.Queue.empty[ITelegramQuery]
|
||||||
RawText(),
|
|
||||||
MyInformation(),
|
def register (queries: ITelegramQuery*): Unit =
|
||||||
ShareToolTwitter(),
|
this.queries ++= queries
|
||||||
ShareToolBilibili(),
|
|
||||||
ShareToolSocialContent()
|
|
||||||
)
|
|
||||||
|
|
||||||
def query (event: Update): List[InlineQueryUnit[_]] = {
|
def query (event: Update): List[InlineQueryUnit[_]] = {
|
||||||
val results = ListBuffer[InlineQueryUnit[_]]()
|
val results = ListBuffer[InlineQueryUnit[_]]()
|
||||||
for (instance <- queryInstances) {
|
for (instance <- queries) {
|
||||||
val r = instance query event
|
val r = instance query event
|
||||||
if (r != null) results ++= r
|
if (r != null) results ++= r
|
||||||
}
|
}
|
@ -184,12 +184,12 @@ class MornyReport (using coeur: MornyCoeur) {
|
|||||||
//noinspection ScalaWeakerAccess
|
//noinspection ScalaWeakerAccess
|
||||||
case class EventTimeUsed (it: DurationMillis)
|
case class EventTimeUsed (it: DurationMillis)
|
||||||
override def atEventPost (using event: EventEnv): Unit = {
|
override def atEventPost (using event: EventEnv): Unit = {
|
||||||
import event.State
|
import event.*
|
||||||
eventTotal += 1
|
eventTotal += 1
|
||||||
event.state match
|
event.state match
|
||||||
case State.OK(from) =>
|
case State.OK(from) =>
|
||||||
val timeUsed = EventTimeUsed(System.currentTimeMillis - event.timeStartup)
|
val timeUsed = EventTimeUsed(System.currentTimeMillis - event.timeStartup)
|
||||||
event provide timeUsed
|
givenCxt << timeUsed
|
||||||
logger debug
|
logger debug
|
||||||
s"""event done with OK
|
s"""event done with OK
|
||||||
| with time consumed ${timeUsed.it}ms
|
| with time consumed ${timeUsed.it}ms
|
||||||
|
58
src/main/scala/cc/sukazyo/cono/morny/util/GivenContext.scala
Normal file
58
src/main/scala/cc/sukazyo/cono/morny/util/GivenContext.scala
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package cc.sukazyo.cono.morny.util
|
||||||
|
|
||||||
|
import scala.annotation.targetName
|
||||||
|
import scala.collection.mutable
|
||||||
|
import scala.reflect.{classTag, ClassTag}
|
||||||
|
|
||||||
|
class GivenContext {
|
||||||
|
|
||||||
|
private type ImplicitsMap [T <: Any] = mutable.HashMap[Class[?], T]
|
||||||
|
|
||||||
|
private val variables: ImplicitsMap[Any] = mutable.HashMap.empty
|
||||||
|
private val variablesWithOwner: ImplicitsMap[ImplicitsMap[Any]] = mutable.HashMap.empty
|
||||||
|
|
||||||
|
def provide (i: Any): Unit =
|
||||||
|
variables += (i.getClass -> i)
|
||||||
|
def << (i: Any): Unit =
|
||||||
|
this.provide(i)
|
||||||
|
|
||||||
|
def >>[T: ClassTag] (consumer: T => Unit): ConsumeResult =
|
||||||
|
this.use[T](consumer)
|
||||||
|
def use [T: ClassTag] (consumer: T => Unit): ConsumeResult =
|
||||||
|
variables get classTag[T].runtimeClass match
|
||||||
|
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
|
||||||
|
case None => ConsumeResult(false)
|
||||||
|
def consume [T: ClassTag] (consume: T => Unit): ConsumeResult =
|
||||||
|
this.use[T](consume)
|
||||||
|
|
||||||
|
@targetName("ownedBy")
|
||||||
|
def / [O: ClassTag] (owner: O): OwnedContext[O] =
|
||||||
|
OwnedContext[O]()
|
||||||
|
def ownedBy [O: ClassTag]: OwnedContext[O] =
|
||||||
|
OwnedContext[O]()
|
||||||
|
|
||||||
|
class OwnedContext [O: ClassTag] {
|
||||||
|
|
||||||
|
def provide (i: Any): Unit =
|
||||||
|
(variablesWithOwner getOrElseUpdate (classTag[O].runtimeClass, mutable.HashMap.empty))
|
||||||
|
.addOne(i.getClass -> i)
|
||||||
|
def << (i: Any): Unit =
|
||||||
|
this.provide(i)
|
||||||
|
|
||||||
|
def >> [T: ClassTag] (consumer: T => Unit): ConsumeResult =
|
||||||
|
this.use[T](consumer)
|
||||||
|
def use [T: ClassTag] (consumer: T => Unit): ConsumeResult =
|
||||||
|
variablesWithOwner(classTag[O].runtimeClass) get classTag[T].runtimeClass match
|
||||||
|
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
|
||||||
|
case None => ConsumeResult(false)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConsumeResult (success: Boolean) {
|
||||||
|
@targetName("orElse")
|
||||||
|
def || (processor: => Unit): Unit = {
|
||||||
|
if !success then processor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user