using System; using System.Net; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MultiDup; internal class MultiDupServer : MonoSingleton { public enum State { /// /// 未连接,需要初始化(后自动连接) /// UnConnected = 0, /// /// 已连接, 需要登录 /// Connected = 1, /// /// 已完成登录 /// InLobby = 1, /// /// 已登录, 可以上报伤害以及自己的剩余血量 /// InBattleRoom = 2, /// /// 离开房间, 不可以继续上报伤害和剩余血量 /// Leaved = 3 } TasPBSocketManager lobbySocket, battleSocket; // 大厅/战斗 socket /// /// 当前状态 /// public State CurrentState { get; private set; } /// /// 先初始化 /// public void Init() { var ip = "192.168.10.17"; if (GlobalConfig.netType == eNetType.Online || GlobalConfig.netType == eNetType.TestOnline) { var uri = "ylsjtt.game7000.com"; IPHostEntry entry = Dns.GetHostEntry(uri); if (entry != null && entry.AddressList != null && entry.AddressList.Length > 0) { IPAddress addr = entry.AddressList[0]; //使用时使用AddressList[0]即可 ip = addr.ToString(); } } var port = 6004; // 多人副本端口 lobbySocket = new TasPBSocketManager(); lobbySocket.Connect(ip, port); // 挂载 服务端消息回调处理函数 MessageCenter.Instance.addObsever(eProtocalCommand.ScMdEnterLobby, On_EnterLobby); // 进入大厅返回此消息 MessageCenter.Instance.addObsever(eProtocalCommand.ScMdGetRoomList, On_UpdateRoomList); MessageCenter.Instance.addObsever(eProtocalCommand.ScMdCreateRoom, On_CreateRoom); // 创建房间成功 MessageCenter.Instance.addObsever(eProtocalCommand.ScMdEnterRoom, On_EnterRoom); MessageCenter.Instance.addObsever(eProtocalCommand.ScMdBeginDup, On_Start); MessageCenter.Instance.addObsever(eProtocalCommand.ScMdLeaveRoom, On_LeaveGame); lobbySocket.OnConnected = () => EnterLobby(); } #region 向服务端发送消息 public void EnterLobby() { if (CurrentState == State.UnConnected) { var p = UserProxy.Instance.player; var msg = new CS_MD_EnterLobby() { Uid = p.uid, Zoneid = p.zoneid }; lobbySocket.SendMsg(eProtocalCommand.CsMdEnterLobby, msg); LogHelper.Log("多人副本,发送登录大厅请求"); } } /// /// 拉取房间列表 /// public void GetRoomList(int mapId = 1) { UnityEngine.Debug.Assert(CurrentState == State.InLobby, $"当前状态不可以执行拉取房间列表操作,({CurrentState})"); if (CurrentState == State.InLobby) { var p = UserProxy.Instance.player; var msg = new CS_MD_GetRoomList() { Uid = p.uid, Zoneid = p.zoneid }; lobbySocket.SendMsg(eProtocalCommand.CsMdGetRoomList, msg); UnityEngine.Debug.Log("多人副本,发送拉取房间列表请求"); } } /// /// 创建房间 /// /// 使用的地图编号 public void CreateRoom(int mapId = 1) { UnityEngine.Debug.Assert(CurrentState == State.InLobby, $"当前状态不可以执行创建房间操作,({CurrentState})"); if (CurrentState == State.InLobby) { var p = UserProxy.Instance.player; var msg = new CS_MD_CreateRoom() { Uid = p.uid, Mapid = mapId, Zoneid = p.zoneid }; lobbySocket.SendMsg(eProtocalCommand.CsMdCreateRoom, msg); UnityEngine.Debug.Log("多人副本,发送创建房间请求"); } } /// /// 进入房间 /// /// 房间编号 public void EnterRoom(int roomId = 1) { UnityEngine.Debug.Assert(CurrentState == State.InLobby, $"当前状态不可以执行加入房间操作,({CurrentState})"); if (CurrentState == State.InLobby) { var p = UserProxy.Instance.player; var msg = new CS_MD_EnterRoom() { Uid = p.uid, RoomId = roomId, Zoneid = p.zoneid }; lobbySocket.SendMsg(eProtocalCommand.CsMdEnterRoom, msg); UnityEngine.Debug.Log("多人副本,发送创建房间请求"); } } /// /// 开始游戏 /// public void StartGame() { UnityEngine.Debug.Assert(CurrentState == State.InBattleRoom, $"当前状态不可以执行上报操作,({CurrentState})"); if (CurrentState == State.InBattleRoom) { var p = UserProxy.Instance.player; var msg = new CS_MD_BeginDup() { Uid = p.uid, Zoneid = p.zoneid }; lobbySocket.SendMsg(eProtocalCommand.CsMdBeginDup, msg); // 这里应该切换使用战场socket发送消息 } } /// /// 上报退出房间 /// public void LeaveGame() { var p = UserProxy.Instance.player; var msg = new CS_MD_LeaveRoom() { Uid = p.uid, Zoneid = p.zoneid }; battleSocket.SendMsg(eProtocalCommand.CsLeaveRoom, msg); // 这里也是战场socket } #endregion #region 服务端消息回调 public void On_EnterLobby(byte[] _data) { LogHelper.Log("进入大厅"); CurrentState = State.InLobby; // 修改状态为处于大厅中 } /// /// 成功连接到大厅/从战场返回大厅主动查询 /// /// public void On_UpdateRoomList(byte[] _data) { var msg = SC_MD_GetRoomList.Parser.ParseFrom(_data); LogHelper.Log($"最新房间列表: {msg.RoomInfos.Count}"); // todo : 转接客户端逻辑 if (CurrentState == State.InLobby) { var lobby = new MultiDupProxy.LobbyInfo(); msg.RoomInfos.ToList().ForEach(l => // 倒腾着转移一下格式 lobby.RoomList.Add(new MultiDupProxy.LobbyInfo.RoomInfo() { BattleServerAddress = l.Battleserver, MapId = l.Mapid, PlayerUids = l.PlayerUids.ToList(), RoomId = l.RoomId })); MultiDupProxy.Instance.Lobby = lobby; MultiDupProxy.Instance.__On_GetRoomListCallBack?.Invoke(lobby); } } /// /// 创建房间返回值 /// /// public void On_CreateRoom(byte[] _data) { // 创建房间返回值 var msg = SC_MD_CreateRoom.Parser.ParseFrom(_data); LogHelper.Log($"创建房间: {msg.RoomId} ."); // todo : 转接客户端逻辑 MultiDupProxy.Instance.__On_CreateRoomCallBack?.Invoke(msg); // 调用回调 } /// /// 加入房间消息 /// /// public void On_EnterRoom(byte[] _data) { var msg = SC_MD_EnterRoom.Parser.ParseFrom(_data); if (msg != null) { var p = UserProxy.Instance.player; if (msg.Uid == p.uid) { CurrentState = State.InBattleRoom; LogHelper.Log($"连接战斗服务器: {msg.Ip}:{msg.Port}."); MultiBattleProxy.Instance.Init(msg.Ip, msg.Port); LogHelper.Log($"您已成功进入房间: {msg.Mapid}."); } else { UnityEngine.Debug.Log($"{msg.Uid} 来了."); } MultiDupProxy.Instance.__On_EnterRoomCallback?.Invoke(msg); } else { LogHelper.Log($"加入房间消息解析失败"); } } /// /// 开始副本战斗 /// /// public void On_Start(byte[] _data) { // 多人副本开始战斗 var msg = SC_MD_BeginDup.Parser.ParseFrom(_data); LogHelper.Log($"开始副本战斗: {msg} ."); MultiDupProxy.Instance.OnStartGame?.Invoke(msg); // todo : 转接客户端逻辑 } public void On_LeaveGame(byte[] _data) { var msg = SC_MD_LeaveRoom.Parser.ParseFrom(_data); LogHelper.Log($"玩家 {msg.Uid} 已经离开游戏!"); // // todo:转接客户端逻辑 } public void _close() { MessageCenter.Instance.removeObserver(eProtocalCommand.ScMdGetRoomList, On_UpdateRoomList); // 进入大厅返回此消息 MessageCenter.Instance.removeObserver(eProtocalCommand.ScMdCreateRoom, On_CreateRoom); // 创建房间成功 MessageCenter.Instance.removeObserver(eProtocalCommand.ScMdEnterRoom, On_EnterRoom); MessageCenter.Instance.removeObserver(eProtocalCommand.ScMdBeginDup, On_Start); MessageCenter.Instance.removeObserver(eProtocalCommand.ScMdLeaveRoom, On_LeaveGame); if (null != lobbySocket) { LogHelper.Log("销毁lobbySocket"); lobbySocket.Close(); lobbySocket = null; } } public void Update() { lobbySocket?.Update(); //battleSocket?.Update(); } private void OnDisable() { _close(); } protected override void DoOnDestroy() { _close(); } #endregion }