Skip to content

Instantly share code, notes, and snippets.

@ewized
Created May 10, 2016 17:43
Show Gist options
  • Save ewized/7d22194ea9550fd0ef617a40df7322c6 to your computer and use it in GitHub Desktop.
Save ewized/7d22194ea9550fd0ef617a40df7322c6 to your computer and use it in GitHub Desktop.
This file will generate the packet types from the wiki.vg website
#!/usr/bin/python3
# Copyright 2016 Year4000. All Rights Reserved.
from urllib.request import urlopen
from xml.etree.ElementTree import fromstring
import re
def set_up():
""" Ask the user for the url and file name """
# protocol
protocol = input('Enter the protocol version: ')
print('Using: {}'.format(protocol))
# url
url = input('Enter the id of the wiki.vg page: ')
url = 'http://wiki.vg/index.php?oldid={}'.format(url)
print('Using: {}'.format(url))
# file_name
file_name = input('Enter the file to output to: ')
print('Using: {}'.format(file_name))
return (int(protocol), url, file_name)
def generate(xml):
""" Generate the Java constant """
line = 'public static final PacketType {} = of({}, {}, {});'
bind_map = {'client': 'OUTBOUND', 'server': 'INBOUND'}
state = xml['state'].upper()
bind = bind_map[xml['bind']]
name = '{}_{}_{}'.format(state, xml['bind'].upper(), xml['name'].upper())
hex_id = '0x' + xml['id'][2:].upper()
return line.format(name, state, bind, hex_id)
def main():
""" The driver for the generate packets """
protocol, url, file_name = set_up()
lines = [
'// Protocol',
'public static final int PROTOCOL_VERSION = {};'.format(protocol)
]
# Open the url and generate
print('Reading the webpage and generating lines')
with urlopen(url) as response:
string = response.read()
root = fromstring(string) # root is html
binding = ('client', 'server')
states = ('play', 'handshaking', 'status', 'login')
struct = {}
# find all tables that may contains the info
last_state = ''
last_bind = ''
index = 0
names = root.findall("./body//h4/span")
for table in root.findall("./body//table"):
trs = list(table)
if len(trs) > 1:
tds = list(trs[1])
order = 0
# Make sure there is id, status, and binding
if len(tds) < 3:
continue
# Find the fields we need
for elm in tds:
data = elm.text.strip().lower()
if '0x' in data and order == 0:
struct['id'] = data
order += 1
elif data in states and order == 1:
struct['state'] = data
order += 1
elif data in binding and order == 2:
struct['bind'] = data
order += 1
else:
break
# Send to generate when struct is filled
if len(struct) == 3:
# last_state comment
if last_state != struct['state']:
last_state = struct['state']
lines += ['', '// {} packets'.format(last_state).title()]
# last_bind comment
if last_bind != struct['bind']:
last_bind = struct['bind']
lines += ['// {}'.format(last_bind).title()]
# The java code
# the wiki show of a legacy packet
name = re.sub(r'[ -]', '_', names[index].text.upper())
name = re.sub(r'_\([A-Z]+\)', '', name)
struct['name'] = name
index += 1
lines += [generate(struct)]
struct = {}
# to stdout
if file_name == '--':
print('-- RESULTS (std) --')
for line in lines:
print(line)
# to file
else:
print('-- RESULTS (file) --')
with open(file_name, 'w') as file_out:
for line in lines:
file_out.write(line + '\n')
if __name__ == '__main__':
try:
main()
except BaseException as exception:
print('Could not generate packets.')
print(str(exception))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment