using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; using AppGame.Systems; using Cysharp.Threading.Tasks; using DotRecast.Core.Collections; using Game.Input; using Game.JNGFrame.Logic; using Game.JNGFrame.Logic.Entity; using Game.JNGFrame.Logic.System; using Game.JNGFrame.View; using Game.JNGState.Logic.Data; using Game.Logic.System; using JNGame.Sync.State.Tile; using JNGame.Sync.State.Tile.Entity; using JNGame.Sync.System; using JNGame.Sync.System.Data; using JNGame.Util; using Plugins.JNGame.Network.Action; using UnityEngine; namespace AppGame.Sync { /// /// 瓦片状态同步[服务器] /// public class JNGTileServerSystem : JNSSTileServerService { /// /// 测试标识 /// private static int TileId = 1; protected List Inputs = new(); //区块Socket public Dictionary Sockets = new (); //是否开始前尝试连接周围区块去恢复历史数据 public bool isRecover = true; /// /// 初始化服务器 /// /// protected override async Task OnInit() { await base.OnInit(); if (isRecover) { List tileIds = GetTileGridIndex(TID); foreach (var tileId in tileIds) { var client = await AddSocket(tileId); if (client is null) continue; //连接到附近区块 开始 恢复数据 Debug.Log($"[JNGTileServerSystem] 连接到附近区块{tileId} 开始 恢复数据"); var tileInfo = await client.NSyncTileGetTileInfo(TID); if (tileInfo is not null) { Debug.Log("[JNGTileServerSystem] 获取到恢复数据成功 正在恢复数据"); var message = new Dictionary(); tileInfo.Data.Data.ForEach(frame => { message.Clear(); foreach (var data in frame.Messages) { message.Add(data.Key,data.Value.Data.ToByteArray()); } GetSystems().ForEach(child => { if (child.NetID != frame.NetID) return; child.OnInsertUBytes(message); }); }); } else { Debug.Log("[JNGTileServerSystem] 获取到恢复数据失败"); } } Debug.Log("[JNGTileServerSystem] 恢复数据结束"); } //添加Tile服务器 App.Business.Send((int)NActionEnum.NAddTileServer,new JNAddTileServer() { Tile = TID, Ip = "127.0.0.1", Port = App.Server.Port }); //定时更新Socket Timers.Instance.SetInterval(1f, UpdateTileSocket); } public override SLogicSystem[] NewLogicSystems() { return new SLogicSystem[] { //基础数据 new DInputSystem(), //游戏输入 new DDataSystem(), //游戏数据 //逻辑层 new DMapSystem(), //游戏地图 new DWorldSystem(), //游戏逻辑 new DPlayerSystem(), //玩家逻辑 }; } public override SDataSystemBase[] NewDataSystems() { return new SDataSystemBase[] { new EDNodeDataSystem(SStateDataEnum.Server), //游戏数据 new EDPlayerDataSystem(SStateDataEnum.Server), //游戏数据 }; } #if UNITY_EDITOR /// /// 编辑器显示视图层 /// /// public override SViewSystem[] NewViewSystems() { return new SViewSystem[] { //视图层 new DViewSystem(), //游戏视图 }; } #endif protected override JNTileContexts CreateTileContexts() { return new EDContexts(); } protected override int[][] Tiles => new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 }, new[] { 7, 8, 9 }, }; protected override int TileSize => 100; protected override async UniTask FetchTileId() { // await UniTask.NextFrame(); // return TileId++; var message = await App.GAPI.NSyncTileId; return message.data; } protected override void OnRunSimulate() { //插入未处理输入 lock (Inputs) { foreach (var input in Inputs) { GetSystem().Enqueue(input); } Inputs.Clear(); } base.OnRunSimulate(); } /// /// 添加输入 /// public void AddInput(JNStateTileInputs info) { lock (Inputs) { info.Message.Inputs.ForEach(child => { Inputs.Add(child); }); } } /// /// 更新区块Socket /// public void UpdateTileSocket() { //获取周围TileId List grid = GetTileGridIndex(TID); grid.Remove(TID); grid.ForEach(index => { if (!IsTileConnect(index)) { AddSocket(index); } }); } /// /// 判断是否当前区块是否连接 /// /// /// public bool IsTileConnect(int index) { return Sockets.ContainsKey(index); } /// /// 获取当前连接的区块列表 /// /// public override int[] GetLinkTiles() { return Sockets.Keys.Where(key => Sockets[key].IsOpen).ToArray(); } protected async Task AddSocket(int index) { if (IsTileConnect(index)) return null; var client = new JNGTileClient(); Sockets.Add(index,client); //获取连接 var message = (await App.GAPI.NSyncTileServer(index)); TileServerInfo info = message.data; if (info is not null) { Debug.Log($"[{index}] 连接 Socket"); client.SetPoint($"{info.ip}:{info.port}"); client.SetTileServer(info.server); await client.OnInit(); return client; } else { Sockets.Remove(index); } return null; } /// /// 销毁Socket /// /// public void RemoveSocket(int index) { if (Sockets.TryGetValue(index,out var client)) { Debug.Log($"[{index}] 卸载 Socket"); client.OnClose(); } Sockets.Remove(index); } public void RemoveSocket(string server) { Sockets.ToArray().ForEach(tile => { if (tile.Value.TileServer != server) return; tile.Value.OnClose(); Sockets.Remove(tile.Key); }); } } }