Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Resources, socket, sys, struct, select
- from time import sleep
- """
- BASIC NETWORK HANDLING.
- PARSING PACKETS, SENDING LOGIN PACKETS OR OTHERS, ET CETERA.
- """
- #Resets remoteSocket so it can be used in a new connection.
- def resetRemoteSocket():
- global remoteSocket
- try:
- remoteSocket.close()
- except:
- pass
- remoteSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- remoteSocket.settimeout(4)
- return remoteSocket
- #Sends login to main server,
- #which then responds with server info such as server names and populations.
- def sendMasterLogin(socket, username, password):
- global connectionState
- socket = resetRemoteSocket()
- Connection(socket, 'login')
- 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)
- encrypt(socket, msg)
- connectionState = 2
- #Sends login to game server,
- #which then responds with info such as characters and their stats.
- def sendGameLogin(socket, accountID, sessionID, sex):
- global connectionState
- socket = resetRemoteSocket()
- try:
- serverChoice = int(raw_input('Please choose a server:\n'))
- except Exception as e:
- print 'Error in sendGameLogin.'
- print e
- sys.exit()
- Connection(socket, serverChoice)
- 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)))
- encrypt(socket, msg)
- connectionState = 3
- #Sends
- def sendCharChoice(socket, choice):
- msg = str(struct.pack('B'*3, 102, 0, int(choice)))
- encrypt(socket, msg)
- #Sends
- def sendMapLogin():
- pass
- #Called at a high frequency. Handles connections for things like logging in.
- #(Eventually:) Also handles keep alive packets to maintain connections.
- def checkConnection(socket, host, port):
- global connectionState, accountID, servers
- if(connectionState == 1):
- global username, password
- sendMasterLogin(socket, username, password)
- elif(connectionState == 2 and accountID != '' and servers):
- global sessionID, accountSex
- sendGameLogin(socket, accountID, sessionID, accountSex)
- elif(connectionState == 3):
- pass
- else:
- pass
- #Forms a connection with the socket to any server.
- #If an integer is supplied, it connects to a specific server. (Debugging purposes)
- def Connection(socket, server):
- global connectionState
- if(server == 'login'):
- try:
- socket.connect(Resources.loginServer)
- print 'Connecting to iRO login server...\n'
- connectionState = 2
- except Exception as e:
- print 'Error connecting to login server.'
- print e
- sys.exit()
- elif(server >= 1):
- try:
- socket.connect(Resources.gameServer[server - 1])
- print '\nConnected to game server\n'
- connectionState = 3
- except Exception as e:
- print 'Error connecting to game server'
- print e
- sys.exit()
- elif(server == 'char'):
- try:
- socket.connect(Resources.mapServer[0])
- print '\nConnected to map server\n'
- except Exception as e:
- print 'Error connecting to map server'
- print e
- sys.exit()
- else:
- pass
- #Sends messages. Encrypts if needed.
- #(Encryptions to be added as they're discovered).
- #Created in case the server adds encryption or bot needs to be transferred.
- def encrypt(socket, msg):
- try:
- socket.send(msg)
- except:
- print 'Error in encrypt'
- sys.exit()
- #Determines if there's any data sent by the server waiting to be read.
- #Closes socket upon errors.
- def dataWaiting(socket):
- try:
- readable = select.select([socket], [], [], 0.2)
- if socket in readable[0]:
- return True
- else:
- return False
- except:
- socket.close()
- sys.exit()
- #Handles all messages sent by server to client.
- #Uses initial two hex values (switch) to determine what the data is for.
- def parseMessage(socket, msg):
- global accountID, remoteSocket
- received = (socket.recv(30000)).encode('hex')
- switch = received[0:4]
- if(switch == '6900'):
- global sessionID, accountSex
- sessionID = received[8:16].decode('hex')
- accountID = received[16:24].decode('hex')
- accountSex = received[92:]
- if(accountSex == '01'):
- gender = 'Male'
- else:
- gender = 'Female'
- 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'
- return None
- elif(switch == '80f1'):
- global servers
- servers = []
- start = 12
- for i in range(0, len(received) / 64):
- serverName = received[start:start+32].replace('00', '').decode('hex')
- serverPopulation = struct.unpack('<h', received[start+40:start+44].decode('hex'))[0]
- servers.append([serverName, serverPopulation])
- start += 64
- for i in range(0, len(servers)):
- print '-------Server ' + str(i+1) + '-------\n' + str(servers[i][0]) + ':' + str(servers[i][1]) + '\n----------------------\n'
- return None
- elif(switch == '8100'):
- print 'Account disconnected. Please try again.'
- return None
- elif(received == accountID.encode('hex')):
- return None
- elif(switch == '2d08'):
- encrypt(socket, 'a109'.decode('hex'))
- return None
- elif(switch == '9d09'):
- characters = []
- start = 164
- for i in range(0, len(received) / 288):
- charName = received[start:start+32]
- STR = received[start+48:start+50]
- AGI = received[start+50:start+52]
- VIT = received[start+52:start+54]
- INT = received[start+54:start+56]
- DEX = received[start+56:start+58]
- LUK = received[start+58:start+60]
- mapName = received[start+68:start+132].decode('hex').split('\x00')[0]
- charID = received[start+60:start+62]
- characters.append([charName, STR, AGI, VIT, INT, DEX, LUK, mapName, charID])
- start += 288
- for i in range(0, len(characters)):
- 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'
- choice = str(raw_input('Please choose a character\'s ID:\n'))
- sendCharChoice(remoteSocket, choice)
- return None
- elif(switch == '7100'):
- charID = received[4:12]
- mapName = received[12:44].decode('hex')
- print 'CharID: ' + str(charID)
- print 'Map: ' + str(mapName)
- return None
- return received
- """
- ABSTRACTION.
- THINGS LIKE READING MAP FILES TO SEE WHERE YOU CAN WALK.
- PROCESSING GENERAL GAME DATA.
- """
- #Views map fld files and returns a value corresponding to a tile's attributes.
- #0 = walkable, 1 = water, ...
- def mapBlockValue(field, x, y, Routing):
- map = open('Fields/'+field+'.fld', 'rb')
- width = map.read(2)
- width = struct.unpack('<h', width)[0]
- height = map.read(2)
- height = struct.unpack('<h', height)[0]
- map.seek((width * y + x) + 4)
- value = struct.unpack('B', map.read(1))[0]
- return value
- """
- MAIN CODE.
- IT'S THE MAIN CODE.
- """
- username = raw_input('Username: \n')
- password = raw_input('Password: \n')
- connectionState = 1
- sessionID = ''
- accountID = ''
- accountSex = ''
- socket.setdefaulttimeout(5)
- serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- serverSocket.settimeout(2)
- serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- serverSocket.bind((socket.gethostname(), 0))
- serverSocket.listen(5)
- remoteSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- remoteSocket.settimeout(4)
- print '\nPress enter to continue...'
- raw_input()
- done = 0
- while (done < 25):
- if(dataWaiting(remoteSocket)):
- while(dataWaiting(remoteSocket)):
- try:
- message = parseMessage(remoteSocket, 'test')
- if message != None:
- print message
- except Exception as e:
- print e
- remoteSocket.close()
- checkConnection(remoteSocket, 0, 0)
- done += 1
- remoteSocket.close()
- serverSocket.close()
- print '\nSockets closed.'
- raw_input('\nBye!')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement