diff --git a/README.md b/README.md index 996713e..4bbca55 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ # ~~给所有喜欢morny的大家的~~ Morny Coeur 源代码 +~~"你们又有意见又不发issue这样子我很为难的啊"~~ + ![social preview card](morny-github-social-preview-card@0.75x.png) 一个 telegram 上的服侍 A.C.Sukazyo Eyre 和它的花宫成员的 bot 的内核源 diff --git a/build.gradle b/build.gradle index 35dfc91..0fa5a50 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,7 @@ publishing { repositories{ maven { name 'builds' - url = "file://" + new File("./build/publishing").getAbsolutePath() + url publishLocalArchiveRepoUrl } maven { name '-ws-' diff --git a/gradle.properties b/gradle.properties index 5a613bb..97a0d67 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ ## Core -VERSION = 0.7.0.16 +VERSION = 0.7.1.3 CODENAME = fuzhou diff --git a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java index 37de61b..3d2a77a 100644 --- a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java +++ b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java @@ -4,7 +4,7 @@ package cc.sukazyo.cono.morny; * the final field that will be updated by gradle automatically. */ public class GradleProjectConfigures { - public static final String VERSION = "0.7.0.16"; + public static final String VERSION = "0.7.1.3"; public static final String CODENAME = "fuzhou"; - public static final long COMPILE_TIMESTAMP = 1654072970797L; + public static final long COMPILE_TIMESTAMP = 1654858585641L; } diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java index ac5a6dd..d2cb07e 100644 --- a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java +++ b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java @@ -152,6 +152,7 @@ public class MornyCoeur { isRemoveCommandListWhenExit ); MornyDaemons.start(); + logger.info("start telegram events listening"); EventListeners.registerAllListeners(); INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate); if (isAutomaticResetCommandList) { @@ -187,7 +188,7 @@ public class MornyCoeur { * 为程序在虚拟机上添加退出钩子 */ private void configureSafeExit () { - Runtime.getRuntime().addShutdownHook(new Thread(this::exitCleanup, "Exit-Cleaning")); + Runtime.getRuntime().addShutdownHook(new Thread(this::exitCleanup, "exit-cleaning")); } /** diff --git a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java index d7ec325..9f58547 100644 --- a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java +++ b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java @@ -21,6 +21,8 @@ public class ServerMain { public static final String PROP_TOKEN_KEY = "TELEGRAM_BOT_API_TOKEN"; public static final String PROP_TOKEN_MORNY_KEY = "MORNY_TG_TOKEN"; + private static final String THREAD_MORNY_INIT = "morny-init"; + /** * 程序入口,也是参数处理器
*
@@ -233,6 +235,7 @@ public class ServerMain { logger.info("Parameter required has no value:\n --token."); return; } + Thread.currentThread().setName(THREAD_MORNY_INIT); MornyCoeur.main( api, api4File, key, username, diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/command/MornyCommands.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/MornyCommands.java index 1975177..2918a80 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/command/MornyCommands.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/MornyCommands.java @@ -14,6 +14,7 @@ import com.pengrad.telegrambot.model.request.ParseMode; import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendSticker; import com.pengrad.telegrambot.request.SetMyCommands; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -60,8 +61,7 @@ public class MornyCommands { register( new ON(), - new Hello(), - new HelloOnStart(), + new Hello(), new HelloOnStart(), new GetUsernameAndId(), new EventHack(), new Nbnhhsh(), @@ -71,7 +71,7 @@ public class MornyCommands { new Version(), new MornyRuntime(), new Jrrp(), - new Exit() + new Exit(), new ExitAlias() ); // 特殊的命令 @@ -197,6 +197,11 @@ public class MornyCommands { @Nonnull @Override public String getDescription () { return "关闭 Bot (仅可信成员)"; } @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandExitExec(event); } } + private static class ExitAlias implements ISimpleCommand { + @Nonnull @Override public String getName () { return "quit"; } + @Nullable @Override public String[] getAliases () { return new String[]{"stop"}; } + @Override public void execute (@NotNull InputCommand command, @NotNull Update event) { onCommandExitExec(event); } + } private static void onCommandExitExec (@Nonnull Update event) { if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) { MornyCoeur.extra().exec(new SendSticker( diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java index c50e6b2..3ff7ef6 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/EventListeners.java @@ -14,6 +14,7 @@ public class EventListeners { @SuppressWarnings("unused") static final OnKuohuanhuanNeedSleep KUOHUANHUAN_NEED_SLEEP = new OnKuohuanhuanNeedSleep(); public static final OnUserRandoms USER_RANDOMS = new OnUserRandoms(); public static final OnCallMsgSend CALL_MSG_SEND = new OnCallMsgSend(); + public static final OnMedicationNotifyApply MEDICATION_NOTIFY_APPLY = new OnMedicationNotifyApply(); public static void registerAllListeners () { EventListenerManager.addListener( @@ -26,6 +27,7 @@ public class EventListeners { INLINE_QUERY, CALL_ME, CALL_MSG_SEND, + MEDICATION_NOTIFY_APPLY, EVENT_HACK_HANDLE ); } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnEventHackHandle.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnEventHackHandle.java index a85a980..7189857 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnEventHackHandle.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnEventHackHandle.java @@ -84,12 +84,12 @@ public class OnEventHackHandle extends EventListener { @Override public boolean onChannelPost (@Nonnull Update update) { - return onEventHacked(update, update.channelPost().chat().id(), update.channelPost().from().id()); + return onEventHacked(update, update.channelPost().chat().id(), update.channelPost().chat().id()); } @Override public boolean onEditedChannelPost (@Nonnull Update update) { - return onEventHacked(update, update.editedChannelPost().chat().id(), update.editedChannelPost().from().id()); + return onEventHacked(update, update.editedChannelPost().chat().id(), update.editedChannelPost().chat().id()); } @Override diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnMedicationNotifyApply.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnMedicationNotifyApply.java new file mode 100644 index 0000000..a5bd835 --- /dev/null +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnMedicationNotifyApply.java @@ -0,0 +1,28 @@ +package cc.sukazyo.cono.morny.bot.event; + +import cc.sukazyo.cono.morny.bot.api.EventListener; +import cc.sukazyo.cono.morny.daemon.MedicationTimer; +import cc.sukazyo.cono.morny.daemon.MornyDaemons; +import com.pengrad.telegrambot.model.Message; +import com.pengrad.telegrambot.model.Update; +import org.jetbrains.annotations.NotNull; + +public class OnMedicationNotifyApply extends EventListener { + + @Override + public boolean onEditedChannelPost (@NotNull Update update) { + return editedMessageProcess(update.editedChannelPost()); + } + + @Override + public boolean onEditedMessage (@NotNull Update update) { + return editedMessageProcess(update.editedMessage()); + } + + private boolean editedMessageProcess (Message edited) { + if (edited.chat().id() != MedicationTimer.NOTIFY_CHAT) return false; + MornyDaemons.medicationTimerInstance.refreshNotificationWrite(edited); + return true; + } + +} diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnTelegramCommand.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnTelegramCommand.java index 0c632ab..0266cfa 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnTelegramCommand.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnTelegramCommand.java @@ -8,14 +8,19 @@ import com.pengrad.telegrambot.model.Update; import javax.annotation.Nonnull; +import static cc.sukazyo.cono.morny.Log.logger; + public class OnTelegramCommand extends EventListener { @Override public boolean onMessage (@Nonnull Update event) { - if (event.message().text() == null || !event.message().text().startsWith("/")) { + if (event.message().text() == null || !event.message().text().startsWith("/") || event.message().text().startsWith("/ ")) { + logger.debug("not command"); return false; // 检测到非(命令格式)文本,忽略掉命令处理 } final InputCommand command = new InputCommand(event.message().text().substring(1)); + if (!command.getCommand().matches("^\\w+$")) { logger.debug("not command");return false; } + logger.debug("is command"); if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) { return true; // 检测到命令并非针对 morny,退出整个事件处理链 } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java index 960ff17..900f387 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java @@ -41,7 +41,7 @@ public class OnUserSlashAction extends EventListener { final String[] action = CommonCommand.format(text); action[0] = action[0].substring(1); - if (action[0].matches("^[a-zA-Z_]+$")) { + if (action[0].matches("^\\w+(@\\w+)?$")) { return false; // 忽略掉 Telegram 命令格式的输入 } else if (action[0].contains("/")) { return false; // 忽略掉疑似目录格式的输入 diff --git a/src/main/java/cc/sukazyo/cono/morny/daemon/MedicationTimer.java b/src/main/java/cc/sukazyo/cono/morny/daemon/MedicationTimer.java index 36d464a..5932bb8 100644 --- a/src/main/java/cc/sukazyo/cono/morny/daemon/MedicationTimer.java +++ b/src/main/java/cc/sukazyo/cono/morny/daemon/MedicationTimer.java @@ -1,19 +1,31 @@ package cc.sukazyo.cono.morny.daemon; import cc.sukazyo.cono.morny.MornyCoeur; -import cc.sukazyo.cono.morny.data.TelegramStickers; -import com.pengrad.telegrambot.request.PinChatMessage; -import com.pengrad.telegrambot.request.SendSticker; +import cc.sukazyo.cono.morny.util.CommonFormatUtils; +import com.pengrad.telegrambot.model.Message; +import com.pengrad.telegrambot.model.MessageEntity; +import com.pengrad.telegrambot.model.request.ParseMode; +import com.pengrad.telegrambot.request.EditMessageText; +import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.response.SendResponse; +import java.util.ArrayList; +import java.util.List; + import static cc.sukazyo.cono.morny.Log.logger; public class MedicationTimer extends Thread { - public static final long NOTIFY_RECEIVE_CHAT = 5028252995L; + public static final long NOTIFY_CHAT = -1001729016815L; + public static final String NOTIFY_MESSAGE = "\uD83C\uDF65⏲"; + private static final String DAEMON_THREAD_NAME = "TIMER_Medication"; + + private static final long LAST_NOTIFY_ID_NULL = -1L; + private long lastNotify = LAST_NOTIFY_ID_NULL; + MedicationTimer () { - super("TIMER_Medication"); + super(DAEMON_THREAD_NAME); } @Override @@ -34,9 +46,25 @@ public class MedicationTimer extends Thread { logger.info("MedicationTimer stopped"); } - private static void sendNotification () { - SendResponse m = MornyCoeur.extra().exec(new SendSticker(NOTIFY_RECEIVE_CHAT, TelegramStickers.ID_PROGYNOVA)); - if (m.isOk()) MornyCoeur.extra().exec(new PinChatMessage(NOTIFY_RECEIVE_CHAT, m.message().messageId())); + private void sendNotification () { + final SendResponse resp = MornyCoeur.extra().exec(new SendMessage(NOTIFY_CHAT, NOTIFY_MESSAGE)); + if (resp.isOk()) lastNotify = resp.message().messageId(); + else lastNotify = LAST_NOTIFY_ID_NULL; + } + + public void refreshNotificationWrite (Message edited) { + if (edited.messageId() != lastNotify) return; + final String editTime = CommonFormatUtils.formatDate(edited.editDate()*1000, 8); + ArrayList entities = new ArrayList<>(); + if (edited.entities() != null) entities.addAll(List.of(edited.entities())); + entities.add(new MessageEntity(MessageEntity.Type.italic, edited.text().length() + "\n-- ".length(), editTime.length())); + EditMessageText sending = new EditMessageText( + NOTIFY_CHAT, + edited.messageId(), + edited.text() + "\n-- " + editTime + " --" + ).parseMode(ParseMode.HTML).entities(entities.toArray(MessageEntity[]::new)); + MornyCoeur.extra().exec(sending); + lastNotify = LAST_NOTIFY_ID_NULL; } private static long calcNextRoutineTimestamp () { diff --git a/src/main/java/cc/sukazyo/cono/morny/daemon/MornyDaemons.java b/src/main/java/cc/sukazyo/cono/morny/daemon/MornyDaemons.java index 7fe2678..b7585aa 100644 --- a/src/main/java/cc/sukazyo/cono/morny/daemon/MornyDaemons.java +++ b/src/main/java/cc/sukazyo/cono/morny/daemon/MornyDaemons.java @@ -4,12 +4,11 @@ import static cc.sukazyo.cono.morny.Log.logger; public class MornyDaemons { - static MedicationTimer medicationTimerInstance; + public static final MedicationTimer medicationTimerInstance = new MedicationTimer(); public static void start () { logger.info("ALL Morny Daemons starting..."); TrackerDataManager.init(); - medicationTimerInstance = new MedicationTimer(); medicationTimerInstance.start(); logger.info("Morny Daemons started."); }