Compare commits

...

6 Commits

Author SHA1 Message Date
c8fe2c3fdd [Version] 更新版本(2.5.0-20200504.2-SNAPSHOT -> 2.5.0-20200505.1-SNAPSHOT);
[Update] net.lamgc:java-utils 更新依赖版本(1.1.0 -> 1.2.0_20200505.1-SNAPSHOT);
2020-05-05 01:29:11 +08:00
49a33d4078 [Add] MessageEventExecutionDebugger 添加对消息处理的调试器Enum;
[Add] BotEventHandler 添加对 MessageEventExecutionDebugger 的支持;
[Add] VirtualLoadMessageEvent 增加 toVirtualLoadMessageEvent(MessageEvent) 方法;
2020-05-05 01:27:10 +08:00
cd1d2316ee [Add] BotEventHandler 添加executeMessageEvent(MessageEvent)方法;
[Change] BotEventHandler 将BotEventHandler.executor设为private;
[Change] MiraiMain, CQPluginMain, RankingUpdateTimer 适配BotEventHandler的调整
2020-05-04 23:06:07 +08:00
cf08353ed9 [Change] BotEventHandler 调整事件处理线程池的线程数(min: 4, Max: 32); 2020-05-04 22:52:47 +08:00
bef6a684b9 [Change] BotEventHandler 调整事件处理线程池的线程数; 2020-05-04 22:46:06 +08:00
04960889b4 [Version] 更新版本(2.5.0-20200504.01-SNAPSHOT -> 2.5.0-20200504.2-SNAPSHOT);
[Update] net.lamgc:java-utils 更新依赖版本(1.1.0_5-SNAPSHOT -> 1.1.0);
[Update] net.lamgc:PixivLoginProxyServer 更新依赖版本(1.1.0 -> 1.1.1);
2020-05-04 19:44:11 +08:00
7 changed files with 136 additions and 14 deletions

View File

@ -6,7 +6,7 @@
<groupId>net.lamgc</groupId>
<artifactId>ContentGrabbingJi</artifactId>
<version>2.5.0-20200504.01-SNAPSHOT</version>
<version>2.5.0-20200505.1-SNAPSHOT</version>
<repositories>
<repository>
@ -86,7 +86,7 @@
<dependency>
<groupId>net.lamgc</groupId>
<artifactId>java-utils</artifactId>
<version>1.1.0_5-SNAPSHOT</version>
<version>1.2.0_20200505.1-SNAPSHOT</version>
</dependency>
<dependency>
@ -172,7 +172,7 @@
<dependency>
<groupId>net.lamgc</groupId>
<artifactId>PixivLoginProxyServer</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.squareup</groupId>

View File

@ -0,0 +1,79 @@
package net.lamgc.cgj.bot;
import net.lamgc.cgj.bot.event.MessageEvent;
import net.lamgc.cgj.bot.event.VirtualLoadMessageEvent;
import net.lamgc.utils.event.EventExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
/**
* 消息事件处理调试器.
* <p>当启用了消息事件处理调试后, 将会根据调试器代号调用指定调试器</p>
*/
@SuppressWarnings("unused")
public enum MessageEventExecutionDebugger {
/**
* PM - 压力测试
*/
PM ((executor, event, properties, log) -> {
MessageEvent virtualLoadEvent = VirtualLoadMessageEvent.toVirtualLoadMessageEvent(event, false);
int rotation = 5;
int number = 50;
int interval = 2500;
try {
rotation = Integer.parseInt(properties.getProperty("debug.pm.rotation", "5"));
} catch(NumberFormatException ignored) {}
try {
number = Integer.parseInt(properties.getProperty("debug.pm.number", "50"));
} catch(NumberFormatException ignored) {}
try {
interval = Integer.parseInt(properties.getProperty("debug.pm.interval", "2500"));
} catch(NumberFormatException ignored) {}
boolean interrupted = false;
Thread currentThread = Thread.currentThread();
for(int rotationCount = 0; rotationCount < rotation && !interrupted; rotationCount++) {
for(int sendCount = 0; sendCount < number; sendCount++) {
if(currentThread.isInterrupted()) {
interrupted = true;
break;
}
executor.executor(virtualLoadEvent);
}
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
break;
}
}
});
public final static String debuggerLoggerNameTemp = "MessageEventExecuteDebugger-{debugger}";
public final MessageExecuteDebugger debugger;
MessageEventExecutionDebugger(MessageExecuteDebugger debugger) {
this.debugger = debugger;
}
public static Logger getDebuggerLogger(MessageEventExecutionDebugger debugger) {
return LoggerFactory.getLogger(debuggerLoggerNameTemp.replace("{debugger}", debugger.name()));
}
@FunctionalInterface
public interface MessageExecuteDebugger {
/**
* 接收事件并根据指定需求处理
* @param executor 事件执行器
* @param event 消息事件对象
* @param properties 配置项, 调试器应按'debug.[debuggerName].'为前缀存储相应调试信息
* @throws Exception 当抛出异常则打断调试, 并输出至日志
*/
void accept(EventExecutor executor, MessageEvent event, Properties properties, Logger logger) throws Exception;
}
}

View File

