Browse Source

修改房间和大厅对peer的管理, peer增加连接断开的通知.

王刚 3 years ago
parent
commit
3aa9470953

+ 4 - 4
CSserver/BattleRoom/Program.cs

@@ -20,7 +20,7 @@ namespace BattleRoom
 
             InitServerPeer();
 
-            Task.Run(WatchConnecting);                                                // 开启监听线程 
+            Task.Run(WatchConnecting).Wait();                                                // 开启监听线程 
 
         }
 
@@ -29,9 +29,9 @@ namespace BattleRoom
         /// </summary>
         async static void InitServerPeer()
         {
-            var port = 6005;                                                           // 连接本机的大厅服务端口            
-            var endPoint = new IPEndPoint(IPAddress.Loopback, port);   
- 
+            var port = 6005;                                                                // 连接本机的大厅服务端口            
+            //var endPoint = new IPEndPoint(IPAddress.Loopback, port);
+            var endPoint = new IPEndPoint(IPAddress.Parse("192.168.10.17"), port);
             using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
             {
                 try

+ 8 - 4
CSserver/BattleRoom/server/Peer.cs

@@ -64,7 +64,7 @@ namespace BattleRoom
         /// socket连接
         /// </summary>
         public readonly Socket Sock;
-
+        public Action OnSocketDisconnected;
         public string UID => Properties.TryGetValue(PropertyName.Uid, out var uid)? uid.ToString():"";
             
         public int zoneid => Properties.TryGetValue(PropertyName.Zoneid, out var zoneid)?Convert.ToInt32(zoneid):1;
@@ -165,7 +165,7 @@ namespace BattleRoom
         {
 
             var _databuffer = new DataBuffer();
-            byte[] arrServerRecMsg = new byte[4096];                                       // 创建一个内存缓冲区,其大小为4k字节  
+            byte[] arrServerRecMsg = new byte[4096];                                                // 创建一个内存缓冲区,其大小为4k字节  
             while (true)
             {
                 try
@@ -173,6 +173,7 @@ namespace BattleRoom
                     var length = await socketServer.ReceiveAsync(new ArraySegment<byte>(arrServerRecMsg), SocketFlags.None);   // 将接收到的信息存入到内存缓冲区,并返回其字节数组的长度    
                     if (length <= 0 || CurrentState == ClientState.Leaved)                                                     // 视为客户端已经close连接
                     {
+                        OnSocketDisconnected?.Invoke();
                         break;
                     }
                     _databuffer.AddBuffer(arrServerRecMsg, length);                                  //将收到的数据添加到缓存器中
@@ -191,6 +192,9 @@ namespace BattleRoom
                                 {
                                     await room.MsgChannel.Writer.WriteAsync(new KeyValuePair<int, sSocketData>(this.Id, _socketData));           // 放入房间channel
                                 }
+                                else {
+                                    Console.WriteLine("错误! 尚未进入对应房间!");
+                                }
                                 break;
                             case ClientState.Leaved:
                                 break;
@@ -201,9 +205,9 @@ namespace BattleRoom
                 }
                 catch (SocketException e)
                 {
-                    if (e.ErrorCode == 10060)                                          // 超时的时候错误号码是10060
+                    if (e.ErrorCode == 10060)                                                    // 超时的时候错误号码是10060
                     {
-                        continue;                                                      // 继续等待  
+                        continue;                                                                // 继续等待  
                     }
                     break;
                 }

+ 48 - 16
CSserver/BattleRoom/server/Room.cs

@@ -76,14 +76,16 @@ namespace BattleRoom
         /// </summary>
         public Channel<KeyValuePair<int, sSocketData>> MsgChannel = Channel.CreateBounded<KeyValuePair<int, sSocketData>>(1000);
 
-        // 房间计数器
-        private static int _roomIdCounter = 0;
+
         /// <summary>
         /// 房间编号
         /// </summary>
         public int Id { get; }
 
-        public int mapId { get; }
+        /// <summary>
+        /// 玩家id集合
+        /// </summary>
+        public List<string> PlayerUids = new List<string>();
 
         /// <summary>
         /// 战斗服务器端口
@@ -97,30 +99,58 @@ namespace BattleRoom
         /// <summary>
         /// 构造函数
         /// </summary> 
-        public Room(int mapid)
+        public Room(int RoomId, IEnumerable<string> uids)
         {
-            mapId= mapid;
-            Id = _roomIdCounter++; 
+            Id = RoomId;
+            PlayerUids = uids.ToList();
 
-            callbacks.Add(eProtocalCommand.CsMdBeginDup, On_Start);
 
             callbacks.Add(eProtocalCommand.CsLeaveRoom, On_Leave);
-
+            callbacks.Add(eProtocalCommand.CsBtStatus, On_BtStatus);
+            callbacks.Add(eProtocalCommand.CsBtPosition, On_BtPosition);
+            callbacks.Add(eProtocalCommand.CsBtBroadCast, On_BtBroadCast);
             var t = Task.Run(MsgLoop);
             Open();
         }
 
-        /// <summary>
-        /// 开始游戏 
-        /// </summary>
-        /// <param name="data"></param>
-        void On_Start(int peerId, sSocketData data)
+        void On_BtStatus(int peerId, sSocketData data)
         {
-            if (this.ClientPeers.TryGetValue(peerId, out var peer))
+            var msg = CS_BT_Status.Parser.ParseFrom(data._data);
+            if (ClientPeers.TryGetValue(peerId, out var peer))
+            {
+                var info = new SC_BT_Status() { PropertyName = msg.PropertyName, Value = msg.Value, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
+                this.Broadcast(TargetType.Others, eProtocalCommand.CsBtStatus, info);
+            }
+        }
+        void On_BtPosition(int peerId, sSocketData data)
+        {
+            var msg = CS_BT_Position.Parser.ParseFrom(data._data);
+            if (ClientPeers.TryGetValue(peerId, out var peer))
             {
-                Broadcast(TargetType.All, eProtocalCommand.ScMdBeginDup, new SC_MD_BeginDup() { }); 
+                var info = new SC_BT_Position() { X = msg.X, Y = msg.Y, Z = msg.Z, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
+                this.Broadcast(TargetType.Others, eProtocalCommand.CsBtStatus, info);
             }
         }
+        void On_BtBroadCast(int peerId, sSocketData data)
+        {
+            var msg = CS_BT_BroadCast.Parser.ParseFrom(data._data);
+            if (ClientPeers.TryGetValue(peerId, out var peer))
+            {
+                var info = new SC_BT_BroadCast() {Msg= msg.Msg, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
+                this.Broadcast(TargetType.Others, eProtocalCommand.CsBtStatus, info);
+            }
+        }
+
+        void On_BtOver(int peerId, sSocketData data)
+        {
+            var msg = CS_BT_Over.Parser.ParseFrom(data._data);
+            if (ClientPeers.TryGetValue(peerId, out var peer))
+            {
+                var info = new SC_BT_Over() { Msg= msg.Msg, SenderUid = msg.SenderUid, Zoneid = msg.Zoneid };
+                this.Broadcast(TargetType.Others, eProtocalCommand.CsBtStatus, info);
+            }
+        }
+
 
 
         /// <summary>
@@ -138,6 +168,8 @@ namespace BattleRoom
         }
 
 
+
+
         #region 网络
         async void MsgLoop()
         {
@@ -201,7 +233,7 @@ namespace BattleRoom
                     this.ClientPeers.Add(p.Id, p);
                 }
                 var list = new SC_MD_EnterRoom() { Uid = p.UID, Zoneid = p.zoneid };
-                
+
                 ClientPeers.Values.ToList().ForEach(c => list.PlayerUids.Add(c.UID));
                 Broadcast(TargetType.All, eProtocalCommand.ScMdEnterRoom, list);
             }

+ 23 - 57
CSserver/BattleRoom/server/RoomManager.cs

@@ -47,11 +47,9 @@ namespace BattleRoom
 
         public RoomManager()
         {
-            this.callbacks.Add(eProtocalCommand.CsMdEnterLobby, On_EnterLobby);
+            this.callbacks.Add(eProtocalCommand.CsBtLogin, On_BtLogin);
             this.callbacks.Add(eProtocalCommand.CsLeaveRoom, On_Leave);
-            callbacks.Add(eProtocalCommand.CsMdGetRoomList, On_GetRoomList);
-            callbacks.Add(eProtocalCommand.CsMdCreateRoom, On_CreateRoom);
-            callbacks.Add(eProtocalCommand.CsMdEnterRoom, On_EnterRoom);
+             
             var t = Task.Run(MsgLoop);
 
         }
@@ -61,6 +59,7 @@ namespace BattleRoom
             lock (lock_peers)
             {
                 this.ClientPeers.Add(p.Id, p);
+                Console.WriteLine(p.UID + " 连接上来了!");
             }
 
         }
@@ -84,78 +83,45 @@ namespace BattleRoom
         /// 进入大厅(登陆自己的uid)
         /// </summary>
         /// <param name="data"></param>
-        void On_EnterLobby(int peerId, sSocketData data)
+        void On_BtLogin(int peerId, sSocketData data)
         {
-            var msg = CS_MD_EnterLobby.Parser.ParseFrom(data._data);
+            var msg = CS_BT_Login.Parser.ParseFrom(data._data);
 
             if (this.ClientPeers.TryGetValue(peerId, out var peer))
             {
-                peer.SendEvent(eProtocalCommand.ScMdEnterLobby, new SC_MD_EnterLobby() { });
-                peer.CurrentState = ClientState.InLobby;
+                roomDic.Values.ToList().ForEach(r => {
+                    if (r.PlayerUids.Contains(msg.Uid))
+                    {
+                        peer.room = r;               // 设置自己的room
+                        r.AddPeer(peer);
+                    }
+                });
+
                 peer.Properties.Add(PropertyName.Uid, msg.Uid);
                 peer.Properties.Add(PropertyName.Zoneid, msg.Zoneid);
+                peer.CurrentState = ClientState.InGame;
+                peer.SendEvent(eProtocalCommand.ScBtLogin, new SC_BT_Login() { });
             }
         }
 
-        /// <summary>
-        /// 查询房间列表
-        /// </summary>
-        /// <param name="data"></param>
-        void On_GetRoomList(int peerId, sSocketData data)
-        {
 
-            var msg = new SC_MD_GetRoomList() { };
-            if (this.ClientPeers.TryGetValue(peerId, out var peer))
-            {
-                this.roomDic.Values.ToList().ForEach(r =>
-                {
-                    var info = new SC_MD_GetRoomList.Types.RoomInfo() { Battleserver =r.BattleServerIp, BattleServerPort=r.BattleServerPort, Mapid = r.mapId, RoomId = r.Id };
-                    r.ClientPeers.Values.ToList().ForEach(peer =>
-                    {
-                        info.PlayerUids.Add(peer.UID);
-                    });
-                    msg.RoomInfos.Add(info);
-                });
-
-                peer.SendEvent(eProtocalCommand.ScMdGetRoomList, msg);
-            }
-        }
 
         /// <summary>
         /// 创建一个房间(副本)
         /// </summary>
         /// <param name="data"></param>
-        void On_CreateRoom(int peerId, sSocketData data)
+        public void CreateRoom(sSocketData data)
         {
-            var msg = CS_MD_CreateRoom.Parser.ParseFrom(data._data);
-            if (this.ClientPeers.TryGetValue(peerId, out var peer))
-            {
-                peer.SendEvent(eProtocalCommand.ScMdCreateRoom, new SC_MD_CreateRoom() { });
-                var room = new Room(msg.Mapid);
-                room.AddPeer(peer);                                                    // 转移进房间
-                roomDic.Add(room.Id, room);
+            var msg = SS_CreateBattleServer.Parser.ParseFrom(data._data);
+             
+            var room = new Room(msg.RoomId, msg.PlayerUids);
+            roomDic.Add(room.Id, room);
 
-                //RemovePeer(peerId);                                                  // 从大厅移除
-            }
-        }
+            ServerPeer.SendEvent(eProtocalCommand.SsCreateBattleRoomOk, new SS_CreateBattleServerOK() { });
+            // todo: 建立玩家列表, 当玩家登录进来以后, 将其连接转入房间
 
-        /// <summary>
-        /// 进入房间
-        /// </summary>
-        /// <param name="data"></param>
-        void On_EnterRoom(int peerId, sSocketData data)
-        {
-            var msg = CS_MD_EnterRoom.Parser.ParseFrom(data._data);
-            if (this.ClientPeers.TryGetValue(peerId, out var peer))
-            {
-                if (roomDic.TryGetValue(msg.RoomId, out var room))
-                {
-                    room.AddPeer(peer);
-                }
-
-            }
         }
-
+         
         /// <summary>
         /// 离开房间(战斗结束)
         /// </summary>

+ 7 - 10
CSserver/BattleRoom/server/ServerPeer.cs

@@ -41,24 +41,21 @@ namespace BattleRoom
 
         #region 逻辑处理
 
-        public void On_CreateBattleRoom(sSocketData _sData) {
-
+        public void On_CreateBattleRoom(sSocketData _sData)
+        {
             var msg = SS_CreateBattleServer.Parser.ParseFrom(_sData._data);
-            // 开辟一个处理对象, room, 然后后续逻辑由room对象等待连接过来. 
-
-
-            // 返回成功
-            this.SendEvent(eProtocalCommand.SsCreateBattleRoomOk, new SS_CreateBattleServerOK() { });
-
+            RoomManager.Instance.CreateRoom(_sData);                           // 开辟一个处理对象, room, 然后后续逻辑由room对象等待连接过来. 
+            this.SendEvent(eProtocalCommand.SsCreateBattleRoomOk, new SS_CreateBattleServerOK() { });// 返回成功
         }
 
 
         #endregion
 
-
+        /// <summary>
+        /// 关闭连接
+        /// </summary>
         public void Close()
         {
-
             this.sendDataBuffer.Reader.Completion
                 .ContinueWith(t =>
                 Task.Delay(5000).ContinueWith(t1 => Sock.Close())

+ 6 - 5
CSserver/MultiDup/Program.cs

@@ -11,7 +11,7 @@ namespace MultiDup
     {
         const int serverport = 6005;                                            // 用于监听服务端连接的端口号
 
-        static ServerPeer serverPeer = null;                                             // 战斗server的连接
+        public static ServerPeer serverPeer = null;                             // 战斗server的连接
 
         const int port = 6004;                                                  // 端口号(用来监听的) 
         static void Main(string[] args)
@@ -48,7 +48,7 @@ namespace MultiDup
             SocketWatch.Bind(ipe);                                             // 监听绑定的网络节点           
             SocketWatch.Listen(20);                                            // 将套接字的监听队列长度限制为20    
 
-            while (true)                                                                 // 持续不断监听客户端发来的请求     
+            while (true)                                                       // 持续不断监听客户端发来的请求     
             {
                 Socket connection;
                 try
@@ -57,14 +57,15 @@ namespace MultiDup
                 }
                 catch (Exception ex)
                 {
-                    Console.WriteLine(ex.Message);                                       // 提示套接字监听异常     
+                    Console.WriteLine(ex.Message);                             // 提示套接字监听异常     
                     break;
                 }
 
-                Lobby.Instance.OnNewPeerConnected(new Peer(connection));                 // 有新客户端连入
+                Lobby.Instance.OnNewPeerConnected(new Peer(connection));       // 有新客户端连入
             }
             SocketWatch.Close();                                               // 结束监听socket
         }
+
         /// <summary>
         /// 监听服务端发来的请求  
         /// </summary>
@@ -90,7 +91,7 @@ namespace MultiDup
                     Console.WriteLine(ex.Message);                                       // 提示套接字监听异常     
                     break;
                 }
-
+                Console.WriteLine("server peer 连接上来了.");
                 serverPeer = new ServerPeer(connection);                                 // 建立与服务端的连接
             }
             SocketWatch.Close();                                                         // 结束监听socket

+ 6 - 1
CSserver/MultiDup/server/Lobby.cs

@@ -67,6 +67,11 @@ namespace MultiDup
             }
         }
 
+
+        public void RemoveRoom(int roomid) { 
+            roomDic.Remove(roomid);
+        }
+
         public void OnNewPeerConnected(Peer peer)
         {
             AddPeer(peer);
@@ -125,7 +130,7 @@ namespace MultiDup
                 var room = new Room(msg.Mapid);
                 room.AddPeer(peer);                   // 转移进房间
                 roomDic.Add(room.Id, room);
-
+                 
                 //RemovePeer(peerId);                                                  // 从大厅移除
             }
         }

