dfpyre 0.4.6__py3-none-any.whl → 0.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dfpyre might be problematic. Click here for more details.

dfpyre/scriptgen.py ADDED
@@ -0,0 +1,193 @@
1
+ import dataclasses
2
+ import re
3
+ from dfpyre.items import *
4
+ from dfpyre.actiondump import get_default_tags
5
+
6
+
7
+ SCRIPT_START = '''from dfpyre import *\n\n'''
8
+
9
+ TEMPLATE_FUNCTION_LOOKUP = {
10
+ 'event': 'player_event',
11
+ 'entity_event': 'entity_event',
12
+ 'func': 'function',
13
+ 'process': 'process',
14
+ 'call_func': 'call_function',
15
+ 'start_process': 'start_process',
16
+ 'player_action': 'player_action',
17
+ 'game_action': 'game_action',
18
+ 'entity_action': 'entity_action',
19
+ 'if_player': 'if_player',
20
+ 'if_var': 'if_variable',
21
+ 'if_game': 'if_game',
22
+ 'if_entity': 'if_entity',
23
+ 'else': 'else_',
24
+ 'repeat': 'repeat',
25
+ 'control': 'control',
26
+ 'select_obj': 'select_object',
27
+ 'set_var': 'set_variable'
28
+ }
29
+
30
+ TARGET_CODEBLOCKS = {'player_action', 'entity_action', 'if_player', 'if_entity'}
31
+ CONTAINER_CODEBLOCKS = {'event', 'entity_event', 'func', 'process', 'if_player', 'if_entity', 'if_game', 'if_var', 'else', 'repeat'}
32
+ VAR_SCOPES = {'unsaved': 'g', 'saved': 's', 'local': 'l', 'line': 'i'}
33
+
34
+
35
+ @dataclasses.dataclass
36
+ class GeneratorFlags:
37
+ indent_size: int
38
+ literal_shorthand: bool
39
+ var_shorthand: bool
40
+
41
+
42
+ def item_to_string(class_name: str, i: Item):
43
+ i.nbt.data.pop('~DF_NBT', None)
44
+ stripped_id = i.get_id().replace('minecraft:', '')
45
+ if i.nbt.key_set() == {'~id', '~count'}:
46
+ if i.get_count() == 1:
47
+ return f'{class_name}("{stripped_id}")'
48
+ return f'{class_name}("{stripped_id}", {i.get_count()})'
49
+ return f'{class_name}.from_nbt("""{i.get_nbt()}""")'
50
+
51
+
52
+ def argument_item_to_string(flags: GeneratorFlags, arg_item: object) -> str:
53
+ class_name = arg_item.__class__.__name__
54
+ if isinstance(arg_item, Item):
55
+ return item_to_string(class_name, arg_item)
56
+
57
+ if isinstance(arg_item, String):
58
+ value = arg_item.value.replace('\n', '\\n')
59
+ return f'{class_name}("{value}")'
60
+
61
+ if isinstance(arg_item, Text):
62
+ value = arg_item.value.replace('\n', '\\n')
63
+ if flags.literal_shorthand:
64
+ return f'"{value}"'
65
+ return f'{class_name}("{value}")'
66
+
67
+ if isinstance(arg_item, Number):
68
+ if not re.match(NUMBER_REGEX, str(arg_item.value)):
69
+ return f'{class_name}("{arg_item.value}")'
70
+ if flags.literal_shorthand:
71
+ return str(arg_item.value)
72
+ return f'{class_name}({arg_item.value})'
73
+
74
+ if isinstance(arg_item, Location):
75
+ loc_components = [arg_item.x, arg_item.y, arg_item.z]
76
+ if arg_item.pitch != 0:
77
+ loc_components.append(arg_item.pitch)
78
+ if arg_item.yaw != 0:
79
+ loc_components.append(arg_item.yaw)
80
+ return f'{class_name}({", ".join(str(c) for c in loc_components)})'
81
+
82
+ if isinstance(arg_item, Variable):
83
+ if flags.var_shorthand:
84
+ return f'"${VAR_SCOPES[arg_item.scope]} {arg_item.name}"'
85
+ if arg_item.scope == 'unsaved':
86
+ return f'{class_name}("{arg_item.name}")'
87
+ return f'{class_name}("{arg_item.name}", "{arg_item.scope}")'
88
+
89
+ if isinstance(arg_item, Sound):
90
+ return f'{class_name}("{arg_item.name}", {arg_item.pitch}, {arg_item.vol})'
91
+
92
+ if isinstance(arg_item, Particle):
93
+ return f'{class_name}({arg_item.particle_data})'
94
+
95
+ if isinstance(arg_item, Potion):
96
+ return f'{class_name}("{arg_item.name}", {arg_item.dur}, {arg_item.amp})'
97
+
98
+ if isinstance(arg_item, GameValue):
99
+ if arg_item.target == 'Default':
100
+ return f'{class_name}("{arg_item.name}")'
101
+ return f'{class_name}("{arg_item.name}", "{arg_item.target}")'
102
+
103
+ if isinstance(arg_item, Parameter):
104
+ param_type_class_name = arg_item.param_type.__class__.__name__
105
+ param_args = [f'"{arg_item.name}"', f'{param_type_class_name}.{arg_item.param_type.name}']
106
+ if arg_item.plural:
107
+ param_args.append('plural=True')
108
+ if arg_item.optional:
109
+ param_args.append('optional=True')
110
+ if arg_item.default_value is not None:
111
+ param_args.append(f'default_value={argument_item_to_string(flags, arg_item.default_value)}')
112
+ if arg_item.description:
113
+ param_args.append(f'description="{arg_item.description}"')
114
+ if arg_item.note:
115
+ param_args.append(f'note="{arg_item.note}"')
116
+ return f'{class_name}({", ".join(param_args)})'
117
+
118
+ if isinstance(arg_item, Vector):
119
+ return f'{class_name}({arg_item.x}, {arg_item.y}, {arg_item.z})'
120
+
121
+
122
+ def add_script_line(flags: GeneratorFlags, script_lines: list[str], indent_level: int, line: str, add_comma: bool=True):
123
+ added_line = ' '*flags.indent_size*indent_level + line
124
+ if add_comma and indent_level > 0:
125
+ added_line += ','
126
+ script_lines.append(added_line)
127
+
128
+
129
+ def generate_script(template, flags: GeneratorFlags) -> str:
130
+ indent_level = 0
131
+ script_lines = []
132
+
133
+ def remove_comma_from_last_line():
134
+ script_lines[-1] = script_lines[-1][:-1]
135
+
136
+ for codeblock in template.codeblocks:
137
+ # Handle closing brackets
138
+ if codeblock.type == 'bracket':
139
+ if codeblock.data['direct'] == 'close':
140
+ remove_comma_from_last_line()
141
+ indent_level -= 1
142
+ add_script_line(flags, script_lines, indent_level, '])')
143
+ continue
144
+
145
+ # Get codeblock function and start its arguments with the action
146
+ function_name = TEMPLATE_FUNCTION_LOOKUP[codeblock.type]
147
+ function_args = [f'"{codeblock.action_name}"']
148
+
149
+ # Set function or process name if necessary
150
+ if codeblock.action_name == 'dynamic':
151
+ function_args[0] = f'"{codeblock.data["data"]}"'
152
+
153
+ # Convert argument objects to valid Python strings
154
+ codeblock_args = [argument_item_to_string(flags, i) for i in codeblock.args]
155
+ if codeblock_args:
156
+ function_args.extend(codeblock_args)
157
+
158
+ # Add target if necessary
159
+ if function_name in TARGET_CODEBLOCKS and codeblock.target.name != 'SELECTION':
160
+ function_args.append(f'target=Target.{codeblock.target.name}')
161
+
162
+ # Add tags
163
+ if codeblock.tags:
164
+ default_tags = get_default_tags(codeblock.data.get('block'), codeblock.action_name)
165
+ written_tags = {t: o for t, o in codeblock.tags.items() if default_tags[t] != o}
166
+ if written_tags:
167
+ function_args.append(f'tags={str(written_tags)}')
168
+
169
+ # Add sub-action for repeat
170
+ if codeblock.data.get('subAction'):
171
+ function_args.append(f'sub_action="{codeblock.data["subAction"]}"')
172
+
173
+ # Add inversion for NOT
174
+ if codeblock.data.get('attribute') == 'NOT':
175
+ function_args.append('inverted=True')
176
+
177
+ if codeblock.type in CONTAINER_CODEBLOCKS:
178
+ if codeblock.type == 'else':
179
+ line = f'{function_name}(['
180
+ elif codeblock.type in {'event', 'entity_event'}:
181
+ line = f'{function_name}({", ".join(function_args)}, [' # omit `codeblocks=` when we don't need it
182
+ else:
183
+ line = f'{function_name}({", ".join(function_args)}, codeblocks=['
184
+ add_script_line(flags, script_lines, indent_level, line, False)
185
+ indent_level += 1
186
+ else:
187
+ line = f'{function_name}({", ".join(function_args)})'
188
+ add_script_line(flags, script_lines, indent_level, line)
189
+
190
+ remove_comma_from_last_line()
191
+ indent_level -= 1
192
+ add_script_line(flags, script_lines, indent_level, '])') # add final closing brackets
193
+ return SCRIPT_START + '\n'.join(script_lines)
dfpyre/style.py CHANGED
@@ -1,22 +1,22 @@
1
1
  import re
