130 lines
3.9 KiB
C#
130 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 System.Net.Sockets;
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|