Skip to content

Commit

Permalink
refactor: 优化
Browse files Browse the repository at this point in the history
  • Loading branch information
cnlimiter committed Jan 18, 2024
1 parent 756545d commit 5ebbaa4
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 43 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -33,7 +33,7 @@ dependencies {
implementation("cn.evole.bot:OneBot-SDK:0.2.7")
"shadowLink"("cn.evole.bot:OneBot-SDK")
implementation("io.github.pcmind:leveldb:1.2")
"shadowLink"("io.github.pcmind:leveldb")
"shadowLink"("io.github.pcmind:leveldb"){transitive = false}
implementation("com.google.code.gson:gson:2.10.1")


Expand Down
102 changes: 87 additions & 15 deletions src/main/java/cn/evole/onebot/mirai/OneBotMirai.java
Expand Up @@ -4,14 +4,22 @@
import cn.evole.onebot.mirai.core.SessionManager;
import cn.evole.onebot.mirai.util.BaseUtils;
import cn.evole.onebot.mirai.util.DBUtils;
import cn.evole.onebot.mirai.util.HttpUtils;
import cn.evole.onebot.sdk.util.FileUtils;
import cn.evole.onebot.sdk.util.NetUtils;
import lombok.val;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.Mirai;
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
import net.mamoe.mirai.contact.Friend;
import net.mamoe.mirai.contact.Group;
import net.mamoe.mirai.contact.Member;
import net.mamoe.mirai.event.Event;
import net.mamoe.mirai.event.GlobalEventChannel;
import net.mamoe.mirai.event.Listener;
import net.mamoe.mirai.event.events.*;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.message.data.OnlineAudio;
import net.mamoe.mirai.utils.MiraiLogger;
import org.iq80.leveldb.DB;
import org.iq80.leveldb.Options;
Expand All @@ -24,6 +32,9 @@
import java.util.List;
import java.util.Objects;

import static cn.evole.onebot.mirai.util.ImgUtils.constructCacheImageMeta;
import static cn.evole.onebot.mirai.util.ImgUtils.getImageType;

public final class OneBotMirai extends JavaPlugin {
public static String VERSION;
public static final OneBotMirai INSTANCE = new OneBotMirai();
Expand All @@ -36,8 +47,8 @@ private OneBotMirai() {
VERSION = getDescription().getVersion().toString();
}

private File imageFolder = new File(getDataFolder(), "image");
private File recordFolder = new File(getDataFolder(), "record");
private final File imageFolder = new File(getDataFolder(), "image");
private final File recordFolder = new File(getDataFolder(), "record");
public DB db = null;

@Override
Expand Down Expand Up @@ -65,9 +76,9 @@ public void onEnable() {
instances.forEach(bot -> {
logger.info(String.format("bot : %d", bot.getId()));
if (!SessionManager.getSessions().containsKey(bot.getId())) {
var botId = String.valueOf(bot.getId());
val botId = String.valueOf(bot.getId());
if (Objects.requireNonNull(PluginConfig.INSTANCE.getBots()).containsKey(botId)){
var mapConfig = PluginConfig.INSTANCE.getBots().get(botId);
val mapConfig = PluginConfig.INSTANCE.getBots().get(botId);
SessionManager.createBotSession(bot, mapConfig);
logger.info(String.format("创建配置: %d", bot.getId()));
}
Expand All @@ -86,47 +97,98 @@ public void onEnable() {
}
if (event instanceof BotOnlineEvent onlineEvent){
if (!SessionManager.containsSession(onlineEvent.getBot().getId())){
var botId = String.valueOf(onlineEvent.getBot().getId());
val botId = String.valueOf(onlineEvent.getBot().getId());
if (Objects.requireNonNull(PluginConfig.INSTANCE.getBots()).containsKey(String.valueOf(event.getBot().getId()))){
var mapConfig = PluginConfig.INSTANCE.getBots().get(botId);
SessionManager.createBotSession(onlineEvent.getBot(), mapConfig);
logger.warning(String.format("%s 创建OneBot Session", event.getBot().getId()));

val mapConfig = PluginConfig.INSTANCE.getBots().get(botId);
val session = SessionManager.createBotSession(onlineEvent.getBot(), mapConfig);
logger.info(String.format("机器人 %s 创建 OneBot Session", event.getBot().getId()));
}
else {
logger.warning(String.format("%s 未进行OneBot配置,请在setting.yml中进行配置", event.getBot().getId()));
logger.warning(String.format("机器人 %s 未进行OneBot配置,请在setting.yml中进行配置", event.getBot().getId()));
}
}

}
else if (event instanceof MessageEvent messageEvent){
if (SessionManager.containsSession(messageEvent.getBot().getId())) {
val bot = messageEvent.getBot();
val botId = bot.getId();
if (SessionManager.containsSession(botId)) {
DBUtils.saveMessageToDB(messageEvent);//存入数据库
var session = SessionManager.get(messageEvent.getBot().getId());
val session = SessionManager.get(botId);
if (messageEvent instanceof GroupMessageEvent groupMessageEvent){
session.getApiImpl().getCachedSourceQueue().add(groupMessageEvent.getSource());
}
else if (messageEvent instanceof GroupTempMessageEvent groupTempMessageEvent){
session.getApiImpl().getCachedTempContact()
.put(groupTempMessageEvent.getSender().getId(), groupTempMessageEvent.getGroup().getId());
}
if (session.getBotConfig().getCacheImage()){
messageEvent.getMessage().stream()
.filter(singleMessage -> singleMessage instanceof Image)
.forEach(singleMessage -> {
val img = (Image) singleMessage;
long imageSize;
val imageMD5 = BaseUtils.bytesToHexString(img.getMd5());
val subject = messageEvent.getSubject();
if (subject instanceof Member || subject instanceof Friend){
val imageHeight = img.getHeight();
val imageWidth = img.getWidth();
imageSize = (long) imageHeight * imageWidth;
}
else if (subject instanceof Group){
imageSize = img.getSize();
}
else imageSize = 0;

val imgMetaContent = constructCacheImageMeta(
imageMD5,
imageSize,
Mirai.getInstance().queryImageUrl(bot, img),
getImageType(img)
);
saveImageOrRecord(
img.getImageId() + ".cqimg",
imgMetaContent,
true
);

});
}
if (session.getBotConfig().getCacheRecord()){
messageEvent.getMessage().stream()
.filter(singleMessage -> singleMessage instanceof OnlineAudio)
.forEach(singleMessage -> {
val audio = (OnlineAudio) singleMessage;
val voiceUrl = audio.getUrlForDownload();
val voiceBytes = HttpUtils.getBytesFromHttpUrl(voiceUrl);
if (voiceBytes != null) {
saveImageOrRecord(
BaseUtils.bytesToHexString(audio.getFileMd5()) + ".cqrecord",
voiceBytes,
false
);
}
});
}


}
}
else if (event instanceof NewFriendRequestEvent requestEvent) {
if (SessionManager.containsSession(requestEvent.getBot().getId())) {
var session = SessionManager.get(requestEvent.getBot().getId());
val session = SessionManager.get(requestEvent.getBot().getId());
session.getApiImpl().getCacheRequestQueue().add(requestEvent);
}
}
else if (event instanceof MemberJoinRequestEvent requestEvent) {
if (SessionManager.containsSession(requestEvent.getBot().getId())) {
var session = SessionManager.get(requestEvent.getBot().getId());
val session = SessionManager.get(requestEvent.getBot().getId());
session.getApiImpl().getCacheRequestQueue().add(requestEvent);
}
}
else if (event instanceof BotInvitedJoinGroupRequestEvent requestEvent) {
if (SessionManager.containsSession(requestEvent.getBot().getId())) {
var session = SessionManager.get(requestEvent.getBot().getId());
val session = SessionManager.get(requestEvent.getBot().getId());
session.getApiImpl().getCacheRequestQueue().add(requestEvent);
}
}
Expand All @@ -149,6 +211,16 @@ private File record(String recordName){
return new File(this.recordFolder, recordName);
}

public void saveImageOrRecord(String name, String data, boolean img){
BaseUtils.safeRun(() -> {
if(data != null) {
try {
Files.writeString(img ? image(name).toPath() : record(name).toPath(), data, StandardOpenOption.WRITE);
} catch (IOException ignored) {}
}
});
}

public void saveImageOrRecord(String name, byte[] data, boolean img){
BaseUtils.safeRun(() -> {
if(data != null) {
Expand Down
41 changes: 30 additions & 11 deletions src/main/java/cn/evole/onebot/mirai/core/session/BotSession.java
Expand Up @@ -34,6 +34,18 @@ public class BotSession {
private final List<OneBotWSClient> websocketClient = new ArrayList<>();
private final MiraiLogger miraiLogger = MiraiLogger.Factory.INSTANCE.create(BotSession.class);


@Override
public String toString() {
return """
Bot Id: %s,
Bot Config: %s,
OneBot Clients: %s,
OneBot Server: %s
""".formatted(bot.getBot().getId(), botConfig.toString(), websocketClient.size(), websocketServer.getAddress())
;
}

public BotSession(Bot bot, BotConfig botConfig){
this.bot = bot;
this.apiImpl = new ApiMap(bot);
Expand Down Expand Up @@ -68,21 +80,28 @@ public void triggerEvent(BotEvent event){
var e = EventMap.toDTO(event);
var json = GsonUtils.getGson().toJson(e);
if (!(e instanceof IgnoreEvent)) {
var debug = PluginConfig.INSTANCE.getDebug();
if (this.botConfig.getWs().getEnable()){
OneBotMirai.logger.info("将广播正向websocket事件");
if (debug) OneBotMirai.logger.info("将广播正向websocket事件");
websocketServer.broadcast(json);
}
long sendCount = websocketClient.stream().filter(client -> {
try{
if (client.isOpen()) {
client.send(json);
}
}catch (Exception ex){
OneBotMirai.logger.warning("error sending msg", ex);

for(PluginConfig.WSReverseConfig ws_re : botConfig.getWsReverse()){
if (ws_re.getEnable()){
long sendCount = websocketClient.stream().filter(client -> {
try{
if (client.isOpen()) {
client.send(json);
}
}catch (Exception ex){
OneBotMirai.logger.warning("error sending msg", ex);
}
return client.isOpen();
}).count();
if (debug) OneBotMirai.logger.info(String.format("将广播反向websocket事件, 共计发送 :%d", sendCount));
}
return client.isOpen();
}).count();
OneBotMirai.logger.info(String.format("广播反向websocket事件, 共计发送 :%d", sendCount));
}

}
}

Expand Down
7 changes: 5 additions & 2 deletions src/main/java/cn/evole/onebot/mirai/util/ActionUtils.java
@@ -1,6 +1,7 @@
package cn.evole.onebot.mirai.util;

import cn.evole.onebot.mirai.OneBotMirai;
import cn.evole.onebot.mirai.config.PluginConfig;
import cn.evole.onebot.mirai.core.ApiMap;
import com.google.gson.JsonObject;
import org.java_websocket.WebSocket;
Expand All @@ -15,16 +16,18 @@
public class ActionUtils {
public static void handleWebSocketActions(WebSocket session, ApiMap api, JsonObject json){
try {
OneBotMirai.logger.info(String.format("WebSocket收到操作请求: %s", GsonUtils.getGson().toJson(json)));
var debug = PluginConfig.INSTANCE.getDebug();
if (debug) OneBotMirai.logger.info(String.format("WebSocket收到操作请求: %s", GsonUtils.getGson().toJson(json)));

var echo = json.get("echo").getAsString();
var action = json.get("action").getAsString();

var responseDTO = api.callMiraiApi(action, json.get("params").getAsJsonObject());

responseDTO.setEcho(echo);
var jsonToSend = GsonUtils.getGson().toJson(responseDTO);
OneBotMirai.logger.info(String.format("WebSocket将返回结果: %s" ,jsonToSend));
session.send(jsonToSend);
if (debug) OneBotMirai.logger.info(String.format("WebSocket将返回结果: %s" ,jsonToSend));
} catch (Exception e) {
OneBotMirai.logger.error(e.getMessage());
}
Expand Down
25 changes: 17 additions & 8 deletions src/main/java/cn/evole/onebot/mirai/util/BaseUtils.java
Expand Up @@ -71,26 +71,33 @@ else if (new File(systemDataFolder + name).getAbsoluteFile().exists()){
}
}

public static String byteToHex(byte[] bytes){
String strHex = "";
StringBuilder sb = new StringBuilder();
for (int n = bytes.length-1; n >=0; n--) {
strHex = Integer.toHexString(bytes[n] & 0xFF);
sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示,位数不够,高位补0
/**
* 更加高效
* @param bytes 数据
* @return 字符
*/
public static String bytesToHexString(byte[] bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();//通过对一个只读数组hexArray进行读取来实现
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return sb.toString().trim();
return new String(hexChars);
}

public static String bytesToString(byte[] str) {
String keyword = null;
try {
keyword = new String(str,"GBK");
keyword = new String(str, "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return keyword;
}


public static int byteToInt(byte[] b) {
int s = 0;
int s0 = b[0] & 0xff;// 最低位
Expand All @@ -103,4 +110,6 @@ public static int byteToInt(byte[] b) {
s = s0 | s1 | s2 | s3;
return s;
}


}
20 changes: 17 additions & 3 deletions src/main/java/cn/evole/onebot/mirai/util/ImgUtils.java
@@ -1,6 +1,7 @@
package cn.evole.onebot.mirai.util;

import lombok.val;
import net.mamoe.mirai.message.data.Image;
import org.jetbrains.annotations.Nullable;

import java.io.File;
Expand All @@ -19,7 +20,7 @@

public class ImgUtils {

public static String constructCacheImageMeta(String md5, int size, String url, String imageType){
public static String constructCacheImageMeta(String md5, long size, String url, String imageType){
return """
[image]
md5=%s
Expand All @@ -30,6 +31,17 @@ public static String constructCacheImageMeta(String md5, int size, String url, S
""".formatted(md5, size, url, System.currentTimeMillis(), imageType);
}


public static String getImageType(Image image){
val parts = image.getImageId().split("\\.", 2);
if (parts.length == 2){
return parts[1];
}
else {
return "unknown";
}
}

public static String getImageType(byte[] bytes){
byte[] b1 = new byte[8];
System.arraycopy(bytes, 0, b1, 0, 8);
Expand Down Expand Up @@ -119,10 +131,12 @@ else if (name.endsWith(".image")){
val bytes = Files.readAllBytes(cacheFile.toPath());
byte[] b1 = new byte[16];
System.arraycopy(bytes, 0, b1, 0, 16);
md5[0] = BaseUtils.bytesToString(b1);
byte[] b2 = new byte[16];
md5[0] = BaseUtils.bytesToHexString(b1);

byte[] b2 = new byte[4];
System.arraycopy(bytes, 16, b2, 0, 4);
size[0] = BaseUtils.byteToInt(b2);

url[0] = "https://c2cpicdw.qpic.cn/offpic_new//0/0-00-$md5/0?term=2";
}
catch (IOException ignored){}
Expand Down
5 changes: 3 additions & 2 deletions src/main/kotlin/cn/evole/onebot/mirai/config/PluginConfig.kt
Expand Up @@ -8,11 +8,12 @@ import net.mamoe.mirai.console.data.value
object PluginConfig : AutoSavePluginConfig("setting"){
val bots: MutableMap<String, BotConfig>? by value(mutableMapOf("12345654321" to BotConfig()))
val db by value(DBSettings())
val debug : Boolean = false

@Serializable
data class BotConfig(
var cacheImage: Boolean = false,
var cacheRecord: Boolean = false,
var cacheImage: Boolean = true,
var cacheRecord: Boolean = true,
var heartbeat: HeartbeatConfig = HeartbeatConfig(),
var http: HTTPConfig = HTTPConfig(),
@SerialName("ws_reverse")
Expand Down

0 comments on commit 5ebbaa4

Please sign in to comment.