diff --git a/gradle.properties b/gradle.properties
index 68bfd0c..c5f6335 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
## Core
-VERSION = 0.5.0.0
+VERSION = 0.5.0.1
# dependencies
diff --git a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
index b13d0d3..0ce77cb 100644
--- a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
+++ b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
@@ -4,6 +4,6 @@ package cc.sukazyo.cono.morny;
* the final field that will be updated by gradle automatically.
*/
public class GradleProjectConfigures {
- public static final String VERSION = "0.5.0.0";
- public static final long COMPILE_TIMESTAMP = 1643097522208L;
+ public static final String VERSION = "0.5.0.1";
+ public static final long COMPILE_TIMESTAMP = 1643447337882L;
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java
index b745d2d..50b0ef2 100644
--- a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java
+++ b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java
@@ -1,11 +1,13 @@
package cc.sukazyo.cono.morny;
import cc.sukazyo.cono.morny.bot.api.OnUpdate;
+import cc.sukazyo.cono.morny.bot.command.MornyCommands;
import cc.sukazyo.cono.morny.bot.event.EventListeners;
import cc.sukazyo.cono.morny.data.tracker.TrackerDataManager;
import cc.sukazyo.untitled.telegram.api.extra.ExtraAction;
import com.pengrad.telegrambot.TelegramBot;
+import com.pengrad.telegrambot.model.DeleteMyCommands;
import com.pengrad.telegrambot.request.GetMe;
import javax.annotation.Nonnull;
@@ -24,10 +26,13 @@ public class MornyCoeur {
/** 当前 Morny 的{@link MornyTrusted 信任验证机}实例 */
private final MornyTrusted trusted;
+ /** 当前 Morny 的 telegram 命令管理器 */
+ private final MornyCommands commandManager = new MornyCommands();
/** morny 的 bot 账户 */
private final TelegramBot account;
private final ExtraAction extraActionInstance;
+ private final boolean isRemoveCommandListWhenExit;
/**
* morny 的 bot 账户的用户名
*
@@ -67,10 +72,12 @@ public class MornyCoeur {
*/
private MornyCoeur (
@Nonnull String botKey, @Nullable String botUsername,
- long master, long trustedChat, long latestEventTimestamp
+ long master, long trustedChat, long latestEventTimestamp,
+ boolean isRemoveCommandListWhenExit
) {
this.latestEventTimestamp = latestEventTimestamp;
+ this.isRemoveCommandListWhenExit = isRemoveCommandListWhenExit;
configureSafeExit();
logger.info("args key:\n " + botKey);
@@ -113,14 +120,24 @@ public class MornyCoeur {
*/
public static void main (
@Nonnull String botKey, @Nullable String botUsername,
- long master, long trustedChat, long latestEventTimestamp
+ long master, long trustedChat, long latestEventTimestamp,
+ boolean isAutomaticResetCommandList, boolean isRemoveCommandListWhenExit
) {
if (INSTANCE == null) {
logger.info("System Starting");
- INSTANCE = new MornyCoeur(botKey, botUsername, master, trustedChat, latestEventTimestamp);
+ INSTANCE = new MornyCoeur(
+ botKey, botUsername,
+ master, trustedChat,
+ latestEventTimestamp,
+ isRemoveCommandListWhenExit
+ );
TrackerDataManager.init();
EventListeners.registerAllListeners();
INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate);
+ if (isAutomaticResetCommandList) {
+ logger.info("resetting telegram command list");
+ commandManager().automaticUpdateList();
+ }
logger.info("System start complete");
return;
}
@@ -141,13 +158,17 @@ public class MornyCoeur {
private void exitCleanup () {
TrackerDataManager.DAEMON.interrupt();
TrackerDataManager.trackingLock.lock();
+ if (isRemoveCommandListWhenExit) {
+ extra().exec(new DeleteMyCommands());
+ logger.info("cleaned up command list.");
+ }
}
/**
* 为程序在虚拟机上添加退出钩子
*/
private void configureSafeExit () {
- Runtime.getRuntime().addShutdownHook(new Thread(this::exitCleanup));
+ Runtime.getRuntime().addShutdownHook(new Thread(this::exitCleanup, "Exit-Cleaning"));
}
/**
@@ -229,6 +250,11 @@ public class MornyCoeur {
return INSTANCE.trusted;
}
+ @Nonnull
+ public static MornyCommands commandManager () {
+ return INSTANCE.commandManager;
+ }
+
@Nonnull
public static ExtraAction extra () {
return INSTANCE.extraActionInstance;
diff --git a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java
index fcbe489..09590b9 100644
--- a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java
+++ b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java
@@ -49,6 +49,12 @@ public class ServerMain {
* {@code --outdated-block} 会使得 {@link MornyCoeur#latestEventTimestamp}
* 赋值为程序启动的时间,从而造成阻挡程序启动之前的消息事件处理效果。
*
+ *
+ * {@code --auto-cmd-list} 使 morny 在启动时自动依据程序本体更新登录 bot 的命令列表
+ *
+ *
+ * {@code --auto-cmd-remove} 使 morny 在关闭时自动依据程序本体删除 bot 的命令列表
+ *
*
* 除去选项之外,第一个参数会被赋值为 bot 的 telegram bot api token,
* 第二个参数会被赋值为 bot 的 username 限定名。其余的参数会被认定为无法理解。
@@ -59,7 +65,7 @@ public class ServerMain {
* 但实际上这并不影响现在的使用,选项赋值目前仍属于测试功能
* 但请勿混用,这将使两个赋值出现混淆并产生不可知的结果
*
- * @see MornyCoeur#main(String, String, long, long, long)
+ * @see MornyCoeur#main
* @since 0.4.0.0
* @param args 参数组
*/
@@ -70,25 +76,27 @@ public class ServerMain {
boolean outdatedBlock = false;
long master = 793274677L;
long trustedChat = -1001541451710L;
+ boolean autoCmdList = false;
+ boolean autoCmdRemove = false;
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
switch (args[i]) {
- case "--outdated-block" -> {
+ case "--outdated-block", "-ob" -> {
outdatedBlock = true;
continue;
}
- case "--no-hello" -> {
+ case "--no-hello", "-hf" -> {
showWelcome = false;
continue;
}
- case "--only-hello" -> {
+ case "--only-hello", "-o" -> {
welcomeEchoMode = true;
continue;
}
- case "--version" -> {
+ case "--version", "-v" -> {
versionEchoMode = true;
continue;
}
@@ -112,6 +120,14 @@ public class ServerMain {
trustedChat = Long.parseLong(args[i]);
continue;
}
+ case "--auto-cmd-list", "-ca" -> {
+ autoCmdList = true;
+ continue;
+ }
+ case "--auto-cmd-remove", "-cr" -> {
+ autoCmdRemove = true;
+ continue;
+ }
}
} else {
@@ -155,7 +171,12 @@ public class ServerMain {
if (welcomeEchoMode) return;
assert key != null;
- MornyCoeur.main(key, username, master, trustedChat, outdatedBlock?System.currentTimeMillis():0);
+ MornyCoeur.main(
+ key, username,
+ master, trustedChat,
+ outdatedBlock?System.currentTimeMillis():0,
+ autoCmdList, autoCmdRemove
+ );
}
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 198c6c9..19f3078 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
@@ -7,15 +7,19 @@ import cc.sukazyo.cono.morny.data.MornyJrrp;
import cc.sukazyo.cono.morny.data.TelegramStickers;
import cc.sukazyo.untitled.telegram.api.formatting.TGToString;
import cc.sukazyo.untitled.util.telegram.object.InputCommand;
+import com.pengrad.telegrambot.model.BotCommand;
import com.pengrad.telegrambot.model.Update;
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 javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import static cc.sukazyo.cono.morny.Log.logger;
@@ -25,7 +29,7 @@ import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
public class MornyCommands {
- private final Map commands = new HashMap<>();
+ private final Map commands = new LinkedHashMap<>();
private void pushCommandTo (@Nonnull String name, @Nonnull ITelegramCommand instance) {
if (commands.containsKey(name)) {
@@ -52,20 +56,18 @@ public class MornyCommands {
public MornyCommands () {
register(
- // simple commands register
new ON(),
new Hello(),
- new Exit(),
+ new GetUsernameAndId(),
+ new EventHack(),
+ new Nbnhhsh(),
+ new Ip186Query.Ip(),
+ new Ip186Query.Whois(),
+ new SaveData(),
new Version(),
new MornyRuntime(),
new Jrrp(),
- new SaveData(),
- // rich commands register
- new EventHack(),
- new GetUsernameAndId(),
- new Ip186Query.Ip(),
- new Ip186Query.Whois(),
- new Nbnhhsh()
+ new Exit()
);
}
@@ -78,6 +80,43 @@ public class MornyCommands {
return nonCommandExecutable(event, command);
}
+ public void automaticUpdateList () {
+ BotCommand[] commandList = getCommandListTelegram();
+ MornyCoeur.extra().exec(new SetMyCommands(
+ commandList
+ ));
+ logger.info("automatic updated telegram command list :\n" + commandListToString(commandList));
+ }
+
+ private String commandListToString (@Nonnull BotCommand[] list) {
+ StringBuilder builder = new StringBuilder();
+ for (BotCommand signal : list) {
+ builder.append(signal.command()).append(" - ").append(signal.description()).append("\n");
+ }
+ return builder.substring(0, builder.length()-1);
+ }
+
+ public BotCommand[] getCommandListTelegram () {
+ final List telegramFormatListing = new ArrayList<>();
+ commands.forEach((regKey, command) -> {
+ if (regKey.equals(command.getName())) {
+ telegramFormatListing.add(formatTelegramCommandListLine(
+ command.getName(),
+ command.getParamRule(),
+ command.getDescription()
+ ));
+ if (command.getAliases() != null) for (String alias : command.getAliases()) {
+ telegramFormatListing.add(formatTelegramCommandListLine(alias, "", "↑"));
+ }
+ }
+ });
+ return telegramFormatListing.toArray(BotCommand[]::new);
+ }
+
+ private BotCommand formatTelegramCommandListLine (@Nonnull String commandName, @Nonnull String paramRule, @Nonnull String intro) {
+ return new BotCommand(commandName, "".equals(paramRule) ? (intro) : (paramRule+" - "+intro));
+ }
+
private boolean nonCommandExecutable (Update event, InputCommand command) {
if (command.getTarget() == null) return false; // 无法解析的命令,转交事件链后代处理
else { // 无法解析的显式命令格式,报错找不到命令
@@ -90,6 +129,11 @@ public class MornyCommands {
}
}
+ /// /// /// /// /// /// /// /// ///
+ ///
+ /// Old Simple Command Block
+ ///
+
private static class ON implements ITelegramCommand {
@Nonnull @Override public String getName () { return "/on"; }
@Nullable
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 2b971ed..e0f2419 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
@@ -2,7 +2,6 @@ package cc.sukazyo.cono.morny.bot.event;
import cc.sukazyo.cono.morny.MornyCoeur;
import cc.sukazyo.cono.morny.bot.api.EventListener;
-import cc.sukazyo.cono.morny.bot.command.MornyCommands;
import cc.sukazyo.untitled.util.telegram.object.InputCommand;
import com.pengrad.telegrambot.model.Update;
@@ -11,8 +10,6 @@ import javax.annotation.Nonnull;
public class OnTelegramCommand extends EventListener {
- private final MornyCommands commandManager = new MornyCommands();
-
@Override
public boolean onMessage (@Nonnull Update event) {
if (event.message().text() == null) {
@@ -22,7 +19,7 @@ public class OnTelegramCommand extends EventListener {
if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) {
return true; // 检测到命令并非针对 morny,退出整个事件处理链
}
- return commandManager.execute(command, event); // 转交命令管理器执行命令
+ return MornyCoeur.commandManager().execute(command, event); // 转交命令管理器执行命令
}
}