using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BestHTTP.SocketIO;
using BestHTTP.SocketIO.Transports;
using Cute;
using LitJson;
using MessagePack;
using MiniJSON;
using PlatformSupport.Collections.ObjectModel;
using UnityEngine;
using Wizard;
using Wizard.Battle.Recovery;
using Wizard.ErrorDialog;
using Wizard.RoomMatch;

public class RealTimeNetworkAgent : MonoBehaviour
{
	public enum EmitCategory
	{
		battle = 1,
		matching = 2,
		room = 3,
		watch = 11,
		general = 99
	}

	public enum MatchingStatus
	{
		OffLine = 0,
		Connect = 10,
		StartLoad = 30,
		Loaded = 40,
		Prepared = 50,
		Disconnected = 80,
		RoomReady = 90,
		Room = 100
	}

	public enum DESTROY_OBJECT_LOG
	{
		BattleResult,
		Maintenance,
		NodeError,
		ResultCode,
		Room,
		MatchingDisconnect,
		WatchMaintenance,
		Debug,
		Replay,
		HandleResultCode
	}

	private DateTime _receiveWaitTime = DateTime.MinValue;

	private bool _isCheckReceiveWaitTime;

	private int _oldReceiveDataCount;

	private const float RECEIVE_WAIT_ERROR_LOG_TIME = 60f;

	protected NetworkBattleManagerBase _networkBattleManager;

	public Action<NetworkBattleDefine.NetworkBattleURI, Dictionary<string, object>> OnMatchingReceiveUri;

	public Action<NetworkBattleDefine.NetworkBattleURI> OnEmit;

	private BattleFinishSendBase _battleFinishSendBase;

	public static FinishTaskBase FinishTaskBase;

	private bool _initNetworkSuccess;

	protected bool _failedRecoveryToNotSendFinishTask;

	protected bool _isFinishResultSuccses;

	public List<string> _serializeList = new List<string>();

	public List<string> _trySerializeList = new List<string>();

	private int _currentTryNum;

	protected SocketManager _manager;

	private int viewerId;

	private string battleRoomId;

	protected string bid = "";

	private Matching _matching;

	private Action _onEveryTimeFail;

	public const string SEND_SEQ_NAME = "pubSeq";

	public const string RECEIVE_SEQ_NAME = "playSeq";

	protected StockReceiveMgr stockReceiveMessageMgr;

	protected StockEmitMgr stockEmitMessageMgr;

	private Action _onFinishedEmit;

	protected Gungnir _gungnir;

	private bool _isAlreadyDestroyedGameObject;

	private static readonly string status_try = "try";

	private string errorLog = "";

	private const string EmitMsg = "msg";

	private const string EmitHand = "hand";

	private const string HAND_DATA_KEY = "StockHandData";

	public const string CategoryParameter = "cat";

	public Action<int> OnResultCodeError;

	protected const int ERROR_MAINTENANCE = 5;

	private bool _notEmit;

	public Action<Dictionary<string, object>> OnAck;

	public bool IsNotPlayReceivingData;

	public const string RECEIVE_URI = "uri";

	public const string IS_RESUME = "isResume";

	private long _battlePreparedStartTicks;

	private int _disconnectNum;

	private int _emitLogNum;

	private bool _isAddEmitLog;

	private string _emitLog = "";

	private const int DISCONNECT_LOG_NUM = 5;

	private const int EMIT_LOG_NUM = 3;

	private int _connectNumToReconnect;

	private long _connectTicks;

	private const int CONNECT_TO_RECONNECT_MAX_NUM = 3;

	private const float CONNECT_TO_RECONNECT_TIMER = 30f;

	private long _stopPlayReceiveLogTime;

	private const float STOP_PLAY_RECEIVE_LOG_TIME = 60f;

	public bool IsRecovery { get; private set; }

	public bool IsBattleStart { get; private set; }

	public NetworkStatus OpponentNetworkStatus { get; protected set; }

	public bool IsOpponentDisconnected => !OpponentNetworkStatus.IsAlive;

	public SocketManager SocketManager => _manager;

	public int StockReceiveCount => stockReceiveMessageMgr.GetSequenceDataCount();

	public int MaxMessageSequenceNumber => stockReceiveMessageMgr.GetMaxSequenceNumber();

	public int StockEmitCount => stockEmitMessageMgr.GetSequenceDataCount();

	public NetworkStatus PlayerNetworkStatus { get; private set; }

	public bool IsReceiveSelfDisconnect
	{
		get
		{
			if (_gungnir != null)
			{
				return _gungnir._DisconnectStatus == Gungnir.DisconnectStatus.SELF_DISCONNECT;
			}
			return false;
		}
	}

	public bool IsReceiveOpponentDisconnect
	{
		get
		{
			if (_gungnir != null)
			{
				return _gungnir._DisconnectStatus == Gungnir.DisconnectStatus.OPPONENT_DISCONNECT;
			}
			return false;
		}
	}

	public Action<Dictionary<string, object>> OnReceivedEvent { get; set; }

	public MatchingStatus CurrentMatchingStatus { get; protected set; }

	public int LastEmitSeqNumber { get; private set; }

	public bool IsExistTitleReturnError { get; private set; }

	public INetworkLogger<NetworkLog> NetworkLogger { get; protected set; }

	public string NowSocketID { get; private set; }

	public void SetIsRecovery(bool flg)
	{
		IsRecovery = flg;
	}

	public void SetIsBattleStart(bool flag)
	{
		IsBattleStart = flag;
	}

	public int GetIsFirstPlayer()
	{
		return GameMgr.GetIns().GetNetworkUserInfoData().TurnState;
	}

	public int GetViewId()
	{
		return viewerId;
	}

	public long GetBattleId()
	{
		if (string.IsNullOrEmpty(bid))
		{
			return -1L;
		}
		return long.Parse(bid);
	}

	public void SetbattleId(string battleId)
	{
		bid = battleId;
	}

	public int GetActionSequenceCount()
	{
		if (_gungnir != null)
		{
			return _gungnir._actionSequenceNum;
		}
		return -1;
	}

	protected virtual void Awake()
	{
		UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
		GameMgr.GetIns().SetNetworkUserInfoData(new NetworkUserInfoData());
		stockReceiveMessageMgr = new StockReceiveMgr("playSeq");
		stockEmitMessageMgr = new StockEmitMgr("pubSeq");
		InitializeNetworkLogger();
		InitializePlayerNetworkStatus();
		InitializeGungnir();
		TaskManager.GetInstance().MyPageSend();
	}

	private void Update()
	{
		if (ToolboxGame.RealTimeNetworkAgent.CurrentMatchingStatus != MatchingStatus.Prepared && ToolboxGame.RealTimeNetworkAgent.CurrentMatchingStatus != MatchingStatus.Disconnected && _matching != null)
		{
			_matching.UpdateMatching();
		}
		if (BattleManagerBase.GetIns() == null)
		{
			LocalLog.SubmitAccumulateLastTraceLog();
		}
		if (!IsNotPlayReceivingData)
		{
			PlayReceiveData();
			CheckLogStopPlayReceive();
		}
	}

	protected virtual void InitializeNetworkLogger()
	{
		NetworkLogger = new NetworkNullLogger();
	}

	protected virtual void InitializePlayerNetworkStatus()
	{
		PlayerNetworkStatus = new NetworkStatus();
	}

	protected virtual void InitializeGungnir()
	{
		_gungnir = new Gungnir(this);
		Gungnir gungnir = _gungnir;
		gungnir.OnAlive = (Action)Delegate.Combine(gungnir.OnAlive, new Action(PlayerNetworkStatus.ToKeepAlive));
		Gungnir gungnir2 = _gungnir;
		gungnir2.OnAlive = (Action)Delegate.Combine(gungnir2.OnAlive, (Action)delegate
		{
			LocalLog.AddGungnirLog("GungnirOnAlived");
		});
		Gungnir gungnir3 = _gungnir;
		gungnir3.OnResendEmitData = (Action<int>)Delegate.Combine(gungnir3.OnResendEmitData, new Action<int>(ResendPubSeqData));
	}

