BluetoothAim.cs 55 KB

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