- 新增 /connection 路由,从全局选中设备 SN 读取并渲染远程控制页 - 首页镜像操作改为静默下发 mirror 命令并跳转远程控制页 - 更新 AGENTS.md 版本管理策略为使用最新稳定版本 - 调整 pubspec.lock 中 hooks 与 record_use 版本
140 lines
3.8 KiB
Dart
140 lines
3.8 KiB
Dart
import 'dart:typed_data';
|
||
|
||
/// 控制指令 Action 枚举(与控制端 proto 的 Action 字段号一致)。
|
||
class ActionType {
|
||
static const unknown = 0;
|
||
static const touch = 1;
|
||
static const swipe = 2;
|
||
static const key = 3;
|
||
static const longPress = 4;
|
||
static const motionEvent = 5;
|
||
static const setResolution = 6;
|
||
static const reportResolution = 7;
|
||
static const setStreamMode = 8;
|
||
static const reportStreamMode = 9;
|
||
}
|
||
|
||
/// protobuf wire format 编码器。
|
||
///
|
||
/// 与控制端 `com.ttstd.control.ControlMessage`(protobuf 3)字段号完全对齐:
|
||
/// action=1, x=2, y=3, x1=4, y1=5, x2=6, y2=7, duration=8,
|
||
/// key_code=9, key_action=10, motion_action=11, width=12, height=13,
|
||
/// fps=14, stream_mode=15, supported_fps=16(repeated int32)。
|
||
///
|
||
/// 坐标均为相对屏幕百分比(0.0~1.0),被控端乘以真实分辨率还原像素。
|
||
class ControlMessageEncoder {
|
||
final int action;
|
||
|
||
// 单点坐标
|
||
final double x;
|
||
final double y;
|
||
|
||
// 滑动起止
|
||
final double x1;
|
||
final double y1;
|
||
final double x2;
|
||
final double y2;
|
||
final int duration;
|
||
|
||
// 按键
|
||
final int keyCode;
|
||
final int keyAction;
|
||
|
||
// 原始动作
|
||
final int motionAction;
|
||
|
||
// 分辨率/帧率
|
||
final int width;
|
||
final int height;
|
||
final int fps;
|
||
final int streamMode;
|
||
|
||
const ControlMessageEncoder({
|
||
required this.action,
|
||
this.x = 0,
|
||
this.y = 0,
|
||
this.x1 = 0,
|
||
this.y1 = 0,
|
||
this.x2 = 0,
|
||
this.y2 = 0,
|
||
this.duration = 0,
|
||
this.keyCode = 0,
|
||
this.keyAction = 0,
|
||
this.motionAction = 0,
|
||
this.width = 0,
|
||
this.height = 0,
|
||
this.fps = 0,
|
||
this.streamMode = 0,
|
||
});
|
||
|
||
/// 编码为 protobuf 二进制字节数组。
|
||
Uint8List encode() {
|
||
final out = BytesBuilder(copy: false);
|
||
|
||
// 1: action (enum=int32)
|
||
_writeVarintField(out, 1, action);
|
||
|
||
// 2: x, 3: y (double, wire type 1)
|
||
if (x != 0) _writeFixed64Field(out, 2, x);
|
||
if (y != 0) _writeFixed64Field(out, 3, y);
|
||
|
||
// 4-7: swipe 起止
|
||
if (x1 != 0) _writeFixed64Field(out, 4, x1);
|
||
if (y1 != 0) _writeFixed64Field(out, 5, y1);
|
||
if (x2 != 0) _writeFixed64Field(out, 6, x2);
|
||
if (y2 != 0) _writeFixed64Field(out, 7, y2);
|
||
|
||
// 8: duration (int64)
|
||
if (duration != 0) _writeVarintField(out, 8, duration);
|
||
|
||
// 9: key_code, 10: key_action (int32)
|
||
if (keyCode != 0) _writeVarintField(out, 9, keyCode);
|
||
if (keyAction != 0) _writeVarintField(out, 10, keyAction);
|
||
|
||
// 11: motion_action
|
||
if (motionAction != 0) _writeVarintField(out, 11, motionAction);
|
||
|
||
// 12-14: width/height/fps
|
||
if (width != 0) _writeVarintField(out, 12, width);
|
||
if (height != 0) _writeVarintField(out, 13, height);
|
||
if (fps != 0) _writeVarintField(out, 14, fps);
|
||
|
||
// 15: stream_mode
|
||
if (streamMode != 0) _writeVarintField(out, 15, streamMode);
|
||
|
||
return out.toBytes();
|
||
}
|
||
|
||
// ---- protobuf wire format 原语 ----
|
||
|
||
void _writeVarintField(BytesBuilder out, int field, int value) {
|
||
_writeTag(out, field, 0); // wire type 0 = varint
|
||
_writeVarint(out, value);
|
||
}
|
||
|
||
void _writeFixed64Field(BytesBuilder out, int field, double value) {
|
||
_writeTag(out, field, 1); // wire type 1 = 64-bit (double)
|
||
// protobuf 的 fixed64/double 必须为 little-endian,否则设备端解析出错误值(如 NaN/Infinity)
|
||
final bd = ByteData(8);
|
||
bd.setFloat64(0, value, Endian.little);
|
||
out.add(bd.buffer.asUint8List());
|
||
}
|
||
|
||
void _writeTag(BytesBuilder out, int field, int wireType) {
|
||
_writeVarint(out, (field << 3) | wireType);
|
||
}
|
||
|
||
void _writeVarint(BytesBuilder out, int value) {
|
||
// 转成无符号 64 位表示,配合逻辑右移 >>>,避免负数算术右移导致死循环(OOM)。
|
||
var v = value.toUnsigned(64);
|
||
while (true) {
|
||
if ((v & ~0x7F) == 0) {
|
||
out.addByte(v & 0xFF);
|
||
break;
|
||
}
|
||
out.addByte((v & 0x7F) | 0x80);
|
||
v = v >>> 7;
|
||
}
|
||
}
|
||
}
|