BluetoothAim_SDK.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using ArduinoBluetoothAPI;
  6. namespace SmartBowSDK
  7. {
  8. public class BluetoothAim_SDK : MonoBehaviour
  9. {
  10. public SmartBowHelper smartBowHelper;
  11. public BluetoothDeviceConfig deviceConfig;
  12. private BluetoothHelper _bluetoothHelper;
  13. private BluetoothHelperService _bluetoothService;
  14. private BluetoothHelperCharacteristic _characteristicWrite;
  15. private static HashSet<object> _ScanLocker = new HashSet<object>();
  16. private int _receivedDataCount = 0;
  17. public string macAddress = null;
  18. public BluetoothStatusEnum bluetoothStatus;
  19. private BluetoothWindows _bluetoothWindows;
  20. /// <summary>
  21. /// 6轴
  22. /// </summary>
  23. private o06DOF.SixAxisFusion sixAxisFusion;
  24. /// <summary>
  25. /// 过滤名称
  26. /// </summary>
  27. public string filters { get; set; } = "";
  28. /// <summary>
  29. /// 是否使用mac过滤
  30. /// </summary>
  31. public bool isConnectName { get; set; } = true;//默认用名字连接
  32. /// <summary>
  33. /// 传入的mac
  34. /// </summary>
  35. public string connectMacStr { get; set; } = "";
  36. /// <summary>
  37. /// 当前的传感器类型
  38. /// </summary>
  39. public SensorAxisType sensorAxisType { get; set; } = SensorAxisType.NineAxisSensor;
  40. private void SetStatus(BluetoothStatusEnum newStatus)
  41. {
  42. BluetoothStatusEnum oldStatus = bluetoothStatus;
  43. if (oldStatus == newStatus) return;
  44. bluetoothStatus = newStatus;
  45. SmartBowLogger.Log(this, $"oldStatus[{oldStatus}]=>newStatus[{newStatus}]");
  46. if (newStatus == BluetoothStatusEnum.None)
  47. {
  48. _bluetoothHelper = null;
  49. _bluetoothService = null;
  50. _characteristicWrite = null;
  51. _receivedDataCount = 0;
  52. macAddress = null;
  53. _battery = 0;
  54. moduleInited = false;
  55. }
  56. smartBowHelper.InvokeOnBluetoothStatusChanged(oldStatus, newStatus);
  57. }
  58. void Awake()
  59. {
  60. DontDestroyOnLoad(gameObject);
  61. deviceConfig = BluetoothDeviceConfig.GetDefault();
  62. }
  63. void Update()
  64. {
  65. LoopHandleCommands();
  66. }
  67. private static int _NoneToConnectingStep = 0;
  68. public BluetoothWindows CreateWindowBLE() {
  69. //如果是window环境,直接实例化一个BluetoothWindows
  70. if (BluetoothWindows.IsWindows())
  71. {
  72. _bluetoothWindows = new BluetoothWindows();
  73. _bluetoothWindows.OnConnected = OnConnected_windows;
  74. _bluetoothWindows.OnConnectionFailed = OnConnectionFailed_windows;
  75. _bluetoothWindows.OnCharacteristicChanged = OnCharacteristicChanged_windows;
  76. return _bluetoothWindows;
  77. }
  78. return null;
  79. }
  80. public void Connect()
  81. {
  82. if (BluetoothWindows.IsWindows())
  83. {
  84. if (bluetoothStatus == BluetoothStatusEnum.None)
  85. {
  86. _bluetoothWindows.Connect();
  87. SetStatus(BluetoothStatusEnum.Connecting);
  88. //初始化一次六轴解析
  89. if (sixAxisFusion == null)
  90. {
  91. Vector3 accelOffset = Vector3.zero;
  92. Vector3 gyroOffset = Vector3.zero;
  93. float gForce = 1.0f;
  94. float gyroToDegree = 1.0f;
  95. sixAxisFusion = new o06DOF.SixAxisFusion(accelOffset, gyroOffset, gForce, gyroToDegree);
  96. }
  97. }
  98. return;
  99. }
  100. if (_ScanLocker.Count > 0) return;
  101. if (bluetoothStatus != BluetoothStatusEnum.None) return;
  102. if (_NoneToConnectingStep > 0) return;
  103. _NoneToConnectingStep = 1;
  104. if (Application.platform == RuntimePlatform.Android)
  105. {
  106. if (!BluetoothHelperAndroid_SDK.IsBluetoothEnabled())
  107. {
  108. HandleConnectError(BluetoothError.BluetoothNotEnabled, "蓝牙开关未打开");
  109. return;
  110. }
  111. if (BluetoothHelperAndroid_SDK.RequestBluetoothPermissions(() =>
  112. {
  113. _NoneToConnectingStep = 0;
  114. Connect();
  115. }, (permission) =>
  116. {
  117. if (permission.Contains("LOCATION"))
  118. {
  119. HandleConnectError(BluetoothError.LocationPermissionNotGranted, "尚未授予定位权限");
  120. }
  121. else if (permission.Contains("BLUETOOTH"))
  122. {
  123. HandleConnectError(BluetoothError.ScanPermissionNotGranted, "尚未授予扫描附近设备权限");
  124. }
  125. })) return;
  126. }
  127. try
  128. {
  129. BluetoothHelper.BLE = true;
  130. _bluetoothHelper = BluetoothHelper.GetNewInstance();
  131. _bluetoothHelper.OnConnected += OnConnected;
  132. _bluetoothHelper.OnConnectionFailed += OnConnectionFailed;
  133. SmartBowLogger.Log(this,"创建蓝牙的SensorAxisType类型:"+ sensorAxisType);
  134. if (sensorAxisType == SensorAxisType.SixAxisSensor)
  135. {
  136. //6轴时候,另外的解析操作
  137. _bluetoothHelper.OnCharacteristicChanged += OnCharacteristicChanged6Axis;
  138. //初始化一次六轴解析
  139. if (sixAxisFusion == null) {
  140. Vector3 accelOffset = Vector3.zero;
  141. Vector3 gyroOffset = Vector3.zero;
  142. float gForce = 1.0f;
  143. float gyroToDegree = 1.0f;
  144. sixAxisFusion = new o06DOF.SixAxisFusion(accelOffset, gyroOffset, gForce, gyroToDegree);
  145. }
  146. }
  147. else {
  148. //九轴的解析
  149. _bluetoothHelper.OnCharacteristicChanged += OnCharacteristicChanged;
  150. }
  151. _bluetoothHelper.OnScanEnded += OnScanEnded;
  152. _bluetoothHelper.ScanNearbyDevices();
  153. _NoneToConnectingStep = 2;
  154. }
  155. catch (Exception e)
  156. {
  157. HandleConnectError(BluetoothError.Unknown, e.ToString());
  158. }
  159. if (_NoneToConnectingStep == 2)
  160. {
  161. _NoneToConnectingStep = 0;
  162. _ScanLocker.Add(_bluetoothHelper);
  163. SetStatus(BluetoothStatusEnum.Connecting);
  164. }
  165. }
  166. private void HandleConnectError(BluetoothError error, string message)
  167. {
  168. _NoneToConnectingStep = 0;
  169. smartBowHelper.InvokeOnBluetoothError(error, message);
  170. }
  171. public void Disconnect()
  172. {
  173. //断开连接时候清除AimDeviceInfo
  174. ResetAimDeviceInfoToNull();
  175. if (BluetoothWindows.IsWindows())
  176. {
  177. if (_bluetoothWindows.Disconnect())
  178. SetStatus(BluetoothStatusEnum.None);
  179. return;
  180. }
  181. if (_bluetoothHelper != null)
  182. _bluetoothHelper.Disconnect();
  183. SetStatus(BluetoothStatusEnum.None);
  184. }
  185. void OnConnected(BluetoothHelper helper)
  186. {
  187. if (helper != _bluetoothHelper) return;
  188. SetStatus(BluetoothStatusEnum.Connected);
  189. foreach (BluetoothHelperService service in helper.getGattServices())
  190. {
  191. if (service.getName().ToLower().StartsWith(deviceConfig.service))
  192. {
  193. _bluetoothService = service;
  194. foreach (BluetoothHelperCharacteristic characteristic in service.getCharacteristics())
  195. {
  196. if (characteristic.getName().ToLower().StartsWith(deviceConfig.characteristicWrite))
  197. {
  198. _characteristicWrite = characteristic;
  199. }
  200. else if (characteristic.getName().ToLower().StartsWith(deviceConfig.characteristicNotify))
  201. {
  202. BluetoothHelperCharacteristic c = new BluetoothHelperCharacteristic(characteristic.getName());
  203. c.setService(_bluetoothService.getName());
  204. _bluetoothHelper.Subscribe(c);
  205. }
  206. }
  207. }
  208. }
  209. //指令区分
  210. if (sensorAxisType == SensorAxisType.SixAxisSensor)
  211. {
  212. //6轴指令
  213. StartCoroutine(InitWhenConnected6Axis());
  214. }
  215. else
  216. {
  217. //九轴
  218. StartCoroutine(InitWhenConnected());
  219. }
  220. }
  221. void OnConnected_windows()
  222. {
  223. SetStatus(BluetoothStatusEnum.Connected);
  224. if (sensorAxisType == SensorAxisType.SixAxisSensor)
  225. {
  226. //6轴指令
  227. StartCoroutine(InitWhenConnected6Axis());
  228. }
  229. else
  230. {
  231. //九轴
  232. StartCoroutine(InitWhenConnected());
  233. }
  234. }
  235. void OnConnectionFailed(BluetoothHelper helper)
  236. {
  237. if (helper != _bluetoothHelper) return;
  238. SetStatus(BluetoothStatusEnum.None);
  239. }
  240. void OnConnectionFailed_windows()
  241. {
  242. SetStatus(BluetoothStatusEnum.None);
  243. }
  244. /// <summary>
  245. /// 原九轴的传感器解析
  246. /// </summary>
  247. /// <param name="helper"></param>
  248. /// <param name="value"></param>
  249. /// <param name="characteristic"></param>
  250. void OnCharacteristicChanged(BluetoothHelper helper, byte[] value, BluetoothHelperCharacteristic characteristic)
  251. {
  252. if (helper != _bluetoothHelper) return;
  253. if (bluetoothStatus != BluetoothStatusEnum.Connected) return;
  254. byte[] bytes = value;
  255. if (macAddress == null && _receivedDataCount++ < 500) ParseMacAddress(value);
  256. smartBowHelper.aimHandler.OnDataReceived(bytes);
  257. }
  258. /// <summary>
  259. /// 六轴传感器时候使用的解析
  260. /// </summary>
  261. /// <param name="helper"></param>
  262. /// <param name="value"></param>
  263. /// <param name="characteristic"></param>
  264. void OnCharacteristicChanged6Axis(BluetoothHelper helper, byte[] value, BluetoothHelperCharacteristic characteristic)
  265. {
  266. if (helper != _bluetoothHelper) return;
  267. if (bluetoothStatus != BluetoothStatusEnum.Connected) return;
  268. byte[] bytes = value;
  269. if (macAddress == null && _receivedDataCount++ < 500) ParseMacAddress(value);
  270. //smartBowHelper.aimHandler.OnDataReceived(bytes);
  271. //转字符串后就是 Bat
  272. if (bytes.Length == 20 && bytes[19] == 0x0a
  273. //Bat
  274. && bytes[2] == 0x42 && bytes[3] == 0x61 && bytes[4] == 0x74) {
  275. //第一步 解析电量?
  276. string betty = System.Text.Encoding.ASCII.GetString(bytes);
  277. // SmartBowLogger.Log(this, BitConverter.ToString(bytes).Replace("-", ""));
  278. //SmartBowLogger.Log(this, "betty:" + betty);
  279. // 第二步:解析JSON字符串
  280. Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(betty);
  281. // 第三步:提取"Bat"的值
  282. int batValue = (int)json["Bat"];
  283. SmartBowLogger.Log(this, "Bat Value: " + batValue); // 输出: 100
  284. battery = batValue;
  285. }
  286. //传感器数据
  287. if (bytes.Length == 20 && bytes[0] == 0x7b && bytes[19] == 0x7d)
  288. {
  289. o06DOF.SixData sixData = sixAxisFusion.getSixAxisByBytes(bytes);
  290. Quaternion quaternion = sixAxisFusion.tranUpdateData(sixData);
  291. //输出欧拉角 pitch yaw roll
  292. smartBowHelper.InvokeOnSixAxisRotationUpdate(quaternion.eulerAngles);
  293. //smartBowHelper.InvokeOnAxisDataUpdateEvent(bytes);
  294. }
  295. }
  296. /// <summary>
  297. /// 重置6轴identify
  298. /// </summary>
  299. public void ResetSixAxisFusion() {
  300. if (sixAxisFusion != null) {
  301. sixAxisFusion.ResetToInitialRotation();
  302. }
  303. }
  304. /// <summary>
  305. /// pc调用
  306. /// </summary>
  307. /// <param name="deviceId"></param>
  308. /// <param name="value"></param>
  309. void OnCharacteristicChanged_windows(string deviceId, byte[] value)
  310. {
  311. if (sensorAxisType == SensorAxisType.SixAxisSensor)
  312. {
  313. //6轴指令
  314. OnCharacteristicChanged6Axis(null, value, null);
  315. }
  316. else
  317. {
  318. //九轴
  319. OnCharacteristicChanged(null, value, null);
  320. }
  321. }
  322. void OnScanEnded(BluetoothHelper helper, LinkedList<BluetoothDevice> nearbyDevices)
  323. {
  324. _ScanLocker.Remove(helper);
  325. if (helper != _bluetoothHelper) return;
  326. foreach (BluetoothDevice device in nearbyDevices)
  327. {
  328. SmartBowLogger.Log(this, $"发现设备{device.DeviceName},is fileters empty:{ string.IsNullOrEmpty(filters)},name:{filters}");
  329. if (isConnectName)
  330. {
  331. //if (device.DeviceName == deviceConfig.deviceName)
  332. //后续匹配名字 可以是多个设备
  333. string _filters = string.IsNullOrEmpty(filters) ? deviceConfig.deviceName : filters;
  334. if (_filters.Contains(device.DeviceName))
  335. {
  336. _bluetoothHelper.setDeviceName(device.DeviceName);
  337. _bluetoothHelper.Connect();
  338. SmartBowLogger.Log(this, $"Name匹配设备{device.DeviceName}");
  339. return;
  340. }
  341. }
  342. else
  343. {
  344. //按mac地址匹配
  345. if (device.DeviceAddress == connectMacStr)
  346. {
  347. _bluetoothHelper.setDeviceName(device.DeviceName);
  348. _bluetoothHelper.setDeviceAddress(connectMacStr);
  349. _bluetoothHelper.Connect();
  350. SmartBowLogger.Log(this, $"Mac匹配设备{device.DeviceAddress}");
  351. return;
  352. }
  353. }
  354. }
  355. SetStatus(BluetoothStatusEnum.None);
  356. smartBowHelper.InvokeOnBluetoothError(BluetoothError.ScanNotFoundTargetDevice, "扫描结束后未发现目标设备");
  357. }
  358. private float _lastWriteDataTime;
  359. bool WriteData(string data)
  360. {
  361. try
  362. {
  363. if (BluetoothWindows.IsWindows())
  364. {
  365. return _bluetoothWindows.Write(data);
  366. }
  367. BluetoothHelperCharacteristic c = new BluetoothHelperCharacteristic(_characteristicWrite.getName());
  368. c.setService(_bluetoothService.getName());
  369. _bluetoothHelper.WriteCharacteristic(c, data);
  370. _lastWriteDataTime = Time.realtimeSinceStartup;
  371. return true;
  372. }
  373. catch (Exception e)
  374. {
  375. Debug.LogError(e);
  376. return false;
  377. }
  378. }
  379. bool WriteByteData(byte[] data)
  380. {
  381. try
  382. {
  383. if (BluetoothWindows.IsWindows())
  384. {
  385. return _bluetoothWindows.WriteByte(data);
  386. }
  387. BluetoothHelperCharacteristic c = new BluetoothHelperCharacteristic(_characteristicWrite.getName());
  388. c.setService(_bluetoothService.getName());
  389. _bluetoothHelper.WriteCharacteristic(c, data);
  390. _lastWriteDataTime = Time.realtimeSinceStartup;
  391. return true;
  392. }
  393. catch (Exception e)
  394. {
  395. Debug.LogError(e);
  396. return false;
  397. }
  398. }
  399. public bool moduleInited;
  400. private string _connectedHandlerID = "";
  401. IEnumerator InitWhenConnected()
  402. {
  403. string myConnectedHandlerID = Guid.NewGuid().ToString();
  404. _connectedHandlerID = myConnectedHandlerID;
  405. yield return new WaitForSecondsRealtime(BluetoothWindows.IsWindows() ? 0.3f : 2.2f);
  406. Queue<string> cmds = new Queue<string>(new string[] { "M", "b", "b", "1" });
  407. while (cmds.Count > 0)
  408. {
  409. if (bluetoothStatus != BluetoothStatusEnum.Connected || myConnectedHandlerID != _connectedHandlerID) yield break;
  410. string cmd = cmds.Dequeue();
  411. WriteData(cmd);
  412. yield return new WaitForSecondsRealtime(0.3f);
  413. }
  414. if (bluetoothStatus != BluetoothStatusEnum.Connected || myConnectedHandlerID != _connectedHandlerID) yield break;
  415. StartCoroutine(LoopRequestBattery(myConnectedHandlerID));
  416. moduleInited = true;
  417. smartBowHelper.InvokeOnBluetoothModuleInited();
  418. }
  419. /// <summary>
  420. /// 初始化6轴指令
  421. /// </summary>
  422. /// <returns></returns>
  423. IEnumerator InitWhenConnected6Axis()
  424. {
  425. string myConnectedHandlerID = Guid.NewGuid().ToString();
  426. _connectedHandlerID = myConnectedHandlerID;
  427. yield return new WaitForSecondsRealtime(BluetoothWindows.IsWindows() ? 0.3f : 2.2f);
  428. Queue<string> cmds = new Queue<string>(new string[] { "M", "B", "B" });
  429. while (cmds.Count > 0)
  430. {
  431. if (bluetoothStatus != BluetoothStatusEnum.Connected || myConnectedHandlerID != _connectedHandlerID) yield break;
  432. string cmd = cmds.Dequeue();
  433. WriteData(cmd);
  434. yield return new WaitForSecondsRealtime(0.3f);
  435. }
  436. if (bluetoothStatus != BluetoothStatusEnum.Connected || myConnectedHandlerID != _connectedHandlerID) yield break;
  437. StartCoroutine(LoopRequestBattery6Axis(myConnectedHandlerID));
  438. moduleInited = true;
  439. smartBowHelper.InvokeOnBluetoothModuleInited();
  440. }
  441. private int _battery = 0;
  442. public int battery
  443. {
  444. get => _battery;
  445. set
  446. {
  447. _battery = value;
  448. //SmartBowLogger.Log(this, "Battery缓存成功");
  449. }
  450. }
  451. /// <summary>
  452. /// 九轴原本的连接电池指令
  453. /// </summary>
  454. /// <param name="myConnectedHandlerID"></param>
  455. /// <returns></returns>
  456. IEnumerator LoopRequestBattery(string myConnectedHandlerID)
  457. {
  458. while (bluetoothStatus == BluetoothStatusEnum.Connected && myConnectedHandlerID == _connectedHandlerID)
  459. {
  460. yield return new WaitForSecondsRealtime(10);
  461. AddCommandToQueue("b");
  462. }
  463. }
  464. /// <summary>
  465. /// 6轴的连接电池指令
  466. /// </summary>
  467. /// <param name="myConnectedHandlerID"></param>
  468. /// <returns></returns>
  469. IEnumerator LoopRequestBattery6Axis(string myConnectedHandlerID)
  470. {
  471. while (bluetoothStatus == BluetoothStatusEnum.Connected && myConnectedHandlerID == _connectedHandlerID)
  472. {
  473. yield return new WaitForSecondsRealtime(10);
  474. AddCommandToQueue("B");
  475. }
  476. }
  477. private List<string> _commands = new List<string>();
  478. void LoopHandleCommands()
  479. {
  480. if (bluetoothStatus != BluetoothStatusEnum.Connected || !moduleInited)
  481. {
  482. if (_commands.Count > 0) _commands.Clear();
  483. return;
  484. }
  485. if (Time.realtimeSinceStartup - _lastWriteDataTime < 0.2f) return;
  486. if (_commands.Count == 0) return;
  487. string cmd = _commands[0];
  488. _commands.RemoveAt(0);
  489. WriteData(cmd);
  490. }
  491. bool AddCommandToQueue(string cmd)
  492. {
  493. if (bluetoothStatus != BluetoothStatusEnum.Connected || !moduleInited) return false;
  494. //如果待插入的指令跟队尾的指令一样,就不要插入了,因为冗余的指令无意义
  495. if (_commands.Count > 0 && _commands[_commands.Count - 1].Equals(cmd)) return true;
  496. _commands.Add(cmd);
  497. return true;
  498. }
  499. public void ReplyInfraredShoot()
  500. {
  501. if (bluetoothStatus != BluetoothStatusEnum.Connected || !moduleInited) return;
  502. WriteData("I");
  503. }
  504. public void ReplyByte(byte[] value)
  505. {
  506. if (bluetoothStatus != BluetoothStatusEnum.Connected || !moduleInited) return;
  507. WriteByteData(value);
  508. }
  509. public bool RequestOpen9Axis()
  510. {
  511. return AddCommandToQueue("3");
  512. }
  513. public bool RequestClose9Axis()
  514. {
  515. return AddCommandToQueue("4");
  516. }
  517. public bool RequestOpenInfrared()
  518. {
  519. return AddCommandToQueue("w");
  520. }
  521. public bool RequestCloseInfrared()
  522. {
  523. return AddCommandToQueue("s");
  524. }
  525. void ParseMacAddress(byte[] bytes)
  526. {
  527. string mac = System.Text.Encoding.ASCII.GetString(bytes);
  528. if (mac != null) mac = mac.Trim();
  529. if (CheckIsMacValid(mac))
  530. {
  531. #region 根据aimDeviceInfo存在添加一个判断
  532. if (aimDeviceInfo != null) {
  533. //需要增加一个判断,判断是否对应的mac设备。不是需要进行重新连接
  534. if (!aimDeviceInfo.bInitMac)
  535. {
  536. SmartBowLogger.Log(this, "设置设备mac:" + mac);
  537. SetAimDeviceMac(mac);
  538. }
  539. else if (aimDeviceInfo.mac != mac)
  540. {
  541. SmartBowLogger.LogError(this, "设备不一样,断开连接");
  542. Disconnect();
  543. //抛出一个错误,给用户处理其他业务流程
  544. smartBowHelper.InvokeOnBluetoothError(BluetoothError.MacAddressAndDeviceMismatch, "验证设备MAC和记录的MAC不匹配!");
  545. return;
  546. }
  547. }
  548. #endregion
  549. macAddress = mac;
  550. SmartBowLogger.Log(this, "MacAddress解析成功");
  551. //获取MacAddress对应的校准记录
  552. string macXXX = macAddress;
  553. smartBowHelper.smartBowNetwork.GetCalibrateRecord(macXXX, (record) =>
  554. {
  555. if (macAddress != macXXX) return;
  556. smartBowHelper.aimHandler.ResumeCalibrateRecord(record);
  557. });
  558. }
  559. else SmartBowLogger.LogWarning(this, "MacAddress解析失败");
  560. }
  561. bool CheckIsMacValid(string mac)
  562. {
  563. if (mac == null) return false;
  564. if (!mac.StartsWith("{")) return false;
  565. if (!mac.EndsWith("}")) return false;
  566. if (!mac.Contains(":")) return false;
  567. char[] validChars = { '{', '}', ':', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  568. foreach (var c in mac.ToCharArray())
  569. {
  570. if (Array.IndexOf(validChars, c) == -1) return false;
  571. }
  572. if (mac.Length != 19) return false;
  573. string macNoneFrame = mac.Substring(1, mac.Length - 2);
  574. string[] macNoneFrameSplits = macNoneFrame.Split(':');
  575. if (macNoneFrameSplits.Length != 6) return false;
  576. foreach (var item in macNoneFrameSplits)
  577. {
  578. if (item.Length != 2) return false;
  579. foreach (var c in item.ToCharArray())
  580. if (Array.IndexOf(validChars, c) < 3) return false;
  581. }
  582. return true;
  583. }
  584. #region 记录的设备处理部分
  585. //连接时候判断信息。存在对象则连接需要判断MAC
  586. //记录一个设备
  587. AimDeviceInfo aimDeviceInfo = null;
  588. //用户初始化一个保存数据的操作的id。
  589. //不设置情况下不给进行相关操作
  590. string keyPrefix = "aim-device-info-";
  591. string userTags = "";
  592. int deviceId = -1;
  593. //清空对应id的数据
  594. public void onClearAimDeviceInfoByDeviceId(string _userTags, int _deviceId)
  595. {
  596. string deviceInfo = PlayerPrefs.GetString(keyPrefix + _userTags + _deviceId, "");
  597. if (deviceInfo != "") {
  598. PlayerPrefs.DeleteKey(keyPrefix + _userTags + _deviceId);
  599. ResetAimDeviceInfoToNull();
  600. }
  601. }
  602. public AimDeviceInfo onGetAimDeviceInfos(string _userTags, int _deviceId)
  603. {
  604. OnGetAimDeviceInfo(_userTags, _deviceId);
  605. //SmartBowLogger.Log(this, $"onGetAimDeviceInfos[{JsonUtility.ToJson(aimDeviceInfo)}]");
  606. return aimDeviceInfo;
  607. }
  608. //根据设置的
  609. void OnGetAimDeviceInfo(string _userTags, int _deviceId)
  610. {
  611. string deviceInfo = PlayerPrefs.GetString(keyPrefix + _userTags + _deviceId, "");
  612. if (deviceInfo != "")
  613. {
  614. aimDeviceInfo = JsonUtility.FromJson<AimDeviceInfo>(deviceInfo);//这里的类是依据最外层{}决定的
  615. }
  616. }
  617. void OnSaveAimDeviceInfo(string _userTags, int _deviceId)
  618. {
  619. if (_userTags.Length == 0)
  620. {
  621. SmartBowLogger.LogError(this, $"存储标识不存在!");
  622. return;
  623. }
  624. SmartBowLogger.Log(this, $"OnSaveAimDeviceInfo [{JsonUtility.ToJson(aimDeviceInfo)}]");
  625. PlayerPrefs.SetString(keyPrefix + _userTags + _deviceId, JsonUtility.ToJson(aimDeviceInfo));
  626. }
  627. //连接蓝牙调用。连接时候创建一个连接信息,用于记录mac 是否要验证
  628. //传入一个id用于区分是哪个设备
  629. //bRecreateDeviceInfo 是否重新创建
  630. public void initAimDeviceInfo(string _userTags, int _deviceId, bool bRecreateDeviceInfo)
  631. {
  632. userTags = _userTags;
  633. deviceId = _deviceId;
  634. if (bRecreateDeviceInfo)
  635. {
  636. //直接覆盖设备信息
  637. onRecreateAimDeviceInfoById();
  638. }
  639. else
  640. {
  641. //获取设备信息。没有创建
  642. onCreateAimDeviceInfoById();
  643. }
  644. }
  645. //是否存在AimDeviceInfo,存在获取,不存在创建;
  646. void onCreateAimDeviceInfoById()
  647. {
  648. ResetAimDeviceInfoToNull();
  649. OnGetAimDeviceInfo(userTags, deviceId);
  650. if (aimDeviceInfo == null)
  651. {
  652. aimDeviceInfo = new AimDeviceInfo(deviceId);
  653. OnSaveAimDeviceInfo(userTags, deviceId);
  654. }
  655. }
  656. //直接覆盖新元素
  657. void onRecreateAimDeviceInfoById()
  658. {
  659. // 使用Lambda表达式删除特定条件的元素
  660. ResetAimDeviceInfoToNull();
  661. //添加一个新元素
  662. aimDeviceInfo = new AimDeviceInfo(deviceId);
  663. //更新信息
  664. OnSaveAimDeviceInfo(userTags, deviceId);
  665. }
  666. //APP连接需进行MAC地址的比对。
  667. void SetAimDeviceMac(string _mac)
  668. {
  669. aimDeviceInfo.setInitMac(_mac);
  670. OnSaveAimDeviceInfo(userTags, deviceId);
  671. }
  672. public void ResetAimDeviceInfoToNull()
  673. {
  674. aimDeviceInfo = null;
  675. }
  676. #endregion
  677. }
  678. #region 添加一个记录设备连接的信息,主要用于判断mac地址是否连接操作
  679. [Serializable]//需要在转换为json格式的类的上方添加序列化
  680. public class AimDeviceInfo
  681. {
  682. public int id; //区分用户设备对应的id
  683. public bool bInitMac = false; //是否初始化Mac
  684. public string mac; //记录当前
  685. public AimDeviceInfo(int _id)
  686. {
  687. this.id = _id;
  688. }
  689. public void setInitMac(string macTemp)
  690. {
  691. bInitMac = true;
  692. mac = macTemp;
  693. }
  694. public void resetInitMac()
  695. {
  696. bInitMac = false;
  697. mac = "";
  698. }
  699. }
  700. #endregion
  701. }