blockmine 1.15.2 → 1.16.2
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/CHANGELOG.md +27 -0
- package/backend/src/api/routes/bots.js +18 -0
- package/backend/src/api/routes/plugins.js +15 -1
- package/backend/src/core/BotManager.js +1 -0
- package/backend/src/core/GraphExecutionEngine.js +35 -0
- package/backend/src/core/NodeRegistry.js +18 -0
- package/frontend/dist/assets/{index-Q43S68Ug.js → index-ComgCgjP.js} +267 -267
- package/frontend/dist/assets/index-_stfadil.css +1 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/frontend/dist/assets/index-B3e51n-B.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
# История версий
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
### [1.16.2](https://github.com/blockmineJS/blockmine/compare/v1.16.1...v1.16.2) (2025-07-20)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
### 🐛 Исправления
|
|
8
|
+
|
|
9
|
+
* обновление плагинов починено ([6b3c536](https://github.com/blockmineJS/blockmine/commit/6b3c5360c490dda43b0fd8cbf5b77a6c4d329543))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### 🛠 Рефакторинг
|
|
13
|
+
|
|
14
|
+
* удалены отладочные сообщения и неиспользуемый код из компонента InstalledPluginsView ([1b41026](https://github.com/blockmineJS/blockmine/commit/1b410264d1e844c76404c047c4547e86199bbb27))
|
|
15
|
+
|
|
16
|
+
### [1.16.1](https://github.com/blockmineJS/blockmine/compare/v1.16.0...v1.16.1) (2025-07-20)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### 🐛 Исправления
|
|
20
|
+
|
|
21
|
+
* настройки плагинов опять можно менять на страничке плагинов. вернул сортировку по новым ([a89f9ca](https://github.com/blockmineJS/blockmine/commit/a89f9ca49437b7ca9eac76917f809433c4c7bbf1))
|
|
22
|
+
|
|
23
|
+
## [1.16.0](https://github.com/blockmineJS/blockmine/compare/v1.15.2...v1.16.0) (2025-07-20)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### ✨ Новые возможности
|
|
27
|
+
|
|
28
|
+
* добавлен новый узел 'flow:switch' с динамическими case'ами ([81886db](https://github.com/blockmineJS/blockmine/commit/81886db75da6792d499cdc2c277494f9e39136c3))
|
|
29
|
+
* добавлена кнопка перезапуска бота ([db13070](https://github.com/blockmineJS/blockmine/commit/db130707637a8a5e93e8c783463ca38f0ab2bf85))
|
|
30
|
+
|
|
4
31
|
### [1.15.2](https://github.com/blockmineJS/blockmine/compare/v1.15.1...v1.15.2) (2025-07-19)
|
|
5
32
|
|
|
6
33
|
### [1.15.1](https://github.com/blockmineJS/blockmine/compare/v1.15.0...v1.15.1) (2025-07-19)
|
|
@@ -230,6 +230,24 @@ router.post('/:id/stop', authorize('bot:start_stop'), (req, res) => {
|
|
|
230
230
|
}
|
|
231
231
|
});
|
|
232
232
|
|
|
233
|
+
router.post('/:id/restart', authorize('bot:start_stop'), async (req, res) => {
|
|
234
|
+
try {
|
|
235
|
+
const botId = parseInt(req.params.id, 10);
|
|
236
|
+
botManager.stopBot(botId);
|
|
237
|
+
setTimeout(async () => {
|
|
238
|
+
const botConfig = await prisma.bot.findUnique({ where: { id: botId }, include: { server: true } });
|
|
239
|
+
if (!botConfig) {
|
|
240
|
+
return res.status(404).json({ success: false, message: 'Бот не найден' });
|
|
241
|
+
}
|
|
242
|
+
botManager.startBot(botConfig);
|
|
243
|
+
res.status(202).json({ success: true, message: 'Команда на перезапуск отправлена.' });
|
|
244
|
+
}, 1000);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error(`[API] Ошибка перезапуска бота ${req.params.id}:`, error);
|
|
247
|
+
res.status(500).json({ success: false, message: 'Ошибка при перезапуске бота: ' + error.message });
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
233
251
|
router.post('/:id/chat', authorize('bot:interact'), (req, res) => {
|
|
234
252
|
try {
|
|
235
253
|
const botId = parseInt(req.params.id, 10);
|
|
@@ -70,7 +70,17 @@ router.get('/:id/info', authenticate, authorize('plugin:list'), async (req, res)
|
|
|
70
70
|
|
|
71
71
|
const plugin = await prisma.installedPlugin.findUnique({
|
|
72
72
|
where: { id: pluginId },
|
|
73
|
-
|
|
73
|
+
select: {
|
|
74
|
+
id: true,
|
|
75
|
+
name: true,
|
|
76
|
+
version: true,
|
|
77
|
+
description: true,
|
|
78
|
+
sourceType: true,
|
|
79
|
+
sourceUri: true,
|
|
80
|
+
isEnabled: true,
|
|
81
|
+
manifest: true,
|
|
82
|
+
settings: true,
|
|
83
|
+
createdAt: true,
|
|
74
84
|
commands: {
|
|
75
85
|
select: {
|
|
76
86
|
id: true,
|
|
@@ -116,7 +126,11 @@ router.get('/bot/:botId', authenticate, authorize('plugin:list'), async (req, re
|
|
|
116
126
|
version: true,
|
|
117
127
|
description: true,
|
|
118
128
|
sourceType: true,
|
|
129
|
+
sourceUri: true,
|
|
119
130
|
isEnabled: true,
|
|
131
|
+
manifest: true,
|
|
132
|
+
settings: true,
|
|
133
|
+
createdAt: true,
|
|
120
134
|
commands: {
|
|
121
135
|
select: {
|
|
122
136
|
id: true,
|
|
@@ -837,6 +837,7 @@ class BotManager {
|
|
|
837
837
|
if (child && !child.killed) {
|
|
838
838
|
child.send({ type: 'plugins:reload' });
|
|
839
839
|
console.log(`[BotManager] Sent plugins:reload to bot process ${botId}`);
|
|
840
|
+
const { getIO } = require('../real-time/socketHandler');
|
|
840
841
|
getIO().emit('bot:plugins_reloaded', { botId });
|
|
841
842
|
return { success: true, message: 'Команда на перезагрузку плагинов отправлена.' };
|
|
842
843
|
}
|
|
@@ -254,6 +254,41 @@ class GraphExecutionEngine {
|
|
|
254
254
|
}
|
|
255
255
|
break;
|
|
256
256
|
}
|
|
257
|
+
case 'flow:switch': {
|
|
258
|
+
const value = await this.resolvePinValue(node, 'value');
|
|
259
|
+
const caseCount = node.data?.caseCount || 0;
|
|
260
|
+
let matched = false;
|
|
261
|
+
|
|
262
|
+
for (let i = 0; i < caseCount; i++) {
|
|
263
|
+
const caseValue = node.data?.[`case_${i}`];
|
|
264
|
+
if (caseValue !== undefined) {
|
|
265
|
+
let isMatch = false;
|
|
266
|
+
|
|
267
|
+
if (Array.isArray(value) && Array.isArray(caseValue)) {
|
|
268
|
+
isMatch = JSON.stringify(value) === JSON.stringify(caseValue);
|
|
269
|
+
} else if (typeof value === 'object' && typeof caseValue === 'object' && value !== null && caseValue !== null) {
|
|
270
|
+
isMatch = JSON.stringify(value) === JSON.stringify(caseValue);
|
|
271
|
+
} else if (typeof value === 'number' && typeof caseValue === 'number') {
|
|
272
|
+
isMatch = value === caseValue;
|
|
273
|
+
} else if (typeof value === 'boolean' && typeof caseValue === 'boolean') {
|
|
274
|
+
isMatch = value === caseValue;
|
|
275
|
+
} else {
|
|
276
|
+
isMatch = String(value) === String(caseValue);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (isMatch) {
|
|
280
|
+
await this.traverse(node, `case_${i}`);
|
|
281
|
+
matched = true;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!matched) {
|
|
288
|
+
await this.traverse(node, 'default');
|
|
289
|
+
}
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
257
292
|
case 'debug:log': {
|
|
258
293
|
const value = await this.resolvePinValue(node, 'value');
|
|
259
294
|
console.log('[Graph Debug]', value);
|
|
@@ -1064,6 +1064,24 @@ class NodeRegistry {
|
|
|
1064
1064
|
}
|
|
1065
1065
|
});
|
|
1066
1066
|
|
|
1067
|
+
this.registerNodeType({
|
|
1068
|
+
type: 'flow:switch',
|
|
1069
|
+
label: '🔄 Switch (свитч)',
|
|
1070
|
+
category: 'Поток',
|
|
1071
|
+
description: 'Выполняет разные действия в зависимости от значения. Автоматически определяет тип сравнения.',
|
|
1072
|
+
graphType: all,
|
|
1073
|
+
dynamicPins: true,
|
|
1074
|
+
pins: {
|
|
1075
|
+
inputs: [
|
|
1076
|
+
{ id: 'exec', name: 'Выполнить', type: 'Exec', required: true },
|
|
1077
|
+
{ id: 'value', name: 'Значение', type: 'Wildcard', required: true }
|
|
1078
|
+
],
|
|
1079
|
+
outputs: [
|
|
1080
|
+
{ id: 'default', name: 'Default', type: 'Exec' }
|
|
1081
|
+
]
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1067
1085
|
console.log(`NodeRegistry: Registered ${this.nodes.size} base nodes`);
|
|
1068
1086
|
}
|
|
1069
1087
|
|