GateSession.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Numerics;
  5. using System.Threading.Tasks;
  6. using ENet;
  7. using Helper;
  8. using Log;
  9. namespace LoginClient
  10. {
  11. public class GateSession: IDisposable
  12. {
  13. public int ID { get; set; }
  14. public IMessageChannel IMessageChannel { get; set; }
  15. public GateSession(int id, IMessageChannel eNetChannel)
  16. {
  17. this.ID = id;
  18. this.IMessageChannel = eNetChannel;
  19. }
  20. public void Dispose()
  21. {
  22. this.IMessageChannel.Dispose();
  23. }
  24. public async void Login(SRP6Client srp6Client)
  25. {
  26. var smsgAuthChallenge = await this.Handle_SMSG_Auth_Challenge();
  27. var clientSeed = (uint)TimeHelper.EpochTimeSecond();
  28. byte[] digest = srp6Client.CalculateGateDigest(clientSeed, smsgAuthChallenge.Seed);
  29. var cmsgAuthSession = new CMSG_Auth_Session()
  30. {
  31. ClientBuild = 11723,
  32. ClientSeed = clientSeed,
  33. Digest = digest,
  34. Hd = new byte[0],
  35. Mac = new byte[0],
  36. Unk2 = 0,
  37. Unk3 = 0,
  38. Unk4 = 0,
  39. Username = srp6Client.Account
  40. };
  41. this.IMessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_SESSION, cmsgAuthSession);
  42. await Handle_SMSG_Auth_Response();
  43. Logger.Trace("session: {0}, login gate OK!", this.ID);
  44. }
  45. public async Task<SMSG_Auth_Challenge> Handle_SMSG_Auth_Challenge()
  46. {
  47. var result = await this.IMessageChannel.RecvMessage();
  48. ushort opcode = result.Item1;
  49. byte[] message = result.Item2;
  50. if (opcode != MessageOpcode.SMSG_AUTH_CHALLENGE)
  51. {
  52. throw new LoginException(string.Format(
  53. "session: {0}, opcode: {1}", this.ID, opcode));
  54. }
  55. var smsgAuthChallenge = ProtobufHelper.FromBytes<SMSG_Auth_Challenge>(message);
  56. return smsgAuthChallenge;
  57. }
  58. public async Task<SMSG_Auth_Response> Handle_SMSG_Auth_Response()
  59. {
  60. var result = await this.IMessageChannel.RecvMessage();
  61. ushort opcode = result.Item1;
  62. byte[] message = result.Item2;
  63. if (opcode != MessageOpcode.SMSG_AUTH_RESPONSE)
  64. {
  65. throw new LoginException(string.Format(
  66. "session: {0}, opcode: {1}", this.ID, opcode));
  67. }
  68. var smsgAuthResponse = ProtobufHelper.FromBytes<SMSG_Auth_Response>(message);
  69. if (smsgAuthResponse.ErrorCode != 0)
  70. {
  71. throw new LoginException(string.Format(
  72. "session: {0}, SMSG_Auth_Response: {1}",
  73. this.ID, JsonHelper.ToString(smsgAuthResponse)));
  74. }
  75. return smsgAuthResponse;
  76. }
  77. }
  78. }