终端界面
Program.exe 启动后会接管当前控制台,画出一个固定表头 + 独立日志区的终端界面。 表头永不移动,插件输出滚动显示在下方的日志区里。
界面由三部分组成
| 区域 | 内容 |
|---|---|
| 表头 | NT VECTOR 大字标题、边框、状态行、动画小人 |
| 状态行 | 左侧当前状态(空闲 / 忙碌 / 崩溃)、右侧 Producer : Nell - vtbot.cn |
| 日志区 | 插件与程序的输出,可翻历史 |
控制台标题栏会被设为 Vector-lurete。
三个状态
状态由「当前活跃任务数」和「最近是否有聊天消息」共同决定:
| 状态 | 触发条件 | 表现 |
|---|---|---|
| 空闲 | 没有活跃任务 | 小人快速左右走动 |
| 忙碌 | 活跃任务数 ≥ 1 | 小人放慢走动,撞到边框折返、带闪烁 |
| 崩溃 | 活跃任务数 ≥ 3,或 5 秒内收到过聊天消息 | 黄色高亮 |
阈值可以调整(默认 busyMin = 1、portalMin = 3、聊天保持 5000 毫秒):
VectorUI::SetStateThresholds(busyMin, portalMin)VectorUI::SetChatHoldMs(ms)
日志区显示什么
日志区捕获的是 fd 1 / fd 2 的输出,所以任何写标准输出的东西都会进来:
- 插件里的
print()、sys.stdout.write() - 框架输出,例如
[Vector_import] 收到消息: …、CHAT <Vtbot> … - 程序自身经
Logger输出的日志 —— 仅在带--logger时显示
为什么要接管 fd 1/2
直接往控制台写文本会顶掉表头(这也是早期版本"一出现文字就被挤掉"的原因)。 接管后用独立线程把输出读进日志区,表头就再也不会被覆盖。
Python 侧同时做了三件事,否则中文会乱码或日志延迟出现: PYTHONUNBUFFERED=1、PYTHONIOENCODING=utf-8,以及启动时 sys.stdout.reconfigure(encoding='utf-8', line_buffering=True)。
翻历史与复制文本
这里有一个必须知道的取舍:Windows 控制台的「鼠标滚轮」和「原生拖拽选中 + 右键复制」 由同一个开关控制 —— 一旦程序捕获鼠标事件以接收滚轮,控制台自带的选中复制就失效了。
所以默认不抢鼠标,把选中复制留给你:
| 操作 | 默认 | 加 --mouse-scroll 或按 F7 后 |
|---|---|---|
| 左键拖拽选中 + 右键复制 | ✅ 可用 | 需按住 Shift 才能选中 |
| 鼠标滚轮翻日志 | ❌ 无效 | ✅ 可用 |
PageUp / PageDown / ↑ / ↓ / Home / End | ✅ 可用 | ✅ 可用 |
建议
日常用 PageUp / PageDown 翻历史(两种模式下都可用); 确实想要滚轮时按一下 F7 即时切换,不用重启 —— 切换后日志区会打印一行提示告诉你当前模式。
备用屏幕缓冲区
界面运行期间会切到备用屏幕缓冲区(ESC[?1049h,即 vim / htop 用的机制)。
原因是 Windows Terminal 自己维护一份回滚历史,和控制台屏幕缓冲区是两套东西: 即使程序把缓冲区缩到窗口大小,往上滚动依然会翻出历史帧,界面看起来就是一堆残影。 备用屏幕没有回滚历史,从根上避免这个问题;退出时切回原屏幕。
因此界面运行期间终端的滚动条是无效的,历史只存在于日志区里。
相关命令行参数
| 参数 | 说明 |
|---|---|
| (默认) | 开启终端界面 |
--no-ui | 关闭界面,退回普通输出模式 |
--ui-demo | 预览三种状态(每 5 秒切换一次,不连接服务器),并每 3 秒写一次 ui_diag.txt |
--mouse-scroll | 捕获鼠标以支持滚轮翻日志(会牺牲原生拖拽选中,可用 F7 随时切换) |
--logger | 让程序自身的日志也进入日志区 |
没有真实控制台时
如果 stdout 被重定向(例如 Program.exe > log.txt),界面会自动关闭而不是把转义码 写进文件。此时日志按普通文本输出,和 --no-ui 等价。
