LoginController.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using Newtonsoft.Json;
  6. using UnityEngine.SceneManagement;
  7. using Cinemachine;
  8. using UnityEngine.UI;
  9. using TMPro;
  10. /* 使用login token进行登录和数据读取保存
  11. * TestDataInjection 是测试用的假数据注入
  12. * LoginTokenCheck 验证login token是否有效,和服务器比对
  13. * 比较版本是否可以符合游戏可以允许最低版本
  14. * 弹出用户注册窗口
  15. */
  16. public class LoginController : MonoBehaviour
  17. {
  18. // Start is called once before the first execution of Update after the MonoBehaviour is created
  19. private GameObject canvasPlaceholder, regCanvas, createAdoptCanvas, loginCanvas;
  20. void Start()
  21. {
  22. canvasPlaceholder = GameObject.Find("Canvas Placeholder");
  23. regCanvas = canvasPlaceholder.transform.Find("Register Canvas").gameObject;
  24. createAdoptCanvas = canvasPlaceholder.transform.Find("Create Or Adopt Canvas").gameObject;
  25. loginCanvas = canvasPlaceholder.transform.Find("Login Canvas").gameObject;
  26. // 判断是否要切换到注册狗的子场景
  27. if (GameData.subScene == "Login_InitDog")
  28. {
  29. SwitchToInitDogScene();
  30. GameData.subScene = null;
  31. }
  32. else
  33. {
  34. //启动自动采用Login Token 登录。其他登录方式为手动登录。
  35. StartCoroutine(LoginTokenRequest());
  36. }
  37. }
  38. // Update is called once per frame
  39. //void Update()
  40. //{
  41. //}
  42. // LoginToken登录方法
  43. IEnumerator LoginTokenRequest()
  44. {
  45. Debug.Log("LoginToken Request start");
  46. string UUID = SystemInfo.deviceUniqueIdentifier; // 这里需要考虑这段代码执行在Enviroment Controller之前
  47. string LoginToken = PlayerPrefs.GetString("LoginToken", null);
  48. string LoginTokenTime = PlayerPrefs.GetString("LoginTokenTime", null);
  49. // 比较LoginTokenTime 如果超时直接放弃后面代码。比较UUID是否是null如果是直接放弃后面代码
  50. if (LoginToken == null) { yield break; }
  51. ;
  52. if (LoginTokenTime == null) { yield break; }
  53. ;
  54. DateTime tokenTime;
  55. DateTime now = DateTime.Now;
  56. if (DateTime.TryParse(LoginTokenTime, out tokenTime))
  57. {
  58. TimeSpan span = now - tokenTime;
  59. if (span.TotalHours > 7 * 24)
  60. {
  61. yield break;
  62. }
  63. }
  64. else { yield break; }
  65. // 提交POST
  66. string url = "/api/login/token/";
  67. WWWForm form = new();
  68. form.AddField("login_token", LoginToken);
  69. form.AddField("UUID", UUID);
  70. StartCoroutine(WebController.PostRequest(url, form, callback: LoginTokenCallback));
  71. }
  72. // Post之后callback的函数
  73. void LoginTokenCallback(string json)
  74. {
  75. LoginSucessHandler(json);
  76. if (UserProperty.userId != null && EnviromentSetting.accessToken != null)
  77. {
  78. // 启动获取用户信息请求
  79. StartCoroutine(GetUserData());
  80. }
  81. else
  82. {
  83. Debug.Log("LoginTokenCallback 登陆失败");
  84. Debug.Log(json);
  85. }
  86. }
  87. void LoginSucessHandler(string json)
  88. {
  89. var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  90. if (data != null && data["status"] == "success")
  91. {
  92. Debug.Log("Login Token sucess!");
  93. PlayerPrefs.SetString("LoginToken", data["login_token"]);
  94. PlayerPrefs.SetString("LoginTokenTime", DateTime.Now.ToString());
  95. EnviromentSetting.accessToken = data["access_token"];
  96. EnviromentSetting.accessTokenReceivedTime = DateTime.Now;
  97. UserProperty.userId = data["user_id"];
  98. // 比较游戏版本
  99. // TODO 等后台更改后删除
  100. //string allowed_client_ver = data["allowed_client_ver"];
  101. string allowed_client_ver = "0.1";
  102. string current_ver = EnviromentSetting.version;
  103. Version curVer = new Version(current_ver);
  104. Version allowVer = new Version(allowed_client_ver);
  105. int verCompare = curVer.CompareTo(allowVer);
  106. if (verCompare < 0)
  107. {
  108. // 弹窗,然后退出
  109. string err_msg;
  110. if (EnviromentSetting.platform == "IPhonePlayer")
  111. {
  112. err_msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "not_allow_version_IOS", EnviromentSetting.languageCode });
  113. }
  114. else if (EnviromentSetting.platform == "Android")
  115. {
  116. if (EnviromentSetting.languageCode == "zh-cn") // 安卓中文环境
  117. {
  118. err_msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "not_allow_version_Andriod_CN", EnviromentSetting.languageCode });
  119. }
  120. else
  121. {
  122. // 安卓其他语言
  123. err_msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "not_allow_version_Andriod_WW", EnviromentSetting.languageCode });
  124. }
  125. }
  126. else
  127. {
  128. // 不明操作系统
  129. err_msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "not_allow_version_Generic", EnviromentSetting.languageCode });
  130. }
  131. MessageBoxController.ShowMessage(err_msg, ShutDown);
  132. }
  133. }
  134. else
  135. {
  136. Debug.Log("Login Token fail!");
  137. Debug.Log(json);
  138. }
  139. }
  140. // 当版本检查不符合游戏时退出游戏
  141. public void ShutDown()
  142. {
  143. Application.Quit();
  144. }
  145. IEnumerator GetUserData()
  146. {
  147. Debug.Log("GetUserData request");
  148. yield return null; // 跳过第一帧
  149. // 提交POST
  150. string url = "/api/user/info/";
  151. WWWForm form = new();
  152. form.AddField("user_id", UserProperty.userId);
  153. StartCoroutine(WebController.PostRequest(url, form, callback: GetUserDataCallback));
  154. }
  155. void GetUserDataCallback(string json)
  156. {
  157. var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
  158. if (data != null && data["status"].ToString() == "success")
  159. {
  160. var user_info = data["user_info"].ToString();
  161. UserProperty.FreshUserInfo(user_info);
  162. // 保存狗的数据
  163. string dogsJson = data["dogs"].ToString();
  164. UserProperty.FreshDogInfo(dogsJson);
  165. // 保存道具数据
  166. UserProperty.FreshUserItems(data["props"].ToString());
  167. // 判断用户狗的数量,如果为0就跳转用户创建狗。
  168. if (UserProperty.dogs.Count < 1)
  169. {
  170. SwitchToInitDogScene();
  171. }
  172. else if (!UserProperty.isRegUser)
  173. {
  174. // 如果非注册用户,提示用户注册
  175. var loginCanvas = GameObject.Find("Login Canvas");
  176. loginCanvas.SetActive(false);
  177. string msg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "reg_reminder", EnviromentSetting.languageCode });
  178. //MessageBoxController.YorN_Message(msg, ()=> regCanvas.SetActive(true), ()=> SceneManager.LoadScene("Home"));
  179. MessageBoxController.YorN_Message(msg, () => regCanvas.SetActive(true), () => MaskTransitions.TransitionManager.Instance.LoadLevel("Home"));
  180. }
  181. else
  182. {
  183. ShowStartGameUI();
  184. }
  185. }
  186. else
  187. {
  188. Debug.Log(data["message"]);
  189. }
  190. }
  191. void ShowStartGameUI()
  192. {
  193. var uiPlaceholder = GameObject.Find("Canvas Placeholder");
  194. if (uiPlaceholder != null)
  195. {
  196. var startGameUI = uiPlaceholder.transform.Find("Start Game Canvas").gameObject;
  197. startGameUI.SetActive(true);
  198. var loginCanvas = uiPlaceholder.transform.Find("Login Canvas").gameObject;
  199. loginCanvas.SetActive(false);
  200. }
  201. }
  202. // Quick Start 登录方式,用UUID换取Login Token
  203. public void QuickStart()
  204. {
  205. Debug.Log("Quick start post request.");
  206. string url = "/api/game/quick_start/";
  207. Dictionary<string, string> formData = new();
  208. WWWForm form = new();
  209. form.AddField("UUID", EnviromentSetting.UUID);
  210. StartCoroutine(WebController.PostRequest(url, form, callback: QuickStartCallback));
  211. }
  212. void QuickStartCallback(string json)
  213. {
  214. var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  215. if (data != null && data["status"] == "success")
  216. {
  217. PlayerPrefs.SetString("LoginToken", data["login_token"]);
  218. PlayerPrefs.SetString("LoginTokenTime", DateTime.Now.ToString());
  219. UserProperty.userId = data["user_id"];
  220. StartCoroutine(LoginTokenRequest());
  221. }
  222. else
  223. {
  224. string errMsg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "login_fail", EnviromentSetting.languageCode });
  225. MessageBoxController.ShowMessage(errMsg);
  226. }
  227. }
  228. public void ResetPassword()
  229. {
  230. var uiPlaceholder = GameObject.Find("Canvas Placeholder");
  231. if (uiPlaceholder != null)
  232. {
  233. var resetUI = uiPlaceholder.transform.Find("Reset Pasword").gameObject;
  234. var loginCanvas = uiPlaceholder.transform.Find("Login Canvas").gameObject;
  235. resetUI.SetActive(true);
  236. loginCanvas.SetActive(false);
  237. }
  238. }
  239. // 切换到生成狗的子场景
  240. void SwitchToInitDogScene()
  241. {
  242. createAdoptCanvas.SetActive(true);
  243. loginCanvas.SetActive(false);
  244. regCanvas.SetActive(false);
  245. var loginCam = GameObject.Find("V Cam Login").GetComponent<CinemachineVirtualCamera>();
  246. var initDogCam = GameObject.Find("V Cam Init Dog").GetComponent<CinemachineVirtualCamera>();
  247. loginCam.Priority = 0;
  248. initDogCam.Priority = 10;
  249. }
  250. // 使用账户密码登录方法
  251. public void Login()
  252. {
  253. string account = GameObject.Find("Account input").GetComponent<TMP_InputField>().text;
  254. string password = GameObject.Find("Password input").GetComponent<TMP_InputField>().text;
  255. string url = "/api/login/";
  256. Dictionary<string, string> formData = new();
  257. WWWForm form = new();
  258. form.AddField("client_language", EnviromentSetting.languageCode);
  259. if (EnviromentSetting.languageCode == "zh-cn")
  260. {
  261. form.AddField("mobile_number", account.Trim());
  262. }
  263. else
  264. {
  265. form.AddField("email", account.Trim());
  266. }
  267. form.AddField("password", password.Trim());
  268. StartCoroutine(WebController.PostRequest(url, form, callback: LoginCallback));
  269. }
  270. void LoginCallback(string json)
  271. {
  272. var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
  273. if (data != null && data["status"].ToString() == "success")
  274. {
  275. LoginSucessHandler(json);
  276. if (UserProperty.userId != null && EnviromentSetting.accessToken != null)
  277. {
  278. // 启动获取用户信息请求
  279. StartCoroutine(GetUserData());
  280. }
  281. else
  282. {
  283. Debug.Log("LoginTokenCallback 登陆失败");
  284. Debug.Log(json);
  285. }
  286. }
  287. else
  288. {
  289. string errMsg = GameTool.GetValueAtPath(EnviromentSetting.languageData, new string[] { "game_message", "login_fail", EnviromentSetting.languageCode });
  290. MessageBoxController.ShowMessage(errMsg);
  291. }
  292. }
  293. }