mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 11:14:55 +08:00
[[[release 0.5.0.6]]]
## 📇功能 - 添加了 [inline][li-me] 版本的 /user 目前只支持获取自己的信息 - 添加 [「喵呜」][cm-meow] 系列...命令...? ## 🔌系统接口 - 正式删除了被弃用的 key 和 username 的参数直赋 - 添加自动向 Telegram 同步与清理命令列表的功能 - 添加了启动选项 --auto-cmd-list 控制同步行为 - 添加了启动选项 --auto-cmd-remove 控制清理行为 - 为现在已有的启动行为控制类选项添加了其简写形式 - 添加 TelegramCommand 抽象层与管理类 - 添加了 InlineQuery 抽象层与管理器 ## 🔩技术修改/typo - 关闭 raw 输出 在查询字符串为空时的触发 - 删除显示 186 whois 查询 查询结果的 >>> xxx <<< 后的注释信息
This commit is contained in:
commit
f0821ac492
35
README.md
Normal file
35
README.md
Normal file
@ -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/
|
||||
|
||||
<div align=center>
|
||||
|
||||
# ~~给所有喜欢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]
|
||||
|
||||
<br>
|
||||
|
||||
---
|
||||
|
||||
<br>
|
||||
|
||||
### Libraries Used
|
||||
|
||||
[Java Telegram Bot API][tg4j]
|
||||
|
||||
[SpotBugs Annotations][spotbugs] | [JUnit 5][junit5]
|
||||
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
## Core
|
||||
|
||||
VERSION = 0.4.3.7
|
||||
VERSION = 0.5.0.6
|
||||
|
||||
# dependencies
|
||||
|
||||
|
BIN
morny-github-social-preview-card@0.75x.png
Normal file
BIN
morny-github-social-preview-card@0.75x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
@ -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;
|
||||
}
|
||||
|
@ -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 账户的用户名<br>
|
||||
* <br>
|
||||
@ -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;
|
||||
|
@ -49,6 +49,12 @@ public class ServerMain {
|
||||
* {@code --outdated-block} 会使得 {@link MornyCoeur#latestEventTimestamp}
|
||||
* 赋值为程序启动的时间,从而造成阻挡程序启动之前的消息事件处理效果。
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code --auto-cmd-list} 使 morny 在启动时自动依据程序本体更新登录 bot 的命令列表
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code --auto-cmd-remove} 使 morny 在关闭时自动依据程序本体删除 bot 的命令列表
|
||||
* </li>
|
||||
* </ul>
|
||||
* 除去选项之外,第一个参数会被赋值为 bot 的 telegram bot api token,
|
||||
* 第二个参数会被赋值为 bot 的 username 限定名。其余的参数会被认定为无法理解。<br>
|
||||
@ -59,7 +65,7 @@ public class ServerMain {
|
||||
* <s>但实际上这并不影响现在的使用,选项赋值目前仍属于测试功能</s><br>
|
||||
* <b>但请勿混用</b>,这将使两个赋值出现混淆并<b>产生不可知的结果</b>
|
||||
*
|
||||
* @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
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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} 的命令行前端<br>
|
||||
@ -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;
|
||||
|
@ -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 :
|
||||
- <code>%d</code>""",
|
||||
userId
|
||||
));
|
||||
if (user.username() == null) {
|
||||
userInformation.append("\nusername : <u>null</u>");
|
||||
} else {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
username :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.username())
|
||||
));
|
||||
}
|
||||
if (user.firstName() == null) {
|
||||
userInformation.append("\nfirstname : <u>null</u>");
|
||||
} else {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
firstname :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.firstName())
|
||||
));
|
||||
}
|
||||
if (user.lastName() == null) {
|
||||
userInformation.append("\nlastname : <u>null</u>");
|
||||
} else {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
lastname :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.lastName())
|
||||
));
|
||||
}
|
||||
if (user.languageCode() != null) {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
language-code :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.languageCode())
|
||||
));
|
||||
}
|
||||
|
||||
MornyCoeur.extra().exec(new SendMessage(
|
||||
event.message().chat().id(),
|
||||
userInformation.toString()
|
||||
TelegramUserInformation.informationOutputHTML(user)
|
||||
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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(
|
@ -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<String, ISimpleCommand> 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<BotCommand> 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:
|
||||
- <code>%s</code>
|
||||
core md5_hash:
|
||||
- <code>%s</code>
|
||||
compile timestamp:
|
||||
- <code>%d</code>
|
||||
- <code>%s [UTC]</code>""",
|
||||
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:
|
||||
- <code>%s</code>
|
||||
- <code>%s</code>
|
||||
- <code>%d</code> cores
|
||||
java runtime:
|
||||
- <code>%s</code>
|
||||
- <code>%s</code>
|
||||
vm memory:
|
||||
- <code>%d</code> / <code>%d</code> MB
|
||||
morny version:
|
||||
- <code>%s</code>
|
||||
- <code>%s</code>
|
||||
- <code>%s [UTC]</code>
|
||||
- [<code>%d</code>]
|
||||
continuous:
|
||||
- <code>%s</code>
|
||||
- [<code>%d</code>]
|
||||
- <code>%s [UTC]</code>
|
||||
- [<code>%d</code>]""",
|
||||
// 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的)今天的运气指数是———— <code>%.2f%%</code> %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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
@ -0,0 +1,4 @@
|
||||
package cc.sukazyo.cono.morny.bot.command;
|
||||
|
||||
public class Roll {
|
||||
}
|
59
src/main/java/cc/sukazyo/cono/morny/bot/command/喵呜.java
Normal file
59
src/main/java/cc/sukazyo/cono/morny/bot/command/喵呜.java
Normal file
@ -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(),
|
||||
"<tg-spoiler>(贴贴喵呜&.&)</tg-spoiler>"
|
||||
).parseMode(ParseMode.HTML));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
|
@ -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:
|
||||
- <code>%s</code>
|
||||
core md5_hash:
|
||||
- <code>%s</code>
|
||||
compile timestamp:
|
||||
- <code>%d</code>
|
||||
- <code>%s [UTC]</code>""",
|
||||
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:
|
||||
- <code>%s</code>
|
||||
- <code>%s</code>
|
||||
- <code>%d</code> cores
|
||||
java runtime:
|
||||
- <code>%s</code>
|
||||
- <code>%s</code>
|
||||
vm memory:
|
||||
- <code>%d</code> / <code>%d</code> MB
|
||||
morny version:
|
||||
- <code>%s</code>
|
||||
- <code>%s</code>
|
||||
- <code>%s [UTC]</code>
|
||||
- [<code>%d</code>]
|
||||
continuous:
|
||||
- <code>%s</code>
|
||||
- [<code>%d</code>]
|
||||
- <code>%s [UTC]</code>
|
||||
- [<code>%d</code>]""",
|
||||
// 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的)今天的运气指数是———— <code>%.2f%%</code> %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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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<InlineQueryResult<?>> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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); // 转交命令管理器执行命令
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package cc.sukazyo.cono.morny.bot.event.on_commands;
|
||||
|
||||
public class Roll {
|
||||
}
|
@ -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 <T extends InlineQueryResult<T>> {
|
||||
|
||||
@Nullable
|
||||
T query (Update event);
|
||||
|
||||
}
|
@ -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<ITelegramQuery<?>> queryInstances = new ArrayList<>();
|
||||
|
||||
public MornyQueries () {
|
||||
queryInstances.add(new RawText());
|
||||
queryInstances.add(new MyInformation());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<InlineQueryResult<?>> query (@Nonnull Update event) {
|
||||
final List<InlineQueryResult<?>> results = new ArrayList<>();
|
||||
for (ITelegramQuery<?> instance : queryInstances) {
|
||||
final InlineQueryResult<?> r = instance.query(event);
|
||||
if (r!=null) results.add(r);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -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<InlineQueryResultArticle> {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/cc/sukazyo/cono/morny/bot/query/RawText.java
Normal file
27
src/main/java/cc/sukazyo/cono/morny/bot/query/RawText.java
Normal file
@ -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<InlineQueryResultArticle> {
|
||||
|
||||
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())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -62,6 +62,20 @@ public class IP186QueryHandler {
|
||||
return commonQuery(requestUrl, QUERY_WHOIS_PARAM);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 {@link #queryWhois(String)} 的结果进行裁剪.
|
||||
* <br>
|
||||
* 将会删除返回内容中 {@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();
|
||||
|
@ -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);
|
||||
|
@ -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 :
|
||||
- <code>%d</code>""",
|
||||
user.id()
|
||||
));
|
||||
if (user.username() == null) {
|
||||
userInformation.append("\nusername : <u>null</u>");
|
||||
} else {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
username :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.username())
|
||||
));
|
||||
}
|
||||
if (user.firstName() == null) {
|
||||
userInformation.append("\nfirstname : <u>null</u>");
|
||||
} else {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
firstname :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.firstName())
|
||||
));
|
||||
}
|
||||
if (user.lastName() == null) {
|
||||
userInformation.append("\nlastname : <u>null</u>");
|
||||
} else {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
lastname :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.lastName())
|
||||
));
|
||||
}
|
||||
if (user.languageCode() != null) {
|
||||
userInformation.append(String.format(
|
||||
"""
|
||||
|
||||
language-code :
|
||||
- <code>%s</code>""",
|
||||
escapeHtml(user.languageCode())
|
||||
));
|
||||
}
|
||||
|
||||
return userInformation.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user