diff --git a/README.md b/README.md
index fd670f5..3a9066c 100644
--- a/README.md
+++ b/README.md
@@ -27,12 +27,12 @@ src/main/java/top/gtb520/java/gnu/java/utils/library/
支持 **Tar.Gz** 和 **Zip** 两种压缩格式的压缩与解压操作,支持单文件和整个目录的递归处理。
-| 方法 | 说明 | 参数 |
-|------|------|------|
-| `compress.MakeTarGz(source, dest)` | 将文件或目录压缩为 `.tar.gz` | `source` 源路径,`dest` 压缩包输出路径 |
-| `compress.UnTarGz(source, dest)` | 解压 `.tar.gz` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
-| `compress.MakeZip(source, dest)` | 将文件或目录压缩为 `.zip` | `source` 源路径,`dest` 压缩包输出路径 |
-| `compress.UnZip(source, dest)` | 解压 `.zip` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
+| 方法 | 说明 | 参数 |
+|------------------------------------|---------------------|------------------------------|
+| `compress.MakeTarGz(source, dest)` | 将文件或目录压缩为 `.tar.gz` | `source` 源路径,`dest` 压缩包输出路径 |
+| `compress.UnTarGz(source, dest)` | 解压 `.tar.gz` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
+| `compress.MakeZip(source, dest)` | 将文件或目录压缩为 `.zip` | `source` 源路径,`dest` 压缩包输出路径 |
+| `compress.UnZip(source, dest)` | 解压 `.zip` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
**使用示例:**
@@ -65,21 +65,21 @@ main.compress.TarGz(source, dest);
基于 ANSI 转义序列,在终端中输出彩色文本。
-| 方法 | 说明 | 参数 |
-|------|------|------|
-| `echo.ColorPrintln(message, color)` | 使用预定义颜色打印 | `message` 文本内容,`color` 颜色枚举 |
+| 方法 | 说明 | 参数 |
+|-------------------------------------------|------------------|-------------------------------------|
+| `echo.ColorPrintln(message, color)` | 使用预定义颜色打印 | `message` 文本内容,`color` 颜色枚举 |
| `echo.ColorHexPrintln(message, hexColor)` | 使用自定义 ANSI 颜色码打印 | `message` 文本内容,`hexColor` ANSI 颜色代码 |
**支持的颜色枚举 (`ColorNameEnum`):**
-| 枚举值 | 颜色 |
-|--------|------|
-| `RED` | 红色 |
-| `GREEN` | 绿色 |
+| 枚举值 | 颜色 |
+|----------|----|
+| `RED` | 红色 |
+| `GREEN` | 绿色 |
| `YELLOW` | 黄色 |
-| `BLUE` | 蓝色 |
+| `BLUE` | 蓝色 |
| `PURPLE` | 紫色 |
-| `CYAN` | 青色 |
+| `CYAN` | 青色 |
**使用示例:**
@@ -109,10 +109,10 @@ main.echo.ColorHexPrintln("自定义颜色", "31");
随机生成器,提供生成随机字符串、数字、UUID 等功能。
-| 方法 | 说明 | 参数 |
-|------|------|---------------------------------|
+| 方法 | 说明 | 参数 |
+|-------------------------------------------------------------|--------------|-----------------------------------|
| `processing.random.defaults.random(start_scope, end_scope)` | 根据输入的范围生成随机数 | `start_scope` 起始数,`end_scope` 结束数 |
-| `processing.random.defaults.randomString(int length)` | 生成指定长度的随机字符串 | `length` 字符串长度 |
+| `processing.random.defaults.randomString(int length)` | 生成指定长度的随机字符串 | `length` 字符串长度 |
**使用示例:**
@@ -127,9 +127,9 @@ defaults.randomString(10);
HWID生成器,提供生成硬件ID的功能。
-| 方法 | 说明 | 参数 |
-|---------------------------------------------------------------------------------------|--------|---|
-| `processing.hwid.getHWID.generateHWID()` | 生成HWID | 无 |
+| 方法 | 说明 | 参数 |
+|------------------------------------------|--------|----|
+| `processing.hwid.getHWID.generateHWID()` | 生成HWID | 无 |
**使用示例:**
@@ -142,6 +142,26 @@ System.out.println("HWID: " + Hwid_Str);
System.out.println("HWID length: " + Hwid_Str.length());
```
+### 5. 终端颜色打印Plus(ColorPrintlnPlus)
+
+在单行内打印多种颜色的文字,包含Minecraft格式代码的文本
+
+| 方法 | 说明 | 参数 |
+|------------------------------------|----------------------|-----------------------------|
+| `ColorPrintlnPlus(String Message)` | 仿照Minecraft类型的文本终端打印 | `message` 待打印的文本,包含颜色与功能控制符 |
+
+**使用示例:**
+
+```java
+import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
+
+public class Main {
+ public static void main() {
+ echo.ColorPrintlnPlus("&dHello &2World&6!");
+ }
+}
+```
+
## 构建
```bash
diff --git a/pom.xml b/pom.xml
index f494fa4..f775f0b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
top.gtb520.java.gnu
gnu_java_utils_library
- 1.1-SNAPSHOT
+ 1.2-SNAPSHOT
25
diff --git a/src/main/java/top/gtb520/java/gnu/java/utils/library/main.java b/src/main/java/top/gtb520/java/gnu/java/utils/library/main.java
index 47f1882..d2a484d 100644
--- a/src/main/java/top/gtb520/java/gnu/java/utils/library/main.java
+++ b/src/main/java/top/gtb520/java/gnu/java/utils/library/main.java
@@ -37,6 +37,11 @@ public interface main {
static void ColorHexPrintln(String Message, String ColorCode) {
top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorHexPrintln(Message, ColorCode);
}
+
+ // 在单行内打印多种颜色的文字,包含Minecraft格式代码的文本,仿照Minecraft类型的文本终端打印
+ static void ColorPrintlnPlus(String Message) {
+ top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorPrintlnPlus(Message);
+ }
}
// 随机数生成接口与方法
diff --git a/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/print/echo.java b/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/print/echo.java
index 83e40ea..e3a500b 100644
--- a/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/print/echo.java
+++ b/src/main/java/top/gtb520/java/gnu/java/utils/library/utils/print/echo.java
@@ -1,5 +1,7 @@
package top.gtb520.java.gnu.java.utils.library.utils.print;
+import java.util.concurrent.ThreadLocalRandom;
+
/**
* 终端彩色输出工具类
* 提供基于 ANSI 转义序列的终端彩色打印功能
@@ -71,4 +73,112 @@ public class echo {
System.out.println(Message);
}
}
+
+ /**
+ * 在单行内打印多种颜色的文字
+ *
+ * 颜色代码仿照Minecraft格式,如:
+ * &4(红色)、&c(浅红色)、
+ * &6(橙色)、&e(黄色)、
+ * &2(绿色)、&a(浅绿色)、
+ * &b(浅青色)、&3(深青色)、
+ * &1(蓝色)、&9(浅蓝色)、
+ * &d(粉色)、&5(紫色)、
+ * &f(白色)、&7(灰色)、
+ * &8(深灰色)、&0(黑色)、
+ * &l(加粗)、&n(下划线)、
+ * &o(斜体)、&k(乱码)、
+ * &m(删除线)、&r(重置)。
+ *
+ * 示例:&6Welcome &2to &4Project
+ *
+ * @param Message 包含Minecraft格式代码的文本
+ */
+ public static void ColorPrintlnPlus(String Message) {
+ if (Message == null) {
+ System.out.println();
+ return;
+ }
+
+ StringBuilder result = new StringBuilder();
+ boolean obfuscated = false;
+ int i = 0;
+
+ while (i < Message.length()) {
+ // 检测格式代码:& 后跟一个字符
+ if (Message.charAt(i) == '&' && i + 1 < Message.length()) {
+ char code = Character.toLowerCase(Message.charAt(i + 1));
+ String ansi = getAnsiCode(code);
+ if (ansi != null) {
+ // 先重置,再应用新格式(避免格式叠加冲突)
+ result.append("\033[0m");
+ result.append(ansi);
+ // &k 开启乱码模式,其他颜色/格式码关闭乱码模式
+ obfuscated = (code == 'k');
+ i += 2;
+ continue;
+ }
+ }
+
+ // 普通字符
+ char ch = Message.charAt(i);
+ if (obfuscated && ch != '\n' && ch != '\r') {
+ // 乱码模式:将可见字符替换为随机字符
+ result.append(randomChar());
+ } else {
+ result.append(ch);
+ }
+ i++;
+ }
+
+ // 结尾重置格式
+ result.append("\033[0m");
+ System.out.println(result.toString());
+ }
+
+ /**
+ * 根据 Minecraft 格式代码字符返回对应的 ANSI 转义序列
+ *
+ * @param code & 后的小写字符
+ * @return ANSI 转义序列,若字符不是合法格式代码则返回 null
+ */
+ private static String getAnsiCode(char code) {
+ switch (code) {
+ // ===== 颜色码 =====
+ case '0': return "\033[30m"; // 黑色
+ case '1': return "\033[34m"; // 深蓝色
+ case '2': return "\033[32m"; // 深绿色
+ case '3': return "\033[36m"; // 深青色
+ case '4': return "\033[31m"; // 深红色
+ case '5': return "\033[35m"; // 深紫色
+ case '6': return "\033[38;5;214m"; // 橙色(Gold)
+ case '7': return "\033[37m"; // 灰色
+ case '8': return "\033[90m"; // 深灰色
+ case '9': return "\033[94m"; // 浅蓝色
+ case 'a': return "\033[92m"; // 浅绿色
+ case 'b': return "\033[96m"; // 浅青色
+ case 'c': return "\033[91m"; // 浅红色
+ case 'd': return "\033[95m"; // 粉色
+ case 'e': return "\033[93m"; // 黄色
+ case 'f': return "\033[97m"; // 白色
+ // ===== 格式码 =====
+ case 'l': return "\033[1m"; // 加粗
+ case 'm': return "\033[9m"; // 删除线
+ case 'n': return "\033[4m"; // 下划线
+ case 'o': return "\033[3m"; // 斜体
+ case 'k': return "\033[8m"; // 乱码(隐藏文字,配合随机字符替换实现)
+ case 'r': return "\033[0m"; // 重置
+ default: return null; // 非合法格式码,原样保留
+ }
+ }
+
+ /**
+ * 生成一个随机可见字符,用于乱码模式
+ *
+ * @return 随机可见字符
+ */
+ private static char randomChar() {
+ // 从可打印 ASCII 字符范围(33~126)中随机选取
+ return (char) ThreadLocalRandom.current().nextInt(33, 127);
+ }
}
diff --git a/src/test/java/ColorPrintlnPlusTest2.java b/src/test/java/ColorPrintlnPlusTest2.java
new file mode 100644
index 0000000..2275d5d
--- /dev/null
+++ b/src/test/java/ColorPrintlnPlusTest2.java
@@ -0,0 +1,7 @@
+import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
+
+public class ColorPrintlnPlusTest2 {
+ public static void main() {
+ echo.ColorPrintlnPlus("&dHello &2World&6!");
+ }
+}
diff --git a/src/test/java/echo.java b/src/test/java/echo.java
index 58eaeb2..8d53d57 100644
--- a/src/test/java/echo.java
+++ b/src/test/java/echo.java
@@ -11,6 +11,9 @@ public class echo {
main.echo.Println("RED", ColorNameEnum.RED);
ColorHexPrintlnTest();
+
+ System.out.println("111111111111111111");
+ main.echo.Println("头上带点绿,生活过得去", ColorNameEnum.GREEN);
}
static void ColorHexPrintlnTest() {
diff --git a/src/test/java/top/gtb520/java/gnu/java/utils/library/utils/print/ColorPrintlnPlusTest.java b/src/test/java/top/gtb520/java/gnu/java/utils/library/utils/print/ColorPrintlnPlusTest.java
new file mode 100644
index 0000000..9515fff
--- /dev/null
+++ b/src/test/java/top/gtb520/java/gnu/java/utils/library/utils/print/ColorPrintlnPlusTest.java
@@ -0,0 +1,335 @@
+package top.gtb520.java.gnu.java.utils.library.utils.print;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+public class ColorPrintlnPlusTest {
+
+ static int passed = 0;
+ static int failed = 0;
+
+ public static void main(String[] args) {
+ System.out.println("========== ColorPrintlnPlus 测试开始 ==========");
+
+ testNullInput();
+ testPlainMessageNoFormatCode();
+ testSingleColorCode();
+ testMultipleColorCodes();
+ testFormatCodeBold();
+ testFormatCodeUnderline();
+ testFormatCodeItalic();
+ testFormatCodeStrikethrough();
+ testFormatCodeReset();
+ testObfuscatedMode();
+ testObfuscatedModeDifferentEachCall();
+ testObfuscatedModeTurnsOffOnNewCode();
+ testInvalidCodeKeptAsIs();
+ testAmpersandAtEndOfString();
+ testCaseInsensitiveCodes();
+ testAllColorCodes();
+ testVisualOutput();
+
+ System.out.println("========================================");
+ System.out.println("测试完成: 通过 " + passed + ", 失败 " + failed);
+ if (failed > 0) {
+ System.exit(1);
+ }
+ }
+
+ /**
+ * 捕获 ColorPrintlnPlus 输出到字符串
+ */
+ static String captureOutput(String input) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream original = System.out;
+ System.setOut(new PrintStream(baos));
+ try {
+ echo.ColorPrintlnPlus(input);
+ } finally {
+ System.setOut(original);
+ }
+ return baos.toString();
+ }
+
+ /**
+ * 测试 null 输入
+ */
+ static void testNullInput() {
+ String testName = "testNullInput";
+ try {
+ String output = captureOutput(null);
+ assertCondition(testName + " - null输入应输出空行", output.trim().isEmpty());
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试无格式代码的纯文本
+ */
+ static void testPlainMessageNoFormatCode() {
+ String testName = "testPlainMessageNoFormatCode";
+ try {
+ String output = captureOutput("Hello World");
+ assertCondition(testName + " - 应包含原文本", output.contains("Hello World"));
+ assertCondition(testName + " - 应以重置序列结尾", output.contains("\033[0m"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试单个颜色代码
+ */
+ static void testSingleColorCode() {
+ String testName = "testSingleColorCode";
+ try {
+ String output = captureOutput("&4Red Text");
+ // &4 应转换为深红色 ANSI 序列 \033[31m
+ assertCondition(testName + " - 应包含红色ANSI序列", output.contains("\033[31m"));
+ assertCondition(testName + " - 应包含文本内容", output.contains("Red Text"));
+ assertCondition(testName + " - 不应包含格式代码&4", !output.contains("&4"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试多个颜色代码
+ */
+ static void testMultipleColorCodes() {
+ String testName = "testMultipleColorCodes";
+ try {
+ String output = captureOutput("&6Welcome &2to &4Project");
+ // &6 → 橙色 \033[38;5;214m
+ assertCondition(testName + " - 应包含橙色ANSI序列", output.contains("\033[38;5;214m"));
+ // &2 → 深绿色 \033[32m
+ assertCondition(testName + " - 应包含深绿色ANSI序列", output.contains("\033[32m"));
+ // &4 → 深红色 \033[31m
+ assertCondition(testName + " - 应包含深红色ANSI序列", output.contains("\033[31m"));
+ assertCondition(testName + " - 应包含Welcome", output.contains("Welcome"));
+ assertCondition(testName + " - 应包含to", output.contains("to"));
+ assertCondition(testName + " - 应包含Project", output.contains("Project"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试加粗格式码 &l
+ */
+ static void testFormatCodeBold() {
+ String testName = "testFormatCodeBold";
+ try {
+ String output = captureOutput("&lBold Text");
+ assertCondition(testName + " - 应包含加粗ANSI序列", output.contains("\033[1m"));
+ assertCondition(testName + " - 应包含文本", output.contains("Bold Text"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试下划线格式码 &n
+ */
+ static void testFormatCodeUnderline() {
+ String testName = "testFormatCodeUnderline";
+ try {
+ String output = captureOutput("&nUnderlined");
+ assertCondition(testName + " - 应包含下划线ANSI序列", output.contains("\033[4m"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试斜体格式码 &o
+ */
+ static void testFormatCodeItalic() {
+ String testName = "testFormatCodeItalic";
+ try {
+ String output = captureOutput("&oItalic");
+ assertCondition(testName + " - 应包含斜体ANSI序列", output.contains("\033[3m"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试删除线格式码 &m
+ */
+ static void testFormatCodeStrikethrough() {
+ String testName = "testFormatCodeStrikethrough";
+ try {
+ String output = captureOutput("&mStrike");
+ assertCondition(testName + " - 应包含删除线ANSI序列", output.contains("\033[9m"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试重置格式码 &r
+ */
+ static void testFormatCodeReset() {
+ String testName = "testFormatCodeReset";
+ try {
+ String output = captureOutput("&4Red&r Normal");
+ // &r 应产生重置序列 \033[0m
+ assertCondition(testName + " - 应包含重置序列", output.contains("\033[0m"));
+ assertCondition(testName + " - 应包含Normal", output.contains("Normal"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试乱码模式 &k:字符被替换为随机字符
+ */
+ static void testObfuscatedMode() {
+ String testName = "testObfuscatedMode";
+ try {
+ String output = captureOutput("&kSecret");
+ // 输出不应包含原始文本 "Secret"(因为被替换为随机字符)
+ // 但应包含乱码ANSI序列 \033[8m
+ assertCondition(testName + " - 应包含乱码ANSI序列", output.contains("\033[8m"));
+ // 输出中"Secret"被替换,长度应与原词相同(6个字符区域)
+ assertCondition(testName + " - 不应包含原始文本Secret", !output.contains("Secret"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试乱码模式每次调用产生不同结果
+ */
+ static void testObfuscatedModeDifferentEachCall() {
+ String testName = "testObfuscatedModeDifferentEachCall";
+ try {
+ String output1 = captureOutput("&kAAAAAAAAAA");
+ String output2 = captureOutput("&kAAAAAAAAAA");
+ // 两次调用的乱码结果应不同(10个字符全部随机,几乎不可能相同)
+ assertCondition(testName + " - 两次调用应产生不同乱码", !output1.equals(output2));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试乱码模式在遇到新格式码时关闭
+ */
+ static void testObfuscatedModeTurnsOffOnNewCode() {
+ String testName = "testObfuscatedModeTurnsOffOnNewCode";
+ try {
+ String output = captureOutput("&kHidden&aVisible");
+ // &a 应关闭乱码并开启绿色
+ assertCondition(testName + " - 应包含绿色ANSI序列", output.contains("\033[92m"));
+ // "Visible" 应保持原文
+ assertCondition(testName + " - 新格式码后的文本应保持原文", output.contains("Visible"));
+ // "Hidden" 不应出现
+ assertCondition(testName + " - 乱码区域的文本不应出现", !output.contains("Hidden"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试非合法格式码保持原样
+ */
+ static void testInvalidCodeKeptAsIs() {
+ String testName = "testInvalidCodeKeptAsIs";
+ try {
+ String output = captureOutput("&zUnknown");
+ // &z 不是合法格式码,应保持原样
+ assertCondition(testName + " - 非合法格式码应保持原样", output.contains("&zUnknown"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试 & 在字符串末尾
+ */
+ static void testAmpersandAtEndOfString() {
+ String testName = "testAmpersandAtEndOfString";
+ try {
+ String output = captureOutput("Text&");
+ // 末尾的 & 后无字符,应保持原样
+ assertCondition(testName + " - 末尾的&应保持原样", output.contains("Text&"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试格式码大小写不敏感
+ */
+ static void testCaseInsensitiveCodes() {
+ String testName = "testCaseInsensitiveCodes";
+ try {
+ String outputLower = captureOutput("&4red");
+ String outputUpper = captureOutput("&4red");
+ assertCondition(testName + " - 小写格式码应正常工作", outputLower.contains("\033[31m"));
+ assertCondition(testName + " - 大写格式码应正常工作", outputUpper.contains("\033[31m"));
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 测试所有16种颜色码均能正确转换
+ */
+ static void testAllColorCodes() {
+ String testName = "testAllColorCodes";
+ String[][] colorMap = {
+ {"0", "\033[30m"}, {"1", "\033[34m"}, {"2", "\033[32m"}, {"3", "\033[36m"},
+ {"4", "\033[31m"}, {"5", "\033[35m"}, {"6", "\033[38;5;214m"}, {"7", "\033[37m"},
+ {"8", "\033[90m"}, {"9", "\033[94m"}, {"a", "\033[92m"}, {"b", "\033[96m"},
+ {"c", "\033[91m"}, {"d", "\033[95m"}, {"e", "\033[93m"}, {"f", "\033[97m"}
+ };
+ try {
+ boolean allPassed = true;
+ for (String[] pair : colorMap) {
+ String output = captureOutput("&" + pair[0] + "x");
+ if (!output.contains(pair[1])) {
+ assertCondition(testName + " - &" + pair[0] + " 应转换为 " + pair[1], false);
+ allPassed = false;
+ }
+ }
+ if (allPassed) {
+ assertCondition(testName + " - 全部16种颜色码转换正确", true);
+ }
+ } catch (Exception e) {
+ assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
+ }
+ }
+
+ /**
+ * 视觉测试:在终端直接展示各种效果
+ */
+ static void testVisualOutput() {
+ System.out.println("--- 视觉测试(请人工确认)---");
+ echo.ColorPrintlnPlus("&4深红色 &c浅红色 &6橙色 &e黄色 &2深绿色 &a浅绿色");
+ echo.ColorPrintlnPlus("&b浅青色 &3深青色 &1深蓝色 &9浅蓝色 &d粉色 &5深紫色");
+ echo.ColorPrintlnPlus("&f白色 &7灰色 &8深灰色 &0黑色");
+ echo.ColorPrintlnPlus("&l加粗文字 &n下划线文字 &o斜体文字 &m删除线文字");
+ echo.ColorPrintlnPlus("&6Welcome &2to &4Project");
+ echo.ColorPrintlnPlus("&k这是一段乱码文字每次不同");
+ echo.ColorPrintlnPlus("&4红色 &l加粗红色 &r重置为普通");
+ System.out.println("--- 视觉测试结束 ---");
+ // 视觉测试直接计为通过
+ passed++;
+ }
+
+ // ========== 辅助方法 ==========
+
+ static void assertCondition(String message, boolean condition) {
+ if (condition) {
+ System.out.println("[PASS] " + message);
+ passed++;
+ } else {
+ System.out.println("[FAIL] " + message);
+ failed++;
+ }
+ }
+}