trustedRDinner, long latestEventTimestamp,
- boolean isAutomaticResetCommandList, boolean isRemoveCommandListWhenExit
- ) {
+ public static void main (MornyConfig config) {
if (INSTANCE == null) {
+
logger.info("Coeur Starting");
- INSTANCE = new MornyCoeur(
- botApi, botApi4File,
- botKey, botUsername,
- master, trustedChat, trustedRDinner,
- latestEventTimestamp,
- isRemoveCommandListWhenExit
- );
+ INSTANCE = new MornyCoeur(config);
+
MornyDaemons.start();
+
logger.info("start telegram events listening");
EventListeners.registerAllListeners();
INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate);
- if (isAutomaticResetCommandList) {
+
+ if (config.commandLoginRefresh) {
logger.info("resetting telegram command list");
commandManager().automaticUpdateList();
}
+
logger.info("Coeur start complete");
return;
+
}
logger.error("Coeur already started!!!");
}
@@ -179,7 +154,7 @@ public class MornyCoeur {
private void exitCleanup () {
logger.info("clean:save tracker data.");
MornyDaemons.stop();
- if (isRemoveCommandListWhenExit) {
+ if (config.commandLogoutClear) {
commandManager.automaticRemoveList();
}
}
@@ -192,16 +167,20 @@ public class MornyCoeur {
}
/**
- * 登录 bot
- *
+ * 登录 bot.
+ *
* 会反复尝试三次进行登录。如果登录失败,则会直接抛出 RuntimeException 结束处理。
* 会通过 GetMe 动作验证是否连接上了 telegram api 服务器,
* 同时也要求登录获得的 username 和 {@link #username} 声明值相等
*
- * @param api bot client 将会连接到的 telegram bot api 位置
- * @param api4File bot client 将会连接到的 telegram file api 位置,如果不指定则会跟随 {@code api} 选项的设定
- * @param key bot 的 api-token
- * @param requireName 要求登录到的需要的 username,如果登陆后的 username 与此不同则会报错退出
+ * @param api bot client 将会连接到的 telegram bot api 位置。
+ * 填入 {@code null} 则使用默认的 {@code "https://api.telegram.org/bot"}
+ * @param api4File bot client 将会连接到的 telegram file api 位置。
+ * 如果传入 {@code null} 则会跟随 {@param api} 选项的设定(具体为在 {@param api} 路径的后面添加 {@code /file} 路径)。
+ * 如果两者都为 {@code null},则跟随默认的 {@value FileApi#FILE_API}
+ * @param key bot 的 api-token. 必要值
+ * @param requireName 要求登录到的需要的 username,如果登陆后的 username 与此不同则会报错退出。
+ * 填入 {@code null} 则表示不对 username 作要求
* @return 成功登录后的 {@link TelegramBot} 对象
*/
@Nonnull
@@ -281,13 +260,13 @@ public class MornyCoeur {
}
/**
+ * 获取当前 morny 的配置数据
*
- * 获取忽略时间点
- *
- * @return {@link #latestEventTimestamp MornyCoeur.latestEventTimestamp}
+ * @return {@link #config MornyCoeur.config}
*/
- public static long getLatestEventTimestamp () {
- return INSTANCE.latestEventTimestamp;
+ @Nonnull
+ public static MornyConfig config () {
+ return INSTANCE.config;
}
/**
diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyConfig.java b/src/main/java/cc/sukazyo/cono/morny/MornyConfig.java
new file mode 100644
index 0000000..004302c
--- /dev/null
+++ b/src/main/java/cc/sukazyo/cono/morny/MornyConfig.java
@@ -0,0 +1,137 @@
+package cc.sukazyo.cono.morny;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class MornyConfig {
+
+ /* ======================================= *
+ * Config props Names Definition *
+ * ======================================= */
+
+ public static final String PROP_TOKEN_KEY_DEFAULT = "TELEGRAM_BOT_API_TOKEN";
+ public static final String PROP_TOKEN_MORNY_KEY = "MORNY_TG_TOKEN";
+ public static final String[] PROP_TOKEN_KEY = {PROP_TOKEN_KEY_DEFAULT, PROP_TOKEN_MORNY_KEY};
+
+ /* ======================================= *
+ * telegram bot login config *
+ * ======================================= */
+
+ /**
+ * Morny Telegram 使用的 API 服务器.
+ *
+ * 不设定的话,默认将会使用 {@code https://api.telegram.org/bot}
+ */
+ @Nullable public final String telegramBotApiServer;
+ /**
+ * Morny Telegram 使用的 API 服务器的 file 服务路径.
+ *
+ * 不设定的话,默认将会使用 {@value com.pengrad.telegrambot.impl.FileApi#FILE_API}
+ */
+ @Nullable public final String telegramBotApiServer4File;
+
+ /**
+ * morny 使用的 telegram bot 的 bot api token.
+ *
+ * 这个值必须设定。
+ */
+ @Nonnull public final String telegramBotKey;
+ /**
+ * morny 所使用的 bot 的 username.
+ *
+ * 如果设定了这个值,则在 morny 登录 bot 时将会检查所登录的 bot 的 username 是否和这里设定的 username 匹配。
+ * 如果不匹配,则会拒绝登录然后报错。
+ *
+ * 如果没有设定这个值,则不会对登录 bot 的 username 进行限制。
+ */
+ @Nullable public final String telegramBotUsername;
+
+ /* ======================================= *
+ * morny trusted config *
+ * ======================================= */
+
+ /**
+ * morny 的主人.
+ *
+ * 这项值的对象总是会被{@link MornyTrusted 信任管理器}认为是可信任的
+ */
+ public final long trustedMaster;
+ /**
+ * morny 可信群聊的 id.
+ *
+ * {@link MornyTrusted 信任管理器}将会认为这个群聊中的所有拥有
+ * {@link com.pengrad.telegrambot.model.ChatMember.Status#administrator administrator} 权限的成员是可信任的。
+ *
+ * id 需要符合 bot api 标准。
+ */
+ public final long trustedChat;
+
+ /* ======================================= *
+ * system: event ignore *
+ * ======================================= */
+
+ public final boolean eventIgnoreOutdated;
+ /**
+ * morny 的事件忽略前缀时间
+ *
+ * {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
+ * 会根据这里定义的时间戳取消掉比此时间更早的事件链
+ */
+ public final long eventOutdatedTimestamp;
+
+ /* ======================================= *
+ * system: command list automation *
+ * ======================================= */
+
+ public final boolean commandLoginRefresh;
+ public final boolean commandLogoutClear;
+
+ /* ======================================= *
+ * function: dinner query tool *
+ * ======================================= */
+
+ @Nonnull public final Set dinnerTrustedReaders;
+ public final long dinnerChatId;
+
+ public MornyConfig (@Nonnull Prototype prototype) throws CheckFailure {
+ this.telegramBotApiServer = prototype.telegramBotApiServer;
+ this.telegramBotApiServer4File = prototype.telegramBotApiServer4File;
+ if (prototype.telegramBotKey == null) throw new CheckFailure.NullTelegramBotKey();
+ this.telegramBotKey = prototype.telegramBotKey;
+ this.telegramBotUsername = prototype.telegramBotUsername;
+ this.trustedMaster = prototype.trustedMaster;
+ this.trustedChat = prototype.trustedChat;
+ this.eventIgnoreOutdated = prototype.eventIgnoreOutdated;
+ if (prototype.eventOutdatedTimestamp < 1) throw new CheckFailure.UnsetEventOutdatedTimestamp();
+ this.eventOutdatedTimestamp = prototype.eventOutdatedTimestamp;
+ this.commandLoginRefresh = prototype.commandLoginRefresh;
+ this.commandLogoutClear = prototype.commandLogoutClear;
+ this.dinnerTrustedReaders = prototype.dinnerTrustedReaders;
+ this.dinnerChatId = prototype.dinnerChatId;
+ }
+
+ public static class CheckFailure extends Exception {
+ public static class NullTelegramBotKey extends CheckFailure {}
+ public static class UnsetEventOutdatedTimestamp extends CheckFailure {}
+ }
+
+ public static class Prototype {
+
+ @Nullable public String telegramBotApiServer = null;
+ @Nullable public String telegramBotApiServer4File = null;
+ @Nullable public String telegramBotKey = null;
+ @Nullable public String telegramBotUsername = null;
+ public long trustedMaster = 793274677L;
+ public long trustedChat = -1001541451710L;
+ public boolean eventIgnoreOutdated = false;
+ public long eventOutdatedTimestamp = -1;
+ public boolean commandLoginRefresh = false;
+ public boolean commandLogoutClear = false;
+ @Nonnull public Set dinnerTrustedReaders = new HashSet<>();
+ public long dinnerChatId = -1001707106392L;
+
+ }
+
+}
diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java b/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java
index ba93789..ae2b3bb 100644
--- a/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java
+++ b/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java
@@ -1,7 +1,7 @@
package cc.sukazyo.cono.morny;
import com.pengrad.telegrambot.model.ChatMember.Status;
-import java.util.HashSet;
+
import java.util.Set;
/**
@@ -9,27 +9,10 @@ import java.util.Set;
*/
public class MornyTrusted {
- /**
- * 群聊id,其指向的群聊指示了哪个群的成员是受信任的
- * @see #isTrusted(long) 受信检查
- */
- public final Long TRUSTED_CHAT_ID;
+ private final MornyCoeur instance;
- /**
- * morny 的主人
- * 这项值的对象总是会被认为是可信任的
- */
- public final long MASTER;
-
- private final Set TRUSTED_READERS_OF_DINNER;
-
- public MornyTrusted (long master, long trustedChatId, Set trustedRDinner) {
- this.TRUSTED_CHAT_ID = trustedChatId;
- this.MASTER = master;
- this.TRUSTED_READERS_OF_DINNER = new HashSet<>(){{
- this.add(master);
- this.addAll(trustedRDinner);
- }};
+ public MornyTrusted (MornyCoeur instance) {
+ this.instance = instance;
}
/**
@@ -37,22 +20,22 @@ public class MornyTrusted {
*
* 用户需要受信任才能执行一些对程序甚至是宿主环境而言危险的操作,例如关闭程序
*
- * 它的逻辑(目前)是检查群聊 {@link #TRUSTED_CHAT_ID} 中这个用户是否为群组管理员
+ * 它的逻辑(目前)是检查群聊 {@link MornyConfig#trustedChat} 中这个用户是否为群组管理员
*
* @param userId 需要检查的用户的id
* @return 所传递的用户id对应的用户是否受信任
*/
public boolean isTrusted (long userId) {
- if (userId == MASTER) return true;
- return MornyCoeur.extra().isUserInGroup(userId, TRUSTED_CHAT_ID, Status.administrator);
+ if (userId == instance.config.trustedMaster) return true;
+ return MornyCoeur.extra().isUserInGroup(userId, instance.config.trustedChat, Status.administrator);
}
public boolean isTrustedForDinnerRead (long userId) {
- return TRUSTED_READERS_OF_DINNER.contains(userId);
+ return instance.config.dinnerTrustedReaders.contains(userId);
}
public Set getTrustedReadersOfDinnerSet () {
- return Set.copyOf(TRUSTED_READERS_OF_DINNER);
+ return Set.copyOf(instance.config.dinnerTrustedReaders);
}
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java
index 17a831f..7e6f6ac 100644
--- a/src/main/java/cc/sukazyo/cono/morny/ServerMain.java
+++ b/src/main/java/cc/sukazyo/cono/morny/ServerMain.java
@@ -4,9 +4,6 @@ import cc.sukazyo.cono.morny.util.CommonFormat;
import javax.annotation.Nonnull;
-import java.util.HashSet;
-import java.util.Set;
-
import static cc.sukazyo.cono.morny.Log.logger;
/**
@@ -18,8 +15,7 @@ import static cc.sukazyo.cono.morny.Log.logger;
*/
public class ServerMain {
- public static final String PROP_TOKEN_KEY = "TELEGRAM_BOT_API_TOKEN";
- public static final String PROP_TOKEN_MORNY_KEY = "MORNY_TG_TOKEN";
+ public static final long systemStartupTime = System.currentTimeMillis();
private static final String THREAD_MORNY_INIT = "morny-init";
@@ -57,7 +53,7 @@ public class ServerMain {
* 与 {@code --only-hello} 参数不兼容 —— 会导致程序完全没有任何输出
*
*
- * {@code --outdated-block} 会使得 {@link MornyCoeur#latestEventTimestamp}
+ * {@code --outdated-block} 会使得 {@link MornyConfig#eventIgnoreOutdated}
* 赋值为程序启动的时间,从而造成阻挡程序启动之前的消息事件处理效果。
*
*
@@ -85,20 +81,12 @@ public class ServerMain {
//#
//# 启动参数设置区块
//#
-
+ final MornyConfig.Prototype config = new MornyConfig.Prototype();
boolean versionEchoMode = false;
boolean welcomeEchoMode = false;
boolean showWelcome = true;
- String key = null;
- String username = null;
- boolean outdatedBlock = false;
- long master = 793274677L;
- Set trustedReadersOfDinner = new HashSet<>();
- long trustedChat = -1001541451710L;
- boolean autoCmdList = false;
- boolean autoCmdRemove = false;
- String api = null;
- String api4File = null;
+
+ config.eventOutdatedTimestamp = systemStartupTime;
for (int i = 0; i < args.length; i++) {
@@ -106,7 +94,7 @@ public class ServerMain {
switch (args[i]) {
case "--outdated-block", "-ob" -> {
- outdatedBlock = true;
+ config.eventIgnoreOutdated = true;
continue;
}
case "--no-hello", "-hf", "--quiet", "-q" -> {
@@ -123,51 +111,51 @@ public class ServerMain {
}
case "--token", "-t" -> {
i++;
- key = args[i];
+ config.telegramBotKey = args[i];
continue;
}
case "--username", "-u" -> {
i++;
- username = args[i];
+ config.telegramBotUsername = args[i];
continue;
}
case "--master", "-mm" -> {
i++;
- master = Long.parseLong(args[i]);
+ config.trustedMaster = Long.parseLong(args[i]);
continue;
}
case "--trusted-chat", "-trs" -> {
i++;
- trustedChat = Long.parseLong(args[i]);
+ config.trustedChat = Long.parseLong(args[i]);
continue;
}
//noinspection SpellCheckingInspection
case "--trusted-reader-dinner", "-trsd" -> {
i++;
- trustedReadersOfDinner.add(Long.parseLong(args[i]));
+ config.dinnerTrustedReaders.add(Long.parseLong(args[i]));
continue;
}
case "--auto-cmd", "-cmd", "-c" -> {
- autoCmdList = true;
- autoCmdRemove = true;
+ config.commandLoginRefresh = true;
+ config.commandLogoutClear = true;
continue;
}
case "--auto-cmd-list", "-ca" -> {
- autoCmdList = true;
+ config.commandLoginRefresh = true;
continue;
}
case "--auto-cmd-remove", "-cr" -> {
- autoCmdRemove = true;
+ config.commandLogoutClear = true;
continue;
}
case "--api", "-a" -> {
i++;
- api = args[i];
+ config.telegramBotApiServer = args[i];
continue;
}
case "--api-files", "files-api", "-af" -> {
i++;
- api4File = args[i];
+ config.telegramBotApiServer4File = args[i];
continue;
}
}
@@ -180,7 +168,7 @@ public class ServerMain {
String propToken = null;
String propTokenKey = null;
- for (String iKey : new String[]{PROP_TOKEN_KEY, PROP_TOKEN_MORNY_KEY}) {
+ for (String iKey : MornyConfig.PROP_TOKEN_KEY) {
if (System.getenv(iKey) != null) {
propToken = System.getenv(iKey);
propTokenKey = iKey;
@@ -228,21 +216,19 @@ public class ServerMain {
//#
if (propToken != null) {
- key = propToken;
+ config.telegramBotKey = propToken;
logger.info("Parameter set by EnvVar $"+propTokenKey);
}
- if (key == null) {
- logger.info("Parameter required has no value:\n --token.");
- return;
- }
+
Thread.currentThread().setName(THREAD_MORNY_INIT);
- MornyCoeur.main(
- api, api4File,
- key, username,
- master, trustedChat, trustedReadersOfDinner,
- outdatedBlock?System.currentTimeMillis():0,
- autoCmdList, autoCmdRemove
- );
+ try {
+ MornyCoeur.main(new MornyConfig(config));
+ } catch (MornyConfig.CheckFailure.NullTelegramBotKey ignore) {
+ logger.info("Parameter required has no value:\n --token.");
+ } catch (MornyConfig.CheckFailure e) {
+ logger.error("Unknown failure occurred while starting ServerMain!:");
+ e.printStackTrace(System.out);
+ }
}
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMe.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMe.java
index c448881..89ed0fc 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMe.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMe.java
@@ -1,7 +1,6 @@
package cc.sukazyo.cono.morny.bot.event;
import cc.sukazyo.cono.morny.MornyCoeur;
-import cc.sukazyo.cono.morny.MornyTrusted;
import cc.sukazyo.cono.morny.bot.api.EventListener;
import cc.sukazyo.cono.morny.data.TelegramStickers;
import cc.sukazyo.cono.morny.util.CommonFormat;
@@ -27,10 +26,10 @@ public class OnCallMe extends EventListener {
/**
* 主人的 telegram user id,同时被用于 chat id
- * 跟随 {@link MornyTrusted#MASTER} 的值
+ * 跟随 {@link cc.sukazyo.cono.morny.MornyConfig#trustedMaster} 的值
* @since 0.4.2.1
*/
- private static final long ME = MornyCoeur.trustedInstance().MASTER;
+ private static final long ME = MornyCoeur.config().trustedMaster;
/**
* 监听私聊 bot 的消息进行呼叫关键字匹配。
@@ -112,7 +111,7 @@ public class OnCallMe extends EventListener {
boolean isAllowed = false;
Message lastDinnerData = null;
if (MornyCoeur.trustedInstance().isTrustedForDinnerRead(event.message().from().id())) {
- lastDinnerData = MornyCoeur.extra().exec(new GetChat(MornyCoeur.DINNER_CHAT_ID)).chat().pinnedMessage();
+ lastDinnerData = MornyCoeur.extra().exec(new GetChat(MornyCoeur.config().dinnerChatId)).chat().pinnedMessage();
SendResponse sendResp = MornyCoeur.extra().exec(new ForwardMessage(
event.message().from().id(),
lastDinnerData.forwardFromChat().id(),
diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java
index 80eff7f..faee77f 100644
--- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java
+++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUpdateTimestampOffsetLock.java
@@ -7,7 +7,7 @@ import com.pengrad.telegrambot.model.Update;
import javax.annotation.Nonnull;
/**
- * 阻止 {@link MornyCoeur#latestEventTimestamp 指定时间} 之前的事件处理.
+ * 阻止 {@link cc.sukazyo.cono.morny.MornyConfig#eventOutdatedTimestamp 指定时间} 之前的事件处理.
*
* 只支持以下事件
*
@@ -27,7 +27,7 @@ public class OnUpdateTimestampOffsetLock extends EventListener {
* @since 0.4.2.7
*/
public boolean isOutdated(long timestamp) {
- return timestamp < MornyCoeur.getLatestEventTimestamp()/1000;
+ return timestamp < MornyCoeur.config().eventOutdatedTimestamp/1000;
}
@Override