diff --git a/src/main/java/net/lamgc/cgj/bot/MessageEventExecutionDebugger.java b/src/main/java/net/lamgc/cgj/bot/MessageEventExecutionDebugger.java new file mode 100644 index 0000000..1ce2976 --- /dev/null +++ b/src/main/java/net/lamgc/cgj/bot/MessageEventExecutionDebugger.java @@ -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; + +/** + * 消息事件处理调试器. + *
当启用了消息事件处理调试后, 将会根据调试器代号调用指定调试器
+ */ +@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; + } + +} diff --git a/src/main/java/net/lamgc/cgj/bot/event/BotEventHandler.java b/src/main/java/net/lamgc/cgj/bot/event/BotEventHandler.java index d1ace35..4c551ee 100644 --- a/src/main/java/net/lamgc/cgj/bot/event/BotEventHandler.java +++ b/src/main/java/net/lamgc/cgj/bot/event/BotEventHandler.java @@ -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; @@ -129,8 +128,23 @@ public class BotEventHandler implements EventHandler { * 投递消息事件 * @param event 事件对象 */ + @NotAccepted public static void executeMessageEvent(MessageEvent event) { - BotEventHandler.executor.executor(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); + } } /** diff --git a/src/main/java/net/lamgc/cgj/bot/event/VirtualLoadMessageEvent.java b/src/main/java/net/lamgc/cgj/bot/event/VirtualLoadMessageEvent.java index 9523064..25afefd 100644 --- a/src/main/java/net/lamgc/cgj/bot/event/VirtualLoadMessageEvent.java +++ b/src/main/java/net/lamgc/cgj/bot/event/VirtualLoadMessageEvent.java @@ -5,6 +5,28 @@ package net.lamgc.cgj.bot.event; */ public class VirtualLoadMessageEvent extends MessageEvent { + /** + * 将任意消息事件转换为假负载消息事件. + *转换之后, 除了fromGroup, fromQQ, message外其他信息不会保留
+ * @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); }