SHARE
TWEET

Clientless RO

a guest Feb 18th, 2016 33 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Resources, socket, sys, struct, select
  2. from time import sleep
  3.  
  4. """
  5. BASIC NETWORK HANDLING.
  6. PARSING PACKETS, SENDING LOGIN PACKETS OR OTHERS, ET CETERA.
  7. """
  8. #Resets remoteSocket so it can be used in a new connection.
  9. def resetRemoteSocket():
  10.     global remoteSocket
  11.     try:
  12.         remoteSocket.close()
  13.     except:
  14.         pass
  15.     remoteSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  16.     remoteSocket.settimeout(4)
  17.     return remoteSocket
  18.  
  19. #Sends login to main server,
  20. #which then responds with server info such as server names and populations.
  21. def sendMasterLogin(socket, username, password):
  22.     global connectionState
  23.     socket = resetRemoteSocket()
  24.     Connection(socket, 'login')
  25.     msg = str(struct.pack('B'*6, 100,0,Resources.version,0,0,0)) + str(username) + chr(0)*(24 - len(username)) + str(password) + chr(0)*(24 - len(password)) + struct.pack('B', Resources.masterVersion)
  26.     encrypt(socket, msg)
  27.     connectionState = 2
  28.  
  29. #Sends login to game server,
  30. #which then responds with info such as characters and their stats.
  31. def sendGameLogin(socket, accountID, sessionID, sex):
  32.     global connectionState
  33.     socket = resetRemoteSocket()
  34.     try:
  35.         serverChoice = int(raw_input('Please choose a server:\n'))
  36.     except Exception as e:
  37.         print 'Error in sendGameLogin.'
  38.         print e
  39.         sys.exit()
  40.     Connection(socket, serverChoice)
  41.     msg = str(struct.pack('B'*2, 101, 0)) + str(accountID) + str(sessionID) + str(struct.pack('B'*7, 0, 0, 0, 0, 0, 0, int(sex)))
  42.     encrypt(socket, msg)
  43.     connectionState = 3
  44.  
  45. #Sends
  46. def sendCharChoice(socket, choice):
  47.     msg = str(struct.pack('B'*3, 102, 0, int(choice)))
  48.     encrypt(socket, msg)
  49.    
  50. #Sends
  51. def sendMapLogin():
  52.     pass
  53.  
  54. #Called at a high frequency. Handles connections for things like logging in.
  55. #(Eventually:) Also handles keep alive packets to maintain connections.
  56. def checkConnection(socket, host, port):
  57.     global connectionState, accountID, servers
  58.     if(connectionState == 1):
  59.         global username, password
  60.         sendMasterLogin(socket, username, password)
  61.     elif(connectionState == 2 and accountID != '' and servers):
  62.         global sessionID, accountSex
  63.         sendGameLogin(socket, accountID, sessionID, accountSex)
  64.     elif(connectionState == 3):
  65.         pass
  66.     else:
  67.         pass
  68.  
  69. #Forms a connection with the socket to any server.
  70. #If an integer is supplied, it connects to a specific server. (Debugging purposes)
  71. def Connection(socket, server):
  72.     global connectionState
  73.     if(server == 'login'):
  74.         try:
  75.             socket.connect(Resources.loginServer)
  76.             print 'Connecting to iRO login server...\n'
  77.             connectionState = 2
  78.         except Exception as e:
  79.             print 'Error connecting to login server.'
  80.             print e
  81.             sys.exit()
  82.     elif(server >= 1):
  83.         try:
  84.             socket.connect(Resources.gameServer[server - 1])
  85.             print '\nConnected to game server\n'
  86.             connectionState = 3
  87.         except Exception as e:
  88.             print 'Error connecting to game server'
  89.             print e
  90.             sys.exit()
  91.     elif(server == 'char'):
  92.         try:
  93.             socket.connect(Resources.mapServer[0])
  94.             print '\nConnected to map server\n'
  95.         except Exception as e:
  96.             print 'Error connecting to map server'
  97.             print e
  98.             sys.exit()
  99.     else:
  100.         pass
  101.  
  102. #Sends messages. Encrypts if needed.
  103. #(Encryptions to be added as they're discovered).
  104. #Created in case the server adds encryption or bot needs to be transferred.
  105. def encrypt(socket, msg):
  106.     try:
  107.         socket.send(msg)
  108.     except:
  109.         print 'Error in encrypt'
  110.         sys.exit()
  111.  
  112. #Determines if there's any data sent by the server waiting to be read.
  113. #Closes socket upon errors.
  114. def dataWaiting(socket):
  115.     try:
  116.         readable = select.select([socket], [], [], 0.2)
  117.         if socket in readable[0]:
  118.             return True
  119.         else:
  120.             return False
  121.     except:
  122.         socket.close()
  123.         sys.exit()
  124.  
  125. #Handles all messages sent by server to client.
  126. #Uses initial two hex values (switch) to determine what the data is for.
  127. def parseMessage(socket, msg):
  128.     global accountID, remoteSocket
  129.     received = (socket.recv(30000)).encode('hex')
  130.     switch = received[0:4]
  131.     if(switch == '6900'):
  132.         global sessionID, accountSex
  133.         sessionID = received[8:16].decode('hex')
  134.         accountID = received[16:24].decode('hex')
  135.         accountSex = received[92:]
  136.         if(accountSex == '01'):
  137.             gender = 'Male'
  138.         else:
  139.             gender = 'Female'
  140.         print '-----Account info-----\n' + 'Session ID:' + str(sessionID) + '\nHex:' + str(sessionID.encode('hex')) + '\nAccount ID:' + str(accountID) + '\nHex:' + str(accountID.encode('hex')) + '\nSex:' + str(gender) + '\n----------------------\n'
  141.         return None
  142.     elif(switch == '80f1'):
  143.         global servers
  144.         servers = []
  145.         start = 12
  146.         for i in range(0, len(received) / 64):
  147.             serverName = received[start:start+32].replace('00', '').decode('hex')
  148.             serverPopulation = struct.unpack('<h', received[start+40:start+44].decode('hex'))[0]
  149.             servers.append([serverName, serverPopulation])
  150.             start += 64
  151.         for i in range(0, len(servers)):
  152.             print '-------Server ' + str(i+1) + '-------\n' + str(servers[i][0]) + ':' + str(servers[i][1]) + '\n----------------------\n'
  153.         return None
  154.     elif(switch == '8100'):
  155.         print 'Account disconnected. Please try again.'
  156.         return None
  157.     elif(received == accountID.encode('hex')):
  158.         return None
  159.     elif(switch == '2d08'):
  160.         encrypt(socket, 'a109'.decode('hex'))
  161.         return None
  162.     elif(switch == '9d09'):
  163.         characters = []
  164.         start = 164
  165.         for i in range(0, len(received) / 288):
  166.             charName = received[start:start+32]
  167.             STR = received[start+48:start+50]
  168.             AGI = received[start+50:start+52]
  169.             VIT = received[start+52:start+54]
  170.             INT = received[start+54:start+56]
  171.             DEX = received[start+56:start+58]
  172.             LUK = received[start+58:start+60]
  173.             mapName = received[start+68:start+132].decode('hex').split('\x00')[0]
  174.             charID = received[start+60:start+62]
  175.             characters.append([charName, STR, AGI, VIT, INT, DEX, LUK, mapName, charID])
  176.             start += 288
  177.         for i in range(0, len(characters)):
  178.             print '------Character '+str(characters[i][8])+'------\n'+str(characters[i][0]).decode('hex')+'\nSTR: '+str(int(characters[i][1], 16))+'\nAGI: '+str(int(characters[i][2], 16))+'\nVIT: '+str(int(characters[i][3], 16))+'\nINT: '+str(int(characters[i][4], 16))+'\nDEX: '+str(int(characters[i][5], 16))+'\nLUK: '+str(int(characters[i][6], 16))+'\nMap: '+str(characters[i][7])+'\n------------------------\n\n'
  179.         choice = str(raw_input('Please choose a character\'s ID:\n'))
  180.         sendCharChoice(remoteSocket, choice)
  181.         return None
  182.     elif(switch == '7100'):
  183.         charID = received[4:12]
  184.         mapName = received[12:44].decode('hex')
  185.         print 'CharID: ' + str(charID)
  186.         print 'Map: ' + str(mapName)
  187.         return None
  188.     return received
  189.  
  190. """
  191. ABSTRACTION.
  192. THINGS LIKE READING MAP FILES TO SEE WHERE YOU CAN WALK.
  193. PROCESSING GENERAL GAME DATA.
  194. """
  195. #Views map fld files and returns a value corresponding to a tile's attributes.
  196. #0 = walkable, 1 = water, ...
  197. def mapBlockValue(field, x, y, Routing):
  198.         map = open('Fields/'+field+'.fld', 'rb')
  199.         width = map.read(2)
  200.         width = struct.unpack('<h', width)[0]
  201.         height = map.read(2)
  202.         height = struct.unpack('<h', height)[0]
  203.         map.seek((width * y + x) + 4)
  204.         value = struct.unpack('B', map.read(1))[0]
  205.         return value
  206.  
  207. """
  208. MAIN CODE.
  209. IT'S THE MAIN CODE.
  210. """
  211.  
  212. username = raw_input('Username: \n')
  213. password = raw_input('Password: \n')
  214. connectionState = 1
  215. sessionID = ''
  216. accountID = ''
  217. accountSex = ''
  218. socket.setdefaulttimeout(5)
  219. serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  220. serverSocket.settimeout(2)
  221. serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  222. serverSocket.bind((socket.gethostname(), 0))
  223. serverSocket.listen(5)
  224. remoteSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  225. remoteSocket.settimeout(4)
  226. print '\nPress enter to continue...'
  227. raw_input()
  228. done = 0
  229. while (done < 25):
  230.     if(dataWaiting(remoteSocket)):
  231.         while(dataWaiting(remoteSocket)):
  232.             try:
  233.                 message = parseMessage(remoteSocket, 'test')
  234.                 if message != None:
  235.                     print message
  236.             except Exception as e:
  237.                 print e
  238.                 remoteSocket.close()
  239.     checkConnection(remoteSocket, 0, 0)
  240.     done += 1
  241. remoteSocket.close()
  242. serverSocket.close()
  243. print '\nSockets closed.'
  244. raw_input('\nBye!')
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257. -------------------
  258. Resources.py:
  259. # IP Addresses
  260. global version
  261. version = 18
  262. global masterVersion
  263. masterVersion = 1
  264. global loginServer
  265. loginServer = ('128.241.92.162', 6800)
  266. global mapServer
  267. mapServer = ('128.241.92.102', 4500)
  268. global gameServer
  269. gameServer = [('128.241.92.131', 4500), ('128.241.92.98', 4500)]
RAW Paste Data
Pastebin PRO Summer Special!
Get 60% OFF on Pastebin PRO accounts!
Top