LoginController.cs 13 KB

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