7 Commits

Author SHA1 Message Date
01a2feec03 Update API Version to 2 2023-09-03 10:09:33 +08:00
04b8d2dc77 update plugin api version to 3 2023-09-02 18:03:04 +08:00
4129eaa13e update plugin version to v1.0.0 2023-09-02 18:02:51 +08:00
dc90a17824 feat: implement group command response 2023-09-02 18:02:20 +08:00
e795c5a9c4 Upgrade to 1.6.0 2023-06-03 00:12:41 +08:00
28456bb179 Update version to 0.2.1 2023-04-09 20:42:30 +08:00
397cf392f5 Implement token reloading (fix #2) 2023-04-09 20:41:18 +08:00
10 changed files with 94 additions and 20 deletions

View File

@@ -45,7 +45,6 @@ Server command (requires `server.chat.others` permissions) :
- `/serverchat op|deop <userId(QQ)>` Set or remove op
- The account set as op can directly execute commands with the admin prefix in the specified group
- The command prefix can be set in the configuration file `adminPrefix`, the default is `/`, for example `/sc ban @10002`
- At present, there is no reply when executing commands in the group, because the console execution process will only log to the console, which is not easy to capture
`/serverchat` can be aliased as `/sc`

View File

@@ -14,7 +14,7 @@
在游戏内与服务器账号对话,相当于发送到世界频道,服务器内所有玩家均可收到消息。
## TODO List
## 功能列表
- [x] 玩家间聊天
- [x] 聊天管理命令
- [x] 发言频率限制
@@ -72,12 +72,10 @@
7. 在GC中使用 `/sc op <userId(QQ)>` 来设置管理员账号
8. 现在,理论上已经完成了群服互联,在群里可以看到玩家上下线和聊天,同时玩家也可以在游戏里看到群里聊天,
你还可以在群里用默认前缀 `/` 来执行命令,
但是暂时**不会**回复结果,你可能需要自己看控制台来查看执行结果。
_值得注意的是本插件支持的是 [OneBot-v11](https://github.com/botuniverse/onebot-11) 协议理论上所有支持OneBot-v11 [反向WebSocket](https://github.com/botuniverse/onebot-11/blob/master/communication/ws-reverse.md) 的机器人框架都可以连接不仅限于cqhttp。_
_TODO: 计划会出一个极简的纯对话协议比OneBot更简单方便第三方对接。_
---

View File

@@ -3,7 +3,7 @@ plugins {
}
group 'com.github.jie65535.openchat'
version 'dev-0.2.0'
version '1.0.0'
repositories {
mavenCentral()

View File

@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
public class MiniOneBot implements WsStream.WsMessageHandler {
private final Logger logger;
private final Javalin javalin;
private final String token;
private String token;
private MiniOneBotWsServer server;
// private MiniOneBotWsClient client;
@@ -43,6 +43,21 @@ public class MiniOneBot implements WsStream.WsMessageHandler {
this.logger = logger;
}
/**
* 更新OneBot Token
* @param token 授权令牌
*/
public void setToken(String token) {
if (!Objects.equals(this.token, token)) {
this.token = token;
if (server != null)
server.setToken(token);
// if (client != null)
// client.setToken(token);
logger.info("MiniOneBot Token changed.");
}
}
// region WebSocket
public void startWsServer(String path) {

View File

@@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class MiniOneBotWsServer implements WsStream, Closeable {
private final String token;
private String token;
private final Logger logger;
private final Map<WsContext, String> connections = new ConcurrentHashMap<>();
@@ -46,6 +46,10 @@ public class MiniOneBotWsServer implements WsStream, Closeable {
logger.info("WebSocket server started at {}", path);
}
public void setToken(String token) {
this.token = token;
}
public void onConnect(WsConnectContext ctx) {
logger.info("onConnect: address={} headers={}", ctx.session.getRemoteAddress(), ctx.headerMap());
var author = ctx.header("Authorization");

View File

@@ -17,6 +17,8 @@
*/
package com.github.jie65535.openchat;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent;
import emu.grasscutter.server.event.player.PlayerJoinEvent;
public final class EventListeners {
@@ -26,4 +28,31 @@ public final class EventListeners {
((OpenChatSystem) cs).onPlayerJoin(event);
}
}
private static final StringBuilder consoleMessageHandler = new StringBuilder();
private static StringBuilder commandResponseHandler;
public static String runConsoleCommand(String rawCommand) {
synchronized (consoleMessageHandler) {
commandResponseHandler = consoleMessageHandler;
consoleMessageHandler.setLength(0);
// 尝试执行管理员命令
CommandMap.getInstance().invoke(null, null, rawCommand);
commandResponseHandler = null;
return consoleMessageHandler.toString();
}
}
/**
* 命令执行反馈事件处理
*/
public static void onCommandResponse(ReceiveCommandFeedbackEvent event) {
if (commandResponseHandler == null || event.getPlayer() != null) return;
if (!consoleMessageHandler.isEmpty()) {
// New line
consoleMessageHandler.append(System.lineSeparator());
}
consoleMessageHandler.append(event.getMessage());
}
}

View File

@@ -23,6 +23,7 @@ import com.github.jie65535.openchat.utils.SensitiveWordFilter;
import emu.grasscutter.plugin.Plugin;
import emu.grasscutter.server.event.EventHandler;
import emu.grasscutter.server.event.HandlerPriority;
import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent;
import emu.grasscutter.server.event.player.PlayerJoinEvent;
import emu.grasscutter.utils.JsonUtils;
@@ -37,6 +38,10 @@ public final class OpenChatPlugin extends Plugin {
return instance;
}
private OpenChatSystem openChatSystem;
public OpenChatSystem getOpenChatSystem() {
return openChatSystem;
}
@Override
public void onLoad() {
@@ -54,13 +59,18 @@ public final class OpenChatPlugin extends Plugin {
.priority(HandlerPriority.NORMAL)
.listener(EventListeners::onJoin)
.register(this);
new EventHandler<>(ReceiveCommandFeedbackEvent.class)
.priority(HandlerPriority.NORMAL)
.listener(EventListeners::onCommandResponse)
.register(this);
// Register commands.
getHandle().registerCommand(new ChatServerCommands());
getHandle().registerCommand(new ChatPlayerCommands());
// Set my chat system.
getServer().setChatSystem(new OpenChatSystem(this));
openChatSystem = new OpenChatSystem(this);
getServer().setChatSystem(openChatSystem);
// Log a plugin status message.
getLogger().info("[OpenChat] Enabled, see https://github.com/jie65535/gc-openchat-plugin");

View File

@@ -20,7 +20,6 @@ package com.github.jie65535.openchat;
import com.github.jie65535.minionebot.MiniOneBot;
import com.github.jie65535.minionebot.events.GroupMessage;
import emu.grasscutter.GameConstants;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.game.chat.ChatSystem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.player.PlayerJoinEvent;
@@ -45,6 +44,19 @@ public class OpenChatSystem extends ChatSystem {
// 获取HttpServer框架
var javalin = plugin.getHandle().getHttpServer().getHandle();
// 构造MiniOneBot
miniOneBot = new MiniOneBot(javalin, loadToken(), logger);
// 启动WebSocket服务
miniOneBot.startWsServer(plugin.getConfig().wsPath);
// 订阅群消息事件
miniOneBot.subscribeGroupMessageEvent(this::onGroupMessage);
}
/**
* 从配置文件中载入WsToken如果为空则生成一个
* @return Token
*/
private String loadToken() {
var token = plugin.getConfig().wsToken;
if (token == null || token.isEmpty()) {
token = Utils.base64Encode(Crypto.createSessionKey(24));
@@ -52,12 +64,14 @@ public class OpenChatSystem extends ChatSystem {
plugin.saveConfig();
logger.warn("Detected that wsToken is empty, automatically generated Token for you as follows: {}", token);
}
// 构造MiniOneBot
miniOneBot = new MiniOneBot(javalin, token, logger);
// 启动WebSocket服务
miniOneBot.startWsServer(plugin.getConfig().wsPath);
// 订阅群消息事件
miniOneBot.subscribeGroupMessageEvent(this::onGroupMessage);
return token;
}
/**
* 重新载入Token
*/
public void reloadToken() {
miniOneBot.setToken(loadToken());
}
/**
@@ -244,9 +258,9 @@ public class OpenChatSystem extends ChatSystem {
) {
try {
logger.info("Command used by op [{}({})]: {}", event.senderCardOrNickname(), event.senderId(), event.message());
// 尝试执行管理员命令
CommandMap.getInstance().invoke(null, null,
event.message().substring(plugin.getConfig().adminPrefix.length()));
String rawCommand = event.message().substring(plugin.getConfig().adminPrefix.length());
String result = EventListeners.runConsoleCommand(rawCommand);
miniOneBot.sendGroupMessage(event.groupId(), result);
} catch (Exception ex) {
logger.error("Administrator command execution failed", ex);
}

View File

@@ -106,8 +106,12 @@ public class ChatServerCommands implements CommandHandler {
CommandHandler.sendMessage(sender, "OK");
}
case "reload" -> {
// 重载配置
plugin.loadConfig();
// 重载敏感词
plugin.loadSensitiveWordList();
// 重载令牌
plugin.getOpenChatSystem().reloadToken();
CommandHandler.sendMessage(sender, "OK");
}
case "group" -> {

View File

@@ -1,7 +1,8 @@
{
"name": "openchat-plugin",
"description": "Chat with players in the server console",
"version": "0.1.0",
"version": "1.0.0",
"mainClass": "com.github.jie65535.openchat.OpenChatPlugin",
"authors": ["jie65535"]
"authors": ["jie65535"],
"api": 2
}