dfpyre 0.4.2__py3-none-any.whl → 0.10.5__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/__init__.py +3 -1
- dfpyre/core/actiondump.py +277 -0
- dfpyre/core/codeblock.py +207 -0
- dfpyre/core/items.py +580 -0
- dfpyre/core/template.py +220 -0
- dfpyre/data/actiondump_min.json +1 -0
- dfpyre/data/deprecated_actions.json +172 -0
- dfpyre/data/method_templates/action.txt +5 -0
- dfpyre/data/method_templates/conditional.txt +7 -0
- dfpyre/data/method_templates/event.txt +6 -0
- dfpyre/data/method_templates/notarget_action.txt +5 -0
- dfpyre/data/method_templates/notarget_conditional.txt +6 -0
- dfpyre/data/method_templates/repeat.txt +5 -0
- dfpyre/data/method_templates/repeat_while.txt +9 -0
- dfpyre/data/method_templates/select_obj_subaction.txt +8 -0
- dfpyre/export/action_classes.py +10891 -0
- dfpyre/export/block_functions.py +90 -0
- dfpyre/gen/action_class_data.py +203 -0
- dfpyre/gen/action_literals.py +20 -0
- dfpyre/scripts/action_gen.py +222 -0
- dfpyre/scripts/action_literal_gen.py +43 -0
- dfpyre/tool/scriptgen.py +274 -0
- dfpyre/tool/slice.py +199 -0
- dfpyre/util/style.py +23 -0
- dfpyre/util/util.py +65 -0
- dfpyre-0.10.5.dist-info/METADATA +64 -0
- dfpyre-0.10.5.dist-info/RECORD +29 -0
- {dfpyre-0.4.2.dist-info → dfpyre-0.10.5.dist-info}/WHEEL +1 -2
- {dfpyre-0.4.2.dist-info → dfpyre-0.10.5.dist-info/licenses}/LICENSE +21 -21
- dfpyre/data/data.json +0 -1
- dfpyre/items.py +0 -244
- dfpyre/pyre.py +0 -407
- dfpyre/style.py +0 -21
- dfpyre-0.4.2.dist-info/METADATA +0 -11
- dfpyre-0.4.2.dist-info/RECORD +0 -10
- dfpyre-0.4.2.dist-info/top_level.txt +0 -1
dfpyre/core/template.py
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A package for making code templates for the DiamondFire Minecraft server.
|
|
3
|
+
|
|
4
|
+
By Amp
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import datetime
|
|
9
|
+
import platform
|
|
10
|
+
from rapidnbt import CompoundTag, StringTag, DoubleTag
|
|
11
|
+
from dfpyre.util.util import df_encode, df_decode, flatten, deprecated
|
|
12
|
+
from dfpyre.core.items import *
|
|
13
|
+
from dfpyre.core.codeblock import CodeBlock, Target, TARGETS, DEFAULT_TARGET, CONDITIONAL_CODEBLOCKS, TEMPLATE_STARTERS, EVENT_CODEBLOCKS
|
|
14
|
+
from dfpyre.core.actiondump import get_default_tags
|
|
15
|
+
from dfpyre.gen.action_literals import *
|
|
16
|
+
from dfpyre.tool.scriptgen import generate_script, GeneratorFlags
|
|
17
|
+
from dfpyre.tool.slice import slice_template
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
'Target', 'CodeBlock', 'DFTemplate',
|
|
21
|
+
] + VAR_ITEM_TYPES
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
DYNAMIC_CODEBLOCKS = {'func', 'process', 'call_func', 'start_process'}
|
|
25
|
+
|
|
26
|
+
DATE_FORMAT_STR = "%b %#d, %Y" if platform.system() == "Windows" else "%b %-d, %Y"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DFTemplate:
|
|
30
|
+
"""
|
|
31
|
+
Represents a DiamondFire code template.
|
|
32
|
+
"""
|
|
33
|
+
def __init__(self, codeblocks: list[CodeBlock], author: str='pyre'):
|
|
34
|
+
self.codeblocks = codeblocks
|
|
35
|
+
self.author = author
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_template_name(self) -> str:
|
|
39
|
+
"""
|
|
40
|
+
Returns an auto-generated name for this template.
|
|
41
|
+
|
|
42
|
+
:return: Template name
|
|
43
|
+
"""
|
|
44
|
+
first_block_data = self.codeblocks[0].data
|
|
45
|
+
if 'data' in first_block_data:
|
|
46
|
+
name = first_block_data['data']
|
|
47
|
+
return name if name else 'Unnamed Template'
|
|
48
|
+
return first_block_data['block'] + '_' + first_block_data['action']
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@deprecated('Use get_template_name instead')
|
|
52
|
+
def _get_template_name(self):
|
|
53
|
+
return self.get_template_name()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def __repr__(self) -> str:
|
|
57
|
+
return f'DFTemplate(name: "{self.get_template_name()}", author: "{self.author}", codeblocks: {len(self.codeblocks)})'
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def from_code(template_code: str, preserve_item_slots: bool=True, author: str='pyre'):
|
|
62
|
+
"""
|
|
63
|
+
Create a template object from an existing template code.
|
|
64
|
+
|
|
65
|
+
:param str template_code: The base64 string to create a template from.
|
|
66
|
+
:param bool preserve_item_slots: If True, the positions of items within chests will be saved.
|
|
67
|
+
:param str author: The author of this template.
|
|
68
|
+
"""
|
|
69
|
+
template_dict = json.loads(df_decode(template_code))
|
|
70
|
+
codeblocks: list[CodeBlock] = []
|
|
71
|
+
for block_dict in template_dict['blocks']:
|
|
72
|
+
block_tags = get_default_tags(block_dict.get('block'), block_dict.get('action'))
|
|
73
|
+
if 'args' in block_dict:
|
|
74
|
+
block_args = []
|
|
75
|
+
for item_dict in block_dict['args']['items']:
|
|
76
|
+
if item_dict['item'].get('id') == 'bl_tag':
|
|
77
|
+
tag_data = item_dict['item']['data']
|
|
78
|
+
block_tags[tag_data['tag']] = tag_data['option']
|
|
79
|
+
parsed_item = item_from_dict(item_dict, preserve_item_slots)
|
|
80
|
+
if parsed_item is not None:
|
|
81
|
+
block_args.append(parsed_item)
|
|
82
|
+
|
|
83
|
+
codeblock_target = Target(TARGETS.index(block_dict['target'])) if 'target' in block_dict else DEFAULT_TARGET
|
|
84
|
+
codeblock_type = block_dict.get('block')
|
|
85
|
+
|
|
86
|
+
if codeblock_type is None:
|
|
87
|
+
codeblock = CodeBlock.new_bracket(block_dict['direct'], block_dict['type'])
|
|
88
|
+
|
|
89
|
+
elif codeblock_type == 'else':
|
|
90
|
+
codeblock = CodeBlock.new_else()
|
|
91
|
+
|
|
92
|
+
elif codeblock_type in DYNAMIC_CODEBLOCKS:
|
|
93
|
+
codeblock = CodeBlock.new_data(codeblock_type, block_dict['data'], block_args, block_tags)
|
|
94
|
+
|
|
95
|
+
elif 'action' in block_dict:
|
|
96
|
+
codeblock_action = block_dict['action']
|
|
97
|
+
attribute = block_dict.get('attribute')
|
|
98
|
+
inverted = attribute == 'NOT'
|
|
99
|
+
sub_action = block_dict.get('subAction')
|
|
100
|
+
if sub_action is not None:
|
|
101
|
+
codeblock = CodeBlock.new_subaction_block(codeblock_type, codeblock_action, block_args, block_tags, sub_action, inverted)
|
|
102
|
+
elif codeblock_type in EVENT_CODEBLOCKS:
|
|
103
|
+
ls_cancel = attribute == 'LS-CANCEL'
|
|
104
|
+
codeblock = CodeBlock.new_event(codeblock_type, codeblock_action, ls_cancel)
|
|
105
|
+
elif codeblock_type in CONDITIONAL_CODEBLOCKS:
|
|
106
|
+
codeblock = CodeBlock.new_conditional(codeblock_type, codeblock_action, block_args, block_tags, inverted, codeblock_target)
|
|
107
|
+
else:
|
|
108
|
+
codeblock = CodeBlock.new_action(codeblock_type, codeblock_action, block_args, block_tags, codeblock_target)
|
|
109
|
+
|
|
110
|
+
codeblocks.append(codeblock)
|
|
111
|
+
|
|
112
|
+
return DFTemplate(codeblocks, author)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def generate_template_item(self) -> Item:
|
|
116
|
+
"""
|
|
117
|
+
Create an item from this template.
|
|
118
|
+
|
|
119
|
+
:return: Template item
|
|
120
|
+
"""
|
|
121
|
+
template_code = self.build()
|
|
122
|
+
|
|
123
|
+
now = datetime.datetime.now()
|
|
124
|
+
name = self.get_template_name()
|
|
125
|
+
|
|
126
|
+
template_item = Item('yellow_shulker_box')
|
|
127
|
+
template_item.set_name(f'&x&f&f&5&c&0&0>> &x&f&f&c&7&0&0{name}')
|
|
128
|
+
template_item.set_lore([
|
|
129
|
+
f'&8Author: {self.author}',
|
|
130
|
+
f'&8Date: {now.strftime(DATE_FORMAT_STR)}',
|
|
131
|
+
'',
|
|
132
|
+
'&7This template was generated by &6pyre&7.',
|
|
133
|
+
'&7https://github.com/Amp63/pyre'
|
|
134
|
+
])
|
|
135
|
+
|
|
136
|
+
custom_data_tag = CompoundTag({
|
|
137
|
+
'PublicBukkitValues': CompoundTag({
|
|
138
|
+
'hypercube:codetemplatedata': StringTag(f'{{"author":"{self.author}","name":"{name}","version": 1,"code":"{template_code}"}}'),
|
|
139
|
+
'hypercube:pyre_creation_timestamp': DoubleTag(now.timestamp())
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
template_item.set_component('minecraft:custom_data', custom_data_tag)
|
|
143
|
+
|
|
144
|
+
return template_item
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def insert(self, insert_codeblocks: CodeBlock|list[CodeBlock], index: int=-1):
|
|
148
|
+
"""
|
|
149
|
+
Insert `insert_codeblocks` into this template at `index`.
|
|
150
|
+
|
|
151
|
+
:param CodeBlock|list[CodeBlock] insert_codeblocks: The block(s) to insert.
|
|
152
|
+
:param int index: The index to insert at.
|
|
153
|
+
:return: self
|
|
154
|
+
"""
|
|
155
|
+
if isinstance(insert_codeblocks, list):
|
|
156
|
+
insert_codeblocks = list(flatten(insert_codeblocks))
|
|
157
|
+
if index == -1:
|
|
158
|
+
self.codeblocks.extend(insert_codeblocks)
|
|
159
|
+
else:
|
|
160
|
+
self.codeblocks[index:index+len(insert_codeblocks)] = insert_codeblocks
|
|
161
|
+
elif isinstance(insert_codeblocks, CodeBlock):
|
|
162
|
+
if index == -1:
|
|
163
|
+
index = len(self.codeblocks)
|
|
164
|
+
self.codeblocks.insert(index, insert_codeblocks)
|
|
165
|
+
else:
|
|
166
|
+
raise PyreException('Expected CodeBlock or list[CodeBlock] to insert.')
|
|
167
|
+
return self
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def build(self) -> str:
|
|
171
|
+
"""
|
|
172
|
+
Build this template.
|
|
173
|
+
|
|
174
|
+
:return: String containing encoded template data.
|
|
175
|
+
"""
|
|
176
|
+
template_dict_blocks = [codeblock.build() for codeblock in self.codeblocks]
|
|
177
|
+
template_dict = {'blocks': template_dict_blocks}
|
|
178
|
+
first_block = template_dict_blocks[0]
|
|
179
|
+
if first_block['block'] not in TEMPLATE_STARTERS:
|
|
180
|
+
warn('Template does not start with an event, function, or process.')
|
|
181
|
+
|
|
182
|
+
json_string = json.dumps(template_dict, separators=(',', ':'))
|
|
183
|
+
return df_encode(json_string)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def build_and_send(self) -> int:
|
|
187
|
+
"""
|
|
188
|
+
Builds this template and sends it to DiamondFire automatically.
|
|
189
|
+
"""
|
|
190
|
+
template_item = self.generate_template_item()
|
|
191
|
+
return template_item.send_to_minecraft()
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def generate_script(self, indent_size: int=4, literal_shorthand: bool=True, var_shorthand: bool=False,
|
|
195
|
+
preserve_slots: bool=False, assign_variable: bool=False, include_import: bool=True,
|
|
196
|
+
build_and_send: bool=False) -> str:
|
|
197
|
+
"""
|
|
198
|
+
Generate an equivalent python script for this template.
|
|
199
|
+
|
|
200
|
+
:param int indent_size: The multiple of spaces to add when indenting lines.
|
|
201
|
+
:param bool literal_shorthand: If True, `Text` and `Number` items will be written as strings and ints respectively.
|
|
202
|
+
:param bool var_shorthand: If True, all variables will be written using variable shorthand.
|
|
203
|
+
:param bool preserve_slots: If True, the positions of items within chests will be saved.
|
|
204
|
+
:param bool assign_variable: If True, the generated template will be assigned to a variable.
|
|
205
|
+
:param bool include_import: If True, the `dfpyre` import statement will be added.
|
|
206
|
+
:param bool build_and_send: If True, `.build_and_send()` will be added to the end of the generated template.
|
|
207
|
+
"""
|
|
208
|
+
flags = GeneratorFlags(indent_size, literal_shorthand, var_shorthand, preserve_slots, assign_variable, include_import, build_and_send)
|
|
209
|
+
return generate_script(self.codeblocks, flags)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def slice(self, target_length: int) -> list['DFTemplate']:
|
|
213
|
+
"""
|
|
214
|
+
Slice the current template into multiple other templates.
|
|
215
|
+
Useful for compressing a template to fit on a smaller plot.
|
|
216
|
+
|
|
217
|
+
:param int target_length: The maximum allowed length of each sliced template.
|
|
218
|
+
"""
|
|
219
|
+
sliced_templates = slice_template(self.codeblocks, target_length, self.get_template_name())
|
|
220
|
+
return [DFTemplate(t, self.author) for t in sliced_templates]
|