BluetoothAim.cs 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  1. using ArduinoBluetoothAPI;
  2. using System;
  3. using UnityEngine;
  4. using System.Collections.Generic;
  5. using UnityEngine.UI;
  6. using DG.Tweening;
  7. using SmartBowSDK;
  8. using System.Collections;
  9. using UnityEngine.SceneManagement;
  10. using BleWinHelper = SmartBowSDK_BleWinHelper.BleWinHelper;
  11. /* 蓝牙瞄准模块 */
  12. /* 管理1p和2p蓝牙连接,脚本外调用逻辑如果同时连接1p和2p设备,以前的逻辑还是以1p为主,如果只连2p,则使用2p数据*/
  13. public class BluetoothAim : MonoBehaviour
  14. {
  15. #region 2p蓝牙使用的是sdk,所以需要另外定义
  16. //2p时候过滤的名字
  17. readonly string targetDeviceName2P = "Bbow_20210501 | HOUYI Pro | Pistol | Pistol M9 | ARTEMIS Pro | Pistol M17 | Rifle M416";
  18. #endregion
  19. #region 弓箭蓝牙模块基本信息
  20. readonly string targetDeviceNameAxis = "Bbow_20210501 | ARTEMIS | HOUYI";
  21. readonly string targetDeviceName = "Bbow_20210501 | ARTEMIS Pro";//HOUYI Pro
  22. readonly string targetDeviceNameHOUYIPro = "HOUYI Pro";
  23. readonly string targetDeviceNameGun = "Pistol | Pistol M9 | Bbow_20210501";
  24. readonly string targetDeviceNameGun_M17 = "Pistol M17";
  25. readonly string targetDeviceNameGun_M416 = "Rifle M416";
  26. string targetDeviceService
  27. {
  28. get
  29. {
  30. if (CommonConfig.devicePlan == 0 || CommonConfig.devicePlan == 3)
  31. {
  32. #if UNITY_ANDROID
  33. return "0000fff0";
  34. #else
  35. return "fff0";
  36. #endif
  37. }
  38. return "6e400001";
  39. }
  40. }
  41. string targetDeviceCharacteristicWrite
  42. {
  43. get
  44. {
  45. if (CommonConfig.devicePlan == 0 || CommonConfig.devicePlan == 3)
  46. {
  47. #if UNITY_ANDROID
  48. return "0000fff2";
  49. #else
  50. return "fff2";
  51. #endif
  52. }
  53. return "6e400002";
  54. }
  55. }
  56. string targetDeviceCharacteristicNotify
  57. {
  58. get
  59. {
  60. if (CommonConfig.devicePlan == 0 || CommonConfig.devicePlan == 3)
  61. {
  62. #if UNITY_ANDROID
  63. return "0000fff1";
  64. #else
  65. return "fff1";
  66. #endif
  67. }
  68. return "6e400003";
  69. }
  70. }
  71. #endregion
  72. //当前选择的设备
  73. BluetoothPlayer currentBLEPlayer = BluetoothPlayer.FIRST_PLAYER;
  74. //1p蓝牙连接
  75. BluetoothHelper bluetoothHelper;
  76. BluetoothHelperCharacteristic characteristicWrite;
  77. BluetoothHelperService bluetoothService;
  78. string deviceName = "";
  79. bool canConnect = true;
  80. public BluetoothStatusEnum status = BluetoothStatusEnum.Connect;
  81. int dataCount = 0;
  82. public bool hasData = false;
  83. public long hasDataTime;
  84. public static bool scanLock = false; //防止同时扫描冲突
  85. public static BluetoothAim ins;
  86. //根据设备情况来看是否需要解密,目前就是枪需要进行解密操作
  87. public bool NeedDecryption = false;
  88. public BluetoothWindows firstBluetoothWindows { get; set; }
  89. //首页初始化时候调用一次连接
  90. public bool bStartConnect = false;
  91. void Start()
  92. {
  93. ins = this;
  94. InitAutoDormancy();
  95. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  96. // new GameObject("BleUDP").AddComponent<BleUDP>();
  97. firstBluetoothWindows = new BluetoothWindows();
  98. firstBluetoothWindows.OnConnected = OnConnected_windows1;
  99. firstBluetoothWindows.OnConnectionFailed = OnConnectionFailed_windows1;
  100. firstBluetoothWindows.OnCharacteristicChanged = OnCharacteristicChanged_windows1;
  101. //window蓝牙连接
  102. if (currentBLEPlayer == BluetoothPlayer.FIRST_PLAYER)
  103. {
  104. Debug.Log("FIRST_PLAYER BleWinHelper.RegisterTo");
  105. BleWinHelper.RegisterTo(gameObject, firstBluetoothWindows, "1P");
  106. }
  107. #endif
  108. }
  109. void OnDestroy()
  110. {
  111. //删除ble。1p,2p 都删除
  112. DisconnectBleHelper();
  113. DisconnectSmartBowHelper2P();
  114. }
  115. /// <summary>
  116. /// 首页初始化的时候,如果是第一次。尝试连接蓝牙。只进行一次
  117. /// </summary>
  118. public void HomeViewConnectBLE()
  119. {
  120. if (bStartConnect) return;
  121. bStartConnect = true;
  122. //当已经连接过一把弓(1P)时,下一次打开 APP,1P 就自动处于连接的状态;用户只要打1.开 APP 和打开模块就可以自动连接,减少连接设备的操作。
  123. Debug.Log("[初始化自动连接蓝牙] 自动开始连接上一次连接的设备 1P?");
  124. AimHandler.ins.OnGetAimDeviceInfos();
  125. if (AimHandler.ins.aimDeviceInfos.arry.Count != 0)
  126. {
  127. //如果需要连接
  128. if (status != BluetoothStatusEnum.ConnectSuccess)
  129. {
  130. //setBLEPlayer(BluetoothPlayer.FIRST_PLAYER);
  131. Debug.Log("[初始化自动连接蓝牙] 当前选择的操作用户:" + getBLEPlayer());
  132. //AimHandler.ins.SetAimDeviceSelectIndex(0);
  133. //第一次进入从存储的资料获取 aimDeviceInfo
  134. AimHandler.ins.onCreateAimDeviceInfoById();
  135. DoConnect();
  136. }
  137. }
  138. }
  139. private bool userDoConnect = false;
  140. private bool doConnect = false;
  141. public Func<bool> action_DoConnectInterceptor;
  142. public void DoConnect()
  143. {
  144. if (action_DoConnectInterceptor != null)
  145. {
  146. if (action_DoConnectInterceptor.Invoke()) return;
  147. }
  148. if (status == BluetoothStatusEnum.Connect)
  149. {
  150. connectCanceled = false;
  151. userDoConnect = true;
  152. doConnect = true;
  153. SetStatus(BluetoothStatusEnum.Connecting);
  154. }
  155. else if (status == BluetoothStatusEnum.ConnectSuccess)
  156. {
  157. userDoConnect = false;
  158. doConnect = false;
  159. OnDisconnect();
  160. DisconnectBleHelper();
  161. }
  162. }
  163. //连接取消,退回登录时需要取消连接(扫描)
  164. [NonSerialized] public bool connectCanceled = false;
  165. void OnDisconnect()
  166. {
  167. curMac = null;
  168. dataCount = 0;
  169. hasData = false;
  170. canConnect = true;
  171. SetStatus(BluetoothStatusEnum.ConnectFail);
  172. BowCamera.isTouchMode = true;
  173. DestroyWhenDisconenct();
  174. }
  175. void Update()
  176. {
  177. updateSmartBowHelper2P();
  178. if (userDoConnect && status == BluetoothStatusEnum.Connect)
  179. {
  180. DoConnect();
  181. }
  182. if (doConnect) Connect();
  183. }
  184. void SetStatus(BluetoothStatusEnum statusValue)
  185. {
  186. status = statusValue;
  187. if (status == BluetoothStatusEnum.ConnectFail)
  188. {
  189. Sequence sequence = DOTween.Sequence();
  190. sequence.AppendInterval(2f);
  191. sequence.AppendCallback(delegate ()
  192. {
  193. if (status == BluetoothStatusEnum.ConnectFail)
  194. {
  195. status = BluetoothStatusEnum.Connect;
  196. }
  197. });
  198. sequence.SetUpdate(true);
  199. SimulateMouseController.ins?.SetBleConnected(false);
  200. }
  201. else if (status == BluetoothStatusEnum.ConnectSuccess)
  202. {
  203. SimulateMouseController.ins?.SetBleConnected(true);
  204. }
  205. }
  206. void DisconnectBleHelper()
  207. {
  208. if (BluetoothWindows.IsWindows())
  209. {
  210. if (firstBluetoothWindows.Disconnect())
  211. SetStatus(BluetoothStatusEnum.Connect);
  212. return;
  213. }
  214. if (bluetoothHelper != null) bluetoothHelper.Disconnect();
  215. }
  216. void DisconnectSmartBowHelper2P()
  217. {
  218. //2p
  219. if (smartBowHelper2P != null) smartBowHelper2P.Disconnect();
  220. }
  221. void Connect()
  222. {
  223. if (!canConnect)
  224. {
  225. return;
  226. }
  227. doConnect = false;
  228. doConnect2P = false;
  229. scanLock = true;
  230. canConnect = false;
  231. _scanCanRetryCount = 4;
  232. SetStatus(BluetoothStatusEnum.Connecting);
  233. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  234. firstBluetoothWindows.Connect();
  235. #else
  236. ConnectBleHelper();
  237. #endif
  238. }
  239. int _scanCanRetryCount = 4;
  240. void ConnectBleHelper()
  241. {
  242. #if UNITY_ANDROID
  243. PopupMgr.ins.ClearAllTip();
  244. if (BluetoothHelperAndroid.IsBluetoothEnabled() == false)
  245. {
  246. Debug.Log("BluetoothHelperAndroid.IsBluetoothEnabled():" + BluetoothHelperAndroid.IsBluetoothEnabled());
  247. HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-exception1"));
  248. return;
  249. }
  250. if (BluetoothHelperAndroid.RequestBluetoothPermissions(ConnectBleHelper, (permission) =>
  251. {
  252. Debug.Log("permission ==== :" + permission);
  253. if (permission.Contains("LOCATION"))
  254. {
  255. HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-exception2"));
  256. }
  257. else if (permission.Contains("BLUETOOTH"))
  258. {
  259. HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-exception3"));
  260. }
  261. })) return;
  262. #endif
  263. try
  264. {
  265. BluetoothHelper.BLE = true;
  266. bluetoothHelper = BluetoothHelper.GetNewInstance();
  267. bluetoothHelper.OnConnected += (BluetoothHelper helper) =>
  268. {
  269. Log("连接成功\n" + helper.getDeviceName());
  270. SetStatus(BluetoothStatusEnum.ConnectSuccess);
  271. SetMainConnectDeviceType();
  272. if (connectCanceled)
  273. {
  274. Debug.Log("ble connectCanceled");
  275. DoConnect();
  276. return;
  277. }
  278. BowCamera.isTouchMode = false;
  279. foreach (BluetoothHelperService service in helper.getGattServices())
  280. {
  281. if (service.getName().ToLower().StartsWith(targetDeviceService))
  282. {
  283. bluetoothService = service;
  284. foreach (BluetoothHelperCharacteristic characteristic in service.getCharacteristics())
  285. {
  286. if (characteristic.getName().ToLower().StartsWith(targetDeviceCharacteristicWrite))
  287. {
  288. characteristicWrite = characteristic;
  289. }
  290. else if (characteristic.getName().ToLower().StartsWith(targetDeviceCharacteristicNotify))
  291. {
  292. BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristic.getName());
  293. ch.setService(bluetoothService.getName());
  294. bluetoothHelper.Subscribe(ch);
  295. }
  296. }
  297. }
  298. }
  299. if (CommonConfig.EnableDecryption && NeedDecryption)
  300. {
  301. // 这里验证指令,开始请求授权
  302. // 启动轮询协程
  303. StartCoroutine(PollingCoroutine());
  304. }
  305. else
  306. {
  307. //除了pc,Android 直接连接
  308. CallDelay(2, () =>
  309. {
  310. if (status != BluetoothStatusEnum.ConnectSuccess) return;
  311. InitWhenConenct();
  312. });
  313. }
  314. };
  315. bluetoothHelper.OnConnectionFailed += (BluetoothHelper helper) =>
  316. {
  317. Log("连接失败\n" + helper.getDeviceName());
  318. OnDisconnect();
  319. };
  320. bluetoothHelper.OnCharacteristicChanged += (helper, value, characteristic) =>
  321. {
  322. OnCharacteristicChanged(helper, value, characteristic);
  323. };
  324. bluetoothHelper.OnScanEnded += (BluetoothHelper helper, LinkedList<BluetoothDevice> nearbyDevices) =>
  325. {
  326. scanLock = false;
  327. if (connectCanceled)
  328. {
  329. userDoConnect = false;
  330. canConnect = true;
  331. status = BluetoothStatusEnum.Connect;
  332. Debug.Log("ble connectCanceled");
  333. return;
  334. }
  335. foreach (BluetoothDevice device in nearbyDevices)
  336. {
  337. Log("发现设备 " + device.DeviceName);
  338. //if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.HOUYIPRO)
  339. //{ //需要判断是否是红外弓箭
  340. // //targetDeviceNameHOUYIPro targetDeviceNameHOUYIPro{ HOUYI Pro }
  341. // if (targetDeviceNameHOUYIPro.Contains(device.DeviceName))
  342. // {
  343. // BLEConnectByName(device.DeviceName);
  344. // Log("匹配HOUYIPRO设备 " + device.DeviceName);
  345. // return;
  346. // }
  347. //}
  348. //else if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.ARTEMISPRO)
  349. //{ //需要判断是否是ARTEMISPro弓箭
  350. // if (targetDeviceName.Contains(device.DeviceName))
  351. // {
  352. // BLEConnectByName(device.DeviceName);
  353. // Log("匹配ARTEMISPro设备 " + device.DeviceName);
  354. // return;
  355. // }
  356. //}
  357. //else if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.Gun ||
  358. // AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.PistolM17 ||
  359. // AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.RifleM416)
  360. //{
  361. // //需要判断是否是枪
  362. // if (targetDeviceNameGun.Contains(device.DeviceName))
  363. // {
  364. // BLEConnectByName(device.DeviceName);
  365. // Log("匹配枪设备 " + device.DeviceName);
  366. // return;
  367. // }
  368. //}
  369. if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.HOUYIPRO)
  370. { //需要判断是否是红外弓箭
  371. if (TryConnectDevice(targetDeviceNameHOUYIPro, device.DeviceName, "HOUYIPRO")) return;
  372. }
  373. else if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.ARTEMISPRO)
  374. { //需要判断是否是ARTEMISPro弓箭
  375. if (TryConnectDevice(targetDeviceName, device.DeviceName, "ARTEMISPRO")) return;
  376. }
  377. else if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.Gun)
  378. {
  379. if (TryConnectDevice(targetDeviceNameGun, device.DeviceName, "Pistol")) return;
  380. }
  381. else if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.PistolM17)
  382. {
  383. if (TryConnectDevice(targetDeviceNameGun_M17, device.DeviceName, "PistolM17")) return;
  384. }
  385. else if (AimHandler.ins.aimDeviceInfo.type == (int)AimDeviceType.RifleM416)
  386. {
  387. if (TryConnectDevice(targetDeviceNameGun_M416, device.DeviceName, "RifleM416")) return;
  388. }
  389. else
  390. { //其余的九轴连接
  391. //不允许匹配HOUYIPRO,因为这个没有九轴 targetDeviceName { Bbow_20210501 }
  392. //if (targetDeviceName.Contains(device.DeviceName))
  393. //{
  394. // BLEConnectByName(device.DeviceName);
  395. // Log("匹配普通设备设备 " + device.DeviceName);
  396. // return;
  397. //}
  398. if (TryConnectDevice(targetDeviceNameAxis, device.DeviceName, device.DeviceName)) return;
  399. }
  400. }
  401. if (_scanCanRetryCount > 0)
  402. {
  403. _scanCanRetryCount--;
  404. scanLock = true;
  405. ConnectBleHelper();
  406. }
  407. else
  408. {
  409. userDoConnect = false;
  410. canConnect = true;
  411. Log("没有发现设备");
  412. TextAutoLanguage2.GetTextByKey("ble-dev-notfound");
  413. SetStatus(BluetoothStatusEnum.ConnectFail);
  414. }
  415. };
  416. bluetoothHelper.ScanNearbyDevices();
  417. Log("正在扫描设备");
  418. }
  419. catch (Exception e)
  420. {
  421. Debug.LogError(e);
  422. HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-please-open-ble"));
  423. }
  424. }
  425. /// <summary>
  426. /// 精确匹配,大小写敏感,多设备名字用 " | " 分隔
  427. /// </summary>
  428. /// <param name="filterNames">过滤字符串</param>
  429. /// <param name="deviceName">真实连接名字</param>
  430. /// <param name="deviceTypeName">日志名字</param>
  431. /// <returns></returns>
  432. private bool TryConnectDevice(string filterNames, string deviceName, string deviceTypeName)
  433. {
  434. if (string.IsNullOrWhiteSpace(filterNames)) return false;
  435. string[] filterArray = filterNames.Split('|'); // 支持多个名字
  436. foreach (var f in filterArray)
  437. {
  438. if (string.Equals(f.Trim(), deviceName.Trim(), StringComparison.OrdinalIgnoreCase))
  439. {
  440. BLEConnectByName(deviceName);
  441. Log($"匹配设备 {deviceTypeName}: {deviceName}");
  442. return true;
  443. }
  444. }
  445. return false;
  446. }
  447. void BLEConnectByName(string name)
  448. {
  449. deviceName = name;
  450. bluetoothHelper.setDeviceName(deviceName);
  451. bluetoothHelper.Connect();
  452. }
  453. void HandleConnectException(string errorText)
  454. {
  455. scanLock = false;
  456. canConnect = true;
  457. // SetStatus(BluetoothStatusEnum.ConnectFail);
  458. status = BluetoothStatusEnum.Connect;
  459. userDoConnect = false;
  460. PopupMgr.ins.ShowTip(errorText);
  461. }
  462. // 协程来处理轮询
  463. // 目前仅手枪支持该指令。
  464. // 调用 AUTHOR_SendReq 方法,传递系统Tick值(在这里用一个示例值)
  465. private bool isPolling = false;
  466. private int PollingCoroutineCount = 4;
  467. private IEnumerator PollingCoroutine()
  468. {
  469. // 发送请求
  470. // SendEncrypt();
  471. // 设置轮询标志
  472. isPolling = true;
  473. PollingCoroutineCount = 4;
  474. uint systemTick = (uint)DateTime.Now.Ticks;
  475. while (isPolling)
  476. {
  477. // 等待一秒
  478. yield return new WaitForSeconds(1f);
  479. SendEncrypt(systemTick);
  480. PollingCoroutineCount--;
  481. }
  482. }
  483. /// <summary>
  484. /// 1、加密字节由系统生成的随机码加密而成;
  485. /// 2、蓝牙每次断开并重新连接后,会重新生成随机加密值;
  486. /// 3、当设备未发送正确的解密信息时,APP会每秒发送1次请求,直到解密成功。
  487. /// </summary>
  488. /// <param name="systemTick"></param>
  489. private void SendEncrypt(uint systemTick)
  490. {
  491. byte[] sendByte = BluetoothDecryptor.AUTHOR_SendReq(systemTick);
  492. Debug.Log("请求sendByte:" + BitConverter.ToString(sendByte));
  493. WriteByteData(sendByte);
  494. }
  495. // 模拟从硬件读取数据
  496. public void StopEncrypt()
  497. {
  498. isPolling = false;
  499. }
  500. #region 自动进入/退出休眠状态, 这里做程指令发送队列,为了控制连续发送指令的间隔,避免硬件收不到或处理不过来
  501. class CmdToSend
  502. {
  503. public string[] cmds;
  504. public Action onComplete;
  505. public Func<bool> canDo;
  506. public CmdToSend(string[] cmds, Action onComplete, Func<bool> canDo)
  507. {
  508. this.cmds = cmds;
  509. this.onComplete = onComplete;
  510. this.canDo = canDo;
  511. }
  512. }
  513. Queue<CmdToSend> cmdWaitingList = new Queue<CmdToSend>();
  514. bool isSendCmdLocked = false;
  515. bool canAutoDormancy = false;
  516. bool isStartUp = false;
  517. JCUnityLib.CountLock needModularAwake = new JCUnityLib.CountLock();
  518. void CheckAndStartUp()
  519. {
  520. if (needModularAwake.IsLocked())
  521. {
  522. StartUp();
  523. }
  524. else
  525. {
  526. Dormancy();
  527. }
  528. }
  529. void InitAutoDormancy()
  530. {
  531. // GlobalEventCenter.ins.onGameSceneLoad += () => {
  532. // needModularAwake.Lock();
  533. // CheckAndStartUp();
  534. // };
  535. // GlobalEventCenter.ins.onGameSceneDestroy += () => {
  536. // needModularAwake.Unlock();
  537. // CheckAndStartUp();
  538. // };
  539. // GlobalEventCenter.ins.onSimulateMouseAwakeChanged += (waked) => {
  540. // if (waked) needModularAwake.Lock();
  541. // else needModularAwake.Unlock();;
  542. // CheckAndStartUp();
  543. // };
  544. // GlobalEventCenter.ins.onDeviceCalibrateViewAwakeChanged += (waked) => {
  545. // if (waked) needModularAwake.Lock();
  546. // else needModularAwake.Unlock();;
  547. // CheckAndStartUp();
  548. // };
  549. //暂时关闭自动休眠,默认是需要模块保持激活
  550. needModularAwake.Lock();
  551. }
  552. void InitWhenConenct()
  553. {
  554. canAutoDormancy = true;
  555. List<string> cmds = new List<string>();
  556. cmds.Add("M"); //获取Mac地址
  557. cmds.Add("I"); //获取设备信息
  558. cmds.Add("b"); //确保开启stm32
  559. cmds.Add("b"); //获取初始电量
  560. cmds.Add("1"); //开启发送逻辑
  561. Action onComplete = null;
  562. if (needModularAwake.IsLocked())
  563. {
  564. cmds.Add("w"); //红外灯开启
  565. cmds.Add("3"); //九轴开启
  566. onComplete = () =>
  567. {
  568. isStartUp = true;
  569. };
  570. }
  571. else
  572. {
  573. cmds.Add("s"); //红外灯关闭
  574. cmds.Add("S"); //Stm32关闭
  575. cmds.Add("4"); //九轴关闭
  576. onComplete = () =>
  577. {
  578. isStartUp = false;
  579. };
  580. }
  581. SendCDM(null, onComplete, cmds.ToArray());
  582. }
  583. void DestroyWhenDisconenct()
  584. {
  585. canAutoDormancy = false;
  586. sendCMD_CheckAndDoStop(null);
  587. }
  588. //启动
  589. void StartUp()
  590. {
  591. SendCDM(() =>
  592. {
  593. return !isStartUp;
  594. }, () =>
  595. {
  596. isStartUp = true;
  597. }, "b", "w", "3");
  598. }
  599. //休眠
  600. void Dormancy()
  601. {
  602. SendCDM(() =>
  603. {
  604. return isStartUp;
  605. }, () =>
  606. {
  607. isStartUp = false;
  608. }, "4", "s", "S");
  609. }
  610. void SendCDM(Func<bool> canDo, Action onComplete, params string[] cmds)
  611. {
  612. CmdToSend cmdToSend = new CmdToSend(cmds, onComplete, canDo);
  613. if (isSendCmdLocked)
  614. {
  615. cmdWaitingList.Enqueue(cmdToSend);
  616. return;
  617. }
  618. sendCMD_NotCheck(cmdToSend);
  619. }
  620. void sendCMD_NotCheck(CmdToSend cmdToSend)
  621. {
  622. if (cmdToSend.canDo != null && !cmdToSend.canDo.Invoke())
  623. {
  624. sendCMD_CheckNext();
  625. return;
  626. }
  627. isSendCmdLocked = true;
  628. Sequence sequence = DOTween.Sequence();
  629. sequence.PrependInterval(0.3f);
  630. foreach (var cmd in cmdToSend.cmds)
  631. {
  632. sequence.AppendCallback(() =>
  633. {
  634. bool stopped = sendCMD_CheckAndDoStop(sequence);
  635. if (!stopped) WriteData(cmd);
  636. });
  637. sequence.AppendInterval(0.5f);
  638. }
  639. sequence.AppendCallback(() =>
  640. {
  641. bool stopped = sendCMD_CheckAndDoStop(sequence);
  642. if (!stopped)
  643. {
  644. isSendCmdLocked = false;
  645. cmdToSend.onComplete?.Invoke();
  646. sendCMD_CheckNext();
  647. }
  648. });
  649. sequence.SetUpdate(true);
  650. }
  651. void sendCMD_CheckNext()
  652. {
  653. if (cmdWaitingList.Count <= 0) return;
  654. CmdToSend cmdToSend = cmdWaitingList.Dequeue();
  655. sendCMD_NotCheck(cmdToSend);
  656. }
  657. bool sendCMD_CheckAndDoStop(Sequence sequence)
  658. {
  659. if (canAutoDormancy) return false;
  660. isStartUp = false;
  661. isSendCmdLocked = false;
  662. cmdWaitingList.Clear();
  663. if (sequence != null) sequence.Kill();
  664. return true;
  665. }
  666. #endregion
  667. public void RequestBattery()
  668. {
  669. if (!isStartUp) return;
  670. if (isSendCmdLocked) return;
  671. WriteData("b");
  672. }
  673. /// <summary>
  674. /// 获取设备信息 手枪、HOUYI Pro 和 ARTEMIS Pro
  675. /// </summary>
  676. public void RequestDeviceInfo()
  677. {
  678. if (isSendCmdLocked) return;
  679. WriteData("I");
  680. }
  681. /// <summary>
  682. /// 旧的红外射箭指令
  683. /// </summary>
  684. public void ReplyInfraredShoot()
  685. {
  686. if (isSendCmdLocked) return;
  687. WriteData("I");
  688. }
  689. void CallDelay(float delayTime, TweenCallback callback)
  690. {
  691. Sequence sequence = DOTween.Sequence();
  692. sequence.PrependInterval(delayTime).AppendCallback(callback);
  693. sequence.SetUpdate(true);
  694. }
  695. public void WriteData(string data)
  696. {
  697. //Debug.Log("WriteData:" + data);
  698. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  699. //BleUDP.ins.SendMsg(data);
  700. firstBluetoothWindows.Write(data);
  701. #else
  702. if (DebugDeviceCMD.ins) DebugDeviceCMD.ins.ShowCMD(data);
  703. BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristicWrite.getName());
  704. ch.setService(bluetoothService.getName());
  705. bluetoothHelper.WriteCharacteristic(ch, data);
  706. #endif
  707. }
  708. public void WriteByteData(byte[] data)
  709. {
  710. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  711. firstBluetoothWindows.WriteByte(data);
  712. #else
  713. BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristicWrite.getName());
  714. ch.setService(bluetoothService.getName());
  715. bluetoothHelper.WriteCharacteristic(ch, data);
  716. #endif
  717. }
  718. void Log(string text)
  719. {
  720. Debug.Log(string.Format("[{0}]{1}", typeof(BluetoothAim).Name, text));
  721. }
  722. [NonSerialized] public string curMac;
  723. void UploadMacAddress(byte[] bytes)
  724. {
  725. string mac = System.Text.Encoding.ASCII.GetString(bytes);
  726. if (mac != null) mac = mac.Trim();
  727. if (CheckIsMacValid(mac))
  728. {
  729. SideTipView.ShowTip("Mac获取成功:" + mac, Color.white);
  730. //需要增加一个判断,判断是否对应的mac设备。不是需要进行重新连接
  731. if (!AimHandler.ins.aimDeviceInfo.bInitMac)
  732. {
  733. Debug.Log("设置设备mac:" + mac);
  734. AimHandler.ins.SetAimDeviceMac(mac);
  735. }
  736. else if (AimHandler.ins.aimDeviceInfo.mac != mac)
  737. {
  738. Debug.Log("设备不一样,断开连接");
  739. DoConnect();
  740. //延迟一点时间后重新触发扫描
  741. CallDelay(4, () =>
  742. {
  743. Debug.Log("CallDelay 重新连接");
  744. DoConnect();
  745. });
  746. return;
  747. }
  748. curMac = mac;
  749. LoginMgr.myUserInfo.mac = mac;
  750. UserComp.Instance.saveMac();
  751. }
  752. //else {
  753. // SideTipView.ShowTip("Mac获取失败", Color.yellow);
  754. //}
  755. }
  756. bool CheckIsMacValid(string mac)
  757. {
  758. if (mac == null) return false;
  759. if (!mac.StartsWith("{")) return false;
  760. if (!mac.EndsWith("}")) return false;
  761. if (!mac.Contains(":")) return false;
  762. char[] validChars = { '{', '}', ':', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  763. foreach (var c in mac.ToCharArray())
  764. {
  765. if (Array.IndexOf(validChars, c) == -1) return false;
  766. }
  767. if (mac.Length != 19) return false;
  768. string macNoneFrame = mac.Substring(1, mac.Length - 2);
  769. string[] macNoneFrameSplits = macNoneFrame.Split(':');
  770. if (macNoneFrameSplits.Length != 6) return false;
  771. foreach (var item in macNoneFrameSplits)
  772. {
  773. if (item.Length != 2) return false;
  774. foreach (var c in item.ToCharArray())
  775. if (Array.IndexOf(validChars, c) < 3) return false;
  776. }
  777. return true;
  778. }
  779. #region 1p蓝牙部分,使用了SmartBowSDK (修改项目1p使用的蓝牙。统一使用sdk,后续方便管理)
  780. //1p蓝牙连接 使用 SmartBowSDK
  781. SmartBowHelper smartBowHelper1P;
  782. #endregion
  783. #region 2p蓝牙部分,使用了SmartBowSDK
  784. //2p蓝牙连接 使用 SmartBowSDK
  785. SmartBowHelper smartBowHelper2P;
  786. //陀螺仪校准进度
  787. public int smartBowHelper2_Progress { get => (int)(smartBowHelper2P.GetGyrProgress() * 100); }
  788. bool doConnect2P = false;
  789. bool userDoConnect2P = false;
  790. int _scanCanRetryCount2P = 4;
  791. bool canConnect2P = true;
  792. public bool bNoNeedToReconnect { get; set; } = true;//是否需要重连
  793. bool lerpForRotation2P = true;
  794. float lerpTimeRate2P = 7;
  795. private Quaternion newRotation2P = Quaternion.identity;
  796. //数据存储标识
  797. string userTags = "smartbow";
  798. int deviceId2 = 2;
  799. public void onCreateSmartBowHelper2P()
  800. {
  801. smartBowHelper2P = SmartBowHelper.NewInstance();
  802. smartBowHelper2P.SetFilters(targetDeviceName2P);
  803. smartBowHelper2P.OnBluetoothModuleInited += () =>
  804. {
  805. Debug.Log("OnBluetoothModuleInited");
  806. //判断是否是同一个mac
  807. //需要增加一个判断,判断是否对应的mac设备。不是需要进行重新连接
  808. string mac = smartBowHelper2P.GetMacAddress();
  809. if (!AimHandler.ins.aimDeviceInfo.bInitMac)
  810. {
  811. Debug.Log("smartBowHelper2P 设置设备mac:" + mac);
  812. AimHandler.ins.SetAimDeviceMac(mac);
  813. }
  814. else if (AimHandler.ins.aimDeviceInfo.mac != mac)
  815. {
  816. Debug.Log("设备不一样,断开连接");
  817. DoConnect2P();
  818. //延迟一点时间后重新触发扫描
  819. CallDelay(4, () =>
  820. {
  821. Debug.Log("CallDelay 重新连接");
  822. DoConnect2P();
  823. });
  824. return;
  825. }
  826. UpdateConnectText();
  827. smartBowHelper2P.StartRotationSensor();
  828. smartBowHelper2P.StartShootingSensor();
  829. //if (SB_EventSystem.ins)
  830. //{
  831. // //唤起/隐藏虚拟鼠标
  832. // SB_EventSystem.ins.AwakenSimulateMouse();
  833. //}
  834. };
  835. smartBowHelper2P.OnBluetoothError += (error, message) =>
  836. {
  837. Debug.Log("smartBowHelper2P error:" + error);
  838. if (error == BluetoothError.ScanNotFoundTargetDevice)
  839. {
  840. scanLock = false;
  841. PopupMgr.ins.ShowTip("连接失败,未发现目标设备!");
  842. if (_scanCanRetryCount2P > 0)
  843. {
  844. _scanCanRetryCount2P--;
  845. scanLock = true;
  846. ConnectSmartBowHelper2P();
  847. }
  848. else
  849. {
  850. userDoConnect2P = false;
  851. canConnect2P = true;
  852. Log("没有发现设备");
  853. TextAutoLanguage2.GetTextByKey("ble-dev-notfound");
  854. }
  855. return;
  856. }
  857. PopupMgr.ins.ShowTip(message);
  858. };
  859. smartBowHelper2P.OnBluetoothStatusChanged += (oldStatus, newStatus) =>
  860. {
  861. UpdateConnectText();
  862. };
  863. smartBowHelper2P.OnRotationUpdate += (r) =>
  864. {
  865. newRotation2P = r;
  866. //GameController.ins.aimCrossHairs[playerIndex].UpdatePositionByModuleRotation(r);
  867. //if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) SB_EventSystem.ins.MoveSimulateMouse(r);
  868. };
  869. smartBowHelper2P.OnShooting += OnShot2P;
  870. smartBowHelper2P.OnFunctionKeyPress += () =>
  871. {
  872. //如果是双人场景,触发提示
  873. if (SceneManager.GetActiveScene().name == "GameDouble")
  874. {
  875. if (GameObject.Find("AutoResetViewNewRight")) return;
  876. GameObject resetView = Instantiate(Resources.Load<GameObject>("AutoResetViewNew"));
  877. resetView.name = "AutoResetViewNewRight";
  878. AutoResetViewNew autoResetViewNewScript = resetView.GetComponent<AutoResetViewNew>();
  879. autoResetViewNewScript.setPosRight();
  880. autoResetViewNewScript.action_OnDestroy += () =>
  881. {
  882. smartBowHelper2P.ResetAim();
  883. };
  884. }
  885. else if (SceneManager.GetActiveScene().name == "InfraredGameDouble" || SceneManager.GetActiveScene().name == "WildAttackDouble")
  886. {
  887. if (GameObject.Find("AutoResetViewNewRight")) return;
  888. GameObject resetView = Instantiate(Resources.Load<GameObject>("AutoResetViewNew"));
  889. resetView.name = "AutoResetViewNewRight";
  890. AutoResetViewNew autoResetViewNewScript = resetView.GetComponent<AutoResetViewNew>();
  891. autoResetViewNewScript.setTextKey("new-user-guider_tip_视角归位-瞄准-infraredD");
  892. autoResetViewNewScript.setPosRight();
  893. autoResetViewNewScript.action_OnDestroy += () =>
  894. {
  895. if (SceneManager.GetActiveScene().name == "InfraredGameDouble")
  896. {
  897. InfraredDemo._ins?.SetAdjustPointsOffset(PlayerType.SecondPlayer);
  898. }
  899. else if (SceneManager.GetActiveScene().name == "WildAttackDouble")
  900. {
  901. WildAttack.GameMananger.GetInstance().ResetAim(WildAttack.PlayerTypeEnum.Second);
  902. }
  903. };
  904. }
  905. //else if (SceneManager.GetActiveScene().name.Equals("WildAttackDouble"))
  906. //{
  907. // //双人场景直接校准2P
  908. // WildAttack.GameMananger.GetInstance().ResetAim(WildAttack.PlayerTypeEnum.Second);
  909. //}
  910. else
  911. {
  912. smartBowHelper2P.ResetAim();
  913. }
  914. };
  915. //#if UNITY_STANDALONE_WIN || UNITY_EDITOR
  916. // //用户2window连接 BluetoothWindows.IsWindows() &&
  917. // if (currentBLEPlayer == BluetoothPlayer.SECONDE_PLAYER)
  918. // {
  919. // Debug.Log("SECONDE_PLAYER BleWinHelper.RegisterTo");
  920. // BleWinHelper com = BleWinHelper.RegisterTo(smartBowHelper2P.gameObject, smartBowHelper2P.CreateBluetoothWindows(), "2P");
  921. // }
  922. //#endif
  923. }
  924. void OnShot2P(float speed)
  925. {
  926. if (SceneManager.GetActiveScene().name.Equals("WildAttackDouble"))
  927. {
  928. WildAttack.SmartBowController.Instance.OnShooting2P(speed);
  929. }
  930. else
  931. {
  932. if (GameController.ins.GetArmBowDoublePlayer(PlayerType.SecondPlayer) != null)
  933. {
  934. //本地双人模式下处理2P ,1P在 ShootCheck 类处理
  935. GameController.ins.GetArmBowDoublePlayer(PlayerType.SecondPlayer).ADS_fire(true, speed);
  936. }
  937. }
  938. }
  939. void UpdateConnectText()
  940. {
  941. var newStatus = smartBowHelper2P.GetBluetoothStatus();
  942. if (newStatus == SmartBowSDK.BluetoothStatusEnum.None)
  943. {
  944. if (GameController.ins)
  945. {
  946. GameController.ins.GetBowCameraDoublePlayer(PlayerType.SecondPlayer).isTouchMode = true;
  947. }
  948. Debug.Log("<color=blue>未连接</color>(点击连接)");
  949. if (!bNoNeedToReconnect) return;
  950. scanLock = false;
  951. if (_scanCanRetryCount2P > 0)
  952. {
  953. _scanCanRetryCount2P--;
  954. scanLock = true;
  955. ConnectSmartBowHelper2P();
  956. }
  957. else
  958. {
  959. userDoConnect2P = false;
  960. canConnect2P = true;
  961. Log("没有发现设备");
  962. PopupMgr.ins.ShowTip("连接失败,未发现目标设备!");
  963. TextAutoLanguage2.GetTextByKey("ble-dev-notfound");
  964. }
  965. }
  966. else if (newStatus == SmartBowSDK.BluetoothStatusEnum.Connecting)
  967. {
  968. Debug.Log("<color=#FF670D>连接中</color>");
  969. if (GameController.ins)
  970. {
  971. GameController.ins.GetBowCameraDoublePlayer(PlayerType.SecondPlayer).isTouchMode = false;
  972. }
  973. }
  974. else if (newStatus == SmartBowSDK.BluetoothStatusEnum.Connected)
  975. {
  976. if (GameController.ins)
  977. {
  978. GameController.ins.GetBowCameraDoublePlayer(PlayerType.SecondPlayer).isTouchMode = false;
  979. }
  980. if (smartBowHelper2P.IsBluetoothModuleInited()) Debug.Log("<color=green>已连接</color>(点击断开)");
  981. else Debug.Log("<color=green>已连接</color><color=blue>(正在初始化)</color>");
  982. }
  983. }
  984. public void ConnectSmartBowHelper2P()
  985. {
  986. if (smartBowHelper2P == null)
  987. {
  988. onCreateSmartBowHelper2P();
  989. CallDelay(1, () =>
  990. {
  991. smartBowHelper2P.Connect(userTags, deviceId2, true);//不在sdk 判断mac
  992. });
  993. }
  994. else
  995. {
  996. smartBowHelper2P.Connect(userTags, deviceId2, true);
  997. }
  998. }
  999. public void DoConnect2P()
  1000. {
  1001. Debug.Log("DoConnect2P");
  1002. if (smartBowHelper2P == null || smartBowHelper2P.GetBluetoothStatus() == SmartBowSDK.BluetoothStatusEnum.None)
  1003. {
  1004. //connectCanceled = false;
  1005. userDoConnect2P = true;
  1006. doConnect2P = true;
  1007. bNoNeedToReconnect = true;
  1008. Connect2P();
  1009. }
  1010. else if (smartBowHelper2P.GetBluetoothStatus() == SmartBowSDK.BluetoothStatusEnum.Connected)
  1011. {
  1012. userDoConnect2P = false;
  1013. doConnect2P = false;
  1014. canConnect2P = true;
  1015. DisconnectSmartBowHelper2P();
  1016. }
  1017. }
  1018. void Connect2P()
  1019. {
  1020. //if (BluetoothShoot.scanLock)
  1021. //{
  1022. // return;
  1023. //}
  1024. if (!canConnect2P)
  1025. {
  1026. return;
  1027. }
  1028. doConnect = false;
  1029. doConnect2P = false;
  1030. scanLock = true;
  1031. canConnect2P = false;
  1032. _scanCanRetryCount2P = 4;
  1033. //SetStatus2P(BluetoothStatusEnum.Connecting);
  1034. ConnectSmartBowHelper2P();
  1035. }
  1036. //初始化陀螺仪
  1037. public void OnCalibrateGyr2P()
  1038. {
  1039. if (smartBowHelper2P.IsGyrCalibrating()) smartBowHelper2P.StopGyrCalibration();
  1040. else smartBowHelper2P.StartGyrCalibration();
  1041. }
  1042. //初始化地磁计
  1043. public void OnCalibrateMag2P()
  1044. {
  1045. smartBowHelper2P.StartMagCalibration();
  1046. }
  1047. #endregion
  1048. #region 当前选择操作的设备 如1p或者2p
  1049. public SmartBowHelper getSmartBowHelper2P()
  1050. {
  1051. return smartBowHelper2P;
  1052. }
  1053. public void setBLEPlayer(BluetoothPlayer blePlayer)
  1054. {
  1055. //切换蓝牙用户时候,判断是否正在连接,如果正在匹配连接的话,取消连接状态
  1056. if (blePlayer != currentBLEPlayer)
  1057. {
  1058. Debug.Log("Set BluetoothPlayer status:" + status);
  1059. onCancelAllConnecting();
  1060. }
  1061. currentBLEPlayer = blePlayer;
  1062. Debug.Log("Set BluetoothPlayer:" + currentBLEPlayer);
  1063. }
  1064. public BluetoothPlayer getBLEPlayer()
  1065. {
  1066. //Debug.Log("Get BluetoothPlayer:" + currentBLEPlayer);
  1067. return currentBLEPlayer;
  1068. }
  1069. //更新跟随点位置
  1070. public void UpdateCameraToLookNewPoint2P()
  1071. {
  1072. if (SceneManager.GetActiveScene().name != "InfraredGameDouble")
  1073. {
  1074. if (CameraToLookNew.ins != null)
  1075. {
  1076. Transform m_controlObj = CameraToLookNew.ins.transform;
  1077. if (lerpForRotation2P)
  1078. m_controlObj.localRotation = Quaternion.Lerp(m_controlObj.localRotation, newRotation2P, Time.deltaTime * lerpTimeRate2P);
  1079. else
  1080. m_controlObj.localRotation = newRotation2P;
  1081. }
  1082. }
  1083. }
  1084. public int get2PBattery()
  1085. {
  1086. return smartBowHelper2P == null ? 0 : smartBowHelper2P.GetBattery();
  1087. }
  1088. //主更新调用
  1089. void updateSmartBowHelper2P()
  1090. {
  1091. UpdateCameraToLookNewPoint2P();
  1092. }
  1093. #endregion
  1094. //取消正在连接的连接
  1095. public void onCancelAllConnecting(BluetoothStatusEnum _bluetoothStatus = BluetoothStatusEnum.ConnectFail)
  1096. {
  1097. // status != BluetoothStatusEnum.ConnectSuccess
  1098. Debug.LogWarning("onCancelAllConnecting 1:" + status);
  1099. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  1100. //BleUDP.ins != null
  1101. //BluetoothWindows.IsWindows() &&
  1102. if (status == BluetoothStatusEnum.Connecting)
  1103. {
  1104. //Debug.LogWarning("onCancelAllConnecting 2:" + status);
  1105. userDoConnect = false;
  1106. doConnect = false;
  1107. OnDisconnect();
  1108. // BleUDP.ins.Disconnect();
  1109. firstBluetoothWindows.Disconnect();
  1110. SetStatus(_bluetoothStatus);
  1111. Debug.LogWarning("onCancelAllConnecting 3:" + status);
  1112. }
  1113. #else
  1114. if (bluetoothHelper != null && status == BluetoothStatusEnum.Connecting)
  1115. {
  1116. Debug.LogWarning("onCancelAllConnecting 2:" + status);
  1117. userDoConnect = false;
  1118. doConnect = false;
  1119. OnDisconnect();
  1120. DisconnectBleHelper();
  1121. SetStatus(_bluetoothStatus);
  1122. }
  1123. #endif
  1124. //smartBowHelper2P.GetBluetoothStatus() != SmartBowSDK.BluetoothStatusEnum.Connected
  1125. if (smartBowHelper2P != null && smartBowHelper2P.GetBluetoothStatus() == SmartBowSDK.BluetoothStatusEnum.Connecting)
  1126. {
  1127. userDoConnect2P = false;
  1128. doConnect2P = false;
  1129. canConnect2P = true;
  1130. DisconnectSmartBowHelper2P();
  1131. //smartBowHelper2P.Disconnect();
  1132. Debug.Log("onCancelAllConnecting smartBowHelper2P 2:" + smartBowHelper2P.GetBluetoothStatus());
  1133. }
  1134. }
  1135. #region 判断是否是1p设备连接的是HOUYIPRO信息
  1136. public bool isMainConnectToHOUYIPRO()
  1137. {
  1138. bool _isHOUYIPRO = false;
  1139. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  1140. {
  1141. if ((int)BluetoothPlayer.FIRST_PLAYER == p.id && p.type == (int)AimDeviceType.HOUYIPRO)
  1142. {
  1143. _isHOUYIPRO = true;
  1144. }
  1145. }
  1146. if (_isHOUYIPRO)
  1147. {
  1148. if (CommonConfig.bDisableBluetooth)
  1149. {
  1150. return true;
  1151. }
  1152. else
  1153. {
  1154. //如果是。判断是否连接
  1155. return status == BluetoothStatusEnum.ConnectSuccess;
  1156. }
  1157. }
  1158. else
  1159. {
  1160. return false;
  1161. }
  1162. }
  1163. #endregion
  1164. #region 判断是否是1p设备连接的是ARTEMISPRO信息
  1165. public bool isMainConnectToARTEMISPRO()
  1166. {
  1167. bool _isARTEMISPRO = false;
  1168. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  1169. {
  1170. if ((int)BluetoothPlayer.FIRST_PLAYER == p.id && p.type == (int)AimDeviceType.ARTEMISPRO)
  1171. {
  1172. _isARTEMISPRO = true;
  1173. }
  1174. }
  1175. if (_isARTEMISPRO)
  1176. {
  1177. if (CommonConfig.bDisableBluetooth)
  1178. {
  1179. return true;
  1180. }
  1181. else
  1182. {
  1183. //如果是。判断是否连接
  1184. return status == BluetoothStatusEnum.ConnectSuccess;
  1185. }
  1186. }
  1187. else
  1188. {
  1189. return false;
  1190. }
  1191. }
  1192. #endregion
  1193. #region 判断是否是1p设备连接的是红外信息,有多种红外设备-弓箭
  1194. public bool isMainConnectToInfraredDevice()
  1195. {
  1196. bool _isInfraredDevice = false;
  1197. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  1198. {
  1199. if ((int)BluetoothPlayer.FIRST_PLAYER == p.id && (p.type == (int)AimDeviceType.ARTEMISPRO || p.type == (int)AimDeviceType.HOUYIPRO))
  1200. {
  1201. _isInfraredDevice = true;
  1202. }
  1203. }
  1204. if (_isInfraredDevice)
  1205. {
  1206. if (CommonConfig.bDisableBluetooth)
  1207. {
  1208. return true;
  1209. }
  1210. else
  1211. {
  1212. //如果是。判断是否连接
  1213. return status == BluetoothStatusEnum.ConnectSuccess;
  1214. }
  1215. }
  1216. else
  1217. {
  1218. return false;
  1219. }
  1220. }
  1221. #endregion
  1222. #region 判断是否是1p设备连接的是Gun信息
  1223. public bool isMainConnectToGun()
  1224. {
  1225. bool _isGun = false;
  1226. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  1227. {
  1228. if ((int)BluetoothPlayer.FIRST_PLAYER == p.id && (p.type == (int)AimDeviceType.Gun || p.type == (int)AimDeviceType.PistolM17 || p.type == (int)AimDeviceType.RifleM416))
  1229. {
  1230. _isGun = true;
  1231. }
  1232. }
  1233. if (_isGun)
  1234. {
  1235. if (CommonConfig.bDisableBluetooth)
  1236. {
  1237. return true;
  1238. }
  1239. else
  1240. {
  1241. //如果是。判断是否连接
  1242. return status == BluetoothStatusEnum.ConnectSuccess;
  1243. }
  1244. }
  1245. else
  1246. {
  1247. return false;
  1248. }
  1249. }
  1250. /// <summary>
  1251. /// 获取连接枪的类型
  1252. /// </summary>
  1253. /// <returns></returns>
  1254. public (bool isGun, AimDeviceType gunType) isMainConnectToGunType()
  1255. {
  1256. bool _isGun = false;
  1257. AimDeviceType aimDeviceType = AimDeviceType.NONE;
  1258. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  1259. {
  1260. if ((int)BluetoothPlayer.FIRST_PLAYER == p.id && (p.type == (int)AimDeviceType.Gun || p.type == (int)AimDeviceType.PistolM17 || p.type == (int)AimDeviceType.RifleM416))
  1261. {
  1262. _isGun = true;
  1263. aimDeviceType = (AimDeviceType)p.type;
  1264. }
  1265. }
  1266. if (_isGun)
  1267. {
  1268. if (CommonConfig.bDisableBluetooth)
  1269. {
  1270. return (true, aimDeviceType);
  1271. }
  1272. else
  1273. {
  1274. //如果是。判断是否连接
  1275. return (status == BluetoothStatusEnum.ConnectSuccess, aimDeviceType);
  1276. }
  1277. }
  1278. else
  1279. {
  1280. return (false, aimDeviceType);
  1281. }
  1282. }
  1283. #endregion
  1284. /// <summary>
  1285. /// 设置设备类型
  1286. /// </summary>
  1287. public void SetMainConnectDeviceType()
  1288. {
  1289. //1号玩家连接蓝牙成功时候,设置一次 GlobalData.MyDeviceMode
  1290. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  1291. {
  1292. if ((int)BluetoothPlayer.FIRST_PLAYER == p.id)
  1293. {
  1294. if (p.type == (int)AimDeviceType.Gun || p.type == (int)AimDeviceType.PistolM17 || p.type == (int)AimDeviceType.RifleM416)
  1295. {
  1296. //设置枪
  1297. HomeView.ins.MyTopBarView.onChangeType(1);
  1298. }
  1299. else
  1300. {
  1301. //其余默认是弓箭
  1302. HomeView.ins.MyTopBarView.onChangeType(0);
  1303. }
  1304. }
  1305. }
  1306. }
  1307. #region 用户1 window ble 连接和部分共用代码
  1308. void OnConnected_windows1()
  1309. {
  1310. Log("[WinBle_1P]连接成功\n" + deviceName);
  1311. SetStatus(BluetoothStatusEnum.ConnectSuccess);
  1312. BowCamera.isTouchMode = false;
  1313. if (CommonConfig.EnableDecryption && NeedDecryption)
  1314. {
  1315. // 这里验证指令,开始请求授权
  1316. // 启动轮询协程
  1317. StartCoroutine(PollingCoroutine());
  1318. }
  1319. else
  1320. {
  1321. //除了pc,Android 直接连接
  1322. InitWhenConenct();
  1323. }
  1324. }
  1325. void OnConnectionFailed_windows1()
  1326. {
  1327. Log("连接失败\n" + deviceName);
  1328. OnDisconnect();
  1329. }
  1330. void OnCharacteristicChanged_windows1(string deviceId, byte[] value)
  1331. {
  1332. OnCharacteristicChanged(null, value, null);
  1333. }
  1334. void OnCharacteristicChanged(BluetoothHelper helper, byte[] value, BluetoothHelperCharacteristic characteristic)
  1335. {
  1336. if (status != BluetoothStatusEnum.ConnectSuccess) return;
  1337. if (!hasData)
  1338. {
  1339. hasData = true;
  1340. hasDataTime = JCUnityLib.TimeUtils.GetTimestamp();
  1341. }
  1342. if (CommonConfig.EnableDecryption && NeedDecryption)
  1343. {
  1344. //Pc 版本先走校验流程
  1345. if (!BluetoothDecryptor.AUTHOR_IsDecrypt())
  1346. {
  1347. if (value[0] == 0x5a)
  1348. {
  1349. // 从硬件读取数据
  1350. if (value != null && value.Length > 0)
  1351. {
  1352. Debug.Log("接收到数据:" + BitConverter.ToString(value));
  1353. BluetoothDecryptor.AUTHOR_Decrypt(value);
  1354. if (BluetoothDecryptor.AUTHOR_IsDecrypt())
  1355. {
  1356. Debug.Log("解密成功!");
  1357. //解密成功后
  1358. StopEncrypt();
  1359. //开始连接其他信息
  1360. InitWhenConenct();
  1361. }
  1362. else
  1363. {
  1364. Debug.Log("解密失败!");
  1365. //SideTipView.ShowTip("设备通信失败,断开连接", Color.yellow);
  1366. //断开连接等操作
  1367. if (PollingCoroutineCount <= 0)
  1368. {
  1369. StopEncrypt();
  1370. DoConnect();
  1371. }
  1372. }
  1373. }
  1374. }
  1375. return;
  1376. }
  1377. }
  1378. dataCount++;
  1379. if (curMac == null && dataCount < 500)
  1380. {
  1381. UploadMacAddress(value);
  1382. }
  1383. byte[] bytes = value;
  1384. if (AimHandler.ins)
  1385. {
  1386. AimHandler.ins.OnDataReceived(bytes);
  1387. }
  1388. }
  1389. #endregion
  1390. #region 管理部分监听通信
  1391. /// <summary>
  1392. /// 监听枪状态
  1393. /// </summary>
  1394. public BleDeviceEvent OnBleDeviceState;
  1395. /// <summary>
  1396. /// 硬件对应的事件
  1397. /// </summary>
  1398. public delegate void BleDeviceEvent(BluetoothDeviceType bleDeviceType, BluetoothDeviceStatus gunStatusEnum);
  1399. internal void InvokeOnBleDevice(BluetoothDeviceType bleDeviceType, BluetoothDeviceStatus gunStatusEnum)
  1400. {
  1401. try
  1402. {
  1403. OnBleDeviceState?.Invoke(bleDeviceType, gunStatusEnum);
  1404. }
  1405. catch (Exception e)
  1406. {
  1407. Debug.LogError(e);
  1408. }
  1409. }
  1410. /// <summary>
  1411. /// 记录硬件反馈的设备状态和连接的设备平台信息
  1412. /// </summary>
  1413. public BluetoothDeviceType myBluetoothDeviceType = BluetoothDeviceType.NONE;
  1414. public ConnectPlatform myConnectPlatform = ConnectPlatform.NONE;
  1415. /// <summary>
  1416. /// 监听设备状态和连接的设备平台信息
  1417. /// </summary>
  1418. public DeviceAndSystemInfoEvent OnDeviceAndSystemInfoEvent;
  1419. /// <summary>
  1420. /// 硬件对应的事件初始化回调
  1421. /// </summary>
  1422. public delegate void DeviceAndSystemInfoEvent(ConnectPlatform connectPlatform, BluetoothDeviceType bleDeviceType);
  1423. internal void InvokeOnDeviceAndSystemInfoEvent(ConnectPlatform connectPlatform, BluetoothDeviceType bleDeviceType)
  1424. {
  1425. try
  1426. {
  1427. myConnectPlatform = connectPlatform;
  1428. myBluetoothDeviceType = bleDeviceType;
  1429. OnDeviceAndSystemInfoEvent?.Invoke(connectPlatform, bleDeviceType);
  1430. }
  1431. catch (Exception e)
  1432. {
  1433. Debug.LogError(e);
  1434. }
  1435. }
  1436. /// <summary>
  1437. /// 获取一次当前记录的信息
  1438. /// </summary>
  1439. public void GetDeviceAndSystemInfoEvent() {
  1440. OnDeviceAndSystemInfoEvent?.Invoke(myConnectPlatform, myBluetoothDeviceType);
  1441. }
  1442. /// <summary>
  1443. /// 返回一个存储用户的新手教程字符串
  1444. /// </summary>
  1445. /// <returns></returns>
  1446. public string GetInfraredGuiderKey() {
  1447. return $"hideInfraredGuider-{LoginMgr.myUserInfo.id}-{myBluetoothDeviceType}";
  1448. }
  1449. /// <summary>
  1450. /// 清除当前红外记录的存储的所有key内容
  1451. /// </summary>
  1452. public void ClearAllInfraredGuider() {
  1453. int userId = LoginMgr.myUserInfo.id;
  1454. foreach (BluetoothDeviceType type in Enum.GetValues(typeof(BluetoothDeviceType)))
  1455. {
  1456. string key = $"hideInfraredGuider-{userId}-{type}";
  1457. PlayerPrefs.DeleteKey(key);
  1458. }
  1459. PlayerPrefs.Save();
  1460. }
  1461. #endregion
  1462. }