feat: adding some feature

This commit is contained in:
wzp 2024-08-26 18:34:30 +08:00
parent 8e5a552ab8
commit 64686d2f47
30 changed files with 1049 additions and 72 deletions

View File

@ -1 +1 @@
1.0.0
1.0.2

View 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>

View File

@ -4,7 +4,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
val projectName = rootProject.name
val groupName by extra("cn.wzpmc")
val projectArtifactId by extra("my-bot")
val projectVersion by extra("1.0.0")
val projectVersion by extra("1.0.1")
plugins {
id("java")

View File

@ -3,7 +3,11 @@ package cn.wzpmc;
import cn.wzpmc.api.api.IMainApi;
import cn.wzpmc.api.api.actions.message.get.GetLoginInfoAction;
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.console.MyBotConsole;
import cn.wzpmc.entities.user.bot.MyBot;
@ -87,8 +91,12 @@ public class Main {
}
load.onLoad();
}
// 注册内置指令
CommandManager commandManager = myBot.getCommandManager();
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){
WebSocketConnectionHandler webSocketConnectionHandler = new WebSocketConnectionHandler(myBot);
@ -120,6 +128,7 @@ public class Main {
IMainApi mainApi = myBot.getMainApi();
// 获取Bot消息
mainApi.doApiCall(new GetLoginInfoAction());
myBot.registerEventHandler(new CommandEventHandler());
startConsole(myBot, webSocketConnectionHandler);
}
}

View File

@ -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);
}
}

View File

@ -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"));
}
}

View 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);
}
}

View File

@ -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);
}
}

View File

