dfpyre 0.4.5__py3-none-any.whl → 0.5.0__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/data/data.json +1 -1
- dfpyre/items.py +279 -361
- dfpyre/pyre.py +405 -433
- dfpyre/style.py +22 -22
- {dfpyre-0.4.5.dist-info → dfpyre-0.5.0.dist-info}/LICENSE +21 -21
- {dfpyre-0.4.5.dist-info → dfpyre-0.5.0.dist-info}/METADATA +105 -81
- dfpyre-0.5.0.dist-info/RECORD +9 -0
- dfpyre-0.4.5.dist-info/RECORD +0 -9
- {dfpyre-0.4.5.dist-info → dfpyre-0.5.0.dist-info}/WHEEL +0 -0
dfpyre/pyre.py
CHANGED
|
@@ -1,433 +1,405 @@
|
|
|
1
|
-
"""
|
|
2
|
-
A package for externally creating code templates for the DiamondFire Minecraft server.
|
|
3
|
-
|
|
4
|
-
By Amp
|
|
5
|
-
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import base64
|
|
9
|
-
import gzip
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
from
|
|
15
|
-
import
|
|
16
|
-
from
|
|
17
|
-
from
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class Target(Enum):
|
|
39
|
-
SELECTION = 0
|
|
40
|
-
DEFAULT = 1
|
|
41
|
-
KILLER = 2
|
|
42
|
-
DAMAGER = 3
|
|
43
|
-
SHOOTER = 4
|
|
44
|
-
VICTIM = 5
|
|
45
|
-
ALL_PLAYERS = 6
|
|
46
|
-
PROJECTILE = 7
|
|
47
|
-
ALL_ENTITIES = 8
|
|
48
|
-
ALL_MOBS = 9
|
|
49
|
-
LAST_ENTITY = 10
|
|
50
|
-
|
|
51
|
-
def get_string_value(self):
|
|
52
|
-
return TARGETS[self.value]
|
|
53
|
-
|
|
54
|
-
DEFAULT_TARGET = Target.SELECTION
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class CodeBlock:
|
|
58
|
-
def __init__(self, name: str, args: Tuple=(), target: Target=DEFAULT_TARGET, data={}):
|
|
59
|
-
self.name = name
|
|
60
|
-
self.args = args
|
|
61
|
-
self.target = target
|
|
62
|
-
self.data = data
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def _warn(message):
|
|
66
|
-
print(f'{COL_WARN}! WARNING ! {message}{COL_RESET}')
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def
|
|
70
|
-
close = get_close_matches(
|
|
71
|
-
if close:
|
|
72
|
-
_warn(f'Code block name "{
|
|
73
|
-
else:
|
|
74
|
-
_warn(f'Code block name "{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def
|
|
78
|
-
|
|
79
|
-
if os.path.exists(CODEBLOCK_DATA_PATH):
|
|
80
|
-
with open(CODEBLOCK_DATA_PATH, 'r') as f:
|
|
81
|
-
|
|
82
|
-
else:
|
|
83
|
-
_warn('data.json not found -- Item tags and error checking will not work.')
|
|
84
|
-
return ({}, set(), set())
|
|
85
|
-
|
|
86
|
-
del
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
|
|
91
|
-
set(
|
|
92
|
-
set(
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
TAGDATA, TAGDATA_EXTRAS_KEYS, ALL_CODEBLOCK_NAMES =
|
|
96
|
-
|
|
97
|
-
def
|
|
98
|
-
"""
|
|
99
|
-
If inverted is true, add 'inverted': 'NOT' to data.
|
|
100
|
-
"""
|
|
101
|
-
if inverted:
|
|
102
|
-
data['inverted'] = 'NOT'
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def
|
|
106
|
-
|
|
107
|
-
for value in args:
|
|
108
|
-
if type(value) in {int, float}:
|
|
109
|
-
|
|
110
|
-
elif type(value) is str:
|
|
111
|
-
if value[0] == VAR_SHORTHAND_CHAR and value[1] in VAR_SCOPES:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
else:
|
|
115
|
-
|
|
116
|
-
else:
|
|
117
|
-
|
|
118
|
-
return tuple(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def
|
|
122
|
-
"""
|
|
123
|
-
Turns data.json tag items into DiamondFire formatted tag items
|
|
124
|
-
"""
|
|
125
|
-
|
|
126
|
-
for
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
'item': {
|
|
130
|
-
'id': 'bl_tag',
|
|
131
|
-
'data': {
|
|
132
|
-
'option':
|
|
133
|
-
'tag':
|
|
134
|
-
'action':
|
|
135
|
-
'block':
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
'slot':
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def
|
|
145
|
-
"""
|
|
146
|
-
Get tags for the specified codeblock type and name
|
|
147
|
-
"""
|
|
148
|
-
tags = None
|
|
149
|
-
if
|
|
150
|
-
tags = TAGDATA['extras'][
|
|
151
|
-
else:
|
|
152
|
-
tags = TAGDATA[
|
|
153
|
-
return
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def
|
|
157
|
-
"""
|
|
158
|
-
Builds a properly formatted block from a CodeBlock object.
|
|
159
|
-
"""
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
# add target if necessary ('Selection' is the default when 'target' is blank)
|
|
164
|
-
if
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
# add items into args
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
# check for unrecognized name, add tags
|
|
171
|
-
if
|
|
172
|
-
if
|
|
173
|
-
|
|
174
|
-
elif
|
|
175
|
-
tags =
|
|
176
|
-
if len(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def
|
|
185
|
-
"""
|
|
186
|
-
Encodes a stringified json.
|
|
187
|
-
"""
|
|
188
|
-
encodedString = gzip.compress(jsonString.encode('utf-8'))
|
|
189
|
-
return base64.b64encode(encodedString).decode('utf-8')
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
f'
|
|
207
|
-
''
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
self.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
"""
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
self.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
self.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
def
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
self.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
cmd
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
cmd = CodeBlock(name, data={'id': 'block', 'block': '
|
|
317
|
-
self.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
def
|
|
321
|
-
args =
|
|
322
|
-
cmd = CodeBlock(
|
|
323
|
-
self.
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
def
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
data
|
|
363
|
-
|
|
364
|
-
cmd
|
|
365
|
-
self.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
self.
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
def
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
self.
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
def
|
|
403
|
-
args =
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
data['subAction'] = subAction
|
|
407
|
-
cmd = CodeBlock(name, args, data=data)
|
|
408
|
-
self.codeBlocks.append(cmd)
|
|
409
|
-
self._openbracket('repeat')
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
def bracket(self, *args):
|
|
413
|
-
args = _convertDataTypes(args)
|
|
414
|
-
cmd = CodeBlock('Bracket', data={'id': 'bracket', 'direct': 'close', 'type': self.closebracket})
|
|
415
|
-
self.codeBlocks.append(cmd)
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
def control(self, name: str, *args):
|
|
419
|
-
args = _convertDataTypes(args)
|
|
420
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'control', 'action': name})
|
|
421
|
-
self.codeBlocks.append(cmd)
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
def selectObject(self, name: str, *args):
|
|
425
|
-
args = _convertDataTypes(args)
|
|
426
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'select_obj', 'action': name})
|
|
427
|
-
self.codeBlocks.append(cmd)
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
def setVariable(self, name: str, *args):
|
|
431
|
-
args = _convertDataTypes(args)
|
|
432
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'set_var', 'action': name})
|
|
433
|
-
self.codeBlocks.append(cmd)
|
|
1
|
+
"""
|
|
2
|
+
A package for externally creating code templates for the DiamondFire Minecraft server.
|
|
3
|
+
|
|
4
|
+
By Amp
|
|
5
|
+
2/24/2024
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import base64
|
|
9
|
+
import gzip
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
from difflib import get_close_matches
|
|
13
|
+
import datetime
|
|
14
|
+
from typing import Tuple, List, Dict
|
|
15
|
+
from enum import Enum
|
|
16
|
+
from mcitemlib.itemlib import Item as NbtItem
|
|
17
|
+
from dfpyre.items import *
|
|
18
|
+
|
|
19
|
+
COL_WARN = '\x1b[33m'
|
|
20
|
+
COL_RESET = '\x1b[0m'
|
|
21
|
+
COL_SUCCESS = '\x1b[32m'
|
|
22
|
+
COL_ERROR = '\x1b[31m'
|
|
23
|
+
|
|
24
|
+
CODEBLOCK_DATA_PATH = os.path.join(os.path.dirname(__file__), 'data/data.json')
|
|
25
|
+
|
|
26
|
+
VARIABLE_TYPES = {'txt', 'comp', 'num', 'item', 'loc', 'var', 'snd', 'part', 'pot', 'g_val', 'vec', 'pn_el'}
|
|
27
|
+
TEMPLATE_STARTERS = {'event', 'entity_event', 'func', 'process'}
|
|
28
|
+
|
|
29
|
+
TARGETS = ['Selection', 'Default', 'Killer', 'Damager', 'Shooter', 'Victim', 'AllPlayers', 'Projectile', 'AllEntities', 'AllMobs', 'LastEntity']
|
|
30
|
+
TARGET_CODEBLOCKS = {'player_action', 'entity_action', 'if_player', 'if_entity'}
|
|
31
|
+
|
|
32
|
+
VAR_SHORTHAND_CHAR = '$'
|
|
33
|
+
VAR_SCOPES = {'g': 'unsaved', 's': 'saved', 'l': 'local', 'i': 'line'}
|
|
34
|
+
|
|
35
|
+
CODECLIENT_URL = 'ws://localhost:31375'
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Target(Enum):
|
|
39
|
+
SELECTION = 0
|
|
40
|
+
DEFAULT = 1
|
|
41
|
+
KILLER = 2
|
|
42
|
+
DAMAGER = 3
|
|
43
|
+
SHOOTER = 4
|
|
44
|
+
VICTIM = 5
|
|
45
|
+
ALL_PLAYERS = 6
|
|
46
|
+
PROJECTILE = 7
|
|
47
|
+
ALL_ENTITIES = 8
|
|
48
|
+
ALL_MOBS = 9
|
|
49
|
+
LAST_ENTITY = 10
|
|
50
|
+
|
|
51
|
+
def get_string_value(self):
|
|
52
|
+
return TARGETS[self.value]
|
|
53
|
+
|
|
54
|
+
DEFAULT_TARGET = Target.SELECTION
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class CodeBlock:
|
|
58
|
+
def __init__(self, name: str, args: Tuple=(), target: Target=DEFAULT_TARGET, data: Dict={}):
|
|
59
|
+
self.name = name
|
|
60
|
+
self.args = args
|
|
61
|
+
self.target = target
|
|
62
|
+
self.data = data
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _warn(message):
|
|
66
|
+
print(f'{COL_WARN}! WARNING ! {message}{COL_RESET}')
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _warn_unrecognized_name(codeblock_type: str, codeblock_name: str):
|
|
70
|
+
close = get_close_matches(codeblock_name, TAGDATA[codeblock_type].keys())
|
|
71
|
+
if close:
|
|
72
|
+
_warn(f'Code block name "{codeblock_name}" not recognized. Did you mean "{close[0]}"?')
|
|
73
|
+
else:
|
|
74
|
+
_warn(f'Code block name "{codeblock_name}" not recognized. Try spell checking or retyping without spaces.')
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _load_codeblock_data() -> Tuple:
|
|
78
|
+
tag_data = {}
|
|
79
|
+
if os.path.exists(CODEBLOCK_DATA_PATH):
|
|
80
|
+
with open(CODEBLOCK_DATA_PATH, 'r') as f:
|
|
81
|
+
tag_data = json.load(f)
|
|
82
|
+
else:
|
|
83
|
+
_warn('data.json not found -- Item tags and error checking will not work.')
|
|
84
|
+
return ({}, set(), set())
|
|
85
|
+
|
|
86
|
+
del tag_data['meta']
|
|
87
|
+
|
|
88
|
+
all_names = [x for l in [d.keys() for d in tag_data.values()] for x in l] # flatten list
|
|
89
|
+
return (
|
|
90
|
+
tag_data,
|
|
91
|
+
set(tag_data['extras'].keys()),
|
|
92
|
+
set(all_names)
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
TAGDATA, TAGDATA_EXTRAS_KEYS, ALL_CODEBLOCK_NAMES = _load_codeblock_data()
|
|
96
|
+
|
|
97
|
+
def _add_inverted(data, inverted):
|
|
98
|
+
"""
|
|
99
|
+
If inverted is true, add 'inverted': 'NOT' to data.
|
|
100
|
+
"""
|
|
101
|
+
if inverted:
|
|
102
|
+
data['inverted'] = 'NOT'
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _convert_data_types(args):
|
|
106
|
+
converted_args = []
|
|
107
|
+
for value in args:
|
|
108
|
+
if type(value) in {int, float}:
|
|
109
|
+
converted_args.append(num(value))
|
|
110
|
+
elif type(value) is str:
|
|
111
|
+
if value[0] == VAR_SHORTHAND_CHAR and value[1] in VAR_SCOPES:
|
|
112
|
+
var_object = var(value[2:], VAR_SCOPES[value[1]])
|
|
113
|
+
converted_args.append(var_object)
|
|
114
|
+
else:
|
|
115
|
+
converted_args.append(text(value))
|
|
116
|
+
else:
|
|
117
|
+
converted_args.append(value)
|
|
118
|
+
return tuple(converted_args)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _reformat_codeblock_tags(tags, codeblock_type: str, codeblock_name: str):
|
|
122
|
+
"""
|
|
123
|
+
Turns data.json tag items into DiamondFire formatted tag items
|
|
124
|
+
"""
|
|
125
|
+
reformatted_tags = []
|
|
126
|
+
for tag_item in tags:
|
|
127
|
+
action_value = codeblock_name if 'action' not in tag_item else tag_item['action']
|
|
128
|
+
new_tag_item = {
|
|
129
|
+
'item': {
|
|
130
|
+
'id': 'bl_tag',
|
|
131
|
+
'data': {
|
|
132
|
+
'option': tag_item['option'],
|
|
133
|
+
'tag': tag_item['tag'],
|
|
134
|
+
'action': action_value,
|
|
135
|
+
'block': codeblock_type
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
'slot': tag_item['slot']
|
|
139
|
+
}
|
|
140
|
+
reformatted_tags.append(new_tag_item)
|
|
141
|
+
return reformatted_tags
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _get_codeblock_tags(codeblock_type: str, codeblock_name: str):
|
|
145
|
+
"""
|
|
146
|
+
Get tags for the specified codeblock type and name
|
|
147
|
+
"""
|
|
148
|
+
tags = None
|
|
149
|
+
if codeblock_type in TAGDATA_EXTRAS_KEYS:
|
|
150
|
+
tags = TAGDATA['extras'][codeblock_type]
|
|
151
|
+
else:
|
|
152
|
+
tags = TAGDATA[codeblock_type].get(codeblock_name)
|
|
153
|
+
return _reformat_codeblock_tags(tags, codeblock_type, codeblock_name)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _build_block(codeblock: CodeBlock, include_tags: bool):
|
|
157
|
+
"""
|
|
158
|
+
Builds a properly formatted block from a CodeBlock object.
|
|
159
|
+
"""
|
|
160
|
+
final_block = codeblock.data.copy()
|
|
161
|
+
codeblock_type = codeblock.data.get('block')
|
|
162
|
+
|
|
163
|
+
# add target if necessary ('Selection' is the default when 'target' is blank)
|
|
164
|
+
if codeblock_type in TARGET_CODEBLOCKS and codeblock.target != DEFAULT_TARGET:
|
|
165
|
+
final_block['target'] = codeblock.target.get_string_value()
|
|
166
|
+
|
|
167
|
+
# add items into args
|
|
168
|
+
final_args = [arg.format(slot) for slot, arg in enumerate(codeblock.args) if arg.type in VARIABLE_TYPES]
|
|
169
|
+
|
|
170
|
+
# check for unrecognized name, add tags
|
|
171
|
+
if codeblock_type is not None: # for brackets
|
|
172
|
+
if codeblock_type not in TAGDATA_EXTRAS_KEYS and codeblock.name not in ALL_CODEBLOCK_NAMES:
|
|
173
|
+
_warn_unrecognized_name(codeblock_type, codeblock.name)
|
|
174
|
+
elif include_tags:
|
|
175
|
+
tags = _get_codeblock_tags(codeblock_type, codeblock.name)
|
|
176
|
+
if len(final_args) + len(tags) > 27:
|
|
177
|
+
final_args = final_args[:(27-len(tags))] # trim list if over 27 elements
|
|
178
|
+
final_args.extend(tags) # add tags to end
|
|
179
|
+
|
|
180
|
+
final_block['args'] = {'items': final_args}
|
|
181
|
+
return final_block
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _df_encode(jsonString: str) -> str:
|
|
185
|
+
"""
|
|
186
|
+
Encodes a stringified json.
|
|
187
|
+
"""
|
|
188
|
+
encodedString = gzip.compress(jsonString.encode('utf-8'))
|
|
189
|
+
return base64.b64encode(encodedString).decode('utf-8')
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _get_template_item(template_code: str, name: str, author: str) -> NbtItem:
|
|
193
|
+
now = datetime.datetime.now()
|
|
194
|
+
|
|
195
|
+
template_item = NbtItem('yellow_shulker_box')
|
|
196
|
+
template_item.set_name(f'&x&f&f&5&c&0&0>> &x&f&f&c&7&0&0{name}')
|
|
197
|
+
template_item.set_lore([
|
|
198
|
+
f'&8Author: {author}',
|
|
199
|
+
f'&8Date: {now.strftime("%Y-%m-%d")}',
|
|
200
|
+
'',
|
|
201
|
+
'&7This template was generated by &6pyre&7.',
|
|
202
|
+
'&7https://github.com/Amp63/pyre'
|
|
203
|
+
])
|
|
204
|
+
|
|
205
|
+
pbv_tag = {
|
|
206
|
+
'hypercube:codetemplatedata': f'{{"author":"{author}","name":"{name}","version": 1,"code":"{template_code}"}}',
|
|
207
|
+
'hypercube:pyre_creation_timestamp': now.timestamp()
|
|
208
|
+
}
|
|
209
|
+
template_item.set_tag('PublicBukkitValues', pbv_tag, raw=True)
|
|
210
|
+
|
|
211
|
+
return template_item
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class DFTemplate:
|
|
215
|
+
"""
|
|
216
|
+
Represents a DiamondFire code template.
|
|
217
|
+
"""
|
|
218
|
+
def __init__(self, name: str=None, author: str='pyre'):
|
|
219
|
+
self.codeblocks: List[CodeBlock] = []
|
|
220
|
+
self.closebracket = None
|
|
221
|
+
self.name = name
|
|
222
|
+
self.author = author
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _set_template_name(self, first_block):
|
|
226
|
+
if self.name is not None:
|
|
227
|
+
return
|
|
228
|
+
if 'data' in first_block:
|
|
229
|
+
self.name = first_block['data']
|
|
230
|
+
if not self.name:
|
|
231
|
+
self.name = 'Unnamed Template'
|
|
232
|
+
else:
|
|
233
|
+
self.name = first_block['block'] + '_' + first_block['action']
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def build(self, include_tags: bool=True) -> str:
|
|
237
|
+
"""
|
|
238
|
+
Build this template.
|
|
239
|
+
|
|
240
|
+
:param bool includeTags: If True, include item tags in code blocks. Otherwise omit them.
|
|
241
|
+
:return: String containing encoded template data.
|
|
242
|
+
"""
|
|
243
|
+
template_dict_blocks = [_build_block(codeblock, include_tags) for codeblock in self.codeblocks]
|
|
244
|
+
template_dict = {'blocks': template_dict_blocks}
|
|
245
|
+
first_block = template_dict_blocks[0]
|
|
246
|
+
if first_block['block'] not in TEMPLATE_STARTERS:
|
|
247
|
+
_warn('Template does not start with an event, function, or process.')
|
|
248
|
+
|
|
249
|
+
self._set_template_name(first_block)
|
|
250
|
+
|
|
251
|
+
print(f'{COL_SUCCESS}Template built successfully.{COL_RESET}')
|
|
252
|
+
|
|
253
|
+
json_string = json.dumps(template_dict, separators=(',', ':'))
|
|
254
|
+
return _df_encode(json_string)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def build_and_send(self, method: Literal['recode', 'codeclient'], includeTags: bool=True) -> int:
|
|
258
|
+
"""
|
|
259
|
+
Builds this template and sends it to DiamondFire automatically.
|
|
260
|
+
|
|
261
|
+
:param bool includeTags: If True, include item tags in code blocks. Otherwise omit them.
|
|
262
|
+
"""
|
|
263
|
+
templateCode = self.build(includeTags)
|
|
264
|
+
templateItem = _get_template_item(templateCode, self.name, self.author)
|
|
265
|
+
return templateItem.send_to_minecraft(method)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def clear(self):
|
|
269
|
+
"""
|
|
270
|
+
Clears this template's data.
|
|
271
|
+
"""
|
|
272
|
+
self.__init__()
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _openbracket(self, btype: Literal['norm', 'repeat']='norm'):
|
|
276
|
+
bracket = CodeBlock('Bracket', data={'id': 'bracket', 'direct': 'open', 'type': btype})
|
|
277
|
+
self.codeblocks.append(bracket)
|
|
278
|
+
self.closebracket = btype
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# command methods
|
|
282
|
+
def player_event(self, name: str):
|
|
283
|
+
cmd = CodeBlock(name, data={'id': 'block', 'block': 'event', 'action': name})
|
|
284
|
+
self.codeblocks.append(cmd)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def entity_event(self, name: str):
|
|
288
|
+
cmd = CodeBlock(name, data={'id': 'block', 'block': 'entity_event', 'action': name})
|
|
289
|
+
self.codeblocks.append(cmd)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def function(self, name: str, *args):
|
|
293
|
+
args = _convert_data_types(args)
|
|
294
|
+
cmd = CodeBlock('function', args, data={'id': 'block', 'block': 'func', 'data': name})
|
|
295
|
+
self.codeblocks.append(cmd)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def process(self, name: str):
|
|
299
|
+
cmd = CodeBlock('process', data={'id': 'block', 'block': 'process', 'data': name})
|
|
300
|
+
self.codeblocks.append(cmd)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def call_function(self, name: str, *args):
|
|
304
|
+
args = _convert_data_types(args)
|
|
305
|
+
cmd = CodeBlock('call_func', args, data={'id': 'block', 'block': 'call_func', 'data': name})
|
|
306
|
+
self.codeblocks.append(cmd)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def start_process(self, name: str):
|
|
310
|
+
cmd = CodeBlock('start_process', data={'id': 'block', 'block': 'start_process', 'data': name})
|
|
311
|
+
self.codeblocks.append(cmd)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def player_action(self, name: str, *args, target: Target=DEFAULT_TARGET):
|
|
315
|
+
args = _convert_data_types(args)
|
|
316
|
+
cmd = CodeBlock(name, args, target=target, data={'id': 'block', 'block': 'player_action', 'action': name})
|
|
317
|
+
self.codeblocks.append(cmd)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def game_action(self, name: str, *args):
|
|
321
|
+
args = _convert_data_types(args)
|
|
322
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'game_action', 'action': name})
|
|
323
|
+
self.codeblocks.append(cmd)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def entity_action(self, name: str, *args, target: Target=DEFAULT_TARGET):
|
|
327
|
+
args = _convert_data_types(args)
|
|
328
|
+
cmd = CodeBlock(name, args, target=target, data={'id': 'block', 'block': 'entity_action', 'action': name})
|
|
329
|
+
self.codeblocks.append(cmd)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def if_player(self, name: str, *args, target: Target=DEFAULT_TARGET, inverted: bool=False):
|
|
333
|
+
args = _convert_data_types(args)
|
|
334
|
+
data = {'id': 'block', 'block': 'if_player', 'action': name}
|
|
335
|
+
_add_inverted(data, inverted)
|
|
336
|
+
cmd = CodeBlock(name, args, target=target, data=data)
|
|
337
|
+
self.codeblocks.append(cmd)
|
|
338
|
+
self._openbracket()
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def if_variable(self, name: str, *args, inverted: bool=False):
|
|
342
|
+
args = _convert_data_types(args)
|
|
343
|
+
data = {'id': 'block', 'block': 'if_var', 'action': name}
|
|
344
|
+
_add_inverted(data, inverted)
|
|
345
|
+
cmd = CodeBlock(name, args, data=data)
|
|
346
|
+
self.codeblocks.append(cmd)
|
|
347
|
+
self._openbracket()
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def if_game(self, name: str, *args, inverted: bool=False):
|
|
351
|
+
args = _convert_data_types(args)
|
|
352
|
+
data = {'id': 'block', 'block': 'if_game', 'action': name}
|
|
353
|
+
_add_inverted(data, inverted)
|
|
354
|
+
cmd = CodeBlock(name, args, data=data)
|
|
355
|
+
self.codeblocks.append(cmd)
|
|
356
|
+
self._openbracket()
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def if_entity(self, name: str, *args, target: Target=DEFAULT_TARGET, inverted: bool=False):
|
|
360
|
+
args = _convert_data_types(args)
|
|
361
|
+
data = {'id': 'block', 'block': 'if_entity', 'action': name}
|
|
362
|
+
_add_inverted(data, inverted)
|
|
363
|
+
cmd = CodeBlock(name, args, target=target, data=data)
|
|
364
|
+
self.codeblocks.append(cmd)
|
|
365
|
+
self._openbracket()
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def else_(self):
|
|
369
|
+
cmd = CodeBlock('else', data={'id': 'block', 'block': 'else'})
|
|
370
|
+
self.codeblocks.append(cmd)
|
|
371
|
+
self._openbracket()
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def repeat(self, name: str, *args, sub_action: str=None):
|
|
375
|
+
args = _convert_data_types(args)
|
|
376
|
+
data = {'id': 'block', 'block': 'repeat', 'action': name}
|
|
377
|
+
if sub_action is not None:
|
|
378
|
+
data['subAction'] = sub_action
|
|
379
|
+
cmd = CodeBlock(name, args, data=data)
|
|
380
|
+
self.codeblocks.append(cmd)
|
|
381
|
+
self._openbracket('repeat')
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def bracket(self, *args):
|
|
385
|
+
args = _convert_data_types(args)
|
|
386
|
+
cmd = CodeBlock('Bracket', data={'id': 'bracket', 'direct': 'close', 'type': self.closebracket})
|
|
387
|
+
self.codeblocks.append(cmd)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def control(self, name: str, *args):
|
|
391
|
+
args = _convert_data_types(args)
|
|
392
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'control', 'action': name})
|
|
393
|
+
self.codeblocks.append(cmd)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def select_object(self, name: str, *args):
|
|
397
|
+
args = _convert_data_types(args)
|
|
398
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'select_obj', 'action': name})
|
|
399
|
+
self.codeblocks.append(cmd)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def set_variable(self, name: str, *args):
|
|
403
|
+
args = _convert_data_types(args)
|
|
404
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'set_var', 'action': name})
|
|
405
|
+
self.codeblocks.append(cmd)
|