Skip to content

Commit

Permalink
更新1.2.1版本
Browse files Browse the repository at this point in the history
  • Loading branch information
kosaka-bun committed Nov 2, 2022
1 parent b01b458 commit 04f2f68
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 29 deletions.
6 changes: 6 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# 更新日志

## 1.2.1
#### qqrobot-spring-boot-starter 1.2.1
- 增加`RobotConsole`以接管`System.out``System.err`,缓存这些输出流所输出的内容。
- 增强`RobotConsoleWindow`以支持`RobotConsole`
- 修改`AdminApiController`以支持`RobotConsoleWindow`

## 1.2.0
#### qqrobot-spring-boot-starter 1.2.0
- `TesterProperties``webPrefix`转为静态常量。
Expand Down
4 changes: 2 additions & 2 deletions qqrobot-spring-boot-starter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

setupVersion '1.2.0'
setupVersion '1.2.1'

ext {
miraiVersion = '2.8.2'
Expand All @@ -23,7 +23,7 @@ dependencies {
'spring-boot-configuration-processor'
implementation springConfigurationProcessor
annotationProcessor springConfigurationProcessor
implementation 'de.honoka.sdk:honoka-utils:1.0.4'
implementation 'de.honoka.sdk:honoka-utils:1.0.6'
implementation 'de.honoka.sdk:honoka-framework-utils:1.0.0'
implementation "net.mamoe:mirai-core-jvm:$miraiVersion"
implementation 'com.google.code.gson:gson'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package de.honoka.qqrobot.starter.component;

import de.honoka.sdk.util.system.ColorfulOutputStream;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;

import java.awt.*;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

public class RobotConsole {

private ColorfulOutputStream newOut, newErr;

private final StringBuilder lines = new StringBuilder();

@Getter
@Setter
private int maxLineCount = 200;

public RobotConsole() {
init();
}

private void init() {
changeSystemOut();
}

@SneakyThrows
private void changeSystemOut() {
newOut = new ColorfulOutputStream(System.out, Color.LIGHT_GRAY);
newErr = new ColorfulOutputStream(System.err, new Color(
255, 107, 103));
newOut.setPrintMethod(bytes -> write(bytes, newOut));
newErr.setPrintMethod(bytes -> write(bytes, newErr));
PrintStream newOutPrintStream = new PrintStream(newOut,
false, "UTF-8");
PrintStream newErrPrintStream = new PrintStream(newErr,
false, "UTF-8");
System.setOut(newOutPrintStream);
System.setErr(newErrPrintStream);
}

//两个输出流均使用此方法进行输出
private synchronized void write(byte[] bytes, ColorfulOutputStream out) {
String str = new String(bytes, StandardCharsets.UTF_8)
.replace("\r", "");
if(!str.contains("\n")) {
writeLine(str, out);
} else {
//如果不使用split的重载方法,当分隔符位于末尾时,末尾的空串将丢失!
String[] lines = str.split("\n", -1);
for(int i = 0; i < lines.length; i++) {
//不是最后一行
if(i < lines.length - 1) {
writeLine(lines[i] + "\n", out);
this.lines.append("\n");
} else {
writeLine(lines[i], out);
}
}
}
//检查保存的控制台输出是否超过最大行数
int lineCount = StringUtils.countMatches(lines, "\n") + 1;
if(lineCount > maxLineCount) {
int newStartIndex = StringUtils.ordinalIndexOf(lines, "\n",
lineCount - maxLineCount) + 1;
lines.delete(0, newStartIndex);
}
}

private void writeLine(String line, ColorfulOutputStream out) {
//按颜色输出
String[] parts = line.split("\\u001B");
for(int i = 0; i < parts.length; i++) {
if(i == 0) {
//第一部分直接按原色输出
writeColorfulText(parts[i], out.getPrintColor());
} else {
//其他部分先进行处理,改变输出流颜色,并去除控制序列,再输出
String part = out.changePrintColorByAnsiString(parts[i]);
writeColorfulText(part, out.getPrintColor());
}
}
}

private void writeColorfulText(String str, Color color) {
if(StringUtils.isEmpty(str)) return;
String template = "<pre style=\"color: %s;\">%s</pre>";
String colorStr = String.format("#%02X%02X%02X", color.getRed(),
color.getGreen(), color.getBlue());
str = str.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\n", "<br>");
lines.append(String.format(template, colorStr, str));
}

public synchronized String getText() {
return lines.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import de.honoka.qqrobot.framework.Framework;
import de.honoka.qqrobot.starter.RobotBasicProperties;
import de.honoka.sdk.util.code.ThrowsRunnable;
import de.honoka.sdk.util.system.gui.ConsoleWindow;
import de.honoka.sdk.util.text.TextUtils;
import lombok.AccessLevel;
Expand All @@ -20,9 +21,13 @@
@Accessors(chain = true)
public class RobotConsoleWindow {

@Getter
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private static ConsoleWindow console;
private static ConsoleWindow consoleWindow;

@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private static RobotConsole console;

private String name;

Expand All @@ -36,47 +41,82 @@ public class RobotConsoleWindow {

private Consumer<ApplicationContext> onExit = context -> {};

private ThrowsRunnable beforeRunApplication = () -> {};

private boolean showOnCreate = true;

@Setter(AccessLevel.NONE)
private ApplicationContext context;

public RobotConsoleWindow(String name, Class<?> springBootMainClass) {
this.name = name;
this.springBootMainClass = springBootMainClass;
/**
* 强制不使用GUI窗口
*/
private boolean forceNoGui = false;

private RobotConsoleWindow() {}

public static RobotConsoleWindow of(String name, Class<?> springBootMainClass) {
RobotConsoleWindow window = new RobotConsoleWindow();
window.name = name;
window.springBootMainClass = springBootMainClass;
return window;
}

public static RobotConsoleWindow of(String name, double screenZoomScale,
Class<?> springBootMainClass) {
RobotConsoleWindow window = new RobotConsoleWindow();
window.name = name;
window.screenZoomScale = screenZoomScale;
window.springBootMainClass = springBootMainClass;
return window;
}

public RobotConsoleWindow(String name, double screenZoomScale,
Class<?> springBootMainClass) {
this.name = name;
this.screenZoomScale = screenZoomScale;
this.springBootMainClass = springBootMainClass;
private void startApplication() {
beforeRunApplication.run();
SpringApplication app = new SpringApplication(springBootMainClass);
context = app.run(applicationArgs);
}

public void create() {
if(forceNoGui) {
console = new RobotConsole();
startApplication();
return;
}
//创建并显示窗口
console = new ConsoleWindow(name, iconPath, () -> {
onExit.accept(context);
});
console.setAutoScroll(true);
console.setScreenZoomScale(screenZoomScale);
if(showOnCreate) {
console.show();
try {
consoleWindow = ConsoleWindow.Builder.of(name).setOnExit(() -> {
onExit.accept(context);
}).setScreenZoomScale(screenZoomScale).build();
consoleWindow.setAutoScroll(true);
} catch(Throwable t) {
//若不能加载窗口,则直接以控制台方式运行
console = new RobotConsole();
startApplication();
return;
}
//启动应用
SpringApplication app = new SpringApplication(springBootMainClass);
context = app.run(applicationArgs);
startApplication();
//添加托盘图标菜单项
Framework<?> framework = context.getBean(Framework.class);
RobotBasicProperties basicProperties = context.getBean(
RobotBasicProperties.class);
console.addTrayIconMenuItem("重新登录", true,
consoleWindow.addTrayIconMenuItem("重新登录", true,
framework::reboot);
console.addTrayIconMenuItem("发送测试消息",
consoleWindow.addTrayIconMenuItem("发送测试消息",
false, () -> {
String time = TextUtils.getSimpleDateFormat().format(new Date());
framework.sendGroupMsg(basicProperties.getDevelopingGroup(),
time + "\n测试消息");
});
}

public static String getConsoleText() {
if(consoleWindow != null) {
return consoleWindow.getText();
} else if(console != null) {
return console.getText();
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import de.honoka.sdk.util.code.ActionUtils;
import de.honoka.sdk.util.framework.web.ApiResponse;
import de.honoka.sdk.util.system.SystemInfoBean;
import de.honoka.sdk.util.system.gui.ConsoleWindow;
import de.honoka.sdk.util.text.TextUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.annotation.Lazy;
Expand Down Expand Up @@ -152,11 +151,8 @@ public String getUsageLog(

@RequestMapping("/console")
public String getConsole() {
ConsoleWindow window = RobotConsoleWindow.getConsole();
String content;
if(window != null) {
content = window.getText();
} else {
String content = RobotConsoleWindow.getConsoleText();
if(content == null) {
content = "<div style=\"color: white;\">" +
"应用未开启控制台窗口" +
"</div>";
Expand Down

0 comments on commit 04f2f68

Please sign in to comment.