This commit is contained in:
DESKTOP-5RP3AKU\Jisol
2024-01-29 02:28:42 +08:00
parent 68c4d5e811
commit 01a4312761
73 changed files with 13939 additions and 42231 deletions

View File

@@ -10,6 +10,7 @@ using Plugins.JNGame.Network.Util;
using Plugins.JNGame.System;
using Plugins.JNGame.Util;
using UnityEngine;
using Object = System.Object;
namespace Plugins.JNGame.Network
{
@@ -87,11 +88,6 @@ namespace Plugins.JNGame.Network
List<Delegate> funs = _event.EventHandlers[$"{data.HId}"];
funs.ForEach(fun =>
{
if (data.Bytes.Length <= 0)
{
((Action<IMessage>)fun)(null);
return;
}
if(fun.Method.GetParameters().Length == 1 && typeof(IMessage).IsAssignableFrom(fun.Method.GetParameters()[0].ParameterType))
{
var type = fun.Method.GetParameters()[0].ParameterType;
@@ -102,9 +98,17 @@ namespace Plugins.JNGame.Network
if (methodInfo != null)
{
var message = methodInfo.Invoke(cType.GetValue(null), new object[] { data.Bytes });
fun.Method.Invoke(fun.Target,new object[]{ message });
fun.Method.Invoke(fun.Target,new []{ message });
}
}
else
{
fun.Method.Invoke(fun.Target,new [] { (object)null });
}
}
else
{
fun.Method.Invoke(fun.Target,new object[]{ });
}
});
@@ -115,6 +119,11 @@ namespace Plugins.JNGame.Network
{
_event.AddListener($"{hId}",listener);
}
public void AddListener(int hId, global::System.Action listener)
{
_event.AddListener($"{hId}",listener);
}
//删除外部监听
public void RemoveListener<T>(int hId,Action<T> listener) where T : IMessage

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Plugins.JNGame.Sync.Frame.game;
using Plugins.JNGame.System;
using Plugins.JNGame.Util;
using UnityEngine;
@@ -22,7 +24,7 @@ namespace Plugins.JNGame.Sync.Frame
//帧队列
private List<JNFrameInfo> _nFrameQueue = new();
private Queue<JNFrameInfo> _nFrameQueue = new();
//本地帧数
private int _nLocalFrame = 0;
@@ -32,6 +34,9 @@ namespace Plugins.JNGame.Sync.Frame
//暂存帧列表
private Dictionary<int,JNFrameInfo> _nFrameTempQueue = new();
//需要同步的Actor
private List<JNSyncFrameComponent<object>> _nSyncActors = new();
//ID 每添加 JNSyncFrameComponent + 1
public Func<int> nSyncID = RandomUtil.Next(0);
@@ -44,6 +49,9 @@ namespace Plugins.JNGame.Sync.Frame
//是否开始同步
Boolean _isStart = false;
//是否请求后台数据
private Boolean _isRequestServerData = false;
//帧更新
int dtTotal = 0;
//输入更新
@@ -56,9 +64,15 @@ namespace Plugins.JNGame.Sync.Frame
return Task.CompletedTask;
}
//开始
public void onStart(){
this._isStart = true;
}
//重置数据
public void Reset()
public void onStop()
{
this._isStart = false;
this.nSyncID = RandomUtil.Next(0);
this.nRandom = RandomUtil.SyncRandom(100);
this.nRandomInt = RandomUtil.SyncRandomInt(100);
@@ -94,7 +108,35 @@ namespace Plugins.JNGame.Sync.Frame
//运行帧
public void onUpdate()
{
if(!(_nFrameQueue.TryDequeue(out var frame))) return;
int dt = this._nSyncTime / this._nDivideFrame;
//拆出输入
Dictionary<int, JNFrameInput> inputs = new();
foreach (var message in frame.Messages)
{
inputs.Add(message.NId,message);
}
//更新帧
this._nSyncActors.ForEach(child =>
{
if (inputs.ContainsKey(child.NID))
{
child.OnSyncUpdate(dt,frame,child.Decoder(inputs[child.NID].Input.ToByteArray()));
}
else
{
child.OnSyncUpdate(dt,frame,null);
}
});
//执行下一帧物理
Physics.Simulate((float)dt / 1000);
Physics.SyncTransforms();
}
//自适应间隔时间
@@ -127,12 +169,16 @@ namespace Plugins.JNGame.Sync.Frame
* @param frame 帧数据
* @param isLatestData 是否最新的帧数据
*/
public void AddInput(JNFrameInfo frame,Boolean isLatestData = false){
public void AddInput(JNFrameInfo frame,Boolean isLatestData = true)
{
if (!_isStart) return;
if(isLatestData){
//如果推的帧小于本地帧 则 重开
if(frame.Index < _nLocalFrame){
Reset();
onStop();
onStart();
return;
}
}
@@ -143,14 +189,31 @@ namespace Plugins.JNGame.Sync.Frame
//判断接受的帧是否下一帧 如果不是则加入未列入
if (frame.Index != index){
_nFrameTempQueue.Add(frame.Index,frame);
_nFrameTempQueue.TryAdd(frame.Index,frame);
//在未列入中拿到需要的帧
JNFrameInfo tamp = null;
if ((tamp = _nFrameTempQueue[index]) == null){
if ((tamp = _nFrameTempQueue.GetValueOrDefault(index,null)) == null){
//如果没有则向服务器请求我需要的帧数
if (!this._isRequestServerData)
{
this._isRequestServerData = true;
//请求
this.OnServerData(this._nLocalFrame, 0).ContinueWith(infos =>
{
foreach (var frameInfo in infos.Frames)
{
this.AddInput(frameInfo,false);
}
this._isRequestServerData = false;
}).Forget();
}
return;
}
else
@@ -167,15 +230,17 @@ namespace Plugins.JNGame.Sync.Frame
_nLocalFrame = index;
//分帧插入
_nFrameQueue.Add(frame);
for (var i = 0; i < this._nDivideFrame - 1; index++) {
_nFrameQueue.Add(new JNFrameInfo());
_nFrameQueue.Enqueue(frame);
for (var i = 0; i < this._nDivideFrame - 1; i++) {
_nFrameQueue.Enqueue(new JNFrameInfo());
}
}
//发送帧数据
protected abstract void OnSendInput(JNFrameInputs inputs);
//获取帧数据
protected abstract UniTask<JNFrameInfos> OnServerData(int start,int end);
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Text;
using Newtonsoft.Json;
using UnityEngine;
namespace Plugins.JNGame.Sync.Frame.game
@@ -10,7 +12,8 @@ namespace Plugins.JNGame.Sync.Frame.game
//标识
private int _nId;
public int NID => _nId;
//当前输入
private T _input;
@@ -42,8 +45,21 @@ namespace Plugins.JNGame.Sync.Frame.game
//加载
public abstract void OnSyncLoad();
//解析
public T Decoder(byte[] bytes)
{
return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(bytes));
}
//编码
public byte[] Encoder(T input){
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(input));
}
//帧同步
public abstract void OnSyncUpdate(int dt,JNFrameInfo frame,Input input = null);
public abstract void OnSyncUpdate(int dt,JNFrameInfo frame,T input);

View File

@@ -11,6 +11,22 @@ namespace Plugins.JNGame.Util
{
public Dictionary<string, List<Delegate>> EventHandlers { get; private set; } = new();
/// <summary>
/// 添加事件监听器
/// </summary>
/// <param name="eventId">事件标识符</param>
/// <param name="listener">事件监听器</param>
public void AddListener(string eventId, Delegate listener)
{
if (!EventHandlers.ContainsKey(eventId))
{
EventHandlers[eventId] = new List<Delegate>();
}
EventHandlers[eventId].Add(listener);
Debug.Log(eventId+ "AddListener" + EventHandlers[eventId].Count);
}
/// <summary>
/// 添加事件监听器
/// </summary>
@@ -26,7 +42,6 @@ namespace Plugins.JNGame.Util
EventHandlers[eventId].Add(listener);
Debug.Log(eventId+ "AddListener" + EventHandlers[eventId].Count);
//eventHandlers[eventId] = (Action<T>)eventHandlers[eventId] + listener;
}
/// <summary>

View File

@@ -0,0 +1,62 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine.Networking;
namespace Plugins.JNGame.Util
{
public class JAPIConfig{
public string BaseURL = "http://localhost:8080"; //baseURL 默认HTTP头
public int Timeout = 5000; //超时时间
}
public class JAPIData<T>{
public T Data;
}
/**
* JNGame 的 网络请求类
*/
public class JAPI {
private JAPIConfig _config;
public JAPI(JAPIConfig config = null)
{
if (config == null) config = new JAPIConfig();
this._config = config;
}
public async UniTask<T> Get<T>(string url)
{
var request = UnityWebRequest.Get($"{this._config.BaseURL}/{url}");
return JsonConvert.DeserializeObject<T>((await request.SendWebRequest()).downloadHandler.text);
}
public async UniTask<T> Post<T>(string url,Dictionary<string,string> data)
{
var request = UnityWebRequest.Post($"{this._config.BaseURL}/{url}",data);
return JsonConvert.DeserializeObject<T>((await request.SendWebRequest()).downloadHandler.text);
}
public async UniTask<T> Post<T,TA>(string url,TA data)
{
var request = UnityWebRequest.Post($"{this._config.BaseURL}/{url}",JsonConvert.SerializeObject(data));
return JsonConvert.DeserializeObject<T>((await request.SendWebRequest()).downloadHandler.text);
}
public async UniTask<byte[]> GetByte(string url)
{
var request = UnityWebRequest.Get($"{this._config.BaseURL}/{url}");
return (await request.SendWebRequest()).downloadHandler.data;
}
public async UniTask<byte[]> PostByte(string url,Dictionary<string,string> data)
{
var request = UnityWebRequest.Post($"{this._config.BaseURL}/{url}",data);
return (await request.SendWebRequest()).downloadHandler.data;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fc72d9190d1241f680950baaaf2ec27e
timeCreated: 1706373831