Files
gamer147 957af3d1ec feat(battle-engine): full Unity/VFX/god-object shims + expanded copy closure (2570 files)
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.
2026-06-05 17:22:20 -04:00

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;
}
}