+ 6 - 2
CSserver/MultiDup/server/Peer.cs

@@ -70,6 +70,9 @@ namespace MultiDup
 
         public Room room;
 
+
+        public Action OnSocketDisconnected;
+
         /// <summary>
         /// 线程安全的peer计数器
         /// </summary>
@@ -86,14 +89,14 @@ namespace MultiDup
             Id = _UniqPeerId++;
             var t = Task.Run(() => recv(Sock));                                 // 新建接收线程 
             var tcs = Task.Run(WriteToClient);                                  // 向客户端发送消息线程
-
+             
         }
 
 
         public void Close()
         {
             this.CurrentState = ClientState.Leaved;                              // 关闭接收窗口
-            //room.RemovePeer(this);                                      // 从房间中移除自己
+            //room.RemovePeer(this);                                             // 从房间中移除自己
             
             this.sendDataBuffer.Reader.Completion
                 .ContinueWith(t =>
@@ -171,6 +174,7 @@ namespace MultiDup
                     var length = await socketServer.ReceiveAsync(new ArraySegment<byte>(arrServerRecMsg), SocketFlags.None);   // 将接收到的信息存入到内存缓冲区,并返回其字节数组的长度    
                     if (length <= 0 || CurrentState == ClientState.Leaved)                                                     // 视为客户端已经close连接
                     {
+                        OnSocketDisconnected?.Invoke();
                         break;
                     }
                     _databuffer.AddBuffer(arrServerRecMsg, length);                                  //将收到的数据添加到缓存器中

+ 29 - 4
CSserver/MultiDup/server/Room.cs

@@ -99,8 +99,8 @@ namespace MultiDup
         /// </summary> 
         public Room(int mapid)
         {
-            mapId= mapid;
-            Id = _roomIdCounter++; 
+            mapId = mapid;
+            Id = _roomIdCounter++;
 
             callbacks.Add(eProtocalCommand.CsMdBeginDup, On_Start);
 
@@ -118,7 +118,20 @@ namespace MultiDup
         {
             if (this.ClientPeers.TryGetValue(peerId, out var peer))
             {
-                Broadcast(TargetType.All, eProtocalCommand.ScMdBeginDup, new SC_MD_BeginDup() { }); 
+                if (null != Program.serverPeer)                                                     // battleServer创建对应的房间
+                {
+                    var sendmsg = new SS_CreateBattleServer() { RoomId = this.Id };
+                    this.ClientPeers.Values.ToList().ForEach(p =>
+                    {
+                        sendmsg.PlayerUids.Add(p.UID);
+                    });
+                    Program.serverPeer.SendEvent(eProtocalCommand.SsCreateBattleRoom, sendmsg);     // 向battle服务器发送创建房间的指令
+                }
+                else
+                {
+                    Console.WriteLine(" 没有可用的battle服务器! ");
+                }
+                Broadcast(TargetType.All, eProtocalCommand.ScMdBeginDup, new SC_MD_BeginDup() { Battleserver = this.BattleServerIp, BattleServerPort = this.BattleServerPort });
             }
         }
 
@@ -186,6 +199,8 @@ namespace MultiDup
         {
             this.CurrentState = RoomState.Close;
             Task.Delay(TimeSpan.FromMinutes(1)).ContinueWith(t => Open());
+            Lobby.Instance.RemoveRoom(this.Id);
+
         }
 
 
@@ -201,9 +216,15 @@ namespace MultiDup
                     this.ClientPeers.Add(p.Id, p);
                 }
                 var list = new SC_MD_EnterRoom() { Uid = p.UID, Zoneid = p.zoneid };
-                
+
                 ClientPeers.Values.ToList().ForEach(c => list.PlayerUids.Add(c.UID));
                 Broadcast(TargetType.All, eProtocalCommand.ScMdEnterRoom, list);
+                p.OnSocketDisconnected = () =>
+                {
+                    Lobby.Instance.RemovePeer(p.Id);
+                    RemovePeer(p);
+                };
+                 
             }
             else
             {
@@ -222,6 +243,10 @@ namespace MultiDup
                 {
                     this.ClientPeers.Remove(p.Id);
                 }
+                if (ClientPeers.Count == 0)
+                {
+                    this.Close();
+                }
             }
         }
         public void RemovePeer(int peerId)

