blockmine 1.17.0 → 1.18.1
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/package.json +27 -27
- package/backend/src/api/routes/bots.js +4 -3
- package/backend/src/api/routes/tasks.js +2 -1
- package/backend/src/core/BotManager.js +23 -2
- package/backend/src/core/BotProcess.js +15 -1
- package/backend/src/core/PluginLoader.js +86 -131
- package/backend/src/core/PluginManager.js +427 -402
- package/backend/src/core/TaskScheduler.js +82 -52
- package/backend/src/core/utils/settingsMerger.js +25 -0
- package/frontend/dist/assets/{index-BpUwmzIs.js → index-BYC2UyN-.js} +1667 -1667
- package/frontend/dist/create_issue.png +0 -0
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -30,60 +30,86 @@ class TaskScheduler {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async executeTask(task) {
|
|
33
|
-
console.log(`[TaskScheduler] Выполнение задачи: "${task.name}" (ID: ${task.id})`);
|
|
34
|
-
let botIds = [];
|
|
35
|
-
|
|
36
33
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
console.log(`[TaskScheduler] Выполнение задачи: "${task.name}" (ID: ${task.id}) в ${new Date().toLocaleString('ru-RU')}`);
|
|
35
|
+
let botIds = [];
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const targetIds = JSON.parse(task.targetBotIds);
|
|
39
|
+
if (Array.isArray(targetIds) && targetIds[0] === 'ALL') {
|
|
40
|
+
const allBots = await prisma.bot.findMany({ select: { id: true } });
|
|
41
|
+
botIds = allBots.map(b => b.id);
|
|
42
|
+
console.log(`[TaskScheduler] Задача будет выполнена для всех ботов (${botIds.length} ботов)`);
|
|
43
|
+
} else {
|
|
44
|
+
botIds = targetIds.map(id => parseInt(id, 10));
|
|
45
|
+
console.log(`[TaskScheduler] Задача будет выполнена для ботов: ${botIds.join(', ')}`);
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error(`[TaskScheduler] Ошибка парсинга targetBotIds для задачи ${task.id}:`, e.message);
|
|
49
|
+
return;
|
|
43
50
|
}
|
|
44
|
-
} catch (e) {
|
|
45
|
-
console.error(`[TaskScheduler] Ошибка парсинга targetBotIds для задачи ${task.id}:`, e.message);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
for (const botId of botIds) {
|
|
53
|
+
try {
|
|
54
|
+
const botConfig = await prisma.bot.findUnique({ where: { id: botId }, include: { server: true } });
|
|
55
|
+
if (!botConfig) continue;
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
break;
|
|
63
|
-
case 'RESTART_BOT':
|
|
64
|
-
console.log(` -> Перезапуск бота ${botConfig.username}`);
|
|
65
|
-
if (botManager.bots.has(botId)) {
|
|
66
|
-
botManager.stopBot(botId);
|
|
67
|
-
setTimeout(() => botManager.startBot(botConfig), 5000);
|
|
68
|
-
} else {
|
|
69
|
-
await botManager.startBot(botConfig);
|
|
70
|
-
}
|
|
71
|
-
break;
|
|
72
|
-
case 'SEND_COMMAND':
|
|
73
|
-
if (botManager.bots.has(botId)) {
|
|
74
|
-
const payload = JSON.parse(task.payload || '{}');
|
|
75
|
-
if (payload.command) {
|
|
76
|
-
console.log(` -> Отправка команды "${payload.command}" боту ${botConfig.username}`);
|
|
77
|
-
botManager.sendMessageToBot(botId, payload.command);
|
|
57
|
+
switch (task.action) {
|
|
58
|
+
case 'START_BOT':
|
|
59
|
+
console.log(`[TaskScheduler] -> Запуск бота ${botConfig.username} (ID: ${botId})`);
|
|
60
|
+
if (!botManager.bots.has(botId)) {
|
|
61
|
+
await botManager.startBot(botConfig);
|
|
62
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} успешно запущен`);
|
|
63
|
+
} else {
|
|
64
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} уже запущен`);
|
|
78
65
|
}
|
|
79
|
-
|
|
80
|
-
|
|
66
|
+
break;
|
|
67
|
+
case 'STOP_BOT':
|
|
68
|
+
console.log(`[TaskScheduler] -> Остановка бота ${botConfig.username} (ID: ${botId})`);
|
|
69
|
+
if (botManager.bots.has(botId)) {
|
|
70
|
+
botManager.stopBot(botId);
|
|
71
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} остановлен`);
|
|
72
|
+
} else {
|
|
73
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} уже остановлен`);
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case 'RESTART_BOT':
|
|
77
|
+
console.log(`[TaskScheduler] -> Перезапуск бота ${botConfig.username} (ID: ${botId})`);
|
|
78
|
+
if (botManager.bots.has(botId)) {
|
|
79
|
+
console.log(`[TaskScheduler] -> Останавливаем бота ${botConfig.username}...`);
|
|
80
|
+
botManager.stopBot(botId);
|
|
81
|
+
console.log(`[TaskScheduler] -> Запланирован запуск бота ${botConfig.username} через 10 секунд`);
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
console.log(`[TaskScheduler] -> Запускаем бота ${botConfig.username}...`);
|
|
84
|
+
botManager.startBot(botConfig);
|
|
85
|
+
}, 10000);
|
|
86
|
+
} else {
|
|
87
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} не запущен, запускаем...`);
|
|
88
|
+
await botManager.startBot(botConfig);
|
|
89
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} успешно запущен`);
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
case 'SEND_COMMAND':
|
|
93
|
+
if (botManager.bots.has(botId)) {
|
|
94
|
+
const payload = JSON.parse(task.payload || '{}');
|
|
95
|
+
if (payload.command) {
|
|
96
|
+
console.log(`[TaskScheduler] -> Отправка команды "${payload.command}" боту ${botConfig.username}`);
|
|
97
|
+
botManager.sendMessageToBot(botId, payload.command);
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
console.log(`[TaskScheduler] -> Бот ${botConfig.username} не запущен, команда не отправлена`);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(`[TaskScheduler] Ошибка выполнения действия для бота ID ${botId}:`, error);
|
|
81
106
|
}
|
|
82
|
-
} catch (error) {
|
|
83
|
-
console.error(`[TaskScheduler] Ошибка выполнения действия для бота ID ${botId}:`, error);
|
|
84
107
|
}
|
|
108
|
+
await prisma.scheduledTask.update({ where: { id: task.id }, data: { lastRun: new Date() } });
|
|
109
|
+
console.log(`[TaskScheduler] Задача "${task.name}" выполнена успешно`);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error(`[TaskScheduler] Критическая ошибка при выполнении задачи "${task.name}":`, error);
|
|
85
112
|
}
|
|
86
|
-
await prisma.scheduledTask.update({ where: { id: task.id }, data: { lastRun: new Date() } });
|
|
87
113
|
}
|
|
88
114
|
|
|
89
115
|
scheduleTask(task) {
|
|
@@ -98,13 +124,17 @@ class TaskScheduler {
|
|
|
98
124
|
return;
|
|
99
125
|
}
|
|
100
126
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
127
|
+
try {
|
|
128
|
+
const job = cron.schedule(task.cronPattern, () => this.executeTask(task), {
|
|
129
|
+
scheduled: true,
|
|
130
|
+
timezone: "Europe/Moscow"
|
|
131
|
+
});
|
|
105
132
|
|
|
106
|
-
|
|
107
|
-
|
|
133
|
+
this.scheduledJobs.set(task.id, job);
|
|
134
|
+
console.log(`[TaskScheduler] Задача "${task.name}" запланирована с паттерном: ${task.cronPattern}`);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error(`[TaskScheduler] Ошибка планирования задачи "${task.name}":`, error.message);
|
|
137
|
+
}
|
|
108
138
|
}
|
|
109
139
|
|
|
110
140
|
unscheduleTask(taskId) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Глубокое объединение объектов настроек
|
|
3
|
+
* @param {Object} defaultSettings - Настройки по умолчанию
|
|
4
|
+
* @param {Object} savedSettings - Сохраненные настройки
|
|
5
|
+
* @returns {Object} Объединенные настройки
|
|
6
|
+
*/
|
|
7
|
+
function deepMergeSettings(defaultSettings, savedSettings) {
|
|
8
|
+
const result = { ...defaultSettings };
|
|
9
|
+
|
|
10
|
+
for (const key in savedSettings) {
|
|
11
|
+
if (savedSettings.hasOwnProperty(key)) {
|
|
12
|
+
if (typeof savedSettings[key] === 'object' && savedSettings[key] !== null && !Array.isArray(savedSettings[key])) {
|
|
13
|
+
// Если это объект, рекурсивно объединяем
|
|
14
|
+
result[key] = deepMergeSettings(result[key] || {}, savedSettings[key]);
|
|
15
|
+
} else {
|
|
16
|
+
// Если это примитив или массив, просто заменяем
|
|
17
|
+
result[key] = savedSettings[key];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = { deepMergeSettings };
|