mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-25 12:37:39 +08:00
分离程序入口与主程序启动,优化参数处理,添加过期事件抑制功能
This commit is contained in:
parent
b32b465a12
commit
d65f2d9f24
@ -7,7 +7,7 @@ plugins {
|
||||
}
|
||||
|
||||
group 'cc.sukazyo'
|
||||
version '0.3.4.4'
|
||||
version '0.4.0.0'
|
||||
project.ext.archiveBaseName = 'Coeur_Morny_Cono'
|
||||
project.ext.artifactId = 'morny-coeur'
|
||||
mainClassName = 'cc.sukazyo.cono.morny.MornyCoeur'
|
||||
|
@ -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.3.4.4";
|
||||
public static final long COMPILE_TIMESTAMP = 1638884621273L;
|
||||
public static final String VERSION = "0.4.0.0";
|
||||
public static final long COMPILE_TIMESTAMP = 1638938409169L;
|
||||
}
|
||||
|
@ -7,12 +7,7 @@ import com.pengrad.telegrambot.TelegramBot;
|
||||
import com.pengrad.telegrambot.request.GetMe;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static cc.sukazyo.cono.morny.Logger.logger;
|
||||
|
||||
@ -28,61 +23,45 @@ public class MornyCoeur {
|
||||
/**
|
||||
* morny 的 bot 账户的用户名<br>
|
||||
* <br>
|
||||
* 出于技术限制,这个字段目前是写死的
|
||||
* 这个字段将会在登陆成功后赋值为登录到的 bot 的 username。
|
||||
* 它应该是和 {@link #account} 的 username 同步的<br>
|
||||
* <br>
|
||||
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
||||
* 是否与定义的 username 符合。如果不符合则会报错。
|
||||
*/
|
||||
public static String username;
|
||||
private static String username;
|
||||
/**
|
||||
* morny 的事件忽略前缀时间<br>
|
||||
* <br>
|
||||
* {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
|
||||
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
||||
*/
|
||||
public static long latestEventTimestamp;
|
||||
|
||||
/**
|
||||
* 程序入口<br>
|
||||
* <br>
|
||||
* 会从命令行参数取得初始化数据并初始化程序和bot<br>
|
||||
* <br>
|
||||
* - 第一个参数({@code args[0]})必序传递,值为 telegram-bot 的 api-token<br>
|
||||
* - 第二个参数可选 {@code --no-hello} 和 {@code --only-hello},
|
||||
* 前者表示不输出{@link MornyHello#MORNY_PREVIEW_IMAGE_ASCII 欢迎标语},
|
||||
* 后者表示只输出{@link MornyHello#MORNY_PREVIEW_IMAGE_ASCII 欢迎标语}而不运行程序逻辑<br>
|
||||
* <br>
|
||||
* 或者,在第一个参数处使用 {@code --version} 来输出当前程序的版本信息
|
||||
* bot 启动入口,执行 bot 初始化
|
||||
*
|
||||
* @param args 程序命令行参数
|
||||
* @param botKey bot 的 telegram bot api token
|
||||
* @param botUsername bot 的 username 限定。如果为 null 则表示不限定,
|
||||
* 如果指定,则登录时会检查所登陆的 bot 的用户名是否与此相等
|
||||
* @param latestEventTimestamp 事件处理器会处理事件的最早时间戳 ——
|
||||
* 只有限定的 message 事件会受此影响。
|
||||
* 单位为毫秒
|
||||
*/
|
||||
public static void main (@Nonnull String[] args) {
|
||||
public static void main (@Nonnull String botKey, @Nullable String botUsername, long latestEventTimestamp) {
|
||||
|
||||
if ("--version".equals(args[0])) {
|
||||
logger.info(String.format("""
|
||||
Morny Cono Version
|
||||
- version :
|
||||
%s
|
||||
- md5hash :
|
||||
%s
|
||||
- co.time :
|
||||
%d
|
||||
%s [UTC]""",
|
||||
MornySystem.VERSION,
|
||||
MornySystem.getJarMd5(),
|
||||
GradleProjectConfigures.COMPILE_TIMESTAMP,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant(
|
||||
Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP),
|
||||
ZoneId.ofOffset("UTC", ZoneOffset.UTC)))
|
||||
));
|
||||
return;
|
||||
}
|
||||
MornyCoeur.latestEventTimestamp = latestEventTimestamp;
|
||||
|
||||
if (!(args.length > 1 && "--no-hello".equals(args[1])))
|
||||
logger.info(MornyHello.MORNY_PREVIEW_IMAGE_ASCII);
|
||||
if (args.length > 1 && "--only-hello".equals(args[1]))
|
||||
return;
|
||||
logger.info("System Starting");
|
||||
|
||||
configureSafeExit();
|
||||
|
||||
logger.info("args key:\n " + args[0]);
|
||||
if (args.length > 2) {
|
||||
username = args[2];
|
||||
logger.info("login as:\n " + args[2]);
|
||||
logger.info("args key:\n " + botKey);
|
||||
if (botUsername != null) {
|
||||
logger.info("login as:\n " + botUsername);
|
||||
}
|
||||
|
||||
try { account = login(args[0]); }
|
||||
try { account = login(botKey); }
|
||||
catch (Exception e) { logger.error("Cannot login to bot/api. :\n " + e.getMessage()); System.exit(-1); }
|
||||
|
||||
logger.info("Bot login succeed.");
|
||||
@ -128,7 +107,7 @@ public class MornyCoeur {
|
||||
if (i != 1) logger.info("retrying...");
|
||||
try {
|
||||
final String username = account.execute(new GetMe()).user().username();
|
||||
if (username != null && !MornyCoeur.username.equals(username))
|
||||
if (MornyCoeur.username != null && !MornyCoeur.username.equals(username))
|
||||
throw new RuntimeException("Required the bot @" + MornyCoeur.username + " but @" + username + " logged in!");
|
||||
else MornyCoeur.username = username;
|
||||
logger.info("Succeed login to @" + username);
|
||||
@ -150,4 +129,13 @@ public class MornyCoeur {
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录 bot 的 username
|
||||
*
|
||||
* @return {@link #username MornyCoeur.username}
|
||||
*/
|
||||
public static String getUsername () {
|
||||
return username;
|
||||
}
|
||||
|
||||
}
|
||||
|
139
src/main/java/cc/sukazyo/cono/morny/ServerMain.java
Normal file
139
src/main/java/cc/sukazyo/cono/morny/ServerMain.java
Normal file
@ -0,0 +1,139 @@
|
||||
package cc.sukazyo.cono.morny;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import static cc.sukazyo.cono.morny.Logger.logger;
|
||||
|
||||
/**
|
||||
* 程序启动入口<br>
|
||||
* <br>
|
||||
* 会处理程序传入的参数和选项等数据,并执行对应的启动方式<br>
|
||||
* <br>
|
||||
* - 第一个参数({@code args[0]})必序传递,值为 telegram-bot 的 api-token<br>
|
||||
* - 第二个参数可选 {@code --no-hello} 和 {@code --only-hello},
|
||||
* 前者表示不输出{@link MornyHello#MORNY_PREVIEW_IMAGE_ASCII 欢迎标语},
|
||||
* 后者表示只输出{@link MornyHello#MORNY_PREVIEW_IMAGE_ASCII 欢迎标语}而不运行程序逻辑<br>
|
||||
* <br>
|
||||
* 或者,在第一个参数处使用 {@code --version} 来输出当前程序的版本信息
|
||||
*
|
||||
* @since 0.4.0.0
|
||||
*/
|
||||
public class ServerMain {
|
||||
|
||||
private static boolean versionEchoMode = false;
|
||||
private static boolean welcomeEchoMode = false;
|
||||
|
||||
private static boolean showWelcome = true;
|
||||
|
||||
/**
|
||||
* 程序入口,也是参数处理器<br>
|
||||
* <br>
|
||||
* 以 {@code -} 开头的参数会被解析为选项<br>
|
||||
* <br>
|
||||
* 支持以下选项
|
||||
* <ul>
|
||||
* <li>
|
||||
* {@code --version} 只输出版本信息,不运行主程序。此参数会导致其它所有参数失效(优先级最高)
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code --only-hello} 只输出欢迎字符画({@link MornyHello}),不运行主程序。
|
||||
* 不要同时使用 {@code --no-hello},原因见下。
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code --no-hello} 不在主程序启动时输出用于欢迎消息的字符画。
|
||||
* 与 {@code --only-hello} 参数不兼容 —— 会导致程序完全没有任何输出
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code --outdated-block} 会使得 {@link MornyCoeur#latestEventTimestamp}
|
||||
* 赋值为程序启动的时间,从而造成阻挡程序启动之前的消息事件处理效果。
|
||||
* </li>
|
||||
* </ul>
|
||||
* 除去选项之外,第一个参数会被赋值为 bot 的 telegram bot api token,
|
||||
* 第二个参数会被赋值为 bot 的 username 限定名。其余的参数会被认定为无法理解。
|
||||
*
|
||||
* @see MornyCoeur#main(String, String, long)
|
||||
* @since 0.4.0.0
|
||||
* @param args 参数组
|
||||
*/
|
||||
public static void main (@Nonnull String[] args) {
|
||||
|
||||
String key = null;
|
||||
String username = null;
|
||||
boolean outdatedBlock = false;
|
||||
|
||||
for (String arg : args) {
|
||||
|
||||
if (arg.startsWith("-")) {
|
||||
|
||||
switch (arg) {
|
||||
case "--outdated-block" -> {
|
||||
outdatedBlock = true;
|
||||
continue;
|
||||
}
|
||||
case "--no-hello" -> {
|
||||
showWelcome = false;
|
||||
continue;
|
||||
}
|
||||
case "--only-hello" -> {
|
||||
welcomeEchoMode = true;
|
||||
continue;
|
||||
}
|
||||
case "--version" -> {
|
||||
versionEchoMode = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (key == null) {
|
||||
key = arg;
|
||||
continue;
|
||||
}
|
||||
if (username == null) {
|
||||
username = arg;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logger.warn("Can't understand arg to some meaning :\n " + arg);
|
||||
|
||||
}
|
||||
|
||||
if (versionEchoMode) {
|
||||
|
||||
logger.info(String.format("""
|
||||
Morny Cono Version
|
||||
- version :
|
||||
%s
|
||||
- md5hash :
|
||||
%s
|
||||
- co.time :
|
||||
%d
|
||||
%s [UTC]""",
|
||||
MornySystem.VERSION,
|
||||
MornySystem.getJarMd5(),
|
||||
GradleProjectConfigures.COMPILE_TIMESTAMP,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.ofInstant(
|
||||
Instant.ofEpochMilli(GradleProjectConfigures.COMPILE_TIMESTAMP),
|
||||
ZoneId.ofOffset("UTC", ZoneOffset.UTC)))
|
||||
));
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (showWelcome) logger.info(MornyHello.MORNY_PREVIEW_IMAGE_ASCII);
|
||||
if (welcomeEchoMode) return;
|
||||
|
||||
assert key != null;
|
||||
MornyCoeur.main(key, username, outdatedBlock?System.currentTimeMillis():0);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -7,10 +7,12 @@ public class EventListeners {
|
||||
public static final OnCommandExecute COMMANDS_LISTENER = new OnCommandExecute();
|
||||
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 void registerAllListeners () {
|
||||
EventListenerManager.addListener(
|
||||
ACTIVITY_RECORDER,
|
||||
UPDATE_TIMESTAMP_OFFSET_LOCK,
|
||||
COMMANDS_LISTENER,
|
||||
USER_SLASH_ACTION
|
||||
);
|
||||
|
@ -35,7 +35,7 @@ public class OnCommandExecute extends EventListener {
|
||||
return false; // 检测到无消息文本,忽略掉命令处理
|
||||
}
|
||||
final InputCommand command = new InputCommand(event.message().text());
|
||||
if (command.getTarget() != null && !MornyCoeur.username.equals(command.getTarget())) {
|
||||
if (command.getTarget() != null && !MornyCoeur.getUsername().equals(command.getTarget())) {
|
||||
return true; // 检测到命令并非针对 morny,退出整个事件处理链
|
||||
}
|
||||
switch (command.getCommand()) {
|
||||
|
@ -0,0 +1,15 @@
|
||||
package cc.sukazyo.cono.morny.bot.event;
|
||||
|
||||
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||
import com.pengrad.telegrambot.model.Update;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class OnUpdateTimestampOffsetLock extends EventListener {
|
||||
|
||||
@Override
|
||||
public boolean onMessage (@NotNull Update update) {
|
||||
return update.message().date() < MornyCoeur.latestEventTimestamp*1000;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user