	public void SetCurrentMatchingStatus(MatchingStatus status)
	{
		if (CurrentMatchingStatus != MatchingStatus.Disconnected)
		{
			if (CurrentMatchingStatus >= status)
			{
				LocalLog.AccumulateTraceLog("SetCurrentMatchingStatus Old" + CurrentMatchingStatus.ToString() + " " + status);
				return;
			}
			CurrentMatchingStatus = status;
			LocalLog.AccumulateLastTraceLog("SetStatus:" + CurrentMatchingStatus);
		}
	}

	public void SetNetworkBattleMgr(NetworkBattleManagerBase mgr)
	{
		_networkBattleManager = mgr;
	}

	public void StartPreparedStartTimer(DateTime nowTimer)
	{
		_battlePreparedStartTicks = nowTimer.Ticks;
	}

	public int GetPreparedStartTimer()
	{
		return (int)NetworkUtility.GetTimeSpanMilliSecond(_battlePreparedStartTicks);
	}

	private void OnApplicationPause(bool appPause)
	{
		if (GameMgr.GetIns() != null && !GameMgr.GetIns().IsReplayBattle && appPause && _manager != null)
		{
			Dictionary<string, object> dictionary = CreateEmitData(NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Kill], null);
			dictionary.Add("state", "pause");
			_manager.Socket.Emit("msg", null, CreatePackEmitData(dictionary));
		}
	}

	protected virtual void PlayReceiveData()
	{
		int sequenceDataCount = stockReceiveMessageMgr.GetSequenceDataCount();
		if (!_isCheckReceiveWaitTime)
		{
			_receiveWaitTime = TimeUtil.GetAbsoluteTime();
		}
		_isCheckReceiveWaitTime = _oldReceiveDataCount == sequenceDataCount && sequenceDataCount != 0;
		_oldReceiveDataCount = sequenceDataCount;
		Dictionary<string, object> dictionary = stockReceiveMessageMgr.FindData(stockReceiveMessageMgr.SequenceAlreadyNumber + 1);
		string text = "";
		if (dictionary != null)
		{
			text = dictionary["uri"].ToString();
		}
		if (!IsPlayReceiveDataOk(text))
		{
			if (_isCheckReceiveWaitTime && (float)NetworkUtility.GetTimeSpanSecond(_receiveWaitTime.Ticks) >= 60f)
			{
				NetworkBattleGenericTool.CreateLoadAndPlayEffectVfxLastTurnLog();
				_isCheckReceiveWaitTime = false;
			}
		}
		else if ((stockEmitMessageMgr.IsEmpty() || !(text == "BattleFinish")) && dictionary != null)
		{
			_stopPlayReceiveLogTime = TimeUtil.GetAbsoluteTime().Ticks;
			bool flag = PlayReceiveData(dictionary);
			flag |= IsFromResumeData(dictionary);
			if (ToolboxGame.RealTimeNetworkAgent.CurrentMatchingStatus != MatchingStatus.Room && ToolboxGame.RealTimeNetworkAgent.CurrentMatchingStatus != MatchingStatus.RoomReady)
			{
				UpdateReciveSeqNumber(dictionary, flag);
			}
		}
	}

	public static bool IsFromResumeData(Dictionary<string, object> data)
	{
		if (data.ContainsKey("isResume"))
		{
			return (bool)data["isResume"];
		}
		return false;
	}

	private void CheckLogStopPlayReceive()
	{
		DateTime absoluteTime = TimeUtil.GetAbsoluteTime();
		if (stockReceiveMessageMgr.GetStockDataList().Count == 0 || GameMgr.GetIns().IsAINetwork || GameMgr.GetIns().IsWatchBattle)
		{
			_stopPlayReceiveLogTime = absoluteTime.Ticks;
			return;
		}
		int timeSpanSecond = NetworkUtility.GetTimeSpanSecond(_stopPlayReceiveLogTime);
		if (!((float)timeSpanSecond >= 60f))
		{
			return;
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("SeqStopLog: \n");
		foreach (Dictionary<string, object> stockData in stockReceiveMessageMgr.GetStockDataList())
		{
			stringBuilder.AppendLine(stockData["uri"].ToString() + stockReceiveMessageMgr.GetSequenceNumber(stockData) + "|");
		}
		stringBuilder.AppendLine("\n seqNum:" + stockReceiveMessageMgr.SequenceAlreadyNumber);
		stringBuilder.AppendLine("\n matchingStatus:" + CurrentMatchingStatus);
		stringBuilder.AppendLine("\n stopPlayReceiveTimeSpanSecond:" + timeSpanSecond);
		if (_networkBattleManager != null)
		{
			stringBuilder.AppendLine("\n vfxEnd:" + _networkBattleManager.VfxMgr.IsEnd);
			stringBuilder.AppendLine(" currentVfx:" + _networkBattleManager.VfxMgr.CurrentVfxName);
			stringBuilder.AppendLine(" currentVfxTime:" + _networkBattleManager.VfxMgr.CurrentVfxTime);
			stringBuilder.AppendLine("\n loadResourcePhase:" + LocalLog.GetLoadResourceLog());
			stringBuilder.AppendLine("\n isEchoWait:" + _networkBattleManager.IsEchoWait());
		}
		string text = stringBuilder.ToString();
		Debug.LogError(text);
		NetworkLogger.LogInfo(text);
		LocalLog.AccumulateLastTraceLog("StopPlayReceive " + text);
		LocalLog.RecordMemoryOnLastTurnLog();
		_stopPlayReceiveLogTime = absoluteTime.Ticks;
	}

	public void UpdateReciveSeqNumber(Dictionary<string, object> playData, bool isUpdateSequence = true)
	{
		if (playData != null)
		{
			LocalLog.AccumulateLastTraceLog("Front Uri " + playData["uri"]);
			LocalLog.AccumulateLastTraceLog("UpdateReceiveSequenceBefore: Max " + stockReceiveMessageMgr.GetMaxSequenceNumber() + "Already" + stockReceiveMessageMgr.SequenceAlreadyNumber);
			if (isUpdateSequence)
			{
				stockReceiveMessageMgr.UpdateSequenceAlreadyNumber(playData);
			}
			stockReceiveMessageMgr.RemoveSelectData(playData);
		}
		LocalLog.AccumulateLastTraceLog("UpdateReceiveSequence: Max " + stockReceiveMessageMgr.GetMaxSequenceNumber() + "Already" + stockReceiveMessageMgr.SequenceAlreadyNumber);
	}

	public virtual bool IsPlayReceiveDataOk(string uri = null, bool isWatchCheck = false)
	{
		return true;
	}

	public void Connect(int viewerId, string battleId, Action onEveryTimeFail, Matching matching, bool isBeforeBattleStartRetry = false)
	{
		SettingMatchingClass(matching);
		this.viewerId = viewerId;
		battleRoomId = battleId;
		string value = CryptAES.encryptForNode(viewerId.ToString());
		_onEveryTimeFail = onEveryTimeFail;
		SocketOptions socketOptions = new SocketOptions();
		socketOptions.ConnectWith = TransportTypes.WebSocket;
		socketOptions.AutoConnect = true;
		socketOptions.AdditionalQueryParams = new ObservableDictionary<string, string>();
		socketOptions.AdditionalQueryParams.Add("User-Agent", SystemInfo.operatingSystem.ToString());
		socketOptions.AdditionalQueryParams.Add("BattleId", battleId);
		socketOptions.AdditionalQueryParams.Add("viewerId", value);
		_manager = new SocketManager(new Uri(CustomPreference.GetNodeServerURL()), socketOptions);
		_manager.SettingRealtimeNetworkAgent(this);
		ConnectSocket();
		if (isBeforeBattleStartRetry || (IsRecovery && matching != null))
		{
			_initNetworkSuccess = true;
			if (!IsRecovery)
			{
				StartGungnir();
			}
		}
	}

	public SocketManager.States Connect(int viewerId, string battleId, Action onEveryTimeFail)
	{
		this.viewerId = viewerId;
		battleRoomId = battleId;
		string value = CryptAES.encryptForNode(viewerId.ToString());
		_onEveryTimeFail = onEveryTimeFail;
		SocketOptions socketOptions = new SocketOptions();
		socketOptions.ConnectWith = TransportTypes.WebSocket;
		socketOptions.AutoConnect = true;
		socketOptions.AdditionalQueryParams = new ObservableDictionary<string, string>();
		socketOptions.AdditionalQueryParams.Add("User-Agent", SystemInfo.operatingSystem.ToString());
		socketOptions.AdditionalQueryParams.Add("BattleId", battleId);
		socketOptions.AdditionalQueryParams.Add("viewerId", value);
		_manager = new SocketManager(new Uri(CustomPreference.GetNodeServerURL()), socketOptions);
		_manager.SettingRealtimeNetworkAgent(this);
		return ConnectSocket();
	}

	public void SettingMatchingClass(Matching matching)
	{
		if (matching != null)
		{
			_matching = matching;
		}
	}

	public static void ReconnectSocketAndLogFlagOn()
	{
		ToolboxGame.RealTimeNetworkAgent.ReconnectSocket();
		if (GameMgr.GetIns().GetDataMgr().m_BattleType == DataMgr.BattleType.RankBattle && Wizard.Data.CurrentFormat == Format.Rotation)
		{
			PlayerPrefsWrapper.SetValue(PlayerPrefsWrapper.SELF_DISCONNECT_OPEN_STATUS_TO_REPLACE_LOG, 1f);
		}
	}

	public static bool IsNormalNetworkBattle()
	{
		if (ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.CurrentMatchingStatus >= MatchingStatus.Prepared && GameMgr.GetIns().IsNetworkBattle && !GameMgr.GetIns().IsWatchBattle && !GameMgr.GetIns().IsReplayBattle && !GameMgr.GetIns().IsAINetwork && BattleManagerBase.GetIns() != null)
		{
			return !BattleManagerBase.GetIns().IsRecovery;
		}
		return false;
	}

	public SocketManager.States ReconnectSocket()
	{
		if (viewerId == 0 || _manager == null)
		{
			return SocketManager.States.Initial;
		}
		_manager.Close();
		return Connect(viewerId, battleRoomId, _onEveryTimeFail);
	}

	private SocketManager.States ConnectSocket()
	{
		_manager.Socket.On("disconnect", OnDisconnect);
		_manager.Socket.On("opponent_lost", OnOpponentLost);
		_manager.Socket.On("synchronize", OnReceived);
		_manager.Socket.On("hand", OnHandReceived);
		_manager.Socket.On("reconnect_socket", OnReconnect);
		_manager.Socket.On("alive", OnAlived);
		_manager.Socket.On("connect_socket", OnConnect_Socket);
		_manager.Socket.On("heartbeat_ping", OnHeartbeatPing);
		_manager.Socket.On("heartbeat_pong", OnHeartbeatPong);
		_manager.Socket.On("heartbeat_timeout", OnHeartbeatTimeOut);
		_manager.Socket.On(SocketIOEventTypes.Error, delegate(Socket socket, Packet packet, object[] args)
		{
			_onEveryTimeFail.Call();
			if (args != null && args.Count() >= 1 && errorLog != args.First().ToString())
			{
				errorLog = args.First().ToString();
				LocalLog.AccumulateTraceLog(errorLog);
			}
		});
		_manager.Open();
		return _manager.State;
	}

	protected virtual void OnEmitAckCallback(Socket socket, Packet originalPacket, params object[] args)
	{
		if ((float)NetworkUtility.GetTimeSpanSecond(stockEmitMessageMgr.GetEmitTime()) < StockEmitMgr.WAIT_ACK_TIMEOUT)
		{
			int number = int.Parse(args[0].ToString());
			EmitSuccessToNextEmitData(number);
		}
	}

	public void EmitSuccessToNextEmitData(int number)
	{
		Dictionary<string, object> selectData = stockEmitMessageMgr.GetSelectData(number);
		OnAck.Call(selectData);
		stockEmitMessageMgr.SetReceiveAck();
		if (selectData == null)
		{
			LocalLog.AccumulateLastTraceLog("OnAckCallback Null " + number);
			return;
		}
		string text = "";
		bool flag = false;
		if (selectData.ContainsKey("StockHandData"))
		{
			flag = true;
			text = GetHandUri(selectData);
		}
		else
		{
			text = selectData["uri"].ToString();
		}
		LocalLog.AccumulateLastTraceLog("OnAckCallback Uri " + text + " number" + number);
		stockEmitMessageMgr.RemoveSelectData(selectData);
		if (text == NetworkBattleDefine.NetworkBattleURI.TurnStart.ToString() && !_gungnir._actionSeqPubSeqList.Contains(number))
		{
			if (text == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.TurnStart])
			{
				SetGungnirSendActionSequence(isActive: false);
			}
			_gungnir._actionSeqPubSeqList.Add(number);
			LocalLog.AccumulateLastTraceLog("uri:" + text + " ActionSeq:" + GetActionSequenceCount() + " NotRecovery");
			AddActionSequence();
		}
		EmitFrontStockData();
		NetworkBattleManagerBase networkBattleManagerBase = BattleManagerBase.GetIns() as NetworkBattleManagerBase;
		NetworkBattleDefine.NetworkBattleURI result = NetworkBattleDefine.NetworkBattleURI.None;
		object value;
		bool flag2 = selectData.TryGetValue("uri", out value);
		bool flag3 = flag2 && Enum.TryParse<NetworkBattleDefine.NetworkBattleURI>(value.ToString(), out result);
		if (networkBattleManagerBase != null && !flag && flag2 && flag3)
		{
			networkBattleManagerBase.SendIntervalTriggerMain.SendDataCheck(networkBattleManagerBase, result);
		}
	}

	public void SetGungnirSendActionSequence(bool isActive)
	{
		_gungnir.SetSendActionSequenceNumFlag(isActive);
	}

	private void ResendPubSeqData(int resendOrderNum)
	{
		if ((float)NetworkUtility.GetTimeSpanSecond(stockEmitMessageMgr.GetEmitTime()) < StockEmitMgr.WAIT_ACK_TIMEOUT)
		{
			return;
		}
		List<Dictionary<string, object>> sequenceAllData = stockEmitMessageMgr.GetSequenceAllData();
		if (sequenceAllData != null && sequenceAllData.Count > 0)
		{
			int num = int.Parse(sequenceAllData[0]["pubSeq"].ToString());
			if (num > resendOrderNum)
			{
				for (int i = 0; i < num - resendOrderNum; i++)
				{
					Dictionary<string, object> allSelectData = stockEmitMessageMgr.GetAllSelectData(num - i);
					if (allSelectData != null)
					{
						stockEmitMessageMgr.FirstAddSequenceDataList(allSelectData);
					}
				}
				DateTime absoluteTime = TimeUtil.GetAbsoluteTime();
				stockEmitMessageMgr.SetEmitTime(absoluteTime.Ticks);
				EmitFrontStockData();
			}
			else if (num == resendOrderNum && (float)NetworkUtility.GetTimeSpanSecond(stockEmitMessageMgr.GetEmitTime()) > StockEmitMgr.WAIT_ACK_TIMEOUT)
			{
				DateTime absoluteTime2 = TimeUtil.GetAbsoluteTime();
				stockEmitMessageMgr.SetEmitTime(absoluteTime2.Ticks);
				EmitFrontStockData();
			}
			else if (num < resendOrderNum)
			{
				LocalLog.AccumulateTraceLog("ClinentPubSeq < NodePubSeq");
			}
		}
		else
		{
			if (sequenceAllData == null || sequenceAllData.Count != 0)
			{
				return;
			}
			int sequenceNumber = stockEmitMessageMgr.SequenceNumber;
			if (sequenceNumber <= resendOrderNum)
			{
				return;
			}
			for (int j = 0; j < sequenceNumber - resendOrderNum; j++)
			{
				Dictionary<string, object> allSelectData2 = stockEmitMessageMgr.GetAllSelectData(sequenceNumber - j);
				if (allSelectData2 != null)
				{
					stockEmitMessageMgr.FirstAddSequenceDataList(allSelectData2);
				}
			}
			DateTime absoluteTime3 = TimeUtil.GetAbsoluteTime();
			stockEmitMessageMgr.SetEmitTime(absoluteTime3.Ticks);
			EmitFrontStockData();
		}
	}

	private void EmitFrontStockData()
	{
		if (!_notEmit)
		{
			List<Dictionary<string, object>> sequenceAllData = stockEmitMessageMgr.GetSequenceAllData();
			if (sequenceAllData == null || sequenceAllData.Count == 0)
			{
				Action onFinishedEmit = _onFinishedEmit;
				_onFinishedEmit = null;
				onFinishedEmit.Call();
			}
			else
			{
				EmitDataToAckCallBack(sequenceAllData[0]);
			}
		}
	}

	private void EmitDataToAckCallBack(Dictionary<string, object> frontData)
	{
		if (_manager != null && !GameMgr.GetIns().IsWatchBattle)
		{
			int num = Convert.ToInt32(frontData[status_try].ToString());
			CheckAndRemoveFirstSerializeLogData(num);
			_currentTryNum = num;
			num++;
			frontData[status_try] = num;
			EmitStockData(frontData);
			AddSerializeLogData();
		}
	}

	private void EmitStockData(Dictionary<string, object> frontData)
	{
		if (!_notEmit)
		{
			string text = "";
			byte[] array = null;
			string eventName = "msg";
			if (frontData.ContainsKey("StockHandData"))
			{
				eventName = "hand";
				List<object> info = frontData["StockHandData"] as List<object>;
				text = GetHandUri(frontData);
				array = CreatePackEmitHandData(info);
			}
			else
			{
				text = frontData["uri"].ToString();
				array = CreatePackEmitData(frontData);
			}
			int result = 0;
			if (int.TryParse(text, out result))
			{
				string text2 = "Emit Hand " + Enum.GetName(typeof(NetworkBattleSender.HAND_URI_TYPE), result);
				NetworkLogger.LogInfo(text2);
				LocalLog.AccumulateLastTraceLog(text2);
			}
			else
			{
				string text3 = "Emit Uri " + text;
				LocalLog.AccumulateLastTraceLog(text3);
				NetworkLogger.LogInfo(text3);
			}
			DateTime absoluteTime = TimeUtil.GetAbsoluteTime();
			stockEmitMessageMgr.SetEmitTime(absoluteTime.Ticks);
			if (text == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.InitNetwork])
			{
				LocalLog.AccumulateLastTraceLog("EmitStockData_InitNetwork " + StackTraceUtility.ExtractStackTrace());
			}
			_emitLog = "";
			if (isSendEmitLog())
			{
				_isAddEmitLog = true;
				_emitLogNum++;
				LocalLog._isSendGungnirLog = true;
				LocalLog._isSendSocketFrameLog = true;
			}
			_manager.Socket.Emit(eventName, OnEmitAckCallback, array);
			if (_isAddEmitLog)
			{
				_isAddEmitLog = false;
				LocalLog.AccumulateLastTraceLog("EmitLog:" + _emitLog);
			}
		}
	}

	public bool isSendEmitLog()
	{
		if (_disconnectNum >= 5 && CurrentMatchingStatus == MatchingStatus.Prepared && _emitLogNum < 3 && (float)NetworkUtility.GetTimeSpanSecond(stockEmitMessageMgr.EmitToAckCheckTime) > StockEmitMgr.ACK_NOT_RECEIVE_LOG_TIME)
		{
			return (float)NetworkUtility.GetTimeSpanSecond(_gungnir.GungnirReceiveCheckTime) < 5f;
		}
		return false;
	}

	public void AddEmitLog(string log)
	{
		if (_isAddEmitLog)
		{
			_emitLog += log;
		}
	}

	public byte[] CreatePackEmitData(Dictionary<string, object> info)
	{
		byte[] array = MessagePackSerializer.Serialize(CryptAES.encryptForNode(JsonMapper.ToJson(info)));
		if (BattleManagerBase.GetIns() != null)
		{
			KeyValuePair<string, object> keyValuePair = info.SingleOrDefault((KeyValuePair<string, object> s) => s.Key == "uri");
			if (!keyValuePair.Equals(default(KeyValuePair<string, object>)) && keyValuePair.Value.ToString() != "Gungnir")
			{
				DateTime dateTime = DateTime.Now.ToUniversalTime();
				_serializeList.Add(string.Format("{0}/{1}:{2}:{3}:{4:000}:{5}", dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond.ToString("000"), "\n" + keyValuePair.Value?.ToString() + " serialize data = " + Convert.ToBase64String(array)));
			}
		}
		return array;
	}

	private void AddSerializeLogData()
	{
		if (_currentTryNum >= 1)
		{
			_trySerializeList.AddRange(_serializeList);
			_serializeList.Clear();
		}
	}

	private void CheckAndRemoveFirstSerializeLogData(int nowTryCount)
	{
		if (_currentTryNum == 0 && nowTryCount == 0 && _serializeList.Count > 2)
		{
			_serializeList.RemoveRange(0, _serializeList.Count - 1);
		}
	}

	private byte[] CreatePackEmitHandData(List<object> info)
	{
		return MessagePackSerializer.Serialize(JsonMapper.ToJson(info));
	}

	protected void OnReceived(Socket socket, Packet packet, params object[] args)
	{
		if (_notEmit)
		{
			LocalLog.AccumulateLastTraceLog("OnReceivedNotEmit");
			return;
		}
		byte[] bytes = packet.Attachments[0];
		Dictionary<string, object> dictionary = null;
		string text = "";
		try
		{
			text = MessagePackSerializer.Deserialize<string>(bytes);
		}
		catch (Exception ex)
		{
			LocalLog.AccumulateLastTraceLog("OnReceivedUnpack Error：" + ex);
			return;
		}
		dictionary = Json.Deserialize(CryptAES.decryptForNode(text)) as Dictionary<string, object>;
		string text2 = dictionary["uri"].ToString();
		if (text2 == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.InitNetwork])
		{
			_initNetworkSuccess = true;
		}
		if (text2 == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.TurnStart])
		{
			LocalLog.InitGungnirLog();
			LocalLog.InitDisconnectLog();
			LocalLog.InitSocketFrameLog();
		}
		if (text2 != RoomParamKey.WatchUriNames[PlayerControllerForWatching.SEND_PARAMETER.Watch])
		{
			string text3 = "OnReceived URI:" + text2;
			NetworkLogger.LogInfo(text3);
			LocalLog.AccumulateLastTraceLog(text3);
		}
		if (!HandleingNodeResultCodeIfNeeded(dictionary) && !CheckReceiveMaintenanceToDestroy(text2))
		{
			if (text2 == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Resume])
			{
				ResumeToStockReceive(dictionary);
			}
			else if (text2 == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Watch])
			{
				PlayReceiveData(dictionary);
			}
			else
			{
				ProcessingRecivedData(dictionary);
			}
		}
	}

	private bool CheckReceiveMaintenanceToDestroy(string uri)
	{
		if (uri == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Maintenance])
		{
			StopNetworkBattle();
			ShowMaintenanceError();
			DestroyObj(DESTROY_OBJECT_LOG.Maintenance);
			return true;
		}
		return false;
	}

	protected void OnHandReceived(Socket socket, Packet packet, params object[] args)
	{
		if (!_notEmit)
		{
			byte[] bytes = packet.Attachments[0];
			List<object> list = null;
			try
			{
				list = Json.Deserialize(MessagePackSerializer.Deserialize<string>(bytes)) as List<object>;
			}
			catch (Exception ex)
			{
				Debug.LogError("Unpack Error：" + ex);
				return;
			}
			if (int.Parse(list[0].ToString()) == 99)
			{
				int errorCode = int.Parse(list[1].ToString());
				HandleResultCode(errorCode, isMatching: false);
			}
		}
	}

	protected void OnAlived(Socket socket, Packet packet, params object[] args)
	{
		_gungnir.ReceiveGungnir(packet, args);
	}

	private void OnHeartbeatPing(Socket socket, Packet packet, params object[] args)
	{
		string log = DateTime.UtcNow.ToString() + DateTime.UtcNow.Millisecond + " [" + socket.Id + "] Ping->";
		if (_disconnectNum >= 5)
		{
			LocalLog.AccumulateLastTraceLog(log);
		}
		LocalLog.AddGungnirLog(" Ping->");
	}

	private void OnHeartbeatPong(Socket socket, Packet packet, params object[] args)
	{
		string log = DateTime.UtcNow.ToString() + DateTime.UtcNow.Millisecond + " [" + socket.Id + "] <- Pong ";
		if (_disconnectNum >= 5)
		{
			LocalLog.AccumulateLastTraceLog(log);
		}
		LocalLog.AddGungnirLog(" <- Pong ");
	}

	private void OnHeartbeatTimeOut(Socket socket, Packet packet, params object[] args)
	{
		LocalLog.AccumulateLastTraceLog(DateTime.UtcNow.ToString() + DateTime.UtcNow.Millisecond + " [" + socket.Id + "]× TIME OUT");
	}

	public Dictionary<string, object> DeserializeEncryptedPacket(Packet packet)
	{
		byte[] bytes = packet.Attachments[0];
		string src;
		try
		{
			src = MessagePackSerializer.Deserialize<string>(bytes);
		}
		catch (Exception ex)
		{
			Debug.LogError("Unpack Error：" + ex);
			return new Dictionary<string, object>();
		}
		return (Json.Deserialize(CryptAES.decryptForNode(src)) as Dictionary<string, object>) ?? new Dictionary<string, object>();
	}

	private void HandleResultCode(int errorCode, bool isMatching)
	{
		if (!isMatching && errorCode == 30002)
		{
			if (BattleManagerBase.GetIns() is NetworkBattleManagerBase networkBattleManagerBase)
			{
				networkBattleManagerBase.NodeErrorToNocontest();
			}
			return;
		}
		if (errorCode == 30001 || errorCode == 30213)
		{
			IsExistTitleReturnError = true;
		}
		if (!isMatching)
		{
			CreateNetworkBattleErrorDialog(errorCode);
		}
		else if (errorCode != 30212)
		{
			Dialog.Create(errorCode);
		}
	}

	public void CreateNetworkBattleErrorDialog(int errorCode)
	{
		StopNetworkBattle();
		Dialog.Create(errorCode);
		DestroyObj(DESTROY_OBJECT_LOG.HandleResultCode);
	}

	public bool HandleingNodeResultCodeIfNeeded(Dictionary<string, object> receivedMessage)
	{
		if (!receivedMessage.Keys.Contains(NetworkBattleDefine.NetworkParameterNames[NetworkBattleDefine.NetworkParameter.resultCode]))
		{
			return false;
		}
		int num = Convert.ToInt32(receivedMessage[NetworkBattleDefine.NetworkParameterNames[NetworkBattleDefine.NetworkParameter.resultCode]]);
		bool flag = false;
		if (Enum.IsDefined(typeof(NetworkBattleDefine.ReceiveNodeResultCode), num))
		{
			NetworkBattleDefine.ReceiveNodeResultCode receiveNodeResultCode = (NetworkBattleDefine.ReceiveNodeResultCode)num;
			switch (receiveNodeResultCode)
			{
			case NetworkBattleDefine.ReceiveNodeResultCode.Success:
				return false;
			case NetworkBattleDefine.ReceiveNodeResultCode.RoomCreateError:
				LocalLog.AccumulateTraceLogAddRoomCreateLog();
				break;
			case NetworkBattleDefine.ReceiveNodeResultCode.SwapTimeoutError:
				(BattleManagerBase.GetIns() as NetworkBattleManagerBase).NetworkSender.SendJudgeResult(NetworkBattleSender.JUDGE_RESULT_STATUS.SwapTimeoutError);
				return false;
			case NetworkBattleDefine.ReceiveNodeResultCode.RoomSetupLock:
				return false;
			case NetworkBattleDefine.ReceiveNodeResultCode.FoundRemovedUserErrorSelf:
			case NetworkBattleDefine.ReceiveNodeResultCode.FoundRemovedUserErrorOppo:
			case NetworkBattleDefine.ReceiveNodeResultCode.FoundRemovedUserErrorWatcher:
			case NetworkBattleDefine.ReceiveNodeResultCode.RoomTimeEndError:
			case NetworkBattleDefine.ReceiveNodeResultCode.WatcherInRemovedOwnerRoomError:
			case NetworkBattleDefine.ReceiveNodeResultCode.RoomTornamentOwnTimeEndError:
			case NetworkBattleDefine.ReceiveNodeResultCode.RoomTornamentOppoTimeEndError:
			case NetworkBattleDefine.ReceiveNodeResultCode.BattleFinishTimeEnd:
				OnResultCodeError.Call(num);
				return false;
			case NetworkBattleDefine.ReceiveNodeResultCode.Different_UUID:
			case NetworkBattleDefine.ReceiveNodeResultCode.RedisReplyError:
			case NetworkBattleDefine.ReceiveNodeResultCode.CurrentBattleError:
			case NetworkBattleDefine.ReceiveNodeResultCode.UnexpectedPhaseError:
			case NetworkBattleDefine.ReceiveNodeResultCode.WatchError:
			{
				bool flag2 = ToolboxGame.RealTimeNetworkAgent.CurrentMatchingStatus < MatchingStatus.Prepared && !IsRecovery;
				if (!flag2 && receiveNodeResultCode == NetworkBattleDefine.ReceiveNodeResultCode.CurrentBattleError)
				{
					(BattleManagerBase.GetIns() as NetworkBattleManagerBase).NetworkSender.SendJudgeResult(NetworkBattleSender.JUDGE_RESULT_STATUS.RecoveryError);
					return false;
				}
				switch (receiveNodeResultCode)
				{
				case NetworkBattleDefine.ReceiveNodeResultCode.RedisReplyError:
					if (BattleManagerBase.GetIns() is NetworkBattleManagerBase networkBattleManagerBase)
					{
						networkBattleManagerBase.NodeErrorToNocontest();
						break;
					}
					return false;
				case NetworkBattleDefine.ReceiveNodeResultCode.Different_UUID:
				case NetworkBattleDefine.ReceiveNodeResultCode.UnexpectedPhaseError:
					IsExistTitleReturnError = true;
					break;
				}
				if (!flag2)
				{
					StopNetworkBattle();
					if (receiveNodeResultCode != NetworkBattleDefine.ReceiveNodeResultCode.RedisReplyError)
					{
						Dialog.Create(num.ToString());
					}
					DestroyObj(DESTROY_OBJECT_LOG.NodeError);
					return false;
				}
				if (receiveNodeResultCode != NetworkBattleDefine.ReceiveNodeResultCode.CurrentBattleError)
				{
					Dialog.Create(num.ToString());
				}
				break;
			}
			case NetworkBattleDefine.ReceiveNodeResultCode.UnmatchedError:
				_matching.StopMatchingAction();
				flag = true;
				break;
			default:
				flag = true;
				break;
			case NetworkBattleDefine.ReceiveNodeResultCode.MatchingTimeOut:
				break;
			}
		}
		else
		{
			flag = true;
		}
		if (flag)
		{
			StopNetworkBattle();
			Dialog.Create(num);
		}
		OnResultCodeError.Call(num);
		DestroyObj(DESTROY_OBJECT_LOG.ResultCode);
		return true;
	}

	private void OnReconnect(Socket socket, Packet packet, params object[] args)
	{
		NetworkLogger.LogInfo("OnReconnect");
		LocalLog.AccumulateLastTraceLog("OnReconnect Socket " + socket.Id);
		ConnectToReconnect();
	}

	private void OnConnect_Socket(Socket socket, Packet packet, params object[] args)
	{
		Toolbox.DeviceManager.ClearIpAddress();
		LocalLog.AccumulateTraceLog("ipAddress" + Toolbox.DeviceManager.GetIpAddress());
		string text = "ConnectSocket Socket " + socket.Id;
		NetworkLogger.LogInfo(text);
		LocalLog.AccumulateLastTraceLog(text);
		NowSocketID = socket.Id;
		if (IsRecovery)
		{
			StartGungnir();
		}
		ConnectToReconnect();
	}

	private void ConnectToReconnect()
	{
		DateTime absoluteTime = TimeUtil.GetAbsoluteTime();
		if (_connectNumToReconnect == 0)
		{
			_connectTicks = absoluteTime.Ticks;
			_connectNumToReconnect++;
			return;
		}
		long ticks = TimeUtil.GetAbsoluteTime().Ticks - _connectTicks;
		if ((float)new TimeSpan(ticks).Seconds <= 30f)
		{
			_connectNumToReconnect++;
			if (_connectNumToReconnect >= 3)
			{
				ReconnectSocketAndLogFlagOn();
				_connectNumToReconnect = 0;
			}
		}
		else
		{
			_connectNumToReconnect = 1;
			_connectTicks = absoluteTime.Ticks;
		}
	}

	public void StartGungnir()
	{
		_gungnir.Start();
	}

	protected virtual void ProcessingRecivedData(Dictionary<string, object> receivedMessage)
	{
		if (stockReceiveMessageMgr.IsNoStockData(receivedMessage))
		{
			bool num = PlayReceiveData(receivedMessage);
			receivedMessage["uri"].ToString();
			if ((num | IsFromResumeData(receivedMessage)) && stockReceiveMessageMgr.IsIncludedSequenceName(receivedMessage) && stockReceiveMessageMgr.GetSequenceNumber(receivedMessage) == stockReceiveMessageMgr.SequenceAlreadyNumber + 1)
			{
				stockReceiveMessageMgr.UpdateSequenceAlreadyNumber(receivedMessage);
			}
		}
		else if (stockReceiveMessageMgr.CheckStockData(receivedMessage))
		{
			string text = "StockData Uri " + receivedMessage["uri"]?.ToString() + ":seqNum " + stockReceiveMessageMgr.GetSequenceNumber(receivedMessage);
			NetworkLogger.LogInfo(text);
			LocalLog.AccumulateLastTraceLog(text);
			stockReceiveMessageMgr.StockData(receivedMessage);
		}
		else
		{
			string text2 = "NotReceiveStock " + receivedMessage["uri"];
			NetworkLogger.LogInfo(text2);
			LocalLog.AccumulateLastTraceLog(text2);
		}
	}

	private void ResumeToStockReceive(Dictionary<string, object> receivedMessage)
	{
		object value = null;
		if (!receivedMessage.TryGetValue("resume", out value))
		{
			return;
		}
		List<object> list = value as List<object>;
		for (int i = 0; i < list.Count; i++)
		{
			Dictionary<string, object> dictionary = list[i] as Dictionary<string, object>;
			object obj = dictionary["uri"];
			if (CheckReceiveMaintenanceToDestroy(obj.ToString()))
			{
				break;
			}
			stockReceiveMessageMgr.SettingOppoDisconnectSequenceNumber(dictionary);
			if (stockReceiveMessageMgr.CheckStockData(dictionary))
			{
				dictionary["isResume"] = true;
				string text = "Resume StockData Uri " + dictionary["uri"]?.ToString() + ":seqNum" + stockReceiveMessageMgr.GetSequenceNumber(dictionary);
				NetworkLogger.LogInfo(text);
				LocalLog.AccumulateLastTraceLog(text);
				stockReceiveMessageMgr.StockData(dictionary);
			}
		}
	}

	public virtual bool PlayReceiveData(Dictionary<string, object> synchronizeData)
	{
		OnReceivedEvent.Call(synchronizeData);
		return true;
	}

	private void OnOpponentLost(Socket socket, Packet packet, params object[] args)
	{
		LocalLog.AccumulateLastTraceLog("OnOpponentLost Socket " + socket.Id);
	}

	private void OnDisconnect(Socket socket, Packet packet, params object[] args)
	{
		_disconnectNum++;
		string text = "";
		if (NowSocketID != socket.Id)
		{
			text += " differID ";
		}
		LocalLog.AccumulateLastTraceLog("OnDisconnect socket " + socket.Id + " " + text);
		PlayerNetworkStatus.ToDisconnect();
	}

	protected virtual void OnDestroy()
	{
		LocalLog.AccumulateLastTraceLog("OnDestroy");
		ManagerClose();
	}

	public void ManagerClose()
	{
		if (_manager != null)
		{
			_manager.Close();
			LocalLog.AccumulateTraceLog("LastSocketID " + NowSocketID);
		}
		_manager = null;
	}

	public bool IsOpen()
	{
		if (_manager == null)
		{
			return false;
		}
		if (_manager.State == SocketManager.States.Open)
		{
			return true;
		}
		return false;
	}

	public bool IsInitNetworkSuccess()
	{
		if (_manager == null)
		{
			return false;
		}
		return _initNetworkSuccess;
	}

	public void EmitMsgPack(string uri, EmitCategory emitCategory, Dictionary<string, object> info, Action onFinishedSend = null, bool isGetableAck = true, bool isStockData = true, int fixedSeqNumber = -1)
	{
		if (info == null)
		{
			info = new Dictionary<string, object>();
		}
		info.Add("cat", (int)emitCategory);
		_onFinishedEmit = onFinishedSend;
		info = CreateEmitData(uri, info);
		EmitMsgUriPack(info, isGetableAck, isStockData, fixedSeqNumber);
	}

	public void EmitMsgPack(NetworkBattleDefine.NetworkBattleURI uri, Dictionary<string, object> info = null, Action onFinishedSend = null, bool isGetableAck = true, int fixedSeqNumber = -1, bool isStockData = true, bool isNotActionSeq = false)
	{
		if (OnEmit != null)
		{
			OnEmit(uri);
		}
		if (uri != NetworkBattleDefine.NetworkBattleURI.BattleFinish && uri != NetworkBattleDefine.NetworkBattleURI.TurnEndFinal && CurrentMatchingStatus == MatchingStatus.Disconnected)
		{
			LocalLog.AccumulateLastTraceLog("EmitMsgPack Disconnected " + uri);
			return;
		}
		EmitCategory emitCategory = EmitCategory.battle;
		emitCategory = ((!IsMatchingURI(uri.ToString())) ? EmitCategory.battle : ((uri != NetworkBattleDefine.NetworkBattleURI.InitNetwork) ? EmitCategory.matching : EmitCategory.general));
		if (uri == NetworkBattleDefine.NetworkBattleURI.TurnStart)
		{
			LocalLog.InitGungnirLog();
			LocalLog.InitDisconnectLog();
			LocalLog.InitSocketFrameLog();
		}
		if (!isNotActionSeq && (uri == NetworkBattleDefine.NetworkBattleURI.PlayActions || uri == NetworkBattleDefine.NetworkBattleURI.TurnEndActions || uri == NetworkBattleDefine.NetworkBattleURI.Echo))
		{
			AddActionSequence();
			LocalLog.AccumulateLastTraceLog("uri:" + uri.ToString() + " ActionSeq:" + GetActionSequenceCount() + " NotRecovery");
		}
		string uri2 = uri.ToString();
		EmitCategory emitCategory2 = emitCategory;
		int fixedSeqNumber2 = fixedSeqNumber;
		EmitMsgPack(uri2, emitCategory2, info, onFinishedSend, isGetableAck, isStockData, fixedSeqNumber2);
	}

	public void EmitHandData(List<object> parameters, NetworkBattleSender.HAND_URI_TYPE uri, bool isSkipDuplicateCheck = false)
	{
		if (_notEmit || GameMgr.GetIns().IsWatchBattle)
		{
			return;
		}
		List<object> list = CreateEmitHandData(parameters, (int)uri);
		if (_manager == null)
		{
			return;
		}
		if (uri == NetworkBattleSender.HAND_URI_TYPE.SELECT_SKILL_URI || uri == NetworkBattleSender.HAND_URI_TYPE.SLIDE_OBJECT_URI)
		{
			if ((uri != NetworkBattleSender.HAND_URI_TYPE.SLIDE_OBJECT_URI || !IsDuplicateSlideData(list)) && (isSkipDuplicateCheck || uri != NetworkBattleSender.HAND_URI_TYPE.SELECT_SKILL_URI || !IsDuplicateSelectSkillData(list)))
			{
				Dictionary<string, object> dictionary = new Dictionary<string, object>();
				dictionary.Add("StockHandData", list);
				dictionary.Add(status_try, 0);
				EmitMsgUriPack(dictionary, isGetableAck: true, isStockData: true, -1, isHandData: true);
			}
		}
		else
		{
			_manager.Socket.Emit("hand", CreatePackEmitHandData(list));
		}
	}

	private bool IsDuplicateSelectSkillData(List<object> parameters)
	{
		if (parameters.Count == 5)
		{
			return false;
		}
		try
		{
			List<Dictionary<string, object>> stockDataList = stockEmitMessageMgr.GetStockDataList();
			for (int i = 0; i < stockDataList.Count; i++)
			{
				Dictionary<string, object> dictionary = stockDataList[i];
				if (!dictionary.ContainsKey("StockHandData"))
				{
					continue;
				}
				List<object> list = dictionary["StockHandData"] as List<object>;
				if ((int)list[0] == 2)
				{
					string value = parameters[4].ToString();
					string value2 = parameters[5].ToString();
					string text = list[5].ToString();
					string text2 = list[6].ToString();
					if (text.Equals(value) && text2.Equals(value2))
					{
						return true;
					}
				}
			}
		}
		catch (Exception message)
		{
			Debug.LogError(message);
			return false;
		}
		return false;
	}

	private bool IsDuplicateSlideData(List<object> parameters)
	{
		try
		{
			List<Dictionary<string, object>> stockDataList = stockEmitMessageMgr.GetStockDataList();
			for (int i = 0; i < stockDataList.Count; i++)
			{
				Dictionary<string, object> dictionary = stockDataList[i];
				if (!dictionary.ContainsKey("StockHandData"))
				{
					continue;
				}
				List<object> list = dictionary["StockHandData"] as List<object>;
				if ((int)list[0] == 5)
				{
					string value = parameters[3].ToString();
					string value2 = parameters[4].ToString();
					string text = list[4].ToString();
					string text2 = list[5].ToString();
					if (text.Equals(value) && text2.Equals(value2))
					{
						return true;
					}
				}
			}
		}
		catch (Exception message)
		{
			Debug.LogError(message);
			return false;
		}
		return false;
	}

	public Dictionary<string, object> CreateEmitData(string uri, Dictionary<string, object> sendData, bool isTrySend = true)
	{
		if (sendData == null)
		{
			sendData = new Dictionary<string, object>();
		}
		if (!sendData.Any((KeyValuePair<string, object> s) => s.Key == "uri"))
		{
			sendData.Add("uri", uri);
		}
		int num = viewerId;
		sendData.Add("viewerId", num);
		sendData.Add("uuid", Certification.Udid);
		if (!string.IsNullOrEmpty(bid))
		{
			sendData.Add("bid", bid.ToString());
		}
		if (isTrySend && !sendData.Any((KeyValuePair<string, object> s) => s.Key == status_try))
		{
			sendData.Add(status_try, 0);
		}
		return sendData;
	}

	private List<object> CreateEmitHandData(List<object> parameters, int uri)
	{
		List<object> list = new List<object>();
		list.Add(uri);
		list.Add(viewerId);
		list.Add(Certification.Udid);
		list.AddRange(parameters);
		return list;
	}

	private string GetHandUri(Dictionary<string, object> data)
	{
		return (data["StockHandData"] as List<object>)[0].ToString();
	}

	private void EmitMsgUriPack(Dictionary<string, object> info, bool isGetableAck, bool isStockData, int fixedSeqNumber, bool isHandData = false)
	{
		string text = "";
		text = (isHandData ? GetHandUri(info) : info["uri"].ToString());
		if (_notEmit)
		{
			LocalLog.AccumulateLastTraceLog("EmitMsgUriPack _notEmit " + text);
		}
		else if (isGetableAck)
		{
			int num = stockEmitMessageMgr.SequenceNumber + 1;
			if (fixedSeqNumber == -1)
			{
				LastEmitSeqNumber = stockEmitMessageMgr.SequenceNumber + 1;
				stockEmitMessageMgr.AddSequenceNumber();
			}
			else
			{
				num = fixedSeqNumber;
			}
			info.Add("pubSeq", num);
			if (isHandData)
			{
				(info["StockHandData"] as List<object>).Insert(3, num);
			}
			if (isStockData)
			{
				stockEmitMessageMgr.StockData(info);
				List<Dictionary<string, object>> sequenceAllData = stockEmitMessageMgr.GetSequenceAllData();
				if (sequenceAllData != null && sequenceAllData.Count == 1)
				{
					EmitFrontStockData();
				}
				else if (isHandData)
				{
					LocalLog.AccumulateLastTraceLog("Emit StockHand " + Enum.GetName(typeof(NetworkBattleSender.HAND_URI_TYPE), int.Parse(text)));
				}
				else
				{
					LocalLog.AccumulateLastTraceLog("Emit Stock " + text);
				}
			}
			else
			{
				EmitDataToAckCallBack(info);
			}
		}
		else
		{
			if (text == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.InitNetwork])
			{
				LocalLog.AccumulateLastTraceLog("EmitMsgUriPack_InitNetwork " + StackTraceUtility.ExtractStackTrace());
			}
			_manager.Socket.Emit("msg", CreatePackEmitData(info));
			if (text != RoomParamKey.WatchUriNames[PlayerControllerForWatching.SEND_PARAMETER.Watch])
			{
				string text2 = "Emit NotWait Uri " + info["uri"];
				NetworkLogger.LogInfo(text2);
				LocalLog.AccumulateLastTraceLog(text2);
			}
		}
	}

	public bool GetTurnState()
	{
		if (GameMgr.GetIns().GetNetworkUserInfoData().TurnState != 0)
		{
			return false;
		}
		return true;
	}

	public void SetNetworkInfo(Dictionary<string, object> synchronizeData, ref NetworkBattleDefine.NetworkBattleURI receiveUri)
	{
		foreach (KeyValuePair<string, object> synchronizeDatum in synchronizeData)
		{
			switch (synchronizeDatum.Key)
			{
			case "uri":
			{
				string text = synchronizeDatum.Value.ToString();
				if (Enum.IsDefined(typeof(NetworkBattleDefine.NetworkBattleURI), text))
				{
					receiveUri = (NetworkBattleDefine.NetworkBattleURI)Enum.Parse(typeof(NetworkBattleDefine.NetworkBattleURI), text);
					if (text == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Matched])
					{
						GameMgr.GetIns().InitializeSelfInfo();
					}
					break;
				}
				Enum.IsDefined(typeof(PlayerController.ROOM_URI), text);
				return;
			}
			case "selfInfo":
			{
				Dictionary<string, object> info2 = synchronizeDatum.Value as Dictionary<string, object>;
				if (receiveUri != NetworkBattleDefine.NetworkBattleURI.BattleStart)
				{
					IsBattleStart = true;
					GameMgr.GetIns().SettingSelfInfo(info2, isWatchReplayRecovery: false);
				}
				else
				{
					GameMgr.GetIns().SettingBattleStartSelfInfo(info2);
					Wizard.Data.RoomTwoPickBeforeBattleInfo.SelfInfoClasIdCopyTwoPickDraftData();
				}
				break;
			}
			case "selfDeck":
			{
				GameMgr ins = GameMgr.GetIns();
				List<object> list = synchronizeDatum.Value as List<object>;
				ins.GetDataMgr().SetDeckMaxCount(list.Count, isSelf: true);
				ins.SettingSelfDeck(synchronizeDatum.Value as List<object>);
				break;
			}
			case "turnState":
				GameMgr.GetIns().GetNetworkUserInfoData().TurnState = Convert.ToInt32(synchronizeDatum.Value);
				break;
			case "oppoInfo":
			{
				Dictionary<string, object> info = synchronizeDatum.Value as Dictionary<string, object>;
				if (receiveUri != NetworkBattleDefine.NetworkBattleURI.BattleStart)
				{
					GameMgr.GetIns().SettingOpponentInfo(info, isWatchReplayRecovery: false);
				}
				else
				{
					GameMgr.GetIns().SettingBattleStartOpponentInfo(info);
				}
				break;
			}
			case "bid":
				bid = synchronizeDatum.Value.ToString();
				break;
			}
		}
	}

	public void FinishBattleTask()
	{
		if (_failedRecoveryToNotSendFinishTask)
		{
			LocalLog.AccumulateLastTraceLog("Finsish BattleTask Error");
			return;
		}
		if (CurrentMatchingStatus == MatchingStatus.Disconnected)
		{
			LocalLog.AccumulateLastTraceLog("FinishBattleTask Disconnected");
			return;
		}
		StopNetworkBattle(isNotCloseWindow: true);
		if (_battleFinishSendBase == null)
		{
			_battleFinishSendBase = new BattleFinishSendBase(_networkBattleManager);
		}
		_battleFinishSendBase.SendMatchingFinish(FinishTaskBase, FinishResultSuccses);
		FinishTaskBase = null;
	}

	public void FinishBattleTask(BattleManagerBase battleMgr)
	{
		if (_failedRecoveryToNotSendFinishTask)
		{
			LocalLog.AccumulateLastTraceLog("Finsish BattleTask Error");
			return;
		}
		if (CurrentMatchingStatus == MatchingStatus.Disconnected)
		{
			LocalLog.AccumulateLastTraceLog("FinishBattleTask Disconnected");
			return;
		}
		StopNetworkBattle(isNotCloseWindow: true);
		if (_battleFinishSendBase == null)
		{
			_battleFinishSendBase = new BattleFinishSendBase(battleMgr);
		}
		_battleFinishSendBase.SendMatchingFinish(FinishTaskBase, FinishResultSuccses);
		FinishTaskBase = null;
	}

	protected virtual void FinishResultSuccses(NetworkTask.ResultCode result)
	{
		LocalLog.AccumulateLastTraceLog("FinishResultSuccses" + result);
		if (_isFinishResultSuccses)
		{
			return;
		}
		_isFinishResultSuccses = true;
		LocalLog.RecordCheckLog(LocalLog.RecordType.HADES, _networkBattleManager.BattleResultType == BattleManagerBase.BATTLE_RESULT_TYPE.WIN);
		_networkBattleManager.SettingNetworkBattleEnd();
		UIManager.GetInstance().dialogAllClear();
		NetworkBattleReceiver.RESULT_CODE judgeResultReceiveCode = _networkBattleManager.JudgeResultReceiveCode;
		bool classDead = false;
		if ((uint)(judgeResultReceiveCode - 105) <= 1u || (uint)(judgeResultReceiveCode - 201) <= 7u)
		{
			classDead = true;
		}
		_networkBattleManager.FinishBattleEffect(classDead);
		if (judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.NoContest && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.DisconnectWin && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.DisconnectLose && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.Invalid && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.TurnendWin && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.TurnendLose && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.TurnstartWin && judgeResultReceiveCode != NetworkBattleReceiver.RESULT_CODE.TurnstartLose)
		{
			TaskManager.GetInstance().NotMyPageSend();
		}
		if (judgeResultReceiveCode == NetworkBattleReceiver.RESULT_CODE.NoContest)
		{
			LocalLog.SendLastTraceLog(null);
		}
		if (_trySerializeList.Any())
		{
			string text = string.Empty;
			for (int i = 0; i < _trySerializeList.Count; i++)
			{
				text += _trySerializeList[i];
			}
			LocalLog.AccumulateTraceLog(text);
			_trySerializeList.Clear();
		}
		DestroyObj(DESTROY_OBJECT_LOG.BattleResult);
	}

	public void InitCurrentMatchingStatus()
	{
		CurrentMatchingStatus = MatchingStatus.OffLine;
	}

	public void CallMaintenanceError()
	{
		ShowMaintenanceError();
	}

	protected virtual void ShowMaintenanceError()
	{
		Dialog.Create(5);
	}

	public virtual void StopNetworkBattle(bool isNotCloseWindow = false)
	{
	}

	public void DestroyObj(DESTROY_OBJECT_LOG log)
	{
		NetworkLogger.ClearLog();
		int num = (int)log;
		LocalLog.AccumulateLastTraceLog("RealtimeNetwork DestroyObj" + num);
		ManagerClose();
		_onEveryTimeFail = null;
		_onFinishedEmit = null;
		OnReceivedEvent = null;
		OnResultCodeError = null;
		OnAck = null;
		if (!_isAlreadyDestroyedGameObject)
		{
			_isAlreadyDestroyedGameObject = true;
			UnityEngine.Object.Destroy(base.gameObject);
		}
		if (_gungnir != null)
		{
			_gungnir.Dispose();
			_gungnir = null;
		}
	}

	public virtual void StartRecovery(string battleId, int maxSequenceNumber, int currentSequenceNumber)
	{
		SetIsRecovery(flg: true);
		bid = battleId;
		stockReceiveMessageMgr.Recovery(maxSequenceNumber);
		stockEmitMessageMgr.Recovery(currentSequenceNumber);
	}

	public virtual void EndRecovery()
	{
		if (RecoveryManagerBase.failedRecoveryFlag)
		{
			_notEmit = true;
		}
		SetIsRecovery(flg: false);
	}

	public virtual void GetRecoveryInfo(out string battleId, out int maxSequenceNumber, out int currentSequenceNumber, out int turnState_)
	{
		battleId = bid;
		maxSequenceNumber = stockReceiveMessageMgr.SequenceAlreadyNumber;
		currentSequenceNumber = stockEmitMessageMgr.SequenceNumber;
		turnState_ = -1;
	}

	public int GetCurrentSequenceNumber()
	{
		return stockEmitMessageMgr.SequenceNumber;
	}

	protected bool IsDataHaveSequenceNumber(Dictionary<string, object> data)
	{
		if (stockReceiveMessageMgr.IsNoStockData(data))
		{
			return false;
		}
		return true;
	}

	public void UpdateLastGungnirSuccessTime()
	{
		if (_gungnir != null)
		{
			_gungnir.Tick();
		}
	}

	protected bool IsMatchingURI(string uri)
	{
		if (uri == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.InitBattle] || uri == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.InitRoomBattle] || uri == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Matched] || uri == NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.InitNetwork])
		{
			return true;
		}
		return false;
	}

	public void SetRoomWatchMode(bool isWatchRoom)
	{
		_gungnir._isNotEmit = isWatchRoom;
	}

	public void ClearStockEmitData()
	{
		stockEmitMessageMgr.ClearSequenceDataList();
	}

	public virtual void StartRecoveryRecording()
	{
		_networkBattleManager.StartRecoveryRecording();
	}

	public void ResetDisconnectLogNum()
	{
		_disconnectNum = 0;
		_emitLogNum = 0;
	}

	public void AddActionSequence()
	{
		_gungnir._actionSequenceNum++;
		NetworkLogger.LogInfo("ActionSeq" + _gungnir._actionSequenceNum);
	}

	public void SetEnableTimeOutCallBack(bool enable)
	{
		_gungnir.IsEnableTimeoutCallBack = enable;
	}

	public int GetTurnSequence()
	{
		return _gungnir._actionSequenceNum;
	}
}
