blockmine 1.20.0 → 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 +13 -1
- package/CHANGELOG.md +15 -0
- package/backend/src/core/BotManager.js +2 -2
- 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 +36 -639
- package/backend/src/core/NodeRegistry.js +144 -1
- 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/package.json +1 -1
- package/frontend/dist/assets/index-BFd7YoAj.css +0 -1
- package/frontend/dist/assets/index-CMMutadc.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 }
|
|
@@ -302,6 +327,7 @@ class NodeRegistry {
|
|
|
302
327
|
description: 'Отправляет сообщение в чат. Поддерживает переменные в формате {varName}',
|
|
303
328
|
graphType: all,
|
|
304
329
|
dynamicPins: true,
|
|
330
|
+
executor: require('./nodes/action_send_message').execute,
|
|
305
331
|
pins: {
|
|
306
332
|
inputs: [
|
|
307
333
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -321,6 +347,7 @@ class NodeRegistry {
|
|
|
321
347
|
category: 'Действия',
|
|
322
348
|
description: 'Отправляет сообщение в консоль на странице бота.',
|
|
323
349
|
graphType: all,
|
|
350
|
+
executor: require('./nodes/action_send_log').execute,
|
|
324
351
|
pins: {
|
|
325
352
|
inputs: [
|
|
326
353
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -338,6 +365,7 @@ class NodeRegistry {
|
|
|
338
365
|
category: 'Действия',
|
|
339
366
|
description: 'Поворачивает голову бота в сторону координат или сущности.',
|
|
340
367
|
graphType: all,
|
|
368
|
+
executor: require('./nodes/action_bot_look_at').execute,
|
|
341
369
|
pins: {
|
|
342
370
|
inputs: [
|
|
343
371
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -356,6 +384,7 @@ class NodeRegistry {
|
|
|
356
384
|
category: 'Действия',
|
|
357
385
|
description: 'Сохраняет значение в переменную графа.',
|
|
358
386
|
graphType: all,
|
|
387
|
+
executor: require('./nodes/action_bot_set_variable').execute,
|
|
359
388
|
pins: {
|
|
360
389
|
inputs: [
|
|
361
390
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -369,12 +398,41 @@ class NodeRegistry {
|
|
|
369
398
|
}
|
|
370
399
|
});
|
|
371
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
|
+
|
|
372
429
|
this.registerNodeType({
|
|
373
430
|
type: 'data:get_argument',
|
|
374
431
|
label: '📥 Получить аргумент',
|
|
375
432
|
category: 'Данные',
|
|
376
433
|
description: 'Получает значение аргумента команды по его имени.',
|
|
377
434
|
graphType: command,
|
|
435
|
+
evaluator: require('./nodes/data_get_argument').evaluate,
|
|
378
436
|
data: {
|
|
379
437
|
argumentName: {
|
|
380
438
|
type: 'argument',
|
|
@@ -396,6 +454,7 @@ class NodeRegistry {
|
|
|
396
454
|
category: 'Данные',
|
|
397
455
|
description: 'Получает значение переменной графа.',
|
|
398
456
|
graphType: all,
|
|
457
|
+
evaluator: require('./nodes/data_get_variable').evaluate,
|
|
399
458
|
pins: {
|
|
400
459
|
inputs: [],
|
|
401
460
|
outputs: [
|
|
@@ -410,6 +469,7 @@ class NodeRegistry {
|
|
|
410
469
|
category: 'Данные',
|
|
411
470
|
description: 'Получает определенное поле из объекта сущности (например, "position.x", "username").',
|
|
412
471
|
graphType: all,
|
|
472
|
+
evaluator: require('./nodes/data_get_entity_field').evaluate,
|
|
413
473
|
pins: {
|
|
414
474
|
inputs: [
|
|
415
475
|
{ id: 'entity', name: 'Сущность', type: 'Object', required: true },
|
|
@@ -427,8 +487,10 @@ class NodeRegistry {
|
|
|
427
487
|
type: 'data:string_literal',
|
|
428
488
|
label: '📜 Строка',
|
|
429
489
|
category: 'Данные',
|
|
430
|
-
description: '
|
|
490
|
+
description: 'Текстовое значение с поддержкой переменных. Используйте {имя} для вставки значений.',
|
|
431
491
|
graphType: all,
|
|
492
|
+
dynamicPins: true,
|
|
493
|
+
evaluator: require('./nodes/data_string_literal').evaluate,
|
|
432
494
|
pins: {
|
|
433
495
|
inputs: [],
|
|
434
496
|
outputs: [
|
|
@@ -443,6 +505,7 @@ class NodeRegistry {
|
|
|
443
505
|
category: 'Данные',
|
|
444
506
|
description: 'Простое числовое значение.',
|
|
445
507
|
graphType: all,
|
|
508
|
+
evaluator: require('./nodes/data_number_literal').evaluate,
|
|
446
509
|
pins: {
|
|
447
510
|
inputs: [
|
|
448
511
|
{ id: 'value', name: 'Значение', type: 'Number', required: true }
|
|
@@ -459,6 +522,7 @@ class NodeRegistry {
|
|
|
459
522
|
category: 'Данные',
|
|
460
523
|
description: 'Значение Истина/Ложь.',
|
|
461
524
|
graphType: all,
|
|
525
|
+
evaluator: require('./nodes/data_boolean_literal').evaluate,
|
|
462
526
|
pins: {
|
|
463
527
|
inputs: [
|
|
464
528
|
{ id: 'value', name: 'Значение', type: 'Boolean', required: true }
|
|
@@ -476,6 +540,7 @@ class NodeRegistry {
|
|
|
476
540
|
description: 'Создает массив из элементов.',
|
|
477
541
|
graphType: all,
|
|
478
542
|
dynamicPins: true,
|
|
543
|
+
evaluator: require('./nodes/data_array_literal').evaluate,
|
|
479
544
|
pins: {
|
|
480
545
|
inputs: [],
|
|
481
546
|
outputs: [
|
|
@@ -491,6 +556,7 @@ class NodeRegistry {
|
|
|
491
556
|
description: 'Создает JSON-объект из пар ключ-значение.',
|
|
492
557
|
graphType: all,
|
|
493
558
|
dynamicPins: true,
|
|
559
|
+
evaluator: require('./nodes/data_make_object').evaluate,
|
|
494
560
|
pins: {
|
|
495
561
|
inputs: [],
|
|
496
562
|
outputs: [
|
|
@@ -505,6 +571,7 @@ class NodeRegistry {
|
|
|
505
571
|
category: 'Данные',
|
|
506
572
|
description: 'Приводит входящее значение к указанному целевому типу.',
|
|
507
573
|
graphType: all,
|
|
574
|
+
evaluator: require('./nodes/data_cast').evaluate,
|
|
508
575
|
pins: {
|
|
509
576
|
inputs: [
|
|
510
577
|
{ id: 'value', name: 'Значение', type: 'Wildcard', required: true }
|
|
@@ -521,6 +588,7 @@ class NodeRegistry {
|
|
|
521
588
|
category: 'Массив',
|
|
522
589
|
graphType: 'all',
|
|
523
590
|
description: 'Возвращает количество элементов в массиве или длину строки.',
|
|
591
|
+
evaluator: require('./nodes/data_length').evaluate,
|
|
524
592
|
pins: {
|
|
525
593
|
inputs: [
|
|
526
594
|
{ id: 'data', name: 'Массив или Строка', type: 'Any', required: true }
|
|
@@ -537,6 +605,8 @@ class NodeRegistry {
|
|
|
537
605
|
category: 'Строки',
|
|
538
606
|
description: 'Проверяет, содержит ли одна строка другую.',
|
|
539
607
|
graphType: all,
|
|
608
|
+
executor: require('./nodes/string_contains').execute,
|
|
609
|
+
evaluator: require('./nodes/string_contains').evaluate,
|
|
540
610
|
pins: {
|
|
541
611
|
inputs: [
|
|
542
612
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -551,12 +621,35 @@ class NodeRegistry {
|
|
|
551
621
|
}
|
|
552
622
|
});
|
|
553
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
|
+
|
|
554
645
|
this.registerNodeType({
|
|
555
646
|
type: 'string:equals',
|
|
556
647
|
label: 'Строка: Равно',
|
|
557
648
|
category: 'Строки',
|
|
558
649
|
description: 'Проверяет, равны ли строки (с учетом/без учета регистра).',
|
|
559
650
|
graphType: all,
|
|
651
|
+
executor: require('./nodes/string_equals').execute,
|
|
652
|
+
evaluator: require('./nodes/string_equals').evaluate,
|
|
560
653
|
pins: {
|
|
561
654
|
inputs: [
|
|
562
655
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -577,6 +670,8 @@ class NodeRegistry {
|
|
|
577
670
|
category: 'Строки',
|
|
578
671
|
description: 'Проверяет, начинается ли строка с указанной подстроки.',
|
|
579
672
|
graphType: all,
|
|
673
|
+
executor: require('./nodes/string_starts_with').execute,
|
|
674
|
+
evaluator: require('./nodes/string_starts_with').evaluate,
|
|
580
675
|
pins: {
|
|
581
676
|
inputs: [
|
|
582
677
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -597,6 +692,8 @@ class NodeRegistry {
|
|
|
597
692
|
category: 'Строки',
|
|
598
693
|
description: 'Проверяет, заканчивается ли строка указанной подстрокой.',
|
|
599
694
|
graphType: all,
|
|
695
|
+
executor: require('./nodes/string_ends_with').execute,
|
|
696
|
+
evaluator: require('./nodes/string_ends_with').evaluate,
|
|
600
697
|
pins: {
|
|
601
698
|
inputs: [
|
|
602
699
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -617,6 +714,8 @@ class NodeRegistry {
|
|
|
617
714
|
category: 'Строки',
|
|
618
715
|
description: 'Возвращает количество символов в строке.',
|
|
619
716
|
graphType: all,
|
|
717
|
+
executor: require('./nodes/string_length').execute,
|
|
718
|
+
evaluator: require('./nodes/string_length').evaluate,
|
|
620
719
|
pins: {
|
|
621
720
|
inputs: [
|
|
622
721
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -635,6 +734,8 @@ class NodeRegistry {
|
|
|
635
734
|
category: 'Строки',
|
|
636
735
|
description: 'Разделяет строку на массив подстрок по разделителю.',
|
|
637
736
|
graphType: all,
|
|
737
|
+
executor: require('./nodes/string_split').execute,
|
|
738
|
+
evaluator: require('./nodes/string_split').evaluate,
|
|
638
739
|
pins: {
|
|
639
740
|
inputs: [
|
|
640
741
|
{ id: 'exec', name: 'Exec', type: 'Exec', required: true },
|
|
@@ -655,6 +756,7 @@ class NodeRegistry {
|
|
|
655
756
|
description: 'Объединяет две или более строки в одну.',
|
|
656
757
|
graphType: all,
|
|
657
758
|
dynamicPins: true,
|
|
759
|
+
evaluator: require('./nodes/string_concat').evaluate,
|
|
658
760
|
pins: {
|
|
659
761
|
inputs: [],
|
|
660
762
|
outputs: [
|
|
@@ -669,6 +771,7 @@ class NodeRegistry {
|
|
|
669
771
|
category: 'Математика',
|
|
670
772
|
description: 'Выполняет математическую операцию над двумя числами.',
|
|
671
773
|
graphType: all,
|
|
774
|
+
evaluator: require('./nodes/math_operation').evaluate,
|
|
672
775
|
pins: {
|
|
673
776
|
inputs: [
|
|
674
777
|
{ id: 'a', name: 'A', type: 'Number', required: true },
|
|
@@ -687,6 +790,7 @@ class NodeRegistry {
|
|
|
687
790
|
description: 'Выполняет логическую операцию. Для НЕ (NOT) используется только вход А.',
|
|
688
791
|
graphType: all,
|
|
689
792
|
dynamicPins: true,
|
|
793
|
+
evaluator: require('./nodes/logic_operation').evaluate,
|
|
690
794
|
pins: {
|
|
691
795
|
inputs: [
|
|
692
796
|
{ id: 'a', name: 'A', type: 'Boolean', required: true },
|
|
@@ -704,6 +808,7 @@ class NodeRegistry {
|
|
|
704
808
|
category: 'Отладка',
|
|
705
809
|
description: 'Выводит значение в консоль терминала, где запущен бот.',
|
|
706
810
|
graphType: all,
|
|
811
|
+
executor: require('./nodes/debug_log').execute,
|
|
707
812
|
pins: {
|
|
708
813
|
inputs: [
|
|
709
814
|
{ id: 'exec', name: 'Exec', type: 'Exec' },
|
|
@@ -721,6 +826,7 @@ class NodeRegistry {
|
|
|
721
826
|
category: 'Математика',
|
|
722
827
|
graphType: 'all',
|
|
723
828
|
description: 'Генерирует случайное число в заданном диапазоне.',
|
|
829
|
+
evaluator: require('./nodes/math_random_number').evaluate,
|
|
724
830
|
pins: {
|
|
725
831
|
inputs: [
|
|
726
832
|
{ id: 'min', name: 'Мин', type: 'Number' },
|
|
@@ -736,6 +842,7 @@ class NodeRegistry {
|
|
|
736
842
|
category: 'Массив',
|
|
737
843
|
graphType: 'all',
|
|
738
844
|
description: 'Возвращает случайный элемент из массива и его индекс.',
|
|
845
|
+
evaluator: require('./nodes/array_get_random_element').evaluate,
|
|
739
846
|
pins: {
|
|
740
847
|
inputs: [
|
|
741
848
|
{ id: 'array', name: 'Массив', type: 'Array', required: true }
|
|
@@ -753,6 +860,7 @@ class NodeRegistry {
|
|
|
753
860
|
category: 'Массив',
|
|
754
861
|
description: 'Проверяет, содержит ли массив указанный элемент и возвращает его индекс.',
|
|
755
862
|
graphType: all,
|
|
863
|
+
evaluator: require('./nodes/array_contains').evaluate,
|
|
756
864
|
pins: {
|
|
757
865
|
inputs: [
|
|
758
866
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -771,6 +879,7 @@ class NodeRegistry {
|
|
|
771
879
|
category: 'Массив',
|
|
772
880
|
description: 'Получает элемент массива по его индексу.',
|
|
773
881
|
graphType: all,
|
|
882
|
+
evaluator: require('./nodes/array_get_by_index').evaluate,
|
|
774
883
|
pins: {
|
|
775
884
|
inputs: [
|
|
776
885
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -788,6 +897,7 @@ class NodeRegistry {
|
|
|
788
897
|
category: 'Массив',
|
|
789
898
|
description: 'Добавляет элемент в конец массива.',
|
|
790
899
|
graphType: all,
|
|
900
|
+
evaluator: require('./nodes/array_add_element').evaluate,
|
|
791
901
|
pins: {
|
|
792
902
|
inputs: [
|
|
793
903
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -805,6 +915,7 @@ class NodeRegistry {
|
|
|
805
915
|
category: 'Массив',
|
|
806
916
|
description: 'Удаляет элемент из массива по его индексу.',
|
|
807
917
|
graphType: all,
|
|
918
|
+
evaluator: require('./nodes/array_remove_by_index').evaluate,
|
|
808
919
|
pins: {
|
|
809
920
|
inputs: [
|
|
810
921
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -822,6 +933,7 @@ class NodeRegistry {
|
|
|
822
933
|
category: 'Массив',
|
|
823
934
|
description: 'Находит индекс элемента в массиве (или -1 если не найден).',
|
|
824
935
|
graphType: all,
|
|
936
|
+
evaluator: require('./nodes/array_find_index').evaluate,
|
|
825
937
|
pins: {
|
|
826
938
|
inputs: [
|
|
827
939
|
{ id: 'array', name: 'Массив', type: 'Array', required: true },
|
|
@@ -840,6 +952,7 @@ class NodeRegistry {
|
|
|
840
952
|
description: 'Создает объект из пар ключ-значение.',
|
|
841
953
|
graphType: all,
|
|
842
954
|
dynamicPins: true,
|
|
955
|
+
evaluator: require('./nodes/object_create').evaluate,
|
|
843
956
|
pins: {
|
|
844
957
|
inputs: [],
|
|
845
958
|
outputs: [
|
|
@@ -854,6 +967,7 @@ class NodeRegistry {
|
|
|
854
967
|
category: 'Объект',
|
|
855
968
|
description: 'Получает значение по ключу из объекта.',
|
|
856
969
|
graphType: all,
|
|
970
|
+
evaluator: require('./nodes/object_get').evaluate,
|
|
857
971
|
pins: {
|
|
858
972
|
inputs: [
|
|
859
973
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -871,6 +985,7 @@ class NodeRegistry {
|
|
|
871
985
|
category: 'Объект',
|
|
872
986
|
description: 'Добавляет или изменяет значение по ключу в объекте.',
|
|
873
987
|
graphType: all,
|
|
988
|
+
evaluator: require('./nodes/object_set').evaluate,
|
|
874
989
|
pins: {
|
|
875
990
|
inputs: [
|
|
876
991
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -889,6 +1004,7 @@ class NodeRegistry {
|
|
|
889
1004
|
category: 'Объект',
|
|
890
1005
|
description: 'Удаляет ключ из объекта.',
|
|
891
1006
|
graphType: all,
|
|
1007
|
+
evaluator: require('./nodes/object_delete').evaluate,
|
|
892
1008
|
pins: {
|
|
893
1009
|
inputs: [
|
|
894
1010
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -906,6 +1022,7 @@ class NodeRegistry {
|
|
|
906
1022
|
category: 'Объект',
|
|
907
1023
|
description: 'Проверяет наличие ключа в объекте и возвращает значение.',
|
|
908
1024
|
graphType: all,
|
|
1025
|
+
evaluator: require('./nodes/object_has_key').evaluate,
|
|
909
1026
|
pins: {
|
|
910
1027
|
inputs: [
|
|
911
1028
|
{ id: 'object', name: 'Объект', type: 'Object', required: true },
|
|
@@ -924,6 +1041,7 @@ class NodeRegistry {
|
|
|
924
1041
|
category: 'Данные',
|
|
925
1042
|
graphType: 'all',
|
|
926
1043
|
description: 'Возвращает массив с именами всех игроков на сервере.',
|
|
1044
|
+
evaluator: require('./nodes/data_get_server_players').evaluate,
|
|
927
1045
|
pins: {
|
|
928
1046
|
inputs: [],
|
|
929
1047
|
outputs: [
|
|
@@ -938,6 +1056,7 @@ class NodeRegistry {
|
|
|
938
1056
|
category: 'Логика',
|
|
939
1057
|
description: 'Сравнивает два значения.',
|
|
940
1058
|
graphType: all,
|
|
1059
|
+
evaluator: require('./nodes/logic_compare').evaluate,
|
|
941
1060
|
pins: {
|
|
942
1061
|
inputs: [
|
|
943
1062
|
{ id: 'a', name: 'A', type: 'Wildcard' },
|
|
@@ -955,6 +1074,7 @@ class NodeRegistry {
|
|
|
955
1074
|
category: 'Бот',
|
|
956
1075
|
description: 'Возвращает текущую позицию бота в мире.',
|
|
957
1076
|
graphType: all,
|
|
1077
|
+
evaluator: require('./nodes/bot_get_position').evaluate,
|
|
958
1078
|
pins: {
|
|
959
1079
|
inputs: [],
|
|
960
1080
|
outputs: [
|
|
@@ -970,6 +1090,7 @@ class NodeRegistry {
|
|
|
970
1090
|
category: 'Пользователи',
|
|
971
1091
|
description: 'Проверяет, находится ли пользователь в черном списке.',
|
|
972
1092
|
graphType: all,
|
|
1093
|
+
evaluator: require('./nodes/user_check_blacklist').evaluate,
|
|
973
1094
|
pins: {
|
|
974
1095
|
inputs: [
|
|
975
1096
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -986,6 +1107,7 @@ class NodeRegistry {
|
|
|
986
1107
|
category: 'Пользователи',
|
|
987
1108
|
description: 'Добавляет или убирает пользователя из черного списка.',
|
|
988
1109
|
graphType: all,
|
|
1110
|
+
executor: require('./nodes/user_set_blacklist').execute,
|
|
989
1111
|
pins: {
|
|
990
1112
|
inputs: [
|
|
991
1113
|
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
@@ -1006,6 +1128,7 @@ class NodeRegistry {
|
|
|
1006
1128
|
category: 'Пользователь',
|
|
1007
1129
|
description: 'Возвращает массив названий групп, в которых состоит пользователь.',
|
|
1008
1130
|
graphType: all,
|
|
1131
|
+
evaluator: require('./nodes/user_get_groups').evaluate,
|
|
1009
1132
|
pins: {
|
|
1010
1133
|
inputs: [
|
|
1011
1134
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -1022,6 +1145,7 @@ class NodeRegistry {
|
|
|
1022
1145
|
category: 'Пользователь',
|
|
1023
1146
|
description: 'Возвращает массив прав пользователя.',
|
|
1024
1147
|
graphType: all,
|
|
1148
|
+
evaluator: require('./nodes/user_get_permissions').evaluate,
|
|
1025
1149
|
pins: {
|
|
1026
1150
|
inputs: [
|
|
1027
1151
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -1038,6 +1162,7 @@ class NodeRegistry {
|
|
|
1038
1162
|
category: 'Данные',
|
|
1039
1163
|
description: 'Получает различные данные из объекта пользователя.',
|
|
1040
1164
|
graphType: all,
|
|
1165
|
+
evaluator: require('./nodes/data_get_user_field').evaluate,
|
|
1041
1166
|
pins: {
|
|
1042
1167
|
inputs: [
|
|
1043
1168
|
{ id: 'user', name: 'Пользователь', type: 'User', required: true }
|
|
@@ -1065,6 +1190,23 @@ class NodeRegistry {
|
|
|
1065
1190
|
}
|
|
1066
1191
|
});
|
|
1067
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
|
+
|
|
1068
1210
|
this.registerNodeType({
|
|
1069
1211
|
type: 'flow:switch',
|
|
1070
1212
|
label: '🔄 Switch (свитч)',
|
|
@@ -1072,6 +1214,7 @@ class NodeRegistry {
|
|
|
1072
1214
|
description: 'Выполняет разные действия в зависимости от значения. Автоматически определяет тип сравнения.',
|
|
1073
1215
|
graphType: all,
|
|
1074
1216
|
dynamicPins: true,
|
|
1217
|
+
executor: require('./nodes/flow_switch').execute,
|
|
1075
1218
|
pins: {
|
|
1076
1219
|
inputs: [
|
|
1077
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
|
+
};
|