diff --git a/Api/WebService.cs b/Api/WebService.cs index 4194c43..4a1bc1f 100644 --- a/Api/WebService.cs +++ b/Api/WebService.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using OnlineUserPool.Model; - +using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; @@ -34,5 +34,38 @@ namespace OnlineUserPool.Api } return GetAsync>>($"MapRecord/GetRandomRankingUserRecord?top={ top }&routeIds={ routeIdsStr }").ConfigureAwait(false).GetAwaiter().GetResult().data; } + + public static List GetGameRoomList(int pageIndex,int pageSize) + { + return GetAsync>>($"GameRoom/GetList?pageIndex={ pageIndex }&pageSize={ pageSize }").ConfigureAwait(false).GetAwaiter().GetResult().data; + } + + public static void DeleteGameRoom(int id) + { + var result = PostAsync($"GameRoom/Delete", new {id}).ConfigureAwait(false); + } + + public static void AddGameRoom(int roomId, int status,int userId,string name, int routeId, string pwd, DateTime startTime, int closeTime, int maxMembers) + { + var result = PostAsync($"Admin/GameRoom/Add", new { + status, + userId, + name, + routeId, + pwd, + startTime, + closeTime, + maxMembers + }).ConfigureAwait(false); + } + + public static void UpdateGameRoom(int roomId, int status) + { + var result = PostAsync($"Admin/GameRoom/Update", new + { + roomId, + status + }).ConfigureAwait(false); + } } } diff --git a/Hander/MapRecordRankingHander.cs b/Hander/MapRecordRankingHander.cs index ab73e9d..6625d1a 100644 --- a/Hander/MapRecordRankingHander.cs +++ b/Hander/MapRecordRankingHander.cs @@ -42,10 +42,10 @@ namespace OnlineUserPool.Hander } private const int START = 15; - private const int SMALL = 50; - private const int MEDIUM = 100; - private const int LARGE = 200; - private const int OFFSET = 15; + private const int SMALL = 30; + private const int MEDIUM = 50; + private const int LARGE = 80; + private const int OFFSET = 30; //根据当前时段计算虚拟总人数 private int ComputeTop() @@ -56,19 +56,19 @@ namespace OnlineUserPool.Hander int offset = 1;//少:1 中:3 多:10 if (hour <= 6) { - offset = rand.Next(START- OFFSET, START+ OFFSET); + offset = rand.Next((int)(0.8 * START), (int)(1.2 * START)); } if (hour > 6 && hour <= 18) { - offset = rand.Next(MEDIUM - OFFSET, MEDIUM + OFFSET); + offset = rand.Next((int)(0.8 * OFFSET), (int)(1.2 * MEDIUM)); } if (hour >= 18 && hour <= 22) { - offset = rand.Next(LARGE - OFFSET, LARGE + OFFSET); + offset = rand.Next((int)(0.8 * LARGE), (int)(1.2 * LARGE)); } if (hour > 22 && hour <= 24) { - offset = rand.Next(SMALL - OFFSET, SMALL + OFFSET); + offset = rand.Next((int)(0.8 * SMALL), (int)(1.2 * SMALL)); } return offset; } diff --git a/Hander/MultiUserHandle.cs b/Hander/MultiUserHandle.cs index b6bf421..4b9a526 100644 --- a/Hander/MultiUserHandle.cs +++ b/Hander/MultiUserHandle.cs @@ -15,8 +15,8 @@ namespace OnlineUserPool.Hander private int _index = 0; //3600*3; private MultiUserModel model; private TurfHelper _turfHelper; - private int _routeId = 1215; //5593; //1660; - private int _size = 100; + private int _routeId = 12353; //5593; //1660; + private int _size = 10; private int _competitionid = 0;//35; public MultiUserHandle() { @@ -33,7 +33,7 @@ namespace OnlineUserPool.Hander #region sis - _routeId = 1215; + _routeId = 12353; _competitionid = 0; #endregion @@ -41,7 +41,7 @@ namespace OnlineUserPool.Hander double i = 0; foreach (var item in model.users) { - i += 0.0012; + i += 0.01; item.Distance = i; } _turfHelper = new TurfHelper(model.route.List.Select(d => d.Point)); diff --git a/Model/CustomList.cs b/Model/CustomList.cs new file mode 100644 index 0000000..4137681 --- /dev/null +++ b/Model/CustomList.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace OnlineUserPool.Model +{ + public class CustomList + { + private List List = new List(); + + public object lockObj = new object(); + + public void Add(T o) + { + lock (lockObj) + { + List.Add(o); + } + } + + public void Remove(T o) + { + lock (lockObj) + { + List.Remove(o); + } + } + public List ToList() + { + return List; + } + public int Count() + { + return List.Count; + } + } +} diff --git a/Model/HostModel.cs b/Model/HostModel.cs index 1e2382d..33bdfed 100644 --- a/Model/HostModel.cs +++ b/Model/HostModel.cs @@ -121,5 +121,35 @@ namespace OnlineUserPool.Model SetProperty(ref _IsWatch, value); } } + + private string _Request; + public string Request + { + get { return _Request; } + set + { + SetProperty(ref _Request, value); + } + } + + private string _Model; + public string Model + { + get { return _Model; } + set + { + SetProperty(ref _Model, value); + } + } + + private int _RoomId; + public int RoomId + { + get { return _RoomId; } + set + { + SetProperty(ref _RoomId, value); + } + } } } diff --git a/Model/MsgModel.cs b/Model/MsgModel.cs index 30c4e71..eb783bf 100644 --- a/Model/MsgModel.cs +++ b/Model/MsgModel.cs @@ -42,13 +42,20 @@ namespace OnlineUserPool.Model //public bool ShowVirtual { get; set; } + public int FrameRate { get; set; } + public int RoomId { get; set; } + public DateTime? StartTime { get; set; } + + public string Request { get; set; } + + public string Model { get; set; } public string ToString(int v) { if (v == 2) { - return $"{ RouteId },{ MemberId },{ string.Join(":", Point) },{ Convert.ToInt32(IsCompleted) },{ Speed },{ PreDistance },{ EndDistance },{ WeightKg },{ Competitionid },{ Convert.ToInt32(Saved)},{ Power} ,{ HeartRate},{ Cadence},{ TotalTicks}"; + return $"{ RouteId },{ MemberId },{ string.Join(":", Point) },{ Convert.ToInt32(IsCompleted) },{ Speed },{ PreDistance },{ EndDistance },{ WeightKg },{ Competitionid },{ Convert.ToInt32(Saved)},{ Power} ,{ HeartRate},{ Cadence},{ TotalTicks},{ FrameRate},{RoomId},{StartTime}"; } return $"{ RouteId },{ MemberId },{ string.Join(":", Point) },{ Convert.ToInt32(IsCompleted) },{ Speed },{ PreDistance },{ EndDistance },{ WeightKg },{ Competitionid },{ Convert.ToInt32(Saved)}"; } diff --git a/Model/ReceiveModel.cs b/Model/ReceiveModel.cs index a111c0d..41a991d 100644 --- a/Model/ReceiveModel.cs +++ b/Model/ReceiveModel.cs @@ -15,6 +15,94 @@ namespace OnlineUserPool.Model /// 能处理的消息格式的版本号 /// public int V { get; set; } + /// + /// 子命令类型 + /// + public byte SubType { get; set; } + } + + public class SetModelCommand : ReceiveModel + { + public string Model { get; set; } + } + public class QueryGameRoomListCommand : ReceiveModel + { + public string Name { get; set; } + public int UserId { get; set; } + public int PageIndex { get; set; } + public int PageSize { get; set; } + } + public class CreateGameRoomCommand : ReceiveModel + { + public int Id { get; set; } + + public string Name { get; set; } + + public int RouteId { get; set; } + + public int UserId { get; set; } + + public int CloseTime { get; set; } + + public int MaxMembers { get; set; } + + public string Password { get; set; } + + public DateTime CreateTime { get; set; } + public string MapRouteName { get; set; } + public double Distance { get; set; } + public double TotalClimb { get; set; } + public double AverageGrade { get; set; } + public bool Enable3D { get; set; } + public bool EnableAR { get; set; } + public bool IsLock { get; set; } + public string FileName { get; set; } + public string FileUrl { get; set; } + public string AltitudeGraph { get; set; } + } + + public class JoinGameRoomCommand : ReceiveModel + { + public int RoomId { get; set; } + + public int UserId { get; set; } + + public DateTime JoinAt { get; set; } + } + + public class GameRoomReadyCommand : ReceiveModel + { + public int RoomId { get; set; } + + public int UserId { get; set; } + + public int Status { get; set; } + } + + public class GameRoomStartCommand : ReceiveModel + { + public int RoomId { get; set; } + + public int UserId { get; set; } + + public DateTime StartTime { get; set; } + } + public class GameRoomKickCommand : ReceiveModel + { + public int RoomId { get; set; } + + public int UserId { get; set; }//被踢的人 + + public int OnwerId { get; set; }//房主 + } + + public class GameRoomProcessCommand : ReceiveModel + { + public int RoomId { get; set; } + + public int UserId { get; set; } + + public double Process { get; set; } } public class SetClientCommand : ReceiveModel diff --git a/Model/RoomModel.cs b/Model/RoomModel.cs new file mode 100644 index 0000000..5a3fab6 --- /dev/null +++ b/Model/RoomModel.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OnlineUserPool.Model +{ + public class RoomModel + { + public int Id { get; set; } + public int RoomId { get; set; } + public string Name { get; set; } + public int UserId { get; set; }//房主 + public int Status { get; set; }//房间状态 0 :准备状态 1:开始loading + public DateTime StatusChangedTime { get; set; } + public DateTime CreateTime { get; set; }//创建时间 + public DateTime? StartTime { get; set; }//开始时间 + public int CloseTime { get; set; } + public int MaxMembers { get; set; } + public int MapRouteId { get; set; } + public string MapRouteName { get; set; } + public double Distance { get; set; } + public double TotalClimb { get; set; } + public double AverageGrade { get; set; } + public bool Enable3D { get; set; } + public bool EnableAR { get; set; } + public bool IsLock { get; set; } + public string Password { get; set; } + public string FileName { get; set; } + public string FileUrl { get; set; } + public string AltitudeGraph { get; set; } + + public bool Saved { get; set; } + + public List List { get; set; } + + public override string ToString() + { + return $"{RoomId},{UserId},{Name},{CloseTime},{MaxMembers},{MapRouteId},{MapRouteName},{Distance},{TotalClimb},{AverageGrade},{Enable3D},{EnableAR},{IsLock},{Password},{FileName},{FileUrl},{AltitudeGraph},{Status},{StartTime}"; + } + } + + public class RoomDetailModel + { + public int RoomId { get; set; } + public int UserId { get; set; } + public DateTime JoinAt { get; set; } + public int Status { get; set; } + public double Process { get; set; } + public bool IsOwner { get; set; } + public bool Saved { get; set; } + public DateTime LastActiveTime { get; set; } + + public override string ToString() + { + return $"{RoomId},{UserId},{JoinAt},{Status},{Process},{IsOwner}"; + } + } + //附件信息 + public class ExtendPropertiesModel + { + //AR骑行的视频帧数 + public int FrameRate { get; set; } + + public override string ToString() + { + return $"{FrameRate}"; + } + } +} diff --git a/Model/TargetData.cs b/Model/TargetData.cs index d8d99bf..5a3a314 100644 --- a/Model/TargetData.cs +++ b/Model/TargetData.cs @@ -24,6 +24,10 @@ namespace OnlineUserPool.Model /// public double _Lon = 0d; public double _Bearing = 0d; + /// + /// 帧数 + /// + public int? _FrameRate = 0; public TargetData Clone() { @@ -32,7 +36,7 @@ namespace OnlineUserPool.Model public override string ToString() { - return string.Format($"Ticks:{Ticks} Power:{_Power} Speed:{_Speed} Distance:{_Distance} Cadence:{_Cadence} HeartRate:{_HeartRate} Lat:{_Lat} Lon:{_Lon}"); + return string.Format($"Ticks:{Ticks} Power:{_Power} Speed:{_Speed} Distance:{_Distance} Cadence:{_Cadence} HeartRate:{_HeartRate} Lat:{_Lat} Lon:{_Lon} FrameRate:{_FrameRate}"); } public string Write() diff --git a/Services/TcpService1.cs b/Services/TcpService1.cs index ad545cc..375cc49 100644 --- a/Services/TcpService1.cs +++ b/Services/TcpService1.cs @@ -145,6 +145,38 @@ namespace OnlineUserPool.Services //{ // _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); //} + else if (msg.CommandType == 3) + { + if (msg.SubType == 0) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + if (msg.SubType == 1) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + if (msg.SubType == 2) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + if (msg.SubType == 3) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + + if (msg.SubType == 4) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + if (msg.SubType == 5) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + if (msg.SubType == 6) + { + _action(ipEndPoint, JsonConvert.DeserializeObject(temp)); + } + } else { _action(ipEndPoint, msg); diff --git a/Unility/ConfigHelp.cs b/Unility/ConfigHelp.cs index f8aa254..e065fa3 100644 --- a/Unility/ConfigHelp.cs +++ b/Unility/ConfigHelp.cs @@ -22,6 +22,8 @@ namespace OnlineUserPool.Unility public static int TcpPort { get; private set; } + public static string GameRoomFilePath { get; private set; } + static ConfigHelp() { @@ -32,7 +34,6 @@ namespace OnlineUserPool.Unility UdpPort = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Port"]); TcpPort = int.Parse(System.Configuration.ConfigurationManager.AppSettings["TcpPort"]); - } } } diff --git a/Unility/GameRoomHelper.cs b/Unility/GameRoomHelper.cs new file mode 100644 index 0000000..156854a --- /dev/null +++ b/Unility/GameRoomHelper.cs @@ -0,0 +1,60 @@ +using Newtonsoft.Json; +using OnlineUserPool.Model; +using Serilog; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace OnlineUserPool.Unility +{ + public class GameRoomHelper + { + public static string GameRoomFilePath { get; set; } + static GameRoomHelper() + { + GameRoomFilePath = AppDomain.CurrentDomain.BaseDirectory + "\\GameRoom.txt"; + if (!File.Exists(GameRoomFilePath)) + { + File.Create(GameRoomFilePath); + } + } + + public static List Get() + { + var list = new List(); + try + { + if (!File.Exists(GameRoomFilePath)) + { + return list; + } + var content = File.ReadAllText(GameRoomFilePath); + if (string.IsNullOrEmpty(content)) + { + return list; + } + return JsonConvert.DeserializeObject>(content); + } + catch (Exception e) + { + Log.Error($"读取本地存储对战信息出错:{e}"); + } + return list; + } + + public static void Set(List list) + { + try + { + var str = JsonConvert.SerializeObject(list); + File.WriteAllText(GameRoomFilePath,str); + } + catch (Exception e) + { + Log.Error($"本地存储对战信息出错:{e}"); + } + } + } +} diff --git a/ViewModels/MainWindowViewModel.cs b/ViewModels/MainWindowViewModel.cs index c286a47..fca0f80 100644 --- a/ViewModels/MainWindowViewModel.cs +++ b/ViewModels/MainWindowViewModel.cs @@ -19,13 +19,18 @@ using System.Collections.Concurrent; using System.IO.Compression; using System.IO; using System.Windows; +using OnlineUserPool.Api; +using OnlineUserPool.Api.Model; namespace OnlineUserPool.ViewModels { + + public class MainWindowViewModel : BindableBase - { + { public ObservableCollection Clients { get; private set; } = new ObservableCollection(); private static ConcurrentBag receiveMes = new ConcurrentBag(); + private static CustomList RoomList = new CustomList(); private static object locker = new object(); public static System.Timers.Timer timer; private static IHandle mapRecordRankingHander; @@ -77,6 +82,14 @@ namespace OnlineUserPool.ViewModels public MainWindowViewModel() { + //初始化对战房间信息 + var r = GameRoomHelper.Get(); + foreach (var item in r) + { + RoomList.Add(item); + } + //初测程序关闭事件 + Application.Current.MainWindow.Closing += MainWindow_Closing; Title = $"{ IPAddress.Any }:{ ConfigHelp.UdpPort }"; dispatcher = Dispatcher.CurrentDispatcher; @@ -90,7 +103,7 @@ namespace OnlineUserPool.ViewModels new TcpService1().RunServer(ReceivedData, CientDisconnected); //var tet = new System.Collections.Concurrent.ConcurrentBag(); - + var _udpService = new UdpService(); _udpService.RunServer(ReceivedData); @@ -104,6 +117,11 @@ namespace OnlineUserPool.ViewModels //Console.ReadKey(); } + private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + GameRoomHelper.Set(RoomList.ToList()); + } + private void ReceivedData(IPEndPoint remoteIpEndPoint, ReceiveModel msg, IService service) { dispatcher.Invoke(() => @@ -130,7 +148,7 @@ namespace OnlineUserPool.ViewModels { var client = Clients.FirstOrDefault(n => n.Equals(remoteIpEndPoint)); client.LastActiveTime = DateTime.Now; - if(msg.V > 0) + if (msg.V > 0) { client.V = msg.V; } @@ -142,11 +160,38 @@ namespace OnlineUserPool.ViewModels var client = Clients.FirstOrDefault(n => n.Equals(remoteIpEndPoint)); var msg1 = (msg as MsgModel); client.Competitionid = msg1.Competitionid; + client.Model = msg1.Model; + client.RoomId = msg1.RoomId; if (msg1.V > 0) { client.V = msg1.V; } receiveMes.Add(msg1); + //对战房间内的人保存处理 + if (msg1.RoomId > 0 && msg1.Saved) + { + var current = RoomList.ToList().Where(c => c.RoomId == msg1.RoomId).FirstOrDefault(); + if (current != null) + { + //更新房间内的人的保存状态 + var currentPlayer = current.List.Where(c => c.UserId == msg1.MemberId).FirstOrDefault(); + if (currentPlayer != null) + { + currentPlayer.Saved = true; + } + var notAllSaved = current.List.Where(c => !c.Saved).Any(); + if (!notAllSaved && current.Status != 2) + { + current.Status = 2; + WebService.UpdateGameRoom(current.RoomId, current.Status); + } + if (!current.Saved) + { + current.Saved = true; + WebService.AddGameRoom(current.RoomId,current.Status,current.UserId, current.Name, current.MapRouteId, current.Password, current.StartTime.Value, current.CloseTime, current.MaxMembers); + } + } + } } break; //设置客户端 @@ -162,28 +207,26 @@ namespace OnlineUserPool.ViewModels client.IsWatch = msg1.IsWatch; } break; - //case 3: - // { - // var client = Clients.FirstOrDefault(n => n.Equals(remoteIpEndPoint)); - // var msg1 = (msg as SetWatchCommand); - // client.Competitionid = msg1.Competitionid; - // client.IsWatch = true; - // } - // break; + //GameRoom + case 3: + { + HandleGameRoom(msg); + } + break; default: break; } if (msg.CommandType == 0) { - - + + //client.ShowVirtual = msg.ShowVirtual; } else if (msg.CommandType == 1) { - + } - + }); } @@ -192,11 +235,357 @@ namespace OnlineUserPool.ViewModels NotifyClient(); } + private void HandleGameRoom(ReceiveModel msg) + { + //收 + switch (msg.SubType) + { + case 0: HandleCreateGameRoom(msg); break; + case 1: HandleJoinGameRoom(msg); break; + case 2: HandleGameRoomReadyStatus(msg); break; + case 3: HandleGameRoomStart(msg); break; + case 4: HandleGameRoomKick(msg); break; + case 5: HandleGameRoomProcess(msg); break; + case 6: HandleQueryGameRoomList(msg); break;//查询房间列表 + default: + break; + } + switch (msg.SubType) + { + case 0: + case 1: + case 2: + case 3: + case 4: BroadCastGameRoomList(); break; + } + } + private void SendGameRoomMessage(RoomModel gameRoom) + { + if (gameRoom == null) + return; + var list = new List(); + list.Add(new MsgModel() + { + V = 2, + Point = new double[] { 0d, 0d }, + }); + string ss = ""; + if (gameRoom.List != null && gameRoom.List.Count > 0) + { + ss = string.Join("|", gameRoom.List.Select(c => c.ToString())); + } + var G = $"[{gameRoom},detail{{{ss}}}]"; + var temp = string.Join("|", list.Select(m => m.ToString(2))) + "|"; + var strV21 = $"*l{{{ temp }}};g{{{ G}}};#"; + var ddd = new Data1(strV21); + + var needList = Clients.Where(c => c.RoomId == gameRoom.RoomId).ToList(); + foreach (var client in needList) + { + bool isZip = client.Encoding == "gzip"; + client.Service.Send(ddd.GetBytes(isZip), ddd.GetBytes(isZip).Length, client.IPEndPoint); + client.Request = ""; + } + } + private void BroadCastGameRoomList() + { + //广播 + var needlist = Clients.Where(c => !string.IsNullOrEmpty(c.Model) && c.Model.Equals("GameRoom") && !string.IsNullOrEmpty(c.Request)); + + var list = new List(); + list.Add(new MsgModel() + { + V = 2, + Point = new double[] { 0d, 0d }, + }); + var temp = string.Join("|", list.Select(m => m.ToString(2))) + "|"; + foreach (var item in needlist) + { + var G = GameRoomMessageHandler(item); + var strV21 = $"*l{{{ temp }}};g{{{ G}}};#"; + var ddd = new Data1(strV21); + bool isZip = item.Encoding == "gzip"; + item.Service.Send(ddd.GetBytes(isZip), ddd.GetBytes(isZip).Length, item.IPEndPoint); + } + } + //查询房间列表 + private void HandleQueryGameRoomList(ReceiveModel msg) + { + var query = msg as QueryGameRoomListCommand; + var needSend = Clients.Where(c => c.MemberId == query.UserId).FirstOrDefault(); + if (needSend == null) + return; + + needSend.Request = $"List/{query.PageIndex}/{query.PageSize}/{query.Name}"; + + var list = new List(); + list.Add(new MsgModel() + { + V = 2, + Point = new double[] { 0d, 0d }, + }); + + var temp = string.Join("|", list.Where(m => m.Competitionid == needSend.Competitionid).Select(m => m.ToString(2))) + "|"; + List rooms; + if (!string.IsNullOrEmpty(query.Name)) + { + rooms = RoomList.ToList().Where(c => c.Name.Contains(query.Name) || c.RoomId.ToString() == query.Name).OrderBy(c => c.Status).ThenByDescending(c => c.CreateTime).Skip(query.PageIndex * query.PageSize).Take(query.PageSize).ToList(); + } + else + { + rooms = RoomList.ToList().OrderBy(c => c.Status).ThenByDescending(c => c.CreateTime).Skip(query.PageIndex * query.PageSize).Take(query.PageSize).ToList(); + } + string G = ""; + foreach (var r in rooms) + { + string ss = ""; + if (r.List != null && r.List.Count > 0) + { + ss = string.Join("|", r.List.Select(c => c.ToString())); + } + G += $"[{r.ToString()},detail{{{ss}}}]"; + } + + var strV21 = $"*l{{{ temp }}};g{{{ G}}};#"; + var ddd = new Data1(strV21); + bool isZip = needSend.Encoding == "gzip"; + needSend.Service.Send(ddd.GetBytes(isZip), ddd.GetBytes(isZip).Length, needSend.IPEndPoint); + } + //查询房间明细 + private void HandleQueryGameRoomDetail(ReceiveModel msg) + { + + } + //创建房间 + private void HandleCreateGameRoom(ReceiveModel msg) + { + var createMsg = msg as CreateGameRoomCommand; + var list = new List(); + list.Add(new RoomDetailModel() + { + UserId = createMsg.UserId, + JoinAt = DateTime.Now.ToUniversalTime(), + IsOwner = true, + }); + var maxId = 0; + if (RoomList.Count() > 0) + { + maxId = RoomList.ToList().Max(c => c.RoomId); + } + var room = new RoomModel + { + RoomId = maxId + 1, + Name = createMsg.Name, + Password = createMsg.Password, + CloseTime = createMsg.CloseTime, + CreateTime = createMsg.CreateTime, + MapRouteId = createMsg.RouteId, + MapRouteName = createMsg.MapRouteName, + AltitudeGraph = createMsg.AltitudeGraph, + MaxMembers = createMsg.MaxMembers, + UserId = createMsg.UserId, + AverageGrade = createMsg.AverageGrade, + TotalClimb = createMsg.TotalClimb, + Distance = createMsg.Distance, + EnableAR = createMsg.EnableAR, + Enable3D = createMsg.Enable3D, + FileName = createMsg.FileName, + FileUrl = createMsg.FileUrl, + IsLock = !string.IsNullOrEmpty(createMsg.Password), + List = list, + }; + var mine = Clients.Where(c => c.MemberId == createMsg.UserId).FirstOrDefault(); + if (mine != null) + { + mine.RoomId = room.RoomId; + } + RoomList.Add(room); + //创建房间 + } + //处理当前用户加入房间 + private void HandleJoinGameRoom(ReceiveModel msg) + { + var msg1 = msg as JoinGameRoomCommand; + var room = RoomList.ToList().Where(c => c.RoomId == msg1.RoomId).FirstOrDefault(); + var client = Clients.FirstOrDefault(n => n.MemberId.Equals(msg1.UserId)); + //更新房间信息 + if (room != null) + { + var list = room.List; + var member = list.Where(c => c.UserId == msg1.UserId).FirstOrDefault(); + if (member != null) + { + member.JoinAt = msg1.JoinAt; + } + else + { + list.Add(new RoomDetailModel + { + UserId = msg1.UserId, + JoinAt = msg1.JoinAt, + RoomId = msg1.RoomId + }); + } + if (client != null) + { + client.RoomId = room.RoomId; + client.Request = ""; + } + } + //发送当前房间的信息给当前房间内的人 + SendGameRoomMessage(room); + } + //处理当前用户准备状态 + private void HandleGameRoomReadyStatus(ReceiveModel msg) + { + var msg1 = msg as GameRoomReadyCommand; + var room = RoomList.ToList().Where(c => c.RoomId == msg1.RoomId).FirstOrDefault(); + if (room != null) + { + var list = room.List; + var member = list.Where(c => c.UserId == msg1.UserId).FirstOrDefault(); + if (member != null) + { + member.Status = msg1.Status; + } + } + //发送信息给当前房间内的人 + SendGameRoomMessage(room); + } + //处理当前用户准备状态 + private void HandleGameRoomStart(ReceiveModel msg) + { + var msg1 = msg as GameRoomStartCommand; + var room = RoomList.ToList().Where(c => c.RoomId == msg1.RoomId).FirstOrDefault(); + if (room != null) + { + room.Status = 1; + room.StatusChangedTime = DateTime.Now; + } + //发送信息给当前房间内的人 + SendGameRoomMessage(room); + } + //处理房间踢人的操作 + private void HandleGameRoomKick(ReceiveModel msg) + { + var msg1 = msg as GameRoomKickCommand; + var room = RoomList.ToList().Where(c => c.RoomId == msg1.RoomId).FirstOrDefault(); + if (room != null) + { + var list = room.List; + var needRemove = list.Where(c => c.UserId == msg1.UserId).FirstOrDefault(); + if (needRemove != null) + { + list.Remove(needRemove); + //如果当前是房主退出房间,房主替换成其他人 + if (needRemove.IsOwner && list.Count() > 0) + { + var newOwner = list.FirstOrDefault(); + newOwner.IsOwner = true; + room.UserId = newOwner.UserId; + } + } + //人数为0,删除房间 + if (list.Count() == 0) + { + RoomList.Remove(room); + } + var mine = Clients.Where(c => c.MemberId == msg1.UserId).FirstOrDefault(); + if (mine != null) + { + mine.RoomId = 0; + } + //发送信息给当前房间内的人 + SendGameRoomMessage(room); + } + } + private const int ROOM_TIME_OUT = 60; + private const int TOTAL_PROCESS = 100; + //处理房间内人loading进度 + private void HandleGameRoomProcess(ReceiveModel msg) + { + var msg1 = msg as GameRoomProcessCommand; + var room = RoomList.ToList().Where(c => c.RoomId == msg1.RoomId).FirstOrDefault(); + var client = Clients.Where(c => c.MemberId == msg1.UserId).FirstOrDefault(); + if (room != null) + { + var list = room.List; + var player = list.Where(c => c.UserId == msg1.UserId).FirstOrDefault(); + if (player != null) + { + player.Process = msg1.Process; + } + var notReady = list.Where(c => c.Process < TOTAL_PROCESS).Any(); + var now = DateTime.Now; + + var timespan = now - room.StatusChangedTime; + //超时时间1分钟所有人强制开始 + if ((notReady && timespan.TotalSeconds > ROOM_TIME_OUT) || !notReady) + { + room.StartTime = now.AddSeconds(10).ToUniversalTime(); + } + if (client != null) + { + client.RoomId = room.RoomId; + } + SendGameRoomMessage(room); + } + + } + + private string GameRoomMessageHandler(HostModel item) + { + //如果当前Client有请求房间列表信息,发送房间列表信息 + var G = ""; + if (!string.IsNullOrEmpty(item.Request)) + { + //var resultList = WebService.GetGameRoomList(0, 1000); + //List / 0 / 6 / + var param = item.Request.Split('/'); + var pageInfo = param[0]; + if (pageInfo.Equals("List")) + { + var pageIndex = Convert.ToInt32(param[1]); + var pageSize = Convert.ToInt32(param[2]); + var querName = param[3].ToString(); + List rooms; + if (!string.IsNullOrEmpty(querName)) + { + rooms = RoomList.ToList().Where(c => c.Name.Contains(querName) || c.RoomId.ToString() == querName).OrderBy(c => c.Status).ThenByDescending(c => c.CreateTime).Skip(pageIndex * pageSize).Take(pageSize).ToList(); + } + else + { + rooms = RoomList.ToList().OrderBy(c => c.Status).ThenByDescending(c => c.CreateTime).Skip(pageIndex * pageSize).Take(pageSize).ToList(); + } + foreach (var r in rooms) + { + string ss = ""; + if (r.List != null && r.List.Count > 0) + { + ss = string.Join("|", r.List.Select(c => c.ToString())); + } + G += $"[{r.ToString()},detail{{{ss}}}]"; + } + } + } + + ////如果当前Client有房间信息,将当前房间信息发送当前客户端 + //var currentRoom = RoomList.Where(c => c.Code == item.RoomCode).FirstOrDefault(); + //var gameList = ""; + //var room = ""; + //if (currentRoom != null) + //{ + // room = currentRoom.ToString(); + // gameList = string.Join('|', currentRoom.List.Select(c => c.ToString())); + //} + return $"list{G}"; + } + private void NotifyClient() { try { - if(!receiveMes.Any()) + if (!receiveMes.Any()) { dispatcher.Invoke(() => { @@ -233,8 +622,9 @@ namespace OnlineUserPool.ViewModels #endif msgs.AddRange(virtualData); } - - SendMessage(Clients, msgs); + //屏蔽房间模式的用户 + var c = Clients.Where(c => string.IsNullOrEmpty(c.Model)).ToList(); + SendMessage(c, msgs); dispatcher.Invoke(() => { @@ -251,7 +641,7 @@ namespace OnlineUserPool.ViewModels //移除下线的客户端 for (int i = 0; i < msgs.Count; i++) { - if (msgs[i].exit && msgs[i].MemberId >0)//客户端退出,并且不是虚拟的人物 + if (msgs[i].exit && msgs[i].MemberId > 0)//客户端退出,并且不是虚拟的人物 { //这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字) var info = Clients.FirstOrDefault(n => n.MemberId == msgs[i].MemberId); @@ -282,14 +672,14 @@ namespace OnlineUserPool.ViewModels } } - private void SendMessage(Collection clients, List msgModels) + private void SendMessage(IList clients, List msgModels) { if (!clients.Any() || !msgModels.Any()) { return; } var clients1 = clients.ToList(); - + var list = CloneJson>(msgModels); foreach (var item in list) { @@ -297,7 +687,7 @@ namespace OnlineUserPool.ViewModels item.EndDistance = Math.Round(item.EndDistance, 5); item.WeightKg = Math.Round(item.WeightKg, 2); } - string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(list.Select(m=> new { + string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(list.Select(m => new { m.RouteId, m.MemberId, m.Point, @@ -310,6 +700,7 @@ namespace OnlineUserPool.ViewModels m.WeightKg, m.Competitionid, m.Saved, + m.FrameRate, })); var data = Encoding.ASCII.GetBytes(jsonString); //SendDataSize = (data.Length/1000D).ToString() +"KB"; @@ -339,14 +730,14 @@ namespace OnlineUserPool.ViewModels ////var dataCompressV2 = Encoding.UTF8.GetBytes($"{ Convert.ToBase64String(CommonHelper.Compress(strV2)) }"); //var data2 = new Data1(strV2); - SendDataSize = $"\t单客户端数据包V1:{ data1.GetBytes().Length/1000D }KB,一共占用带宽:{ data1.GetBytes().Length / 1000D * clients1.Count }KB,压缩以后{ data1.GetBytes(true).Length/1000D * clients1.Count }KB"; + SendDataSize = $"\t单客户端数据包V1:{ data1.GetBytes().Length / 1000D }KB,一共占用带宽:{ data1.GetBytes().Length / 1000D * clients1.Count }KB,压缩以后{ data1.GetBytes(true).Length / 1000D * clients1.Count }KB"; #region udp发送数据 foreach (var item in clients1) { try { - if(item == null) + if (item == null) { continue; } @@ -372,22 +763,20 @@ namespace OnlineUserPool.ViewModels } else if (item.V == 2) { - //ddd = data2; - var temp = string.Join("|", list.Where(m => m.Competitionid == item.Competitionid).Select(m => m.ToString(2))) + "|"; - var watchList1 = string.Join('|', clients1.Where(c => c.IsWatch && c.Competitionid == item.Competitionid).Select(c => c.MemberId)); - var strV21 = $"*l{{{ temp }}};w{{{ watchList1 }}}#"; + var e = string.Join("|", list.Where(c => c.RoomId > 0).Distinct().Select(c => $"{c.MemberId},{c.RoomId}")); + //TODO:去重 + var strV21 = $"*l{{{ temp }}};w{{{ watchList1 }}};e{{{ e }}};#"; ddd = new Data1(strV21); - } else { continue; } bool isZip = item.Encoding == "gzip"; - item.Service.Send(ddd.GetBytes(isZip), ddd.GetBytes(isZip).Length, item.IPEndPoint); - } + item.Service.Send(ddd.GetBytes(isZip), ddd.GetBytes(isZip).Length, item.IPEndPoint); + } } catch (Exception e) { @@ -406,6 +795,27 @@ namespace OnlineUserPool.ViewModels //#endregion } + private void GameRoomDisConnectHandler(HostModel client) + { + //如果是在对战房间或者对战列表掉线执行,骑行阶段断开连接不移除房间信息 + if ( !string.IsNullOrEmpty(client.Model) && !client.Model.Equals("GameRoom")) + return; + + RoomList.ToList().ForEach(o => { + if (o.List != null && o.Status == 0) + { + var needRemove = o.List.Where(c => c.UserId == client.MemberId).FirstOrDefault(); + o.List.Remove(needRemove); + } + }); + var needRemoveList = RoomList.ToList().Where(c => c.List.Count == 0).ToList(); + foreach (var item in needRemoveList) + { + RoomList.Remove(item); + } + BroadCastGameRoomList(); + } + void WriteLine(string str) { @@ -439,6 +849,7 @@ namespace OnlineUserPool.ViewModels if (client != null) { Clients.Remove(client); + GameRoomDisConnectHandler(client); } } catch(Exception ex)