using SC.XR.Unity; using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using System; using LitJson; public class AuthenticationManager : SingletonMono { //存储包名和ChannelId private const string CHANNEL_SAVE_KEY = "CHANNEL_SAVE_KEY"; //存储鉴权数据 private const string AUTHENTICATION_SAVE_KEY = "AUTHENTICATION_SAVE_KEY"; //存储上报数据 private const string REPORT_SAVE_KEY = "REPORT_SAVE_KEY"; //请求地址 private const UrlName URL_NAME = UrlName.pro; //token过期时间 private const int EXPIRE_DAYS = 6; //游戏时间 private const int GAME_EXPIRE_MINUTES = 1440; public UrlConfig urlConfig; public Action onAuthenticationEventCallback; //private string unionId = null; private AuthenticationData localAuthenticationData; //计时器 private float timer = 0f; //查看频率 private float checkPerSecond = 60f; //启动Id private string gameBootId = string.Empty; //启动时间 private DateTime gameBootTime; private int alreadyPlayedMinutes = 0; private bool alreadyGetAuthentication = false; //[HideInInspector] public bool testMode = false; public string testUserId = "202"; //private NetworkReachability previousNetworkReachAbility; //初始化,设置Binder监听, private void Awake() { NetworkReachability networkReachability = Application.internetReachability; Init(); GetPackageInfoByChannel(GetChannelId()); } private void OnApplicationPause(bool pause) { return; if (!pause && alreadyGetAuthentication) { GetAuthenticationInfo(); } } private void Init() { SetAuthenticationUnionIdListener(); } private void SetAuthenticationUnionIdListener() { #if !UNITY_EDITOR AndroidJavaClass loginManager = new AndroidJavaClass("com.xr.login.LoginManager"); AndroidJavaObject loginManagerInstance = loginManager.CallStatic("getInstance"); loginManagerInstance.Call("setGetLoginInfoUnityListener", new AuthenticationLoginListener(OnGetLoginInfo, OnServiceConnectError)); #endif } //获取UnionId private void GetLoginInfo(string packageName) { Debug.Log("getLoginInfoFromAppStore"); if (testMode) { Debug.LogError("TestMode"); OnGetLoginInfo(JsonUtility.ToJson(new LoginInfo() { unionId = testUserId })); return; } #if UNITY_EDITOR OnGetLoginInfo(JsonUtility.ToJson(new LoginInfo() { unionId = testUserId })); return; #endif AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject unityActivity = unityClass.GetStatic("currentActivity"); AndroidJavaClass loginManager = new AndroidJavaClass("com.xr.login.LoginManager"); AndroidJavaObject loginManagerInstance = loginManager.CallStatic("getInstance"); loginManagerInstance.Call("getLoginInfoFromAppStore", unityActivity, packageName); } //获取渠道Id private string GetChannelId() { if (testMode) { return "0"; } #if !UNITY_EDITOR AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject unityActivity = unityClass.GetStatic("currentActivity"); AndroidJavaClass loginManager = new AndroidJavaClass("com.xr.login.LoginManager"); AndroidJavaObject loginManagerInstance = loginManager.CallStatic("getInstance"); return loginManagerInstance.Call("getChannelId", unityActivity); #else return "0"; #endif } //private string GetSerialno() //{ // AndroidJavaClass loginManager = new AndroidJavaClass("com.xr.login.LoginManager"); // AndroidJavaObject loginManagerInstance = loginManager.CallStatic("getInstance"); // string serialno = loginManagerInstance.Call("getSerialno"); // Debug.Log("Serialno:" + serialno); // return serialno; //} //获取包名 private string GetChannelPackageName() { string channelId = GetChannelId(); Debug.Log("GetChannelPackageName:" + channelId); ChannelDataList channelDataList = LoadChannelData(); List channelDatas = channelDataList.channelDatas.Where(item => item.channelId == channelId).ToList(); if (channelDatas == null || channelDatas.Count == 0) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.GetChannelPackageNameFail, channelId); return string.Empty; } return channelDatas[0].packageName; } //呼出登录界面 private void ShowLoginDialog() { string packageName = GetChannelPackageName(); if (string.IsNullOrEmpty(packageName)) { return; } AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject unityActivity = unityClass.GetStatic("currentActivity"); AndroidJavaClass loginManager = new AndroidJavaClass("com.xr.login.LoginManager"); AndroidJavaObject loginManagerInstance = loginManager.CallStatic("getInstance"); loginManagerInstance.Call("showLoginDialog", unityActivity, Application.identifier, packageName); } private void OnServiceConnectError() { if (Application.internetReachability == NetworkReachability.NotReachable) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.CannotGetChannelUserId, ""); return; } ShowLoginDialog(); } private void OnGetLoginInfo(string loginInfoStr) { Debug.Log("OnGetLoginInfo:" + loginInfoStr); LoginInfo loginInfo = JsonUtility.FromJson(loginInfoStr); //无网状态下 if (Application.internetReachability == NetworkReachability.NotReachable) { //无网状态无法获取个人中心用户信息 if (loginInfo == null || string.IsNullOrEmpty(loginInfo.unionId)) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.CannotGetChannelUserId, ""); return; } //无网状态本地鉴权信息与个人中心不一致,需要联网 if (localAuthenticationData.channelUserId != loginInfo.unionId) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.ChannelUserIdNotMatch, "channelUserId:" + localAuthenticationData.channelUserId + " " + " unionId:" + loginInfo.unionId); return; } //无网状态本地鉴权信息已过期 if (CheckExpire()) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.LocalAuthenticationExpire, localAuthenticationData.refreshTime.ToString()); return; } onAuthenticationEventCallback?.Invoke(AuthenticationEvent.LocalAuthenticationOK, JsonUtility.ToJson(localAuthenticationData)); return; } //有网状态无法获取个人中心用户信息 if (loginInfo == null || string.IsNullOrEmpty(loginInfo.unionId)) { ShowLoginDialog(); return; } string channelId = GetChannelId(); #if !UNITY_EDITOR string appPackageName = Application.identifier; #else string appPackageName = "com.Company.jianping"; #endif string deviceId = API_Module_Device.Current.SN; //GetSerialno();// GetNetworkAuthenticationInfo(channelId, appPackageName, deviceId, loginInfo.unionId); } //判断token是否过期,判断游戏时间是否过期 private bool CheckExpire() { if (localAuthenticationData != null) { TimeSpan expireTimeSpan = DateTime.Now - TimeUtils.ConvertToDateTime(localAuthenticationData.refreshTime); return expireTimeSpan.TotalDays > EXPIRE_DAYS || localAuthenticationData.playMinutes > GAME_EXPIRE_MINUTES || DateTime.Now < TimeUtils.ConvertToDateTime(localAuthenticationData.checkTime); } return true; } private void Update() { if (localAuthenticationData == null) { return; } if (string.IsNullOrEmpty(gameBootId)) { gameBootId = Guid.NewGuid().ToString(); gameBootTime = DateTime.Now; alreadyPlayedMinutes = localAuthenticationData.playMinutes; GenerateReportData(1); GenerateReportData(3); } timer += Time.deltaTime; if (timer > checkPerSecond) { timer = 0f; GenerateReportData(2); GenerateReportData(3); UpdateReportData(); //在游戏中出现过期 if (CheckExpire()) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.LocalAuthenticationExpire, localAuthenticationData.refreshTime.ToString()); if (Application.internetReachability != NetworkReachability.NotReachable) { ShowLoginDialog(); } } else { TimeSpan timeSpan = DateTime.Now - gameBootTime; Debug.Log("playMinutes:" + Mathf.RoundToInt((float)timeSpan.TotalMinutes) + " alreadyPlayMinutes:" + alreadyPlayedMinutes); localAuthenticationData.playMinutes = alreadyPlayedMinutes + Mathf.RoundToInt((float)timeSpan.TotalMinutes); localAuthenticationData.checkTime = TimeUtils.ConvertToTimeStamp(DateTime.Now); SaveAuthenticationData(localAuthenticationData); } } } public void GetAuthenticationInfo() { alreadyGetAuthentication = true; string channelPackageName = GetChannelPackageName(); if (string.IsNullOrEmpty(channelPackageName)) { return; } Debug.Log("ChannelPackageName:" + channelPackageName); if (Application.internetReachability == NetworkReachability.NotReachable) { GetLocalAuthenticationInfo(channelPackageName); return; } GetLoginInfo(channelPackageName); } public void GetPackageInfoByChannel(string channelId) { string requestUrl = GetConfigUrl() + NetworkApiConstant.SDK_PACKAGENAME; Dictionary headerDic = new Dictionary(); headerDic.Add("Content-Type", "application/json"); PackageInfoRequestData packageInfoRequestData = new PackageInfoRequestData(); packageInfoRequestData.channelId = channelId; AuthenticationNetworkManager.Instance.Post(requestUrl, headerDic, packageInfoRequestData, (responseStr) => { PackageInfoResponseData packageInfoResponseData = JsonUtility.FromJson(responseStr); if (packageInfoResponseData.code == 200) { Debug.Log("channelId:" + channelId + " packageName:" + packageInfoResponseData.data.packageName); RefreshChannelData(channelId, packageInfoResponseData.data.packageName); } }, (errorStr) => { //do nothing }, EncryptUtils.AesEncrypt); } //联网获取鉴权信息 private void GetNetworkAuthenticationInfo(string channelId, string appPackageName, string deviceId, string unionId) { string requestUrl = GetConfigUrl() + NetworkApiConstant.SDK_AUTHENTICATION; //"http://yapi.tech.shadowcreator.com/mock/205/v1/sdk/authentication?status=ok"; Dictionary headerDic = new Dictionary(); headerDic.Add("Content-Type", "application/json"); AuthenticationRequestData authenticationRequestData = new AuthenticationRequestData(); authenticationRequestData.channelId = channelId; authenticationRequestData.appPackageName = appPackageName; authenticationRequestData.deviceId = deviceId; authenticationRequestData.channelUserId = unionId; //Debug.LogError("RequestUrl:" + requestUrl); AuthenticationNetworkManager.Instance.Post(requestUrl, headerDic, authenticationRequestData, (responseStr) => { //Debug.LogError("Response:" + responseStr); AuthenticationResponseData authenticationResponseData = JsonUtility.FromJson(responseStr); if (authenticationResponseData.code == 200) { authenticationResponseData.data.refreshTime = TimeUtils.ConvertToTimeStamp(DateTime.Now); authenticationResponseData.data.checkTime = TimeUtils.ConvertToTimeStamp(DateTime.Now); authenticationResponseData.data.playMinutes = 0; localAuthenticationData = authenticationResponseData.data; SaveAuthenticationData(authenticationResponseData.data); onAuthenticationEventCallback?.Invoke(AuthenticationEvent.NetworkAuthenticationOK, JsonUtility.ToJson(authenticationResponseData.data)); } else { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.NetworkAuthenticationFail, authenticationResponseData.code.ToString()); //ShowLoginDialog(); } }, (errorStr) => { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.NetworkAuthenticationFail, "NetworkError"); //ShowLoginDialog(); }, EncryptUtils.AesEncrypt); } //获取本地鉴权信息 private void GetLocalAuthenticationInfo(string packageName) { localAuthenticationData = LoadAuthenticationData(); //判断本地是否保存鉴权信息 if (localAuthenticationData == null) { onAuthenticationEventCallback?.Invoke(AuthenticationEvent.NoAuthenticationDataInLocal, ""); return; } GetLoginInfo(packageName); } private string GetConfigUrl() { List urlDataList = urlConfig.urls; if (urlDataList == null) { Debug.LogError("urlConfig not config"); return null; } List selectUrlDataList = urlDataList.Where((item) => item.urlName == URL_NAME).ToList(); if (selectUrlDataList == null || selectUrlDataList.Count == 0) { Debug.LogError("selectUrlDataList is null or empty"); return null; } return selectUrlDataList.First().url; } public void SaveAuthenticationData(AuthenticationData authenticationData) { PlayerPrefs.SetString(AUTHENTICATION_SAVE_KEY, JsonUtility.ToJson(authenticationData)); PlayerPrefs.Save(); } public AuthenticationData LoadAuthenticationData() { string json = PlayerPrefs.GetString(AUTHENTICATION_SAVE_KEY, string.Empty); return JsonUtility.FromJson(json); } public void SaveReportData(ReportDataList reportDataList) { PlayerPrefs.SetString(REPORT_SAVE_KEY, JsonUtility.ToJson(reportDataList)); PlayerPrefs.Save(); } public ReportDataList LoadReportData() { string json = PlayerPrefs.GetString(REPORT_SAVE_KEY, string.Empty); return JsonUtility.FromJson(json); } public void SaveChannelData(ChannelDataList channelDataList) { PlayerPrefs.SetString(CHANNEL_SAVE_KEY, JsonUtility.ToJson(channelDataList)); PlayerPrefs.Save(); } public ChannelDataList LoadChannelData() { string json = PlayerPrefs.GetString(CHANNEL_SAVE_KEY, string.Empty); if (string.IsNullOrEmpty(json)) { ChannelDataList channelDataList = new ChannelDataList(); channelDataList.channelDatas = new List(); ChannelData defaultNoloData = new ChannelData(); defaultNoloData.channelId = "4120948381"; defaultNoloData.packageName = "com.nolo"; ChannelData defaultMovisionxrData = new ChannelData(); defaultMovisionxrData.channelId = "1335068101"; defaultMovisionxrData.packageName = "com.movisionxr.unitysdk"; ChannelData defaultDemoData = new ChannelData(); defaultDemoData.channelId = "4938271003"; defaultDemoData.packageName = "com.demo"; ChannelData defaultTestData = new ChannelData(); defaultDemoData.channelId = "0"; defaultDemoData.packageName = "Test"; channelDataList.channelDatas.Add(defaultNoloData); channelDataList.channelDatas.Add(defaultMovisionxrData); channelDataList.channelDatas.Add(defaultDemoData); channelDataList.channelDatas.Add(defaultTestData); return channelDataList; } return JsonUtility.FromJson(json); } public void RefreshChannelData(string channelId, string packageName) { ChannelDataList channelDataList = LoadChannelData(); for (int i = 0; i < channelDataList.channelDatas.Count; i++) { ChannelData channelData = channelDataList.channelDatas[i]; if (channelData.channelId == channelId) { channelData.packageName = packageName; } } SaveChannelData(channelDataList); } #region 上报数据 public void GenerateReportData(int status) { if (testMode) return; ReportDataList reportDataList = LoadReportData(); if (reportDataList == null) { reportDataList = new ReportDataList(); reportDataList.datas = new List(); } if (status != 3) { ReportData reportData = new ReportData(); reportData.gameBootId = gameBootId; reportData.reportId = Guid.NewGuid().ToString(); reportData.status = status; reportData.startTime = GetTimeStampSeconds(gameBootTime); reportData.runTime = GetRunSeconds(); reportDataList.datas.Add(reportData); } else { ChangeEndGameRuntime(reportDataList.datas); } SaveReportData(reportDataList); } //修改结束游戏时间/新增游戏结束时间 private void ChangeEndGameRuntime(List reportDataList) { for (int i = 0; i < reportDataList.Count; i++) { ReportData reportData = reportDataList[i]; if (reportData.status == 3 && reportData.gameBootId == gameBootId) { reportData.runTime = GetRunSeconds(); return; } } ReportData newReportData = new ReportData(); newReportData.gameBootId = gameBootId; newReportData.reportId = Guid.NewGuid().ToString(); newReportData.status = 3; newReportData.startTime = GetTimeStampSeconds(gameBootTime); newReportData.runTime = GetRunSeconds(); reportDataList.Add(newReportData); } private void UpdateReportData() { if (Application.internetReachability == NetworkReachability.NotReachable) { Debug.LogError("Cannot Update Report Data, no network"); return; } string channelId = GetChannelId(); string deviceId = API_Module_Device.Current.SN;//GetSerialno(); string deviceBrand = "ShadowCreator"; string deviceModel = API_Module_Device.Current.DeviceName; string systemName = SystemInfo.operatingSystem; string systemVersion = SystemInfo.operatingSystem; string androidVersion = API_Module_Device.Current.RELEASE_VERSION; string channelUserId = localAuthenticationData.channelUserId; #if !UNITY_EDITOR string appPackageName = Application.identifier; #else string appPackageName = "com.Company.jianping"; #endif Debug.Log("deviceModel:" + deviceModel + " deviceId:" + deviceId); ReportDataList reportDataList = LoadReportData(); if (reportDataList == null) { return; } List uploadReportDataList = reportDataList.datas.Where(item => item.status != 3 || (item.status == 3 && item.gameBootId != gameBootId)).ToList(); //for (int i = 0; i < uploadReportDataList.Count; i++) //{ //ReportData uploadReportData = uploadReportDataList[i]; SendReportInfo(channelId, deviceId, deviceBrand, deviceModel, systemName, systemVersion, androidVersion, channelUserId, appPackageName, uploadReportDataList, (reportId) => { ReportDataList localReportData = LoadReportData(); int removeCount = reportDataList.datas.RemoveAll(item => item.status != 3 || (item.status == 3 && item.gameBootId != gameBootId)); Debug.LogError("删除" + removeCount.ToString() + "条数据"); SaveReportData(reportDataList); }); //} } //上报数据接口 private void SendReportInfo(string channelId, string deviceId, string deviceBrand, string deviceModel, string systemName, string systemVersion, string androidVersion, string channelUserId, string appPackageName, List reportData, Action onReportSuccess) { if (testMode) return; string requestUrl = GetConfigUrl() + NetworkApiConstant.SDK_REPORT; Dictionary headerDic = new Dictionary(); headerDic.Add("Content-Type", "application/json"); ReportRequestDataList reportRequestDataList = new ReportRequestDataList(); reportRequestDataList.data = new List(); for (int i = 0; i < reportData.Count; i++) { ReportRequestData reportRequestData = new ReportRequestData(); reportRequestData.channelId = channelId; reportRequestData.deviceId = deviceId; reportRequestData.deviceBrand = deviceBrand; reportRequestData.deviceModel = deviceModel; reportRequestData.systemName = systemName; reportRequestData.systemVersion = systemVersion; reportRequestData.androidVersion = androidVersion; reportRequestData.channelUserId = channelUserId; reportRequestData.appPackageName = appPackageName; reportRequestData.status = reportData[i].status; reportRequestData.startTime = reportData[i].startTime; reportRequestData.runTime = reportData[i].runTime; reportRequestData.runUniqTag = reportData[i].gameBootId; reportRequestData.singleRunTime = reportData[i].status == 2 ? (long)checkPerSecond : 0; reportRequestDataList.data.Add(reportRequestData); } AuthenticationNetworkManager.Instance.Post(requestUrl, headerDic, reportRequestDataList, (responseStr) => { onReportSuccess?.Invoke(responseStr); }, (errorStr) => { }, EncryptUtils.AesEncrypt); } public long GetTimeStampSeconds(DateTime dateTime) { TimeSpan ts = dateTime - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0)); return Convert.ToInt64(ts.TotalSeconds); } public long GetRunSeconds() { TimeSpan ts = DateTime.Now - gameBootTime; return Convert.ToInt64(ts.TotalSeconds); } #endregion }