mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-23 03:27:39 +08:00
major 0.7 update 整合
> Merge branch 'major/0.7' # Conflicts: # src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java # src/main/java/cc/sukazyo/cono/morny/ServerMain.java # src/main/java/cc/sukazyo/cono/morny/bot/command/MornyCommands.java - 顺手修复了 /start command-name 问题
This commit is contained in:
commit
7ae339f47a
@ -1,6 +1,6 @@
|
|||||||
## Core
|
## Core
|
||||||
|
|
||||||
VERSION = 0.6.5.1
|
VERSION = 0.7.0.11
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
|
|
||||||
|
@ -4,6 +4,6 @@ package cc.sukazyo.cono.morny;
|
|||||||
* the final field that will be updated by gradle automatically.
|
* the final field that will be updated by gradle automatically.
|
||||||
*/
|
*/
|
||||||
public class GradleProjectConfigures {
|
public class GradleProjectConfigures {
|
||||||
public static final String VERSION = "0.6.5.1";
|
public static final String VERSION = "0.7.0.11";
|
||||||
public static final long COMPILE_TIMESTAMP = 1652771241057L;
|
public static final long COMPILE_TIMESTAMP = 1653443614307L;
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,11 @@ import cc.sukazyo.cono.morny.bot.api.OnUpdate;
|
|||||||
import cc.sukazyo.cono.morny.bot.command.MornyCommands;
|
import cc.sukazyo.cono.morny.bot.command.MornyCommands;
|
||||||
import cc.sukazyo.cono.morny.bot.event.EventListeners;
|
import cc.sukazyo.cono.morny.bot.event.EventListeners;
|
||||||
import cc.sukazyo.cono.morny.bot.query.MornyQueries;
|
import cc.sukazyo.cono.morny.bot.query.MornyQueries;
|
||||||
import cc.sukazyo.cono.morny.data.tracker.TrackerDataManager;
|
import cc.sukazyo.cono.morny.daemon.MornyDaemons;
|
||||||
|
import cc.sukazyo.cono.morny.daemon.TrackerDataManager;
|
||||||
import cc.sukazyo.untitled.telegram.api.extra.ExtraAction;
|
import cc.sukazyo.untitled.telegram.api.extra.ExtraAction;
|
||||||
import com.pengrad.telegrambot.TelegramBot;
|
import com.pengrad.telegrambot.TelegramBot;
|
||||||
|
import com.pengrad.telegrambot.model.User;
|
||||||
import com.pengrad.telegrambot.request.GetMe;
|
import com.pengrad.telegrambot.request.GetMe;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -43,7 +45,13 @@ public class MornyCoeur {
|
|||||||
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
||||||
* 是否与定义的 username 符合。如果不符合则会报错。
|
* 是否与定义的 username 符合。如果不符合则会报错。
|
||||||
*/
|
*/
|
||||||
private final String username;
|
public final String username;
|
||||||
|
/**
|
||||||
|
* morny 的 bot 账户的 telegram id<br>
|
||||||
|
* <br>
|
||||||
|
* 这个字段将会在登陆成功后赋值为登录到的 bot 的 id。
|
||||||
|
*/
|
||||||
|
public final long userid;
|
||||||
/**
|
/**
|
||||||
* morny 的事件忽略前缀时间<br>
|
* morny 的事件忽略前缀时间<br>
|
||||||
* <br>
|
* <br>
|
||||||
@ -59,7 +67,7 @@ public class MornyCoeur {
|
|||||||
|
|
||||||
public static final long DINNER_CHAT_ID = -1001707106392L;
|
public static final long DINNER_CHAT_ID = -1001707106392L;
|
||||||
|
|
||||||
private record LogInResult(TelegramBot account, String username) { }
|
private record LogInResult(TelegramBot account, String username, long userid) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行 bot 初始化
|
* 执行 bot 初始化
|
||||||
@ -93,6 +101,7 @@ public class MornyCoeur {
|
|||||||
final LogInResult loginResult = login(botKey, botUsername);
|
final LogInResult loginResult = login(botKey, botUsername);
|
||||||
this.account = loginResult.account;
|
this.account = loginResult.account;
|
||||||
this.username = loginResult.username;
|
this.username = loginResult.username;
|
||||||
|
this.userid = loginResult.userid;
|
||||||
this.trusted = new MornyTrusted(master, trustedChat, trustedRDinner);
|
this.trusted = new MornyTrusted(master, trustedChat, trustedRDinner);
|
||||||
StringBuilder trustedReadersDinnerIds = new StringBuilder();
|
StringBuilder trustedReadersDinnerIds = new StringBuilder();
|
||||||
trusted.getTrustedReadersOfDinnerSet().forEach(id -> trustedReadersDinnerIds.append("\n ").append(id));
|
trusted.getTrustedReadersOfDinnerSet().forEach(id -> trustedReadersDinnerIds.append("\n ").append(id));
|
||||||
@ -131,24 +140,24 @@ public class MornyCoeur {
|
|||||||
boolean isAutomaticResetCommandList, boolean isRemoveCommandListWhenExit
|
boolean isAutomaticResetCommandList, boolean isRemoveCommandListWhenExit
|
||||||
) {
|
) {
|
||||||
if (INSTANCE == null) {
|
if (INSTANCE == null) {
|
||||||
logger.info("System Starting");
|
logger.info("Coeur Starting");
|
||||||
INSTANCE = new MornyCoeur(
|
INSTANCE = new MornyCoeur(
|
||||||
botKey, botUsername,
|
botKey, botUsername,
|
||||||
master, trustedChat, trustedRDinner,
|
master, trustedChat, trustedRDinner,
|
||||||
latestEventTimestamp,
|
latestEventTimestamp,
|
||||||
isRemoveCommandListWhenExit
|
isRemoveCommandListWhenExit
|
||||||
);
|
);
|
||||||
TrackerDataManager.init();
|
MornyDaemons.start();
|
||||||
EventListeners.registerAllListeners();
|
EventListeners.registerAllListeners();
|
||||||
INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate);
|
INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate);
|
||||||
if (isAutomaticResetCommandList) {
|
if (isAutomaticResetCommandList) {
|
||||||
logger.info("resetting telegram command list");
|
logger.info("resetting telegram command list");
|
||||||
commandManager().automaticUpdateList();
|
commandManager().automaticUpdateList();
|
||||||
}
|
}
|
||||||
logger.info("System start complete");
|
logger.info("Coeur start complete");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.error("System already started coeur!!!");
|
logger.error("Coeur already started!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,8 +173,7 @@ public class MornyCoeur {
|
|||||||
*/
|
*/
|
||||||
private void exitCleanup () {
|
private void exitCleanup () {
|
||||||
logger.info("clean:save tracker data.");
|
logger.info("clean:save tracker data.");
|
||||||
TrackerDataManager.DAEMON.interrupt();
|
MornyDaemons.stop();
|
||||||
TrackerDataManager.trackingLock.lock();
|
|
||||||
if (isRemoveCommandListWhenExit) {
|
if (isRemoveCommandListWhenExit) {
|
||||||
commandManager.automaticRemoveList();
|
commandManager.automaticRemoveList();
|
||||||
}
|
}
|
||||||
@ -195,11 +203,11 @@ public class MornyCoeur {
|
|||||||
for (int i = 1; i < 4; i++) {
|
for (int i = 1; i < 4; i++) {
|
||||||
if (i != 1) logger.info("retrying...");
|
if (i != 1) logger.info("retrying...");
|
||||||
try {
|
try {
|
||||||
final String username = account.execute(new GetMe()).user().username();
|
final User remote = account.execute(new GetMe()).user();
|
||||||
if (requireName != null && !requireName.equals(username))
|
if (requireName != null && !requireName.equals(remote.username()))
|
||||||
throw new RuntimeException("Required the bot @" + requireName + " but @" + username + " logged in!");
|
throw new RuntimeException("Required the bot @" + requireName + " but @" + remote.username() + " logged in!");
|
||||||
logger.info("Succeed login to @" + username);
|
logger.info("Succeed login to @" + remote.username());
|
||||||
return new LogInResult(account, username);
|
return new LogInResult(account, remote.username(), remote.id());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.out);
|
e.printStackTrace(System.out);
|
||||||
logger.error("login failed.");
|
logger.error("login failed.");
|
||||||
@ -272,4 +280,6 @@ public class MornyCoeur {
|
|||||||
return INSTANCE.extraActionInstance;
|
return INSTANCE.extraActionInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getUserid () { return INSTANCE.userid; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,8 @@ import static cc.sukazyo.cono.morny.Log.logger;
|
|||||||
*/
|
*/
|
||||||
public class ServerMain {
|
public class ServerMain {
|
||||||
|
|
||||||
private static boolean versionEchoMode = false;
|
public static final String PROP_TOKEN_KEY = "TELEGRAM_BOT_API_TOKEN";
|
||||||
private static boolean welcomeEchoMode = false;
|
public static final String PROP_TOKEN_MORNY_KEY = "MORNY_TG_TOKEN";
|
||||||
|
|
||||||
private static boolean showWelcome = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 程序入口,也是参数处理器<br>
|
* 程序入口,也是参数处理器<br>
|
||||||
@ -77,6 +75,13 @@ public class ServerMain {
|
|||||||
*/
|
*/
|
||||||
public static void main (@Nonnull String[] args) {
|
public static void main (@Nonnull String[] args) {
|
||||||
|
|
||||||
|
//#
|
||||||
|
//# 启动参数设置区块
|
||||||
|
//#
|
||||||
|
|
||||||
|
boolean versionEchoMode = false;
|
||||||
|
boolean welcomeEchoMode = false;
|
||||||
|
boolean showWelcome = true;
|
||||||
String key = null;
|
String key = null;
|
||||||
String username = null;
|
String username = null;
|
||||||
boolean outdatedBlock = false;
|
boolean outdatedBlock = false;
|
||||||
@ -154,6 +159,19 @@ public class ServerMain {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String propToken = null;
|
||||||
|
String propTokenKey = null;
|
||||||
|
for (String iKey : new String[]{PROP_TOKEN_KEY, PROP_TOKEN_MORNY_KEY}) {
|
||||||
|
if (System.getenv(iKey) != null) {
|
||||||
|
propToken = System.getenv(iKey);
|
||||||
|
propTokenKey = iKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#
|
||||||
|
//# 启动相关参数的检查和处理
|
||||||
|
//#
|
||||||
|
|
||||||
if (versionEchoMode) {
|
if (versionEchoMode) {
|
||||||
|
|
||||||
logger.info(String.format("""
|
logger.info(String.format("""
|
||||||
@ -183,6 +201,14 @@ public class ServerMain {
|
|||||||
MornySystem.VERSION, MornySystem.getJarMd5(), GradleProjectConfigures.COMPILE_TIMESTAMP
|
MornySystem.VERSION, MornySystem.getJarMd5(), GradleProjectConfigures.COMPILE_TIMESTAMP
|
||||||
));
|
));
|
||||||
|
|
||||||
|
//#
|
||||||
|
//# Coeur 参数检查和正式启动主程序
|
||||||
|
//#
|
||||||
|
|
||||||
|
if (propToken != null) {
|
||||||
|
key = propToken;
|
||||||
|
logger.info("Parameter <token> set by EnvVar $"+propTokenKey);
|
||||||
|
}
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
logger.info("Parameter required has no value:\n --token.");
|
logger.info("Parameter required has no value:\n --token.");
|
||||||
return;
|
return;
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
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.Chat;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.request.DeleteMessage;
|
||||||
|
import com.pengrad.telegrambot.request.GetChatMember;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.Log.logger;
|
||||||
|
|
||||||
|
public class DirectMsgClear implements ISimpleCommand {
|
||||||
|
|
||||||
|
@Nonnull @Override public String getName () { return "r"; }
|
||||||
|
|
||||||
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
||||||
|
|
||||||
|
logger.debug("Executing command /r");
|
||||||
|
if (event.message().replyToMessage() == null) return;
|
||||||
|
logger.trace("Message is a reply");
|
||||||
|
if (event.message().replyToMessage().from().id() != MornyCoeur.getUserid()) return;
|
||||||
|
logger.trace("Message is from me");
|
||||||
|
if (System.currentTimeMillis()/1000 - event.message().replyToMessage().date() > 48*60*60) return;
|
||||||
|
logger.trace("Message is not older than 48 hours");
|
||||||
|
|
||||||
|
final boolean isTrusted = MornyCoeur.trustedInstance().isTrusted(event.message().from().id());
|
||||||
|
|
||||||
|
if (
|
||||||
|
isTrusted || (
|
||||||
|
event.message().replyToMessage().replyToMessage() != null &&
|
||||||
|
event.message().replyToMessage().replyToMessage().from().id().equals(event.message().from().id())
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
|
||||||
|
MornyCoeur.extra().exec(new DeleteMessage(
|
||||||
|
event.message().chat().id(), event.message().replyToMessage().messageId()
|
||||||
|
));
|
||||||
|
if (event.message().chat().type() == Chat.Type.Private || (
|
||||||
|
MornyCoeur.extra().exec(
|
||||||
|
new GetChatMember(event.message().chat().id(), event.message().from().id())
|
||||||
|
).chatMember().canDeleteMessages()
|
||||||
|
)) {
|
||||||
|
MornyCoeur.extra().exec(new DeleteMessage(
|
||||||
|
event.message().chat().id(), event.message().messageId()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else logger.trace("User is not trusted");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,7 +18,7 @@ import javax.annotation.Nullable;
|
|||||||
*/
|
*/
|
||||||
public class EventHack implements ITelegramCommand {
|
public class EventHack implements ITelegramCommand {
|
||||||
|
|
||||||
@Nonnull @Override public String getName () { return "/event_hack"; }
|
@Nonnull @Override public String getName () { return "event_hack"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return "[(user|group|any)]"; }
|
@Nonnull @Override public String getParamRule () { return "[(user|group|any)]"; }
|
||||||
@Nonnull @Override public String getDescription () { return "输出 bot 下一个获取到的事件序列化数据"; }
|
@Nonnull @Override public String getDescription () { return "输出 bot 下一个获取到的事件序列化数据"; }
|
||||||
|
@ -15,7 +15,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
public class GetUsernameAndId implements ITelegramCommand {
|
public class GetUsernameAndId implements ITelegramCommand {
|
||||||
|
|
||||||
@Nonnull @Override public String getName () { return "/user"; }
|
@Nonnull @Override public String getName () { return "user"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return "[userid]"; }
|
@Nonnull @Override public String getParamRule () { return "[userid]"; }
|
||||||
@Nonnull @Override public String getDescription () { return "获取指定或回复的用户相关信息"; }
|
@Nonnull @Override public String getDescription () { return "获取指定或回复的用户相关信息"; }
|
||||||
|
@ -20,8 +20,11 @@ import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
|
|||||||
*/
|
*/
|
||||||
public class Ip186Query {
|
public class Ip186Query {
|
||||||
|
|
||||||
|
public static final String CMD_IP = "ip";
|
||||||
|
public static final String CMD_WHOIS = "whois";
|
||||||
|
|
||||||
public static class Ip implements ITelegramCommand {
|
public static class Ip implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/ip"; }
|
@Nonnull @Override public String getName () { return CMD_IP; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Nonnull @Override public String getParamRule () { return "[ip]"; }
|
@Nonnull @Override public String getParamRule () { return "[ip]"; }
|
||||||
@Nonnull @Override public String getDescription () { return "通过 https://ip.186526.xyz 查询 ip 资料"; }
|
@Nonnull @Override public String getDescription () { return "通过 https://ip.186526.xyz 查询 ip 资料"; }
|
||||||
@ -29,7 +32,7 @@ public class Ip186Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Whois implements ITelegramCommand {
|
public static class Whois implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/whois"; }
|
@Nonnull @Override public String getName () { return CMD_WHOIS; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Nonnull @Override public String getParamRule () { return "[domain]"; }
|
@Nonnull @Override public String getParamRule () { return "[domain]"; }
|
||||||
@Nonnull @Override public String getDescription () { return "通过 https://ip.186526.xyz 查询域名资料"; }
|
@Nonnull @Override public String getDescription () { return "通过 https://ip.186526.xyz 查询域名资料"; }
|
||||||
@ -62,8 +65,8 @@ public class Ip186Query {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
IP186QueryResponse response = switch (command.getCommand()) {
|
IP186QueryResponse response = switch (command.getCommand()) {
|
||||||
case "/ip" -> IP186QueryHandler.queryIp(arg);
|
case CMD_IP -> IP186QueryHandler.queryIp(arg);
|
||||||
case "/whois" -> IP186QueryHandler.queryWhoisPretty(arg);
|
case CMD_WHOIS -> IP186QueryHandler.queryWhoisPretty(arg);
|
||||||
default -> throw new IllegalArgumentException("Unknown 186-IP query method " + command.getCommand());
|
default -> throw new IllegalArgumentException("Unknown 186-IP query method " + command.getCommand());
|
||||||
};
|
};
|
||||||
MornyCoeur.extra().exec(new SendMessage(
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
@ -61,6 +61,7 @@ public class MornyCommands {
|
|||||||
register(
|
register(
|
||||||
new ON(),
|
new ON(),
|
||||||
new Hello(),
|
new Hello(),
|
||||||
|
new HelloOnStart(),
|
||||||
new GetUsernameAndId(),
|
new GetUsernameAndId(),
|
||||||
new EventHack(),
|
new EventHack(),
|
||||||
new Nbnhhsh(),
|
new Nbnhhsh(),
|
||||||
@ -73,6 +74,11 @@ public class MornyCommands {
|
|||||||
new Exit()
|
new Exit()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 特殊的命令
|
||||||
|
register(
|
||||||
|
new DirectMsgClear()
|
||||||
|
);
|
||||||
|
|
||||||
// 统一注册这些奇怪的东西&.&
|
// 统一注册这些奇怪的东西&.&
|
||||||
register(
|
register(
|
||||||
new 喵呜.抱抱(),
|
new 喵呜.抱抱(),
|
||||||
@ -153,7 +159,7 @@ public class MornyCommands {
|
|||||||
///
|
///
|
||||||
|
|
||||||
private static class ON implements ITelegramCommand {
|
private static class ON implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/o"; }
|
@Nonnull @Override public String getName () { return "o"; }
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override public String[] getAliases () { return null; }
|
@Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@ -169,12 +175,13 @@ public class MornyCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class Hello implements ITelegramCommand {
|
private static class Hello implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/hello"; }
|
@Nonnull @Override public String getName () { return "hello"; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[]{"/hi"}; }
|
@Nullable @Override public String[] getAliases () { return new String[]{"hi"}; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@Nonnull @Override public String getDescription () { return "打招呼"; }
|
@Nonnull @Override public String getDescription () { return "打招呼"; }
|
||||||
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandHelloExec(event); }
|
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandHelloExec(event); }
|
||||||
}
|
}
|
||||||
|
private static class HelloOnStart implements ISimpleCommand { @Nonnull @Override public String getName () { return "start"; }@Nullable @Override public String[] getAliases () { return new String[0]; }@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) { onCommandHelloExec(event); }}
|
||||||
private static void onCommandHelloExec (@Nonnull Update event) {
|
private static void onCommandHelloExec (@Nonnull Update event) {
|
||||||
MornyCoeur.extra().exec(new SendSticker(
|
MornyCoeur.extra().exec(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
@ -184,7 +191,7 @@ public class MornyCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class Exit implements ITelegramCommand {
|
private static class Exit implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/exit"; }
|
@Nonnull @Override public String getName () { return "exit"; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@Nonnull @Override public String getDescription () { return "关闭 Bot (仅可信成员)"; }
|
@Nonnull @Override public String getDescription () { return "关闭 Bot (仅可信成员)"; }
|
||||||
@ -210,7 +217,7 @@ public class MornyCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class Version implements ITelegramCommand {
|
private static class Version implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/version"; }
|
@Nonnull @Override public String getName () { return "version"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@Nonnull @Override public String getDescription () { return "检查 Bot 版本信息"; }
|
@Nonnull @Override public String getDescription () { return "检查 Bot 版本信息"; }
|
||||||
@ -237,7 +244,7 @@ public class MornyCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class MornyRuntime implements ITelegramCommand {
|
private static class MornyRuntime implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/runtime"; }
|
@Nonnull @Override public String getName () { return "runtime"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@Nonnull @Override public String getDescription () { return "获取 Bot 运行时信息(包括版本号)"; }
|
@Nonnull @Override public String getDescription () { return "获取 Bot 运行时信息(包括版本号)"; }
|
||||||
@ -260,12 +267,12 @@ public class MornyCommands {
|
|||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%d</code> cores
|
|
||||||
java runtime:
|
java runtime:
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
vm memory:
|
vm memory:
|
||||||
- <code>%d</code> / <code>%d</code> MB
|
- <code>%d</code> / <code>%d</code> MB
|
||||||
|
- <code>%d</code> cores
|
||||||
coeur version:
|
coeur version:
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
@ -278,15 +285,15 @@ public class MornyCommands {
|
|||||||
- [<code>%d</code>]""",
|
- [<code>%d</code>]""",
|
||||||
// system
|
// system
|
||||||
escapeHtml(hostname),
|
escapeHtml(hostname),
|
||||||
escapeHtml(System.getProperty("os.name")),
|
escapeHtml(String.format("%s (%s)", System.getProperty("os.name"), System.getProperty("os.arch"))),
|
||||||
escapeHtml(System.getProperty("os.version")),
|
escapeHtml(System.getProperty("os.version")),
|
||||||
Runtime.getRuntime().availableProcessors(),
|
|
||||||
// java
|
// java
|
||||||
escapeHtml(System.getProperty("java.vm.name")),
|
escapeHtml(System.getProperty("java.vm.vendor")+"."+System.getProperty("java.vm.name")),
|
||||||
escapeHtml(System.getProperty("java.version")),
|
escapeHtml(System.getProperty("java.vm.version")),
|
||||||
// memory
|
// memory
|
||||||
Runtime.getRuntime().totalMemory() / 1024 / 1024,
|
Runtime.getRuntime().totalMemory() / 1024 / 1024,
|
||||||
Runtime.getRuntime().maxMemory() / 1024 / 1024,
|
Runtime.getRuntime().maxMemory() / 1024 / 1024,
|
||||||
|
Runtime.getRuntime().availableProcessors(),
|
||||||
// version
|
// version
|
||||||
escapeHtml(MornySystem.VERSION),
|
escapeHtml(MornySystem.VERSION),
|
||||||
escapeHtml(MornySystem.getJarMd5()),
|
escapeHtml(MornySystem.getJarMd5()),
|
||||||
@ -302,7 +309,7 @@ public class MornyCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class Jrrp implements ITelegramCommand {
|
private static class Jrrp implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/jrrp"; }
|
@Nonnull @Override public String getName () { return "jrrp"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@Nonnull @Override public String getDescription () { return "获取 (假的) jrrp"; }
|
@Nonnull @Override public String getDescription () { return "获取 (假的) jrrp"; }
|
||||||
@ -322,7 +329,7 @@ public class MornyCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class SaveData implements ITelegramCommand {
|
private static class SaveData implements ITelegramCommand {
|
||||||
@Nonnull @Override public String getName () { return "/save"; }
|
@Nonnull @Override public String getName () { return "save"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return ""; }
|
@Nonnull @Override public String getParamRule () { return ""; }
|
||||||
@Nonnull @Override public String getDescription () { return "保存缓存数据到文件(仅可信成员)"; }
|
@Nonnull @Override public String getDescription () { return "保存缓存数据到文件(仅可信成员)"; }
|
||||||
|
@ -16,7 +16,7 @@ import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
|
|||||||
|
|
||||||
public class Nbnhhsh implements ITelegramCommand {
|
public class Nbnhhsh implements ITelegramCommand {
|
||||||
|
|
||||||
@Nonnull @Override public String getName () { return "/nbnhhsh"; }
|
@Nonnull @Override public String getName () { return "nbnhhsh"; }
|
||||||
@Nullable @Override public String[] getAliases () { return null; }
|
@Nullable @Override public String[] getAliases () { return null; }
|
||||||
@Nonnull @Override public String getParamRule () { return "[text]"; }
|
@Nonnull @Override public String getParamRule () { return "[text]"; }
|
||||||
@Nonnull @Override public String getDescription () { return "检索文本内 nbnhhsh 词条"; }
|
@Nonnull @Override public String getDescription () { return "检索文本内 nbnhhsh 词条"; }
|
||||||
|
@ -13,7 +13,7 @@ import javax.annotation.Nullable;
|
|||||||
public class 喵呜 {
|
public class 喵呜 {
|
||||||
|
|
||||||
public static class 抱抱 implements ISimpleCommand {
|
public static class 抱抱 implements ISimpleCommand {
|
||||||
@Nonnull @Override public String getName () { return "/抱抱"; }
|
@Nonnull @Override public String getName () { return "抱抱"; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
||||||
MornyCoeur.extra().exec(new SendMessage(
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
@ -24,7 +24,7 @@ public class 喵呜 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class 揉揉 implements ISimpleCommand {
|
public static class 揉揉 implements ISimpleCommand {
|
||||||
@Nonnull @Override public String getName () { return "/揉揉"; }
|
@Nonnull @Override public String getName () { return "揉揉"; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
||||||
MornyCoeur.extra().exec(new SendMessage(
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
@ -35,7 +35,7 @@ public class 喵呜 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class 蹭蹭 implements ISimpleCommand {
|
public static class 蹭蹭 implements ISimpleCommand {
|
||||||
@Nonnull @Override public String getName () { return "/蹭蹭"; }
|
@Nonnull @Override public String getName () { return "蹭蹭"; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
||||||
MornyCoeur.extra().exec(new SendMessage(
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
@ -46,7 +46,7 @@ public class 喵呜 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class 贴贴 implements ISimpleCommand {
|
public static class 贴贴 implements ISimpleCommand {
|
||||||
@Nonnull @Override public String getName () { return "/贴贴"; }
|
@Nonnull @Override public String getName () { return "贴贴"; }
|
||||||
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
@Nullable @Override public String[] getAliases () { return new String[0]; }
|
||||||
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
@Override public void execute (@Nonnull InputCommand command, @Nonnull Update event) {
|
||||||
MornyCoeur.extra().exec(new SendMessage(
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
@ -13,7 +13,7 @@ import java.util.concurrent.ThreadLocalRandom;
|
|||||||
public class 私わね implements ISimpleCommand {
|
public class 私わね implements ISimpleCommand {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override public String getName () { return "/me"; }
|
@Override public String getName () { return "me"; }
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override public String[] getAliases () { return null; }
|
@Override public String[] getAliases () { return null; }
|
||||||
|
@ -12,6 +12,8 @@ public class EventListeners {
|
|||||||
public static final OnCallMe CALL_ME = new OnCallMe();
|
public static final OnCallMe CALL_ME = new OnCallMe();
|
||||||
public static final OnEventHackHandle EVENT_HACK_HANDLE = new OnEventHackHandle();
|
public static final OnEventHackHandle EVENT_HACK_HANDLE = new OnEventHackHandle();
|
||||||
public static final OnKuohuanhuanNeedSleep KUOHUANHUAN_NEED_SLEEP = new OnKuohuanhuanNeedSleep();
|
public static final OnKuohuanhuanNeedSleep KUOHUANHUAN_NEED_SLEEP = new OnKuohuanhuanNeedSleep();
|
||||||
|
public static final OnUserRandoms USER_RANDOMS = new OnUserRandoms();
|
||||||
|
public static final OnCallMsgSend CALL_MSG_SEND = new OnCallMsgSend();
|
||||||
|
|
||||||
public static void registerAllListeners () {
|
public static void registerAllListeners () {
|
||||||
EventListenerManager.addListener(
|
EventListenerManager.addListener(
|
||||||
@ -19,9 +21,11 @@ public class EventListeners {
|
|||||||
UPDATE_TIMESTAMP_OFFSET_LOCK,
|
UPDATE_TIMESTAMP_OFFSET_LOCK,
|
||||||
KUOHUANHUAN_NEED_SLEEP,
|
KUOHUANHUAN_NEED_SLEEP,
|
||||||
COMMANDS_LISTENER,
|
COMMANDS_LISTENER,
|
||||||
|
USER_RANDOMS,
|
||||||
USER_SLASH_ACTION,
|
USER_SLASH_ACTION,
|
||||||
INLINE_QUERY,
|
INLINE_QUERY,
|
||||||
CALL_ME,
|
CALL_ME,
|
||||||
|
CALL_MSG_SEND,
|
||||||
EVENT_HACK_HANDLE
|
EVENT_HACK_HANDLE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cc.sukazyo.cono.morny.bot.event;
|
package cc.sukazyo.cono.morny.bot.event;
|
||||||
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
import cc.sukazyo.cono.morny.data.tracker.TrackerDataManager;
|
import cc.sukazyo.cono.morny.daemon.TrackerDataManager;
|
||||||
import com.pengrad.telegrambot.model.Chat;
|
import com.pengrad.telegrambot.model.Chat;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
|
||||||
|
220
src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMsgSend.java
Normal file
220
src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMsgSend.java
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.event;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.pengrad.telegrambot.model.Chat;
|
||||||
|
import com.pengrad.telegrambot.model.Message;
|
||||||
|
import com.pengrad.telegrambot.model.MessageEntity;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
|
import com.pengrad.telegrambot.request.GetChat;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
import com.pengrad.telegrambot.request.SendSticker;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
|
import cc.sukazyo.cono.morny.data.TelegramStickers;
|
||||||
|
import com.pengrad.telegrambot.response.GetChatResponse;
|
||||||
|
import com.pengrad.telegrambot.response.SendResponse;
|
||||||
|
|
||||||
|
import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
|
||||||
|
|
||||||
|
public class OnCallMsgSend extends EventListener {
|
||||||
|
|
||||||
|
private static final Pattern REGEX_MSG_SENDREQ_DATA_HEAD = Pattern.compile("^\\*msg([\\d-]+)(\\*\\S+)?\\n([\\s\\S]+)$");
|
||||||
|
|
||||||
|
private record MessageToSend (
|
||||||
|
String message,
|
||||||
|
MessageEntity[] entities,
|
||||||
|
ParseMode parseMode,
|
||||||
|
long targetId
|
||||||
|
) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMessage(Update update) {
|
||||||
|
|
||||||
|
// 执行体检查
|
||||||
|
if (update.message().chat().type() != Chat.Type.Private) return false;
|
||||||
|
if (update.message().text() == null) return false;
|
||||||
|
if (!update.message().text().startsWith("*msg")) return false;
|
||||||
|
|
||||||
|
// 权限检查
|
||||||
|
if (!MornyCoeur.trustedInstance().isTrusted(update.message().from().id())) {
|
||||||
|
MornyCoeur.extra().exec(new SendSticker(
|
||||||
|
update.message().chat().id(),
|
||||||
|
TelegramStickers.ID_403
|
||||||
|
).replyToMessageId(update.message().messageId()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Message msgsendReqRaw; // 用户书写的发送请求原文
|
||||||
|
MessageToSend msgsendReqBody; // 解析后的发送请求实例
|
||||||
|
|
||||||
|
// *msgsend 发送标识
|
||||||
|
// 处理发送要求
|
||||||
|
if (update.message().text().equals("*msgsend")) {
|
||||||
|
// 发送体处理
|
||||||
|
if (update.message().replyToMessage() == null) return answer404(update);
|
||||||
|
msgsendReqBody = parseRequest(update.message().replyToMessage());
|
||||||
|
if (msgsendReqBody == null) return answer404(update);
|
||||||
|
// 执行发送任务
|
||||||
|
SendResponse sendResponse = MornyCoeur.getAccount().execute(parseMessageToSend(msgsendReqBody));
|
||||||
|
if (!sendResponse.isOk()) { // 发送失败
|
||||||
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
update.message().chat().id(),
|
||||||
|
String.format("""
|
||||||
|
<b><u>%d</u> FAILED</b>
|
||||||
|
<code>%s</code>""",
|
||||||
|
sendResponse.errorCode(),
|
||||||
|
sendResponse.description()
|
||||||
|
)
|
||||||
|
).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
|
} else { // 发送成功信号
|
||||||
|
MornyCoeur.extra().exec(new SendSticker(
|
||||||
|
update.message().chat().id(),
|
||||||
|
TelegramStickers.ID_SENT
|
||||||
|
).replyToMessageId(update.message().messageId()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
// 发送完成/失败 - 事件结束
|
||||||
|
}
|
||||||
|
|
||||||
|
// *msg 检查标识
|
||||||
|
if (update.message().text().equals("*msg")) { // 处理对曾经的原文的检查
|
||||||
|
if (update.message().replyToMessage() == null) {
|
||||||
|
return answer404(update);
|
||||||
|
}
|
||||||
|
msgsendReqRaw = update.message().replyToMessage();
|
||||||
|
} else if (update.message().text().startsWith("*msg")) { // 对接受到的原文进行检查
|
||||||
|
msgsendReqRaw = update.message();
|
||||||
|
} else {
|
||||||
|
return answer404(update); // 未定义的动作
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对发送请求的用户原文进行解析
|
||||||
|
msgsendReqBody = parseRequest(msgsendReqRaw);
|
||||||
|
if (msgsendReqBody == null) {
|
||||||
|
return answer404(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输出发送目标信息
|
||||||
|
GetChatResponse targetChatReq = MornyCoeur.getAccount().execute(new GetChat(msgsendReqBody.targetId()));
|
||||||
|
if (!targetChatReq.isOk()) {
|
||||||
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
update.message().chat().id(),
|
||||||
|
String.format("""
|
||||||
|
<b><u>%d</u> FAILED</b>
|
||||||
|
<code>%s</code>""",
|
||||||
|
targetChatReq.errorCode(),
|
||||||
|
targetChatReq.description()
|
||||||
|
)
|
||||||
|
).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
|
} else {
|
||||||
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
update.message().chat().id(),
|
||||||
|
targetChatReq.chat().type() == Chat.Type.Private ? (
|
||||||
|
String.format("""
|
||||||
|
<i><u>%d</u>@%s</i>
|
||||||
|
🔒 <b>%s</b> %s""",
|
||||||
|
msgsendReqBody.targetId(),
|
||||||
|
escapeHtml(targetChatReq.chat().type().name()),
|
||||||
|
escapeHtml(targetChatReq.chat().firstName()+(targetChatReq.chat().lastName()==null?"":" "+targetChatReq.chat().lastName())),
|
||||||
|
targetChatReq.chat().username()==null?
|
||||||
|
String.format("<a href='tg://user?id=%d'>@@</a>", targetChatReq.chat().id()):
|
||||||
|
(escapeHtml("@"+targetChatReq.chat().username()))
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
String.format("""
|
||||||
|
<i><u>%d</u>@%s</i>:::
|
||||||
|
%s <b>%s</b>%s""",
|
||||||
|
msgsendReqBody.targetId(),
|
||||||
|
escapeHtml(targetChatReq.chat().type().name()),
|
||||||
|
switch (targetChatReq.chat().type()) {
|
||||||
|
case group -> "💭";
|
||||||
|
case channel -> "📢";
|
||||||
|
case supergroup -> "💬";
|
||||||
|
default -> "⭕️";
|
||||||
|
},
|
||||||
|
escapeHtml(targetChatReq.chat().title()),
|
||||||
|
targetChatReq.chat().username() != null?String.format(
|
||||||
|
" @%s", escapeHtml(targetChatReq.chat().username())
|
||||||
|
):""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
|
}
|
||||||
|
// 发送文本测试
|
||||||
|
SendResponse testSendResp = MornyCoeur.getAccount().execute(
|
||||||
|
parseMessageToSend(msgsendReqBody, update.message().chat().id()).replyToMessageId(update.message().messageId())
|
||||||
|
);
|
||||||
|
if (!testSendResp.isOk()) {
|
||||||
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
update.message().chat().id(),
|
||||||
|
String.format("""
|
||||||
|
<b><u>%d</u> FAILED</b>
|
||||||
|
<code>%s</code>""",
|
||||||
|
testSendResp.errorCode(),
|
||||||
|
testSendResp.description()
|
||||||
|
)
|
||||||
|
).replyToMessageId(update.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static MessageToSend parseRequest (@Nonnull Message requestBody) {
|
||||||
|
|
||||||
|
final Matcher matcher = REGEX_MSG_SENDREQ_DATA_HEAD.matcher(requestBody.text());
|
||||||
|
if (matcher.matches()) {
|
||||||
|
long targetId = Long.parseLong(matcher.group(1));
|
||||||
|
ParseMode parseMode = matcher.group(2) == null ? null : switch (matcher.group(2)) {
|
||||||
|
case "*markdown", "*md", "*m↓" -> ParseMode.MarkdownV2;
|
||||||
|
case "*md1" -> ParseMode.Markdown;
|
||||||
|
case "*html" -> ParseMode.HTML;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
final int offset = "*msg".length()+matcher.group(1).length()+(matcher.group(2)==null?0:matcher.group(2).length())+1;
|
||||||
|
final ArrayList<MessageEntity> entities = new ArrayList<>();
|
||||||
|
if (requestBody.entities() != null) for (MessageEntity entity : requestBody.entities()) {
|
||||||
|
final MessageEntity parsed = new MessageEntity(entity.type(), entity.offset() - offset, entity.length());
|
||||||
|
if (entity.url() != null) parsed.url(entity.url());
|
||||||
|
if (entity.user() != null) parsed.user(entity.user());
|
||||||
|
if (entity.language() != null) parsed.language(entity.language());
|
||||||
|
entities.add(parsed);
|
||||||
|
}
|
||||||
|
return new MessageToSend(matcher.group(3), entities.toArray(MessageEntity[]::new), parseMode, targetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static SendMessage parseMessageToSend (@Nonnull MessageToSend body) {
|
||||||
|
return parseMessageToSend(body, body.targetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static SendMessage parseMessageToSend (@Nonnull MessageToSend body, long targetId) {
|
||||||
|
SendMessage sendingBody = new SendMessage(targetId, body.message);
|
||||||
|
if (body.entities != null) sendingBody.entities(body.entities);
|
||||||
|
if (body.parseMode != null) sendingBody.parseMode(body.parseMode);
|
||||||
|
return sendingBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean answer404 (@Nonnull Update update) {
|
||||||
|
MornyCoeur.extra().exec(new SendSticker(
|
||||||
|
update.message().chat().id(),
|
||||||
|
TelegramStickers.ID_404
|
||||||
|
).replyToMessageId(update.message().messageId()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,10 +12,10 @@ public class OnTelegramCommand extends EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMessage (@Nonnull Update event) {
|
public boolean onMessage (@Nonnull Update event) {
|
||||||
if (event.message().text() == null) {
|
if (event.message().text() == null || !event.message().text().startsWith("/")) {
|
||||||
return false; // 检测到无消息文本,忽略掉命令处理
|
return false; // 检测到非(命令格式)文本,忽略掉命令处理
|
||||||
}
|
}
|
||||||
final InputCommand command = new InputCommand(event.message().text());
|
final InputCommand command = new InputCommand(event.message().text().substring(1));
|
||||||
if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) {
|
if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) {
|
||||||
return true; // 检测到命令并非针对 morny,退出整个事件处理链
|
return true; // 检测到命令并非针对 morny,退出整个事件处理链
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
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.command.CommonCommand;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class OnUserRandoms extends EventListener {
|
||||||
|
|
||||||
|
private static final Pattern USER_OR_CN_QUERY = Pattern.compile("(.+)还是(.+)");
|
||||||
|
private static final Pattern USER_OR_EN_QUERY = Pattern.compile("(.+)or(.+)");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMessage (@NotNull Update update) {
|
||||||
|
|
||||||
|
if (update.message().text() == null) return false;
|
||||||
|
if (!update.message().text().startsWith("/")) return false;
|
||||||
|
|
||||||
|
final String[] preProcess = CommonCommand.format(update.message().text());
|
||||||
|
if (preProcess.length > 1) return false;
|
||||||
|
final String query = preProcess[0];
|
||||||
|
|
||||||
|
// ----- START CODE BLOCK COMMENT -----
|
||||||
|
// 这里实现思路和代码优化有至少一半是 copilot 和 IDEA 提供的
|
||||||
|
// 实现思路都可以从人类手里抢一半贡献太恐怖了aba
|
||||||
|
String result = null;
|
||||||
|
final Matcher matcher;
|
||||||
|
if (query.contains("还是")) {
|
||||||
|
matcher = USER_OR_CN_QUERY.matcher(query);
|
||||||
|
} else {
|
||||||
|
matcher = USER_OR_EN_QUERY.matcher(query);
|
||||||
|
}
|
||||||
|
if (matcher.find()) {
|
||||||
|
result = ThreadLocalRandom.current().nextBoolean() ? matcher.group(1) : matcher.group(2);
|
||||||
|
}
|
||||||
|
// ----- STOP CODE BLOCK COMMENT -----
|
||||||
|
|
||||||
|
if (result == null) return false;
|
||||||
|
MornyCoeur.extra().exec(new SendMessage(
|
||||||
|
update.message().chat().id(), result
|
||||||
|
).replyToMessageId(update.message().messageId()));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package cc.sukazyo.cono.morny.daemon;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
|
import cc.sukazyo.cono.morny.data.TelegramStickers;
|
||||||
|
import com.pengrad.telegrambot.request.SendSticker;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.Log.logger;
|
||||||
|
|
||||||
|
public class MedicationTimer extends Thread {
|
||||||
|
|
||||||
|
public static final long NOTIFY_RECEIVE_CHAT = 5028252995L;
|
||||||
|
|
||||||
|
MedicationTimer () {
|
||||||
|
super("TIMER_Medication");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run () {
|
||||||
|
logger.info("MedicationTimer started");
|
||||||
|
while (!interrupted()) {
|
||||||
|
try {
|
||||||
|
waitToNextRoutine();
|
||||||
|
sendNotification();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
interrupt();
|
||||||
|
logger.info("MedicationTimer was interrupted, will be exit now");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Unexpected error occurred");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("MedicationTimer stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sendNotification () {
|
||||||
|
MornyCoeur.extra().exec(new SendSticker(NOTIFY_RECEIVE_CHAT, TelegramStickers.ID_PROGYNOVA));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long calcNextRoutineTimestamp () {
|
||||||
|
return ((System.currentTimeMillis()+8*60*60*1000) / (12*60*60*1000) + 1) * 12*60*60*1000 - 8*60*60*1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitToNextRoutine () throws InterruptedException {
|
||||||
|
sleep(calcNextRoutineTimestamp() - System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/main/java/cc/sukazyo/cono/morny/daemon/MornyDaemons.java
Normal file
31
src/main/java/cc/sukazyo/cono/morny/daemon/MornyDaemons.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package cc.sukazyo.cono.morny.daemon;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.Log.logger;
|
||||||
|
|
||||||
|
public class MornyDaemons {
|
||||||
|
|
||||||
|
static MedicationTimer medicationTimerInstance;
|
||||||
|
|
||||||
|
public static void start () {
|
||||||
|
logger.info("ALL Morny Daemons starting...");
|
||||||
|
TrackerDataManager.init();
|
||||||
|
medicationTimerInstance = new MedicationTimer();
|
||||||
|
medicationTimerInstance.start();
|
||||||
|
logger.info("Morny Daemons started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stop () {
|
||||||
|
|
||||||
|
logger.info("ALL Morny Daemons stopping...");
|
||||||
|
|
||||||
|
TrackerDataManager.DAEMON.interrupt();
|
||||||
|
medicationTimerInstance.interrupt();
|
||||||
|
|
||||||
|
TrackerDataManager.trackingLock.lock();
|
||||||
|
try { medicationTimerInstance.join(); } catch (InterruptedException e) { e.printStackTrace(System.out); }
|
||||||
|
|
||||||
|
logger.info("ALL Morny Daemons STOPPED.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cc.sukazyo.cono.morny.data.tracker;
|
package cc.sukazyo.cono.morny.daemon;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -27,6 +27,7 @@ public class TrackerDataManager {
|
|||||||
@Override
|
@Override
|
||||||
public void run () {
|
public void run () {
|
||||||
trackingLock.lock();
|
trackingLock.lock();
|
||||||
|
logger.info("Tracker started.");
|
||||||
long lastWaitTimestamp = System.currentTimeMillis();
|
long lastWaitTimestamp = System.currentTimeMillis();
|
||||||
boolean postProcess = false;
|
boolean postProcess = false;
|
||||||
do {
|
do {
|
||||||
@ -48,6 +49,7 @@ public class TrackerDataManager {
|
|||||||
else logger.info("nothing to do yet");
|
else logger.info("nothing to do yet");
|
||||||
} while (!postProcess);
|
} while (!postProcess);
|
||||||
trackingLock.unlock();
|
trackingLock.unlock();
|
||||||
|
logger.info("Tracker exited.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -14,5 +14,6 @@ public class TelegramStickers {
|
|||||||
public static final String ID_WAITING = "CAACAgEAAx0CSQh32gABA-8DYbh7W2VhJ490ucfZMUMrgMR2FW4AAm4nAAJ4_MYFjx6zpxJPWsQjBA";
|
public static final String ID_WAITING = "CAACAgEAAx0CSQh32gABA-8DYbh7W2VhJ490ucfZMUMrgMR2FW4AAm4nAAJ4_MYFjx6zpxJPWsQjBA";
|
||||||
public static final String ID_SENT = "CAACAgEAAx0CSQh32gABA--zYbiyU_wOijEitp-0tSl_k7W6l3gAAgMmAAJ4_MYF4GrompjXPx4jBA";
|
public static final String ID_SENT = "CAACAgEAAx0CSQh32gABA--zYbiyU_wOijEitp-0tSl_k7W6l3gAAgMmAAJ4_MYF4GrompjXPx4jBA";
|
||||||
public static final String ID_SAVED = "CAACAgEAAx0CSQh32gABBExuYdB_G0srfhQldRWkBYxWzCOv4-IAApooAAJ4_MYFcjuNZszfQcQjBA";
|
public static final String ID_SAVED = "CAACAgEAAx0CSQh32gABBExuYdB_G0srfhQldRWkBYxWzCOv4-IAApooAAJ4_MYFcjuNZszfQcQjBA";
|
||||||
|
public static final String ID_PROGYNOVA = "CAACAgUAAxkBAAICm2KEuL7UQqNP7vSPCg2DHJIND6UsAAKLAwACH4WSBszIo722aQ3jJAQ";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,41 @@
|
|||||||
package cc.sukazyo.cono.morny.util;
|
package cc.sukazyo.cono.morny.util;
|
||||||
|
|
||||||
import com.pengrad.telegrambot.model.User;
|
import com.pengrad.telegrambot.model.User;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
|
import static cc.sukazyo.untitled.util.telegram.formatting.MsgEscape.escapeHtml;
|
||||||
|
|
||||||
public class TelegramUserInformation {
|
public class TelegramUserInformation {
|
||||||
|
|
||||||
|
public static final String DC_QUERY_SOURCE_SITE = "https://t.me/";
|
||||||
|
public static final Pattern DC_QUERY_PROCESSOR_REGEX = Pattern.compile("(cdn[1-9]).tele(sco.pe|gram-cdn.org)");
|
||||||
|
|
||||||
|
private static final OkHttpClient httpClient = new OkHttpClient();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getDataCenterFromUsername (String username) {
|
||||||
|
final Request request = new Request.Builder().url(DC_QUERY_SOURCE_SITE + username).build();
|
||||||
|
try (Response response = httpClient.newCall(request).execute()) {
|
||||||
|
final ResponseBody body = response.body();
|
||||||
|
if (body == null) return "empty upstream response";
|
||||||
|
final Matcher matcher = DC_QUERY_PROCESSOR_REGEX.matcher(body.string());
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static String informationOutputHTML (User user) {
|
public static String informationOutputHTML (User user) {
|
||||||
|
|
||||||
final StringBuilder userInformation = new StringBuilder();
|
final StringBuilder userInformation = new StringBuilder();
|
||||||
@ -16,7 +46,7 @@ public class TelegramUserInformation {
|
|||||||
user.id()
|
user.id()
|
||||||
));
|
));
|
||||||
if (user.username() == null) {
|
if (user.username() == null) {
|
||||||
userInformation.append("\nusername : <u>null</u>");
|
userInformation.append("\nusername : <u>null</u>\ndatacenter : <u>null</u>");
|
||||||
} else {
|
} else {
|
||||||
userInformation.append(String.format(
|
userInformation.append(String.format(
|
||||||
"""
|
"""
|
||||||
@ -25,6 +55,10 @@ public class TelegramUserInformation {
|
|||||||
- <code>%s</code>""",
|
- <code>%s</code>""",
|
||||||
escapeHtml(user.username())
|
escapeHtml(user.username())
|
||||||
));
|
));
|
||||||
|
// 依赖 username 的 datacenter 查询
|
||||||
|
final String dataCenter = getDataCenterFromUsername(user.username());
|
||||||
|
if (dataCenter == null) { userInformation.append("\ndatacenter : <u>null</u>"); }
|
||||||
|
else { userInformation.append(String.format("\ndatacenter : <code>%s</code>", escapeHtml(dataCenter))); }
|
||||||
}
|
}
|
||||||
if (user.firstName() == null) {
|
if (user.firstName() == null) {
|
||||||
userInformation.append("\nfirstname : <u>null</u>");
|
userInformation.append("\nfirstname : <u>null</u>");
|
||||||
|
Loading…
Reference in New Issue
Block a user