完成实现广播服务器控制台日志的功能

Fix #15
This commit is contained in:
Xujiayao 2022-02-16 16:06:08 +08:00
parent baad0559e7
commit 0fe3069e8a
11 changed files with 129 additions and 44 deletions

View file

@ -58,9 +58,11 @@ can [submit an issue](https://github.com/Xujiayao/MCDiscordChat/issues/new).
- Announce when Server MSPT is higher than a certain value
- Customizable Webhook Avatar API
- Customizable in-game message display format
- Customizable Discord bot command prefix
- Blacklist can be used to prohibit the processing of a player or user's message
- Admin list can be used to configure the user's authority to use certain commands
- Broadcast player command execution
- Broadcast server console log
- Support Hot Reloading of the configuration file
- Check for updates

View file

@ -57,9 +57,11 @@ BRForgers/DisFabric 的功能补充和增强。
- 在服务器 MSPT 高于一定值时发出通知
- 可自定义游戏内消息显示格式
- 可自定义 Webhook 头像 API
- 可自定义 Discord 机器人命令前缀
- 可使用黑名单禁止处理某位玩家或用户的消息
- 可使用管理员名单配置用户使用某些命令的权限
- 可广播玩家指令执行
- 可广播服务器控制台日志
- 支持配置文件热重载
- 检查更新

View file

@ -53,6 +53,6 @@ java {
jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
rename { "${it}_${project.archivesBaseName}" }
}
}

View file

