Authored Unity primitive/object-model shim, VFX layer (control-flow-preserving, InstantVfx never invokes its action -- headless suppression), god-object stubs (GameMgr/EffectMgr/UIManager with faithfully-extracted nested enums), View/UI/Touch tree, LitJson+BetterList+Tuple copied, third-party stubs. Discovered Roslyn header-error masking: fixing class-header type errors unmasks body references, so the true copy closure is ~2570 files (was 782 under masking). Errors: masked-25720 -> 268; our shim files compile clean. Remaining: ~50 residual shim/external types, 24 NGUI UI-base overrides, static-type fixes, plus likely 1-2 more unmask waves.
304 lines
7.3 KiB
C#
304 lines
7.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using BestHTTP.SocketIO;
|
|
using Cute;
|
|
using UnityEngine;
|
|
using Wizard;
|
|
|
|
public class Gungnir : IDisposable
|
|
{
|
|
private enum ConnectingStatus
|
|
{
|
|
ONLINE,
|
|
WAITING,
|
|
OFFLINE,
|
|
TIMEOUT
|
|
}
|
|
|
|
public enum DisconnectStatus
|
|
{
|
|
NOT,
|
|
SELF_DISCONNECT,
|
|
OPPONENT_DISCONNECT
|
|
}
|
|
|
|
public const string URI = "Gungnir";
|
|
|
|
public const string EMIT_ALIVE = "alive";
|
|
|
|
private const string CURRENT_SEQUENCE = "currentSeq";
|
|
|
|
public const string ACTION_SEQ = "actionSeq";
|
|
|
|
private const string OCS_KEY = "ocs";
|
|
|
|
private const string SCS_KEY = "scs";
|
|
|
|
private const string CLIENT_PUB_SEQ_KEY = "clientPubSeq";
|
|
|
|
private const string CLIENT_REQ_RESEND_KEY = "reqResend";
|
|
|
|
private const float REPORT_INTERVAL = 5f;
|
|
|
|
private RealTimeNetworkAgent _agent;
|
|
|
|
private ConnectionReporter _connectionReporter;
|
|
|
|
public Action OnAlive;
|
|
|
|
public Action OnOpponentAlive;
|
|
|
|
public Action OnOpponentDisconnect;
|
|
|
|
public Action OnOpponentOffLine;
|
|
|
|
public Action OnOpponentTimeOut;
|
|
|
|
public Action<int> OnResendEmitData;
|
|
|
|
public bool _isNotEmit;
|
|
|
|
private int _receiveReSendZeroNum;
|
|
|
|
public List<int> _actionSeqPubSeqList = new List<int>();
|
|
|
|
public int _actionSequenceNum;
|
|
|
|
private float _gungnirLogWaitTimer;
|
|
|
|
private Coroutine _gungnirAckCheckCoroutine;
|
|
|
|
public const float SUCCESS_GUNGNIR_RECEIVE_LOG_TIME = 5f;
|
|
|
|
public DisconnectStatus _DisconnectStatus { get; private set; }
|
|
|
|
public long LastSuccessTime { get; private set; }
|
|
|
|
public bool IsSendActionSequenceNum { get; private set; }
|
|
|
|
public bool IsEnableTimeoutCallBack { get; set; } = true;
|
|
|
|
public long GungnirReceiveCheckTime { get; private set; }
|
|
|
|
public Gungnir(RealTimeNetworkAgent agent)
|
|
{
|
|
_agent = agent;
|
|
_connectionReporter = new ConnectionReporter(agent, EmitGungnir, 5f);
|
|
Tick();
|
|
_DisconnectStatus = DisconnectStatus.NOT;
|
|
}
|
|
|
|
private IEnumerator GungnirLogAckCheck()
|
|
{
|
|
while (true)
|
|
{
|
|
_gungnirLogWaitTimer += Time.deltaTime;
|
|
if (_gungnirLogWaitTimer >= 2f)
|
|
{
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
if (!LocalLog._isSendGungnirLog)
|
|
{
|
|
_agent.NetworkLogger.LogInfo("OnGungnirLog");
|
|
}
|
|
LocalLog._isSendGungnirLog = true;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
_agent.NetworkLogger.LogInfo("Gungnir: Start");
|
|
_connectionReporter.StartReporter();
|
|
LocalLog.InitGungnirLog();
|
|
LocalLog.InitDisconnectLog();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
_connectionReporter.StopReporter();
|
|
_agent.NetworkLogger.LogInfo("Gungnir: Stop");
|
|
LocalLog.AddGungnirLog("GungnirStopReporter ");
|
|
}
|
|
|
|
public void SetSendActionSequenceNumFlag(bool isActive)
|
|
{
|
|
if (!isActive && IsSendActionSequenceNum)
|
|
{
|
|
_agent.NetworkLogger.LogInfo("GungnirSendActionSeq:OFF");
|
|
}
|
|
if (isActive && !IsSendActionSequenceNum)
|
|
{
|
|
_agent.NetworkLogger.LogInfo("GungnirSendActionSeq:ON");
|
|
}
|
|
IsSendActionSequenceNum = isActive;
|
|
}
|
|
|
|
public void EmitGungnir()
|
|
{
|
|
if (GameMgr.GetIns().IsWatchBattle || _isNotEmit)
|
|
{
|
|
return;
|
|
}
|
|
if (_agent.IsOpen())
|
|
{
|
|
_agent.SocketManager.Socket.Emit("alive", OnAckPacket, CreateEmitData());
|
|
if (IsRecordGungnirLog())
|
|
{
|
|
_gungnirAckCheckCoroutine = _agent.StartCoroutine(GungnirLogAckCheck());
|
|
}
|
|
LocalLog.AddGungnirLog("EmitGungnir");
|
|
return;
|
|
}
|
|
LocalLog.AddGungnirLog("NotOpenEmitGungnir");
|
|
if (!LocalLog._isSendGungnirLog)
|
|
{
|
|
_agent.NetworkLogger.LogInfo("OnGungnirLog");
|
|
}
|
|
if (IsRecordGungnirLog())
|
|
{
|
|
LocalLog._isSendGungnirLog = true;
|
|
}
|
|
}
|
|
|
|
private bool IsRecordGungnirLog()
|
|
{
|
|
if (_agent == null || _agent.CurrentMatchingStatus != RealTimeNetworkAgent.MatchingStatus.Prepared || GameMgr.GetIns() == null || GameMgr.GetIns().IsWatchBattle)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private byte[] CreateEmitData()
|
|
{
|
|
Dictionary<string, object> dictionary = _agent.CreateEmitData("Gungnir", null, isTrySend: false);
|
|
dictionary.Add("currentSeq", _agent.MaxMessageSequenceNumber);
|
|
if (IsSendActionSequenceNum)
|
|
{
|
|
dictionary.Add("actionSeq", _actionSequenceNum);
|
|
}
|
|
return _agent.CreatePackEmitData(dictionary);
|
|
}
|
|
|
|
private void OnAckPacket(Socket socket, Packet originalPacket, params object[] args)
|
|
{
|
|
Tick();
|
|
OnAlive.Call();
|
|
LocalLog.AddGungnirLog("GungnirOnAck");
|
|
if (_gungnirAckCheckCoroutine != null)
|
|
{
|
|
_agent.StopCoroutine(_gungnirAckCheckCoroutine);
|
|
}
|
|
_gungnirLogWaitTimer = 0f;
|
|
}
|
|
|
|
public void ReceiveGungnir(Packet originalPacket, params object[] args)
|
|
{
|
|
Dictionary<string, object> dictionary = _agent.DeserializeEncryptedPacket(originalPacket);
|
|
if (dictionary.Count == 0)
|
|
{
|
|
LocalLog.AddGungnirLog("ReceiveGungnirDataZero");
|
|
return;
|
|
}
|
|
string text = dictionary["uri"].ToString();
|
|
if (text != NetworkBattleDefine.NetworkURINames[NetworkBattleDefine.NetworkBattleURI.Gungnir])
|
|
{
|
|
LocalLog.AddGungnirLog("ReceiveGungnirNoUri[" + text + "]");
|
|
}
|
|
else
|
|
{
|
|
if (_agent.HandleingNodeResultCodeIfNeeded(dictionary))
|
|
{
|
|
return;
|
|
}
|
|
if (_agent.IsExistTitleReturnError)
|
|
{
|
|
LocalLog.AddGungnirLog("ReceiveGungnirIsExistTitleReturnError");
|
|
return;
|
|
}
|
|
GungnirReceiveCheckTime = TimeUtil.GetAbsoluteTime().Ticks;
|
|
Tick();
|
|
OnAlive.Call();
|
|
if (dictionary.ContainsKey(NetworkBattleDefine.NetworkParameter.resultCode.ToString()) && int.Parse(dictionary[NetworkBattleDefine.NetworkParameter.resultCode.ToString()].ToString()) == 30002)
|
|
{
|
|
return;
|
|
}
|
|
if (dictionary.ContainsKey("reqResend"))
|
|
{
|
|
int num = int.Parse(dictionary["reqResend"].ToString());
|
|
if (num == 0)
|
|
{
|
|
_receiveReSendZeroNum++;
|
|
}
|
|
if (num == 1 || _receiveReSendZeroNum >= 2)
|
|
{
|
|
_receiveReSendZeroNum = 0;
|
|
if (dictionary.ContainsKey("clientPubSeq"))
|
|
{
|
|
int arg = int.Parse(dictionary["clientPubSeq"].ToString());
|
|
OnResendEmitData.Call(arg);
|
|
}
|
|
}
|
|
}
|
|
if ((ConnectingStatus)Enum.Parse(typeof(ConnectingStatus), dictionary["scs"].ToString()) == ConnectingStatus.OFFLINE)
|
|
{
|
|
_agent.NetworkLogger.LogInfo("Gungnir: Self Offline");
|
|
if (_agent.IsBattleStart)
|
|
{
|
|
_DisconnectStatus = DisconnectStatus.SELF_DISCONNECT;
|
|
}
|
|
return;
|
|
}
|
|
switch ((ConnectingStatus)Enum.Parse(typeof(ConnectingStatus), dictionary["ocs"].ToString()))
|
|
{
|
|
case ConnectingStatus.ONLINE:
|
|
OnOpponentAlive.Call();
|
|
break;
|
|
case ConnectingStatus.WAITING:
|
|
_agent.NetworkLogger.LogInfo("Gungnir: Opponent Disconnect");
|
|
OnOpponentDisconnect.Call();
|
|
break;
|
|
case ConnectingStatus.OFFLINE:
|
|
OpponentOffLine();
|
|
_agent.NetworkLogger.LogInfo("Gungnir: Opponent Offline");
|
|
OnOpponentOffLine.Call();
|
|
break;
|
|
case ConnectingStatus.TIMEOUT:
|
|
OpponentOffLine();
|
|
_agent.NetworkLogger.LogInfo("Gungnir: Opponent TimeOut");
|
|
if (IsEnableTimeoutCallBack)
|
|
{
|
|
OnOpponentTimeOut.Call();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OpponentOffLine()
|
|
{
|
|
if (_agent.IsBattleStart)
|
|
{
|
|
_DisconnectStatus = DisconnectStatus.OPPONENT_DISCONNECT;
|
|
}
|
|
}
|
|
|
|
public void Tick()
|
|
{
|
|
LastSuccessTime = TimeUtil.GetAbsoluteTime().Ticks;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_gungnirAckCheckCoroutine != null)
|
|
{
|
|
_agent.StopCoroutine(_gungnirAckCheckCoroutine);
|
|
}
|
|
_connectionReporter.StopReporter();
|
|
_connectionReporter = null;
|
|
_agent = null;
|
|
}
|
|
}
|