+ 15 - 4
CSserver/PBReferens/pb/MultiDup.proto

@@ -59,13 +59,18 @@ package MultiDup;
 	 float  Y =4;
 	 float  Z =5;
  }
-
+ // 战斗服务, 广播
  message CS_BT_BroadCast{
   	 int32 Zoneid=1;
 	 string SenderUid =2;
 	 string Msg=3;
  }
 
+ message CS_BT_Over{
+  	 int32 Zoneid=1;
+	 string SenderUid =2;
+	 string Msg=3;
+ }
 
  // 
  // 加入房间成功
@@ -110,7 +115,8 @@ package MultiDup;
  }
   // 多人副本, 开始游戏(创建者)
  message SC_MD_BeginDup {
-      
+    string Battleserver =1;
+	int32  BattleServerPort =2;
  }
 
  // 战斗服务 登录
@@ -138,14 +144,19 @@ package MultiDup;
 	 float  Y =4;
 	 float  Z =5;
  }
- // 战斗服务 
+ // 战斗服务 广播
  message SC_BT_BroadCast{
   	 int32 Zoneid=1;
 	   // 发送者uid
 	 string SenderUid =2;
 	 string Msg=3;
  }
-
+ // 战斗服务,结束
+  message SC_BT_Over{
+  	 int32 Zoneid=1;
+	 string SenderUid =2;
+	 string Msg=3;
+ }
 
 
  // 多人副本在战斗服创建房间