@ -32,6 +32,11 @@ public class Config {
// (right-click the channel to copy the ID, you have to turn on developer mode in Discord settings)
public String channelId = "";
// [Required] Discord Channel ID for Console Log Broadcast
// (leave blank to disable this feature)
// (right-click the channel to copy the ID, you have to turn on developer mode in Discord settings)
public String consoleLogChannelId = "";
// [Required] Server world name
public String worldName = "world";
@ -121,6 +126,7 @@ public class Config {
// %message% Content of message
// %mspt% Server MSPT
// %msptLimit% Server MSPT Limit
// %timestamp% Current timestamp
public String serverStarted = "**服务器已启动!**";
public String serverStopped = "**服务器已关闭!**";
@ -136,6 +142,8 @@ public class Config {
public String highMSPT = "**服务器 MSPT (%mspt%) 高于 %msptLimit%**";
public String consoleLogMessage = "**[%timestamp%] [INFO]:** %message%";
public String blueColoredText = "[%servername%] ";
public String roleColoredText = "<%name%>";
public String colorlessText = " %message%";
@ -153,6 +161,7 @@ public class Config {
// %message% Content of message
// %mspt% Server MSPT
// %msptLimit% Server MSPT Limit
// %timestamp% Current timestamp
public String serverStarted = "**Server started!**";
public String serverStopped = "**Server stopped!**";
@ -168,6 +177,8 @@ public class Config {
public String highMSPT = "**Server MSPT (%mspt%) is above %msptLimit%!**";
public String consoleLogMessage = "**[%timestamp%] [INFO]:** %message%";
public String blueColoredText = "[%servername%] ";
public String roleColoredText = "<%name%>";
public String colorlessText = " %message%";

View file

@ -26,12 +26,14 @@ public class Main implements DedicatedServerModInitializer {
public static JDA jda;
public static TextChannel textChannel;
public static TextChannel consoleLogTextChannel;
public static Config config;
public static Texts texts;
public static boolean stop = false;
public static Timer msptMonitorTimer;
public static Timer consoleLogTimer;
@Override
public void onInitializeServer() {
@ -52,6 +54,7 @@ public class Main implements DedicatedServerModInitializer {
jda.awaitReady();
textChannel = jda.getTextChannelById(Main.config.generic.channelId);
consoleLogTextChannel = jda.getTextChannelById(Main.config.generic.consoleLogChannelId);
} catch (Exception e) {
e.printStackTrace();
jda = null;
@ -81,6 +84,10 @@ public class Main implements DedicatedServerModInitializer {
msptMonitorTimer.cancel();
}
if (!config.generic.consoleLogChannelId.isEmpty()) {
consoleLogTimer.cancel();
}
try {
Thread.sleep(250);
} catch (Exception e) {

View file

@ -26,8 +26,11 @@ import top.xujiayao.mcdiscordchat.utils.Utils;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import static top.xujiayao.mcdiscordchat.Main.config;
import static top.xujiayao.mcdiscordchat.Main.consoleLogTextChannel;
import static top.xujiayao.mcdiscordchat.Main.consoleLogTimer;
import static top.xujiayao.mcdiscordchat.Main.textChannel;
/**
@ -126,6 +129,9 @@ public class DiscordEventListener extends ListenerAdapter {
Main.jda.getPresence().setActivity(Activity.listening(config.generic.botListeningStatus));
}
textChannel = Main.jda.getTextChannelById(Main.config.generic.channelId);
consoleLogTextChannel = Main.jda.getTextChannelById(Main.config.generic.consoleLogChannelId);
if (config.generic.announceHighMSPT) {
Main.msptMonitorTimer.cancel();
Main.msptMonitorTimer = new Timer();
@ -134,6 +140,19 @@ public class DiscordEventListener extends ListenerAdapter {
Main.msptMonitorTimer.cancel();
}
if (!config.generic.consoleLogChannelId.isEmpty()) {
Main.consoleLogTimer.cancel();
Main.consoleLogTimer = new Timer();
consoleLogTimer.schedule(new TimerTask() {
@Override
public void run() {
MinecraftEventListener.consoleLogSentTimes = 0;
}
}, 0, 30000);
} else {
Main.consoleLogTimer.cancel();
}
Main.textChannel.sendMessage("**" + (config.generic.switchLanguageFromChinToEng ? "Successfully loaded the configuration file!" : "配置文件加载成功!") + "**").queue();
} catch (Exception ex) {
ex.printStackTrace();
@ -145,36 +164,36 @@ public class DiscordEventListener extends ListenerAdapter {
}
} else if ("help".equals(command)) {
String help = config.generic.switchLanguageFromChinToEng ? """
```
=============== Help ===============
!info: Query server running status
!scoreboard <type> <id>: Query the player scoreboard for this statistic
!ban <type> <id/name>: Add or remove a Discord user or Minecraft player from the blacklist (admins only)
!blacklist: Query blacklist
!console <command>: Executes command in the server console (admins only)
!reload: Reload MCDiscordChat configuration file (admins only)
!admin <id>: Add or remove a Discord user from the list of MCDiscordChat admins (super admins only)
!adminlist: Query admin list
!update: Check for update
!stop: Stop the server (admins only)
```
""" : """
```
=============== 帮助 ===============
!info: 查询服务器运行状态
!scoreboard <type> <id>: 查询该统计信息的玩家排行榜
!ban <type> <id/name>: 将一名 Discord 用户或 Minecraft 玩家从黑名单中添加或移除仅限管理员
!blacklist: 列出黑名单
!console <command>: 在服务器控制台中执行指令仅限管理员
!reload: 重新加载 MCDiscordChat 配置文件仅限管理员
!admin <id>: 将一名 Discord 用户从 MCDiscordChat 普通管理员名单中添加或移除仅限超级管理员
!adminlist: 列出管理员名单
!update: 检查更新
!stop: 停止服务器仅限管理员
```
""";
```
=============== Help ===============
!info: Query server running status
!scoreboard <type> <id>: Query the player scoreboard for this statistic
!ban <type> <id/name>: Add or remove a Discord user or Minecraft player from the blacklist (admins only)
!blacklist: Query blacklist
!console <command>: Executes command in the server console (admins only)
!reload: Reload MCDiscordChat configuration file (admins only)
!admin <id>: Add or remove a Discord user from the list of MCDiscordChat admins (super admins only)
!adminlist: Query admin list
!update: Check for update
!stop: Stop the server (admins only)
```
""" : """
```
=============== 帮助 ===============
!info: 查询服务器运行状态
!scoreboard <type> <id>: 查询该统计信息的玩家排行榜
!ban <type> <id/name>: 将一名 Discord 用户或 Minecraft 玩家从黑名单中添加或移除仅限管理员
!blacklist: 列出黑名单
!console <command>: 在服务器控制台中执行指令仅限管理员
!reload: 重新加载 MCDiscordChat 配置文件仅限管理员
!admin <id>: 将一名 Discord 用户从 MCDiscordChat 普通管理员名单中添加或移除仅限超级管理员
!adminlist: 列出管理员名单
!update: 检查更新
!stop: 停止服务器仅限管理员
```
""";
textChannel.sendMessage(help).queue();
} else if ("blacklist".equals(command)) {

View file

@ -24,13 +24,19 @@ import top.xujiayao.mcdiscordchat.events.SystemMessageCallback;
import top.xujiayao.mcdiscordchat.utils.MarkdownParser;
import top.xujiayao.mcdiscordchat.utils.Utils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Timer;
import java.util.TimerTask;
import static top.xujiayao.mcdiscordchat.Main.client;
import static top.xujiayao.mcdiscordchat.Main.config;
import static top.xujiayao.mcdiscordchat.Main.consoleLogTextChannel;
import static top.xujiayao.mcdiscordchat.Main.consoleLogTimer;
import static top.xujiayao.mcdiscordchat.Main.textChannel;
/**
@ -38,6 +44,8 @@ import static top.xujiayao.mcdiscordchat.Main.textChannel;
*/
public class MinecraftEventListener {
private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
public static int consoleLogSentTimes = 0;
long lastTime = System.currentTimeMillis();
String lastPlayer = "";
@ -171,10 +179,39 @@ public class MinecraftEventListener {
}
});
if (!config.generic.consoleLogChannelId.isEmpty()) {
consoleLogTimer = new Timer();
consoleLogTimer.schedule(new TimerTask() {
@Override
public void run() {
consoleLogSentTimes = 0;
}
}, 0, 30000);
}
SystemMessageCallback.EVENT.register((message) -> {
if (!Main.stop && config.generic.broadcastCommandExecution) {
if (!Main.stop && !config.generic.consoleLogChannelId.isEmpty()) {
try {
textChannel.sendMessage("**[INFO]:** " + message).queue();
consoleLogSentTimes++;
if (consoleLogSentTimes > 10) {
return;
}
consoleLogTextChannel.sendMessage(Main.texts.consoleLogMessage()
.replace("%timestamp%", sdf.format(new Date()))
.replace("%message%", message)).queue();
if (consoleLogSentTimes == 10) {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
consoleLogSentTimes = 0;
}
}, 20000);
consoleLogTextChannel.sendMessage("**" + (config.generic.switchLanguageFromChinToEng ? "Rate limit exceeded! Wait 20 seconds..." : "发送次数超出限制!等待 20 秒...") + "**").queue();
}
} catch (Exception e) {
e.printStackTrace();
textChannel.sendMessage("```\n" + ExceptionUtils.getStackTrace(e) + "\n```").queue();

View file

@ -14,7 +14,7 @@ import java.util.UUID;
* @author Xujiayao
*/
@Mixin(MinecraftServer.class)
public abstract class MixinMinecraftServer {
public class MixinMinecraftServer {
@Redirect(
method = "sendSystemMessage",

View file

@ -12,6 +12,7 @@ public record Texts(String serverStarted,
String advancementChallenge,
String advancementGoal,
String highMSPT,
String consoleLogMessage,
String blueColoredText,
String roleColoredText,
String colorlessText) {

View file

@ -3,6 +3,8 @@ package top.xujiayao.mcdiscordchat.utils;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import net.fabricmc.loader.api.FabricLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import top.xujiayao.mcdiscordchat.Config;
import top.xujiayao.mcdiscordchat.Main;
@ -41,16 +43,18 @@ public class ConfigManager {
} else {
createConfig();
System.err.println("--------------------");
System.err.println("错误:找不到配置文件或配置文件为空!");
System.err.println("Error: The config file cannot be found or is empty!");
System.err.println();
System.err.println("请在重新启动服务器前编辑 /config/mcdiscordchat.json 以配置 MCDiscordChat");
System.err.println("Please edit /config/mcdiscordchat.json to configure MCDiscordChat before restarting the server!");
System.err.println();
System.err.println("正在停止服务器...");
System.err.println("Stopping the server...");
System.err.println("--------------------");
Logger LOGGER = LogManager.getLogger();
LOGGER.error("--------------------");
LOGGER.error("错误:找不到配置文件或配置文件为空!");
LOGGER.error("Error: The config file cannot be found or is empty!");
LOGGER.error("");
LOGGER.error("请在重新启动服务器前编辑 /config/mcdiscordchat.json 以配置 MCDiscordChat");
LOGGER.error("Please edit /config/mcdiscordchat.json to configure MCDiscordChat before restarting the server!");
LOGGER.error("");
LOGGER.error("正在停止服务器...");
LOGGER.error("Stopping the server...");
LOGGER.error("--------------------");
System.exit(1);
}

View file

@ -128,6 +128,7 @@ public class Utils {
Main.config.textsEN.advancementChallenge,
Main.config.textsEN.advancementGoal,
Main.config.textsEN.highMSPT,
Main.config.textsEN.consoleLogMessage,
Main.config.textsEN.blueColoredText,
Main.config.textsEN.roleColoredText,
Main.config.textsEN.colorlessText);
@ -141,6 +142,7 @@ public class Utils {
Main.config.textsZH.advancementChallenge,
Main.config.textsZH.advancementGoal,
Main.config.textsZH.highMSPT,
Main.config.textsZH.consoleLogMessage,
Main.config.textsZH.blueColoredText,
Main.config.textsZH.roleColoredText,
Main.config.textsZH.colorlessText);