diff --git a/README.md b/README.md
new file mode 100644
index 0000000..996713e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+[book]: https://book.sukazyo.cc/morny
+[tg-account]: https://t.me/morny_cono_annie_bot
+[issues]: https://github.com/Eyre-S/Coeur-Morny-Cono/issues
+[todo]: https://github.com/users/Eyre-S/projects/1
+[artifact]: https://mvn.sukazyo.cc/main/cc/sukazyo/morny-coeur
+
+[tg4j]: https://github.com/pengrad/java-telegram-bot-api
+[spotbugs]: https://spotbugs.github.io/
+[junit5]: https://junit.org/junit5/
+
+
+
+# ~~给所有喜欢morny的大家的~~ Morny Coeur 源代码
+
+![social preview card](morny-github-social-preview-card@0.75x.png)
+
+一个 telegram 上的服侍 A.C.Sukazyo Eyre 和它的花宫成员的 bot 的内核源
+
+[Task Listing][todo] | [~~BBS~~][issues] | [Published][artifact]
+
+[说明书][book] | [FindInTelegram][tg-account]
+
+
+
+---
+
+
+
+### Libraries Used
+
+[Java Telegram Bot API][tg4j]
+
+[SpotBugs Annotations][spotbugs] | [JUnit 5][junit5]
+
+
diff --git a/gradle.properties b/gradle.properties
index 78cc80d..6df2753 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
## Core
-VERSION = 0.4.3.7
+VERSION = 0.5.0.6
# dependencies
diff --git a/morny-github-social-preview-card@0.75x.png b/morny-github-social-preview-card@0.75x.png
new file mode 100644
index 0000000..30bf201
Binary files /dev/null and b/morny-github-social-preview-card@0.75x.png differ
diff --git a/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java b/src/main/java/cc/sukazyo/cono/morny/GradleProjectConfigures.java
index 91f2abf..f48072a 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.4.3.7";
- public static final long COMPILE_TIMESTAMP = 1642998030356L;
+ public static final String VERSION = "0.5.0.6";
+ public static final long COMPILE_TIMESTAMP = 1644378359640L;
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java
index b745d2d..2a7d03c 100644
--- a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java
+++ b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java
@@ -1,11 +1,14 @@
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.bot.query.MornyQueries;
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 +27,14 @@ public class MornyCoeur {
/** 当前 Morny 的{@link MornyTrusted 信任验证机}实例 */
private final MornyTrusted trusted;
+ /** 当前 Morny 的 telegram 命令管理器 */
+ private final MornyCommands commandManager = new MornyCommands();
+ private final MornyQueries queryManager = new MornyQueries();
/** morny 的 bot 账户 */
private final TelegramBot account;
private final ExtraAction extraActionInstance;
+ private final boolean isRemoveCommandListWhenExit;
/**
* morny 的 bot 账户的用户名
*
@@ -67,10 +74,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);
@@ -79,7 +88,7 @@ public class MornyCoeur {
}
try {
- final LogInResult loginResult = login(botKey);
+ final LogInResult loginResult = login(botKey, botUsername);
this.account = loginResult.account;
this.username = loginResult.username;
this.trusted = new MornyTrusted(master, trustedChat);
@@ -113,14 +122,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;
}
@@ -139,15 +158,20 @@ public class MornyCoeur {
* 用于退出时进行缓存的任务处理等进行安全退出
*/
private void exitCleanup () {
+ logger.info("clean:save tracker data.");
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"));
}
/**
@@ -161,15 +185,15 @@ public class MornyCoeur {
* @return 成功登录后的 {@link TelegramBot} 对象
*/
@Nonnull
- private LogInResult login (@Nonnull String key) {
+ private static LogInResult login (@Nonnull String key, @Nullable String requireName) {
final TelegramBot account = new TelegramBot(key);
logger.info("Trying to login...");
for (int i = 1; i < 4; i++) {
if (i != 1) logger.info("retrying...");
try {
final String username = account.execute(new GetMe()).user().username();
- if (this.username != null && !this.username.equals(username))
- throw new RuntimeException("Required the bot @" + this.username + " but @" + username + " logged in!");
+ if (requireName != null && !requireName.equals(username))
+ throw new RuntimeException("Required the bot @" + requireName + " but @" + username + " logged in!");
logger.info("Succeed login to @" + username);
return new LogInResult(account, username);
} catch (Exception e) {
@@ -229,6 +253,16 @@ public class MornyCoeur {
return INSTANCE.trusted;
}
+ @Nonnull
+ public static MornyCommands commandManager () {
+ return INSTANCE.commandManager;
+ }
+
+ @Nonnull
+ public static MornyQueries queryManager () {
+ return INSTANCE.queryManager;
+ }
+
@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..b7d9d78 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,17 +120,14 @@ public class ServerMain {
trustedChat = Long.parseLong(args[i]);
continue;
}
- }
-
- } else {
-
- if (key == null) {
- key = args[i];
- continue;
- }
- if (username == null) {
- username = args[i];
- continue;
+ case "--auto-cmd-list", "-ca" -> {
+ autoCmdList = true;
+ continue;
+ }
+ case "--auto-cmd-remove", "-cr" -> {
+ autoCmdRemove = true;
+ continue;
+ }
}
}
@@ -154,8 +159,16 @@ public class ServerMain {
if (showWelcome) logger.info(MornyHello.MORNY_PREVIEW_IMAGE_ASCII);
if (welcomeEchoMode) return;
- assert key != null;
- MornyCoeur.main(key, username, master, trustedChat, outdatedBlock?System.currentTimeMillis():0);
+ if (key == null) {
+ logger.info("Parameter required has no value:\n --token.");
+ return;
+ }
+ MornyCoeur.main(
+ key, username,
+ master, trustedChat,
+ outdatedBlock?System.currentTimeMillis():0,
+ autoCmdList, autoCmdRemove
+ );
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/EventHack.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/EventHack.java
similarity index 78%
rename from src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/EventHack.java
rename to src/main/java/cc/sukazyo/cono/morny/bot/command/EventHack.java
index 36e2571..b43df8d 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/EventHack.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/EventHack.java
@@ -1,4 +1,4 @@
-package cc.sukazyo.cono.morny.bot.event.on_commands;
+package cc.sukazyo.cono.morny.bot.command;
import cc.sukazyo.cono.morny.MornyCoeur;
import cc.sukazyo.cono.morny.MornyTrusted;
@@ -9,11 +9,19 @@ import cc.sukazyo.untitled.util.telegram.object.InputCommand;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.request.SendSticker;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
/**
* {@link OnEventHackHandle} 的命令行前端
* @since 0.4.2.0
*/
-public class EventHack {
+public class EventHack implements ITelegramCommand {
+
+ @Nonnull @Override public String getName () { return "/event_hack"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return "[(user|group|any)]"; }
+ @Nonnull @Override public String getDescription () { return "输出 bot 下一个获取到的事件序列化数据"; }
/**
* {@link OnEventHackHandle} 的命令行前端
@@ -26,7 +34,8 @@ public class EventHack {
* @param command 命令基础参数,解析出的命令对象
* @since 0.4.2.0
*/
- public static void exec (Update event, InputCommand command) {
+ @Override
+ public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
boolean isOk = false;
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/GetUsernameAndId.java
similarity index 54%
rename from src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java
rename to src/main/java/cc/sukazyo/cono/morny/bot/command/GetUsernameAndId.java
index 24fb3df..f7d136f 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/GetUsernameAndId.java
@@ -1,7 +1,8 @@
-package cc.sukazyo.cono.morny.bot.event.on_commands;
+package cc.sukazyo.cono.morny.bot.command;
import cc.sukazyo.cono.morny.MornyCoeur;
-
+import cc.sukazyo.cono.morny.util.TelegramUserInformation;
+import cc.sukazyo.untitled.util.telegram.object.InputCommand;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.model.User;
import com.pengrad.telegrambot.model.request.ParseMode;
@@ -10,12 +11,19 @@ import com.pengrad.telegrambot.request.SendMessage;
import com.pengrad.telegrambot.response.GetChatMemberResponse;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
-import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
-
-public class GetUsernameAndId {
+public class GetUsernameAndId implements ITelegramCommand {
- public static void exec (@Nonnull String[] args, @Nonnull Update event) {
+ @Nonnull @Override public String getName () { return "/user"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return "[userid]"; }
+ @Nonnull @Override public String getDescription () { return "获取指定或回复的用户相关信息"; }
+
+ @Override
+ public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
+
+ final String[] args = command.getArgs();
if (args.length > 1) { MornyCoeur.extra().exec(new SendMessage(
event.message().chat().id(),
@@ -53,59 +61,9 @@ public class GetUsernameAndId {
final User user = response.chatMember().user();
- final StringBuilder userInformation = new StringBuilder();
- userInformation.append(String.format(
- """
- userid :
- - %d
""",
- userId
- ));
- if (user.username() == null) {
- userInformation.append("\nusername : null");
- } else {
- userInformation.append(String.format(
- """
-
- username :
- - %s
""",
- escapeHtml(user.username())
- ));
- }
- if (user.firstName() == null) {
- userInformation.append("\nfirstname : null");
- } else {
- userInformation.append(String.format(
- """
-
- firstname :
- - %s
""",
- escapeHtml(user.firstName())
- ));
- }
- if (user.lastName() == null) {
- userInformation.append("\nlastname : null");
- } else {
- userInformation.append(String.format(
- """
-
- lastname :
- - %s
""",
- escapeHtml(user.lastName())
- ));
- }
- if (user.languageCode() != null) {
- userInformation.append(String.format(
- """
-
- language-code :
- - %s
""",
- escapeHtml(user.languageCode())
- ));
- }
-
MornyCoeur.extra().exec(new SendMessage(
event.message().chat().id(),
- userInformation.toString()
+ TelegramUserInformation.informationOutputHTML(user)
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/command/ISimpleCommand.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/ISimpleCommand.java
new file mode 100644
index 0000000..0f3fea2
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/ISimpleCommand.java
@@ -0,0 +1,19 @@
+package cc.sukazyo.cono.morny.bot.command;
+
+import cc.sukazyo.untitled.util.telegram.object.InputCommand;
+import com.pengrad.telegrambot.model.Update;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public interface ISimpleCommand {
+
+ @Nonnull
+ String getName();
+
+ @Nullable
+ String[] getAliases();
+
+ void execute (@Nonnull InputCommand command, @Nonnull Update event);
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/command/ITelegramCommand.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/ITelegramCommand.java
new file mode 100644
index 0000000..b090a95
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/ITelegramCommand.java
@@ -0,0 +1,12 @@
+package cc.sukazyo.cono.morny.bot.command;
+
+import javax.annotation.Nonnull;
+
+public interface ITelegramCommand extends ISimpleCommand {
+
+ @Nonnull
+ String getParamRule();
+ @Nonnull
+ String getDescription();
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Ip186Query.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/Ip186Query.java
similarity index 61%
rename from src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Ip186Query.java
rename to src/main/java/cc/sukazyo/cono/morny/bot/command/Ip186Query.java
index 48c7f86..7a47390 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Ip186Query.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/Ip186Query.java
@@ -1,4 +1,4 @@
-package cc.sukazyo.cono.morny.bot.event.on_commands;
+package cc.sukazyo.cono.morny.bot.command;
import cc.sukazyo.cono.morny.MornyCoeur;
import cc.sukazyo.cono.morny.data.ip186.IP186QueryResponse;
@@ -7,8 +7,10 @@ import cc.sukazyo.cono.morny.data.ip186.IP186QueryHandler;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.model.request.ParseMode;
import com.pengrad.telegrambot.request.SendMessage;
+import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
@@ -18,7 +20,23 @@ import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
*/
public class Ip186Query {
- public static void exec (@Nonnull Update event, @Nonnull InputCommand command) {
+ public static class Ip implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/ip"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Nonnull @Override public String getParamRule () { return "[ip]"; }
+ @Nonnull @Override public String getDescription () { return "通过 https://ip.186526.xyz 查询 ip 资料"; }
+ @Override public void execute (@NotNull InputCommand command, @NotNull Update event) { exec(event, command); }
+ }
+
+ public static class Whois implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/whois"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Nonnull @Override public String getParamRule () { return "[domain]"; }
+ @Nonnull @Override public String getDescription () { return "通过 https://ip.186526.xyz 查询域名资料"; }
+ @Override public void execute (@NotNull InputCommand command, @NotNull Update event) { exec(event, command); }
+ }
+
+ private static void exec (@Nonnull Update event, @Nonnull InputCommand command) {
String arg = null;
if (!command.hasArgs()) {
@@ -45,7 +63,7 @@ public class Ip186Query {
try {
IP186QueryResponse response = switch (command.getCommand()) {
case "/ip" -> IP186QueryHandler.queryIp(arg);
- case "/whois" -> IP186QueryHandler.queryWhois(arg);
+ case "/whois" -> IP186QueryHandler.queryWhoisPretty(arg);
default -> throw new IllegalArgumentException("Unknown 186-IP query method " + command.getCommand());
};
MornyCoeur.extra().exec(new SendMessage(
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
new file mode 100644
index 0000000..d2fc28b
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/MornyCommands.java
@@ -0,0 +1,335 @@
+package cc.sukazyo.cono.morny.bot.command;
+
+import cc.sukazyo.cono.morny.GradleProjectConfigures;
+import cc.sukazyo.cono.morny.MornyCoeur;
+import cc.sukazyo.cono.morny.MornySystem;
+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.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import static cc.sukazyo.cono.morny.Log.logger;
+import static cc.sukazyo.cono.morny.util.CommonFormatUtils.formatDate;
+import static cc.sukazyo.cono.morny.util.CommonFormatUtils.formatDuration;
+import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
+
+public class MornyCommands {
+
+ private final Map commands = new LinkedHashMap<>();
+
+ private void pushCommandTo (@Nonnull String name, @Nonnull ISimpleCommand instance) {
+ if (commands.containsKey(name)) {
+ logger.warn(String.format("""
+ Telegram command instance named "%s" already exists and will be override by another command instance
+ - current: %s
+ - new : %s""",
+ name,
+ commands.get(name).getClass().getName(),
+ instance.getClass().getName()
+ ));
+ }
+ commands.put(name, instance);
+ }
+
+ public void register (@Nonnull ISimpleCommand... list) {
+ for (ISimpleCommand instance : list) {
+ final String[] aliases = instance.getAliases();
+ pushCommandTo(instance.getName(), instance);
+ if (aliases!=null) for (String alias : aliases) pushCommandTo(alias, instance);
+ }
+ }
+
+ public MornyCommands () {
+
+ register(
+ new ON(),
+ new Hello(),
+ new GetUsernameAndId(),
+ new EventHack(),
+ new Nbnhhsh(),
+ new Ip186Query.Ip(),
+ new Ip186Query.Whois(),
+ new SaveData(),
+ new Version(),
+ new MornyRuntime(),
+ new Jrrp(),
+ new Exit()
+ );
+
+ // 统一注册这些奇怪的东西&.&
+ register(
+ new 喵呜.抱抱(),
+ new 喵呜.揉揉(),
+ new 喵呜.蹭蹭(),
+ new 喵呜.贴贴()
+ );
+
+ }
+
+ public boolean execute (@Nonnull InputCommand command, @Nonnull Update event) {
+ if (commands.containsKey(command.getCommand())) {
+ commands.get(command.getCommand()).execute(command, event);
+ return true;
+ }
+ 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 (command instanceof ITelegramCommand && regKey.equals(command.getName())) {
+ telegramFormatListing.add(formatTelegramCommandListLine(
+ command.getName(),
+ ((ITelegramCommand)command).getParamRule(),
+ ((ITelegramCommand)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 { // 无法解析的显式命令格式,报错找不到命令
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_404
+ ).replyToMessageId(event.message().messageId())
+ );
+ return true;
+ }
+ }
+
+ /// /// /// /// /// /// /// /// ///
+ ///
+ /// Old Simple Command Block
+ ///
+
+ private static class ON implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/on"; }
+ @Nullable
+ @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "检查是否在线"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandOnExec(event); }
+ }
+ private static void onCommandOnExec (@Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_ONLINE_STATUS_RETURN
+ ).replyToMessageId(event.message().messageId())
+ );
+ }
+
+ private static class Hello implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/hello"; }
+ @Nullable @Override public String[] getAliases () { return new String[]{"/hi"}; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "打招呼"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandHelloExec(event); }
+ }
+ private static void onCommandHelloExec (@Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_HELLO
+ ).replyToMessageId(event.message().messageId())
+ );
+ }
+
+ private static class Exit implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/exit"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "关闭 Bot (仅可信成员)"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandExitExec(event); }
+ }
+ private static void onCommandExitExec (@Nonnull Update event) {
+ if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_EXIT
+ ).replyToMessageId(event.message().messageId())
+ );
+ logger.info("Morny exited by user " + TGToString.as(event.message().from()).toStringLogTag());
+ System.exit(0);
+ } else {
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_403
+ ).replyToMessageId(event.message().messageId())
+ );
+ logger.info("403 exited tag from user " + TGToString.as(event.message().from()).toStringLogTag());
+ }
+ }
+
+ private static class Version implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/version"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "检查 Bot 版本信息"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandVersionExec(event); }
+ }
+ private static void onCommandVersionExec (@Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ String.format(
+ """
+ version:
+ - %s
+ core md5_hash:
+ - %s
+ compile timestamp:
+ - %d
+ - %s [UTC]
""",
+ escapeHtml(MornySystem.VERSION),
+ escapeHtml(MornySystem.getJarMd5()),
+ GradleProjectConfigures.COMPILE_TIMESTAMP,
+ escapeHtml(formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0))
+ )
+ ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
+ }
+
+ private static class MornyRuntime implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/runtime"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "获取 Bot 运行时信息(包括版本号)"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandRuntimeExec(event); }
+ }
+ /**
+ * @since 0.4.1.2
+ */
+ private static void onCommandRuntimeExec (@Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ String.format("""
+ system:
+ - %s
+ - %s
+ - %d
cores
+ java runtime:
+ - %s
+ - %s
+ vm memory:
+ - %d
/ %d
MB
+ morny version:
+ - %s
+ - %s
+ - %s [UTC]
+ - [%d
]
+ continuous:
+ - %s
+ - [%d
]
+ - %s [UTC]
+ - [%d
]""",
+ // system
+ escapeHtml(System.getProperty("os.name")),
+ escapeHtml(System.getProperty("os.version")),
+ Runtime.getRuntime().availableProcessors(),
+ // java
+ escapeHtml(System.getProperty("java.vm.name")),
+ escapeHtml(System.getProperty("java.version")),
+ // memory
+ Runtime.getRuntime().totalMemory() / 1024 / 1024,
+ Runtime.getRuntime().maxMemory() / 1024 / 1024,
+ // version
+ escapeHtml(MornySystem.VERSION),
+ escapeHtml(MornySystem.getJarMd5()),
+ escapeHtml(formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)),
+ GradleProjectConfigures.COMPILE_TIMESTAMP,
+ // continuous
+ escapeHtml(formatDuration(System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp)),
+ System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp,
+ escapeHtml(formatDate(MornyCoeur.coeurStartTimestamp, 0)),
+ MornyCoeur.coeurStartTimestamp
+ )
+ ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
+ }
+
+ private static class Jrrp implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/jrrp"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "获取 (假的) jrrp"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandJrrpExec(event); }
+ }
+ private static void onCommandJrrpExec (Update event) {
+ final double jrrp = MornyJrrp.getJrrpFromTelegramUser(event.message().from(), System.currentTimeMillis());
+ final String endChar = jrrp>70 ? "!" : jrrp>30 ? ";" : "...";
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ String.format(
+ "%s 在(utc的)今天的运气指数是———— %.2f%%
%s",
+ TGToString.as(event.message().from()).fullnameRefHtml(),
+ jrrp, escapeHtml(endChar)
+ )
+ ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
+ }
+
+ private static class SaveData implements ITelegramCommand {
+ @Nonnull @Override public String getName () { return "/save"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return ""; }
+ @Nonnull @Override public String getDescription () { return "保存缓存数据到文件(仅可信成员)"; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onSaveDataExec(event); }
+ }
+ /**
+ * @since 0.4.3.0
+ */
+ private static void onSaveDataExec (Update event) {
+ if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
+ logger.info("called save from command by " + TGToString.as(event.message().from()).toStringLogTag());
+ MornyCoeur.callSaveData();
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_SAVED
+ ).replyToMessageId(event.message().messageId())
+ );
+ } else {
+ MornyCoeur.extra().exec(new SendSticker(
+ event.message().chat().id(),
+ TelegramStickers.ID_403
+ ).replyToMessageId(event.message().messageId())
+ );
+ logger.info("403 call save tag from user " + TGToString.as(event.message().from()).toStringLogTag());
+ }
+ }
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Nbnhhsh.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/Nbnhhsh.java
similarity index 79%
rename from src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Nbnhhsh.java
rename to src/main/java/cc/sukazyo/cono/morny/bot/command/Nbnhhsh.java
index 7dd130e..b72127d 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Nbnhhsh.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/Nbnhhsh.java
@@ -1,4 +1,4 @@
-package cc.sukazyo.cono.morny.bot.event.on_commands;
+package cc.sukazyo.cono.morny.bot.command;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.model.request.ParseMode;
@@ -9,11 +9,20 @@ import cc.sukazyo.cono.morny.data.NbnhhshQuery;
import cc.sukazyo.untitled.util.string.StringArrays;
import cc.sukazyo.untitled.util.telegram.object.InputCommand;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
-public class Nbnhhsh {
+public class Nbnhhsh implements ITelegramCommand {
- public static void exec (Update event, InputCommand command) {
+ @Nonnull @Override public String getName () { return "/nbnhhsh"; }
+ @Nullable @Override public String[] getAliases () { return null; }
+ @Nonnull @Override public String getParamRule () { return "[text]"; }
+ @Nonnull @Override public String getDescription () { return "检索文本内 nbnhhsh 词条"; }
+
+ @Override
+ public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
try {
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/command/Roll.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/Roll.java
new file mode 100644
index 0000000..c3c865f
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/Roll.java
@@ -0,0 +1,4 @@
+package cc.sukazyo.cono.morny.bot.command;
+
+public class Roll {
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/command/喵呜.java b/src/main/java/cc/sukazyo/cono/morny/bot/command/喵呜.java
new file mode 100644
index 0000000..ca31006
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/command/喵呜.java
@@ -0,0 +1,59 @@
+package cc.sukazyo.cono.morny.bot.command;
+
+import cc.sukazyo.cono.morny.MornyCoeur;
+import cc.sukazyo.untitled.util.telegram.object.InputCommand;
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.model.request.ParseMode;
+import com.pengrad.telegrambot.request.SendMessage;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+@SuppressWarnings("NonAsciiCharacters")
+public class 喵呜 {
+
+ public static class 抱抱 implements ISimpleCommand {
+ @Nonnull @Override public String getName () { return "/抱抱"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ "抱抱——"
+ ));
+ }
+ }
+
+ public static class 揉揉 implements ISimpleCommand {
+ @Nonnull @Override public String getName () { return "/揉揉"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ "蹭蹭w"
+ ));
+ }
+ }
+
+ public static class 蹭蹭 implements ISimpleCommand {
+ @Nonnull @Override public String getName () { return "/蹭蹭"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ "喵呜~-"
+ ));
+ }
+ }
+
+ public static class 贴贴 implements ISimpleCommand {
+ @Nonnull @Override public String getName () { return "/贴贴"; }
+ @Nullable @Override public String[] getAliases () { return new String[0]; }
+ @Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
+ MornyCoeur.extra().exec(new SendMessage(
+ event.message().chat().id(),
+ "(贴贴喵呜&.&)"
+ ).parseMode(ParseMode.HTML));
+ }
+ }
+
+}
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 716b99d..3920a57 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
@@ -4,11 +4,11 @@ import cc.sukazyo.cono.morny.bot.api.EventListenerManager;
public class EventListeners {
- public static final OnCommandExecute COMMANDS_LISTENER = new OnCommandExecute();
+ public static final OnTelegramCommand COMMANDS_LISTENER = new OnTelegramCommand();
public static final OnActivityRecord ACTIVITY_RECORDER = new OnActivityRecord();
public static final OnUserSlashAction USER_SLASH_ACTION = new OnUserSlashAction();
public static final OnUpdateTimestampOffsetLock UPDATE_TIMESTAMP_OFFSET_LOCK = new OnUpdateTimestampOffsetLock();
- public static final OnInlineQuery INLINE_QUERY = new OnInlineQuery();
+ public static final OnInlineQueries INLINE_QUERY = new OnInlineQueries();
public static final OnCallMe CALL_ME = new OnCallMe();
public static final OnEventHackHandle EVENT_HACK_HANDLE = new OnEventHackHandle();
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java
deleted file mode 100644
index 6196de1..0000000
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package cc.sukazyo.cono.morny.bot.event;
-
-import cc.sukazyo.cono.morny.GradleProjectConfigures;
-import cc.sukazyo.cono.morny.MornyCoeur;
-import cc.sukazyo.cono.morny.MornySystem;
-import cc.sukazyo.cono.morny.bot.api.EventListener;
-import cc.sukazyo.cono.morny.bot.event.on_commands.EventHack;
-import cc.sukazyo.cono.morny.bot.event.on_commands.GetUsernameAndId;
-import cc.sukazyo.cono.morny.bot.event.on_commands.Ip186Query;
-import cc.sukazyo.cono.morny.bot.event.on_commands.Nbnhhsh;
-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.Update;
-import com.pengrad.telegrambot.model.request.ParseMode;
-import com.pengrad.telegrambot.request.SendMessage;
-import com.pengrad.telegrambot.request.SendSticker;
-
-import javax.annotation.Nonnull;
-
-import static cc.sukazyo.cono.morny.Log.logger;
-import static cc.sukazyo.cono.morny.util.CommonFormatUtils.formatDate;
-import static cc.sukazyo.cono.morny.util.CommonFormatUtils.formatDuration;
-import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
-
-public class OnCommandExecute extends EventListener {
-
- @Override
- public boolean onMessage (@Nonnull Update event) {
- if (event.message().text() == null) {
- return false; // 检测到无消息文本,忽略掉命令处理
- }
- final InputCommand command = new InputCommand(event.message().text());
- if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) {
- return true; // 检测到命令并非针对 morny,退出整个事件处理链
- }
- switch (command.getCommand()) {
- case "/user":
- GetUsernameAndId.exec(command.getArgs(), event);
- break;
- case "/event_hack":
- EventHack.exec(event, command);
- break;
- case "/o":
- onCommandOnExec(event);
- break;
- case "/hi":
- case "/hello":
- onCommandHelloExec(event);
- break;
- case "/exit":
- onCommandExitExec(event);
- break;
- case "/version":
- onCommandVersionExec(event);
- break;
- case "/runtime":
- onCommandRuntimeExec(event);
- break;
- case "/save":
- onSaveDataExec(event);
- break;
- case "/jrrp":
- onCommandJrrpExec(event);
- break;
- case "/ip":
- case "/whois":
- Ip186Query.exec(event, command);
- break;
- case "/nbnhhsh":
- Nbnhhsh.exec(event, command);
- break;
- default:
- return nonCommandExecutable(event, command);
- }
- return true; // 命令执行成功,标记事件为已处理,退出事件链
- }
-
- private boolean nonCommandExecutable (Update event, InputCommand command) {
- if (command.getTarget() == null) return false; // 无法解析的命令,转交事件链后代处理
- else { // 无法解析的显式命令格式,报错找不到命令
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_404
- ).replyToMessageId(event.message().messageId())
- );
- return true;
- }
- }
-
- private void onCommandOnExec (@Nonnull Update event) {
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_ONLINE_STATUS_RETURN
- ).replyToMessageId(event.message().messageId())
- );
- }
-
- private void onCommandHelloExec (@Nonnull Update event) {
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_HELLO
- ).replyToMessageId(event.message().messageId())
- );
- }
-
- private void onCommandExitExec (@Nonnull Update event) {
- if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_EXIT
- ).replyToMessageId(event.message().messageId())
- );
- logger.info("Morny exited by user " + TGToString.as(event.message().from()).toStringLogTag());
- System.exit(0);
- } else {
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_403
- ).replyToMessageId(event.message().messageId())
- );
- logger.info("403 exited tag from user " + TGToString.as(event.message().from()).toStringLogTag());
- }
- }
-
- private void onCommandVersionExec (@Nonnull Update event) {
- MornyCoeur.extra().exec(new SendMessage(
- event.message().chat().id(),
- String.format(
- """
- version:
- - %s
- core md5_hash:
- - %s
- compile timestamp:
- - %d
- - %s [UTC]
""",
- escapeHtml(MornySystem.VERSION),
- escapeHtml(MornySystem.getJarMd5()),
- GradleProjectConfigures.COMPILE_TIMESTAMP,
- escapeHtml(formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0))
- )
- ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
- }
-
- /**
- * @since 0.4.1.2
- */
- private void onCommandRuntimeExec (@Nonnull Update event) {
- MornyCoeur.extra().exec(new SendMessage(
- event.message().chat().id(),
- String.format("""
- system:
- - %s
- - %s
- - %d
cores
- java runtime:
- - %s
- - %s
- vm memory:
- - %d
/ %d
MB
- morny version:
- - %s
- - %s
- - %s [UTC]
- - [%d
]
- continuous:
- - %s
- - [%d
]
- - %s [UTC]
- - [%d
]""",
- // system
- escapeHtml(System.getProperty("os.name")),
- escapeHtml(System.getProperty("os.version")),
- Runtime.getRuntime().availableProcessors(),
- // java
- escapeHtml(System.getProperty("java.vm.name")),
- escapeHtml(System.getProperty("java.version")),
- // memory
- Runtime.getRuntime().totalMemory() / 1024 / 1024,
- Runtime.getRuntime().maxMemory() / 1024 / 1024,
- // version
- escapeHtml(MornySystem.VERSION),
- escapeHtml(MornySystem.getJarMd5()),
- escapeHtml(formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)),
- GradleProjectConfigures.COMPILE_TIMESTAMP,
- // continuous
- escapeHtml(formatDuration(System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp)),
- System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp,
- escapeHtml(formatDate(MornyCoeur.coeurStartTimestamp, 0)),
- MornyCoeur.coeurStartTimestamp
- )
- ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
- }
-
- private void onCommandJrrpExec (Update event) {
- final double jrrp = MornyJrrp.getJrrpFromTelegramUser(event.message().from(), System.currentTimeMillis());
- final String endChar = jrrp>70 ? "!" : jrrp>30 ? ";" : "...";
- MornyCoeur.extra().exec(new SendMessage(
- event.message().chat().id(),
- String.format(
- "%s 在(utc的)今天的运气指数是———— %.2f%%
%s",
- TGToString.as(event.message().from()).fullnameRefHtml(),
- jrrp, escapeHtml(endChar)
- )
- ).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
- }
-
- /**
- * @since 0.4.3.0
- */
- private void onSaveDataExec (Update event) {
- if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
- logger.info("called save from command by " + TGToString.as(event.message().from()).toStringLogTag());
- MornyCoeur.callSaveData();
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_SAVED
- ).replyToMessageId(event.message().messageId())
- );
- } else {
- MornyCoeur.extra().exec(new SendSticker(
- event.message().chat().id(),
- TelegramStickers.ID_403
- ).replyToMessageId(event.message().messageId())
- );
- logger.info("403 call save tag from user " + TGToString.as(event.message().from()).toStringLogTag());
- }
- }
-
-}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQuery.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQueries.java
similarity index 50%
rename from src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQuery.java
rename to src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQueries.java
index 5a64be5..4e113c8 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQuery.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnInlineQueries.java
@@ -2,14 +2,12 @@ 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.util.EncryptUtils;
import com.pengrad.telegrambot.model.Update;
-import com.pengrad.telegrambot.model.request.InlineQueryResultArticle;
-import com.pengrad.telegrambot.model.request.InputTextMessageContent;
-import com.pengrad.telegrambot.model.request.ParseMode;
+import com.pengrad.telegrambot.model.request.InlineQueryResult;
import com.pengrad.telegrambot.request.AnswerInlineQuery;
import javax.annotation.Nonnull;
+import java.util.List;
/**
* telegram inlineQuery 功能的处理类,
@@ -17,21 +15,21 @@ import javax.annotation.Nonnull;
*
* @since 0.4.1.3
*/
-public class OnInlineQuery extends EventListener {
+public class OnInlineQueries extends EventListener {
/**
* @since 0.4.1.3
*/
@Override
public boolean onInlineQuery (@Nonnull Update update) {
- MornyCoeur.extra().exec(new AnswerInlineQuery(update.inlineQuery().id(), new InlineQueryResultArticle[]{
- new InlineQueryResultArticle(
- EncryptUtils.encryptByMD5(update.inlineQuery().query()),
- "Raw Input",
- new InputTextMessageContent(update.inlineQuery().query()).parseMode(ParseMode.MarkdownV2)
- )
- }));
+
+ List> results = MornyCoeur.queryManager().query(update);
+
+ if (results.size() == 0) return false;
+
+ MornyCoeur.extra().exec(new AnswerInlineQuery(update.inlineQuery().id(), results.toArray(InlineQueryResult[]::new)));
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
new file mode 100644
index 0000000..e0f2419
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnTelegramCommand.java
@@ -0,0 +1,25 @@
+package cc.sukazyo.cono.morny.bot.event;
+
+import cc.sukazyo.cono.morny.MornyCoeur;
+import cc.sukazyo.cono.morny.bot.api.EventListener;
+import cc.sukazyo.untitled.util.telegram.object.InputCommand;
+
+import com.pengrad.telegrambot.model.Update;
+
+import javax.annotation.Nonnull;
+
+public class OnTelegramCommand extends EventListener {
+
+ @Override
+ public boolean onMessage (@Nonnull Update event) {
+ if (event.message().text() == null) {
+ return false; // 检测到无消息文本,忽略掉命令处理
+ }
+ final InputCommand command = new InputCommand(event.message().text());
+ if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) {
+ return true; // 检测到命令并非针对 morny,退出整个事件处理链
+ }
+ return MornyCoeur.commandManager().execute(command, event); // 转交命令管理器执行命令
+ }
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Roll.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Roll.java
deleted file mode 100644
index 4cb209a..0000000
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/Roll.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package cc.sukazyo.cono.morny.bot.event.on_commands;
-
-public class Roll {
-}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/query/ITelegramQuery.java b/src/main/java/cc/sukazyo/cono/morny/bot/query/ITelegramQuery.java
new file mode 100644
index 0000000..6f1d0da
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/query/ITelegramQuery.java
@@ -0,0 +1,13 @@
+package cc.sukazyo.cono.morny.bot.query;
+
+import javax.annotation.Nullable;
+
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.model.request.InlineQueryResult;
+
+public interface ITelegramQuery > {
+
+ @Nullable
+ T query (Update event);
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/query/MornyQueries.java b/src/main/java/cc/sukazyo/cono/morny/bot/query/MornyQueries.java
new file mode 100644
index 0000000..8bbbd30
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/query/MornyQueries.java
@@ -0,0 +1,29 @@
+package cc.sukazyo.cono.morny.bot.query;
+
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.model.request.InlineQueryResult;
+
+import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MornyQueries {
+
+ private final List> queryInstances = new ArrayList<>();
+
+ public MornyQueries () {
+ queryInstances.add(new RawText());
+ queryInstances.add(new MyInformation());
+ }
+
+ @Nonnull
+ public List> query (@Nonnull Update event) {
+ final List> results = new ArrayList<>();
+ for (ITelegramQuery> instance : queryInstances) {
+ final InlineQueryResult> r = instance.query(event);
+ if (r!=null) results.add(r);
+ }
+ return results;
+ }
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/query/MyInformation.java b/src/main/java/cc/sukazyo/cono/morny/bot/query/MyInformation.java
new file mode 100644
index 0000000..0140b6f
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/query/MyInformation.java
@@ -0,0 +1,26 @@
+package cc.sukazyo.cono.morny.bot.query;
+
+import javax.annotation.Nullable;
+
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.model.request.InlineQueryResultArticle;
+import com.pengrad.telegrambot.model.request.InputTextMessageContent;
+import com.pengrad.telegrambot.model.request.ParseMode;
+
+import cc.sukazyo.cono.morny.util.TelegramUserInformation;
+
+public class MyInformation implements ITelegramQuery {
+
+ public static final String ID_PREFIX = "[morny/info/me]";
+ public static final String TITLE = "My Account Information";
+
+ @Override
+ @Nullable
+ public InlineQueryResultArticle query(Update event) {
+ if (!(event.inlineQuery().query() == null || "".equals(event.inlineQuery().query()))) return null;
+ return new InlineQueryResultArticle(ID_PREFIX, TITLE, new InputTextMessageContent(
+ TelegramUserInformation.informationOutputHTML(event.inlineQuery().from())
+ ).parseMode(ParseMode.HTML));
+ }
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/query/RawText.java b/src/main/java/cc/sukazyo/cono/morny/bot/query/RawText.java
new file mode 100644
index 0000000..2e3cceb
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/query/RawText.java
@@ -0,0 +1,27 @@
+package cc.sukazyo.cono.morny.bot.query;
+
+import cc.sukazyo.cono.morny.util.EncryptUtils;
+
+import javax.annotation.Nullable;
+
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.model.request.InlineQueryResultArticle;
+import com.pengrad.telegrambot.model.request.InputTextMessageContent;
+
+public class RawText implements ITelegramQuery {
+
+ public static final String ID_PREFIX = "[morny/r/text]";
+ public static final String TITLE = "Raw Text";
+
+ @Override
+ @Nullable
+ public InlineQueryResultArticle query (Update event) {
+ if (event.inlineQuery().query() == null || "".equals(event.inlineQuery().query())) return null;
+ return new InlineQueryResultArticle(
+ ID_PREFIX + EncryptUtils.encryptByMD5(event.inlineQuery().query()),
+ TITLE,
+ new InputTextMessageContent(event.inlineQuery().query())
+ );
+ }
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/data/ip186/IP186QueryHandler.java b/src/main/java/cc/sukazyo/cono/morny/data/ip186/IP186QueryHandler.java
index c29d0b9..0f60d81 100644
--- a/src/main/java/cc/sukazyo/cono/morny/data/ip186/IP186QueryHandler.java
+++ b/src/main/java/cc/sukazyo/cono/morny/data/ip186/IP186QueryHandler.java
@@ -62,6 +62,20 @@ public class IP186QueryHandler {
return commonQuery(requestUrl, QUERY_WHOIS_PARAM);
}
+ /**
+ * 将 {@link #queryWhois(String)} 的结果进行裁剪.
+ *
+ * 将会删除返回内容中 {@code >>> XXX <<<} 行以后的注释串,
+ * 以达到只保留重要信息的目的。
+ *
+ * @see #queryWhois(String)
+ */
+ @Nonnull
+ public static IP186QueryResponse queryWhoisPretty (String domain) throws IOException {
+ final IP186QueryResponse raw = queryWhois(domain);
+ return new IP186QueryResponse(raw.url(), raw.body().substring(0, raw.body().indexOf("<<<")+3));
+ }
+
@Nonnull
private static IP186QueryResponse commonQuery (String requestUrl, String queryIpParam) throws IOException {
Request request = new Request.Builder().url(requestUrl + "?" + queryIpParam).build();
diff --git a/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java b/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java
index 06945ab..7b2372f 100644
--- a/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java
+++ b/src/main/java/cc/sukazyo/cono/morny/data/tracker/TrackerDataManager.java
@@ -43,7 +43,7 @@ public class TrackerDataManager {
logger.info("CALLED TO EXIT! writing cache.");
}
if (record.size() != 0) {
- save(reset());
+ save();
}
else logger.info("nothing to do yet");
} while (!postProcess);
diff --git a/src/main/java/cc/sukazyo/cono/morny/util/TelegramUserInformation.java b/src/main/java/cc/sukazyo/cono/morny/util/TelegramUserInformation.java
new file mode 100644
index 0000000..011e4da
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/util/TelegramUserInformation.java
@@ -0,0 +1,64 @@
+package cc.sukazyo.cono.morny.util;
+
+import com.pengrad.telegrambot.model.User;
+
+import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
+public class TelegramUserInformation {
+
+ public static String informationOutputHTML (User user) {
+
+ final StringBuilder userInformation = new StringBuilder();
+ userInformation.append(String.format(
+ """
+ userid :
+ - %d
""",
+ user.id()
+ ));
+ if (user.username() == null) {
+ userInformation.append("\nusername : null");
+ } else {
+ userInformation.append(String.format(
+ """
+
+ username :
+ - %s
""",
+ escapeHtml(user.username())
+ ));
+ }
+ if (user.firstName() == null) {
+ userInformation.append("\nfirstname : null");
+ } else {
+ userInformation.append(String.format(
+ """
+
+ firstname :
+ - %s
""",
+ escapeHtml(user.firstName())
+ ));
+ }
+ if (user.lastName() == null) {
+ userInformation.append("\nlastname : null");
+ } else {
+ userInformation.append(String.format(
+ """
+
+ lastname :
+ - %s
""",
+ escapeHtml(user.lastName())
+ ));
+ }
+ if (user.languageCode() != null) {
+ userInformation.append(String.format(
+ """
+
+ language-code :
+ - %s
""",
+ escapeHtml(user.languageCode())
+ ));
+ }
+
+ return userInformation.toString();
+
+ }
+
+}