AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs

129 lines
3.9 KiB
C#

using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Common;
using AxibugEmuOnline.Client.Network;
using AxibugProtobuf;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
namespace AxibugEmuOnline.Client
{
public class TickLoop : MonoBehaviour
{
public static Action LoopAction_tick;
public static Action LoopAction_1s;
public static Action LoopAction_3s;
public Stopwatch sw = Stopwatch.StartNew();
public TimeSpan LastStartPingTime;
public int LastPingSeed;
public double AveNetDelay;
public double MinNetDelay;
public double MaxNetDelay;
public List<double> NetDelays = new List<double>();
public const int NetAveDelayCount = 3;
private void Awake()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdPing, OnCmdPing);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdPong, OnCmdPong);
LoopAction_3s += Ping;
#if UNITY_EDITOR
UnityEditor.EditorApplication.playModeStateChanged += (state) =>
{
if (state == UnityEditor.PlayModeStateChange.ExitingPlayMode)
OnApplicationQuit();
};
#endif
}
float LastLoopTime_1s;
float LastLoopTime_3s;
private void Update()
{
NetMsg.Instance.DequeueNesMsg();
LoopAction_tick?.Invoke();
if (Time.time - LastLoopTime_1s > 1)
{
LastLoopTime_1s = Time.time;
LoopAction_1s?.Invoke();
}
if (Time.time - LastLoopTime_3s > 3)
{
LastLoopTime_3s = Time.time;
LoopAction_3s?.Invoke();
}
}
void OnApplicationQuit()
{
App.log.Debug("OnApplicationQuit");
App.network.bAutoReConnect = false;
if (App.network.isConnected)
{
App.network.CloseConntect();
}
}
void Ping()
{
if (!App.network.isConnected)
return;
int randSeed = new System.Random().Next(0, int.MaxValue);
LastPingSeed = randSeed;
LastStartPingTime = App.tickLoop.sw.Elapsed;
Protobuf_Ping resp = new Protobuf_Ping()
{
Seed = randSeed,
};
App.network.SendToServer((int)CommandID.CmdPing, ProtoBufHelper.Serizlize(resp));
}
public void OnCmdPing(byte[] reqData)
{
//App.log.Debug($"OnCmdPing");
Protobuf_Ping msg = ProtoBufHelper.DeSerizlize<Protobuf_Ping>(reqData);
Protobuf_Pong resp = new Protobuf_Pong()
{
Seed = msg.Seed,
};
App.network.SendToServer((int)CommandID.CmdPong, ProtoBufHelper.Serizlize(resp));
}
public void OnCmdPong(byte[] reqData)
{
//App.log.Debug($"OnCmdPong");
Protobuf_Pong msg = ProtoBufHelper.DeSerizlize<Protobuf_Pong>(reqData);
if (LastPingSeed == msg.Seed)
{
TimeSpan current = App.tickLoop.sw.Elapsed;
TimeSpan delta = current - LastStartPingTime;
NetDelays.Add(delta.TotalSeconds);
while (NetDelays.Count > NetAveDelayCount)
NetDelays.RemoveAt(0);
double tempMin = double.MaxValue;
double tempMax = double.MinValue;
for (int i = 0; i < NetDelays.Count; i++)
{
tempMin = Math.Min(NetDelays[i], tempMin);
tempMax = Math.Max(NetDelays[i], tempMax);
}
MinNetDelay = tempMin;
MaxNetDelay = tempMax;
AveNetDelay = NetDelays.Average(w => w);
}
}
}
}