+ 448 - 34
CSserver/PBReferens/pbcs/MultiDup.cs

@@ -36,26 +36,30 @@ namespace MultiDup {
             "CSJUCg5DU19CVF9Qb3NpdGlvbhIOCgZab25laWQYASABKAUSEQoJU2VuZGVy",
             "VWlkGAIgASgJEgkKAVgYAyABKAISCQoBWRgEIAEoAhIJCgFaGAUgASgCIkEK",
             "D0NTX0JUX0Jyb2FkQ2FzdBIOCgZab25laWQYASABKAUSEQoJU2VuZGVyVWlk",
-            "GAIgASgJEgsKA01zZxgDIAEoCSISChBTQ19NRF9FbnRlckxvYmJ5Ik4KEFND",
-            "X01EX0NyZWF0ZVJvb20SDgoGWm9uZWlkGAEgASgFEgsKA1VpZBgCIAEoCRIN",
-            "CgVNYXBpZBgDIAEoBRIOCgZSb29tSWQYBCABKAUiuwEKEVNDX01EX0dldFJv",
-            "b21MaXN0EjcKCVJvb21JbmZvcxgBIAMoCzIkLk11bHRpRHVwLlNDX01EX0dl",
-            "dFJvb21MaXN0LlJvb21JbmZvGm0KCFJvb21JbmZvEg4KBlJvb21JZBgBIAEo",
-            "BRINCgVNYXBpZBgCIAEoBRISCgpQbGF5ZXJVaWRzGAMgAygJEhQKDEJhdHRs",
-            "ZXNlcnZlchgEIAEoCRIYChBCYXR0bGVTZXJ2ZXJQb3J0GAUgASgFImsKD1ND",
-            "X01EX0VudGVyUm9vbRIOCgZab25laWQYASABKAUSCwoDVWlkGAIgASgJEg0K",
-            "BU1hcGlkGAMgASgFEgoKAklwGAQgASgJEgwKBFBvcnQYBSABKAUSEgoKUGxh",
-            "eWVyVWlkcxgGIAMoCSIuCg9TQ19NRF9MZWF2ZVJvb20SDgoGWm9uZWlkGAEg",
-            "ASgFEgsKA1VpZBgCIAEoCSIQCg5TQ19NRF9CZWdpbkR1cCI3CgtTQ19CVF9M",
-            "b2dpbhIOCgZab25laWQYASABKAUSCwoDVWlkGAIgASgJEgsKA01zZxgDIAEo",
-            "CSJWCgxTQ19CVF9TdGF0dXMSDgoGWm9uZWlkGAEgASgFEhEKCVNlbmRlclVp",
-            "ZBgCIAEoCRIUCgxQcm9wZXJ0eU5hbWUYAyABKAkSDQoFVmFsdWUYBCABKAki",
-            "VAoOU0NfQlRfUG9zaXRpb24SDgoGWm9uZWlkGAEgASgFEhEKCVNlbmRlclVp",
-            "ZBgCIAEoCRIJCgFYGAMgASgCEgkKAVkYBCABKAISCQoBWhgFIAEoAiJBCg9T",
-            "Q19CVF9Ccm9hZENhc3QSDgoGWm9uZWlkGAEgASgFEhEKCVNlbmRlclVpZBgC",
-            "IAEoCRILCgNNc2cYAyABKAkiOwoVU1NfQ3JlYXRlQmF0dGxlU2VydmVyEg4K",
-            "BlJvb21JZBgBIAEoBRISCgpQbGF5ZXJVaWRzGAIgAygJIhkKF1NTX0NyZWF0",
-            "ZUJhdHRsZVNlcnZlck9LYgZwcm90bzM="));
+            "GAIgASgJEgsKA01zZxgDIAEoCSI8CgpDU19CVF9PdmVyEg4KBlpvbmVpZBgB",
+            "IAEoBRIRCglTZW5kZXJVaWQYAiABKAkSCwoDTXNnGAMgASgJIhIKEFNDX01E",
+            "X0VudGVyTG9iYnkiTgoQU0NfTURfQ3JlYXRlUm9vbRIOCgZab25laWQYASAB",
+            "KAUSCwoDVWlkGAIgASgJEg0KBU1hcGlkGAMgASgFEg4KBlJvb21JZBgEIAEo",
+            "BSK7AQoRU0NfTURfR2V0Um9vbUxpc3QSNwoJUm9vbUluZm9zGAEgAygLMiQu",
+            "TXVsdGlEdXAuU0NfTURfR2V0Um9vbUxpc3QuUm9vbUluZm8abQoIUm9vbUlu",
+            "Zm8SDgoGUm9vbUlkGAEgASgFEg0KBU1hcGlkGAIgASgFEhIKClBsYXllclVp",
+            "ZHMYAyADKAkSFAoMQmF0dGxlc2VydmVyGAQgASgJEhgKEEJhdHRsZVNlcnZl",
+            "clBvcnQYBSABKAUiawoPU0NfTURfRW50ZXJSb29tEg4KBlpvbmVpZBgBIAEo",
+            "BRILCgNVaWQYAiABKAkSDQoFTWFwaWQYAyABKAUSCgoCSXAYBCABKAkSDAoE",
+            "UG9ydBgFIAEoBRISCgpQbGF5ZXJVaWRzGAYgAygJIi4KD1NDX01EX0xlYXZl",
+            "Um9vbRIOCgZab25laWQYASABKAUSCwoDVWlkGAIgASgJIkAKDlNDX01EX0Jl",
+            "Z2luRHVwEhQKDEJhdHRsZXNlcnZlchgBIAEoCRIYChBCYXR0bGVTZXJ2ZXJQ",
+            "b3J0GAIgASgFIjcKC1NDX0JUX0xvZ2luEg4KBlpvbmVpZBgBIAEoBRILCgNV",
+            "aWQYAiABKAkSCwoDTXNnGAMgASgJIlYKDFNDX0JUX1N0YXR1cxIOCgZab25l",
+            "aWQYASABKAUSEQoJU2VuZGVyVWlkGAIgASgJEhQKDFByb3BlcnR5TmFtZRgD",
+            "IAEoCRINCgVWYWx1ZRgEIAEoCSJUCg5TQ19CVF9Qb3NpdGlvbhIOCgZab25l",
+            "aWQYASABKAUSEQoJU2VuZGVyVWlkGAIgASgJEgkKAVgYAyABKAISCQoBWRgE",
+            "IAEoAhIJCgFaGAUgASgCIkEKD1NDX0JUX0Jyb2FkQ2FzdBIOCgZab25laWQY",
+            "ASABKAUSEQoJU2VuZGVyVWlkGAIgASgJEgsKA01zZxgDIAEoCSI8CgpTQ19C",
+            "VF9PdmVyEg4KBlpvbmVpZBgBIAEoBRIRCglTZW5kZXJVaWQYAiABKAkSCwoD",
+            "TXNnGAMgASgJIjsKFVNTX0NyZWF0ZUJhdHRsZVNlcnZlchIOCgZSb29tSWQY",
+            "ASABKAUSEgoKUGxheWVyVWlkcxgCIAMoCSIZChdTU19DcmVhdGVCYXR0bGVT",
+            "ZXJ2ZXJPS2IGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -69,16 +73,18 @@ namespace MultiDup {
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.CS_BT_Status), global::MultiDup.CS_BT_Status.Parser, new[]{ "Zoneid", "SenderUid", "PropertyName", "Value" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.CS_BT_Position), global::MultiDup.CS_BT_Position.Parser, new[]{ "Zoneid", "SenderUid", "X", "Y", "Z" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.CS_BT_BroadCast), global::MultiDup.CS_BT_BroadCast.Parser, new[]{ "Zoneid", "SenderUid", "Msg" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.CS_BT_Over), global::MultiDup.CS_BT_Over.Parser, new[]{ "Zoneid", "SenderUid", "Msg" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_EnterLobby), global::MultiDup.SC_MD_EnterLobby.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_CreateRoom), global::MultiDup.SC_MD_CreateRoom.Parser, new[]{ "Zoneid", "Uid", "Mapid", "RoomId" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_GetRoomList), global::MultiDup.SC_MD_GetRoomList.Parser, new[]{ "RoomInfos" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_GetRoomList.Types.RoomInfo), global::MultiDup.SC_MD_GetRoomList.Types.RoomInfo.Parser, new[]{ "RoomId", "Mapid", "PlayerUids", "Battleserver", "BattleServerPort" }, null, null, null)}),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_EnterRoom), global::MultiDup.SC_MD_EnterRoom.Parser, new[]{ "Zoneid", "Uid", "Mapid", "Ip", "Port", "PlayerUids" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_LeaveRoom), global::MultiDup.SC_MD_LeaveRoom.Parser, new[]{ "Zoneid", "Uid" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_BeginDup), global::MultiDup.SC_MD_BeginDup.Parser, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_MD_BeginDup), global::MultiDup.SC_MD_BeginDup.Parser, new[]{ "Battleserver", "BattleServerPort" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_BT_Login), global::MultiDup.SC_BT_Login.Parser, new[]{ "Zoneid", "Uid", "Msg" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_BT_Status), global::MultiDup.SC_BT_Status.Parser, new[]{ "Zoneid", "SenderUid", "PropertyName", "Value" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_BT_Position), global::MultiDup.SC_BT_Position.Parser, new[]{ "Zoneid", "SenderUid", "X", "Y", "Z" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_BT_BroadCast), global::MultiDup.SC_BT_BroadCast.Parser, new[]{ "Zoneid", "SenderUid", "Msg" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SC_BT_Over), global::MultiDup.SC_BT_Over.Parser, new[]{ "Zoneid", "SenderUid", "Msg" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SS_CreateBattleServer), global::MultiDup.SS_CreateBattleServer.Parser, new[]{ "RoomId", "PlayerUids" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::MultiDup.SS_CreateBattleServerOK), global::MultiDup.SS_CreateBattleServerOK.Parser, null, null, null, null)
           }));