2
2
  from mcitemlib.style import STYLE_CODE_REGEX, FORMAT_CODES, StyledString
3
3
 
4
- def isAmpersandCoded(s: str) -> bool:
4
+ def is_ampersand_coded(s: str) -> bool:
5
5
  return bool(re.match(STYLE_CODE_REGEX, s))
6
6
 
7
7
 
8
- def ampersandToMinimessage(ampersand_code: str) -> str:
8
+ def ampersand_to_minimessage(ampersand_code: str) -> str:
9
9
  ampersand_code = ampersand_code.replace('&r', '<reset>') # bad but should work most of the time
10
- styledString = StyledString.from_codes(ampersand_code)
11
- formattedStringList = []
12
- for substring in styledString.substrings:
13
- formattedSubstringList = []
14
- for styleType, value in substring.data.items():
15
- if styleType in FORMAT_CODES.values() and value:
16
- formattedSubstringList.append(f'<{styleType}>')
17
- if styleType == 'color':
18
- formattedSubstringList.append(f'<{value}>')
10
+ styled_string = StyledString.from_codes(ampersand_code)
11
+ formatted_string_list = []
12
+ for substring in styled_string.substrings:
13
+ formatted_substring_list = []
14
+ for style_type, value in substring.data.items():
15
+ if style_type in FORMAT_CODES.values() and value:
16
+ formatted_substring_list.append(f'<{style_type}>')
17
+ if style_type == 'color':
18
+ formatted_substring_list.append(f'<{value}>')
19
19
 
