rust_minecraft_server/parse_ids.py

99 lines
2.8 KiB
Python

#!/usr/bin/env python
# Использование:
#
# ./parse_ids.py < Packets.html > src/server/protocol/id.rs
import sys
from bs4 import BeautifulSoup
import re
BOUNDS = ["clientbound", "serverbound"]
MODES = {
"#Handshaking": "handshake",
"#Status": "status",
"#Login": "login",
"#Play": "play",
"#Configuration": "configuration"
}
def sanitize_name(name, bound, mode):
name = (" " + name.lower() + " ").replace(" " + bound.lower() + " ", "").replace(" " + mode.lower() + " ", "") \
if name.lower() != bound.lower() and name.lower() != mode.lower() else name
name = re.sub(r'\(.*?\)', '', name)
name = name.strip()
name = name.upper()
name = name.replace(' ', '_')
return name
def parse_packet_id_table(span):
table = span.parent.find_next_sibling("table")
if not table:
return None
rows = table.find_all("tr")
if len(rows) < 2:
return None
code_tag = rows[1].find("td").find("code")
if not code_tag:
return None
return code_tag.text.strip()
def main():
soup = BeautifulSoup(sys.stdin.read(), "html.parser")
print("/*\n")
print(" Generated with parse_ids.py \n")
print(" */\n")
toc = soup.select_one("#toc")
for bound_type in BOUNDS:
print(f"pub mod {bound_type} {{")
for li in toc.find("ul").find_all("li", recursive=False):
a = li.find("a", href=True)
if not a or a["href"] not in MODES:
continue
mode = MODES[a["href"]]
ul = li.find("ul", recursive=False)
if not ul:
continue
lis = ul.find_all("li", recursive=False)
mode_size = 0
try:
bound_list = lis[BOUNDS.index(bound_type)].find_all("li")
except KeyError:
continue
for item in bound_list:
packet_a = item.find("a", href=True)
if not packet_a or not packet_a["href"].startswith("#"):
continue
href = packet_a["href"].lstrip("#")
span = soup.find("span", id=href)
if not span:
continue
packet_id = parse_packet_id_table(span)
if not packet_id:
continue
name = sanitize_name(" ".join(packet_a.text.split(" ")[1:]), bound_type, mode)
if len(name) > 0:
mode_size += 1
if mode_size == 1:
print(f" pub mod {mode} {{")
print(f" pub const {name}: u8 = {packet_id};")
if mode_size > 0:
print(" }\n")
print("}\n")
if __name__ == "__main__":
main()