@ -65,8 +65,7 @@ public class RankingUpdateTimer {
log.debug("不支持的类型, 填空值跳过...(类型: {}.{})", rankingMode.name(), contentType.name());
}
log.info("当前排行榜类型: {}.{}, 正在更新...", rankingMode.name(), contentType.name());
BotEventHandler.executor.executor(
new VirtualLoadMessageEvent(0,0,
BotEventHandler.executeMessageEvent(new VirtualLoadMessageEvent(0,0,
".cgj ranking -type=" + contentType.name() + " -mode=" + rankingMode.name()));
log.info("排行榜 {}.{} 负载指令已投递.", rankingMode.name(), contentType.name());
}

View File

@ -5,6 +5,7 @@ import com.google.common.base.Throwables;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import net.lamgc.cgj.bot.BotAdminCommandProcess;
import net.lamgc.cgj.bot.BotCommandProcess;
import net.lamgc.cgj.bot.MessageEventExecutionDebugger;
import net.lamgc.cgj.util.DateParser;
import net.lamgc.cgj.util.PagesQualityParser;
import net.lamgc.cgj.util.TimeLimitThreadPoolExecutor;
@ -13,10 +14,8 @@ import net.lamgc.utils.base.runner.ArgumentsRunnerConfig;
import net.lamgc.utils.base.runner.exception.DeveloperRunnerException;
import net.lamgc.utils.base.runner.exception.NoSuchCommandException;
import net.lamgc.utils.base.runner.exception.ParameterNoFoundException;
import net.lamgc.utils.event.EventExecutor;
import net.lamgc.utils.event.EventHandler;
import net.lamgc.utils.event.*;
import net.lamgc.utils.event.EventObject;
import net.lamgc.utils.event.EventUncaughtExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;
@ -50,10 +49,10 @@ public class BotEventHandler implements EventHandler {
/**
* 消息事件执行器
*/
public final static EventExecutor executor = new EventExecutor(new TimeLimitThreadPoolExecutor(
private final static EventExecutor executor = new EventExecutor(new TimeLimitThreadPoolExecutor(
60 * 1000,
(int) Math.ceil(Runtime.getRuntime().availableProcessors() / 2F),
Runtime.getRuntime().availableProcessors(),
Math.max(Runtime.getRuntime().availableProcessors(), 4),
Math.max(Math.max(Runtime.getRuntime().availableProcessors() * 2, 4), 32),
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1536),
@ -125,6 +124,29 @@ public class BotEventHandler implements EventHandler {
BotCommandProcess.initialize();
}
/**
* 投递消息事件
* @param event 事件对象
*/
@NotAccepted
public static void executeMessageEvent(MessageEvent event) {
String debuggerName;
if(!event.getMessage().startsWith(ADMIN_COMMAND_PREFIX) &&
!Strings.isNullOrEmpty(debuggerName = BotCommandProcess.globalProp.getProperty("debug.debugger"))) {
try {
MessageEventExecutionDebugger debugger = MessageEventExecutionDebugger.valueOf(debuggerName.toUpperCase());
debugger.debugger.accept(executor, event, BotCommandProcess.globalProp,
MessageEventExecutionDebugger.getDebuggerLogger(debugger));
} catch(IllegalArgumentException e) {
log.warn("未找到指定调试器: '{}'", debuggerName);
} catch (Exception e) {
log.error("事件调试处理时发生异常", e);
}
} else {
BotEventHandler.executor.executor(event);
}
}
/**
* 以事件形式处理消息事件
* @param event 消息事件对象

View File

@ -5,6 +5,28 @@ package net.lamgc.cgj.bot.event;
*/
public class VirtualLoadMessageEvent extends MessageEvent {
/**
* 将任意消息事件转换为假负载消息事件.
* <p>转换之后, 除了fromGroup, fromQQ, message外其他信息不会保留</p>
* @param event 待转换的消息事件
* @param inheritImpl 是否继承除 sendMessage 外的其他 MessageEvent 实现
* @return 转换后的消息事件
*/
public static VirtualLoadMessageEvent toVirtualLoadMessageEvent(MessageEvent event, boolean inheritImpl) {
if(event instanceof VirtualLoadMessageEvent) {
return (VirtualLoadMessageEvent) event;
} else if(!inheritImpl) {
return new VirtualLoadMessageEvent(event.getFromGroup(), event.getFromQQ(), event.getMessage());
} else {
return new VirtualLoadMessageEvent(event.getFromGroup(), event.getFromQQ(), event.getMessage()) {
@Override
public String getImageUrl(String image) {
return event.getImageUrl(image);
}
};
}
}
public VirtualLoadMessageEvent(long fromGroup, long fromQQ, String message) {
super(fromGroup, fromQQ, message);
}

View File

@ -41,7 +41,7 @@ public class CQPluginMain extends CQPlugin implements EventHandler {
if(!BotEventHandler.match(event.getMessage())) {
return MESSAGE_IGNORE;
}
BotEventHandler.executor.executor(new SpringCQMessageEvent(cq, event));
BotEventHandler.executeMessageEvent(new SpringCQMessageEvent(cq, event));
return MESSAGE_BLOCK;
}

View File

@ -43,8 +43,8 @@ public class MiraiMain implements Closeable {
}
bot = BotFactoryJvm.newBot(Long.parseLong(botProperties.getProperty("bot.qq", "0")), Base64.decodeBase64(botProperties.getProperty("bot.password", "")), new BotConfiguration());
Events.subscribeAlways(GroupMessage.class, (msg) -> BotEventHandler.executor.executor(new MiraiMessageEvent(msg)));
Events.subscribeAlways(FriendMessage.class, (msg) -> BotEventHandler.executor.executor(new MiraiMessageEvent(msg)));
Events.subscribeAlways(GroupMessage.class, (msg) -> BotEventHandler.executeMessageEvent(new MiraiMessageEvent(msg)));
Events.subscribeAlways(FriendMessage.class, (msg) -> BotEventHandler.executeMessageEvent(new MiraiMessageEvent(msg)));
bot.login();
MessageSenderBuilder.setCurrentMessageSenderFactory(new MiraiMessageSenderFactory(bot));
BotEventHandler.preLoad();