20
- formattedSubstringList.append(substring.data['text'])
21
- formattedStringList.append(''.join(formattedSubstringList))
22
- return ''.join(formattedStringList)
20
+ formatted_substring_list.append(substring.data['text'])
21
+ formatted_string_list.append(''.join(formatted_substring_list))
22
+ return ''.join(formatted_string_list)
dfpyre/util.py ADDED
@@ -0,0 +1,39 @@
1
+ import base64
2
+ import gzip
3
+
4
+
5
+ COL_WARN = '\x1b[33m'
6
+ COL_RESET = '\x1b[0m'
7
+ COL_SUCCESS = '\x1b[32m'
8
+ COL_ERROR = '\x1b[31m'
9
+
10
+
11
+ class PyreException(Exception):
12
+ pass
13
+
14
+
15
+ def warn(message: str):
16
+ print(f'{COL_WARN}! WARNING ! {message}{COL_RESET}')
17
+
18
+
19
+ def df_encode(json_string: str) -> str:
20
+ """
21
+ Encodes a stringified json.
22
+ """
23
+ encoded_string = gzip.compress(json_string.encode('utf-8'))
24
+ return base64.b64encode(encoded_string).decode('utf-8')
25
+
26
+
27
+ def df_decode(encoded_string: str) -> str:
28
+ return gzip.decompress(base64.b64decode(encoded_string)).decode('utf-8')
29
+
30
+
31
+ def flatten(nested_list: list):
32
+ """
33
+ Flattens a list.
34
+ """
35
+ for item in nested_list:
36
+ if isinstance(item, list):
37
+ yield from flatten(item)
38
+ else:
39
+ yield item
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Amp
3
+ Copyright (c) 2024 Amp
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal