mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-22 19:24:53 +08:00
使 MornyCoeur 和 MornyTrusted 对象封装,添加 master 和 trustedChat 定义参数
This commit is contained in:
parent
6a5a23b6be
commit
def7ee79c2
@ -1,6 +1,6 @@
|
|||||||
## Core
|
## Core
|
||||||
|
|
||||||
VERSION = 0.4.2.6
|
VERSION = 0.4.2.7
|
||||||
|
|
||||||
# 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.4.2.6";
|
public static final String VERSION = "0.4.2.7";
|
||||||
public static final long COMPILE_TIMESTAMP = 1640065256004L;
|
public static final long COMPILE_TIMESTAMP = 1640104964102L;
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,14 @@ import static cc.sukazyo.cono.morny.Log.logger;
|
|||||||
*/
|
*/
|
||||||
public class MornyCoeur {
|
public class MornyCoeur {
|
||||||
|
|
||||||
|
/** 当前程序的 Morny Coeur 实例 */
|
||||||
|
private static MornyCoeur INSTANCE;
|
||||||
|
|
||||||
|
/** 当前 Morny 的{@link MornyTrusted 信任验证机}实例 */
|
||||||
|
private final MornyTrusted trusted;
|
||||||
|
|
||||||
/** morny 的 bot 账户 */
|
/** morny 的 bot 账户 */
|
||||||
private static TelegramBot account;
|
private final TelegramBot account;
|
||||||
/**
|
/**
|
||||||
* morny 的 bot 账户的用户名<br>
|
* morny 的 bot 账户的用户名<br>
|
||||||
* <br>
|
* <br>
|
||||||
@ -28,36 +34,40 @@ public class MornyCoeur {
|
|||||||
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
||||||
* 是否与定义的 username 符合。如果不符合则会报错。
|
* 是否与定义的 username 符合。如果不符合则会报错。
|
||||||
*/
|
*/
|
||||||
private static String username;
|
private final String username;
|
||||||
/**
|
/**
|
||||||
* morny 的事件忽略前缀时间<br>
|
* morny 的事件忽略前缀时间<br>
|
||||||
* <br>
|
* <br>
|
||||||
* {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
|
* {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
|
||||||
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
||||||
*/
|
*/
|
||||||
public static long latestEventTimestamp;
|
public long latestEventTimestamp;
|
||||||
/**
|
/**
|
||||||
* morny 主程序启动时间<br>
|
* morny 主程序启动时间<br>
|
||||||
* 用于统计数据
|
* 用于统计数据
|
||||||
*/
|
*/
|
||||||
public static final long coeurStartTimestamp = System.currentTimeMillis();
|
public static final long coeurStartTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
private record LogInResult(TelegramBot account, String username) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bot 启动入口,执行 bot 初始化
|
* 执行 bot 初始化
|
||||||
*
|
*
|
||||||
* @param botKey bot 的 telegram bot api token
|
* @param botKey bot 的 telegram bot api token
|
||||||
* @param botUsername bot 的 username 限定。如果为 null 则表示不限定,
|
* @param botUsername bot 的 username 限定。如果为 null 则表示不限定,
|
||||||
* 如果指定,则登录时会检查所登陆的 bot 的用户名是否与此相等
|
* 如果指定,则登录时会检查所登陆的 bot 的用户名是否与此相等
|
||||||
|
* @param master morny 实例所信任的主人的 id。用于初始化 {@link #trusted}
|
||||||
|
* @param trustedChat morny 实例所信任的群组的 id。用于初始化 {@link #trusted}
|
||||||
* @param latestEventTimestamp 事件处理器会处理事件的最早时间戳 ——
|
* @param latestEventTimestamp 事件处理器会处理事件的最早时间戳 ——
|
||||||
* 只有限定的 message 事件会受此影响。
|
* 只有限定的 message 事件会受此影响。
|
||||||
* 单位为毫秒
|
* 单位为毫秒
|
||||||
*/
|
*/
|
||||||
public static void main (@Nonnull String botKey, @Nullable String botUsername, long latestEventTimestamp) {
|
private MornyCoeur (
|
||||||
|
@Nonnull String botKey, @Nullable String botUsername,
|
||||||
MornyCoeur.latestEventTimestamp = latestEventTimestamp;
|
long master, long trustedChat, long latestEventTimestamp
|
||||||
|
) {
|
||||||
logger.info("System Starting");
|
|
||||||
|
|
||||||
|
this.latestEventTimestamp = latestEventTimestamp;
|
||||||
configureSafeExit();
|
configureSafeExit();
|
||||||
|
|
||||||
logger.info("args key:\n " + botKey);
|
logger.info("args key:\n " + botKey);
|
||||||
@ -65,23 +75,57 @@ public class MornyCoeur {
|
|||||||
logger.info("login as:\n " + botUsername);
|
logger.info("login as:\n " + botUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
try { account = login(botKey); }
|
try {
|
||||||
catch (Exception e) { logger.error("Cannot login to bot/api. :\n " + e.getMessage()); System.exit(-1); }
|
final LogInResult loginResult = login(botKey);
|
||||||
|
this.account = loginResult.account;
|
||||||
|
this.username = loginResult.username;
|
||||||
|
this.trusted = new MornyTrusted(master, trustedChat);
|
||||||
|
logger.info(String.format("""
|
||||||
|
trusted param set:
|
||||||
|
- master (id)
|
||||||
|
%d
|
||||||
|
- trusted chat (id)
|
||||||
|
%d""",
|
||||||
|
master, trustedChat
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
RuntimeException ex = new RuntimeException("Cannot login to bot/api. :\n " + e.getMessage());
|
||||||
|
logger.error(ex.getMessage());
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("Bot login succeed.");
|
logger.info("Bot login succeed.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向外界暴露的 morny 初始化入口.
|
||||||
|
* <p>
|
||||||
|
* 如果 morny 已经初始化,则不会进行初始化,抛出错误消息并直接退出方法。
|
||||||
|
*
|
||||||
|
* @see #MornyCoeur 程序初始化方法
|
||||||
|
*/
|
||||||
|
public static void main (
|
||||||
|
@Nonnull String botKey, @Nullable String botUsername,
|
||||||
|
long master, long trustedChat, long latestEventTimestamp
|
||||||
|
) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
logger.info("System Starting");
|
||||||
|
INSTANCE = new MornyCoeur(botKey, botUsername, master, trustedChat, latestEventTimestamp);
|
||||||
TrackerDataManager.init();
|
TrackerDataManager.init();
|
||||||
EventListeners.registerAllListeners();
|
EventListeners.registerAllListeners();
|
||||||
account.setUpdatesListener(OnUpdate::onNormalUpdate);
|
INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate);
|
||||||
|
|
||||||
logger.info("System start complete");
|
logger.info("System start complete");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error("System already started coeur!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于退出时进行缓存的任务处理等进行安全退出
|
* 用于退出时进行缓存的任务处理等进行安全退出
|
||||||
*/
|
*/
|
||||||
private static void exitCleanup () {
|
private void exitCleanup () {
|
||||||
TrackerDataManager.DAEMON.interrupt();
|
TrackerDataManager.DAEMON.interrupt();
|
||||||
TrackerDataManager.trackingLock.lock();
|
TrackerDataManager.trackingLock.lock();
|
||||||
}
|
}
|
||||||
@ -89,8 +133,8 @@ public class MornyCoeur {
|
|||||||
/**
|
/**
|
||||||
* 为程序在虚拟机上添加退出钩子
|
* 为程序在虚拟机上添加退出钩子
|
||||||
*/
|
*/
|
||||||
private static void configureSafeExit () {
|
private void configureSafeExit () {
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(MornyCoeur::exitCleanup));
|
Runtime.getRuntime().addShutdownHook(new Thread(this::exitCleanup));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,18 +148,17 @@ public class MornyCoeur {
|
|||||||
* @return 成功登录后的 {@link TelegramBot} 对象
|
* @return 成功登录后的 {@link TelegramBot} 对象
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static TelegramBot login (@Nonnull String key) {
|
private LogInResult login (@Nonnull String key) {
|
||||||
final TelegramBot account = new TelegramBot(key);
|
final TelegramBot account = new TelegramBot(key);
|
||||||
logger.info("Trying to login...");
|
logger.info("Trying to login...");
|
||||||
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 String username = account.execute(new GetMe()).user().username();
|
||||||
if (MornyCoeur.username != null && !MornyCoeur.username.equals(username))
|
if (this.username != null && !this.username.equals(username))
|
||||||
throw new RuntimeException("Required the bot @" + MornyCoeur.username + " but @" + username + " logged in!");
|
throw new RuntimeException("Required the bot @" + this.username + " but @" + username + " logged in!");
|
||||||
else MornyCoeur.username = username;
|
|
||||||
logger.info("Succeed login to @" + username);
|
logger.info("Succeed login to @" + username);
|
||||||
return account;
|
return new LogInResult(account, username);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.out);
|
e.printStackTrace(System.out);
|
||||||
logger.error("login failed.");
|
logger.error("login failed.");
|
||||||
@ -129,8 +172,9 @@ public class MornyCoeur {
|
|||||||
*
|
*
|
||||||
* @return {@link #account MornyCoeur.account}
|
* @return {@link #account MornyCoeur.account}
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public static TelegramBot getAccount () {
|
public static TelegramBot getAccount () {
|
||||||
return account;
|
return INSTANCE.account;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,8 +182,29 @@ public class MornyCoeur {
|
|||||||
*
|
*
|
||||||
* @return {@link #username MornyCoeur.username}
|
* @return {@link #username MornyCoeur.username}
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public static String getUsername () {
|
public static String getUsername () {
|
||||||
return username;
|
return INSTANCE.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 获取忽略时间点
|
||||||
|
*
|
||||||
|
* @return {@link #latestEventTimestamp MornyCoeur.latestEventTimestamp}
|
||||||
|
*/
|
||||||
|
public static long getLatestEventTimestamp () {
|
||||||
|
return INSTANCE.latestEventTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Morny 的{@link MornyTrusted 信任验证机}
|
||||||
|
*
|
||||||
|
* @return {@link #trusted MornyCoeur.trusted}
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public static MornyTrusted trustedInstance () {
|
||||||
|
return INSTANCE.trusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,18 @@ public class MornyTrusted {
|
|||||||
* 群聊id,其指向的群聊指示了哪个群的成员是受信任的
|
* 群聊id,其指向的群聊指示了哪个群的成员是受信任的
|
||||||
* @see #isTrusted(long) 受信检查
|
* @see #isTrusted(long) 受信检查
|
||||||
*/
|
*/
|
||||||
public static final long TRUSTED_CHAT_ID = -1001541451710L;
|
public final Long TRUSTED_CHAT_ID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* morny 的主人<br>
|
* morny 的主人<br>
|
||||||
* 这项值的对象总是会被认为是可信任的
|
* 这项值的对象总是会被认为是可信任的
|
||||||
*/
|
*/
|
||||||
public static final long MASTER = 793274677L;
|
public final long MASTER;
|
||||||
|
|
||||||
|
public MornyTrusted (long master, long trustedChatId) {
|
||||||
|
this.TRUSTED_CHAT_ID = trustedChatId;
|
||||||
|
this.MASTER = master;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于检查一个 telegram-user 是否受信任<br>
|
* 用于检查一个 telegram-user 是否受信任<br>
|
||||||
@ -30,7 +35,7 @@ public class MornyTrusted {
|
|||||||
* @param userId 需要检查的用户的id
|
* @param userId 需要检查的用户的id
|
||||||
* @return 所传递的用户id对应的用户是否受信任
|
* @return 所传递的用户id对应的用户是否受信任
|
||||||
*/
|
*/
|
||||||
public static boolean isTrusted (long userId) {
|
public boolean isTrusted (long userId) {
|
||||||
if (userId == MASTER) return true;
|
if (userId == MASTER) return true;
|
||||||
final ChatMember chatMember = MornyCoeur.getAccount().execute(new GetChatMember(TRUSTED_CHAT_ID, userId)).chatMember();
|
final ChatMember chatMember = MornyCoeur.getAccount().execute(new GetChatMember(TRUSTED_CHAT_ID, userId)).chatMember();
|
||||||
return (
|
return (
|
||||||
|
@ -59,7 +59,7 @@ public class ServerMain {
|
|||||||
* <s>但实际上这并不影响现在的使用,选项赋值目前仍属于测试功能</s><br>
|
* <s>但实际上这并不影响现在的使用,选项赋值目前仍属于测试功能</s><br>
|
||||||
* <b>但请勿混用</b>,这将使两个赋值出现混淆并<b>产生不可知的结果</b>
|
* <b>但请勿混用</b>,这将使两个赋值出现混淆并<b>产生不可知的结果</b>
|
||||||
*
|
*
|
||||||
* @see MornyCoeur#main(String, String, long)
|
* @see MornyCoeur#main(String, String, long, long, long)
|
||||||
* @since 0.4.0.0
|
* @since 0.4.0.0
|
||||||
* @param args 参数组
|
* @param args 参数组
|
||||||
*/
|
*/
|
||||||
@ -68,6 +68,8 @@ public class ServerMain {
|
|||||||
String key = null;
|
String key = null;
|
||||||
String username = null;
|
String username = null;
|
||||||
boolean outdatedBlock = false;
|
boolean outdatedBlock = false;
|
||||||
|
long master = 793274677L;
|
||||||
|
long trustedChat = -1001541451710L;
|
||||||
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
|
||||||
@ -100,6 +102,16 @@ public class ServerMain {
|
|||||||
username = args[i];
|
username = args[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case "--master" -> {
|
||||||
|
i++;
|
||||||
|
master = Long.parseLong(args[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case "--trusted-chat" -> {
|
||||||
|
i++;
|
||||||
|
trustedChat = Long.parseLong(args[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -143,7 +155,7 @@ public class ServerMain {
|
|||||||
if (welcomeEchoMode) return;
|
if (welcomeEchoMode) return;
|
||||||
|
|
||||||
assert key != null;
|
assert key != null;
|
||||||
MornyCoeur.main(key, username, outdatedBlock?System.currentTimeMillis():0);
|
MornyCoeur.main(key, username, master, trustedChat, outdatedBlock?System.currentTimeMillis():0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ public class OnCallMe extends EventListener {
|
|||||||
* 跟随 {@link MornyTrusted#MASTER} 的值
|
* 跟随 {@link MornyTrusted#MASTER} 的值
|
||||||
* @since 0.4.2.1
|
* @since 0.4.2.1
|
||||||
*/
|
*/
|
||||||
private static final long ME = MornyTrusted.MASTER;
|
private static final long ME = MornyCoeur.trustedInstance().MASTER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听私聊 bot 的消息进行呼叫关键字匹配。
|
* 监听私聊 bot 的消息进行呼叫关键字匹配。
|
||||||
|
@ -3,7 +3,6 @@ package cc.sukazyo.cono.morny.bot.event;
|
|||||||
import cc.sukazyo.cono.morny.GradleProjectConfigures;
|
import cc.sukazyo.cono.morny.GradleProjectConfigures;
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur;
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
import cc.sukazyo.cono.morny.MornySystem;
|
import cc.sukazyo.cono.morny.MornySystem;
|
||||||
import cc.sukazyo.cono.morny.MornyTrusted;
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
import cc.sukazyo.cono.morny.bot.api.InputCommand;
|
import cc.sukazyo.cono.morny.bot.api.InputCommand;
|
||||||
import cc.sukazyo.cono.morny.bot.event.on_commands.EventHack;
|
import cc.sukazyo.cono.morny.bot.event.on_commands.EventHack;
|
||||||
@ -88,7 +87,7 @@ public class OnCommandExecute extends EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onCommandExitExec (@Nonnull Update event) {
|
private void onCommandExitExec (@Nonnull Update event) {
|
||||||
if (MornyTrusted.isTrusted(event.message().from().id())) {
|
if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
|
||||||
MornyCoeur.getAccount().execute(new SendSticker(
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
TelegramStickers.ID_EXIT
|
TelegramStickers.ID_EXIT
|
||||||
|
@ -17,30 +17,41 @@ import javax.annotation.Nonnull;
|
|||||||
* <li>{@link EventListener#onChannelPost(Update) 收到频道消息}</li>
|
* <li>{@link EventListener#onChannelPost(Update) 收到频道消息}</li>
|
||||||
* <li>{@link EventListener#onEditedChannelPost(Update) 频道消息被更新}</li>
|
* <li>{@link EventListener#onEditedChannelPost(Update) 频道消息被更新}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
* @see #isOutdated 时间判断
|
||||||
*/
|
*/
|
||||||
public class OnUpdateTimestampOffsetLock extends EventListener {
|
public class OnUpdateTimestampOffsetLock extends EventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查传入时间是否在要求时间之前(即"过期").
|
||||||
|
* @param timestamp 传入时间,秒级
|
||||||
|
* @return 如果传入时间在要求时间<u>之前</u>,返回true,反之false
|
||||||
|
* @since 0.4.2.7
|
||||||
|
*/
|
||||||
|
public boolean isOutdated(long timestamp) {
|
||||||
|
return timestamp < MornyCoeur.getLatestEventTimestamp()/1000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMessage (@NotNull Update update) {
|
public boolean onMessage (@NotNull Update update) {
|
||||||
return update.message().date() < MornyCoeur.latestEventTimestamp/1000;
|
return isOutdated(update.message().date());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 0.4.2.6 */
|
/** @since 0.4.2.6 */
|
||||||
@Override
|
@Override
|
||||||
public boolean onEditedMessage (@Nonnull Update update) {
|
public boolean onEditedMessage (@Nonnull Update update) {
|
||||||
return update.editedMessage().editDate() < MornyCoeur.latestEventTimestamp/1000;
|
return isOutdated(update.editedMessage().editDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 0.4.2.6 */
|
/** @since 0.4.2.6 */
|
||||||
@Override
|
@Override
|
||||||
public boolean onChannelPost (@Nonnull Update update) {
|
public boolean onChannelPost (@Nonnull Update update) {
|
||||||
return update.channelPost().date() < MornyCoeur.latestEventTimestamp/1000;
|
return isOutdated(update.channelPost().date());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 0.4.2.6 */
|
/** @since 0.4.2.6 */
|
||||||
@Override
|
@Override
|
||||||
public boolean onEditedChannelPost (@Nonnull Update update) {
|
public boolean onEditedChannelPost (@Nonnull Update update) {
|
||||||
return update.editedChannelPost().editDate() < MornyCoeur.latestEventTimestamp/1000;
|
return isOutdated(update.editedChannelPost().editDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public class EventHack {
|
|||||||
|
|
||||||
switch (x_mode) {
|
switch (x_mode) {
|
||||||
case "any":
|
case "any":
|
||||||
if (MornyTrusted.isTrusted(event.message().from().id())) {
|
if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
|
||||||
OnEventHackHandle.registerHack(
|
OnEventHackHandle.registerHack(
|
||||||
event.message().messageId(),
|
event.message().messageId(),
|
||||||
event.message().from().id(),
|
event.message().from().id(),
|
||||||
|
Loading…
Reference in New Issue
Block a user