1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
# utilities specifically for codegen
from lib.utils import to_camel_case, to_snake_case, get_dir_location
from typing import Optional
import os
def burger_type_to_rust_type(
burger_type,
field_name: Optional[str] = None,
instruction=None,
class_name: Optional[str] = None,
):
is_var = False
uses = set()
# extra code, like enum definitions
extra_code = []
should_be_signed = False
if field_name and any(
map(
lambda w: w in {"x", "y", "z", "xa", "ya", "za"},
to_snake_case(field_name).split("_"),
)
):
# coordinates are signed
should_be_signed = True
if burger_type == "byte":
field_type_rs = "i8" if should_be_signed else "u8"
elif burger_type == "short":
field_type_rs = "i16" if should_be_signed else "u16"
elif burger_type == "int":
field_type_rs = "i32" if should_be_signed else "u32"
elif burger_type == "long":
field_type_rs = "i64" if should_be_signed else "u64"
elif burger_type == "float":
field_type_rs = "f32"
elif burger_type == "double":
field_type_rs = "f64"
elif burger_type == "varint":
is_var = True
field_type_rs = "i32" if should_be_signed else "u32"
elif burger_type == "varlong":
is_var = True
field_type_rs = "i64" if should_be_signed else "u64"
elif burger_type == "boolean":
field_type_rs = "bool"
elif burger_type == "string":
field_type_rs = "String"
elif burger_type == "chatcomponent":
field_type_rs = "FormattedText"
uses.add("azalea_chat::FormattedText")
elif burger_type == "identifier":
field_type_rs = "Identifier"
uses.add("azalea_core::identifier::Identifier")
elif burger_type == "uuid":
field_type_rs = "Uuid"
uses.add("uuid::Uuid")
elif burger_type == "position":
field_type_rs = "BlockPos"
uses.add("azalea_core::position::BlockPos")
elif burger_type == "nbtcompound":
field_type_rs = "simdnbt::owned::NbtCompound"
elif burger_type == "itemstack":
field_type_rs = "Slot"
uses.add("azalea_core::slot::Slot")
elif burger_type == "metadata":
field_type_rs = "EntityMetadata"
uses.add("azalea_entity::EntityMetadata")
elif burger_type == "bitset":
if instruction:
length = instruction["length"]
field_type_rs = f'todo!("fixed bitset of length {length}")'
else:
field_type_rs = 'todo!("fixed bitset")'
elif burger_type == "abstract":
field_type_rs = "todo!()"
elif burger_type == "interface":
# depends on context
field_type_rs = "todo!()"
elif burger_type == "Iterator":
field_type_rs = "todo!()"
elif burger_type == "Object":
# depends on context
field_type_rs = "todo!()"
elif burger_type == "enum":
if not instruction or not class_name:
field_type_rs = 'todo!("enum")'
else:
# generate the whole enum :)
print(instruction)
enum_field = instruction["field"]
# enums with a.b() as the field
if "." in enum_field:
enum_first_part_name = enum_field.split("/")[0]
print("enum_first_part_name", enum_first_part_name)
print("enum field", enum_field.split(".")[1].split("(")[0])
enum_name = enum_field.split("$")[1].split("(")[0]
print("hm", enum_name)
else:
enum_name = enum_field or class_name
print("enum_name", enum_name)
enum_obfuscated_name = enum_name
print("enum_obfuscated_name", enum_obfuscated_name)
enum_variants = []
raise RuntimeError("TODO: extracting enum variants")
enum_variants.append(field_name)
field_type_rs = to_camel_case(enum_name.split(".")[-1].split("$")[-1])
extra_code.append("")
extra_code.append("#[derive(AzBuf, Clone, Copy, Debug)]")
extra_code.append(f"pub enum {field_type_rs} {{")
for index, variant in enumerate(enum_variants):
extra_code.append(f" {to_camel_case(variant.lower())}={index},")
extra_code.append("}")
elif burger_type.endswith("[]"):
field_type_rs, is_var, uses, extra_code = burger_type_to_rust_type(
burger_type[:-2]
)
field_type_rs = f"Vec<{field_type_rs}>"
# sometimes burger gives us a slightly incorrect type
if instruction:
if field_type_rs == "Vec<u8>":
field = instruction["field"]
if field.endswith(".copy()"):
field = field[:-7]
array_type = field
if array_type == "net.minecraft.network.FriendlyByteBuf":
field_type_rs = "UnsizedByteArray"
uses.add("azalea_buf::UnsizedByteArray")
else:
print("instruction that we errored on:", instruction)
raise Exception(f"Unknown field type: {burger_type} ({class_name})")
return field_type_rs, is_var, uses, extra_code
def write_packet_file(state, packet_module_name, code):
with open(
get_dir_location(
f"../azalea-protocol/src/packets/{state}/{packet_module_name}.rs"
),
"w",
) as f:
f.write(code)
def fmt():
os.system(f"cd {get_dir_location('..')} && cargo fmt")
|