using System; using System.Collections.Generic; using XmdsBattleClient.Client; using XmdsBattleClientBot.XmdsBot; using pomelo.area; using pomelo.connector; using pomelo.gate; using CommonLang; using SimpleJson; namespace Pomelo.DotNetClient { public class LoginHandler { private readonly static int TIMEOUT = 30000; private readonly static int QUAUA_REQUEST_INTERVAL = 2000; private TimeTaskQueue mTimeTasks = new TimeTaskQueue(); private XmdsNetClient mNetClient; private bool mNeedQueueServer = true; private HashMap mIpMapping = new HashMap(); public delegate void OnEnterSceneBegin(); private OnEnterSceneBegin event_EnterSceneBegin; public event OnEnterSceneBegin EnterSceneBegin { add { event_EnterSceneBegin += value; } remove { event_EnterSceneBegin -= value; } } public delegate void OnEnterSceneSuccess(); private OnEnterSceneSuccess event_EnterSceneSuccess; public event OnEnterSceneSuccess EnterSceneSuccess { add { event_EnterSceneSuccess += value; } remove { event_EnterSceneSuccess -= value; } } //一号通登录地址,可读取外部配置后设置此变量,否则为默认地址 public string LoginUrl { get; set; } private CommonLang.Log.Logger log = CommonLang.Log.LoggerFactory.GetLogger("LoginHandler"); public LoginHandler(XmdsNetClient netClient) { mNetClient = netClient; LoginUrl = "192.168.0.151:8888"; } public void AddIpMapping(IDictionary mapping) { if (mapping != null) { mIpMapping.PutAll(mapping); } } public void UpdateTimeMS(int intervalMS) { mTimeTasks.Update(intervalMS); } #region protl data cache public RegisterMessage LastRegister { get; private set; } public LoginMessage LastLogin { get; private set; } public ActivationMessage LastActivation { get; private set; } public EntryResponse LastEntryResponse { get; private set; } public GetRandomNameResponse LastRandomName { get; private set; } public CreatePlayerResponse LastCreateRole { get; private set; } public DeletePlayerResponse LastDeleteRole { get; private set; } public BindPlayerResponse LastBindPlayer { get; private set; } #endregion #region 一号通注册 public void Request_Register(string account, string password, int appid, int channel, int ostype, int logintype, string mac, Action action) { int msgId = (int)XmdsHttpMsgID.Register; Dictionary arg = new Dictionary(); arg.Add("type", msgId.ToString()); arg.Add("username", account); arg.Add("appid", appid.ToString()); arg.Add("channel", channel.ToString()); arg.Add("ostype", ostype.ToString()); arg.Add("logintype", logintype.ToString()); arg.Add("mac", mac); if (password.Length > 0) { string pswRsa = HttpMsgUtils.GetRSAStringWithDefaultKey(password); arg.Add("password", pswRsa); } //if (apnsId.Length > 0) // arg.Add("apnsID", apnsId); mNetClient.RequestHttpPostAsync(LoginUrl, arg, (result) => { var msg = HttpMsgUtils.ParseXmlString(result); this.LastRegister = msg; if (action != null) action.Invoke(msg); }); } #endregion #region 一号通登录 public void Request_Login(string account, string password, int appid, int channel, int ostype, int logintype, int version, string mac, Action action) { int msgId = (int)XmdsHttpMsgID.Login; Dictionary arg = new Dictionary(); arg.Add("type", msgId.ToString()); arg.Add("username", account); arg.Add("appid", appid.ToString()); arg.Add("channel", channel.ToString()); arg.Add("ostype", ostype.ToString()); arg.Add("logintype", logintype.ToString()); arg.Add("version", version.ToString()); arg.Add("mac", mac); if (password.Length > 0) { string pswRsa = HttpMsgUtils.GetRSAStringWithDefaultKey(password); arg.Add("password", pswRsa); } //if (sdkExpansion.Length > 0) // arg.Add("expansion", sdkExpansion); //if (sdkVersion.Length > 0) // arg.Add("sdkversion", sdkVersion); //if (apnsId.Length > 0) // arg.Add("apnsID", apnsId); mNetClient.RequestHttpPostAsync(LoginUrl, arg, (result) => { var msg = HttpMsgUtils.ParseXmlString(result); this.LastLogin = msg; if (action != null) action.Invoke(msg); }); } #endregion #region 激活请求 public void Request_Activation(string code, string account, int appid, int channel, int logintype, int ostype, int version, Action action) { int msgId = (int)XmdsHttpMsgID.Login; Dictionary arg = new Dictionary(); arg.Add("type", msgId.ToString()); arg.Add("mac", code); arg.Add("username", account); arg.Add("appid", appid.ToString()); arg.Add("channel", channel.ToString()); arg.Add("logintype", logintype.ToString()); arg.Add("ostype", ostype.ToString()); arg.Add("version", version.ToString()); mNetClient.RequestHttpPostAsync(LoginUrl, arg, (result) => { ActivationMessage msg = HttpMsgUtils.ParseXmlString(result); this.LastActivation = msg; if (action != null) action.Invoke(msg); }); } #endregion #region 进入服务器 public class RequestEntryServerState { public readonly string account; public readonly string sign; public readonly ulong time; public readonly int logicSvrId; public string ip; public int port; public readonly string c2s_deviceMac; public readonly int c2s_deviceType; public readonly string c2s_clientRegion; public readonly string c2s_clientChannel; public readonly string c2s_clientVersion; public readonly Action action; public readonly Action error = null; public readonly Action queueProgress = null; public RequestEntryServerState( string account, string sign, ulong time, int logicSvrId, string ip, int port, string c2s_deviceMac, int c2s_deviceType, string c2s_clientRegion, string c2s_clientChannel, string c2s_clientVersion, Action action, Action error, Action queueProgress) { this.account = account; this.sign = sign; this.time = time; this.logicSvrId = logicSvrId; this.ip = ip; this.port = port; this.c2s_deviceMac = c2s_deviceMac; this.c2s_deviceType = c2s_deviceType; this.c2s_clientRegion = c2s_clientRegion; this.c2s_clientChannel = c2s_clientChannel; this.c2s_clientVersion = c2s_clientVersion; this.action = action; this.error = error; this.queueProgress = queueProgress; } } public void Cancel_Request_EntryServer() { mNeedQueueServer = false; if (mNetClient.GateSocket.IsConnected) { log.Debug("====socket ==Cancel_Request_EntryServer== disconnect"); mNetClient.GateSocket.disconnect(); } } public void Request_EntryServer( string account, string sign, ulong time, int logicSvrId, string ip, int port, string c2s_deviceMac, int c2s_deviceType, string c2s_clientRegion, string c2s_clientChannel, string c2s_clientVersion, Action action, Action error = null, Action queueProgress = null) { var state = new RequestEntryServerState(account, sign, time, logicSvrId, ip, port, c2s_deviceMac, c2s_deviceType, c2s_clientRegion, c2s_clientChannel, c2s_clientVersion, action, error, queueProgress); Request_EntryServer(state); } void Request_EntryServer(RequestEntryServerState state) { //mNetClient.GameSocket.onRequestStart("area.loginHandler.connectGateSocket", null); log.Debug("---LoginHandler--- GateSocket connect start!"); //连接Gate服务器. mNetClient.StartEntryServer(); mNetClient.Disconnect(); mNetClient.CreateNextBattleClient(); if (mIpMapping.ContainsKey(state.ip + ":" + state.port)) { var addr = mIpMapping.Get(state.ip + ":" + state.port).Split(':'); state.ip = addr[0]; state.port = int.Parse(addr[1]); } mNetClient.GateSocket.ClearLastResponse(); mNeedQueueServer = true; mNetClient.GateSocket.connect(state.ip, state.port, TIMEOUT, (result) => { if (result.ContainsKey("s2c_code")) { var c = result["s2c_code"] + ""; var m = result["s2c_msg"] + ""; if (state.error != null) { state.error.Invoke(new Exception(string.Format("GateSocket connect timeout! \r\n code={0} \r\n msg={1}", c, m))); } return; } _Request_EntryServer_connected(state); }); } public void Request_EntryServerNew( string account, string sign, ulong time, int logicSvrId, string ip, int port, string c2s_deviceMac, int c2s_deviceType, string c2s_clientRegion, string c2s_clientChannel, string c2s_clientVersion, Action action, Action error = null, Action queueProgress = null) { var state = new RequestEntryServerState(account, sign, time, logicSvrId, ip, port, c2s_deviceMac, c2s_deviceType, c2s_clientRegion, c2s_clientChannel, c2s_clientVersion, action, error, queueProgress); Request_EntryServerNew(state); } public void Request_EntryServerNew(RequestEntryServerState state) { mNetClient.StartEntryServer(); mNetClient.ClearBattle(); mNetClient.CreateNextBattleClient(); if (mIpMapping.ContainsKey(state.ip + ":" + state.port)) { var addr = mIpMapping.Get(state.ip + ":" + state.port).Split(':'); state.ip = addr[0]; state.port = int.Parse(addr[1]); } //mNetClient.GateSocket.ClearLastResponse(); mNeedQueueServer = true; var response = new QueryEntryResponse(); response.s2c_pubHost = state.ip; response.s2c_port = state.port; response.s2c_token = state.sign; _Request_EntryServer_queryEntryRequest_response(response, state); } private void _Request_EntryServer_connected(RequestEntryServerState state) { log.Debug("---LoginHandler--- GateSocket connect success!"); log.Debug("---LoginHandler--- queryEntryRequest start!"); //请求真实ip,port mNetClient.GateSocket.gateHandler.queryEntryRequest(state.account, state.sign, state.time.ToString(), state.logicSvrId, (PomeloException exception, QueryEntryResponse response) => { log.Debug("---LoginHandler--- queryEntryRequest Response!"); if (exception == null) { try { if(response.s2c_pos > 0) { if (state.queueProgress != null) { state.queueProgress.Invoke(response); } if (mNeedQueueServer) { mTimeTasks.AddTimeDelayMS(QUAUA_REQUEST_INTERVAL, (task) => { if (mNetClient.GateSocket.IsConnected) { _Request_EntryServer_connected(state); } else { throw new Exception("GateSocket disconnected"); } }); } } else { _Request_EntryServer_queryEntryRequest_response(response, state); } } catch (Exception err) { if (state.error != null) state.error(err); } } else { if (state.error != null) state.error(exception); } }); } private string GameIp; private int GamePort; private void _Request_EntryServer_queryEntryRequest_response(QueryEntryResponse response, RequestEntryServerState state) { //if (mNetClient.GateSocket.IsConnected) //{ // log.Debug("====socket ==Cancel_Request_EntryServer== mNetClient.GateSocket.disconnect()"); // mNetClient.GateSocket.disconnect(); //} if (mNetClient.GameSocket.IsConnected) { if(response.s2c_pubHost.Equals(GameIp) && GamePort == response.s2c_port) { _Request_EntryServer_GameSocket_connected(response, state); return; } } log.Debug("====socket == mNetClient.GameSocket.disconnect()"); mNetClient.GameSocket.disconnect(); log.Debug("---LoginHandler--- GameSocket connect start!"); //if (mIpMapping.ContainsKey(response.s2c_pubHost + ":" + response.s2c_port)) //{ // var addr = mIpMapping.Get(response.s2c_pubHost + ":" + response.s2c_port).Split(':'); // response.s2c_pubHost = addr[0]; // response.s2c_port = int.Parse(addr[1]); //} mNetClient.GameSocket.ClearLastResponse(); GameIp = response.s2c_pubHost; GamePort = response.s2c_port; mNetClient.GameSocket.connect(GameIp, GamePort, TIMEOUT, (result1) => { if (result1.ContainsKey("s2c_code")) { var c = result1["s2c_code"] + ""; var m = result1["s2c_msg"] + ""; if (state.error != null) { state.error.Invoke(new Exception(string.Format("GameSocket connect timeout! \r\n code={0} \r\n msg={1}", c, m))); } return; } _Request_EntryServer_GameSocket_connected(response, state); }); } private void _Request_EntryServer_GameSocket_connected(QueryEntryResponse response, RequestEntryServerState state) { log.Debug("---LoginHandler--- GameSocket connect success!"); log.Debug("---LoginHandler--- entryRequest start!"); //请求进入服务器. mNetClient.GameSocket.entryHandler.entryRequest( state.account, response.s2c_token, state.logicSvrId, state.c2s_deviceMac, state.c2s_deviceType, state.c2s_clientRegion, state.c2s_clientChannel, state.c2s_clientVersion, (PomeloException exception1, EntryResponse response1) => { log.Debug("---LoginHandler--- entryRequest Response!"); LastEntryResponse = response1; if (exception1 != null) { if (state.error != null) state.error(exception1); } else { if (state.action != null) state.action.Invoke(response1); } }); } #endregion public void ConnectToGameServer(Action connectCallback) { if (!mNetClient.GameSocket.IsConnected) { mNetClient.GameSocket.connect(GameIp, GamePort, TIMEOUT, (result) => { if (connectCallback != null) { connectCallback.Invoke(); } }); } else { if (connectCallback != null) { connectCallback.Invoke(); } } } #region 获取随机名 public void Request_RandomName(int pro, Action action, Action error = null) { mNetClient.GameSocket.roleHandler.getRandomNameRequest(pro, (PomeloException exception, GetRandomNameResponse response) => { this.LastRandomName = response; if (exception != null) { if (error != null) error(exception); } else { if (action != null) action.Invoke(response); } }); } #endregion #region 创建角色 public void Request_CreateRole(int pro, string name, int sex = 0, Action action = null, Action error = null) { mNetClient.GameSocket.roleHandler.createPlayerRequest(pro, name, sex, (PomeloException exception, CreatePlayerResponse response) => { this.LastCreateRole = response; if (exception != null) { if (error != null) error(exception); } else { if (action != null) action.Invoke(response); } }); } #endregion #region 删除角色 public void Request_DeleteRole(string playerId, Action action = null, Action error = null) { mNetClient.GameSocket.roleHandler.deletePlayerRequest(playerId, (PomeloException exception, DeletePlayerResponse response) => { this.LastDeleteRole = response; if (exception != null) { if (error != null) error(exception); } else { if (action != null) action.Invoke(response); } }); } #endregion #region 进入场景 public void Request_BindPlayer(string playerId, Action action, Action error = null) { mNetClient.GameSocket.connect(GameIp, GamePort, TIMEOUT,(result)=> { mNetClient.GameSocket.entryHandler.bindPlayerRequest(playerId, (PomeloException exception, BindPlayerResponse response) => { if (exception == null) { log.Debug("lixu=========socket===============Request_BindPlayer success"); this.LastBindPlayer = response; this.mNetClient.BattleClientInitBegin(); if (event_EnterSceneBegin != null) { event_EnterSceneBegin.Invoke(); } if (action != null) action.Invoke(response); } else { log.Warn("lixu=========socket===============Request_BindPlayer error:" + exception.Message); if (error != null) error.Invoke(exception); } }); }); } public void Request_ExitCrossServerToLogicServerRequest(Action action, Action error = null) { mNetClient.GameSocket.entryHandler.exitCrossServerToLogicServerRequest((PomeloException exception, ExitCrossServerToLogicServerResponse response) => { if (exception == null) { if (action != null) action.Invoke(response); } else { if (error != null) error.Invoke(exception); } }); } public void Request_EnterCrossServerRequest(Action action, Action error = null) { mNetClient.GameSocket.entryHandler.enterCrossServerRequest((PomeloException exception, EnterCrossServerResponse response) => { if (exception == null) { if (action != null) action.Invoke(response); } else { if (error != null) error.Invoke(exception); } }); } public void Request_EnterScene(string c2s_instanceId , Action action, Action error = null) { mNetClient.GameSocket.playerHandler.enterSceneRequest(c2s_instanceId, (PomeloException exception, EnterSceneResponse response) => { if (exception == null) { mNetClient.BattleClientInitFinish(); if (event_EnterSceneSuccess != null) { event_EnterSceneSuccess.Invoke(); } if (action != null) action.Invoke(response); } else { if (error != null) error.Invoke(exception); } }); } #endregion #region 切换场景 /// /// 回调 /// public void Invoke_ChangeScene() { this.mNetClient.BattleClientInitBegin(); if (event_EnterSceneBegin != null) { event_EnterSceneBegin.Invoke(); } } [Obsolete("这个命名有点蛋疼,感觉是向服务器请求,但实际只是回调一个方法,用Invoke_ChangeScene替代")] public void Request_ChangeScene() { Invoke_ChangeScene(); } #endregion } }