LoginMgr.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using Newtonsoft.Json;
  5. using JCUnityLib;
  6. using AdaptUI;
  7. /* 登录管理者,用户数据定义和存储 */
  8. public class LoginMgr : MonoBehaviour
  9. {
  10. [SerializeField] GameObject loginView;
  11. [SerializeField] GameObject registerView;
  12. [SerializeField] GameObject loginView_iPad;
  13. [SerializeField] GameObject registerView_iPad;
  14. public static UserInfo myUserInfo = new UserInfo();
  15. public void showRegisterView()
  16. {
  17. // loginView.SetActive(false);
  18. // registerView.SetActive(true);
  19. //获取设备类型
  20. DeviceTypeHelper.DeviceType detectedType = DeviceTypeHelper.DetectDeviceType();
  21. //Debug.Log($"showRegisterView设备类型: {detectedType}");
  22. //根据设备类型显示不同的登录界面
  23. if(detectedType == DeviceTypeHelper.DeviceType.iPad)
  24. {
  25. loginView_iPad.SetActive(false);
  26. registerView_iPad.SetActive(true);
  27. }
  28. else
  29. {
  30. loginView.SetActive(false);
  31. registerView.SetActive(true);
  32. }
  33. AgreenmentOption.ins.gameObject.SetActive(true);
  34. UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(AgreenmentOption.ins.gameObject.GetComponent<RectTransform>());
  35. }
  36. public void showLoginView()
  37. {
  38. //loginView.SetActive(true);
  39. //registerView.SetActive(false);
  40. DeviceTypeHelper.DeviceType detectedType = DeviceTypeHelper.DetectDeviceType();
  41. Debug.Log($"[LoginMgr]showLoginView设备类型: {detectedType}");
  42. //根据设备类型显示不同的登录界面
  43. if(detectedType == DeviceTypeHelper.DeviceType.iPad)
  44. {
  45. loginView.SetActive(false);
  46. loginView_iPad.SetActive(true);
  47. registerView_iPad.SetActive(false);
  48. }
  49. else
  50. {
  51. loginView.SetActive(true);
  52. loginView_iPad.SetActive(false);
  53. registerView.SetActive(false);
  54. }
  55. AgreenmentOption.ins.gameObject.SetActive(true);
  56. }
  57. public void showForgetPWD_View()
  58. {
  59. Instantiate(SceneResourceManager.Instance.GetPrefab("RetrievePasswordView"));
  60. }
  61. public const string LoginTokenKey = "LoginToken";
  62. public static bool HasToken()
  63. {
  64. string loginToken = PlayerPrefs.GetString(LoginMgr.LoginTokenKey, "");
  65. return string.IsNullOrEmpty(loginToken) ? false : true;
  66. }
  67. void Awake()
  68. {
  69. transform.Find("AgreementPopup").gameObject.SetActive(true);
  70. ViewMgr.Instance.DestroyAllViews();
  71. }
  72. void Start()
  73. {
  74. //显示登录界面
  75. showLoginView();
  76. //退出到登录界面,也要把蓝牙断开
  77. if (BluetoothAim.ins) {
  78. if (BluetoothAim.ins.status == BluetoothStatusEnum.ConnectSuccess) BluetoothAim.ins.DoConnect();
  79. else BluetoothAim.ins.connectCanceled = true;
  80. }
  81. }
  82. }
  83. public class UserInfo
  84. {
  85. public int id;
  86. public int avatarID = 0;
  87. public string avatarUrl = "";
  88. public string nickname = "超级射手";
  89. public int gender = 1;
  90. public string phone = "";
  91. public string email = "";
  92. public string birthday = "";
  93. public string country = "";
  94. public string state = "";
  95. public string city = "";
  96. public int integral = 0;
  97. public int coin = 0;
  98. public int diamond = 1000;
  99. public string mac = "";
  100. public List<PropInfo> bagList = new List<PropInfo>();
  101. public List<DeviceInfo> deviceList = new List<DeviceInfo>();
  102. /// <summary>
  103. /// 显示游戏最高分(不同距离分数独立)
  104. /// 2023-7-16兼容WildAttack最高分纪录
  105. /// </summary>
  106. public Dictionary<string, float> timeLimitGameScores = new Dictionary<string, float>();
  107. //闯关记录(gameType:通关数)(野兔、野鸡、野狼的通关数)
  108. public Dictionary<int, int> challengeLevels = new Dictionary<int, int>();
  109. public string guideRecord = "";
  110. public static UserInfo LoadLocal(int id)
  111. {
  112. UserInfo result = null;
  113. if (CommonConfig.StandaloneMode)
  114. {
  115. try
  116. {
  117. //result = JsonConvert.DeserializeObject<UserInfo>(PlayerPrefs.GetString("UserInfo_" + id));
  118. //if (result == null) throw new Exception("UserInfo.LoadLocal Null");
  119. string userInfoString = PlayerPrefs.GetString("UserInfo_" + id);
  120. if (string.IsNullOrEmpty(userInfoString))
  121. {
  122. return null;
  123. }
  124. result = JsonConvert.DeserializeObject<UserInfo>(userInfoString);
  125. if (result == null)
  126. {
  127. throw new Exception("UserInfo.LoadLocal Null");
  128. }
  129. }
  130. catch (Exception e)
  131. {
  132. Debug.LogError(e);
  133. }
  134. }
  135. return result;
  136. }
  137. public void Save()
  138. {
  139. if (CommonConfig.StandaloneMode)
  140. {
  141. PlayerPrefs.SetString("UserInfo_" + id, JsonConvert.SerializeObject(this));
  142. return;
  143. }
  144. try { UserComp.Instance.saveUserInfo(this); } catch (System.Exception e) { Debug.LogError(e.Message); }
  145. }
  146. public void SetChallengeLevelPass(int gameType, int level)
  147. {
  148. if (gameType != 3 && gameType != 4 && gameType != 5) return;
  149. if (challengeLevels.ContainsKey(gameType))
  150. {
  151. if (level <= challengeLevels[gameType])
  152. {
  153. return;
  154. }
  155. }
  156. challengeLevels.Remove(gameType);
  157. challengeLevels.Add(gameType, level);
  158. }
  159. public int GetChallengeLevelPass(int gameType)
  160. {
  161. if (challengeLevels.ContainsKey(gameType))
  162. {
  163. return challengeLevels[gameType];
  164. }
  165. return 0;
  166. }
  167. //判断引导是否完成(服务端保存)
  168. //index0: 新手引导NewUserGuide
  169. public bool IsGuideFinish(int index)
  170. {
  171. if (index == 0)
  172. {
  173. return PlayerPrefs.GetInt("NewUserGuideFinish_" + LoginMgr.myUserInfo.id, 0) == 1;
  174. }
  175. char[] chars = guideRecord.ToCharArray();
  176. if (index < chars.Length)
  177. {
  178. return chars[index] == '1';
  179. }
  180. return false;
  181. }
  182. public void SaveGuideFinish(int index)
  183. {
  184. if (index == 0)
  185. {
  186. PlayerPrefs.SetInt("NewUserGuideFinish_" + LoginMgr.myUserInfo.id, 1);
  187. return;
  188. }
  189. char[] chars = guideRecord.ToCharArray();
  190. if (index < chars.Length)
  191. {
  192. if (chars[index] == '1') return;
  193. chars[index] = '1';
  194. }
  195. else
  196. {
  197. int newLen = index + 1;
  198. char[] newChars = new char[newLen];
  199. for (int i = 0; i < newLen; i++)
  200. {
  201. newChars[i] = i < chars.Length ? chars[i] : '0';
  202. }
  203. newChars[index] = '1';
  204. chars = newChars;
  205. }
  206. this.guideRecord = string.Join("", chars);
  207. UserPlayer.ins?.call("userComp.saveGuideRecord", this.guideRecord);
  208. }
  209. }
  210. public class UserSettings
  211. {
  212. //打开BGM
  213. public bool openBGM = true;
  214. //打开音效
  215. public bool openEffect = true;
  216. //是否打开准心
  217. public bool openCrossHair = true;
  218. //射击难度
  219. public int shootLevel = 0;
  220. //游戏里的箭重,单位克
  221. public float actualArrowWeight = 20;
  222. //弓箭旋转转化
  223. public BowRotateConvert bowRotateConvert = new BowRotateConvert();
  224. //游戏中是否固定镜头
  225. public bool bowCameraFixed = true;
  226. //训练模式
  227. public bool trainMode = false;
  228. //游戏里面视角重置时间(3秒改成默认5秒)
  229. public float calibrationTime = 5f;
  230. //游戏里面的弓箭手臂(在所有游戏中,游戏设置里的‘手臂弓箭’这个选项,默认为关;即在游戏中,不出现手臂和弓箭的模型)
  231. public bool openBowAndArrow = false;
  232. //选择的红外连接设备
  233. public string selectDevicesName = "";
  234. //激光设备开启状态 默认关闭
  235. public bool lightState = false;
  236. //b端 每一局的设置
  237. public int PerRoundCoin = 2; //投币
  238. public int PerRoundSeconds = 1200;//时间
  239. public int TotalCoinsNum = 0;//总投币数
  240. public int ChangeTicket = 0;//多少分兑换一张票
  241. public int TotalTicketNum = 0;//总出票数量
  242. public int NeedCoin = 1;//是否需要投币
  243. public int GiveTicket = 0;//是否出票
  244. //设备校准引导-是否已经完成
  245. public bool deviceCalibrateGuideFinish = false;
  246. //游戏规则引导-是否已经完成(完成则保存对应的GameType)
  247. public HashSet<int> gameRuleGuideFinish = new HashSet<int>();
  248. private static UserSettings _ins;
  249. public static UserSettings ins
  250. {
  251. get
  252. {
  253. if (_ins == null)
  254. {
  255. string dataStr = PlayerPrefs.GetString("UserSettings", "{}");
  256. try
  257. {
  258. _ins = JsonConvert.DeserializeObject<UserSettings>(dataStr);
  259. }
  260. catch (System.Exception) { }
  261. if (_ins == null)
  262. {
  263. _ins = new UserSettings();
  264. }
  265. if (CommonConfig.SpecialVersion1)
  266. {
  267. if (PlayerPrefs.GetInt("sv1_UserSettings_2", 0) == 0)
  268. {
  269. PlayerPrefs.SetInt("sv1_UserSettings_2", 1);
  270. UserSettings us = _ins;
  271. us.bowRotateConvert.screenSize = 60;
  272. us.bowRotateConvert.screenDistance = 1.5f;
  273. us.Save();
  274. }
  275. }
  276. }
  277. return _ins;
  278. }
  279. }
  280. public void Save()
  281. {
  282. PlayerPrefs.SetString("UserSettings", JsonConvert.SerializeObject(this));
  283. }
  284. }
  285. /*
  286. 描述1
  287. 已知:
  288. 屏幕宽高比例w:h=16:9,屏幕尺寸s=60.11英寸,屏幕距离d=2.50米,实际指向右边树的角度为e=5.56°。
  289. 可知:
  290. 屏幕尺寸s1 = (s * 0.0254)米
  291. 屏幕单位大小为unit,关系式(w*unit)^2 + (h*unit)^2 = s1^2
  292. 结果:
  293. 向量(玩家->右边树)在屏幕上投影的长度比例q = tan(e) * d / unit
  294. */
  295. /*
  296. 描述2(适配各种尺寸的屏幕)
  297. 已知:
  298. 屏幕宽高比例w:h=16:9,屏幕尺寸s=(任意)英寸,屏幕距离d=(任意)米,游戏指向右边树的角度为r=27.30°。
  299. 借用描述1的结果q
  300. 可知:
  301. 屏幕尺寸s1 = (s * 0.0254)米
  302. 屏幕单位大小为unit,关系式(w*unit)^2 + (h*unit)^2 = s1^2
  303. 实际指向右边树的角度为e = atan(q * unit / d)
  304. 结果:
  305. 游戏转动角度:实际转动角度 = r / e
  306. */
  307. public class BowRotateConvert
  308. {
  309. public float screenSize = 60; //屏幕尺寸(英寸)
  310. public float screenDistance = 2.5f; //玩家距离屏幕多远(米)
  311. [NonSerialized] public float fieldOfView = 25;
  312. //获取建议的屏幕距离
  313. public float GetAdviseScreenDistance()
  314. {
  315. float w = 16;
  316. float h = 9;
  317. float s1 = screenSize * 0.0254f;
  318. float unit = s1 / Mathf.Sqrt(w * w + h * h);
  319. float screenHeight = 9 * unit;
  320. return screenHeight * 0.5f / Mathf.Tan(fieldOfView / 2 / 180 * Mathf.PI);
  321. }
  322. // 游戏旋转角度 : 实际旋转角度 (这个版本丢弃掉这个功能-所以直接返回1)
  323. public float GetRate()
  324. {
  325. return 1;
  326. }
  327. // 游戏旋转角度 : 实际旋转角度
  328. // public float GetRate() {
  329. // double w = 16;
  330. // double h = 9;
  331. // double s = Convert.ToDouble(screenSize);
  332. // double d = Convert.ToDouble(screenDistance);
  333. // double r = 27.3 / 180 * Math.PI;
  334. // double q = get_q();
  335. // double s1 = s * 0.0254;
  336. // double unit = Math.Sqrt(Math.Pow(s1, 2) / (Math.Pow(w, 2) + Math.Pow(h, 2)));
  337. // double e = Math.Atan(q * unit / d);
  338. // return (float) (r / e);
  339. // }
  340. // private double get_q() {
  341. // double w = 16;
  342. // double h = 9;
  343. // double s = 60.11;
  344. // double d = 2.5;
  345. // double e = 5.56 / 180 * Math.PI;
  346. // double s1 = s * 0.0254;
  347. // double unit = Math.Sqrt(Math.Pow(s1, 2) / (Math.Pow(w, 2) + Math.Pow(h, 2)));
  348. // double q = Math.Tan(e) * d / unit;
  349. // return q;
  350. // }
  351. }