@@ -1653,6 +1659,9 @@ namespace MultiDup {
 
   }
 
+  /// <summary>
+  /// 战斗服务, 广播
+  /// </summary>
   public sealed partial class CS_BT_BroadCast : pb::IMessage<CS_BT_BroadCast> {
     private static readonly pb::MessageParser<CS_BT_BroadCast> _parser = new pb::MessageParser<CS_BT_BroadCast>(() => new CS_BT_BroadCast());
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1826,6 +1835,179 @@ namespace MultiDup {
 
   }
 
+  public sealed partial class CS_BT_Over : pb::IMessage<CS_BT_Over> {
+    private static readonly pb::MessageParser<CS_BT_Over> _parser = new pb::MessageParser<CS_BT_Over>(() => new CS_BT_Over());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<CS_BT_Over> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[10]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public CS_BT_Over() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public CS_BT_Over(CS_BT_Over other) : this() {
+      zoneid_ = other.zoneid_;
+      senderUid_ = other.senderUid_;
+      msg_ = other.msg_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public CS_BT_Over Clone() {
+      return new CS_BT_Over(this);
+    }
+
+    /// <summary>Field number for the "Zoneid" field.</summary>
+    public const int ZoneidFieldNumber = 1;
+    private int zoneid_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Zoneid {
+      get { return zoneid_; }
+      set {
+        zoneid_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "SenderUid" field.</summary>
+    public const int SenderUidFieldNumber = 2;
+    private string senderUid_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string SenderUid {
+      get { return senderUid_; }
+      set {
+        senderUid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "Msg" field.</summary>
+    public const int MsgFieldNumber = 3;
+    private string msg_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Msg {
+      get { return msg_; }
+      set {
+        msg_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as CS_BT_Over);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(CS_BT_Over other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Zoneid != other.Zoneid) return false;
+      if (SenderUid != other.SenderUid) return false;
+      if (Msg != other.Msg) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Zoneid != 0) hash ^= Zoneid.GetHashCode();
+      if (SenderUid.Length != 0) hash ^= SenderUid.GetHashCode();
+      if (Msg.Length != 0) hash ^= Msg.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Zoneid != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(Zoneid);
+      }
+      if (SenderUid.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(SenderUid);
+      }
+      if (Msg.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(Msg);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Zoneid != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Zoneid);
+      }
+      if (SenderUid.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(SenderUid);
+      }
+      if (Msg.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Msg);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(CS_BT_Over other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Zoneid != 0) {
+        Zoneid = other.Zoneid;
+      }
+      if (other.SenderUid.Length != 0) {
+        SenderUid = other.SenderUid;
+      }
+      if (other.Msg.Length != 0) {
+        Msg = other.Msg;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Zoneid = input.ReadInt32();
+            break;
+          }
+          case 18: {
+            SenderUid = input.ReadString();
+            break;
+          }
+          case 26: {
+            Msg = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   /// <summary>
   /// 
   /// 加入房间成功
@@ -1837,7 +2019,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[10]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[11]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1929,7 +2111,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[11]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[12]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2136,7 +2318,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[12]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[13]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2479,7 +2661,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[13]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[14]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2740,7 +2922,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[14]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[15]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2891,7 +3073,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[15]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[16]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2908,6 +3090,8 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SC_MD_BeginDup(SC_MD_BeginDup other) : this() {
+      battleserver_ = other.battleserver_;
+      battleServerPort_ = other.battleServerPort_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2915,6 +3099,28 @@ namespace MultiDup {
       return new SC_MD_BeginDup(this);
     }
 
+    /// <summary>Field number for the "Battleserver" field.</summary>
+    public const int BattleserverFieldNumber = 1;
+    private string battleserver_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Battleserver {
+      get { return battleserver_; }
+      set {
+        battleserver_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "BattleServerPort" field.</summary>
+    public const int BattleServerPortFieldNumber = 2;
+    private int battleServerPort_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int BattleServerPort {
+      get { return battleServerPort_; }
+      set {
+        battleServerPort_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SC_MD_BeginDup);
@@ -2928,12 +3134,16 @@ namespace MultiDup {
       if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Battleserver != other.Battleserver) return false;
+      if (BattleServerPort != other.BattleServerPort) return false;
       return true;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
+      if (Battleserver.Length != 0) hash ^= Battleserver.GetHashCode();
+      if (BattleServerPort != 0) hash ^= BattleServerPort.GetHashCode();
       return hash;
     }
 
@@ -2944,11 +3154,25 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
+      if (Battleserver.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Battleserver);
+      }
+      if (BattleServerPort != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(BattleServerPort);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
+      if (Battleserver.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Battleserver);
+      }
+      if (BattleServerPort != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(BattleServerPort);
+      }
       return size;
     }
 
@@ -2957,6 +3181,12 @@ namespace MultiDup {
       if (other == null) {
         return;
       }
+      if (other.Battleserver.Length != 0) {
+        Battleserver = other.Battleserver;
+      }
+      if (other.BattleServerPort != 0) {
+        BattleServerPort = other.BattleServerPort;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -2967,6 +3197,14 @@ namespace MultiDup {
           default:
             input.SkipLastField();
             break;
+          case 10: {
+            Battleserver = input.ReadString();
+            break;
+          }
+          case 16: {
+            BattleServerPort = input.ReadInt32();
+            break;
+          }
         }
       }
     }
@@ -2980,7 +3218,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[16]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[17]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3156,7 +3394,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[17]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[18]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3366,7 +3604,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[18]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[19]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3592,7 +3830,7 @@ namespace MultiDup {
   }
 
   /// <summary>
-  /// 战斗服务 
+  /// 战斗服务 广播
   /// </summary>
   public sealed partial class SC_BT_BroadCast : pb::IMessage<SC_BT_BroadCast> {
     private static readonly pb::MessageParser<SC_BT_BroadCast> _parser = new pb::MessageParser<SC_BT_BroadCast>(() => new SC_BT_BroadCast());
@@ -3601,7 +3839,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[19]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[20]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3770,6 +4008,182 @@ namespace MultiDup {
 
   }
 
+  /// <summary>
+  /// 战斗服务,结束
+  /// </summary>
+  public sealed partial class SC_BT_Over : pb::IMessage<SC_BT_Over> {
+    private static readonly pb::MessageParser<SC_BT_Over> _parser = new pb::MessageParser<SC_BT_Over>(() => new SC_BT_Over());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<SC_BT_Over> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[21]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public SC_BT_Over() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public SC_BT_Over(SC_BT_Over other) : this() {
+      zoneid_ = other.zoneid_;
+      senderUid_ = other.senderUid_;
+      msg_ = other.msg_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public SC_BT_Over Clone() {
+      return new SC_BT_Over(this);
+    }
+
+    /// <summary>Field number for the "Zoneid" field.</summary>
+    public const int ZoneidFieldNumber = 1;
+    private int zoneid_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Zoneid {
+      get { return zoneid_; }
+      set {
+        zoneid_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "SenderUid" field.</summary>
+    public const int SenderUidFieldNumber = 2;
+    private string senderUid_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string SenderUid {
+      get { return senderUid_; }
+      set {
+        senderUid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "Msg" field.</summary>
+    public const int MsgFieldNumber = 3;
+    private string msg_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Msg {
+      get { return msg_; }
+      set {
+        msg_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as SC_BT_Over);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(SC_BT_Over other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Zoneid != other.Zoneid) return false;
+      if (SenderUid != other.SenderUid) return false;
+      if (Msg != other.Msg) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Zoneid != 0) hash ^= Zoneid.GetHashCode();
+      if (SenderUid.Length != 0) hash ^= SenderUid.GetHashCode();
+      if (Msg.Length != 0) hash ^= Msg.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Zoneid != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(Zoneid);
+      }
+      if (SenderUid.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(SenderUid);
+      }
+      if (Msg.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(Msg);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Zoneid != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Zoneid);
+      }
+      if (SenderUid.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(SenderUid);
+      }
+      if (Msg.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Msg);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(SC_BT_Over other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Zoneid != 0) {
+        Zoneid = other.Zoneid;
+      }
+      if (other.SenderUid.Length != 0) {
+        SenderUid = other.SenderUid;
+      }
+      if (other.Msg.Length != 0) {
+        Msg = other.Msg;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Zoneid = input.ReadInt32();
+            break;
+          }
+          case 18: {
+            SenderUid = input.ReadString();
+            break;
+          }
+          case 26: {
+            Msg = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   /// <summary>
   /// 多人副本在战斗服创建房间
   /// </summary>
@@ -3780,7 +4194,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[20]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[22]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3920,7 +4334,7 @@ namespace MultiDup {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[21]; }
+      get { return global::MultiDup.MultiDupReflection.Descriptor.MessageTypes[23]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]

+ 78 - 8
CSserver/clientTest/Program_MultiDup.cs

@@ -28,7 +28,7 @@ namespace clientTest.multiDup
         /// 消息分发
         /// </summary>
         static private Dictionary<eProtocalCommand, Action<sSocketData>> callbacks = new Dictionary<eProtocalCommand, Action<sSocketData>>();
-        static  void Main(string[] args)
+        static void Main(string[] args)
         {
 
             callbacks.Add(eProtocalCommand.ScMdGetRoomList, On_update);
@@ -42,7 +42,7 @@ namespace clientTest.multiDup
             {
                 list[i] = Task.Run(async () => await send());
             }
-              Task.Run(Dispatch);
+            Task.Run(Dispatch);
 
             Task.WaitAll(list);
         }
@@ -68,7 +68,48 @@ namespace clientTest.multiDup
         /// </summary>
         static void On_begin(sSocketData data)
         {
+            var msg = SC_MD_BeginDup.Parser.ParseFrom(data._data);
+
             Console.WriteLine("xxx开始了游戏.");
+            Console.WriteLine($"正在连接{msg.Battleserver}:{msg.BattleServerPort}");
+
+            var endPoint = new IPEndPoint(IPAddress.Parse(msg.Battleserver), msg.BattleServerPort);
+            //var endPoint = new IPEndPoint(IPAddress.Loopback, port);
+            //var endPoint = new IPEndPoint(IPAddress.Parse("115.159.121.129"), port);
+
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                try
+                {
+                    client.ConnectAsync(endPoint).Wait();
+                }
+                catch (Exception ee)
+                {
+                    Debug.WriteLine(ee.Message);
+                }
+
+
+                var t = Task.Run(() => recv(client));                    // 开启recv监听协程
+                try
+                {
+                    BtLogIn(client).Wait();
+                    // 连上来之后, 创建房间, 开始游戏, 退出房间
+                    BtBroadCast(client).Wait();
+                    BtBroadCast(client).Wait();
+                    BtBroadCast(client).Wait();
+                    Console.WriteLine("已经广播3次,exiting.");
+                }
+                catch (Exception e)
+                {
+                    client.Close();
+                }
+                finally
+                {
+                    client.Close();
+                }
+
+            }
+
         }
         /// <summary>
         /// 客户端进入房间
@@ -88,6 +129,35 @@ namespace clientTest.multiDup
 
         #endregion
 
+
+        async static Task BtLogIn(Socket sock)
+        {
+            try
+            {
+                var msg = new CS_BT_Login() { Msg = $"来自客户端{Environment.UserDomainName}的登录,{DateTime.Now.ToString()}", Uid = Environment.MachineName, Zoneid = 1 };
+                var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsBtLogin, IMsg2Bytes(msg)));
+                await sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
+            }
+            catch (Exception e)
+            {
+                sock.Close();
+            }
+        }
+
+        async static Task BtBroadCast(Socket sock)
+        {
+            try
+            {
+                var msg = new CS_BT_BroadCast() { Msg = $"来自客户端{Environment.UserDomainName}的广播,{DateTime.Now.ToString()}", SenderUid = Environment.MachineName, Zoneid = 1 };
+                var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsBtBroadCast, IMsg2Bytes(msg)));
+                await sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
+            }
+            catch (Exception e)
+            {
+                sock.Close();
+            }
+        }
+
         static async Task send()
         {
 
@@ -113,7 +183,7 @@ namespace clientTest.multiDup
                 try
                 {
                     // 连上来之后, 创建房间, 开始游戏, 退出房间
-                     CreateRoom(client).Wait();
+                    CreateRoom(client).Wait();
                     Thread.Sleep(r.Next(1000, 3000));
                     await BeginGame(client);
                     Thread.Sleep(r.Next(1000, 3000));
@@ -141,7 +211,7 @@ namespace clientTest.multiDup
         {
             try
             {
-                var msg = new CS_MD_CreateRoom() { };
+                var msg = new CS_MD_CreateRoom() { Uid = Environment.MachineName, Zoneid = 1 };
                 var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsMdCreateRoom, IMsg2Bytes(msg)));
                 await Sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
             }
@@ -157,7 +227,7 @@ namespace clientTest.multiDup
         /// <returns></returns>
         async static Task BeginGame(Socket sock)
         {
-            var msg = new CS_MD_BeginDup() { };
+            var msg = new CS_MD_BeginDup() { Uid = Environment.MachineName, Zoneid = 1 };
 
             var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsMdBeginDup, IMsg2Bytes(msg)));
             await sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
@@ -170,7 +240,7 @@ namespace clientTest.multiDup
         /// <returns></returns>
         async static Task LeaveGame(Socket sock)
         {
-            var msg = new CS_MD_LeaveRoom() { };
+            var msg = new CS_MD_LeaveRoom() { Uid = Environment.MachineName, Zoneid = 1 };
 
             var data = SocketDataToBytes(BytesToSocketData(eProtocalCommand.CsMdLeaveRoom, IMsg2Bytes(msg)));
             await sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);
@@ -287,7 +357,7 @@ namespace clientTest.multiDup
                     _databuffer.AddBuffer(arrServerRecMsg, length);                        //将收到的数据添加到缓存器中
                     while (_databuffer.GetData(out sSocketData _socketData))                         //取出一条完整数据
                     {
-                        Console.WriteLine("recv: " + _socketData._protocallType);
+                        Console.WriteLine(socketServer.GetHashCode().ToString() + " recv: " + _socketData._protocallType);
                         await recvDataBuffer.Writer.WriteAsync(_socketData);                 // 放入channel
                     }
                     Array.Clear(arrServerRecMsg, 0, length);
@@ -305,7 +375,7 @@ namespace clientTest.multiDup
                     break;
                 }
             }
-            Console.WriteLine("recv 已退出");
+            Console.WriteLine(socketServer.GetHashCode().ToString() + "recv 已退出");
             socketServer.Close();                                                     // 关闭之前accept出来的和客户端进行通信的套接字 
         }