You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1054 lines
38 KiB
1054 lines
38 KiB
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 : Singleton<SvConnectManager>
|
|
{
|
|
#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<string> actionsucc, Action<SvError> 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<string> actionsucc, Action<SvError> 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
|
|
/// <summary>
|
|
/// 서버 통신 요청 [GET].
|
|
/// </summary>
|
|
/// <param name="bcover">통신 도중에 CoverCamera를 통해서 터치를 막을지.</param>
|
|
/// <param name="iretry">통신 실패시 재시도 횟수.</param>
|
|
/// <param name="strurl">통신할 API URL.</param>
|
|
/// <param name="type">서버 통신 완료 후 받는 데이터의 형식(class).</param>
|
|
/// <param name="actionsucc">통신 성공 후 처리.</param>
|
|
/// <param name="actionfail">통신 실패 후 처리.</param>
|
|
/// <param name="bdatasave">서버에 저장되는 유저 플레이 정보(cPlayData)에 영향을 미치는지.</param>
|
|
/// <param name="blogin">유저 토큰 값을 사용 = 로그인 한 상태에서 처리인지.</param>
|
|
/// <returns>성공: actionsucc(지정한 type의 JSON string). 실패: actionfail(에러 정보)</returns>
|
|
public void RequestSvGet(bool bcover, int iretry, string strurl, Type type, Action<object> actionsucc, Action<SvError> 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<object> actionsucc, Action<SvError> 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<SvError>(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
|
|
/// <summary>
|
|
/// 서버 통신 요청 [POST].
|
|
/// </summary>
|
|
/// <param name="bcover">통신 도중에 CoverCamera를 통해서 터치를 막을지.</param>
|
|
/// <param name="iretry">통신 실패시 재시도 횟수.</param>
|
|
/// <param name="strurl">통신할 API URL.</param>
|
|
/// <param name="type">서버 통신 완료 후 받는 데이터의 형식(class).</param>
|
|
/// <param name="actionsucc">통신 성공 후 처리.</param>
|
|
/// <param name="actionfail">통신 실패 후 처리.</param>
|
|
/// <param name="parameter">서버로 보낼 데이터.</param>
|
|
/// <param name="bdatasave">서버에 저장되는 유저 플레이 정보(cPlayData)에 영향을 미치는지.</param>
|
|
/// <param name="blogin">유저 토큰 값을 사용 = 로그인 한 상태에서 처리인지.</param>
|
|
/// <returns>성공: actionsucc(지정한 type의 JSON string, parameter). 실패: actionfail(에러 정보, parameter)</returns>
|
|
public void RequestSvPost(bool bcover, int iretry, string strurl, Type type, Action<object, object> actionsucc, Action<SvError, object> 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));
|
|
}
|
|
|
|
// 통신[POST].
|
|
private IEnumerator SvPost(bool bcover, int iretry, string strurl, Type type, Action<object, object> actionsucc, Action<SvError, object> 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<SvError>(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<string, ABInfo> dicEventImageList = new Dictionary<string, ABInfo>();
|
|
private static Dictionary<string, Sprite> dicEventImage = new Dictionary<string, Sprite>();
|
|
|
|
// 이미지 목록 다운로드 시도.
|
|
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<ABInfoList>(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<Sprite> onComplete)
|
|
{
|
|
if (StopConnect || string.IsNullOrEmpty(strpath)) return;
|
|
SetEventImage(strpath, onComplete, true, false);
|
|
}
|
|
|
|
// 이미지 세팅.
|
|
private void SetEventImage(string strpath, Action<Sprite> 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<Sprite> 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
|
|
}
|