using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace HC { public class HCAccountManager : HCSingleton { private string staticOnlineKey_loginChannels = "loginChannels"; public string staticSaveKey_DeviceID = "DeviceID"; private string staticSaveKey_LastLoginType = "LastLoginType"; public const string staticSaveKey_UserID = "UserID"; public const string staticSaveKey_UserType = "UserType"; private string staticSaveKey_Token = "Token"; // 当前登录信息 private UserInfo CurrUserInfo; private Action mLoginResultCallback = null; // Start is called before the first frame update void Start() { } /// /// Login /// /// loginType /// loginCallback public void Login(HCLoginType _loginType, Action _loginResultCallback = null) { mLoginResultCallback = _loginResultCallback; HCTools.SavePlayerPrefsInt(staticSaveKey_LastLoginType, (int)_loginType); if (_loginType == HCLoginType.LOGIN_BY_GUESTER) { // 取deviceID给服务器发登录请求 string deviceID = HCTools.GetPlayerPrefsString(staticSaveKey_DeviceID); if (string.IsNullOrEmpty(deviceID)) { deviceID = HCNativeInterface.Instance.GetDeviceID(); if (string.IsNullOrEmpty(deviceID)) { deviceID = System.Guid.NewGuid().ToString(); } HCTools.SavePlayerPrefsString(staticSaveKey_DeviceID, deviceID); GuestLogin(deviceID); } else { GuestLogin(deviceID); } } else { // 调用三方登录 HCNativeInterface.Instance.Login(_loginType, ThirdLoginCallback); } // 事件埋点 if (HCTools.IfFirstCheckPlayerPrefs(string.Format("{0}_IfFirst", HCInnerStaticSting.HC_Login_CreateTKUserid))) { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_CreateTKUserid, HCInnerStaticSting.HC_Account, GetLoginTypeString(_loginType)); } HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_Enter, HCInnerStaticSting.HC_Account, GetLoginTypeString(_loginType)); } /// /// 游客登录方法 /// /// private void GuestLogin(string _deviceID) { _deviceID = _deviceID.Replace("-", ""); UserInfo userInfo = new UserInfo(); userInfo.userID = _deviceID; userInfo.loginType = HCLoginType.LOGIN_BY_GUESTER; LoginByServer(userInfo, ServerLoginCallback); } /// /// 三方登录回调,请求服务器登录 /// /// private void ThirdLoginCallback(LoginInfo _loginInfo) { // 事件埋点 if (_loginInfo.loginStatus == HCLoginStatus.LOGIN_STATUS_SUCC) { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_Success, HCInnerStaticSting.HC_Account, GetLoginTypeString(_loginInfo.userInfo.loginType)); } else { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(_loginInfo.userInfo.loginType)); } if (_loginInfo.loginStatus == HCLoginStatus.LOGIN_STATUS_SUCC) { LoginByServer(_loginInfo.userInfo, ServerLoginCallback); } else { mLoginResultCallback?.Invoke(_loginInfo); } } /// /// 服务器登录返回,callback回游戏 /// /// /// /// private void ServerLoginCallback(int status, string msg, ServerBackLoginInfo callbackInfo) { var loginStatus = status == 0 ? HCLoginStatus.LOGIN_STATUS_SUCC : HCLoginStatus.LOGIN_STATUS_FAILED; var loginTypeEnum = (HCLoginType)Enum.ToObject(typeof(HCLoginType), callbackInfo.user_type); HCTools.SavePlayerPrefsString(staticSaveKey_UserID, callbackInfo.user_id); HCTools.SavePlayerPrefsString(staticSaveKey_Token, callbackInfo.token); HCTools.SavePlayerPrefsInt(staticSaveKey_UserType, callbackInfo.user_type); LoginInfo loginInfo = new LoginInfo(); loginInfo.loginStatus = loginStatus; loginInfo.userInfo = new UserInfo(); loginInfo.userInfo.loginType = loginTypeEnum; loginInfo.loginMsg = msg; loginInfo.userInfo.userID = callbackInfo.user_id; loginInfo.userInfo.token = callbackInfo.token; loginInfo.userInfo.email = ""; loginInfo.userInfo.nickName = ""; loginInfo.userInfo.photoUrl = ""; if (loginStatus == HCLoginStatus.LOGIN_STATUS_SUCC) { CurrUserInfo = loginInfo.userInfo; HCAnalyticsManager.Instance.SetUserId(loginInfo.userInfo.userID); } mLoginResultCallback?.Invoke(loginInfo); // 事件埋点 if (HCTools.IfFirstCheckPlayerPrefs(string.Format("{0}_IfFirst_Result", HCInnerStaticSting.HC_Login_CreateTKUserid))) { if (loginStatus == HCLoginStatus.LOGIN_STATUS_SUCC) { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_CreateTKUserid_Success, HCInnerStaticSting.HC_Account, GetLoginTypeString(loginInfo.userInfo.loginType)); } else { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_CreateTKUserid_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(loginInfo.userInfo.loginType), "fail_reason", msg); } } // 事件埋点 if (loginStatus == HCLoginStatus.LOGIN_STATUS_SUCC) { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_Enter_Success, HCInnerStaticSting.HC_Account, GetLoginTypeString(loginInfo.userInfo.loginType)); } else { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Login_Enter_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(loginInfo.userInfo.loginType), "fail_reason", msg); } } /// /// 自动登录 /// /// public void AutoLogin(Action _loginResultCallback = null) { if (!IsCanAutoLogin()) { Login(HCLoginType.LOGIN_BY_GUESTER, _loginResultCallback); } else { var lastLoginType = HCTools.GetPlayerPrefsInt(staticSaveKey_LastLoginType); Login((HCLoginType)Enum.ToObject(typeof(HCLoginType), lastLoginType), _loginResultCallback); } } /// /// 获取当前用户类型 /// /// public HCLoginType GetAccountType() { int userType = HCTools.GetPlayerPrefsInt(staticSaveKey_UserType); return (HCLoginType)Enum.ToObject(typeof(HCLoginType), userType); } /// /// 是否可自动登录 /// /// public bool IsCanAutoLogin() { return HCTools.HasKey(staticSaveKey_LastLoginType); } /// /// 登出 /// /// public void Logout(Action _logoutCallback = null) { HCTools.DeleteKey(staticSaveKey_LastLoginType); HCTools.DeleteKey(staticSaveKey_UserID); HCTools.DeleteKey(staticSaveKey_UserType); HCTools.DeleteKey(staticSaveKey_Token); if(null != CurrUserInfo) { CurrUserInfo.ClearData(); } _logoutCallback?.Invoke(); HCNativeInterface.Instance.Logout(); HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Logout_Success, HCInnerStaticSting.HC_Account, GetLoginTypeString(CurrUserInfo.loginType)); } /// /// 获取支持登录类型列表 /// 在线参数配置:0,1,2 /// /// public List AvailableLoginChannelList() { string loginChannels = HCSDKManager.Instance.GetRemoteConfigStr(staticOnlineKey_loginChannels, "0,2"); if (string.IsNullOrEmpty(loginChannels)) { loginChannels = "0,2"; } return loginChannels.Split(',') .Select(channel => (HCLoginType)Enum.ToObject(typeof(HCLoginType), int.Parse(channel))).ToList(); } /// /// 删除账号 /// /// public void DeleteAccount(Action deleteAccountCallback = null) { DeleteAccountByServer(HCTools.GetPlayerPrefsString(staticSaveKey_UserID), (code, msg) => { // 退出账号 if(code == 0) { Logout(); } deleteAccountCallback?.Invoke( code == 0 ? HCDeleteStatus.DELETE_ACCOUNT_SUCC : HCDeleteStatus.DELETE_ACCOUNT_FAILED, msg); // 事件埋点 if (code == 0) { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Delete_Account_Success, HCInnerStaticSting.HC_Account, HCInnerStaticSting.HC_Delete_Account_Success); } else { HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Delete_Account_Success, HCInnerStaticSting.HC_Account, HCInnerStaticSting.HC_Delete_Account_Fail); } }); } // 保存当前绑定类型 private HCBindType currBindType = HCBindType.NO_FORCE; // 保存当前要绑定的userID private string currUserID = ""; // 保存绑定回调 private Action currBindAccountCallback = null; /// /// 绑定账号 /// /// /// /// /// public void BindAccount(HCLoginType type, HCBindType isForce, string userId, Action bindAccountCallback) { currBindType = isForce; currUserID = userId; currBindAccountCallback = bindAccountCallback; // 调用三方登录 HCNativeInterface.Instance.Login(type, ThirdLoginCallbackForBind); // 事件埋点 HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind, HCInnerStaticSting.HC_Account, GetLoginTypeString(type)); } /// /// 绑定时三方登录回调,请求服务器绑定 /// /// private void ThirdLoginCallbackForBind(LoginInfo _thirdLoginInfo) { if (_thirdLoginInfo.loginStatus != HCLoginStatus.LOGIN_STATUS_SUCC) { var bindInfo = new BindInfo { userInfo = _thirdLoginInfo.userInfo, bindStatus = HCBindAccountStatus.BIND_CODE_FAILED, bindMsg = _thirdLoginInfo.loginMsg }; HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(_thirdLoginInfo.userInfo.loginType), "fail_reason", $"bind error from login :{_thirdLoginInfo.loginMsg}"); HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Login_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(_thirdLoginInfo.userInfo.loginType), "fail_reason", $"bind error from login :{_thirdLoginInfo.loginMsg}"); currBindAccountCallback?.Invoke(bindInfo); return; } if (currBindType == HCBindType.NO_FORCE) { currUserID = HCTools.GetPlayerPrefsString(staticSaveKey_UserID); } if (_thirdLoginInfo.loginStatus == HCLoginStatus.LOGIN_STATUS_SUCC) { CallBind2Server(_thirdLoginInfo.userInfo, currBindType, _thirdLoginInfo.userInfo.userID, currUserID, currBindAccountCallback); } } /// /// 调用服务器方法操作绑定 /// /// /// /// /// /// private void CallBind2Server(UserInfo userInfo, HCBindType isForce, string thirdUserId, string userId, Action bindAccountCallback) { BindByServer(userInfo, isForce, thirdUserId, userId, (status, msg, data) => { if (status != 0) { BindInfo bindInfo = new BindInfo(); bindInfo.bindStatus = HCBindAccountStatus.BIND_CODE_FAILED; bindInfo.userInfo = new UserInfo(); bindInfo.userInfo.loginType = userInfo.loginType; bindInfo.bindMsg = msg; bindInfo.userInfo.userID = data.user_id; bindInfo.userInfo.token = data.token; bindInfo.userInfo.email = userInfo.email; bindInfo.userInfo.nickName = userInfo.nickName; bindInfo.userInfo.photoUrl = userInfo.photoUrl; bindInfo.userIDs = data.user_ids; bindAccountCallback.Invoke(bindInfo); // 事件埋点 HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(userInfo.loginType), "fail_reason", msg); HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Login_Fail, HCInnerStaticSting.HC_Account, GetLoginTypeString(userInfo.loginType), "fail_reason", $"bind error from login :{msg}"); return; } if (data.user_ids != null && data.user_ids.Length == 2) { // (status, loginTYpe, msg, userId, token, email, displayName, photoUrl, userIdList) BindInfo bindInfo = new BindInfo(); bindInfo.bindStatus = HCBindAccountStatus.BIND_CODE_SELECT; bindInfo.userInfo = new UserInfo(); bindInfo.userInfo.loginType = userInfo.loginType; bindInfo.bindMsg = msg; bindInfo.userInfo.userID = data.user_id; bindInfo.userInfo.token = data.token; bindInfo.userInfo.email = userInfo.email; bindInfo.userInfo.nickName = userInfo.nickName; bindInfo.userInfo.photoUrl = userInfo.photoUrl; bindInfo.userIDs = data.user_ids; bindAccountCallback.Invoke(bindInfo); // 事件埋点 HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Conflict, HCInnerStaticSting.HC_Account, GetLoginTypeString(userInfo.loginType)); } else // 绑定成功 { HCTools.SavePlayerPrefsString(staticSaveKey_UserID, data.user_id); HCTools.SavePlayerPrefsString(staticSaveKey_Token, data.token); HCTools.SavePlayerPrefsInt(staticSaveKey_UserType, (int)userInfo.loginType); BindInfo bindInfo = new BindInfo(); bindInfo.bindStatus = HCBindAccountStatus.BIND_CODE_SUCC; bindInfo.userInfo = new UserInfo(); bindInfo.userInfo.loginType = userInfo.loginType; bindInfo.bindMsg = msg; bindInfo.userInfo.userID = data.user_id; bindInfo.userInfo.token = data.token; bindInfo.userInfo.email = userInfo.email; bindInfo.userInfo.nickName = userInfo.nickName; bindInfo.userInfo.photoUrl = userInfo.photoUrl; bindInfo.userIDs = data.user_ids; CurrUserInfo = bindInfo.userInfo; // 保存当前登录信息 bindAccountCallback.Invoke(bindInfo); // 事件埋点 HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Success, HCInnerStaticSting.HC_Account, GetLoginTypeString(userInfo.loginType)); HCAnalyticsManager.Instance.TrackEvent(HCInnerStaticSting.HC_Click_Bind_Login_Success, HCInnerStaticSting.HC_Account, GetLoginTypeString(userInfo.loginType)); } }); } #region server private void LoginByServer(UserInfo userInfo, Action callback) { Debug.Log("userInfo : " + userInfo); // userInfo.ext?.TryGetValue("anonymousCode", out var anonymousCode); var body = new Dictionary() { ["user_type"] = (int)userInfo.loginType, ["third_uid"] = userInfo.userID, ["user_id"] = HCTools.GetPlayerPrefsString(staticSaveKey_UserID), ["third_token"] = userInfo.token, ["email"] = userInfo.email, ["photoUrl"] = userInfo.photoUrl, ["displayName"] = userInfo.nickName, }; HCDebugger.LogDebug("zj third_token : " + userInfo.token + " , userID : " + userInfo.userID + ", third_id : " + HCTools.GetPlayerPrefsString(staticSaveKey_UserID)); HCServer.Instance.Post(HCServer.URL_LOGIN, body, callback); } public void BindByServer(UserInfo userInfo, HCBindType bindType, string thirdUid, string userId, Action callback) { var args = new Dictionary { { "user_type", (int)userInfo.loginType }, { "third_uid", thirdUid }, { "user_id", userId }, { "is_force", (int)bindType }, { "third_token", userInfo.token }, { "email", userInfo.email }, { "photoUrl", userInfo.photoUrl }, { "displayName", userInfo.nickName }, }; HCServer.Instance.Post(HCServer.URL_BIND, args, callback); } public void DeleteAccountByServer(string userId, Action callback) { if (string.IsNullOrEmpty(userId)) { callback?.Invoke((int)HCDeleteStatus.DELETE_ACCOUNT_FAILED, "empty userID by client."); return; } var args = new Dictionary { { "user_id", userId } }; HCServer.Instance.Post(HCServer.URL_DELETE, args, (code, msg, obj) => { callback.Invoke(code, code == 0 ? userId : msg); }); } /// /// 根据登录类别,获取对应登录事件名称 /// /// /// public string GetLoginTypeString(HCLoginType _loginType) { switch (_loginType) { case HCLoginType.LOGIN_BY_GUESTER: return "Guest"; //Google/Facebook/Geust case HCLoginType.LOGIN_BY_GOOGLE: return "Google"; case HCLoginType.LOGIN_BY_FACEBOOK: return "Facebook"; case HCLoginType.LOGIN_BY_Apple: return "Apple"; case HCLoginType.LOGIN_BY_EMAIL: return "Email"; case HCLoginType.LOGIN_BY_WECHAT_MINI_GAME: return "wechat_mini_game"; default: return "Unknow"; } } /// /// 获取当前UserInfo /// /// public UserInfo GetCurrUserInfo() { return CurrUserInfo; } #endregion } // 登录状态码,登录类型,登录状态信息,userid,token,邮箱 , 显示名称 , 头像url [System.Serializable] public struct LoginInfo { public HCLoginStatus loginStatus; public string loginMsg; public UserInfo userInfo; } // HCBindAccountStatus, HCLoginType, string, string, string, string, string, string, string[] [System.Serializable] public struct BindInfo { public HCBindAccountStatus bindStatus; public string bindMsg; public UserInfo userInfo; public string[] userIDs; } [System.Serializable] public class UserInfo { public HCLoginType loginType; public string userID = ""; public string token = ""; public string email = ""; public string nickName = ""; public string photoUrl = ""; public void ClearData() { userID = ""; token = ""; email = ""; nickName = ""; photoUrl = ""; } } [System.Serializable] public struct ServerBackLoginInfo { public string user_id; public string token; public int user_type; public int first_login; } [System.Serializable] public struct ServerBackBindInfo { public string user_id; public string token; public string[] user_ids; } }