Poodletooth-iLand/tools/write_patcher.py
2015-03-03 17:10:12 -05:00

137 lines
4.6 KiB
Python

#!/usr/bin/env python2
import hashlib
import os
import argparse
import xml.etree.ElementTree as ET
parser = argparse.ArgumentParser()
parser.add_argument('--build-dir', default='build',
help='The directory of the Toontown Unlimited build.')
parser.add_argument('--dest-dir', default='.',
help='The directory in which to store the patcher.')
parser.add_argument('--output', default='patcher.xml',
help='The name of the output file.')
parser.add_argument('--launcher-version', default='unlimited-dev',
help='The current version of the Toontown Unlimited launcher.')
parser.add_argument('--account-server', default='toontownunlimited.com',
help='The address of the Toontown Unlimited account server.')
parser.add_argument('--client-agent', default='192.99.200.107',
help='The IP address of the Client Agent to connect to.')
parser.add_argument('--server-version', default='unlimited-dev',
help='The current version of the Toontown Unlimited game.')
parser.add_argument('--resources-revision', default='',
help='The current revision of the resources repository.')
parser.add_argument('includes', nargs='*', default=['GameData.bin'],
help='The files to include in the main directory.')
args = parser.parse_args()
def getFileMD5Hash(filepath):
md5 = hashlib.md5()
readBlock = lambda: f.read(128 * md5.block_size)
with open(filepath, 'rb') as f:
for chunk in iter(readBlock, b''):
md5.update(chunk)
return md5.hexdigest()
def getFileInfo(filepath):
return (
os.path.basename(filepath),
os.path.getsize(filepath),
getFileMD5Hash(filepath)
)
rootFiles = []
panda3dFiles = []
for include in args.includes:
filepath = os.path.join(args.build_dir, include)
if os.path.dirname(include) == 'panda3d':
panda3dFiles.append(getFileInfo(filepath))
else:
rootFiles.append(getFileInfo(filepath))
print 'Including...', include
resourcesFiles = []
resourcesDir = os.path.join(args.build_dir, 'resources')
for filename in os.listdir(resourcesDir):
if not filename.startswith('phase_'):
continue
if not filename.endswith('.mf'):
continue
filepath = os.path.join(resourcesDir, filename)
resourcesFiles.append(getFileInfo(filepath))
print 'Including...', filename
print 'Writing %s...' % args.output
# First, add the element:
patcher = ET.Element('patcher')
# Next, add the Toontown Unlimited launcher version:
launcher_version = ET.SubElement(patcher, 'launcher-version')
launcher_version.text = args.launcher_version
# Then add the account server address:
account_server = ET.SubElement(patcher, 'account-server')
account_server.text = args.account_server
# Then add the Client Agent IP:
client_agent = ET.SubElement(patcher, 'client-agent')
client_agent.text = args.client_agent
# Next, add the server version:
server_version = ET.SubElement(patcher, 'server-version')
server_version.text = args.server_version
# Next, add the resources revision:
resources_revision = ET.SubElement(patcher, 'resources-revision')
resources_revision.text = args.resources_revision
# Next, add the root directory:
root = ET.SubElement(patcher, 'directory')
root.set('name', '')
# Add all of the root files:
for filename, size, hash in rootFiles:
_filename = ET.SubElement(root, 'file')
_filename.set('name', filename)
_size = ET.SubElement(_filename, 'size')
_size.text = str(size)
_hash = ET.SubElement(_filename, 'hash')
_hash.text = str(hash)
# Next, add the panda3d directory:
panda3dRoot = ET.SubElement(patcher, 'directory')
panda3dRoot.set('name', 'panda3d')
# Add all of the panda3d files:
for filename, size, hash in panda3dFiles:
_filename = ET.SubElement(panda3dRoot, 'file')
_filename.set('name', filename)
_size = ET.SubElement(_filename, 'size')
_size.text = str(size)
_hash = ET.SubElement(_filename, 'hash')
_hash.text = str(hash)
# Next, add the resources directory:
resourcesRoot = ET.SubElement(patcher, 'directory')
resourcesRoot.set('name', 'resources')
# Add all of the resources files:
for filename, size, hash in resourcesFiles:
_filename = ET.SubElement(resourcesRoot, 'file')
_filename.set('name', filename)
_size = ET.SubElement(_filename, 'size')
_size.text = str(size)
_hash = ET.SubElement(_filename, 'hash')
_hash.text = str(hash)
# Finally, write the patcher.xml file:
filepath = os.path.join(args.dest_dir, args.output)
ET.ElementTree(patcher).write(filepath)
print 'Done writing %s.' % args.output