Oskar1121

Untitled

Sep 15th, 2018
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.25 KB | None | 0 0
  1. -- @docclass
  2. ProtocolLogin = extends(Protocol, "ProtocolLogin")
  3.  
  4. LoginServerError = 10
  5. LoginServerTokenSuccess = 12
  6. LoginServerTokenError = 13
  7. LoginServerUpdate = 17
  8. LoginServerMotd = 20
  9. LoginServerUpdateNeeded = 30
  10. LoginServerSessionKey = 40
  11. LoginServerCharacterList = 100
  12. LoginServerExtendedCharacterList = 101
  13.  
  14. -- Since 10.76
  15. LoginServerRetry = 10
  16. LoginServerErrorNew = 11
  17.  
  18. function ProtocolLogin:login(host, port, accountName, accountPassword, authenticatorToken, stayLogged)
  19. if string.len(host) == 0 or port == nil or port == 0 then
  20. signalcall(self.onLoginError, self, tr("You must enter a valid server address and port."))
  21. return
  22. end
  23.  
  24. self.accountName = accountName
  25. self.accountPassword = accountPassword
  26. self.authenticatorToken = authenticatorToken
  27. self.stayLogged = stayLogged
  28. self.connectCallback = self.sendLoginPacket
  29.  
  30. self:connect(host, port)
  31. end
  32.  
  33. function ProtocolLogin:cancelLogin()
  34. self:disconnect()
  35. end
  36.  
  37. function ProtocolLogin:sendLoginPacket()
  38. local msg = OutputMessage.create()
  39. msg:addU8(ClientOpcodes.ClientEnterAccount)
  40. msg:addU16(g_game.getOs())
  41.  
  42. msg:addU16(g_game.getProtocolVersion())
  43.  
  44. if g_game.getFeature(GameClientVersion) then
  45. msg:addU32(g_game.getClientVersion())
  46. end
  47.  
  48. if g_game.getFeature(GameContentRevision) then
  49. msg:addU16(g_things.getContentRevision())
  50. msg:addU16(0)
  51. else
  52. msg:addU32(g_things.getDatSignature())
  53. end
  54. msg:addU32(g_sprites.getSprSignature())
  55. msg:addU32(PIC_SIGNATURE)
  56.  
  57. if g_game.getFeature(GamePreviewState) then
  58. msg:addU8(0)
  59. end
  60.  
  61. local offset = msg:getMessageSize()
  62. if g_game.getFeature(GameLoginPacketEncryption) then
  63. -- first RSA byte must be 0
  64. msg:addU8(0)
  65.  
  66. -- xtea key
  67. self:generateXteaKey()
  68. local xteaKey = self:getXteaKey()
  69. msg:addU32(xteaKey[1])
  70. msg:addU32(xteaKey[2])
  71. msg:addU32(xteaKey[3])
  72. msg:addU32(xteaKey[4])
  73. end
  74.  
  75. if g_game.getFeature(GameAccountNames) then
  76. msg:addString(self.accountName)
  77. else
  78. msg:addU32(tonumber(self.accountName))
  79. end
  80.  
  81. msg:addString(self.accountPassword)
  82.  
  83. if self.getLoginExtendedData then
  84. local data = self:getLoginExtendedData()
  85. msg:addString(data)
  86. end
  87.  
  88. local paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
  89. assert(paddingBytes >= 0)
  90. for i = 1, paddingBytes do
  91. msg:addU8(math.random(0, 0xff))
  92. end
  93.  
  94. if g_game.getFeature(GameLoginPacketEncryption) then
  95. msg:encryptRsa()
  96. end
  97.  
  98. if g_game.getFeature(GameOGLInformation) then
  99. msg:addU8(1) --unknown
  100. msg:addU8(1) --unknown
  101.  
  102. if g_game.getClientVersion() >= 1072 then
  103. msg:addString(string.format('%s %s', g_graphics.getVendor(), g_graphics.getRenderer()))
  104. else
  105. msg:addString(g_graphics.getRenderer())
  106. end
  107. msg:addString(g_graphics.getVersion())
  108. end
  109.  
  110. -- add RSA encrypted auth token
  111. if g_game.getFeature(GameAuthenticator) then
  112. offset = msg:getMessageSize()
  113.  
  114. -- first RSA byte must be 0
  115. msg:addU8(0)
  116. msg:addString(self.authenticatorToken)
  117.  
  118. if g_game.getFeature(GameSessionKey) then
  119. msg:addU8(booleantonumber(self.stayLogged))
  120. end
  121.  
  122. paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
  123. assert(paddingBytes >= 0)
  124. for i = 1, paddingBytes do
  125. msg:addU8(math.random(0, 0xff))
  126. end
  127.  
  128. msg:encryptRsa()
  129. end
  130.  
  131. if g_game.getFeature(GameProtocolChecksum) then
  132. self:enableChecksum()
  133. end
  134.  
  135. self:send(msg)
  136. if g_game.getFeature(GameLoginPacketEncryption) then
  137. self:enableXteaEncryption()
  138. end
  139. self:recv()
  140. end
  141.  
  142. function ProtocolLogin:onConnect()
  143. self.gotConnection = true
  144. self:connectCallback()
  145. self.connectCallback = nil
  146. end
  147.  
  148. function ProtocolLogin:onRecv(msg)
  149. while not msg:eof() do
  150. local opcode = msg:getU8()
  151. if opcode == LoginServerErrorNew then
  152. self:parseError(msg)
  153. elseif opcode == LoginServerError then
  154. self:parseError(msg)
  155. elseif opcode == LoginServerMotd then
  156. self:parseMotd(msg)
  157. elseif opcode == LoginServerUpdateNeeded then
  158. signalcall(self.onLoginError, self, tr("Client needs update."))
  159. elseif opcode == LoginServerTokenSuccess then
  160. local unknown = msg:getU8()
  161. -- elseif opcode == LoginServerTokenError then
  162. -- TODO: prompt for token here
  163. -- local unknown = msg:getU8()
  164. -- signalcall(self.onLoginError, self, tr("Invalid authentification token."))
  165. elseif opcode == LoginServerCharacterList then
  166. self:parseCharacterList(msg)
  167. elseif opcode == LoginServerExtendedCharacterList then
  168. self:parseExtendedCharacterList(msg)
  169. elseif opcode == LoginServerUpdate then
  170. local signature = msg:getString()
  171. signalcall(self.onUpdateNeeded, self, signature)
  172. elseif opcode == LoginServerSessionKey then
  173. self:parseSessionKey(msg)
  174. else
  175. self:parseOpcode(opcode, msg)
  176. end
  177. end
  178. self:disconnect()
  179. end
  180.  
  181. function ProtocolLogin:parseError(msg)
  182. local errorMessage = msg:getString()
  183. signalcall(self.onLoginError, self, errorMessage)
  184. end
  185.  
  186. function ProtocolLogin:parseMotd(msg)
  187. local motd = msg:getString()
  188. signalcall(self.onMotd, self, motd)
  189. end
  190.  
  191. function ProtocolLogin:parseSessionKey(msg)
  192. local sessionKey = msg:getString()
  193. signalcall(self.onSessionKey, self, sessionKey)
  194. end
  195.  
  196. function ProtocolLogin:parseCharacterList(msg)
  197. local characters = {}
  198.  
  199. if g_game.getClientVersion() > 1010 then
  200. local worlds = {}
  201.  
  202. local worldsCount = msg:getU8()
  203. for i=1, worldsCount do
  204. local world = {}
  205. local worldId = msg:getU8()
  206. world.worldName = msg:getString()
  207. world.worldIp = msg:getString()
  208. world.worldPort = msg:getU16()
  209. world.previewState = msg:getU8()
  210. worlds[worldId] = world
  211. end
  212.  
  213. local charactersCount = msg:getU8()
  214. for i=1, charactersCount do
  215. local character = {}
  216. local worldId = msg:getU8()
  217. character.name = msg:getString()
  218. character.worldName = worlds[worldId].worldName
  219. character.worldIp = worlds[worldId].worldIp
  220. character.worldPort = worlds[worldId].worldPort
  221. character.previewState = worlds[worldId].previewState
  222. characters[i] = character
  223. end
  224.  
  225. else
  226. local charactersCount = msg:getU8()
  227. for i=1,charactersCount do
  228. local character = {}
  229. character.name = msg:getString()
  230. character.worldName = msg:getString()
  231. character.worldIp = iptostring(msg:getU32())
  232. character.worldPort = msg:getU16()
  233.  
  234. if g_game.getFeature(GamePreviewState) then
  235. character.previewState = msg:getU8()
  236. end
  237.  
  238. characters[i] = character
  239. end
  240. end
  241.  
  242. local account = {}
  243. account.premDays = msg:getU16()
  244. signalcall(self.onCharacterList, self, characters, account)
  245. end
  246.  
  247. function ProtocolLogin:parseExtendedCharacterList(msg)
  248. local characters = msg:getTable()
  249. local account = msg:getTable()
  250. local otui = msg:getString()
  251. signalcall(self.onCharacterList, self, characters, account, otui)
  252. end
  253.  
  254. function ProtocolLogin:parseOpcode(opcode, msg)
  255. signalcall(self.onOpcode, self, opcode, msg)
  256. end
  257.  
  258. function ProtocolLogin:onError(msg, code)
  259. local text = translateNetworkError(code, self:isConnecting(), msg)
  260. signalcall(self.onLoginError, self, text)
  261. end
Advertisement
Add Comment
Please, Sign In to add comment