LoginHandler.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using XmdsBattleClient.Client;
  5. using XmdsBattleClientBot.XmdsBot;
  6. using pomelo.area;
  7. using pomelo.connector;
  8. using pomelo.gate;
  9. using CommonLang;
  10. using SimpleJson;
  11. namespace Pomelo.DotNetClient
  12. {
  13. public class LoginHandler
  14. {
  15. private readonly static int TIMEOUT = 30000;
  16. private readonly static int QUAUA_REQUEST_INTERVAL = 2000;
  17. private TimeTaskQueue mTimeTasks = new TimeTaskQueue();
  18. private XmdsNetClient mNetClient;
  19. private bool mNeedQueueServer = true;
  20. private HashMap<string, string> mIpMapping = new HashMap<string, string>();
  21. public delegate void OnEnterSceneBegin();
  22. private OnEnterSceneBegin event_EnterSceneBegin;
  23. public event OnEnterSceneBegin EnterSceneBegin
  24. {
  25. add { event_EnterSceneBegin += value; }
  26. remove { event_EnterSceneBegin -= value; }
  27. }
  28. public delegate void OnEnterSceneSuccess();
  29. private OnEnterSceneSuccess event_EnterSceneSuccess;
  30. public event OnEnterSceneSuccess EnterSceneSuccess
  31. {
  32. add { event_EnterSceneSuccess += value; }
  33. remove { event_EnterSceneSuccess -= value; }
  34. }
  35. //一号通登录地址,可读取外部配置后设置此变量,否则为默认地址
  36. public string LoginUrl { get; set; }
  37. private CommonLang.Log.Logger log = CommonLang.Log.LoggerFactory.GetLogger("LoginHandler");
  38. public LoginHandler(XmdsNetClient netClient)
  39. {
  40. mNetClient = netClient;
  41. LoginUrl = "192.168.0.151:8888";
  42. }
  43. public void AddIpMapping(IDictionary<string, string> mapping)
  44. {
  45. if (mapping != null)
  46. {
  47. mIpMapping.PutAll(mapping);
  48. }
  49. }
  50. public void UpdateTimeMS(int intervalMS)
  51. {
  52. mTimeTasks.Update(intervalMS);
  53. }
  54. #region protl data cache
  55. public RegisterMessage LastRegister { get; private set; }
  56. public LoginMessage LastLogin { get; private set; }
  57. public ActivationMessage LastActivation { get; private set; }
  58. public EntryResponse LastEntryResponse { get; private set; }
  59. public GetRandomNameResponse LastRandomName { get; private set; }
  60. public CreatePlayerResponse LastCreateRole { get; private set; }
  61. public DeletePlayerResponse LastDeleteRole { get; private set; }
  62. public BindPlayerResponse LastBindPlayer { get; private set; }
  63. #endregion
  64. #region 一号通注册
  65. public void Request_Register(string account, string password, int appid, int channel, int ostype, int logintype, string mac, Action<RegisterMessage> action)
  66. {
  67. int msgId = (int)XmdsHttpMsgID.Register;
  68. Dictionary<string, string> arg = new Dictionary<string, string>();
  69. arg.Add("type", msgId.ToString());
  70. arg.Add("username", account);
  71. arg.Add("appid", appid.ToString());
  72. arg.Add("channel", channel.ToString());
  73. arg.Add("ostype", ostype.ToString());
  74. arg.Add("logintype", logintype.ToString());
  75. arg.Add("mac", mac);
  76. if (password.Length > 0)
  77. {
  78. string pswRsa = HttpMsgUtils.GetRSAStringWithDefaultKey(password);
  79. arg.Add("password", pswRsa);
  80. }
  81. //if (apnsId.Length > 0)
  82. // arg.Add("apnsID", apnsId);
  83. mNetClient.RequestHttpPostAsync(LoginUrl, arg, (result) =>
  84. {
  85. var msg = HttpMsgUtils.ParseXmlString<RegisterMessage>(result);
  86. this.LastRegister = msg;
  87. if (action != null) action.Invoke(msg);
  88. });
  89. }
  90. #endregion
  91. #region 一号通登录
  92. public void Request_Login(string account, string password, int appid, int channel, int ostype, int logintype, int version, string mac, Action<LoginMessage> action)
  93. {
  94. int msgId = (int)XmdsHttpMsgID.Login;
  95. Dictionary<string, string> arg = new Dictionary<string, string>();
  96. arg.Add("type", msgId.ToString());
  97. arg.Add("username", account);
  98. arg.Add("appid", appid.ToString());
  99. arg.Add("channel", channel.ToString());
  100. arg.Add("ostype", ostype.ToString());
  101. arg.Add("logintype", logintype.ToString());
  102. arg.Add("version", version.ToString());
  103. arg.Add("mac", mac);
  104. if (password.Length > 0)
  105. {
  106. string pswRsa = HttpMsgUtils.GetRSAStringWithDefaultKey(password);
  107. arg.Add("password", pswRsa);
  108. }
  109. //if (sdkExpansion.Length > 0)
  110. // arg.Add("expansion", sdkExpansion);
  111. //if (sdkVersion.Length > 0)
  112. // arg.Add("sdkversion", sdkVersion);
  113. //if (apnsId.Length > 0)
  114. // arg.Add("apnsID", apnsId);
  115. mNetClient.RequestHttpPostAsync(LoginUrl, arg, (result) =>
  116. {
  117. var msg = HttpMsgUtils.ParseXmlString<LoginMessage>(result);
  118. this.LastLogin = msg;
  119. if (action != null) action.Invoke(msg);
  120. });
  121. }
  122. #endregion
  123. #region 激活请求
  124. public void Request_Activation(string code, string account, int appid, int channel, int logintype, int ostype, int version, Action<ActivationMessage> action)
  125. {
  126. int msgId = (int)XmdsHttpMsgID.Login;
  127. Dictionary<string, string> arg = new Dictionary<string, string>();
  128. arg.Add("type", msgId.ToString());
  129. arg.Add("mac", code);
  130. arg.Add("username", account);
  131. arg.Add("appid", appid.ToString());
  132. arg.Add("channel", channel.ToString());
  133. arg.Add("logintype", logintype.ToString());
  134. arg.Add("ostype", ostype.ToString());
  135. arg.Add("version", version.ToString());
  136. mNetClient.RequestHttpPostAsync(LoginUrl, arg, (result) =>
  137. {
  138. ActivationMessage msg = HttpMsgUtils.ParseXmlString<ActivationMessage>(result);
  139. this.LastActivation = msg;
  140. if (action != null) action.Invoke(msg);
  141. });
  142. }
  143. #endregion
  144. #region 进入服务器
  145. public class RequestEntryServerState
  146. {
  147. public readonly string account;
  148. public readonly string sign;
  149. public readonly ulong time;
  150. public readonly int logicSvrId;
  151. public string ip;
  152. public int port;
  153. public readonly string c2s_deviceMac;
  154. public readonly int c2s_deviceType;
  155. public readonly string c2s_clientRegion;
  156. public readonly string c2s_clientChannel;
  157. public readonly string c2s_clientVersion;
  158. public readonly Action<EntryResponse> action;
  159. public readonly Action<Exception> error = null;
  160. public readonly Action<QueryEntryResponse> queueProgress = null;
  161. public RequestEntryServerState(
  162. string account,
  163. string sign,
  164. ulong time,
  165. int logicSvrId,
  166. string ip,
  167. int port,
  168. string c2s_deviceMac,
  169. int c2s_deviceType,
  170. string c2s_clientRegion,
  171. string c2s_clientChannel,
  172. string c2s_clientVersion,
  173. Action<EntryResponse> action,
  174. Action<Exception> error,
  175. Action<QueryEntryResponse> queueProgress)
  176. {
  177. this.account = account;
  178. this.sign = sign;
  179. this.time = time;
  180. this.logicSvrId = logicSvrId;
  181. this.ip = ip;
  182. this.port = port;
  183. this.c2s_deviceMac = c2s_deviceMac;
  184. this.c2s_deviceType = c2s_deviceType;
  185. this.c2s_clientRegion = c2s_clientRegion;
  186. this.c2s_clientChannel = c2s_clientChannel;
  187. this.c2s_clientVersion = c2s_clientVersion;
  188. this.action = action;
  189. this.error = error;
  190. this.queueProgress = queueProgress;
  191. }
  192. }
  193. public void Cancel_Request_EntryServer()
  194. {
  195. mNeedQueueServer = false;
  196. if (mNetClient.GateSocket.IsConnected)
  197. {
  198. log.Debug("====socket ==Cancel_Request_EntryServer== disconnect");
  199. mNetClient.GateSocket.disconnect();
  200. }
  201. }
  202. public void Request_EntryServer(
  203. string account,
  204. string sign,
  205. ulong time,
  206. int logicSvrId,
  207. string ip,
  208. int port,
  209. string c2s_deviceMac,
  210. int c2s_deviceType,
  211. string c2s_clientRegion,
  212. string c2s_clientChannel,
  213. string c2s_clientVersion,
  214. Action<EntryResponse> action,
  215. Action<Exception> error = null,
  216. Action<QueryEntryResponse> queueProgress = null)
  217. {
  218. var state = new RequestEntryServerState(account, sign, time, logicSvrId, ip, port, c2s_deviceMac, c2s_deviceType, c2s_clientRegion, c2s_clientChannel, c2s_clientVersion,
  219. action, error, queueProgress);
  220. Request_EntryServer(state);
  221. }
  222. void Request_EntryServer(RequestEntryServerState state)
  223. {
  224. //mNetClient.GameSocket.onRequestStart("area.loginHandler.connectGateSocket", null);
  225. log.Debug("---LoginHandler--- GateSocket connect start!");
  226. //连接Gate服务器.
  227. mNetClient.StartEntryServer();
  228. mNetClient.Disconnect();
  229. mNetClient.CreateNextBattleClient();
  230. if (mIpMapping.ContainsKey(state.ip + ":" + state.port))
  231. {
  232. var addr = mIpMapping.Get(state.ip + ":" + state.port).Split(':');
  233. state.ip = addr[0];
  234. state.port = int.Parse(addr[1]);
  235. }
  236. mNetClient.GateSocket.ClearLastResponse();
  237. mNeedQueueServer = true;
  238. mNetClient.GateSocket.connect(state.ip, state.port, TIMEOUT, (result) =>
  239. {
  240. if (result.ContainsKey("s2c_code"))
  241. {
  242. var c = result["s2c_code"] + "";
  243. var m = result["s2c_msg"] + "";
  244. if (state.error != null)
  245. {
  246. state.error.Invoke(new Exception(string.Format("GateSocket connect timeout! \r\n code={0} \r\n msg={1}", c, m)));
  247. }
  248. return;
  249. }
  250. _Request_EntryServer_connected(state);
  251. });
  252. }
  253. public void Request_EntryServerNew(
  254. string account,
  255. string sign,
  256. ulong time,
  257. int logicSvrId,
  258. string ip,
  259. int port,
  260. string c2s_deviceMac,
  261. int c2s_deviceType,
  262. string c2s_clientRegion,
  263. string c2s_clientChannel,
  264. string c2s_clientVersion,
  265. Action<EntryResponse> action,
  266. Action<Exception> error = null,
  267. Action<QueryEntryResponse> queueProgress = null)
  268. {
  269. var state = new RequestEntryServerState(account, sign, time, logicSvrId, ip, port, c2s_deviceMac, c2s_deviceType, c2s_clientRegion, c2s_clientChannel, c2s_clientVersion,
  270. action, error, queueProgress);
  271. Request_EntryServerNew(state);
  272. }
  273. public void Request_EntryServerNew(RequestEntryServerState state)
  274. {
  275. mNetClient.StartEntryServer();
  276. mNetClient.ClearBattle();
  277. mNetClient.CreateNextBattleClient();
  278. if (mIpMapping.ContainsKey(state.ip + ":" + state.port))
  279. {
  280. var addr = mIpMapping.Get(state.ip + ":" + state.port).Split(':');
  281. state.ip = addr[0];
  282. state.port = int.Parse(addr[1]);
  283. }
  284. //mNetClient.GateSocket.ClearLastResponse();
  285. mNeedQueueServer = true;
  286. var response = new QueryEntryResponse();
  287. response.s2c_pubHost = state.ip;
  288. response.s2c_port = state.port;
  289. response.s2c_token = state.sign;
  290. _Request_EntryServer_queryEntryRequest_response(response, state);
  291. }
  292. private void _Request_EntryServer_connected(RequestEntryServerState state)
  293. {
  294. log.Debug("---LoginHandler--- GateSocket connect success!");
  295. log.Debug("---LoginHandler--- queryEntryRequest start!");
  296. //请求真实ip,port
  297. mNetClient.GateSocket.gateHandler.queryEntryRequest(state.account, state.sign, state.time.ToString(), state.logicSvrId, (PomeloException exception, QueryEntryResponse response) =>
  298. {
  299. log.Debug("---LoginHandler--- queryEntryRequest Response!");
  300. if (exception == null)
  301. {
  302. try
  303. {
  304. if(response.s2c_pos > 0)
  305. {
  306. if (state.queueProgress != null)
  307. {
  308. state.queueProgress.Invoke(response);
  309. }
  310. if (mNeedQueueServer)
  311. {
  312. mTimeTasks.AddTimeDelayMS(QUAUA_REQUEST_INTERVAL, (task) =>
  313. {
  314. if (mNetClient.GateSocket.IsConnected)
  315. {
  316. _Request_EntryServer_connected(state);
  317. }
  318. else
  319. {
  320. throw new Exception("GateSocket disconnected");
  321. }
  322. });
  323. }
  324. }
  325. else
  326. {
  327. _Request_EntryServer_queryEntryRequest_response(response, state);
  328. }
  329. }
  330. catch (Exception err)
  331. {
  332. if (state.error != null) state.error(err);
  333. }
  334. }
  335. else
  336. {
  337. if (state.error != null) state.error(exception);
  338. }
  339. });
  340. }
  341. private string GameIp;
  342. private int GamePort;
  343. private void _Request_EntryServer_queryEntryRequest_response(QueryEntryResponse response, RequestEntryServerState state)
  344. {
  345. //if (mNetClient.GateSocket.IsConnected)
  346. //{
  347. // log.Debug("====socket ==Cancel_Request_EntryServer== mNetClient.GateSocket.disconnect()");
  348. // mNetClient.GateSocket.disconnect();
  349. //}
  350. if (mNetClient.GameSocket.IsConnected)
  351. {
  352. if(response.s2c_pubHost.Equals(GameIp) && GamePort == response.s2c_port)
  353. {
  354. _Request_EntryServer_GameSocket_connected(response, state);
  355. return;
  356. }
  357. }
  358. log.Debug("====socket == mNetClient.GameSocket.disconnect()");
  359. mNetClient.GameSocket.disconnect();
  360. log.Debug("---LoginHandler--- GameSocket connect start!");
  361. //if (mIpMapping.ContainsKey(response.s2c_pubHost + ":" + response.s2c_port))
  362. //{
  363. // var addr = mIpMapping.Get(response.s2c_pubHost + ":" + response.s2c_port).Split(':');
  364. // response.s2c_pubHost = addr[0];
  365. // response.s2c_port = int.Parse(addr[1]);
  366. //}
  367. mNetClient.GameSocket.ClearLastResponse();
  368. GameIp = response.s2c_pubHost;
  369. GamePort = response.s2c_port;
  370. mNetClient.GameSocket.connect(GameIp, GamePort, TIMEOUT, (result1) =>
  371. {
  372. if (result1.ContainsKey("s2c_code"))
  373. {
  374. var c = result1["s2c_code"] + "";
  375. var m = result1["s2c_msg"] + "";
  376. if (state.error != null)
  377. {
  378. state.error.Invoke(new Exception(string.Format("GameSocket connect timeout! \r\n code={0} \r\n msg={1}", c, m)));
  379. }
  380. return;
  381. }
  382. _Request_EntryServer_GameSocket_connected(response, state);
  383. });
  384. }
  385. private void _Request_EntryServer_GameSocket_connected(QueryEntryResponse response, RequestEntryServerState state)
  386. {
  387. log.Debug("---LoginHandler--- GameSocket connect success!");
  388. log.Debug("---LoginHandler--- entryRequest start!");
  389. //请求进入服务器.
  390. mNetClient.GameSocket.entryHandler.entryRequest(
  391. state.account,
  392. response.s2c_token,
  393. state.logicSvrId,
  394. state.c2s_deviceMac,
  395. state.c2s_deviceType,
  396. state.c2s_clientRegion,
  397. state.c2s_clientChannel,
  398. state.c2s_clientVersion,
  399. (PomeloException exception1, EntryResponse response1) =>
  400. {
  401. log.Debug("---LoginHandler--- entryRequest Response!");
  402. LastEntryResponse = response1;
  403. if (exception1 != null)
  404. {
  405. if (state.error != null) state.error(exception1);
  406. }
  407. else
  408. {
  409. if (state.action != null) state.action.Invoke(response1);
  410. }
  411. });
  412. }
  413. #endregion
  414. public void ConnectToGameServer(Action connectCallback)
  415. {
  416. if (!mNetClient.GameSocket.IsConnected)
  417. {
  418. mNetClient.GameSocket.connect(GameIp, GamePort, TIMEOUT, (result) =>
  419. {
  420. if (connectCallback != null)
  421. {
  422. connectCallback.Invoke();
  423. }
  424. });
  425. }
  426. else
  427. {
  428. if (connectCallback != null)
  429. {
  430. connectCallback.Invoke();
  431. }
  432. }
  433. }
  434. #region 获取随机名
  435. public void Request_RandomName(int pro, Action<GetRandomNameResponse> action, Action<Exception> error = null)
  436. {
  437. mNetClient.GameSocket.roleHandler.getRandomNameRequest(pro, (PomeloException exception, GetRandomNameResponse response) =>
  438. {
  439. this.LastRandomName = response;
  440. if (exception != null)
  441. {
  442. if (error != null) error(exception);
  443. }
  444. else
  445. {
  446. if (action != null) action.Invoke(response);
  447. }
  448. });
  449. }
  450. #endregion
  451. #region 创建角色
  452. public void Request_CreateRole(int pro, string name, int sex = 0, Action<CreatePlayerResponse> action = null, Action<Exception> error = null)
  453. {
  454. mNetClient.GameSocket.roleHandler.createPlayerRequest(pro, name, sex, (PomeloException exception, CreatePlayerResponse response) =>
  455. {
  456. this.LastCreateRole = response;
  457. if (exception != null)
  458. {
  459. if (error != null) error(exception);
  460. }
  461. else
  462. {
  463. if (action != null) action.Invoke(response);
  464. }
  465. });
  466. }
  467. #endregion
  468. #region 删除角色
  469. public void Request_DeleteRole(string playerId, Action<DeletePlayerResponse> action = null, Action<Exception> error = null)
  470. {
  471. mNetClient.GameSocket.roleHandler.deletePlayerRequest(playerId, (PomeloException exception, DeletePlayerResponse response) =>
  472. {
  473. this.LastDeleteRole = response;
  474. if (exception != null)
  475. {
  476. if (error != null) error(exception);
  477. }
  478. else
  479. {
  480. if (action != null) action.Invoke(response);
  481. }
  482. });
  483. }
  484. #endregion
  485. #region 进入场景
  486. public void Request_BindPlayer(string playerId, Action<BindPlayerResponse> action, Action<Exception> error = null)
  487. {
  488. mNetClient.GameSocket.connect(GameIp, GamePort, TIMEOUT,(result)=> {
  489. mNetClient.GameSocket.entryHandler.bindPlayerRequest(playerId, (PomeloException exception, BindPlayerResponse response) =>
  490. {
  491. if (exception == null)
  492. {
  493. log.Debug("lixu=========socket===============Request_BindPlayer success");
  494. this.LastBindPlayer = response;
  495. this.mNetClient.BattleClientInitBegin();
  496. if (event_EnterSceneBegin != null)
  497. {
  498. event_EnterSceneBegin.Invoke();
  499. }
  500. if (action != null) action.Invoke(response);
  501. }
  502. else {
  503. log.Warn("lixu=========socket===============Request_BindPlayer error:" + exception.Message);
  504. if (error != null) error.Invoke(exception);
  505. }
  506. });
  507. });
  508. }
  509. public void Request_ExitCrossServerToLogicServerRequest(Action<ExitCrossServerToLogicServerResponse> action, Action<Exception> error = null)
  510. {
  511. mNetClient.GameSocket.entryHandler.exitCrossServerToLogicServerRequest((PomeloException exception, ExitCrossServerToLogicServerResponse response) =>
  512. {
  513. if (exception == null)
  514. {
  515. if (action != null) action.Invoke(response);
  516. }
  517. else { if (error != null) error.Invoke(exception); }
  518. });
  519. }
  520. public void Request_EnterCrossServerRequest(Action<EnterCrossServerResponse> action, Action<Exception> error = null)
  521. {
  522. mNetClient.GameSocket.entryHandler.enterCrossServerRequest((PomeloException exception, EnterCrossServerResponse response) =>
  523. {
  524. if (exception == null)
  525. {
  526. if (action != null) action.Invoke(response);
  527. }
  528. else { if (error != null) error.Invoke(exception); }
  529. });
  530. }
  531. public void Request_EnterScene(string c2s_instanceId , Action<EnterSceneResponse> action, Action<Exception> error = null)
  532. {
  533. mNetClient.GameSocket.playerHandler.enterSceneRequest(c2s_instanceId, (PomeloException exception, EnterSceneResponse response) =>
  534. {
  535. if (exception == null)
  536. {
  537. mNetClient.BattleClientInitFinish();
  538. if (event_EnterSceneSuccess != null)
  539. {
  540. event_EnterSceneSuccess.Invoke();
  541. }
  542. if (action != null) action.Invoke(response);
  543. }
  544. else
  545. {
  546. if (error != null) error.Invoke(exception);
  547. }
  548. });
  549. }
  550. #endregion
  551. #region 切换场景
  552. /// <summary>
  553. /// 回调
  554. /// </summary>
  555. public void Invoke_ChangeScene()
  556. {
  557. this.mNetClient.BattleClientInitBegin();
  558. if (event_EnterSceneBegin != null)
  559. {
  560. event_EnterSceneBegin.Invoke();
  561. }
  562. }
  563. [Obsolete("这个命名有点蛋疼,感觉是向服务器请求,但实际只是回调一个方法,用Invoke_ChangeScene替代")]
  564. public void Request_ChangeScene()
  565. {
  566. Invoke_ChangeScene();
  567. }
  568. #endregion
  569. }
  570. }