diff --git a/src/main/java/com/alpt/vtools/listeners/ServerCloser.java b/src/main/java/com/alpt/vtools/listeners/ServerCloser.java index 5d64e71..ea68886 100644 --- a/src/main/java/com/alpt/vtools/listeners/ServerCloser.java +++ b/src/main/java/com/alpt/vtools/listeners/ServerCloser.java @@ -9,6 +9,7 @@ import de.strifel.VTools.listeners.TGBridge; import okhttp3.*; import java.io.IOException; +import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; public class ServerCloser { @@ -62,7 +63,7 @@ public class ServerCloser { for (int i = 0; i < 3; i++) { httpSuccess = executeAzure(); if (httpSuccess) { - TGBridge.log("ServerCloser: 向azure发送关机命令成功,正在关闭 pymcd."); + TGBridge.log("ServerCloser: 向 azure 发送关机命令成功,正在关闭 pymcd."); TGBridge.setShuttingDown(0); break; } @@ -140,7 +141,7 @@ public class ServerCloser { while (!lock.isEmpty()) { lock.poll().cancel(); } - lock.add(new Counter(INSTANCE, 1).start()); + lock.add(new Counter(INSTANCE, 1,"收到关机命令已经过了 %s 分钟,即将关机。").start()); } } @@ -149,7 +150,15 @@ public class ServerCloser { while (!lock.isEmpty()) { lock.poll().cancel(); } - lock.add(new Counter(INSTANCE, 60).start()); + lock.add(new Counter(INSTANCE, 60, "虽然关机被取消,但 %s 分钟内依旧没有玩家上线,即将关机。").start()); + } + } + + public void noShutdown(){ + synchronized (lock){ + while (!lock.isEmpty()) { + lock.poll().cancel(); + } } } @@ -158,11 +167,15 @@ public class ServerCloser { private final int totalMin; private int minLeft; private boolean canceled = false; + private final String reason; - protected Counter(ServerCloser instance, int minute) { + protected Counter(ServerCloser instance, int minute) {this(instance, minute, null);} + + protected Counter(ServerCloser instance, int minute, String reason) { this.instance = instance; totalMin = minute; minLeft = minute; + this.reason = Objects.requireNonNullElse(reason, "距离上一个玩家离开已经过了 %s 分钟,即将关机。"); } protected synchronized void cancel() { @@ -199,12 +212,12 @@ public class ServerCloser { minLeft--; switch (minLeft) { case 1 -> { - String msg = "服务器即将在一分钟后关机"; + String msg = "服务器即将在一分钟后关机,使用 /fuck 以取消。"; instance.plugin.logger.info(msg); TGBridge.log(msg); } case 0 -> { - String msg = "ServerCloser: 距离上一个玩家离开已经过了 %s 分钟,即将关机。".formatted(totalMin); + String msg = "ServerCloser: " + reason.formatted(totalMin); instance.plugin.logger.info(msg); TGBridge.log(msg); instance.close(); diff --git a/src/main/java/de/strifel/VTools/listeners/TGBridge.java b/src/main/java/de/strifel/VTools/listeners/TGBridge.java index cc3b1a2..34d602d 100644 --- a/src/main/java/de/strifel/VTools/listeners/TGBridge.java +++ b/src/main/java/de/strifel/VTools/listeners/TGBridge.java @@ -94,7 +94,7 @@ public class TGBridge { Message message = update.message(); if (message.chat() == null || message.chat().id() != CHAT_ID || message.from() == null) continue; - currentAnnounce.abort(); + mergeMessage.abort(); String text = ""; Message replyTo = message.replyToMessage(); @@ -181,10 +181,15 @@ public class TGBridge { } case "/fuck" -> { if (server.getAllPlayers().isEmpty()) { - ServerCloser.INSTANCE.slowShutdown(); - outbound("shutdown timer has been set to 60 minutes."); + if("fuck".equalsIgnoreCase(arg)){ + ServerCloser.INSTANCE.noShutdown(); + outbound("shutdown timer disabled until next player join & left."); + }else { + ServerCloser.INSTANCE.slowShutdown(); + outbound("shutdown timer has been set to 60 minutes."); + } } else { - outbound("still player online, can't shutdown."); + outbound("still player online, will not shutdown."); } } default -> {} @@ -332,11 +337,11 @@ public class TGBridge { } public static void error(String context) { - INSTANCE.outbound("*" + MarkdownString.escapeStr(context) + "*", ParseMode.MarkdownV2); + INSTANCE.appendMessage("*" + MarkdownString.escapeStr(context) + "*"); } public static void log(String context) { - INSTANCE.outbound("_" + MarkdownString.escapeStr(context) + "_", ParseMode.MarkdownV2); + INSTANCE.appendMessage("_" + MarkdownString.escapeStr(context) + "_"); } protected void outbound(String content) {outbound(content, (ParseMode) null);} @@ -383,7 +388,7 @@ public class TGBridge { if (lastDisconnect.equals(username)) { lastDisconnect = ""; } - joinLeftAnnounce(String.format("%s joined the proxy", username)); + joinLeftAnnounce(String.format("`%s` joined the server\\.", MarkdownString.escapeStr(username))); } updateRequests.add(new UpdateRequest()); } @@ -396,8 +401,8 @@ public class TGBridge { String username = event.getPlayer().getUsername(); if (username != null) { lastDisconnect = username; + joinLeftAnnounce(String.format("`%s` left the server\\.", MarkdownString.escapeStr(username))); } - joinLeftAnnounce(String.format("%s left the proxy", username)); } updateRequests.add(new UpdateRequest()); } @@ -411,8 +416,7 @@ public class TGBridge { private boolean PROXY_SHUT_DOWN = false; - private static class UpdateRequest { - } + private static class UpdateRequest {} private LinkedBlockingQueue updateRequests = new LinkedBlockingQueue<>(); @@ -446,27 +450,26 @@ public class TGBridge { if (PROXY_SHUT_DOWN) { return; } - String oldestMessage = null; try { - oldestMessage = announceQueue.take(); + String oldestMessage = announceQueue.take(); + appendMessage(oldestMessage); } catch (InterruptedException ignored) {} - - if (!currentAnnounce.isValid()) { - currentAnnounce = new JoinLeftAnnounceMessage(oldestMessage); - continue; - } - ArrayList messages = new ArrayList<>(announceQueue.size() + 1); - messages.add(oldestMessage); - while (!announceQueue.isEmpty()) { - try { - messages.add(announceQueue.take()); - } catch (InterruptedException ignored) {} - } - currentAnnounce.addLines(messages); } }).start(); } + private static final Object mergeMessageLock = new Object(); + + private void appendMessage(String message) { + synchronized (mergeMessageLock) { + if (!mergeMessage.isValid()) { + mergeMessage = new MergeMessage(message); + } else { + mergeMessage.addLines(message); + } + } + } + private static void sleep(int millis) { try { Thread.sleep(millis); @@ -506,7 +509,7 @@ public class TGBridge { } - private class JoinLeftAnnounceMessage { + private class MergeMessage { private int messageId; private long time; private long timeMinute; @@ -526,21 +529,21 @@ public class TGBridge { abort = true; } - protected JoinLeftAnnounceMessage(String firstMessage) { + protected MergeMessage(String firstMessage) { text = new StringBuilder(firstMessage); time = System.currentTimeMillis(); timeMinute = time / MINUTE; - sendAnnounceMessage(); + send(); } - private void sendAnnounceMessage() { + private void send() { if (bot == null) { messageId = -1; return; } SendResponse response; try { - response = bot.execute(new SendMessage(CHAT_ID, text.toString())); + response = bot.execute(new SendMessage(CHAT_ID, text.toString()).parseMode(ParseMode.MarkdownV2)); } catch (RuntimeException e) { messageId = -1; @@ -553,7 +556,7 @@ public class TGBridge { messageId = response.message().messageId(); } - protected JoinLeftAnnounceMessage() { + protected MergeMessage() { messageId = 0; time = 0; timeMinute = 0; @@ -561,14 +564,14 @@ public class TGBridge { abort = false; } //dummy - private void addLines(List messages) { + private void addLines(String... messages) { for (String message : messages) { text.append('\n').append(message); } - updateAnnounceMessage(); + update(); } - private void updateAnnounceMessage() { + private void update() { if (!isValid()) { plugin.logger.error("message should only push to a valid object"); return; @@ -578,12 +581,12 @@ public class TGBridge { return; } try { - bot.execute(new EditMessageText(CHAT_ID, messageId, text.toString())); + bot.execute(new EditMessageText(CHAT_ID, messageId, text.toString()).parseMode(ParseMode.MarkdownV2)); } catch (RuntimeException ignored) {} } } - private JoinLeftAnnounceMessage currentAnnounce = new JoinLeftAnnounceMessage(); + private MergeMessage mergeMessage = new MergeMessage(); private LinkedBlockingQueue announceQueue = new LinkedBlockingQueue<>(); private void joinLeftAnnounce(String message) {