diff --git a/utils/scripts/opcode_handlers.py b/utils/scripts/opcode_handlers.py index a677142fa..ca4a00d3d 100644 --- a/utils/scripts/opcode_handlers.py +++ b/utils/scripts/opcode_handlers.py @@ -1,625 +1,657 @@ #! /usr/bin/env python # # This script generates cross-references to show associated (handled) opcodes -# between the server and client. It will generate files for each client found -# and provide some basic information..such as opcode names and values, server -# handler and whether opcodes are translated on tx/rx. +# between the server and client. It will generate files for each client and +# server found, and provide some basic information..such as opcode names and +# values, server handler and whether opcodes are translated on tx/rx, etc... # # It's currently limited to the 'Zone' server..but, can be expounded upon to -# include other servers, clients and other criteria and features. +# include other servers and clients, and other criteria and features. import os -#import pickle +# import pickle from time import time, ctime -# pipes relativistic information to the console window -VERBOSE = True +DEBUG = 1 # {0 - normal, 1 - verbose, 2 - in-depth} -# setting this to 'True' will pipe more information than you would ever want! -DEBUG = False +base_path = os.getcwd()[:-14] # '/utils/scripts' -repopath = os.getcwd()[:-14] # '/utils/scripts' +client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF'] +server_list = ['Login', 'World', 'Zone', 'UCS'] -clients = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF'] -servers = ['Login', 'World', 'Zone', 'UCS'] +client_opcodes = {} +server_opcodes = {} -clientops = {} -serverops = {} +client_encodes = {} +client_decodes = {} -encodes = [] -decodes = [] +server_handlers = {} -handlers = {} -outstreams = {} +out_files = {} def main(): print('Loading source data...') - if not loadserveropcodes(): - print('Error! Could not load server opcodes') - return - if not loadclientopcodes(): - print('Error! Could not load client opcodes') + print('Could not load client opcodes...') return - + + if not loadserveropcodes(): + print('Could not load server opcodes...') + return + if not loadclienttranslators(): - print('Error! Could not load client translators') + print('Could not load client translators...') return if not loadserverhandlers(): - print('Error! Could not load server handlers') + print('Could not load server handlers...') return print('Creating output streams...') if not createoutputdirectory(): - print('Output directory could not be created...') + print('Could not create output directory...') return - if not createoutputstreams(): - print('Error! Could not open output files') + if not openoutputfiles(): + print('Could not open output files...') return print('Parsing opcode data...') - if not parseopcodedata(): - print('Error! Could not parse opcode data') + if not parseclientopcodedata(): + print('Could not parse client opcode data...') + return + + if not parseserveropcodedata(): + print('Could not parse server opcode data...') return print('Destroying output streams...') - if not destroyoutputstreams(): - print('Error! Could not close output files') + if not closeoutputfiles(): + print('Could not close output files...') return -def loadserveropcodes(): - # Server opcodes are auto-enumerated with a starting reference of '1' - try: - value = 0 - - filename = '{0}{1}{2}'.format( - repopath, - '/common', - '/emu_oplist.h') - - if VERBOSE or DEBUG: - print(filename) - - with open(filename, 'r') as datafile: - while True: - dataline = datafile.readline() - - if not dataline: - break - - vbegin = dataline.find('OP_', 2) - vend = dataline.find(')', vbegin) - - if vbegin == -1: - continue - if vend == -1: - continue - - value += 1 - - if dataline[:1] == 'N': - serverops[dataline[vbegin:vend]] = value - - if DEBUG: - print('({0}, {1}) = {2}'.format( - 'Server', - dataline[vbegin:vend], - serverops[dataline[vbegin:vend]])) - - datafile.close() - - filename = '{0}{1}{2}'.format( - repopath, - '/common', - '/mail_oplist.h') - - if VERBOSE or DEBUG: - print(filename) - - with open(filename, 'r') as datafile: - while True: - dataline = datafile.readline() - - if not dataline: - break - - vbegin = dataline.find('OP_', 2) - vend = dataline.find(')', vbegin) - - if vbegin == -1: - continue - if vend == -1: - continue - - value += 1 - - if dataline[:1] == 'N': - serverops[dataline[vbegin:vend]] = value - - if DEBUG: - print('({0}, {1}) = {2}'.format( - 'Server', - dataline[vbegin:vend], - serverops[dataline[vbegin:vend]])) - - datafile.close() - except: - return False - - return True - - def loadclientopcodes(): - badclients = [] + bad_clients = [] - for client in clients: + for client in client_list: try: - filename = '{0}{1}{2}{3}{4}'.format( - repopath, - '/utils/patches', + short_name = '{0}{1}{2}'.format( '/patch_', client, '.conf') - - if VERBOSE or DEBUG: - print(filename) - with open(filename, 'r') as datafile: + file_name = '{0}{1}{2}'.format( + base_path, + '/utils/patches', + short_name) + + if DEBUG >= 1: + print(file_name) + + with open(file_name, 'r') as data_file: + client_opcodes[client] = {} # force empty dictionary to avoid collisions + while True: - dataline = datafile.readline() - - if not dataline: + data_line = data_file.readline() + + if not data_line: break - kbegin = dataline.find('OP_') - kend = dataline.find('=', kbegin) + key_begin = data_line.find('OP_') + key_end = data_line.find('=', key_begin) - if not kbegin == 0: - continue - if kend == -1: - continue - - vbegin = dataline.find('0x', kend) - vend = vbegin + 6 - - if vbegin == -1: + if not key_begin == 0 or key_end < 0: continue - value = int(dataline[(vbegin + 2):vend].lower(), 16) + val_begin = data_line.find('0x', key_end) + val_end = val_begin + 6 # max size is always 6 bytes + + if val_begin < 0: + continue + + value = int(data_line[(val_begin + 2):val_end].lower(), 16) if value == 0: continue - clientops[client, dataline[kbegin:kend]] = '0x{0}'.format( - hex(value)[2:].zfill(4)) - - if DEBUG: - print('({0}, {1}) = {2} (int: {3})'.format( + client_opcodes[client][data_line[key_begin:key_end]] = '0x{0}'.format(hex(value)[2:].zfill(4)) + + if DEBUG >= 2: + print('[{0}][{1}] = {2} (int: {3})'.format( client, - dataline[kbegin:kend], - clientops[client, dataline[kbegin:kend]], + data_line[key_begin:key_end], + client_opcodes[client][data_line[key_begin:key_end]], value)) - datafile.close() - except: - badclients.append(client) + data_file.close() + except: # StandardError as se: + #print(se.message) - if len(badclients) > 0: - badentries = [] - - for badclient in badclients: - if VERBOSE or DEBUG: - print('Deleting client {0} from search criteria...'.format( - badclient)) - - clients.remove(badclient) + #if DEBUG >= 2: + # print(pickle.dumps(se.args)) - if VERBOSE or DEBUG: - print('Deleting any partial entries for client {0}...'.format( - badclient)) + bad_clients.append(client) + + if len(bad_clients) > 0: + for bad_client in bad_clients: + if DEBUG >= 1: + print('Deleting \'{0}\' client from search criteria...'.format(bad_client)) - for entry in clientops.keys(): - if entry[0] == badclient: - badentries.append(entry) - - for badentry in badentries: - del clientops[badentry] + client_list.remove(bad_client) + + if DEBUG >= 1: + print('Deleting stale entries for \'{0}\' client...'.format(bad_client)) + + if bad_client in client_opcodes: + del client_opcodes[bad_client] - if len(clients) == 0: + if not len(client_list) > 0: + return False + + return True + + +def loadserveropcodes(): + try: + value = 1 # Server opcodes are auto-enumerated with a starting reference of '1' + + file_name = '{0}{1}{2}'.format( + base_path, + '/common', + '/emu_oplist.h') + + if DEBUG >= 1: + print(file_name) + + with open(file_name, 'r') as data_file: + while True: + data_line = data_file.readline() + + if not data_line: + break + + val_begin = data_line.find('OP_', 2) + val_end = data_line.find(')', val_begin) + + if val_begin < 0 or val_end < 0: + continue + + if data_line[:1] == 'N': + server_opcodes[data_line[val_begin:val_end]] = value + value += 1 + + if DEBUG >= 2: + print('N[{0}]({1}) = {2}'.format( + 'Server', + data_line[val_begin:val_end], + server_opcodes[data_line[val_begin:val_end]])) + + data_file.close() + + file_name = '{0}{1}{2}'.format( + base_path, + '/common', + '/mail_oplist.h') + + if DEBUG >= 1: + print(file_name) + + with open(file_name, 'r') as data_file: + while True: + data_line = data_file.readline() + + if not data_line: + break + + val_begin = data_line.find('OP_', 2) + val_end = data_line.find(')', val_begin) + + if val_begin < 0 or val_end < 0: + continue + + if data_line[:1] == 'N': + server_opcodes[data_line[val_begin:val_end]] = value + value += 1 + + if DEBUG >= 2: + print('N[{0}]({1}) = {2}'.format( + 'Server', + data_line[val_begin:val_end], + server_opcodes[data_line[val_begin:val_end]])) + + data_file.close() + except: # StandardError as se: + #print(se.message) + + #if DEBUG >= 2: + # print(pickle.dumps(se.args)) + return False return True def loadclienttranslators(): - for client in clients: + for client in client_list: if client == '6.2': - shortname = '{0}'.format( - '/Client62_ops.h') + short_name = '{0}'.format('/Client62_ops.h') else: - shortname = '{0}{1}{2}'.format( + short_name = '{0}{1}{2}'.format( '/', client, '_ops.h') try: - filename = '{0}{1}{2}'.format( - repopath, + file_name = '{0}{1}{2}'.format( + base_path, '/common/patches', - shortname) + short_name) - if VERBOSE or DEBUG: - print(filename) + if DEBUG >= 1: + print(file_name) + + with open(file_name, 'r') as data_file: + client_encodes[client] = [] + client_decodes[client] = [] - with open(filename, 'r') as datafile: while True: - dataline = datafile.readline() + data_line = data_file.readline() - if not dataline: + if not data_line: break - vbegin = dataline.find('OP_', 2) - vend = dataline.find(')', vbegin) + val_begin = data_line.find('OP_', 2) + val_end = data_line.find(')', val_begin) - if vbegin == -1: - continue - if vend == -1: + if val_begin < 0 or val_end < 0: continue - if dataline[:1] == 'E': - encodes.append((client, dataline[vbegin:vend])) + if data_line[:1] == 'E': + client_encodes[client].append(data_line[val_begin:val_end]) - if DEBUG: - print('ENCODE({0}, {1}) [floating index: {2}]'.format( + if DEBUG >= 2: + print('E[{0}]({1}) (listed: {2})'.format( client, - dataline[vbegin:vend], - encodes.index((client, dataline[vbegin:vend])))) - elif dataline[:1] == 'D': - decodes.append((client, dataline[vbegin:vend])) + data_line[val_begin:val_end], + data_line[val_begin:val_end] in client_encodes[client])) + elif data_line[:1] == 'D': + client_decodes[client].append(data_line[val_begin:val_end]) - if DEBUG: - print('DECODE({0}, {1}) [floating index: {2}]'.format( + if DEBUG >= 2: + print('D[{0}]({1}) (listed: {2})'.format( client, - dataline[vbegin:vend], - decodes.index((client, dataline[vbegin:vend])))) + data_line[val_begin:val_end], + data_line[val_begin:val_end] in client_decodes[client])) + + data_file.close() + except: # StandardError as se: + #print(se.message) + + #if DEBUG >= 2: + # print(pickle.dumps(se.args)) - datafile.close() - except: - # TODO: need to handle return False - # this will need to change if we ever have a client with 100% support - if len(encodes) == 0 and len(decodes) == 0: + # there's always going to be at least one client with one encode or decode + if not len(client_encodes) > 0 and not len(client_decodes) > 0: return False return True def loadserverhandlers(): - # TODO: handle remarked out definitions; add other servers, if possible - try: - filename = '{0}{1}{2}'.format( - repopath, - '/zone', - '/client_packet.cpp') - - if VERBOSE or DEBUG: - print(filename) - - with open(filename, 'r') as datafile: - dataline = datafile.readline() - - while not dataline[:19] == 'void MapOpcodes() {': - dataline = datafile.readline() - - if not dataline: - break - - while True: - dataline = datafile.readline() - - if not dataline: - break - if dataline[0:1] == '}': - break - - kbegin = dataline.find('OP_') - kend = dataline.find(']', kbegin) - - if kbegin == -1: - continue - if kend == -1: - continue - - vbegin = dataline.find('Client::', kend) - vend = dataline.find(';', vbegin) - - if vbegin == -1: - continue - if vend == -1: - continue - - handlers['Zone', dataline[kbegin:kend]] = dataline[vbegin:vend] - - if DEBUG: - print('({0}, {1}) = {2}'.format( - 'Zone', - dataline[kbegin:kend], - handlers['Zone', dataline[kbegin:kend]])) + # TODO: handle remarked out definitions in file (i.e., // and /**/); + # TODO: out-going-only handlers need to be added..more research... + bad_servers = [] - datafile.close() - except: - # should probably do the same for this (badservers) - # as done for badclients in the above function - return False + for server in server_list: + try: + if server == 'Login': + raise + elif server == 'World': + raise + elif server == 'Zone': + file_name = '{0}{1}{2}'.format( + base_path, + '/zone', + '/client_packet.cpp') + + if DEBUG >= 1: + print(file_name) + + with open(file_name, 'r') as data_file: + server_handlers[server] = {} + + data_line = data_file.readline() + + while not data_line[:19] == 'void MapOpcodes() {': + data_line = data_file.readline() + + if not data_line: + break + + while True: + data_line = data_file.readline() + + if not data_line or data_line[0:1] == '}': + break + + key_begin = data_line.find('OP_') + key_end = data_line.find(']', key_begin) + + if key_begin < 0 or key_end < 0: + continue + + val_begin = data_line.find('Client::', key_end) + val_end = data_line.find(';', val_begin) + + if val_begin < 0 or val_end < 0: + continue + + server_handlers[server][data_line[key_begin:key_end]] = data_line[val_begin:val_end] + + if DEBUG >= 2: + print('[{0}][{1}] = {2}'.format( + server, + data_line[key_begin:key_end], + server_handlers[server][data_line[key_begin:key_end]])) + + data_file.close() + elif server == 'UCS': + raise + else: + if DEBUG >= 2: + print('->LoadServerHandlers(Someone added a new server and forgot to code for the data load...)') + + return False + except: # StandardError as se: + #print(se.message) + + #if DEBUG >= 2: + # print(pickle.dumps(se.args)) + + bad_servers.append(server) + + if len(bad_servers) > 0: + for bad_server in bad_servers: + if DEBUG >= 1: + print('Deleting \'{0}\' server from search criteria...'.format(bad_server)) + + server_list.remove(bad_server) + + if DEBUG >= 1: + print('Deleting stale entries for \'{0}\' server...'.format(bad_server)) + + if bad_server in server_handlers: + del server_handlers[bad_server] + + if not len(server_list) > 0: + return False return True def createoutputdirectory(): - outputpath = '' - try: - outputpath = '{0}{1}'.format( - repopath, + output_path = '{0}{1}'.format( + base_path, '/utils/scripts/opcode_handlers_output') - if VERBOSE or DEBUG: - print(outputpath) + if DEBUG >= 1: + print(output_path) - if not os.path.exists(outputpath): - os.mkdir(outputpath) + if not os.path.exists(output_path): + os.mkdir(output_path) return True - except: + except: # StandardError as se: + #print(se.message) + + #if DEBUG >= 2: + # print(pickle.dumps(se.args)) + return False -def createoutputstreams(): - filename = '' - +def openoutputfiles(): try: - for client in clients: - filename = '{0}{1}{2}{3}'.format( - repopath, + #file_name = '{0}{1}{2}'.format( + # base_path, + # '/utils/scripts/opcode_handlers_output/', + # 'Report.txt') + + #if DEBUG >= 1: + # print(file_name) + + #out_files['Report'] = open(file_name, 'w') + + for client in client_list: + file_name = '{0}{1}{2}{3}'.format( + base_path, '/utils/scripts/opcode_handlers_output/', client, '_opcode_handlers.txt') - if VERBOSE or DEBUG: - print(filename) + if DEBUG >= 1: + print(file_name) - outstreams[client] = open(filename, 'w') + out_files[client] = open(file_name, 'w') message = \ - '------------------------------------------------------\n' \ - '|| Opcode-Handler analysis for \'{0}\' client\n' \ - '|| script-generated file @ {1}\n' \ - '||\n' \ - '|| (only cross-linked (active) opcodes are listed)\n' \ - '------------------------------------------------------\n' \ + '>> \'Opcode-Handler\' analysis for \'{0}\' client\n' \ + '>> file generated @ {1}\n' \ '\n'.format( client, ctime(time())) - outstreams[client].write(message) + out_files[client].write(message) - if DEBUG: + if DEBUG >= 2: print(message[:-2]) - except: - for client in clients: - if client in outstreams.keys(): - outstreams[client].close() - del outstreams[client] - if DEBUG: - print('->CreatingClientStream(exception): {0}'.format( - client)) - - return False + for server in server_list: + file_name = '{0}{1}{2}{3}'.format( + base_path, + '/utils/scripts/opcode_handlers_output/', + server, + '_opcode_handlers.txt') - return True + if DEBUG >= 1: + print(file_name) - -def parseopcodedata(): - serveropnames = [] - - for serveropkey in serverops.keys(): - serveropnames.append(serveropkey) - - if DEBUG: - print('->ServerOpKey: {0}'.format( - serveropkey)) - - if len(serveropnames) == 0: - return False - - for server in servers: - # Login, World, UCS not implemented yet - if not server == 'Zone': - if DEBUG: - print('->SkippingServerOpcodeParse: {0}'.format( - server)) - - continue - - handleropnames = [] - - for handlerkey in handlers.keys(): - if handlerkey[0] == server: - handleropnames.append(handlerkey[1]) - - if DEBUG: - print('->HandlerKey: {0}'.format( - handlerkey[1])) - - if len(handleropnames) == 0: - return False - else: - # sort to process opcode names in ascending order - handleropnames.sort() - - for client in clients: - clientopnames = [] - clientencodes = [] - clientdecodes = [] - - totalopcodes = 0 - encodedecode = 0 - encodeonly = 0 - decodeonly = 0 - notranslation = 0 - - for clientopkey in clientops.keys(): - if clientopkey[0] == client: - clientopnames.append(clientopkey[1]) - - if DEBUG: - print('->ClientOpKey: {0}'.format( - clientopkey[1])) - - if len(clientopnames) == 0: - return False - - for encodeentry in encodes: - if encodeentry[0] == client: - clientencodes.append(encodeentry[1]) - - if DEBUG: - print('->EncodeEntry: {0}'.format( - encodeentry[1])) - - if len(clientencodes) == 0: - return False - - for decodeentry in decodes: - if decodeentry[0] == client: - clientdecodes.append(decodeentry[1]) - - if DEBUG: - print('->DecodeEntry: {0}'.format( - decodeentry[1])) - - if len(clientdecodes) == 0: - return False - - for handleropentry in handleropnames: - try: - clientopindex = clientopnames.index(handleropentry) - except: - clientopindex = -1 - - if clientopindex > -1: - val0 = clientopnames[clientopindex] - val1 = serverops[val0] - val2 = clientops[(client, val0)] - val3 = handlers[(server, val0)] - - try: - val4 = clientencodes.index(val0) > -1 - except: - val4 = False - try: - val5 = clientdecodes.index(val0) > -1 - except: - val5 = False - - message = \ - 'Opcode: {0} | {1}: {2} | {3}: {4}\n' \ - ' {5} Handler: \'{6}\'\n' \ - ' Encoded: {7} | Decoded: {8}\n\n'.format( - val0, - server, - val1, - client, - val2, - server, - val3, - val4, - val5) - - outstreams[client].write(message) - - if DEBUG: - print(message[:-2]) - - totalopcodes += 1 - - if val4 and val5: - encodedecode += 1 - elif val4 and not val5: - encodeonly += 1 - elif not val4 and val5: - decodeonly += 1 - elif not val4 and not val5: - notranslation += 1 - - if DEBUG: - print('->EndOfOpcodeLoop: {0}'.format( - val0)) + out_files[server] = open(file_name, 'w') message = \ - 'Statistics -------------------------------------------\n' \ - '|| Server Opcode Type: {0}\n' \ - '|| Handled Opcodes: {1}\n' \ - '|| Bi-directional: {2}\n' \ - '|| Encodes Only: {3}\n' \ - '|| Decodes Only: {4}\n' \ - '|| No Translations: {5}\n' \ - '\n' \ - 'Notes ------------------------------------------------\n' \ - '|| Encodes are Server-to-Client and Decodes are' \ - ' Server-from-Client in context\n' \ - '|| \'Bi-directional\' indicates translations are performed on' \ - ' tx/rx packets\n' \ - '|| \'Encodes Only\' indicates translations only on tx packets' \ - ' - does not exclude direct packet rx\n' \ - '|| \'Decodes Only\' indicates translations only on rx packets' \ - ' - does not exclude direct packet tx\n' \ - '|| \'No Translations\' indicates no translations of tx/rx' \ - ' packets\n'.format( + '>> \'Opcode-Handler\' analysis for \'{0}\' server\n' \ + '>> file generated @ {1}\n' \ + '\n'.format( server, - totalopcodes, - encodedecode, - encodeonly, - decodeonly, - notranslation) + ctime(time())) - outstreams[client].write(message) + out_files[server].write(message) - if DEBUG: - print(message[:-1]) - print('->EndOfClientLoop: {0}'.format( - client)) - - if DEBUG: - print('->EndOfServerLoop: {0}'.format( - server)) + if DEBUG >= 2: + print(message[:-2]) + except: # StandardError as se: + #print(se.message) + + #if DEBUG >= 2: + # print(pickle.dumps(se.args)) + + for client in client_list: + if client in out_files: + out_files[client].close() + del out_files[client] + + if DEBUG >= 2: + print('->OpeningClientStream(exception): {0}'.format(client)) + + for server in server_list: + if server in out_files: + out_files[server].close() + del out_files[server] + + if DEBUG >= 2: + print('->OpeningServerStream(exception): {0}'.format(server)) + + #if 'Report' in out_files: + # out_files['Report'].close() + # del out_files['Report'] + + # if DEBUG >= 2: + # print('->OpeningReportStream(exception)') + + return False return True -def destroyoutputstreams(): - for client in clients: - if client in outstreams.keys(): - outstreams[client].close() - del outstreams[client] +def parseclientopcodedata(): + # TODO: add metrics + for client in client_list: + server_max_len = 0 + + for server in server_list: + if len(server) > server_max_len: + server_max_len = len(server) + + client_keys = client_opcodes[client].keys() + client_keys.sort() + + for client_opcode in client_keys: + handled = client_opcode in server_opcodes + + if handled is True: + encoded = client_opcode in client_encodes[client] + decoded = client_opcode in client_decodes[client] + else: + encoded = 'n/a' + decoded = 'n/a' + + message = 'Opcode: {0} ({1}) | Handled: {2} | Encoded: {3} | Decoded: {4}\n'.format( + client_opcode, + client_opcodes[client][client_opcode], + handled, + encoded, + decoded) + + for server in server_list: + if client_opcode in server_handlers[server]: + val1 = '{0}'.format(server_opcodes[client_opcode]).zfill(4) + val2 = server_handlers[server][client_opcode] + else: + val1 = '0000' + val2 = 'n/a' + + message += ' Server: {0} ({1}) | Handler: \'{2}\'\n'.format( + server.ljust(len(server) + (server_max_len - len(server)), ' '), + val1, + val2) + + if DEBUG >= 2: + print('->EndOfServerLoop: {0}'.format(server)) + + message += '\n' + + out_files[client].write(message) + + if DEBUG >= 2: + print(message[:-2]) + print('->EndOfOpcodeLoop: {0}'.format(client_opcode)) + + if DEBUG >= 2: + print('->EndOfClientLoop: {0}'.format(client)) + + return True + + +def parseserveropcodedata(): + # TODO: add metrics + for server in server_list: + client_max_len = 0 + + for client in client_list: + if len(client) > client_max_len: + client_max_len = len(client) + + handler_keys = server_handlers[server].keys() + handler_keys.sort() + + for handler_opcode in handler_keys: + message = 'Opcode: {0} ({1}) | Handler: \'{2}\'\n'.format( + handler_opcode, + server_opcodes[handler_opcode], + server_handlers[server][handler_opcode]) + + for client in client_list: + if handler_opcode in client_opcodes[client]: + val1 = client_opcodes[client][handler_opcode] + val2 = 'True' + val3 = '{0}'.format(handler_opcode in client_encodes[client]) + val4 = '{0}'.format(handler_opcode in client_decodes[client]) + else: + val1 = '0x0000' + val2 = 'False' + val3 = 'n/a' + val4 = 'n/a' + + message += ' Client: {0} ({1}) | Handled: {2} | Encoded: {3} | Decoded: {4}\n'.format( + client.ljust(len(client) + (client_max_len - len(client)), ' '), + val1, + val2.ljust(len(val2) + (len('False') - len(val2)), ' '), + val3.ljust(len(val3) + (len('False') - len(val3)), ' '), + val4.ljust(len(val4) + (len('False') - len(val4)), ' ')) + + if DEBUG >= 2: + print('->EndOfClientLoop: {0}'.format(client)) + + message += '\n' + + out_files[server].write(message) + + if DEBUG >= 2: + print(message[:-2]) + print('->EndOfOpcodeLoop: {0}'.format(handler_opcode)) + + if DEBUG >= 2: + print('->EndOfServerLoop: {0}'.format(server)) + + return True + + +def closeoutputfiles(): + for client in client_list: + if client in out_files: + out_files[client].close() + del out_files[client] + + if DEBUG >= 2: + print('->ClosingClientStream: {0}'.format(client)) + + for server in server_list: + if server in out_files: + out_files[server].close() + del out_files[server] + + if DEBUG >= 2: + print('->ClosingServerStream: {0}'.format(server)) + + #if 'Report' in out_files: + # out_files['Report'].close() + # del out_files['Report'] + + # if DEBUG >= 2: + # print('->ClosingReportStream') - if DEBUG: - print('->DestroyingClientStream: {0}'.format( - client)) - return True