feat: adding some feature
This commit is contained in:
parent
8e5a552ab8
commit
64686d2f47
2
.idea/fileTemplates/includes/Version.txt
generated
2
.idea/fileTemplates/includes/Version.txt
generated
@ -1 +1 @@
|
|||||||
1.0.0
|
1.0.2
|
10
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
10
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<Languages>
|
||||||
|
<language minSize="58" name="Java" />
|
||||||
|
</Languages>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
@ -4,7 +4,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
|
|||||||
val projectName = rootProject.name
|
val projectName = rootProject.name
|
||||||
val groupName by extra("cn.wzpmc")
|
val groupName by extra("cn.wzpmc")
|
||||||
val projectArtifactId by extra("my-bot")
|
val projectArtifactId by extra("my-bot")
|
||||||
val projectVersion by extra("1.0.0")
|
val projectVersion by extra("1.0.1")
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
|
@ -3,7 +3,11 @@ package cn.wzpmc;
|
|||||||
import cn.wzpmc.api.api.IMainApi;
|
import cn.wzpmc.api.api.IMainApi;
|
||||||
import cn.wzpmc.api.api.actions.message.get.GetLoginInfoAction;
|
import cn.wzpmc.api.api.actions.message.get.GetLoginInfoAction;
|
||||||
import cn.wzpmc.api.plugins.BasePlugin;
|
import cn.wzpmc.api.plugins.BasePlugin;
|
||||||
import cn.wzpmc.commands.StopCommand;
|
import cn.wzpmc.builtin.commands.DeOpCommand;
|
||||||
|
import cn.wzpmc.builtin.commands.HelpCommand;
|
||||||
|
import cn.wzpmc.builtin.commands.OpCommand;
|
||||||
|
import cn.wzpmc.builtin.commands.StopCommand;
|
||||||
|
import cn.wzpmc.builtin.event.CommandEventHandler;
|
||||||
import cn.wzpmc.configuration.Configuration;
|
import cn.wzpmc.configuration.Configuration;
|
||||||
import cn.wzpmc.console.MyBotConsole;
|
import cn.wzpmc.console.MyBotConsole;
|
||||||
import cn.wzpmc.entities.user.bot.MyBot;
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
@ -87,8 +91,12 @@ public class Main {
|
|||||||
}
|
}
|
||||||
load.onLoad();
|
load.onLoad();
|
||||||
}
|
}
|
||||||
|
// 注册内置指令
|
||||||
CommandManager commandManager = myBot.getCommandManager();
|
CommandManager commandManager = myBot.getCommandManager();
|
||||||
commandManager.registerCommand(new StopCommand(myBot));
|
commandManager.registerCommand(new StopCommand(myBot));
|
||||||
|
commandManager.registerCommand(new OpCommand());
|
||||||
|
commandManager.registerCommand(new HelpCommand());
|
||||||
|
commandManager.registerCommand(new DeOpCommand());
|
||||||
}
|
}
|
||||||
public static WebSocketConnectionHandler createConnection(MyBot myBot, URI uri){
|
public static WebSocketConnectionHandler createConnection(MyBot myBot, URI uri){
|
||||||
WebSocketConnectionHandler webSocketConnectionHandler = new WebSocketConnectionHandler(myBot);
|
WebSocketConnectionHandler webSocketConnectionHandler = new WebSocketConnectionHandler(myBot);
|
||||||
@ -120,6 +128,7 @@ public class Main {
|
|||||||
IMainApi mainApi = myBot.getMainApi();
|
IMainApi mainApi = myBot.getMainApi();
|
||||||
// 获取Bot消息
|
// 获取Bot消息
|
||||||
mainApi.doApiCall(new GetLoginInfoAction());
|
mainApi.doApiCall(new GetLoginInfoAction());
|
||||||
|
myBot.registerEventHandler(new CommandEventHandler());
|
||||||
startConsole(myBot, webSocketConnectionHandler);
|
startConsole(myBot, webSocketConnectionHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package cn.wzpmc.api.commands.arguments;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.message.json.JsonMessagePart;
|
||||||
|
import cn.wzpmc.api.utils.CqCodeUtils;
|
||||||
|
import com.mojang.brigadier.LiteralMessage;
|
||||||
|
import com.mojang.brigadier.StringReader;
|
||||||
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息段参数类型
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 01:18
|
||||||
|
*/
|
||||||
|
public class MessagePartArgument implements ArgumentType<JsonMessagePart> {
|
||||||
|
@Override
|
||||||
|
public JsonMessagePart parse(StringReader stringReader) throws CommandSyntaxException {
|
||||||
|
String s = stringReader.readStringUntil(' ');
|
||||||
|
if (!CqCodeUtils.isCQ(s)){
|
||||||
|
throw new CommandSyntaxException(new SimpleCommandExceptionType(new LiteralMessage("MessagePart")), new LiteralMessage("Cannot read message part"));
|
||||||
|
}
|
||||||
|
return CqCodeUtils.parseToPart(s);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package cn.wzpmc.api.commands.arguments;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.message.json.JsonMessagePart;
|
||||||
|
import cn.wzpmc.api.message.json.parts.At;
|
||||||
|
import cn.wzpmc.api.utils.CqCodeUtils;
|
||||||
|
import cn.wzpmc.console.commands.exceptions.CqCodeException;
|
||||||
|
import com.mojang.brigadier.LiteralMessage;
|
||||||
|
import com.mojang.brigadier.StringReader;
|
||||||
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
|
import com.mojang.brigadier.exceptions.BuiltInExceptions;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID消息类型
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 21:02
|
||||||
|
*/
|
||||||
|
public class UserIdArguments implements ArgumentType<Long> {
|
||||||
|
@Override
|
||||||
|
public Long parse(StringReader stringReader) throws CommandSyntaxException {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
char read = stringReader.read();
|
||||||
|
if (read == '[') {
|
||||||
|
builder.append('[');
|
||||||
|
while (stringReader.canRead()) {
|
||||||
|
read = stringReader.read();
|
||||||
|
builder.append(read);
|
||||||
|
if (read == ']') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String s = builder.toString();
|
||||||
|
if (CqCodeUtils.isCQ(s)) {
|
||||||
|
JsonMessagePart jsonMessagePart = CqCodeUtils.parseToPart(s);
|
||||||
|
if (jsonMessagePart instanceof At){
|
||||||
|
return ((At) jsonMessagePart).getQq();
|
||||||
|
}
|
||||||
|
throw new CqCodeException();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String s = stringReader.readUnquotedString();
|
||||||
|
String s1 = read + s;
|
||||||
|
try {
|
||||||
|
return Long.parseLong(s1);
|
||||||
|
}catch (NumberFormatException ignored) {}
|
||||||
|
}
|
||||||
|
throw new CommandSyntaxException(new BuiltInExceptions().readerInvalidLong(), new LiteralMessage("Cannot read long from user id"));
|
||||||
|
}
|
||||||
|
}
|
55
src/main/java/cn/wzpmc/api/entities/Ops.java
Normal file
55
src/main/java/cn/wzpmc/api/entities/Ops.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package cn.wzpmc.api.entities;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分群op列表
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 20:16
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public final class Ops {
|
||||||
|
/**
|
||||||
|
* BOT总管理员
|
||||||
|
* @since 2024/8/25 20:17 v1.0.0
|
||||||
|
*/
|
||||||
|
private final Set<Long> admins = new HashSet<>();
|
||||||
|
/**
|
||||||
|
* 群内管理员
|
||||||
|
* @since 2024/8/25 20:17 v1.0.0
|
||||||
|
*/
|
||||||
|
private final Map<String, List<Long>> groupAdmins = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断此用户在群中是否为管理
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 20:20 v1.0.0
|
||||||
|
* @param groupId 群ID
|
||||||
|
* @param id 用户ID
|
||||||
|
* @return 是否管理
|
||||||
|
*/
|
||||||
|
public boolean isAdmin(Long groupId, Long id){
|
||||||
|
if (admins.contains(id)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
List<Long> longs = groupAdmins.get(groupId.toString());
|
||||||
|
if (longs == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return longs.contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断此用户是否为管理
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 20:20 v1.0.0
|
||||||
|
* @param id 用户ID
|
||||||
|
* @return 是否管理
|
||||||
|
*/
|
||||||
|
public boolean isAdmin(Long id) {
|
||||||
|
return admins.contains(id);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package cn.wzpmc.api.message.json.parts;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.message.json.JsonMessagePart;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Markdown格式消息
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 15:19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MarkdownMessage implements JsonMessagePart {
|
||||||
|
/**
|
||||||
|
* Markdown格式数据
|
||||||
|
* @since 2024/8/25 15:20 v1.0.0
|
||||||
|
*/
|
||||||
|
private String data;
|
||||||
|
@Override
|
||||||
|
public PartType getPartType() {
|
||||||
|
return PartType.MARKDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject getData() {
|
||||||
|
return JSONObject.of("data", data);
|
||||||
|
}
|
||||||
|
}
|
@ -113,7 +113,12 @@ public enum PartType {
|
|||||||
* JSON消息
|
* JSON消息
|
||||||
* @since 2024/8/23 21:40 v0.0.5-dev
|
* @since 2024/8/23 21:40 v0.0.5-dev
|
||||||
*/
|
*/
|
||||||
JSON(CustomJSONMessage.class);
|
JSON(CustomJSONMessage.class),
|
||||||
|
/**
|
||||||
|
* Markdown消息
|
||||||
|
* @since 2024/8/25 15:20 v1.0.0
|
||||||
|
*/
|
||||||
|
MARKDOWN(MarkdownMessage.class);
|
||||||
public final Class<? extends JsonMessagePart> clazz;
|
public final Class<? extends JsonMessagePart> clazz;
|
||||||
PartType(Class<? extends JsonMessagePart> clazz){
|
PartType(Class<? extends JsonMessagePart> clazz){
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.wzpmc.api.user;
|
package cn.wzpmc.api.user;
|
||||||
|
|
||||||
import cn.wzpmc.api.api.IMainApi;
|
import cn.wzpmc.api.api.IMainApi;
|
||||||
|
import cn.wzpmc.api.entities.Ops;
|
||||||
import cn.wzpmc.api.events.Event;
|
import cn.wzpmc.api.events.Event;
|
||||||
import cn.wzpmc.api.plugins.ICommandManager;
|
import cn.wzpmc.api.plugins.ICommandManager;
|
||||||
import cn.wzpmc.api.plugins.configuration.IConfiguration;
|
import cn.wzpmc.api.plugins.configuration.IConfiguration;
|
||||||
@ -105,4 +106,70 @@ public abstract class IBot extends MessageSender implements CommandSender {
|
|||||||
}
|
}
|
||||||
throw new RuntimeException(new IllegalAccessException("Shouldn't set id after initialized"));
|
throw new RuntimeException(new IllegalAccessException("Shouldn't set id after initialized"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取OP列表
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 14:11 v1.0.0
|
||||||
|
* @return OP列表
|
||||||
|
*/
|
||||||
|
abstract public Ops getOps();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加一个OP用户
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 14:12 v1.0.0
|
||||||
|
* @param userId 用户ID
|
||||||
|
*/
|
||||||
|
abstract public void addOp(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为一个群添加OP用户
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 20:21 v1.0.0
|
||||||
|
* @param groupId 群ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
*/
|
||||||
|
abstract public void addOp(Long groupId, Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除一个用户的OP身份
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 20:23 v1.0.0
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 是否移除
|
||||||
|
*/
|
||||||
|
abstract public boolean removeOp(Long userId);
|
||||||
|
/**
|
||||||
|
* 移除一个用户在群内的OP身份
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 20:23 v1.0.0
|
||||||
|
* @param groupId 群ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 是否移除
|
||||||
|
*/
|
||||||
|
abstract public boolean removeOp(Long groupId, Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户是否为OP
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 14:10 v1.0.0
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 是否为OP
|
||||||
|
*/
|
||||||
|
public boolean isBotOp(Long userId){
|
||||||
|
return getOps().isAdmin(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户在群内是否为OP
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/25 20:22 v1.0.0
|
||||||
|
* @param groupId 群ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 是否为OP
|
||||||
|
*/
|
||||||
|
public boolean isBotOp(Long groupId, Long userId) {
|
||||||
|
return this.getOps().isAdmin(groupId, userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import cn.wzpmc.api.user.CommandSender;
|
|||||||
import cn.wzpmc.api.user.IBot;
|
import cn.wzpmc.api.user.IBot;
|
||||||
import cn.wzpmc.api.user.Sex;
|
import cn.wzpmc.api.user.Sex;
|
||||||
import cn.wzpmc.api.user.permission.Permissions;
|
import cn.wzpmc.api.user.permission.Permissions;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@ -42,7 +43,7 @@ public class GroupCommandSender extends GroupUser implements CommandSender {
|
|||||||
JsonMessage jsonMessage = new JsonMessage();
|
JsonMessage jsonMessage = new JsonMessage();
|
||||||
List<JsonMessagePart> messageParts = jsonMessage.getMessageParts();
|
List<JsonMessagePart> messageParts = jsonMessage.getMessageParts();
|
||||||
messageParts.add(new At(this.getId()));
|
messageParts.add(new At(this.getId()));
|
||||||
messageParts.add(StringMessage.text(messageComponent.toMessageString()));
|
messageParts.add(StringMessage.text(" " + messageComponent.toMessageString()));
|
||||||
SendGroupMessageAction sendGroupMessageAction = new SendGroupMessageAction(this.groupId, jsonMessage);
|
SendGroupMessageAction sendGroupMessageAction = new SendGroupMessageAction(this.groupId, jsonMessage);
|
||||||
mainApi.doApiCall(sendGroupMessageAction);
|
mainApi.doApiCall(sendGroupMessageAction);
|
||||||
}
|
}
|
||||||
@ -68,6 +69,10 @@ public class GroupCommandSender extends GroupUser implements CommandSender {
|
|||||||
String level = sender.getLevel();
|
String level = sender.getLevel();
|
||||||
GroupUserRole role = sender.getRole();
|
GroupUserRole role = sender.getRole();
|
||||||
String title = sender.getTitle();
|
String title = sender.getTitle();
|
||||||
|
IBot instance = MyBot.getInstance();
|
||||||
|
if (!permissions.isAdmin() && instance.isBotOp(eventGroupId, id)) {
|
||||||
|
permissions = Permissions.ADMIN;
|
||||||
|
}
|
||||||
return new GroupCommandSender(id, name, permissions, nickname, sex, age, card, area, level, role, title, eventGroupId);
|
return new GroupCommandSender(id, name, permissions, nickname, sex, age, card, area, level, role, title, eventGroupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
148
src/main/java/cn/wzpmc/api/utils/CqCodeUtils.java
Normal file
148
src/main/java/cn/wzpmc/api/utils/CqCodeUtils.java
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
package cn.wzpmc.api.utils;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.message.json.JsonMessagePart;
|
||||||
|
import cn.wzpmc.api.message.json.parts.PartType;
|
||||||
|
import cn.wzpmc.api.message.json.parts.music.MusicType;
|
||||||
|
import cn.wzpmc.api.message.json.parts.node.CustomNode;
|
||||||
|
import cn.wzpmc.api.message.json.parts.node.SingleNode;
|
||||||
|
import cn.wzpmc.api.message.json.parts.poke.Poke;
|
||||||
|
import cn.wzpmc.api.message.json.parts.poke.PokeType;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CQ码相关工具类
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/26 14:06
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
public class CqCodeUtils {
|
||||||
|
/**
|
||||||
|
* 判断一个字符串是否为CQ码
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/26 14:08 v1.0.0
|
||||||
|
* @param word 一个词(不包含空格)
|
||||||
|
* @return 是否为CQ码
|
||||||
|
*/
|
||||||
|
public static boolean isCQ(String word){
|
||||||
|
return word.startsWith("[") && word.endsWith("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析CQ码为Map
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/26 14:08 v1.0.0
|
||||||
|
* @param word 一个词(不包含空格)
|
||||||
|
* @return 解析后的Map
|
||||||
|
*/
|
||||||
|
public static Map<String, String> parse(String word){
|
||||||
|
StringBuilder key = new StringBuilder();
|
||||||
|
boolean keyDone = false;
|
||||||
|
StringBuilder value = new StringBuilder();
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
for (int i = 0; i < word.length(); i++) {
|
||||||
|
char c = word.charAt(i);
|
||||||
|
if (c == '[') continue;
|
||||||
|
if (c == ']') {
|
||||||
|
result.put(key.toString(), value.toString());
|
||||||
|
}
|
||||||
|
if (keyDone) {
|
||||||
|
if (c == ','){
|
||||||
|
result.put(key.toString(), value.toString());
|
||||||
|
key = new StringBuilder();
|
||||||
|
value = new StringBuilder();
|
||||||
|
keyDone = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value.append(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == ':' || c == '='){
|
||||||
|
keyDone = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
key.append(c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将文本转化为JsonMessagePart
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/26 14:34 v1.0.0
|
||||||
|
* @param word 一个词(不包含空格)
|
||||||
|
* @return 消息文本段
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static JsonMessagePart parseToPart(String word) {
|
||||||
|
Map<String, String> parse = parse(word);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(parse));
|
||||||
|
Object cq = jsonObject.get("CQ");
|
||||||
|
JSONObject jsonObj = JSONObject.of("type", cq, "data", jsonObject);
|
||||||
|
return parsePart(jsonObj);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 将json解析为单个消息段
|
||||||
|
* @author wzp
|
||||||
|
* @since 2024/8/26 14:40 v1.0.0
|
||||||
|
* @param jsonObject json数据
|
||||||
|
* @return 消息段
|
||||||
|
* @throws InvocationTargetException 调用构造方法失败时抛出
|
||||||
|
* @throws InstantiationException 实例化错误时抛出
|
||||||
|
* @throws IllegalAccessException 实例化错误时抛出
|
||||||
|
* @throws NoSuchMethodException 找不到构造方法时抛出
|
||||||
|
*/
|
||||||
|
public static JsonMessagePart parsePart(JSONObject jsonObject) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
|
||||||
|
PartType type = jsonObject.getObject("type", PartType.class);
|
||||||
|
Class<? extends JsonMessagePart> clazz = type.clazz;
|
||||||
|
JSONObject dataObject = jsonObject.getJSONObject("data");
|
||||||
|
if (type.equals(PartType.POKE)){
|
||||||
|
Integer pokeType = dataObject.getInteger("type");
|
||||||
|
Integer pokeId = dataObject.getInteger("id");
|
||||||
|
for (PokeType value : PokeType.values()) {
|
||||||
|
if (value.type.equals(pokeType) && value.id.equals(pokeId)){
|
||||||
|
return new Poke(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.warn("无法识别的戳一戳类型:type: {}, id: {}", pokeType, pokeId);
|
||||||
|
return new Poke();
|
||||||
|
}
|
||||||
|
if (type.equals(PartType.NODE)){
|
||||||
|
if (jsonObject.containsKey("content")){
|
||||||
|
clazz = CustomNode.class;
|
||||||
|
}else{
|
||||||
|
clazz = SingleNode.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type.equals(PartType.MUSIC)){
|
||||||
|
MusicType musicType = dataObject.getObject("type", MusicType.class);
|
||||||
|
dataObject.put("musicType", musicType);
|
||||||
|
clazz = musicType.clazz;
|
||||||
|
}
|
||||||
|
Constructor<? extends JsonMessagePart> declaredConstructor = clazz.getDeclaredConstructor();
|
||||||
|
JsonMessagePart resultPart = declaredConstructor.newInstance();
|
||||||
|
for (Field declaredField : clazz.getDeclaredFields()) {
|
||||||
|
JSONField annotation = declaredField.getAnnotation(JSONField.class);
|
||||||
|
String name = Objects.isNull(annotation) ? declaredField.getName() : annotation.name();
|
||||||
|
if (!dataObject.containsKey(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
declaredField.setAccessible(true);
|
||||||
|
Class<?> thisFieldClass = declaredField.getType();
|
||||||
|
Object value = dataObject.getObject(name, thisFieldClass);
|
||||||
|
declaredField.set(resultPart, value);
|
||||||
|
}
|
||||||
|
return resultPart;
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
* @version 0.0.4-dev
|
* @version 0.0.4-dev
|
||||||
* @since 2024/8/16 00:02
|
* @since 2024/8/16 00:02
|
||||||
*/
|
*/
|
||||||
public class IncreasbleHashMap<K, V> extends HashMap<K, List<V>> implements IncreasbleMap<K, V>{
|
public class IncreasbleHashMap<K, V> extends HashMap<K, List<V>> implements IncreasbleMap<K, V, List<V>>{
|
||||||
@Override
|
@Override
|
||||||
public void add(K key, V value) {
|
public void add(K key, V value) {
|
||||||
List<V> newArrayList = super.getOrDefault(key, new ArrayList<>());
|
List<V> newArrayList = super.getOrDefault(key, new ArrayList<>());
|
||||||
@ -41,7 +41,7 @@ public class IncreasbleHashMap<K, V> extends HashMap<K, List<V>> implements Incr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAll(IncreasbleMap<K, V> increasbleMap) {
|
public void addAll(IncreasbleMap<K, V, List<V>> increasbleMap) {
|
||||||
for (Entry<K, List<V>> entry : increasbleMap.entrySet()) {
|
for (Entry<K, List<V>> entry : increasbleMap.entrySet()) {
|
||||||
this.addAll(entry.getKey(), entry.getValue());
|
this.addAll(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.wzpmc.api.utils;
|
package cn.wzpmc.api.utils;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,8 +8,11 @@ import java.util.Map;
|
|||||||
* @author wzp
|
* @author wzp
|
||||||
* @version 0.0.4-dev
|
* @version 0.0.4-dev
|
||||||
* @since 2024/8/15 23:57
|
* @since 2024/8/15 23:57
|
||||||
|
* @param <C> 集合类型
|
||||||
|
* @param <K> key类型
|
||||||
|
* @param <V> value类型
|
||||||
*/
|
*/
|
||||||
public interface IncreasbleMap<K, V> extends Map<K, List<V>> {
|
public interface IncreasbleMap<K, V, C extends Collection<V>> extends Map<K, C> {
|
||||||
/**
|
/**
|
||||||
* 向一个Key中添加元素
|
* 向一个Key中添加元素
|
||||||
* @author wzp
|
* @author wzp
|
||||||
@ -45,7 +47,7 @@ public interface IncreasbleMap<K, V> extends Map<K, List<V>> {
|
|||||||
* @since 2024/8/16 00:35 v0.0.4-dev
|
* @since 2024/8/16 00:35 v0.0.4-dev
|
||||||
* @param increasbleMap 另一个表
|
* @param increasbleMap 另一个表
|
||||||
*/
|
*/
|
||||||
void addAll(IncreasbleMap<K, V> increasbleMap);
|
void addAll(IncreasbleMap<K, V, C> increasbleMap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将所有value添加到此key中
|
* 将所有value添加到此key中
|
||||||
|
77
src/main/java/cn/wzpmc/builtin/commands/DeOpCommand.java
Normal file
77
src/main/java/cn/wzpmc/builtin/commands/DeOpCommand.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package cn.wzpmc.builtin.commands;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.commands.BrigadierCommand;
|
||||||
|
import cn.wzpmc.api.commands.arguments.UserIdArguments;
|
||||||
|
import cn.wzpmc.api.entities.Ops;
|
||||||
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
|
import cn.wzpmc.api.user.CommandSender;
|
||||||
|
import cn.wzpmc.api.user.IBot;
|
||||||
|
import cn.wzpmc.api.user.group.GroupCommandSender;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
|
import com.mojang.brigadier.arguments.LongArgumentType;
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/26 16:54
|
||||||
|
*/
|
||||||
|
public class DeOpCommand implements BrigadierCommand {
|
||||||
|
private final IBot instance;
|
||||||
|
public DeOpCommand(){
|
||||||
|
this.instance = MyBot.getInstance();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public LiteralArgumentBuilder<CommandSender> getCommandNode() {
|
||||||
|
return LiteralArgumentBuilder.
|
||||||
|
<CommandSender>literal("deop").
|
||||||
|
requires(CommandSender::isAdmin).
|
||||||
|
then(RequiredArgumentBuilder.<CommandSender, Long>argument("user", new UserIdArguments()).
|
||||||
|
executes(e -> {
|
||||||
|
Ops ops = instance.getOps();
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
Long targetId = e.getArgument("user", Long.class);
|
||||||
|
if (source instanceof GroupCommandSender){
|
||||||
|
if (ops.isAdmin(source.getId())){
|
||||||
|
instance.removeOp(targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "移除总OP权限"));
|
||||||
|
}else{
|
||||||
|
Long groupId = ((GroupCommandSender) source).getGroupId();
|
||||||
|
instance.removeOp(groupId, targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "移除群:" + groupId + "的OP权限"));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
instance.removeOp(targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "移除总OP权限"));
|
||||||
|
return 0;
|
||||||
|
}).
|
||||||
|
then(LiteralArgumentBuilder.<CommandSender>literal("group")
|
||||||
|
.then(RequiredArgumentBuilder.<CommandSender, Long>argument("group", LongArgumentType.longArg()).
|
||||||
|
executes(e -> {
|
||||||
|
Long targetGroupId = e.getArgument("group", Long.class);
|
||||||
|
Long targetId = e.getArgument("user", Long.class);
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
if (source instanceof GroupCommandSender){
|
||||||
|
if (!instance.isBotOp(targetGroupId, source.getId())) {
|
||||||
|
source.sendMessage(StringMessage.text("权限不足!"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instance.removeOp(targetGroupId, targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "移除群:" + targetGroupId + "的OP权限"));
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
).requires((e) -> e instanceof GroupCommandSender).executes(e -> {
|
||||||
|
GroupCommandSender source = (GroupCommandSender) e.getSource();
|
||||||
|
Long groupId = source.getGroupId();
|
||||||
|
Long targetId = e.getArgument("user", Long.class);
|
||||||
|
instance.removeOp(groupId, targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "移除群:" + groupId + "的OP权限"));
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
58
src/main/java/cn/wzpmc/builtin/commands/HelpCommand.java
Normal file
58
src/main/java/cn/wzpmc/builtin/commands/HelpCommand.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package cn.wzpmc.builtin.commands;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.commands.BrigadierCommand;
|
||||||
|
import cn.wzpmc.api.commands.RawCommand;
|
||||||
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
|
import cn.wzpmc.api.user.CommandSender;
|
||||||
|
import cn.wzpmc.api.user.IBot;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
|
import cn.wzpmc.plugins.CommandManager;
|
||||||
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
|
import com.mojang.brigadier.tree.RootCommandNode;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 15:07
|
||||||
|
*/
|
||||||
|
public class HelpCommand implements BrigadierCommand {
|
||||||
|
@Override
|
||||||
|
public LiteralArgumentBuilder<CommandSender> getCommandNode() {
|
||||||
|
return LiteralArgumentBuilder.<CommandSender>literal("help").executes(e -> {
|
||||||
|
IBot instance = MyBot.getInstance();
|
||||||
|
CommandManager commandManager = (CommandManager) instance.getCommandManager();
|
||||||
|
CommandDispatcher<CommandSender> dispatcher = commandManager.getDispatcher();
|
||||||
|
RootCommandNode<CommandSender> root = dispatcher.getRoot();
|
||||||
|
Collection<CommandNode<CommandSender>> children = root.getChildren();
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
for (CommandNode<CommandSender> child : children) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append('\n');
|
||||||
|
builder.append('/');
|
||||||
|
builder.append(child.getUsageText());
|
||||||
|
builder.append('\n');
|
||||||
|
handlerNode(child.getChildren(), 1, builder);
|
||||||
|
source.sendMessage(StringMessage.text(builder.toString()));
|
||||||
|
}
|
||||||
|
ConcurrentHashMap<String, RawCommand> rawCommands = commandManager.getRawCommands();
|
||||||
|
for (Map.Entry<String, RawCommand> stringRawCommandEntry : rawCommands.entrySet()) {
|
||||||
|
source.sendMessage(StringMessage.text("/" + stringRawCommandEntry.getKey()));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private static void handlerNode(Collection<CommandNode<CommandSender>> node, int tabCount, StringBuilder builder){
|
||||||
|
for (CommandNode<CommandSender> commandSenderCommandNode : node) {
|
||||||
|
builder.append("\t".repeat(Math.max(0, tabCount)));
|
||||||
|
builder.append(commandSenderCommandNode.getUsageText());
|
||||||
|
builder.append('\n');
|
||||||
|
handlerNode(commandSenderCommandNode.getChildren(), tabCount + 1, builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
183
src/main/java/cn/wzpmc/builtin/commands/OpCommand.java
Normal file
183
src/main/java/cn/wzpmc/builtin/commands/OpCommand.java
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
package cn.wzpmc.builtin.commands;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.commands.BrigadierCommand;
|
||||||
|
import cn.wzpmc.api.commands.arguments.UserIdArguments;
|
||||||
|
import cn.wzpmc.api.entities.Ops;
|
||||||
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
|
import cn.wzpmc.api.user.CommandSender;
|
||||||
|
import cn.wzpmc.api.user.IBot;
|
||||||
|
import cn.wzpmc.api.user.group.GroupCommandSender;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
|
import com.mojang.brigadier.arguments.LongArgumentType;
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 15:35
|
||||||
|
*/
|
||||||
|
public class OpCommand implements BrigadierCommand {
|
||||||
|
private final IBot instance;
|
||||||
|
public OpCommand(){
|
||||||
|
this.instance = MyBot.getInstance();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public LiteralArgumentBuilder<CommandSender> getCommandNode() {
|
||||||
|
return LiteralArgumentBuilder.
|
||||||
|
<CommandSender>literal("op").
|
||||||
|
then(LiteralArgumentBuilder.<CommandSender>literal("list").executes(e -> {
|
||||||
|
Ops ops = instance.getOps();
|
||||||
|
Map<String, List<Long>> groupAdmins = ops.getGroupAdmins();
|
||||||
|
Set<Long> fullAdmins = ops.getAdmins();
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
Long id = source.getId();
|
||||||
|
boolean groupAdmin = false;
|
||||||
|
boolean fullAdmin = fullAdmins.contains(id);
|
||||||
|
Long sendGroupId = -1L;
|
||||||
|
List<Long> sendGroupAdmins = new ArrayList<>();
|
||||||
|
if (source instanceof GroupCommandSender) {
|
||||||
|
sendGroupId = ((GroupCommandSender) source).getGroupId();
|
||||||
|
List<Long> orDefault = groupAdmins.getOrDefault(sendGroupId.toString(), new ArrayList<>());
|
||||||
|
sendGroupAdmins.addAll(orDefault);
|
||||||
|
groupAdmin = orDefault.contains(id);
|
||||||
|
}
|
||||||
|
if (source instanceof IBot) {
|
||||||
|
groupAdmin = true;
|
||||||
|
fullAdmin = true;
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
if (fullAdmin){
|
||||||
|
builder.append(getFullOpListString(fullAdmins)).append('\n');
|
||||||
|
for (Map.Entry<String, List<Long>> stringListEntry : groupAdmins.entrySet()) {
|
||||||
|
builder.append(getGroupOpListString(stringListEntry.getValue(), Long.valueOf(stringListEntry.getKey()))).append('\n');
|
||||||
|
}
|
||||||
|
builder.deleteCharAt(builder.lastIndexOf("\n"));
|
||||||
|
|
||||||
|
}else if (groupAdmin) {
|
||||||
|
builder.append(getGroupOpListString(sendGroupAdmins, sendGroupId));
|
||||||
|
}else {
|
||||||
|
builder.append("权限不足!");
|
||||||
|
}
|
||||||
|
source.sendMessage(StringMessage.text(builder.toString()));
|
||||||
|
return 0;
|
||||||
|
}).then(LiteralArgumentBuilder.<CommandSender>literal("group").
|
||||||
|
then(RequiredArgumentBuilder.<CommandSender, Long>argument("groupId", LongArgumentType.longArg()).
|
||||||
|
executes(e -> {
|
||||||
|
Long groupId = e.getArgument("groupId", Long.class);
|
||||||
|
Ops ops = instance.getOps();
|
||||||
|
Map<String, List<Long>> groupsAdmins = ops.getGroupAdmins();
|
||||||
|
Set<Long> admins = ops.getAdmins();
|
||||||
|
List<Long> groupAdmins = groupsAdmins.getOrDefault(groupId.toString(), new ArrayList<>());
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
Long id = source.getId();
|
||||||
|
String result = "权限不足";
|
||||||
|
if (source instanceof IBot || admins.contains(id) || groupAdmins.contains(id)) {
|
||||||
|
result = getGroupOpListString(groupAdmins, groupId);
|
||||||
|
}
|
||||||
|
source.sendMessage(StringMessage.text(result));
|
||||||
|
return 0;
|
||||||
|
})).
|
||||||
|
executes(e -> {
|
||||||
|
CommandSender commandSender = e.getSource();
|
||||||
|
if (!(commandSender instanceof GroupCommandSender)) {
|
||||||
|
commandSender.sendMessage(StringMessage.text("仅支持群内使用此指令!"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
GroupCommandSender source = (GroupCommandSender) commandSender;
|
||||||
|
Long groupId = source.getGroupId();
|
||||||
|
Ops ops = instance.getOps();
|
||||||
|
Map<String, List<Long>> groupsAdmins = ops.getGroupAdmins();
|
||||||
|
Set<Long> admins = ops.getAdmins();
|
||||||
|
List<Long> groupAdmins = groupsAdmins.getOrDefault(groupId.toString(), new ArrayList<>());
|
||||||
|
Long id = source.getId();
|
||||||
|
String result = "权限不足";
|
||||||
|
if (admins.contains(id) || groupAdmins.contains(id)) {
|
||||||
|
result = getGroupOpListString(groupAdmins, groupId);
|
||||||
|
}
|
||||||
|
source.sendMessage(StringMessage.text(result));
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
).then(LiteralArgumentBuilder.<CommandSender>literal("full").executes(e -> {
|
||||||
|
Ops ops = instance.getOps();
|
||||||
|
Set<Long> admins = ops.getAdmins();
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
Long id = source.getId();
|
||||||
|
String result = "权限不足";
|
||||||
|
if (source instanceof IBot || admins.contains(id)) {
|
||||||
|
result = getFullOpListString(admins);
|
||||||
|
}
|
||||||
|
source.sendMessage(StringMessage.text(result));
|
||||||
|
return 0;
|
||||||
|
}))).
|
||||||
|
requires(CommandSender::isAdmin).
|
||||||
|
then(RequiredArgumentBuilder.<CommandSender, Long>argument("user", new UserIdArguments()).
|
||||||
|
executes(e -> {
|
||||||
|
Ops ops = instance.getOps();
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
Long targetId = e.getArgument("user", Long.class);
|
||||||
|
if (source instanceof GroupCommandSender){
|
||||||
|
if (ops.isAdmin(source.getId())){
|
||||||
|
instance.addOp(targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "添加总OP权限"));
|
||||||
|
}else{
|
||||||
|
Long groupId = ((GroupCommandSender) source).getGroupId();
|
||||||
|
instance.addOp(groupId, targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "添加群:" + groupId + "的OP权限"));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
instance.addOp(targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "添加总OP权限"));
|
||||||
|
return 0;
|
||||||
|
}).
|
||||||
|
then(LiteralArgumentBuilder.<CommandSender>literal("group")
|
||||||
|
.then(RequiredArgumentBuilder.<CommandSender, Long>argument("group", LongArgumentType.longArg()).
|
||||||
|
executes(e -> {
|
||||||
|
Long targetGroupId = e.getArgument("group", Long.class);
|
||||||
|
Long targetId = e.getArgument("user", Long.class);
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
if (source instanceof GroupCommandSender){
|
||||||
|
if (!instance.isBotOp(targetGroupId, source.getId())) {
|
||||||
|
source.sendMessage(StringMessage.text("权限不足!"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instance.addOp(targetGroupId, targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "添加群:" + targetGroupId + "的OP权限"));
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
).requires((e) -> e instanceof GroupCommandSender).executes(e -> {
|
||||||
|
GroupCommandSender source = (GroupCommandSender) e.getSource();
|
||||||
|
Long groupId = source.getGroupId();
|
||||||
|
Long targetId = e.getArgument("user", Long.class);
|
||||||
|
instance.addOp(groupId, targetId);
|
||||||
|
source.sendMessage(StringMessage.text("已为用户:" + targetId + "添加群:" + groupId + "的OP权限"));
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private static String getFullOpListString(Collection<Long> admins){
|
||||||
|
return "总管理:" + '\n' +
|
||||||
|
getOpListString(admins);
|
||||||
|
}
|
||||||
|
private static String getGroupOpListString(Collection<Long> admins, Long groupId){
|
||||||
|
return "群" + groupId + "的管理员:" + '\n' +
|
||||||
|
getOpListString(admins);
|
||||||
|
}
|
||||||
|
private static StringBuilder getOpListString(Collection<Long> admins) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
if (admins.isEmpty()){
|
||||||
|
builder.append("无").append('\n');
|
||||||
|
}
|
||||||
|
for (Long admin : admins) {
|
||||||
|
builder.append('\t').append(admin).append('\n');
|
||||||
|
}
|
||||||
|
int lastLine = builder.lastIndexOf("\n");
|
||||||
|
builder.deleteCharAt(lastLine);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package cn.wzpmc.commands;
|
package cn.wzpmc.builtin.commands;
|
||||||
|
|
||||||
import cn.wzpmc.api.commands.BrigadierCommand;
|
import cn.wzpmc.api.commands.BrigadierCommand;
|
||||||
|
import cn.wzpmc.api.entities.Ops;
|
||||||
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
import cn.wzpmc.api.user.CommandSender;
|
import cn.wzpmc.api.user.CommandSender;
|
||||||
import cn.wzpmc.api.user.IBot;
|
import cn.wzpmc.api.user.IBot;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /stop指令
|
* /stop指令
|
||||||
* @author wzp
|
* @author wzp
|
||||||
@ -18,9 +22,16 @@ public class StopCommand implements BrigadierCommand {
|
|||||||
@Override
|
@Override
|
||||||
public LiteralArgumentBuilder<CommandSender> getCommandNode() {
|
public LiteralArgumentBuilder<CommandSender> getCommandNode() {
|
||||||
return LiteralArgumentBuilder.<CommandSender>literal("stop")
|
return LiteralArgumentBuilder.<CommandSender>literal("stop")
|
||||||
.requires(CommandSender::isAdmin)
|
.requires(e -> {
|
||||||
|
Ops ops = bot.getOps();
|
||||||
|
Set<Long> admins = ops.getAdmins();
|
||||||
|
return admins.contains(e.getId());
|
||||||
|
})
|
||||||
.executes((e) -> {
|
.executes((e) -> {
|
||||||
|
CommandSender source = e.getSource();
|
||||||
|
source.sendMessage(StringMessage.text(" !!!MyBot已关闭!!!"));
|
||||||
this.bot.stop();
|
this.bot.stop();
|
||||||
|
System.exit(0);
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package cn.wzpmc.builtin.event;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.events.message.group.GroupMessageEvent;
|
||||||
|
import cn.wzpmc.api.events.message.priv.PrivateMessageEvent;
|
||||||
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
|
import cn.wzpmc.api.plugins.event.EventHandler;
|
||||||
|
import cn.wzpmc.api.user.Friend;
|
||||||
|
import cn.wzpmc.api.user.IBot;
|
||||||
|
import cn.wzpmc.api.user.group.GroupCommandSender;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
|
import cn.wzpmc.plugins.CommandManager;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命令事件处理器
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 13:40
|
||||||
|
*/
|
||||||
|
public class CommandEventHandler {
|
||||||
|
@EventHandler
|
||||||
|
public void onGroupMessage(GroupMessageEvent event){
|
||||||
|
GroupCommandSender groupCommandSender = GroupCommandSender.of(event);
|
||||||
|
IBot instance = MyBot.getInstance();
|
||||||
|
Long id = instance.getId();
|
||||||
|
String message = event.getRawMessage().getMessage();
|
||||||
|
Pattern compile = Pattern.compile("\\[CQ:at,qq=" + id + ".*?]\\s*?/.*");
|
||||||
|
if (compile.asMatchPredicate().test(message)){
|
||||||
|
CommandManager commandManager = (CommandManager) instance.getCommandManager();
|
||||||
|
commandManager.execute(groupCommandSender, message.replaceFirst("\\[CQ:at,qq=[0-9]{10}.*?]\\s*?/", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@EventHandler
|
||||||
|
public void onPrivateMessage(PrivateMessageEvent event){
|
||||||
|
Friend sender = event.getSender();
|
||||||
|
IBot instance = MyBot.getInstance();
|
||||||
|
StringMessage rawMessage = event.getRawMessage();
|
||||||
|
String message = rawMessage.getMessage();
|
||||||
|
if (message.startsWith("/")){
|
||||||
|
CommandManager commandManager = (CommandManager) instance.getCommandManager();
|
||||||
|
commandManager.execute(sender, message.replaceFirst("/", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,8 @@
|
|||||||
package cn.wzpmc.console;
|
package cn.wzpmc.console;
|
||||||
|
|
||||||
import cn.wzpmc.api.plugins.BasePlugin;
|
|
||||||
import cn.wzpmc.entities.user.bot.MyBot;
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
import cn.wzpmc.network.WebSocketConnectionHandler;
|
import cn.wzpmc.network.WebSocketConnectionHandler;
|
||||||
import cn.wzpmc.plugins.CommandManager;
|
import cn.wzpmc.plugins.CommandManager;
|
||||||
import cn.wzpmc.plugins.PluginManager;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
@ -46,8 +44,6 @@ public class MyBotConsole extends SimpleTerminalConsole {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
PluginManager pluginManager = this.bot.getPluginManager();
|
|
||||||
pluginManager.getPlugins().forEach(BasePlugin::onUnload);
|
|
||||||
this.webSocketConnectionHandler.kill();
|
this.webSocketConnectionHandler.kill();
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package cn.wzpmc.console.commands.exceptions;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.LiteralMessage;
|
||||||
|
import com.mojang.brigadier.Message;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 21:06
|
||||||
|
*/
|
||||||
|
public class CqCodeException extends CommandSyntaxException {
|
||||||
|
private static final Message errorMessage = new LiteralMessage("Cannot read cq code");
|
||||||
|
public CqCodeException() {
|
||||||
|
super(new CqCodeExceptionType(errorMessage), errorMessage);
|
||||||
|
|
||||||
|
}
|
||||||
|
private static final class CqCodeExceptionType extends SimpleCommandExceptionType {
|
||||||
|
public CqCodeExceptionType(Message message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
package cn.wzpmc.entities.user.bot;
|
package cn.wzpmc.entities.user.bot;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.api.ActionResponse;
|
||||||
import cn.wzpmc.api.api.IMainApi;
|
import cn.wzpmc.api.api.IMainApi;
|
||||||
|
import cn.wzpmc.api.api.actions.message.get.GetGroupListAction;
|
||||||
|
import cn.wzpmc.api.entities.GroupInformation;
|
||||||
|
import cn.wzpmc.api.entities.Ops;
|
||||||
import cn.wzpmc.api.events.Event;
|
import cn.wzpmc.api.events.Event;
|
||||||
import cn.wzpmc.api.message.MessageComponent;
|
import cn.wzpmc.api.message.MessageComponent;
|
||||||
import cn.wzpmc.api.message.StringMessage;
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
@ -17,13 +21,21 @@ import cn.wzpmc.plugins.CommandManager;
|
|||||||
import cn.wzpmc.plugins.PluginManager;
|
import cn.wzpmc.plugins.PluginManager;
|
||||||
import cn.wzpmc.plugins.api.MainApi;
|
import cn.wzpmc.plugins.api.MainApi;
|
||||||
import cn.wzpmc.utils.ReflectionUtils;
|
import cn.wzpmc.utils.ReflectionUtils;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机器人实现类
|
* 机器人实现类
|
||||||
@ -48,9 +60,36 @@ public class MyBot extends IBot {
|
|||||||
@Getter
|
@Getter
|
||||||
private IMainApi mainApi;
|
private IMainApi mainApi;
|
||||||
private WebSocketConnectionHandler connectionHandler;
|
private WebSocketConnectionHandler connectionHandler;
|
||||||
|
@Getter
|
||||||
|
private final Ops ops;
|
||||||
|
private final File opFile;
|
||||||
public MyBot(Configuration configuration){
|
public MyBot(Configuration configuration){
|
||||||
|
Ops opsTmp;
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.permissions = Permissions.ADMIN;
|
this.permissions = Permissions.ADMIN;
|
||||||
|
this.opFile = new File("ops.json");
|
||||||
|
if (!this.opFile.isFile()) {
|
||||||
|
opsTmp = new Ops();
|
||||||
|
try {
|
||||||
|
if (!this.opFile.createNewFile()) {
|
||||||
|
log.error("无法创建OP文件!");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("创建OP文件失败!",e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try(FileInputStream fis = new FileInputStream(this.opFile)) {
|
||||||
|
opsTmp = JSON.parseObject(fis, Ops.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("读取OP文件失败!");
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opsTmp == null){
|
||||||
|
opsTmp = new Ops();
|
||||||
|
}
|
||||||
|
this.ops = opsTmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,6 +110,7 @@ public class MyBot extends IBot {
|
|||||||
if (this.console != null) {
|
if (this.console != null) {
|
||||||
this.console.shutdown();
|
this.console.shutdown();
|
||||||
}
|
}
|
||||||
|
this.flushOpsFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -99,4 +139,77 @@ public class MyBot extends IBot {
|
|||||||
this.connectionHandler = connectionHandler;
|
this.connectionHandler = connectionHandler;
|
||||||
this.mainApi = new MainApi(this, this.connectionHandler);
|
this.mainApi = new MainApi(this, this.connectionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addOp(Long userId) {
|
||||||
|
Set<Long> admins = this.ops.getAdmins();
|
||||||
|
admins.add(userId);
|
||||||
|
this.flushOpsFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addOp(Long groupId, Long userId) {
|
||||||
|
Map<String, List<Long>> admins = this.ops.getGroupAdmins();
|
||||||
|
String string = groupId.toString();
|
||||||
|
List<Long> longs = admins.getOrDefault(string, new ArrayList<>());
|
||||||
|
if (!longs.contains(userId)) {
|
||||||
|
longs.add(userId);
|
||||||
|
admins.put(string, longs);
|
||||||
|
this.flushOpsFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeOp(Long userId) {
|
||||||
|
if (!this.ops.isAdmin(userId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Set<Long> admins = this.ops.getAdmins();
|
||||||
|
admins.remove(userId);
|
||||||
|
flushOpsFile();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public boolean removeOp(Long groupId, Long userId) {
|
||||||
|
boolean groupAdmin = this.ops.isAdmin(groupId, userId);
|
||||||
|
boolean admin = this.ops.isAdmin(userId);
|
||||||
|
if (!groupAdmin && !admin){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Map<String, List<Long>> admins = this.ops.getGroupAdmins();
|
||||||
|
String string = groupId.toString();
|
||||||
|
if (groupAdmin && !admin) {
|
||||||
|
List<Long> longs = admins.get(string);
|
||||||
|
longs.remove(userId);
|
||||||
|
admins.put(string, longs);
|
||||||
|
} else {
|
||||||
|
ActionResponse<List<GroupInformation>> listActionResponse = this.mainApi.doApiCall(new GetGroupListAction());
|
||||||
|
List<GroupInformation> data = listActionResponse.getData();
|
||||||
|
this.ops.getAdmins().remove(userId);
|
||||||
|
for (GroupInformation groupInformation : data) {
|
||||||
|
Long groupInformationGroupId = groupInformation.getGroupId();
|
||||||
|
if (groupInformationGroupId.equals(groupId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String groupIdString = groupInformationGroupId.toString();
|
||||||
|
List<Long> orDefault = admins.getOrDefault(groupIdString, new ArrayList<>());
|
||||||
|
if (!orDefault.contains(userId)) {
|
||||||
|
orDefault.add(userId);
|
||||||
|
}
|
||||||
|
admins.put(groupIdString, orDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flushOpsFile();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flushOpsFile() {
|
||||||
|
try(FileOutputStream fos = new FileOutputStream(this.opFile)){
|
||||||
|
JSON.writeTo(fos, this.ops);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("写入OP文件失败!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class PacketHandler extends SimpleChannelInboundHandler<TextWebSocketFram
|
|||||||
@Override
|
@Override
|
||||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame webSocketFrame) {
|
protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame webSocketFrame) {
|
||||||
String text = webSocketFrame.text();
|
String text = webSocketFrame.text();
|
||||||
System.out.println(text);
|
// System.out.println(text);
|
||||||
if (!JSON.isValidObject(text)){
|
if (!JSON.isValidObject(text)){
|
||||||
log.warn("收到了无法处理的WebSocket数据包:{}", text);
|
log.warn("收到了无法处理的WebSocket数据包:{}", text);
|
||||||
return;
|
return;
|
||||||
@ -59,7 +59,8 @@ public class PacketHandler extends SimpleChannelInboundHandler<TextWebSocketFram
|
|||||||
try {
|
try {
|
||||||
this.bot.triggerEvent(event);
|
this.bot.triggerEvent(event);
|
||||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||||
log.error(new RuntimeException(e));
|
log.throwing(e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|||||||
import com.mojang.brigadier.suggestion.Suggestion;
|
import com.mojang.brigadier.suggestion.Suggestion;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
@ -37,7 +38,9 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@Log4j2
|
@Log4j2
|
||||||
public class CommandManager implements ICommandManager, Completer, Highlighter {
|
public class CommandManager implements ICommandManager, Completer, Highlighter {
|
||||||
|
@Getter
|
||||||
private final CommandDispatcher<CommandSender> dispatcher = new CommandDispatcher<>();
|
private final CommandDispatcher<CommandSender> dispatcher = new CommandDispatcher<>();
|
||||||
|
@Getter
|
||||||
private final ConcurrentHashMap<String, RawCommand> rawCommands = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, RawCommand> rawCommands = new ConcurrentHashMap<>();
|
||||||
private static final int[] COLORS = {AttributedStyle.CYAN, AttributedStyle.YELLOW, AttributedStyle.GREEN, AttributedStyle.MAGENTA, AttributedStyle.BLUE};
|
private static final int[] COLORS = {AttributedStyle.CYAN, AttributedStyle.YELLOW, AttributedStyle.GREEN, AttributedStyle.MAGENTA, AttributedStyle.BLUE};
|
||||||
private final IBot bot;
|
private final IBot bot;
|
||||||
|
@ -11,8 +11,10 @@ import cn.wzpmc.api.events.notice.notify.NotifyEvent;
|
|||||||
import cn.wzpmc.api.events.request.RequestEvent;
|
import cn.wzpmc.api.events.request.RequestEvent;
|
||||||
import cn.wzpmc.api.message.StringMessage;
|
import cn.wzpmc.api.message.StringMessage;
|
||||||
import cn.wzpmc.api.message.json.JsonMessage;
|
import cn.wzpmc.api.message.json.JsonMessage;
|
||||||
|
import cn.wzpmc.api.user.Friend;
|
||||||
import cn.wzpmc.api.user.IBot;
|
import cn.wzpmc.api.user.IBot;
|
||||||
import cn.wzpmc.api.user.IUser;
|
import cn.wzpmc.api.user.IUser;
|
||||||
|
import cn.wzpmc.api.user.group.GroupUser;
|
||||||
import cn.wzpmc.utils.json.action.ActionReader;
|
import cn.wzpmc.utils.json.action.ActionReader;
|
||||||
import cn.wzpmc.utils.json.action.ActionWriter;
|
import cn.wzpmc.utils.json.action.ActionWriter;
|
||||||
import cn.wzpmc.utils.json.event.*;
|
import cn.wzpmc.utils.json.event.*;
|
||||||
@ -20,6 +22,8 @@ import cn.wzpmc.utils.json.honor.HonorWriter;
|
|||||||
import cn.wzpmc.utils.json.message.JsonMessageReader;
|
import cn.wzpmc.utils.json.message.JsonMessageReader;
|
||||||
import cn.wzpmc.utils.json.message.JsonMessageWriter;
|
import cn.wzpmc.utils.json.message.JsonMessageWriter;
|
||||||
import cn.wzpmc.utils.json.message.StringMessageReader;
|
import cn.wzpmc.utils.json.message.StringMessageReader;
|
||||||
|
import cn.wzpmc.utils.json.user.FriendUserReader;
|
||||||
|
import cn.wzpmc.utils.json.user.GroupUserReader;
|
||||||
import cn.wzpmc.utils.json.user.IBotReader;
|
import cn.wzpmc.utils.json.user.IBotReader;
|
||||||
import cn.wzpmc.utils.json.user.IUserReader;
|
import cn.wzpmc.utils.json.user.IUserReader;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
@ -59,6 +63,8 @@ public class JsonUtils {
|
|||||||
JSON.register(ActionResponse.class, new ActionReader());
|
JSON.register(ActionResponse.class, new ActionReader());
|
||||||
JSON.register(IUser.class, new IUserReader());
|
JSON.register(IUser.class, new IUserReader());
|
||||||
JSON.register(IBot.class, new IBotReader());
|
JSON.register(IBot.class, new IBotReader());
|
||||||
|
JSON.register(Friend.class, new FriendUserReader());
|
||||||
|
JSON.register(GroupUser.class, new GroupUserReader());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import java.io.InputStream;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
@ -69,9 +70,9 @@ public class ReflectionUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static IncreasbleMap<Class<? extends Event>, EventHandlerMethod> loadEvents(Object eventHandlerObject){
|
public static IncreasbleMap<Class<? extends Event>, EventHandlerMethod, List<EventHandlerMethod>> loadEvents(Object eventHandlerObject){
|
||||||
Class<?> eventHandlerClass = eventHandlerObject.getClass();
|
Class<?> eventHandlerClass = eventHandlerObject.getClass();
|
||||||
IncreasbleMap<Class<? extends Event>, EventHandlerMethod> result = new IncreasbleHashMap<>();
|
IncreasbleMap<Class<? extends Event>, EventHandlerMethod, List<EventHandlerMethod>> result = new IncreasbleHashMap<>();
|
||||||
for (Method declaredMethod : eventHandlerClass.getDeclaredMethods()) {
|
for (Method declaredMethod : eventHandlerClass.getDeclaredMethods()) {
|
||||||
declaredMethod.setAccessible(true);
|
declaredMethod.setAccessible(true);
|
||||||
if (!declaredMethod.isAnnotationPresent(EventHandler.class)){
|
if (!declaredMethod.isAnnotationPresent(EventHandler.class)){
|
||||||
|
@ -2,25 +2,16 @@ package cn.wzpmc.utils.json.message;
|
|||||||
|
|
||||||
import cn.wzpmc.api.message.json.JsonMessage;
|
import cn.wzpmc.api.message.json.JsonMessage;
|
||||||
import cn.wzpmc.api.message.json.JsonMessagePart;
|
import cn.wzpmc.api.message.json.JsonMessagePart;
|
||||||
import cn.wzpmc.api.message.json.parts.PartType;
|
import cn.wzpmc.api.utils.CqCodeUtils;
|
||||||
import cn.wzpmc.api.message.json.parts.music.MusicType;
|
|
||||||
import cn.wzpmc.api.message.json.parts.node.CustomNode;
|
|
||||||
import cn.wzpmc.api.message.json.parts.node.SingleNode;
|
|
||||||
import cn.wzpmc.api.message.json.parts.poke.Poke;
|
|
||||||
import cn.wzpmc.api.message.json.parts.poke.PokeType;
|
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.alibaba.fastjson2.JSONReader;
|
import com.alibaba.fastjson2.JSONReader;
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.alibaba.fastjson2.reader.ObjectReader;
|
import com.alibaba.fastjson2.reader.ObjectReader;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json消息解析器
|
* json消息解析器
|
||||||
@ -36,49 +27,9 @@ public class JsonMessageReader implements ObjectReader<JsonMessage> {
|
|||||||
JSONArray objects = jsonReader.readJSONArray();
|
JSONArray objects = jsonReader.readJSONArray();
|
||||||
JsonMessage message = new JsonMessage();
|
JsonMessage message = new JsonMessage();
|
||||||
List<JsonMessagePart> messageParts = message.getMessageParts();
|
List<JsonMessagePart> messageParts = message.getMessageParts();
|
||||||
messageFor: for (int i = 0; i < objects.size(); i++) {
|
for (int i = 0; i < objects.size(); i++) {
|
||||||
JSONObject jsonObject = objects.getJSONObject(i);
|
JSONObject jsonObject = objects.getJSONObject(i);
|
||||||
PartType type = jsonObject.getObject("type", PartType.class);
|
messageParts.add(CqCodeUtils.parsePart(jsonObject));
|
||||||
Class<? extends JsonMessagePart> clazz = type.clazz;
|
|
||||||
JSONObject dataObject = jsonObject.getJSONObject("data");
|
|
||||||
if (type.equals(PartType.POKE)){
|
|
||||||
Integer pokeType = dataObject.getInteger("type");
|
|
||||||
Integer pokeId = dataObject.getInteger("id");
|
|
||||||
for (PokeType value : PokeType.values()) {
|
|
||||||
if (value.type.equals(pokeType) && value.id.equals(pokeId)){
|
|
||||||
messageParts.add(new Poke(value));
|
|
||||||
continue messageFor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.warn("无法识别的戳一戳类型:type: {}, id: {}", pokeType, pokeId);
|
|
||||||
messageParts.add(new Poke());
|
|
||||||
}
|
|
||||||
if (type.equals(PartType.NODE)){
|
|
||||||
if (jsonObject.containsKey("content")){
|
|
||||||
clazz = CustomNode.class;
|
|
||||||
}else{
|
|
||||||
clazz = SingleNode.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type.equals(PartType.MUSIC)){
|
|
||||||
MusicType musicType = dataObject.getObject("type", MusicType.class);
|
|
||||||
dataObject.put("musicType", musicType);
|
|
||||||
clazz = musicType.clazz;
|
|
||||||
}
|
|
||||||
Constructor<? extends JsonMessagePart> declaredConstructor = clazz.getDeclaredConstructor();
|
|
||||||
JsonMessagePart resultPart = declaredConstructor.newInstance();
|
|
||||||
for (Field declaredField : clazz.getDeclaredFields()) {
|
|
||||||
JSONField annotation = declaredField.getAnnotation(JSONField.class);
|
|
||||||
String name = Objects.isNull(annotation) ? declaredField.getName() : annotation.name();
|
|
||||||
if (!dataObject.containsKey(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
declaredField.setAccessible(true);
|
|
||||||
Class<?> thisFieldClass = declaredField.getType();
|
|
||||||
Object value = dataObject.getObject(name, thisFieldClass);
|
|
||||||
declaredField.set(resultPart, value);
|
|
||||||
}
|
|
||||||
messageParts.add(resultPart);
|
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
35
src/main/java/cn/wzpmc/utils/json/user/FriendUserReader.java
Normal file
35
src/main/java/cn/wzpmc/utils/json/user/FriendUserReader.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package cn.wzpmc.utils.json.user;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.user.Friend;
|
||||||
|
import cn.wzpmc.api.user.IBot;
|
||||||
|
import cn.wzpmc.api.user.permission.Permissions;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
|
import com.alibaba.fastjson2.JSONFactory;
|
||||||
|
import com.alibaba.fastjson2.JSONReader;
|
||||||
|
import com.alibaba.fastjson2.reader.ObjectReader;
|
||||||
|
import com.alibaba.fastjson2.reader.ObjectReaderCreator;
|
||||||
|
import com.alibaba.fastjson2.reader.ObjectReaderProvider;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 15:08
|
||||||
|
*/
|
||||||
|
public class FriendUserReader implements ObjectReader<Friend> {
|
||||||
|
@Override
|
||||||
|
public Friend readObject(JSONReader jsonReader, Type type, Object o, long l) {
|
||||||
|
ObjectReaderProvider defaultObjectReaderProvider = JSONFactory.getDefaultObjectReaderProvider();
|
||||||
|
ObjectReaderCreator creator = defaultObjectReaderProvider.getCreator();
|
||||||
|
ObjectReader<Friend> objectReader = creator.createObjectReader(Friend.class);
|
||||||
|
Friend friend = objectReader.readObject(jsonReader, type, o, l);
|
||||||
|
Long id = friend.getId();
|
||||||
|
IBot instance = MyBot.getInstance();
|
||||||
|
friend.setPermissions(Permissions.MEMBER);
|
||||||
|
if (instance.isBotOp(id)) {
|
||||||
|
friend.setPermissions(Permissions.ADMIN);
|
||||||
|
}
|
||||||
|
return friend;
|
||||||
|
}
|
||||||
|
}
|
36
src/main/java/cn/wzpmc/utils/json/user/GroupUserReader.java
Normal file
36
src/main/java/cn/wzpmc/utils/json/user/GroupUserReader.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package cn.wzpmc.utils.json.user;
|
||||||
|
|
||||||
|
import cn.wzpmc.api.user.IBot;
|
||||||
|
import cn.wzpmc.api.user.group.GroupUser;
|
||||||
|
import cn.wzpmc.api.user.permission.Permissions;
|
||||||
|
import cn.wzpmc.entities.user.bot.MyBot;
|
||||||
|
import com.alibaba.fastjson2.JSONFactory;
|
||||||
|
import com.alibaba.fastjson2.JSONReader;
|
||||||
|
import com.alibaba.fastjson2.reader.ObjectReader;
|
||||||
|
import com.alibaba.fastjson2.reader.ObjectReaderCreator;
|
||||||
|
import com.alibaba.fastjson2.reader.ObjectReaderProvider;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/25 15:08
|
||||||
|
*/
|
||||||
|
public class GroupUserReader implements ObjectReader<GroupUser> {
|
||||||
|
@Override
|
||||||
|
public GroupUser readObject(JSONReader jsonReader, Type type, Object o, long l) {
|
||||||
|
ObjectReaderProvider defaultObjectReaderProvider = JSONFactory.getDefaultObjectReaderProvider();
|
||||||
|
ObjectReaderCreator creator = defaultObjectReaderProvider.getCreator();
|
||||||
|
ObjectReader<GroupUser> objectReader = creator.createObjectReader(GroupUser.class);
|
||||||
|
GroupUser user = objectReader.readObject(jsonReader, type, o, l);
|
||||||
|
Long id = user.getId();
|
||||||
|
IBot instance = MyBot.getInstance();
|
||||||
|
user.setPermissions(Permissions.valueOf(user.getRole().name()));
|
||||||
|
if (Objects.nonNull(user.getPermissions()) && !user.getPermissions().isAdmin() && instance.isBotOp(id)) {
|
||||||
|
user.setPermissions(Permissions.ADMIN);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
29
src/test/java/TestCqUtils.java
Normal file
29
src/test/java/TestCqUtils.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import cn.wzpmc.api.message.json.JsonMessagePart;
|
||||||
|
import cn.wzpmc.api.utils.CqCodeUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wzp
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/8/26 14:14
|
||||||
|
*/
|
||||||
|
public class TestCqUtils {
|
||||||
|
@Test
|
||||||
|
public void testIsCq(){
|
||||||
|
System.out.println(CqCodeUtils.isCQ("[CQ:at,qq=123456789]"));
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testCqParser(){
|
||||||
|
Map<String, String> parse = CqCodeUtils.parse("[CQ:at,qq=123456789,name=123]");
|
||||||
|
for (Map.Entry<String, String> stringStringEntry : parse.entrySet()) {
|
||||||
|
System.out.println(stringStringEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testParseCq(){
|
||||||
|
JsonMessagePart jsonMessagePart = CqCodeUtils.parseToPart("[CQ:at,qq=123456789,name=123]");
|
||||||
|
System.out.println(jsonMessagePart);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user