using System.Collections; using System.Collections.Generic; using UnityEngine; using IVServerFormat; using System; using UnityEngine.Networking; using System.IO; using UnityEngine.Assertions.Must; public class SvConnectManager : MonoSingleton { #region Const public const string HEADER_ConType = "Content-Type"; public const string HEADER_ConTypeValue = "application/json"; public const string HEADER_OSType = "OS-Type"; public const string HEADER_GameVer = "Game-Version"; public const string HEADER_DeviceID = "Device-ID"; public const string HEADER_AccessToken = "Access-Token"; public const string HEADER_Server = "server"; public const string HEADER_UserAgent = "User-Agent"; public const string HEADER_PushToken = "Push-Token"; public const string HEADER_Language = "Language"; public const string HEADER_DeviceToken = "Device-Token"; #if UNITY_EDITOR public const string HValue_OSType = "Unity"; #elif VER_ONESTORE public const string HValue_OSType = "OneStore"; #elif UNITY_ANDROID public const string HValue_OSType = "Google"; #elif UNITY_IOS public const string HValue_OSType = "Apple"; #else public const string HValue_OSType = "Unknown"; #endif #endregion Const #region User Info private static string DeviceID = null; private static string UserAgent = null; #endregion User Info public static int DataSavingCount { get; private set; } = 0; private static bool B_INIT = false; private bool StopConnect = false; #region Server Base public void Init() { if (B_INIT) return; DeviceID = FormatString.CombineAllString(Global.Platform.ToString(), SystemInfo.deviceUniqueIdentifier); #if UNITY_EDITOR UserAgent = FormatString.StringFormat("{0} / {1}", "UnityPlayer", SystemInfo.operatingSystem); #else UserAgent = FormatString.StringFormat("{0} / {1}", SystemInfo.deviceModel, SystemInfo.operatingSystem); #endif B_INIT = true; } // 실행 중에 사용한 모든 데이터 초기화. 게임 재시작 등에서 사용. public void ResetAll() { DeviceID = null; UserAgent = null; StopConnect = false; B_INIT = false; } // 네트워크 상태 확인. private void CheckNetwork() { //error_checknetwork if (Application.internetReachability == NetworkReachability.NotReachable) { if(Time.timeScale > 0) Time.timeScale = 0; Logger.LogWarning("INTERNET NOT AVAIL AT CHECK_NETWORK"); SingleMgr.OpenPopupCheckNet(LocalizationText.GetText("msg_checknetwork"), CheckNetwork); } else { if(Time.timeScale < 1) Time.timeScale = 1.0f; } } // 통신 중지. public void StopConnection() { StopConnect = true; StopAllCoroutines(); AdsMgr.SForceStopCoroutines(); IapMgr.SForceStopCoroutines(); CoverCamera.Reset(); } // 통신 에러 체크. private int CheckError(int status, eErrorCode errorcode, int rescode) { if (status == 500) { switch (errorcode) { case eErrorCode.NONE: return 0; case eErrorCode.UNABLE_REWARD: SingleMgr.OpenPopup1Button(LocalizationText.GetText("msg_unablerew")); return 1; case eErrorCode.COUPON_INVALID: SingleMgr.OpenPopup1Button(LocalizationText.GetText("setting_couponfail")); return 1; case eErrorCode.DB_ROLLBACK: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_db")); return 1; case eErrorCode.DEFAULT_INTERNAL_ERROR: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_sv")); return 1; default: break; } } else { switch (errorcode) { case eErrorCode.NONE: return 0; #region Stop Connection & Game Error (return -1) case eErrorCode.UNAUTHORIZED_ACCESS_TOKEN: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_user"), SingleMgr.GameFinishOnly); StopConnection(); return -1; case eErrorCode.FORBIDDEN_OS: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_os"), SingleMgr.GameFinishOnly); StopConnection(); return -1; case eErrorCode.FORBIDDEN_GAME_VERSION_FORMAT: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_ver"), SingleMgr.GameUpdate, LocalizationText.GetText("all_update"), LocalizationText.GetText("all_update"), false); StopConnection(); return -1; case eErrorCode.FORBIDDEN_GAME_VERSION: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_gamever"), SingleMgr.GameUpdate, LocalizationText.GetText("all_update"), LocalizationText.GetText("all_update"), false); StopConnection(); return -1; case eErrorCode.FORBIDDEN_GAME_MAINTENANCE: SingleMgr.OpenPopup1Button(LocalizationText.GetText("msg_inspect"), SingleMgr.GameFinishOnly); StopConnection(); return -1; case eErrorCode.FORBIDDEN_BAN_USER: SingleMgr.OpenPopup2Button(LocalizationText.GetText("error_block"), SingleMgr.Instance.LogoutAuto, SingleMgr.GameFinishOnly, LocalizationText.GetText("all_logout"), LocalizationText.GetText("all_logout"), LocalizationText.GetText("all_quitdo")); StopConnection(); return -1; case eErrorCode.FORBIDDEN_ACCESS_TOKEN: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_usertoken"), SingleMgr.GameFinishOnly); StopConnection(); return -1; case eErrorCode.MULTI_CONNECTION: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_multiconnect"), SingleMgr.GameFinishOnly); StopConnection(); return -1; case eErrorCode.FORBIDDEN_NOT_ALLOWED: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_notallowed"), SingleMgr.GameFinishOnly); StopConnection(); return -1; #endregion Stop Connection & Game Error (return -1) #region Process Error (return 1) case eErrorCode.BAD_REQUEST_VALIDATION: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_request")); return 1; case eErrorCode.NOT_ENOUGH_CURRENCY: SingleMgr.OpenPopup1Button(LocalizationText.GetText(Global.STR_NoGoods)); return 1; case eErrorCode.NOT_MATCHED_USERDATA: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_data")); return 1; case eErrorCode.NOT_MATCHED_QUEST: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_quest")); return 1; case eErrorCode.NOT_MATCHED_STAGE: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_stage")); return 1; case eErrorCode.DUPLICATED_NAME: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_usedname")); return 1; case eErrorCode.NOT_MATCHED_SPEC: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_spec")); return 1; case eErrorCode.NOT_ENOUGH_DG_JOIN: SingleMgr.OpenPopup1Button(LocalizationText.GetText("msg_noticket")); return 1; case eErrorCode.NOT_MATCHED_DG_DIFF: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_dgdiff")); return 1; case eErrorCode.EMPTY_DATA: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_nodata")); return 1; #endregion Process Error (return 1) case eErrorCode.UNKNOWN: default: break; } } // 응답 코드로 처리. switch (rescode) { #region Stop Connection & Game Error (return -1) case ResCode.NO_AUTHORITY: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_authority"), SingleMgr.GameFinishOnly); StopConnection(); return -1; case ResCode.INVALID_TOKEN: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_token"), SingleMgr.GameFinishOnly); StopConnection(); return -1; #endregion Stop Connection & Game Error (return -1) #region Process Error (return 1) case ResCode.INVALID_REQUEST_FORMAT: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_requestformat")); return 1; case ResCode.NO_FILE: SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_nofile")); return 1; case ResCode.AWS_EXCEPTION: if (status == 500 && (int)errorcode == 301) { SingleMgr.OpenPopup1Button(LocalizationText.GetText("no_samenick_allow")); } else { SingleMgr.OpenPopup1Button(FormatString.StringFormat(LocalizationText.GetText("error_aws"), status.ToString(), ((int)errorcode).ToString())); } return 1; case ResCode.API_EXCEPTION: SingleMgr.OpenPopup1Button(FormatString.StringFormat(LocalizationText.GetText("error_api"), status.ToString(), ((int)errorcode).ToString())); return 1; #endregion Process Error (return 1) default: break; } return 2; } #endregion Server Base #region String // 서버 통신 요청[String]. public void RequestSvString(bool bcover, int iretry, string strurl, Action actionsucc, Action actionfail) { if (StopConnect) return; Logger.Log("RequestSvString : " + strurl); StartCoroutine(SvString(bcover, iretry, strurl, actionsucc, actionfail)); } // 통신[String]. private IEnumerator SvString(bool bcover, int iretry, string strurl, Action actionsucc, Action actionfail) { if (bcover) CoverCamera.Hold(); SvError error = null; string strresult = null; // 네트워크 연결 상태 확인. CheckNetwork(); while (Application.internetReachability == NetworkReachability.NotReachable) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } #region String for (int i = 0; i <= iretry; ++i) { if (i > 0) yield return new WaitForSecondsRealtime(5f); UnityWebRequest request = UnityWebRequest.Get(strurl); request.SetRequestHeader(HEADER_ConType, HEADER_ConTypeValue); request.SetRequestHeader(HEADER_UserAgent, UserAgent); request.SetRequestHeader(HEADER_OSType, HValue_OSType); request.SetRequestHeader(HEADER_GameVer, Global.GameVer.ToString()); request.SetRequestHeader(HEADER_DeviceID, DeviceID); yield return request.SendWebRequest(); #if UNITY_IOS if (!request.isDone || request.downloadHandler.data == null) #else if (!request.isDone || request.result == UnityWebRequest.Result.ConnectionError || request.downloadHandler.data == null) #endif { Logger.LogWarning("Error: RecvDataFromServer : " + request.error); Logger.LogWarning(request.downloadHandler.text); request.Dispose(); if (i < iretry) { yield return new WaitForSecondsRealtime(5f); continue; } else { SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_unstablenetwork")); error = new SvError(eErrorCode.INVALID_USER); break; } } strresult = request.downloadHandler.text.Trim(); bool berror = request.result == UnityWebRequest.Result.ProtocolError; // 에러일 경우. if (berror) { Logger.LogWarning("Sv error from " + strurl); error = new SvError(eErrorCode.UNKNOWN); error.message = "Unkonwn Error."; } request.Dispose(); break; } #endregion String if (error == null || error.code == eErrorCode.NONE) { actionsucc(strresult); } else { if (string.IsNullOrEmpty(strresult)) { Logger.LogWarning("empty result"); } else if (strresult.Length < 512) { Logger.LogWarning(strresult); } else { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(strresult); int ilencnt = sb.Length / 500; while (sb.Length > 500) { Logger.LogWarning(sb.ToString(0, 500)); sb.Remove(0, 500); } Logger.LogWarning(sb.ToString()); } actionfail(error); } if (bcover) CoverCamera.Release(); } #endregion String #region Get /// /// 서버 통신 요청 [GET]. /// /// 통신 도중에 CoverCamera를 통해서 터치를 막을지. /// 통신 실패시 재시도 횟수. /// 통신할 API URL. /// 서버 통신 완료 후 받는 데이터의 형식(class). /// 통신 성공 후 처리. /// 통신 실패 후 처리. /// 서버에 저장되는 유저 플레이 정보(cPlayData)에 영향을 미치는지. /// 유저 토큰 값을 사용 = 로그인 한 상태에서 처리인지. /// 성공: actionsucc(지정한 type의 JSON string). 실패: actionfail(에러 정보) public void RequestSvGet(bool bcover, int iretry, string strurl, Type type, Action actionsucc, Action actionfail, bool bdatasave, bool blogin = true, int iserver = -1) { if (StopConnect) return; Logger.Log("RequestSvGet : " + strurl); StartCoroutine(SvGet(bcover, iretry, strurl, type, actionsucc, actionfail, bdatasave, blogin, iserver)); } // 통신[GET]. private IEnumerator SvGet(bool bcover, int iretry, string strurl, Type type, Action actionsucc, Action actionfail, bool bdatasave, bool blogin, int iserver) { if (bcover) CoverCamera.Hold(); if (blogin && iserver < 0) iserver = DataHandler.PlayData.server; SvError error = null; string strresult = null; object result = null; if (bdatasave) { while (DataSavingCount > 0) { yield return new WaitForSecondsRealtime(0.5f); } DataSavingCount++; } #region Network & Token Check // 네트워크 연결 상태 확인. CheckNetwork(); while (Application.internetReachability == NetworkReachability.NotReachable) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } // 사용자 계정 토큰 갱신 대기. while (blogin && SingleMgr.UserState == SingleMgr.eUserState.Refreshing) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } #endregion Network & Token Check #region Get for (int k = 0; k <= iretry; k++) { if (k > 0) yield return new WaitForSecondsRealtime(5f); if (blogin && (SingleMgr.UserState != SingleMgr.eUserState.Login || string.IsNullOrEmpty(SingleMgr.UserToken))) { if (k < iretry) { if (SingleMgr.UserState != SingleMgr.eUserState.Refreshing) SingleMgr.Instance.LoginRefresh(); yield return new WaitForSecondsRealtime(5f); continue; } SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_user")); error = new SvError(eErrorCode.INVALID_USER); break; } UnityWebRequest request = UnityWebRequest.Get(strurl); request.SetRequestHeader(HEADER_ConType, HEADER_ConTypeValue); request.SetRequestHeader(HEADER_UserAgent, UserAgent); request.SetRequestHeader(HEADER_OSType, HValue_OSType); request.SetRequestHeader(HEADER_GameVer, Global.GameVer.ToString()); request.SetRequestHeader(HEADER_DeviceID, DeviceID); if (blogin) { request.SetRequestHeader(HEADER_AccessToken, SingleMgr.UserToken); request.SetRequestHeader(HEADER_Server, iserver.ToString()); request.SetRequestHeader(HEADER_Language, LocalizationText.LanguageTag); } yield return request.SendWebRequest(); #if UNITY_IOS if (!request.isDone || request.downloadHandler.data == null) #else if (!request.isDone || request.result == UnityWebRequest.Result.ConnectionError || request.downloadHandler.data == null) #endif { Logger.LogWarning("Error: RecvDataFromServer : " + request.error); Logger.LogWarning(request.downloadHandler.text); request.Dispose(); if (k < iretry) { yield return new WaitForSecondsRealtime(5f); continue; } else { SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_unstablenetwork")); error = new SvError(eErrorCode.INVALID_USER); break; } } strresult = request.downloadHandler.text.Trim(); bool berror = request.result == UnityWebRequest.Result.ProtocolError; if (berror) { Logger.LogWarning("Sv error from " + strurl); error = JsonUtility.FromJson(strresult); if (error == null) { error = new SvError(eErrorCode.UNKNOWN); error.message = "Unkonwn Error."; } int ierror = CheckError(error.status, error.code, (int)request.responseCode); if (ierror < 0) { request.Dispose(); yield break; } } else { request.Dispose(); // JSON Parsing. try { result = AsteriskCode.DecodeJson(strresult, type); } catch (Exception e) { Logger.LogWarning("ERROR JSON PARSE: " + e.StackTrace); if (k < iretry) { continue; } else { Logger.LogWarning(strurl + " ERROR : " + strresult); SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_json")); error = new SvError(eErrorCode.PARSE_ERROR); break; } } // 결과 확인. if (result == null) { if (k < iretry) { continue; } else { Logger.LogWarning(strurl + " ERROR : " + strresult); SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_emptydata")); error = new SvError(eErrorCode.DATA_ERROR); break; } } } break; } #endregion Get if (error == null || error.code == eErrorCode.NONE) { actionsucc(result); } else { if (string.IsNullOrEmpty(strresult)) { Logger.LogWarning(strurl + " ERROR : empty result"); } else if (strresult.Length < 512) { Logger.LogWarning(strurl + " ERROR : " + strresult); } else { Logger.LogWarning(strurl + " ERROR : "); System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(strresult); int ilencnt = sb.Length / 500; while (sb.Length > 500) { Logger.LogWarning(sb.ToString(0, 500)); sb.Remove(0, 500); } Logger.LogWarning(sb.ToString()); } actionfail(error); } if (bdatasave) { DataSavingCount--; } if (bcover) CoverCamera.Release(); } #endregion Get #region Post /// /// 서버 통신 요청 [POST]. /// /// 통신 도중에 CoverCamera를 통해서 터치를 막을지. /// 통신 실패시 재시도 횟수. /// 통신할 API URL. /// 서버 통신 완료 후 받는 데이터의 형식(class). /// 통신 성공 후 처리. /// 통신 실패 후 처리. /// 서버로 보낼 데이터. /// 서버에 저장되는 유저 플레이 정보(cPlayData)에 영향을 미치는지. /// 유저 토큰 값을 사용 = 로그인 한 상태에서 처리인지. /// 성공: actionsucc(지정한 type의 JSON string, parameter). 실패: actionfail(에러 정보, parameter) public void RequestSvPost(bool bcover, int iretry, string strurl, Type type, Action actionsucc, Action actionfail, object parameter, bool bdatasave, bool blogin = true, int iserver = -1) { if (StopConnect) return; Logger.Log("RequestSvPost : " + strurl); StartCoroutine(SvPost(bcover, iretry, strurl, type, actionsucc, actionfail, parameter, bdatasave, blogin, iserver)); } public void RequestSvPost(bool bcover, int iretry, string strurl, Action actionsucc, Action actionfail, object parameter, bool bdatasave, bool blogin = true, int iserver = -1) { RequestSvPost(bcover, iretry, strurl, typeof(T), actionsucc, actionfail, parameter, bdatasave, blogin, iserver); } // 통신[POST]. private IEnumerator SvPost(bool bcover, int iretry, string strurl, Type type, Action actionsucc, Action actionfail, object parameter, bool bdatasave, bool blogin, int iserver) { if (bcover) CoverCamera.Hold(); if (blogin && iserver < 0) iserver = DataHandler.PlayData.server; SvError error = null; string strresult = null; object result = null; byte[] jsonbyte = AsteriskCode.EncodeJson(parameter); if (bdatasave) { while (DataSavingCount > 0) { yield return new WaitForSecondsRealtime(0.5f); } DataSavingCount++; } #region Network & Token Check // 네트워크 연결 상태 확인. CheckNetwork(); while (Application.internetReachability == NetworkReachability.NotReachable) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } // 사용자 계정 토큰 갱신 대기. while (blogin && SingleMgr.UserState == SingleMgr.eUserState.Refreshing) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } #endregion Network & Token Check #region Post for (int k = 0; k <= iretry; k++) { if (k > 0) yield return new WaitForSecondsRealtime(5f); if (blogin && (SingleMgr.UserState != SingleMgr.eUserState.Login || string.IsNullOrEmpty(SingleMgr.UserToken))) { if (k < iretry) { if (SingleMgr.UserState != SingleMgr.eUserState.Refreshing) SingleMgr.Instance.LoginRefresh(); yield return new WaitForSecondsRealtime(5f); continue; } SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_user")); error = new SvError(eErrorCode.INVALID_USER); break; } UnityWebRequest request = new UnityWebRequest(strurl, "POST"); request.uploadHandler = new UploadHandlerRaw(jsonbyte); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader(HEADER_ConType, HEADER_ConTypeValue); request.SetRequestHeader(HEADER_UserAgent, UserAgent); request.SetRequestHeader(HEADER_OSType, HValue_OSType); request.SetRequestHeader(HEADER_GameVer, Global.GameVer.ToString()); request.SetRequestHeader(HEADER_DeviceID, DeviceID); if (blogin) { request.SetRequestHeader(HEADER_AccessToken, SingleMgr.UserToken); request.SetRequestHeader(HEADER_Server, iserver.ToString()); request.SetRequestHeader(HEADER_Language, LocalizationText.LanguageTag); } yield return request.SendWebRequest(); #if UNITY_IOS if (!request.isDone || request.downloadHandler.data == null) #else if (!request.isDone || request.result == UnityWebRequest.Result.ConnectionError || request.downloadHandler.data == null) #endif { Logger.LogWarning("Error: RecvDataFromServer : " + request.error); Logger.LogWarning(request.downloadHandler.text); request.Dispose(); if (k < iretry) { yield return new WaitForSecondsRealtime(5f); continue; } else { SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_unstablenetwork")); error = new SvError(eErrorCode.INVALID_USER); break; } } strresult = request.downloadHandler.text.Trim(); bool berror = request.result == UnityWebRequest.Result.ProtocolError; #region Error // 에러일 경우. if (berror) { Logger.LogWarning("Sv error from " + strurl); try { error = JsonUtility.FromJson(strresult); } catch { } if (error == null) { error = new SvError(eErrorCode.UNKNOWN); error.message = "Unkonwn Error."; } int ierror = CheckError(error.status, error.code, (int)request.responseCode); if (ierror < 0) yield break; } #endregion Error request.Dispose(); // 에러가 아닐 경우. if (!berror) { // JSON Parsing. try { result = AsteriskCode.DecodeJson(strresult, type); } catch (System.Exception e) { Logger.LogWarning("ERROR JSON PARSE: " + e.StackTrace); if (k < iretry) { continue; } else { Logger.LogWarning(strurl + " ERROR : " + strresult); SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_json")); error = new SvError(eErrorCode.PARSE_ERROR); break; } } // 결과 확인. if (result == null) { if (k < iretry) { continue; } else { Logger.LogWarning(strurl + " ERROR : " + strresult); SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_emptydata")); error = new SvError(eErrorCode.DATA_ERROR); break; } } } break; } #endregion Post if (error == null || error.code == eErrorCode.NONE) { actionsucc(result, parameter); } else { if (string.IsNullOrEmpty(strresult)) { Logger.LogWarning(strurl + " ERROR : empty result"); } else if (strresult.Length < 512) { Logger.LogWarning(strurl + " ERROR : " + strresult); } else { Logger.LogWarning(strurl + " ERROR : "); System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(strresult); int ilencnt = sb.Length / 500; while (sb.Length > 500) { Logger.LogWarning(sb.ToString(0, 500)); sb.Remove(0, 500); } Logger.LogWarning(sb.ToString()); } actionfail(error, parameter); } if (bdatasave) { DataSavingCount--; } if (bcover) CoverCamera.Release(); } #endregion Post #region Event Image public const int HR_ERROR_HANDLE_DISK_FULL = unchecked((int)0x80070027); public const int HR_ERROR_DISK_FULL = unchecked((int)0x80070070); public const string DIR_Events = "/Events"; public const string PATH_Events = "/Events/{0}"; public const string PREFS_Events = "evimg_{0}"; private static bool UpdateImgList = false; private static Dictionary dicEventImageList = new Dictionary(); private static Dictionary dicEventImage = new Dictionary(); // 이미지 목록 다운로드 시도. public void RequestEventImageList() { if (StopConnect || UpdateImgList) return; // Check Directory string strevdir = Application.persistentDataPath + DIR_Events; if (!Directory.Exists(strevdir)) { Directory.CreateDirectory(strevdir); } StartCoroutine(nameof(SvEventImageList)); } // 이미지 목록 다운로드[GET]. private IEnumerator SvEventImageList() { // 네트워크 연결 상태 확인. UpdateImgList = true; CheckNetwork(); while (Application.internetReachability == NetworkReachability.NotReachable) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } UnityWebRequest request = UnityWebRequest.Get(UrlApi.GetAssetUrl(UrlApi.AsImageList)); yield return request.SendWebRequest(); #if UNITY_IOS if (!request.isDone || request.downloadHandler.data == null) #else if (!request.isDone || request.result == UnityWebRequest.Result.ConnectionError || request.downloadHandler.data == null) #endif { Logger.LogWarning("Error: RecvDataFromServer : " + request.error); Logger.LogWarning(request.downloadHandler.text); request.Dispose(); SingleMgr.OpenPopup1Button(LocalizationText.GetText("error_unstablenetwork")); yield break; } string strresult = request.downloadHandler.text.Trim(); if (string.IsNullOrEmpty(strresult)) { SingleMgr.OpenPopup1Button("Failed to resources list from server. Please restart the game.", SingleMgr.GameFinishOnly); yield break; } request.Dispose(); ABInfoList imglist; try { imglist = JsonUtility.FromJson(strresult); } catch (Exception e) { Logger.Log(strresult); Logger.Log(e.ToString()); SingleMgr.OpenPopup1Button("Failed to connect server. Please restart the game.", SingleMgr.GameFinishOnly); yield break; } for (int i = 0; i < imglist.items.Length; i++) { ABInfo info = imglist.items[i]; dicEventImageList.SafeInsert(info.Name, info); } UpdateImgList = false; } // 이미지 다운로드 시도. public void RequestEventImage(string strpath, Action onComplete) { if (StopConnect || string.IsNullOrEmpty(strpath)) return; SetEventImage(strpath, onComplete, true, false); } // 이미지 세팅. private void SetEventImage(string strpath, Action onComplete, bool recheck, bool brefresh) { if (string.IsNullOrEmpty(strpath)) return; string localpath = FormatString.CombineAllString(Application.persistentDataPath, FormatString.StringFormat(PATH_Events, strpath)); if (recheck && !UpdateImgList && dicEventImageList.TryGetValue(strpath, out ABInfo targetInfo)) { string prefsKey = FormatString.StringFormat(PREFS_Events, strpath); if (targetInfo.HashVersion.Equals(PlayerPrefs.GetString(prefsKey, "")) && File.Exists(localpath)) recheck = false; } if (recheck) { StartCoroutine(SvEventImage(strpath, localpath, onComplete)); } if (!brefresh && dicEventImage.ContainsKey(strpath)) { onComplete(dicEventImage[strpath]); return; } if (!File.Exists(localpath)) { return; } byte[] filedata = File.ReadAllBytes(localpath); #if UNITY_IOS Texture2D tex2d = new Texture2D(2, 2, TextureFormat.ASTC_10x10, false); #else Texture2D tex2d = new Texture2D(2, 2, TextureFormat.ASTC_8x8, false); #endif if (tex2d == null) tex2d = new Texture2D(2, 2, TextureFormat.RGBA32, false); tex2d.filterMode = FilterMode.Bilinear; if (!tex2d.LoadImage(filedata)) { return; } Sprite sprite = Sprite.Create(tex2d, new Rect(0f, 0f, tex2d.width, tex2d.height), Vector2.zero, 100f, 0, SpriteMeshType.FullRect, Vector4.zero, false); if (sprite == null) { return; } if (dicEventImage.ContainsKey(strpath)) dicEventImage[strpath] = sprite; else dicEventImage.Add(strpath, sprite); onComplete(sprite); } // 이미지 목록 다운로드[GET]. private IEnumerator SvEventImage(string strpath, string localpath, Action actionfinish) { while (UpdateImgList && dicEventImageList.Count == 0) yield return YieldInstructionCache.WaitForSeconds(0.5f); if (!dicEventImageList.ContainsKey(strpath)) yield break; string hashversion = dicEventImageList[strpath].HashVersion; string strurl = UrlApi.GetAssetUrl(FormatString.StringFormat(UrlApi.AsEventImage, strpath)); // 네트워크 연결 상태 확인. CheckNetwork(); while (Application.internetReachability == NetworkReachability.NotReachable) { yield return YieldInstructionCache.WaitForSeconds(0.2f); } #region Get UnityWebRequest request = UnityWebRequest.Get(strurl); yield return request.SendWebRequest(); if (!request.isDone || request.result == UnityWebRequest.Result.ConnectionError || request.downloadHandler.data == null) { Logger.LogWarning("Error: RecvDataFromServer : " + request.error); request.Dispose(); yield break; } FileStream fs = new FileStream(localpath, FileMode.Create); try { fs.Write(request.downloadHandler.data, 0, (int)request.downloadedBytes); } catch (Exception ex) { Logger.LogWarning("Exception : " + ex.GetType()); Logger.LogWarning(ex.Message); Logger.LogWarning(ex.StackTrace); Logger.LogError(ex.ToString()); fs.Close(); request.Dispose(); yield break; } fs.Close(); request.Dispose(); // Continue string strprefs = FormatString.StringFormat(PREFS_Events, strpath); PlayerPrefs.SetString(strprefs, hashversion); PlayerPrefs.Save(); #endregion Get SetEventImage(strpath, actionfinish, false, true); } #endregion Event Image }