@ -113,7 +113,12 @@ public enum PartType {
* JSON消息
* @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;
PartType(Class<? extends JsonMessagePart> clazz){
this.clazz = clazz;

View File

@ -1,6 +1,7 @@
package cn.wzpmc.api.user;
import cn.wzpmc.api.api.IMainApi;
import cn.wzpmc.api.entities.Ops;
import cn.wzpmc.api.events.Event;
import cn.wzpmc.api.plugins.ICommandManager;
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"));
}
/**
* 获取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);
}
}

View File

@ -12,6 +12,7 @@ import cn.wzpmc.api.user.CommandSender;
import cn.wzpmc.api.user.IBot;
import cn.wzpmc.api.user.Sex;
import cn.wzpmc.api.user.permission.Permissions;
import cn.wzpmc.entities.user.bot.MyBot;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -42,7 +43,7 @@ public class GroupCommandSender extends GroupUser implements CommandSender {
JsonMessage jsonMessage = new JsonMessage();
List<JsonMessagePart> messageParts = jsonMessage.getMessageParts();
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);
mainApi.doApiCall(sendGroupMessageAction);
}
@ -68,6 +69,10 @@ public class GroupCommandSender extends GroupUser implements CommandSender {
String level = sender.getLevel();
GroupUserRole role = sender.getRole();
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);
}
}

View 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;
}
}

View File

@ -11,7 +11,7 @@ import java.util.List;
* @version 0.0.4-dev
* @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
public void add(K key, V value) {
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
public void addAll(IncreasbleMap<K, V> increasbleMap) {
public void addAll(IncreasbleMap<K, V, List<V>> increasbleMap) {
for (Entry<K, List<V>> entry : increasbleMap.entrySet()) {
this.addAll(entry.getKey(), entry.getValue());
}

View File

@ -1,7 +1,6 @@
package cn.wzpmc.api.utils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
@ -9,8 +8,11 @@ import java.util.Map;
* @author wzp
* @version 0.0.4-dev
* @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中添加元素
* @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
* @param increasbleMap 另一个表
*/
void addAll(IncreasbleMap<K, V> increasbleMap);
void addAll(IncreasbleMap<K, V, C> increasbleMap);
/**
* 将所有value添加到此key中

View 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;
})
)
);
}
}

View 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);
}
}
}

View 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;
}
}

View File

@ -1,11 +1,15 @@
package cn.wzpmc.commands;
package cn.wzpmc.builtin.commands;
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.IBot;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import lombok.RequiredArgsConstructor;
import java.util.Set;
/**
* /stop指令
* @author wzp
@ -18,9 +22,16 @@ public class StopCommand implements BrigadierCommand {
@Override
public LiteralArgumentBuilder<CommandSender> getCommandNode() {
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) -> {
CommandSender source = e.getSource();
source.sendMessage(StringMessage.text(" !!!MyBot已关闭!!!"));
this.bot.stop();
System.exit(0);
return 0;
});
}

View File

@ -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("/", ""));
}
}
}

View File

@ -1,10 +1,8 @@
package cn.wzpmc.console;
import cn.wzpmc.api.plugins.BasePlugin;
import cn.wzpmc.entities.user.bot.MyBot;
import cn.wzpmc.network.WebSocketConnectionHandler;
import cn.wzpmc.plugins.CommandManager;
import cn.wzpmc.plugins.PluginManager;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
@ -46,8 +44,6 @@ public class MyBotConsole extends SimpleTerminalConsole {
@Override
public void shutdown() {
PluginManager pluginManager = this.bot.getPluginManager();
pluginManager.getPlugins().forEach(BasePlugin::onUnload);
this.webSocketConnectionHandler.kill();
running = false;
}

View File

@ -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);
}
}
}

View File

@ -1,6 +1,10 @@
package cn.wzpmc.entities.user.bot;
import cn.wzpmc.api.api.ActionResponse;
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.message.MessageComponent;
import cn.wzpmc.api.message.StringMessage;
@ -17,13 +21,21 @@ import cn.wzpmc.plugins.CommandManager;
import cn.wzpmc.plugins.PluginManager;
import cn.wzpmc.plugins.api.MainApi;
import cn.wzpmc.utils.ReflectionUtils;
import com.alibaba.fastjson2.JSON;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 机器人实现类
@ -48,9 +60,36 @@ public class MyBot extends IBot {
@Getter
private IMainApi mainApi;
private WebSocketConnectionHandler connectionHandler;
@Getter
private final Ops ops;
private final File opFile;
public MyBot(Configuration configuration){
Ops opsTmp;
this.configuration = configuration;
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
@ -71,6 +110,7 @@ public class MyBot extends IBot {
if (this.console != null) {
this.console.shutdown();
}
this.flushOpsFile();
}
@Override
@ -99,4 +139,77 @@ public class MyBot extends IBot {
this.connectionHandler = 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);
}
}
}

View File

@ -33,7 +33,7 @@ public class PacketHandler extends SimpleChannelInboundHandler<TextWebSocketFram
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame webSocketFrame) {
String text = webSocketFrame.text();
System.out.println(text);
// System.out.println(text);
if (!JSON.isValidObject(text)){
log.warn("收到了无法处理的WebSocket数据包{}", text);
return;
@ -59,7 +59,8 @@ public class PacketHandler extends SimpleChannelInboundHandler<TextWebSocketFram
try {
this.bot.triggerEvent(event);
} catch (InvocationTargetException | IllegalAccessException e) {
log.error(new RuntimeException(e));
log.throwing(e);
throw new RuntimeException(e);
}
});
}

View File

@ -13,6 +13,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.tree.LiteralCommandNode;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.ToString;
import lombok.extern.log4j.Log4j2;
@ -37,7 +38,9 @@ import java.util.stream.Collectors;
*/
@Log4j2
public class CommandManager implements ICommandManager, Completer, Highlighter {
@Getter
private final CommandDispatcher<CommandSender> dispatcher = new CommandDispatcher<>();
@Getter
private final ConcurrentHashMap<String, RawCommand> rawCommands = new ConcurrentHashMap<>();
private static final int[] COLORS = {AttributedStyle.CYAN, AttributedStyle.YELLOW, AttributedStyle.GREEN, AttributedStyle.MAGENTA, AttributedStyle.BLUE};
private final IBot bot;

View File

@ -11,8 +11,10 @@ import cn.wzpmc.api.events.notice.notify.NotifyEvent;
import cn.wzpmc.api.events.request.RequestEvent;
import cn.wzpmc.api.message.StringMessage;
import cn.wzpmc.api.message.json.JsonMessage;
import cn.wzpmc.api.user.Friend;
import cn.wzpmc.api.user.IBot;
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.ActionWriter;
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.JsonMessageWriter;
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.IUserReader;
import com.alibaba.fastjson2.JSON;
@ -59,6 +63,8 @@ public class JsonUtils {
JSON.register(ActionResponse.class, new ActionReader());
JSON.register(IUser.class, new IUserReader());
JSON.register(IBot.class, new IBotReader());
JSON.register(Friend.class, new FriendUserReader());
JSON.register(GroupUser.class, new GroupUserReader());
}
}

View File

@ -17,6 +17,7 @@ import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.List;
import java.util.Optional;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@ -69,9 +70,9 @@ public class ReflectionUtils {
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();
IncreasbleMap<Class<? extends Event>, EventHandlerMethod> result = new IncreasbleHashMap<>();
IncreasbleMap<Class<? extends Event>, EventHandlerMethod, List<EventHandlerMethod>> result = new IncreasbleHashMap<>();
for (Method declaredMethod : eventHandlerClass.getDeclaredMethods()) {
declaredMethod.setAccessible(true);
if (!declaredMethod.isAnnotationPresent(EventHandler.class)){

View File

@ -2,25 +2,16 @@ package cn.wzpmc.utils.json.message;
import cn.wzpmc.api.message.json.JsonMessage;
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 cn.wzpmc.api.utils.CqCodeUtils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.reader.ObjectReader;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Objects;
/**
* json消息解析器
@ -36,49 +27,9 @@ public class JsonMessageReader implements ObjectReader<JsonMessage> {
JSONArray objects = jsonReader.readJSONArray();
JsonMessage message = new JsonMessage();
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);
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)){
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);
messageParts.add(CqCodeUtils.parsePart(jsonObject));
}
return message;
}

View 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;
}
}

View 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;
}
}

View 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);
}
}