blockmine 1.19.1 → 1.21.0
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.
- package/.claude/settings.local.json +23 -0
- package/CHANGELOG.md +23 -0
- package/backend/src/core/BotManager.js +34 -4
- package/backend/src/core/BotProcess.js +8 -0
- package/backend/src/core/BreakLoopSignal.js +8 -0
- package/backend/src/core/EventGraphManager.js +5 -0
- package/backend/src/core/GraphExecutionEngine.js +37 -629
- package/backend/src/core/NodeRegistry.js +146 -2
- package/backend/src/core/nodes/action_bot_look_at.js +36 -0
- package/backend/src/core/nodes/action_bot_set_variable.js +32 -0
- package/backend/src/core/nodes/action_http_request.js +98 -0
- package/backend/src/core/nodes/action_send_log.js +23 -0
- package/backend/src/core/nodes/action_send_message.js +32 -0
- package/backend/src/core/nodes/array_add_element.js +23 -0
- package/backend/src/core/nodes/array_contains.js +40 -0
- package/backend/src/core/nodes/array_find_index.js +23 -0
- package/backend/src/core/nodes/array_get_by_index.js +23 -0
- package/backend/src/core/nodes/array_get_random_element.js +32 -0
- package/backend/src/core/nodes/array_remove_by_index.js +30 -0
- package/backend/src/core/nodes/bot_get_position.js +20 -0
- package/backend/src/core/nodes/data_array_literal.js +31 -0
- package/backend/src/core/nodes/data_boolean_literal.js +21 -0
- package/backend/src/core/nodes/data_cast.js +34 -0
- package/backend/src/core/nodes/data_get_argument.js +23 -0
- package/backend/src/core/nodes/data_get_bot_look.js +14 -0
- package/backend/src/core/nodes/data_get_entity_field.js +18 -0
- package/backend/src/core/nodes/data_get_server_players.js +18 -0
- package/backend/src/core/nodes/data_get_user_field.js +40 -0
- package/backend/src/core/nodes/data_get_variable.js +23 -0
- package/backend/src/core/nodes/data_length.js +25 -0
- package/backend/src/core/nodes/data_make_object.js +31 -0
- package/backend/src/core/nodes/data_number_literal.js +21 -0
- package/backend/src/core/nodes/data_string_literal.js +34 -0
- package/backend/src/core/nodes/debug_log.js +16 -0
- package/backend/src/core/nodes/flow_branch.js +15 -0
- package/backend/src/core/nodes/flow_break.js +14 -0
- package/backend/src/core/nodes/flow_for_each.js +39 -0
- package/backend/src/core/nodes/flow_sequence.js +16 -0
- package/backend/src/core/nodes/flow_switch.js +47 -0
- package/backend/src/core/nodes/flow_while.js +64 -0
- package/backend/src/core/nodes/logic_compare.js +33 -0
- package/backend/src/core/nodes/logic_operation.js +35 -0
- package/backend/src/core/nodes/math_operation.js +31 -0
- package/backend/src/core/nodes/math_random_number.js +43 -0
- package/backend/src/core/nodes/object_create.js +40 -0
- package/backend/src/core/nodes/object_delete.js +26 -0
- package/backend/src/core/nodes/object_get.js +23 -0
- package/backend/src/core/nodes/object_has_key.js +30 -0
- package/backend/src/core/nodes/object_set.js +27 -0
- package/backend/src/core/nodes/string_concat.js +27 -0
- package/backend/src/core/nodes/string_contains.js +41 -0
- package/backend/src/core/nodes/string_ends_with.js +43 -0
- package/backend/src/core/nodes/string_equals.js +36 -0
- package/backend/src/core/nodes/string_length.js +36 -0
- package/backend/src/core/nodes/string_matches.js +39 -0
- package/backend/src/core/nodes/string_split.js +37 -0
- package/backend/src/core/nodes/string_starts_with.js +43 -0
- package/backend/src/core/nodes/user_check_blacklist.js +37 -0
- package/backend/src/core/nodes/user_get_groups.js +36 -0
- package/backend/src/core/nodes/user_get_permissions.js +36 -0
- package/backend/src/core/nodes/user_set_blacklist.js +37 -0
- package/frontend/dist/assets/index-B9GedHEa.js +8352 -0
- package/frontend/dist/assets/index-zLiy9MDx.css +1 -0
- package/frontend/dist/index.html +2 -2
- package/frontend/package.json +1 -0
- package/nul +0 -0
- package/package.json +1 -1
- package/.kiro/steering/product.md +0 -27
- package/.kiro/steering/structure.md +0 -89
- package/.kiro/steering/tech.md +0 -94
- package/frontend/dist/assets/index-BFd7YoAj.css +0 -1
- package/frontend/dist/assets/index-DxdxTe6I.js +0 -8352
|
@@ -232,6 +232,7 @@ class NodeRegistry {
|
|
|
232
232
|
category: 'Поток',
|
|
233
233
|
description: 'if/else логика',
|
|
234
234
|
graphType: all,
|
|
235
|
+
executor: require('./nodes/flow_branch').execute,
|
|
235
236
|
pins: {
|
|
236
237
|
inputs: [
|
|
237
238
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -250,6 +251,7 @@ class NodeRegistry {
|
|
|
250
251
|
category: 'Поток',
|
|
251
252
|
description: 'Выполняет действия по очереди',
|
|
252
253
|
graphType: all,
|
|
254
|
+
executor: require('./nodes/flow_sequence').execute,
|
|
253
255
|
pins: {
|
|
254
256
|
inputs: [
|
|
255
257
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true }
|
|
@@ -267,6 +269,7 @@ class NodeRegistry {
|
|
|
267
269
|
category: 'Поток',
|
|
268
270
|
description: 'Выполняет "Тело цикла" для каждого элемента в "Массиве".',
|
|
269
271
|
graphType: all,
|
|
272
|
+
executor: require('./nodes/flow_for_each').execute,
|
|
270
273
|
pins: {
|
|
271
274
|
inputs: [
|
|
272
275
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -281,12 +284,34 @@ class NodeRegistry {
|
|
|
281
284
|
}
|
|
282
285
|
});
|
|
283
286
|
|
|
287
|
+
this.registerNodeType({
|
|
288
|
+
type: 'flow:while',
|
|
289
|
+
label: '🔁 Цикл While',
|
|
290
|
+
category: 'Поток',
|
|
291
|
+
description: 'Выполняет "Тело цикла" пока условие истинно.',
|
|
292
|
+
graphType: all,
|
|
293
|
+
executor: require('./nodes/flow_while').execute,
|
|
294
|
+
evaluator: require('./nodes/flow_while').evaluate,
|
|
295
|
+
pins: {
|
|
296
|
+
inputs: [
|
|
297
|
+
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
298
|
+
{ id: 'condition', name: 'Условие', type: 'Boolean', required: true }
|
|
299
|
+
],
|
|
300
|
+
outputs: [
|
|
301
|
+
{ id: 'loop_body', name: 'Тело цикла', type: 'Exec' },
|
|
302
|
+
{ id: 'iteration', name: 'Итерация', type: 'Number' },
|
|
303
|
+
{ id: 'completed', name: 'Завершено', type: 'Exec' }
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
284
308
|
this.registerNodeType({
|
|
285
309
|
type: 'flow:break',
|
|
286
310
|
label: '🛑 Выйти из цикла',
|
|
287
311
|
category: 'Поток',
|
|
288
312
|
description: 'Немедленно прерывает выполнение цикла (For Each Loop) и передает управление на его выход Completed.',
|
|
289
313
|
graphType: all,
|
|
314
|
+
executor: require('./nodes/flow_break').execute,
|
|
290
315
|
pins: {
|
|
291
316
|
inputs: [
|
|
292
317
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true }
|
|
@@ -299,8 +324,10 @@ class NodeRegistry {
|
|
|
299
324
|
type: 'action:send_message',
|
|
300
325
|
label: '🗣️ Отправить сообщение',
|
|
301
326
|
category: 'Действия',
|
|
302
|
-
description: 'Отправляет сообщение в
|
|
327
|
+
description: 'Отправляет сообщение в чат. Поддерживает переменные в формате {varName}',
|
|
303
328
|
graphType: all,
|
|
329
|
+
dynamicPins: true,
|
|
330
|
+
executor: require('./nodes/action_send_message').execute,
|
|
304
331
|
pins: {
|
|
305
332
|
inputs: [
|
|
306
333
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -320,6 +347,7 @@ class NodeRegistry {
|
|
|
320
347
|
category: 'Действия',
|
|
321
348
|
description: 'Отправляет сообщение в консоль на странице бота.',
|
|
322
349
|
graphType: all,
|
|
350
|
+
executor: require('./nodes/action_send_log').execute,
|
|
323
351
|
pins: {
|
|
324
352
|
inputs: [
|
|
325
353
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -337,6 +365,7 @@ class NodeRegistry {
|
|
|
337
365
|
category: 'Действия',
|
|
338
366
|
description: 'Поворачивает голову бота в сторону координат или сущности.',
|
|
339
367
|
graphType: all,
|
|
368
|
+
executor: require('./nodes/action_bot_look_at').execute,
|
|
340
369
|
pins: {
|
|
341
370
|
inputs: [
|
|
342
371
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -355,6 +384,7 @@ class NodeRegistry {
|
|
|
355
384
|
category: 'Действия',
|
|
356
385
|
description: 'Сохраняет значение в переменную графа.',
|
|
357
386
|
graphType: all,
|
|
387
|
+
executor: require('./nodes/action_bot_set_variable').execute,
|
|
358
388
|
pins: {
|
|
359
389
|
inputs: [
|
|
360
390
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -368,12 +398,41 @@ class NodeRegistry {
|
|
|
368
398
|
}
|
|
369
399
|
});
|
|
370
400
|
|
|
401
|
+
this.registerNodeType({
|
|
402
|
+
type: 'action:http_request',
|
|
403
|
+
label: '🌐 HTTP-запрос',
|
|
404
|
+
category: 'Действия',
|
|
405
|
+
description: 'Выполняет HTTP-запрос (GET, POST, PUT, DELETE и т.д.) и возвращает ответ.',
|
|
406
|
+
graphType: all,
|
|
407
|
+
executor: require('./nodes/action_http_request').execute,
|
|
408
|
+
pins: {
|
|
409
|
+
inputs: [
|
|
410
|
+
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
411
|
+
{ id: 'url', name: 'URL', type: 'String', required: true },
|
|
412
|
+
{ id: 'method', name: 'Метод', type: 'String', required: false },
|
|
413
|
+
{ id: 'headers', name: 'Заголовки (JSON)', type: 'String', required: false },
|
|
414
|
+
{ id: 'body', name: 'Тело (JSON)', type: 'Wildcard', required: false },
|
|
415
|
+
{ id: 'timeout', name: 'Таймаут (мс)', type: 'Number', required: false }
|
|
416
|
+
],
|
|
417
|
+
outputs: [
|
|
418
|
+
{ id: 'exec', name: 'Успех', type: 'Exec' },
|
|
419
|
+
{ id: 'exec_error', name: 'Ошибка', type: 'Exec' },
|
|
420
|
+
{ id: 'status', name: 'Статус', type: 'Number' },
|
|
421
|
+
{ id: 'response', name: 'Ответ', type: 'Wildcard' },
|
|
422
|
+
{ id: 'response_headers', name: 'Заголовки ответа', type: 'Object' },
|
|
423
|
+
{ id: 'success', name: 'Успешно', type: 'Boolean' },
|
|
424
|
+
{ id: 'error', name: 'Ошибка', type: 'String' }
|
|
425
|
+
]
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
|
|
371
429
|
this.registerNodeType({
|
|
372
430
|
type: 'data:get_argument',
|
|
373
431
|
label: '📥 Получить аргумент',
|
|
374
432
|
category: 'Данные',
|
|
375
433
|
description: 'Получает значение аргумента команды по его имени.',
|
|
376
434
|
graphType: command,
|
|
435
|
+
evaluator: require('./nodes/data_get_argument').evaluate,
|
|
377
436
|
data: {
|
|
378
437
|
argumentName: {
|
|
379
438
|
type: 'argument',
|
|
@@ -395,6 +454,7 @@ class NodeRegistry {
|
|
|
395
454
|
category: 'Данные',
|
|
396
455
|
description: 'Получает значение переменной графа.',
|
|
397
456
|
graphType: all,
|
|
457
|
+
evaluator: require('./nodes/data_get_variable').evaluate,
|
|
398
458
|
pins: {
|
|
399
459
|
inputs: [],
|
|
400
460
|
outputs: [
|
|
@@ -409,6 +469,7 @@ class NodeRegistry {
|
|
|
409
469
|
category: 'Данные',
|
|
410
470
|
description: 'Получает определенное поле из объекта сущности (например, "position.x", "username").',
|
|
411
471
|
graphType: all,
|
|
472
|
+
evaluator: require('./nodes/data_get_entity_field').evaluate,
|
|
412
473
|
pins: {
|
|
413
474
|
inputs: [
|
|
414
475
|
{ id: 'entity', name: 'Сущность', type: 'Object', required: true },
|
|
@@ -426,8 +487,10 @@ class NodeRegistry {
|
|
|
426
487
|
type: 'data:string_literal',
|
|
427
488
|
label: '📜 Строка',
|
|
428
489
|
category: 'Данные',
|
|
429
|
-
description: '
|
|
490
|
+
description: 'Текстовое значение с поддержкой переменных. Используйте {имя} для вставки значений.',
|
|
430
491
|
graphType: all,
|
|
492
|
+
dynamicPins: true,
|
|
493
|
+
evaluator: require('./nodes/data_string_literal').evaluate,
|
|
431
494
|
pins: {
|
|
432
495
|
inputs: [],
|
|
433
496
|
outputs: [
|
|
@@ -442,6 +505,7 @@ class NodeRegistry {
|
|
|
442
505
|
category: 'Данные',
|
|
443
506
|
description: 'Простое числовое значение.',
|
|
444
507
|
graphType: all,
|
|
508
|
+
evaluator: require('./nodes/data_number_literal').evaluate,
|
|
445
509
|
pins: {
|
|
446
510
|
inputs: [
|
|
447
511
|
{ id: 'value', name: 'Значение', type: 'Number', required: true }
|
|
@@ -458,6 +522,7 @@ class NodeRegistry {
|
|
|
458
522
|
category: 'Данные',
|
|
459
523
|
description: 'Значение Истина/Ложь.',
|
|
460
524
|
graphType: all,
|
|
525
|
+
evaluator: require('./nodes/data_boolean_literal').evaluate,
|
|
461
526
|
pins: {
|
|
462
527
|
inputs: [
|
|
463
528
|
{ id: 'value', name: 'Значение', type: 'Boolean', required: true }
|
|
@@ -475,6 +540,7 @@ class NodeRegistry {
|
|
|
475
540
|
description: 'Создает массив из элементов.',
|
|
476
541
|
graphType: all,
|
|
477
542
|
dynamicPins: true,
|
|
543
|
+
evaluator: require('./nodes/data_array_literal').evaluate,
|
|
478
544
|
pins: {
|
|
479
545
|
inputs: [],
|
|
480
546
|
outputs: [
|
|
@@ -490,6 +556,7 @@ class NodeRegistry {
|
|
|
490
556
|
description: 'Создает JSON-объект из пар ключ-значение.',
|
|
491
557
|
graphType: all,
|
|
492
558
|
dynamicPins: true,
|
|
559
|
+
evaluator: require('./nodes/data_make_object').evaluate,
|
|
493
560
|
pins: {
|
|
494
561
|
inputs: [],
|
|
495
562
|
outputs: [
|
|
@@ -504,6 +571,7 @@ class NodeRegistry {
|
|
|
504
571
|
category: 'Данные',
|
|
505
572
|
description: 'Приводит входящее значение к указанному целевому типу.',
|
|
506
573
|
graphType: all,
|
|
574
|
+
evaluator: require('./nodes/data_cast').evaluate,
|
|
507
575
|
pins: {
|
|
508
576
|
inputs: [
|
|
509
577
|
{ id: 'value', name: 'Значение', type: 'Wildcard', required: true }
|
|
@@ -520,6 +588,7 @@ class NodeRegistry {
|
|
|
520
588
|
category: 'Массив',
|
|
521
589
|
graphType: 'all',
|
|
522
590
|
description: 'Возвращает количество элементов в массиве или длину строки.',
|
|
591
|
+
evaluator: require('./nodes/data_length').evaluate,
|
|
523
592
|
pins: {
|
|
524
593
|
inputs: [
|
|
525
594
|
{ id: 'data', name: 'Массив или Строка', type: 'Any', required: true }
|
|
@@ -536,6 +605,8 @@ class NodeRegistry {
|
|
|
536
605
|
category: 'Строки',
|
|
537
606
|
description: 'Проверяет, содержит ли одна строка другую.',
|
|
538
607
|
graphType: all,
|
|
608
|
+
executor: require('./nodes/string_contains').execute,
|
|
609
|
+
evaluator: require('./nodes/string_contains').evaluate,
|
|
539
610
|
pins: {
|
|
540
611
|
inputs: [
|
|
541
612
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -550,12 +621,35 @@ class NodeRegistry {
|
|
|
550
621
|
}
|
|
551
622
|
});
|
|
552
623
|
|
|
624
|
+
this.registerNodeType({
|
|
625
|
+
type: 'string:matches',
|
|
626
|
+
label: '🔎 Строка: Совпадает с RegEx',
|
|
627
|
+
category: 'Строки',
|
|
628
|
+
description: 'Проверяет, совпадает ли строка с регулярным выражением.',
|
|
629
|
+
graphType: all,
|
|
630
|
+
executor: require('./nodes/string_matches').execute,
|
|
631
|
+
evaluator: require('./nodes/string_matches').evaluate,
|
|
632
|
+
pins: {
|
|
633
|
+
inputs: [
|
|
634
|
+
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
635
|
+
{ id: 'string', name: 'Строка', type: 'String', required: true },
|
|
636
|
+
{ id: 'regex', name: 'RegEx', type: 'String', required: true }
|
|
637
|
+
],
|
|
638
|
+
outputs: [
|
|
639
|
+
{ id: 'exec', name: 'Exec', type: 'Exec' },
|
|
640
|
+
{ id: 'result', name: 'Результат', type: 'Boolean' }
|
|
641
|
+
]
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
|
|
553
645
|
this.registerNodeType({
|
|
554
646
|
type: 'string:equals',
|
|
555
647
|
label: 'Строка: Равно',
|
|
556
648
|
category: 'Строки',
|
|
557
649
|
description: 'Проверяет, равны ли строки (с учетом/без учета регистра).',
|
|
558
650
|
graphType: all,
|
|
651
|
+
executor: require('./nodes/string_equals').execute,
|
|
652
|
+
evaluator: require('./nodes/string_equals').evaluate,
|
|
559
653
|
pins: {
|
|
560
654
|
inputs: [
|
|
561
655
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -576,6 +670,8 @@ class NodeRegistry {
|
|
|
576
670
|
category: 'Строки',
|
|
577
671
|
description: 'Проверяет, начинается ли строка с указанной подстроки.',
|
|
578
672
|
graphType: all,
|
|
673
|
+
executor: require('./nodes/string_starts_with').execute,
|
|
674
|
+
evaluator: require('./nodes/string_starts_with').evaluate,
|
|
579
675
|
pins: {
|
|
580
676
|
inputs: [
|
|
581
677
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -596,6 +692,8 @@ class NodeRegistry {
|
|
|
596
692
|
category: 'Строки',
|
|
597
693
|
description: 'Проверяет, заканчивается ли строка указанной подстрокой.',
|
|
598
694
|
graphType: all,
|
|
695
|
+
executor: require('./nodes/string_ends_with').execute,
|
|
696
|
+
evaluator: require('./nodes/string_ends_with').evaluate,
|
|
599
697
|
pins: {
|
|
600
698
|
inputs: [
|
|
601
699
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -616,6 +714,8 @@ class NodeRegistry {
|
|
|
616
714
|
category: 'Строки',
|
|
617
715
|
description: 'Возвращает количество символов в строке.',
|
|
618
716
|
graphType: all,
|
|
717
|
+
executor: require('./nodes/string_length').execute,
|
|
718
|
+
evaluator: require('./nodes/string_length').evaluate,
|
|
619
719
|
pins: {
|
|
620
720
|
inputs: [
|
|
621
721
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -634,6 +734,8 @@ class NodeRegistry {
|
|
|
634
734
|
category: 'Строки',
|
|
635
735
|
description: 'Разделяет строку на массив подстрок по разделителю.',
|
|
636
736
|
graphType: all,
|
|
737
|
+
executor: require('./nodes/string_split').execute,
|
|
738
|
+
evaluator: require('./nodes/string_split').evaluate,
|
|
637
739
|
pins: {
|
|
638
740
|
inputs: [
|
|
639
741
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -654,6 +756,7 @@ class NodeRegistry {
|
|
|
654
756
|
description: 'Объединяет две или более строки в одну.',
|
|
655
757
|
graphType: all,
|
|
656
758
|
dynamicPins: true,
|
|
759
|
+
evaluator: require('./nodes/string_concat').evaluate,
|
|
657
760
|
pins: {
|
|
658
761
|
inputs: [],
|
|
659
762
|
outputs: [
|
|
@@ -668,6 +771,7 @@ class NodeRegistry {
|
|
|
668
771
|
category: 'Математика',
|
|
669
772
|
description: 'Выполняет математическую операцию над двумя числами.',
|
|
670
773
|
graphType: all,
|
|
774
|
+
evaluator: require('./nodes/math_operation').evaluate,
|
|
671
775
|
pins: {
|
|
672
776
|
inputs: [
|
|
673
777
|
{ id: 'a', name: 'A', type: 'Number', required: true },
|
|
@@ -686,6 +790,7 @@ class NodeRegistry {
|
|
|
686
790
|
description: 'Выполняет логическую операцию. Для НЕ (NOT) используется только вход А.',
|
|
687
791
|
graphType: all,
|
|
688
792
|
dynamicPins: true,
|
|
793
|
+
evaluator: require('./nodes/logic_operation').evaluate,
|
|
689
794
|
pins: {
|
|
690
795
|
inputs: [
|
|
691
796
|
{ id: 'a', name: 'A', type: 'Boolean', required: true },
|
|
@@ -703,6 +808,7 @@ class NodeRegistry {
|
|
|
703
808
|
category: 'Отладка',
|
|
704
809
|
description: 'Выводит значение в консоль терминала, где запущен бот.',
|
|
705
810
|
graphType: all,
|
|
811
|
+
executor: require('./nodes/debug_log').execute,
|
|
706
812
|
pins: {
|
|
707
813
|
inputs: [
|
|
708
814
|
{ id: 'exec', name: 'Exec', type: 'Exec' },
|
|
@@ -720,6 +826,7 @@ class NodeRegistry {
|
|
|
720
826
|
category: 'Математика',
|
|
721
827
|
graphType: 'all',
|
|
722
828
|
description: 'Генерирует случайное число в заданном диапазоне.',
|
|
829
|
+
evaluator: require('./nodes/math_random_number').evaluate,
|
|
723
830
|
pins: {
|
|
724
831
|
inputs: [
|
|
725
832
|
{ id: 'min', name: 'Мин', type: 'Number' },
|
|
@@ -735,6 +842,7 @@ class NodeRegistry {
|
|
|
735
842
|
category: 'Массив',
|
|
736
843
|
graphType: 'all',
|
|
737
844
|
description: 'Возвращает случайный элемент из массива и его индекс.',
|
|
845
|
+
evaluator: require('./nodes/array_get_random_element').evaluate,
|
|
738
846
|
pins: {
|
|
739
847
|
inputs: [
|
|
740
848
|
{ id: 'array', name: 'Массив', type: 'Array', required: true }
|
|
@@ -752,6 +860,7 @@ class NodeRegistry {
|
|
|
752
860
|
category: 'Массив',
|
|
753
861
|
description: 'Проверяет, содержит ли массив указанный элемент и возвращает его индекс.',
|
|
754
862
|
graphType: all,
|
|
863
|
+
evaluator: require('./nodes/array_contains').evaluate,
|
|
755
864
|
pins: {
|
|
756
865
|
inputs: [
|
|
757
866
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -770,6 +879,7 @@ class NodeRegistry {
|
|
|
770
879
|
category: 'Массив',
|
|
771
880
|
description: 'Получает элемент массива по его индексу.',
|
|
772
881
|
graphType: all,
|
|
882
|
+
evaluator: require('./nodes/array_get_by_index').evaluate,
|
|
773
883
|
pins: {
|
|
774
884
|
inputs: [
|
|
775
885
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -787,6 +897,7 @@ class NodeRegistry {
|
|
|
787
897
|
category: 'Массив',
|
|
788
898
|
description: 'Добавляет элемент в конец массива.',
|
|
789
899
|
graphType: all,
|
|
900
|
+
evaluator: require('./nodes/array_add_element').evaluate,
|
|
790
901
|
pins: {
|
|
791
902
|
inputs: [
|
|
792
903
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -804,6 +915,7 @@ class NodeRegistry {
|
|
|
804
915
|
category: 'Массив',
|
|
805
916
|
description: 'Удаляет элемент из массива по его индексу.',
|
|
806
917
|
graphType: all,
|
|
918
|
+
evaluator: require('./nodes/array_remove_by_index').evaluate,
|
|
807
919
|
pins: {
|
|
808
920
|
inputs: [
|
|
809
921
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -821,6 +933,7 @@ class NodeRegistry {
|
|
|
821
933
|
category: 'Массив',
|
|
822
934
|
description: 'Находит индекс элемента в массиве (или -1 если не найден).',
|
|
823
935
|
graphType: all,
|
|
936
|
+
evaluator: require('./nodes/array_find_index').evaluate,
|
|
824
937
|
pins: {
|
|
825
938
|
inputs: [
|
|
826
939
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -839,6 +952,7 @@ class NodeRegistry {
|
|
|
839
952
|
description: 'Создает объект из пар ключ-значение.',
|
|
840
953
|
graphType: all,
|
|
841
954
|
dynamicPins: true,
|
|
955
|
+
evaluator: require('./nodes/object_create').evaluate,
|
|
842
956
|
pins: {
|
|
843
957
|
inputs: [],
|
|
844
958
|
outputs: [
|
|
@@ -853,6 +967,7 @@ class NodeRegistry {
|
|
|
853
967
|
category: 'Объект',
|
|
854
968
|
description: 'Получает значение по ключу из объекта.',
|
|
855
969
|
graphType: all,
|
|
970
|
+
evaluator: require('./nodes/object_get').evaluate,
|
|
856
971
|
pins: {
|
|
857
972
|
inputs: [
|
|
858
973
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -870,6 +985,7 @@ class NodeRegistry {
|
|
|
870
985
|
category: 'Объект',
|
|
871
986
|
description: 'Добавляет или изменяет значение по ключу в объекте.',
|
|
872
987
|
graphType: all,
|
|
988
|
+
evaluator: require('./nodes/object_set').evaluate,
|
|
873
989
|
pins: {
|
|
874
990
|
inputs: [
|
|
875
991
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -888,6 +1004,7 @@ class NodeRegistry {
|
|
|
888
1004
|
category: 'Объект',
|
|
889
1005
|
description: 'Удаляет ключ из объекта.',
|
|
890
1006
|
graphType: all,
|
|
1007
|
+
evaluator: require('./nodes/object_delete').evaluate,
|
|
891
1008
|
pins: {
|
|
892
1009
|
inputs: [
|
|
893
1010
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -905,6 +1022,7 @@ class NodeRegistry {
|
|
|
905
1022
|
category: 'Объект',
|
|
906
1023
|
description: 'Проверяет наличие ключа в объекте и возвращает значение.',
|
|
907
1024
|
graphType: all,
|
|
1025
|
+
evaluator: require('./nodes/object_has_key').evaluate,
|
|
908
1026
|
pins: {
|
|
909
1027
|
inputs: [
|
|
910
1028
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -923,6 +1041,7 @@ class NodeRegistry {
|
|
|
923
1041
|
category: 'Данные',
|
|
924
1042
|
graphType: 'all',
|
|
925
1043
|
description: 'Возвращает массив с именами всех игроков на сервере.',
|
|
1044
|
+
evaluator: require('./nodes/data_get_server_players').evaluate,
|
|
926
1045
|
pins: {
|
|
927
1046
|
inputs: [],
|
|
928
1047
|
outputs: [
|
|
@@ -937,6 +1056,7 @@ class NodeRegistry {
|
|
|
937
1056
|
category: 'Логика',
|
|
938
1057
|
description: 'Сравнивает два значения.',
|
|
939
1058
|
graphType: all,
|
|
1059
|
+
evaluator: require('./nodes/logic_compare').evaluate,
|
|
940
1060
|
pins: {
|
|
941
1061
|
inputs: [
|
|
942
1062
|
{ id: 'a', name: 'A', type: 'Wildcard' },
|
|
@@ -954,6 +1074,7 @@ class NodeRegistry {
|
|
|
954
1074
|
category: 'Бот',
|
|
955
1075
|
description: 'Возвращает текущую позицию бота в мире.',
|
|
956
1076
|
graphType: all,
|
|
1077
|
+
evaluator: require('./nodes/bot_get_position').evaluate,
|
|
957
1078
|
pins: {
|
|
958
1079
|
inputs: [],
|
|
959
1080
|
outputs: [
|
|
@@ -969,6 +1090,7 @@ class NodeRegistry {
|
|
|
969
1090
|
category: 'Пользователи',
|
|
970
1091
|
description: 'Проверяет, находится ли пользователь в черном списке.',
|
|
971
1092
|
graphType: all,
|
|
1093
|
+
evaluator: require('./nodes/user_check_blacklist').evaluate,
|
|
972
1094
|
pins: {
|
|
973
1095
|
inputs: [
|
|
974
1096
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -985,6 +1107,7 @@ class NodeRegistry {
|
|
|
985
1107
|
category: 'Пользователи',
|
|
986
1108
|
description: 'Добавляет или убирает пользователя из черного списка.',
|
|
987
1109
|
graphType: all,
|
|
1110
|
+
executor: require('./nodes/user_set_blacklist').execute,
|
|
988
1111
|
pins: {
|
|
989
1112
|
inputs: [
|
|
990
1113
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -1005,6 +1128,7 @@ class NodeRegistry {
|
|
|
1005
1128
|
category: 'Пользователь',
|
|
1006
1129
|
description: 'Возвращает массив названий групп, в которых состоит пользователь.',
|
|
1007
1130
|
graphType: all,
|
|
1131
|
+
evaluator: require('./nodes/user_get_groups').evaluate,
|
|
1008
1132
|
pins: {
|
|
1009
1133
|
inputs: [
|
|
1010
1134
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -1021,6 +1145,7 @@ class NodeRegistry {
|
|
|
1021
1145
|
category: 'Пользователь',
|
|
1022
1146
|
description: 'Возвращает массив прав пользователя.',
|
|
1023
1147
|
graphType: all,
|
|
1148
|
+
evaluator: require('./nodes/user_get_permissions').evaluate,
|
|
1024
1149
|
pins: {
|
|
1025
1150
|
inputs: [
|
|
1026
1151
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -1037,6 +1162,7 @@ class NodeRegistry {
|
|
|
1037
1162
|
category: 'Данные',
|
|
1038
1163
|
description: 'Получает различные данные из объекта пользователя.',
|
|
1039
1164
|
graphType: all,
|
|
1165
|
+
evaluator: require('./nodes/data_get_user_field').evaluate,
|
|
1040
1166
|
pins: {
|
|
1041
1167
|
inputs: [
|
|
1042
1168
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -1064,6 +1190,23 @@ class NodeRegistry {
|
|
|
1064
1190
|
}
|
|
1065
1191
|
});
|
|
1066
1192
|
|
|
1193
|
+
this.registerNodeType({
|
|
1194
|
+
type: 'event:health',
|
|
1195
|
+
label: '❤️ Здоровье/Голод изменилось',
|
|
1196
|
+
category: 'События',
|
|
1197
|
+
description: 'Срабатывает при изменении здоровья, голода или насыщения бота.',
|
|
1198
|
+
graphType: event,
|
|
1199
|
+
pins: {
|
|
1200
|
+
inputs: [],
|
|
1201
|
+
outputs: [
|
|
1202
|
+
{ id: 'exec', name: 'Выполнить', type: 'Exec' },
|
|
1203
|
+
{ id: 'health', name: 'Здоровье', type: 'Number' },
|
|
1204
|
+
{ id: 'food', name: 'Голод', type: 'Number' },
|
|
1205
|
+
{ id: 'saturation', name: 'Насыщение', type: 'Number' }
|
|
1206
|
+
]
|
|
1207
|
+
}
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1067
1210
|
this.registerNodeType({
|
|
1068
1211
|
type: 'flow:switch',
|
|
1069
1212
|
label: '🔄 Switch (свитч)',
|
|
@@ -1071,6 +1214,7 @@ class NodeRegistry {
|
|
|
1071
1214
|
description: 'Выполняет разные действия в зависимости от значения. Автоматически определяет тип сравнения.',
|
|
1072
1215
|
graphType: all,
|
|
1073
1216
|
dynamicPins: true,
|
|
1217
|
+
executor: require('./nodes/flow_switch').execute,
|
|
1074
1218
|
pins: {
|
|
1075
1219
|
inputs: [
|
|
1076
1220
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} node - Экземпляр узла из графа.
|
|
3
|
+
* @param {object} context - Контекст выполнения графа.
|
|
4
|
+
* @param {object} helpers - Вспомогательные функции движка.
|
|
5
|
+
* @param {function} helpers.resolvePinValue - Функция для получения значения с пина.
|
|
6
|
+
* @param {function} helpers.traverse - Функция для перехода к следующему узлу.
|
|
7
|
+
*/
|
|
8
|
+
async function execute(node, context, helpers) {
|
|
9
|
+
const { resolvePinValue, traverse } = helpers;
|
|
10
|
+
|
|
11
|
+
const target = await resolvePinValue(node, 'target');
|
|
12
|
+
const yOffset = await resolvePinValue(node, 'add_y', 0);
|
|
13
|
+
|
|
14
|
+
if (target && context.bot?.lookAt) {
|
|
15
|
+
let finalPosition;
|
|
16
|
+
// Если цель - это сущность, у которой есть позиция
|
|
17
|
+
if (target.position) {
|
|
18
|
+
finalPosition = { ...target.position };
|
|
19
|
+
}
|
|
20
|
+
// Если цель - это объект с координатами
|
|
21
|
+
else if (target.x !== undefined && target.y !== undefined && target.z !== undefined) {
|
|
22
|
+
finalPosition = { ...target };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (finalPosition) {
|
|
26
|
+
finalPosition.y += Number(yOffset || 0);
|
|
27
|
+
context.bot.lookAt(finalPosition);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await traverse(node, 'exec');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
execute,
|
|
36
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} node - Экземпляр узла из графа.
|
|
3
|
+
* @param {object} context - Контекст выполнения графа.
|
|
4
|
+
* @param {object} helpers - Вспомогательные функции движка.
|
|
5
|
+
* @param {function} helpers.resolvePinValue - Функция для получения значения с пина.
|
|
6
|
+
* @param {function} helpers.traverse - Функция для перехода к следующему узлу.
|
|
7
|
+
*/
|
|
8
|
+
async function execute(node, context, helpers) {
|
|
9
|
+
const { resolvePinValue, traverse } = helpers;
|
|
10
|
+
|
|
11
|
+
const varName = await resolvePinValue(node, 'name', '');
|
|
12
|
+
const varValue = await resolvePinValue(node, 'value');
|
|
13
|
+
let shouldPersist = await resolvePinValue(node, 'persist', false);
|
|
14
|
+
|
|
15
|
+
// В графах команд принудительно отключаем сохранение в БД, чтобы избежать случайных записей
|
|
16
|
+
if (context.eventType === 'command') {
|
|
17
|
+
shouldPersist = false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (varName) {
|
|
21
|
+
context.variables[varName] = varValue;
|
|
22
|
+
if (context.persistenceIntent) {
|
|
23
|
+
context.persistenceIntent.set(varName, shouldPersist);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await traverse(node, 'exec');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
execute,
|
|
32
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} node - Экземпляр узла из графа.
|
|
3
|
+
* @param {object} context - Контекст выполнения графа.
|
|
4
|
+
* @param {object} helpers - Вспомогательные функции движка.
|
|
5
|
+
* @param {function} helpers.resolvePinValue - Функция для получения значения с входного пина.
|
|
6
|
+
* @param {function} helpers.traverse - Функция для перехода к следующему узлу.
|
|
7
|
+
* @param {Map} helpers.memo - Карта для мемоизации значений.
|
|
8
|
+
*/
|
|
9
|
+
async function execute(node, context, helpers) {
|
|
10
|
+
const { resolvePinValue, traverse, memo } = helpers;
|
|
11
|
+
|
|
12
|
+
const url = await resolvePinValue(node, 'url', '');
|
|
13
|
+
const method = await resolvePinValue(node, 'method', node.data?.method || 'GET');
|
|
14
|
+
const headersStr = await resolvePinValue(node, 'headers', '');
|
|
15
|
+
const body = await resolvePinValue(node, 'body', '');
|
|
16
|
+
const timeout = await resolvePinValue(node, 'timeout', 5000);
|
|
17
|
+
|
|
18
|
+
let headers = {};
|
|
19
|
+
if (headersStr) {
|
|
20
|
+
try {
|
|
21
|
+
headers = JSON.parse(headersStr);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
console.error('[HTTP Request] Ошибка парсинга headers:', e);
|
|
24
|
+
headers = {};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let requestBody = null;
|
|
29
|
+
if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
|
|
30
|
+
if (typeof body === 'object') {
|
|
31
|
+
requestBody = JSON.stringify(body);
|
|
32
|
+
} else if (typeof body === 'string') {
|
|
33
|
+
// Пробуем распарсить строку как JSON
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(body);
|
|
36
|
+
requestBody = JSON.stringify(parsed);
|
|
37
|
+
} catch {
|
|
38
|
+
// Если не JSON, отправляем как есть
|
|
39
|
+
requestBody = body;
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
requestBody = String(body);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!headers['Content-Type']) {
|
|
46
|
+
headers['Content-Type'] = 'application/json';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
53
|
+
|
|
54
|
+
const response = await fetch(url, {
|
|
55
|
+
method,
|
|
56
|
+
headers,
|
|
57
|
+
body: requestBody,
|
|
58
|
+
signal: controller.signal
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
clearTimeout(timeoutId);
|
|
62
|
+
|
|
63
|
+
const responseText = await response.text();
|
|
64
|
+
let responseBody;
|
|
65
|
+
try {
|
|
66
|
+
responseBody = JSON.parse(responseText);
|
|
67
|
+
} catch {
|
|
68
|
+
responseBody = responseText;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const responseHeaders = {};
|
|
72
|
+
response.headers.forEach((value, key) => {
|
|
73
|
+
responseHeaders[key] = value;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
memo.set(`${node.id}:status`, response.status);
|
|
77
|
+
memo.set(`${node.id}:response`, responseBody);
|
|
78
|
+
memo.set(`${node.id}:response_headers`, responseHeaders);
|
|
79
|
+
memo.set(`${node.id}:success`, response.ok);
|
|
80
|
+
memo.set(`${node.id}:error`, null);
|
|
81
|
+
|
|
82
|
+
await traverse(node, 'exec');
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('[HTTP Request] Ошибка запроса:', error);
|
|
85
|
+
|
|
86
|
+
memo.set(`${node.id}:status`, 0);
|
|
87
|
+
memo.set(`${node.id}:response`, null);
|
|
88
|
+
memo.set(`${node.id}:response_headers`, {});
|
|
89
|
+
memo.set(`${node.id}:success`, false);
|
|
90
|
+
memo.set(`${node.id}:error`, error.message);
|
|
91
|
+
|
|
92
|
+
await traverse(node, 'exec_error');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
execute,
|
|
98
|
+
};
|