blockmine 1.4.6 → 1.4.7

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.
@@ -14,8 +14,7 @@
14
14
  "keywords": [],
15
15
  "author": "",
16
16
  "license": "ISC",
17
- "dependencies": {},
18
17
  "devDependencies": {
19
18
  "nodemon": "^3.1.2"
20
19
  }
21
- }
20
+ }
@@ -518,13 +518,36 @@ router.get('/:botId/management-data', authorize('management:view'), async (req,
518
518
  };
519
519
  })
520
520
 
521
- const [groups, users, allPermissions] = await Promise.all([
521
+ const page = parseInt(req.query.page) || 1;
522
+ const pageSize = parseInt(req.query.pageSize) || 100;
523
+
524
+ const userSkip = (page - 1) * pageSize;
525
+
526
+ const [groups, users, allPermissions, usersCount] = await Promise.all([
522
527
  prisma.group.findMany({ where: { botId }, include: { permissions: { include: { permission: true } } }, orderBy: { name: 'asc' } }),
523
- prisma.user.findMany({ where: { botId }, include: { groups: { include: { group: true } } }, orderBy: { username: 'asc' } }),
524
- prisma.permission.findMany({ where: { botId }, orderBy: { name: 'asc' } })
528
+ prisma.user.findMany({
529
+ where: { botId },
530
+ include: { groups: { include: { group: true } } },
531
+ orderBy: { username: 'asc' },
532
+ take: pageSize,
533
+ skip: userSkip,
534
+ }),
535
+ prisma.permission.findMany({ where: { botId }, orderBy: { name: 'asc' } }),
536
+ prisma.user.count({ where: { botId } })
525
537
  ]);
526
538
 
527
- res.json({ groups, permissions: allPermissions, users, commands: finalCommands });
539
+ res.json({
540
+ groups,
541
+ permissions: allPermissions,
542
+ users: {
543
+ items: users,
544
+ total: usersCount,
545
+ page,
546
+ pageSize,
547
+ totalPages: Math.ceil(usersCount / pageSize),
548
+ },
549
+ commands: finalCommands
550
+ });
528
551
 
529
552
  } catch (error) {
530
553
  console.error(`[API Error] /management-data for bot ${req.params.botId}:`, error);
@@ -558,7 +581,7 @@ router.put('/:botId/commands/:commandId', authorize('management:edit'), async (r
558
581
  data: dataToUpdate,
559
582
  });
560
583
 
561
- BotManager.invalidateConfigCache(botId);
584
+ BotManager.reloadBotConfigInRealTime(botId);
562
585
 
563
586
  res.json(updatedCommand);
564
587
  } catch (error) {
@@ -582,7 +605,7 @@ router.post('/:botId/groups', authorize('management:edit'), async (req, res) =>
582
605
  }
583
606
  });
584
607
 
585
- BotManager.invalidateConfigCache(botId);
608
+ BotManager.reloadBotConfigInRealTime(botId);
586
609
 
587
610
 
588
611
  res.status(201).json(newGroup);
@@ -618,7 +641,7 @@ router.put('/:botId/groups/:groupId', authorize('management:edit'), async (req,
618
641
  BotManager.invalidateUserCache(botId, user.username);
619
642
  }
620
643
 
621
- BotManager.invalidateConfigCache(botId);
644
+ BotManager.reloadBotConfigInRealTime(botId);
622
645
 
623
646
  res.status(200).send();
624
647
  } catch (error) {
@@ -636,7 +659,7 @@ router.delete('/:botId/groups/:groupId', authorize('management:edit'), async (re
636
659
  return res.status(403).json({ error: `Нельзя удалить группу с источником "${group.owner}".` });
637
660
  }
638
661
  await prisma.group.delete({ where: { id: groupId } });
639
- BotManager.invalidateConfigCache(botId);
662
+ BotManager.reloadBotConfigInRealTime(botId);
640
663
 
641
664
 
642
665
  res.status(204).send();
@@ -652,7 +675,7 @@ router.post('/:botId/permissions', authorize('management:edit'), async (req, res
652
675
  data: { name, description, botId, owner: 'admin' }
653
676
  });
654
677
 
655
- BotManager.invalidateConfigCache(botId);
678
+ BotManager.reloadBotConfigInRealTime(botId);
656
679
 
657
680
  res.status(201).json(newPermission);
658
681
  } catch (error) {
@@ -0,0 +1,55 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const { PrismaClient } = require('@prisma/client');
4
+ const prisma = new PrismaClient();
5
+
6
+ router.get('/', async (req, res) => {
7
+ const { query } = req.query;
8
+
9
+ if (!query) {
10
+ return res.status(400).json({ error: 'Query parameter is required' });
11
+ }
12
+
13
+ try {
14
+ const bots = await prisma.bot.findMany({
15
+ where: {
16
+ OR: [
17
+ { username: { contains: query } },
18
+ {
19
+ AND: [
20
+ { note: { not: null } },
21
+ { note: { contains: query } }
22
+ ]
23
+ },
24
+ ],
25
+ },
26
+ });
27
+
28
+ const users = await prisma.user.findMany({
29
+ where: {
30
+ username: {
31
+ contains: query,
32
+ },
33
+ },
34
+ });
35
+
36
+ const plugins = await prisma.installedPlugin.findMany({
37
+ where: {
38
+ name: {
39
+ contains: query,
40
+ },
41
+ },
42
+ });
43
+
44
+ res.json({
45
+ bots,
46
+ users,
47
+ plugins,
48
+ });
49
+ } catch (error) {
50
+ console.error('Search error:', error);
51
+ res.status(500).json({ error: 'Internal server error' });
52
+ }
53
+ });
54
+
55
+ module.exports = router;
@@ -96,6 +96,17 @@ class BotManager {
96
96
  }
97
97
  }
98
98
 
99
+ reloadBotConfigInRealTime(botId) {
100
+ this.invalidateConfigCache(botId);
101
+ const child = this.bots.get(botId);
102
+ if (child && !child.killed) {
103
+ child.send({ type: 'config:reload' });
104
+ console.log(`[BotManager] Sent config:reload to bot process ${botId}`);
105
+
106
+ getIO().emit('bot:config_reloaded', { botId });
107
+ }
108
+ }
109
+
99
110
  triggerHeartbeat() {
100
111
  if (!config.telemetry?.enabled) return;
101
112
  if (this.heartbeatDebounceTimer) {
@@ -560,6 +571,18 @@ class BotManager {
560
571
  }
561
572
  return { success: true };
562
573
  }
574
+
575
+ reloadBotConfigInRealTime(botId) {
576
+ this.invalidateConfigCache(botId);
577
+ const child = this.bots.get(botId);
578
+ if (child && !child.killed) {
579
+ child.send({ type: 'config:reload' });
580
+ console.log(`[BotManager] Sent config:reload to bot process ${botId}`);
581
+
582
+ const { getIO } = require('../real-time/socketHandler');
583
+ getIO().emit('bot:config_reloaded', { botId });
584
+ }
585
+ }
563
586
  }
564
587
 
565
588
  module.exports = new BotManager();
@@ -22,6 +22,29 @@ function sendLog(content) {
22
22
  }
23
23
  }
24
24
 
25
+ async function fetchNewConfig(botId) {
26
+ try {
27
+ const botData = await prisma.bot.findUnique({
28
+ where: { id: botId },
29
+ include: {
30
+ server: true,
31
+ installedPlugins: {
32
+ where: { isEnabled: true }
33
+ },
34
+ }
35
+ });
36
+
37
+ if (!botData) return null;
38
+
39
+ const commands = await prisma.command.findMany({ where: { botId } });
40
+
41
+ return { ...botData, commands };
42
+ } catch (error) {
43
+ sendLog(`[fetchNewConfig] Error: ${error.message}`);
44
+ return null;
45
+ }
46
+ }
47
+
25
48
  function handleIncomingCommand(type, username, message) {
26
49
  if (!message.startsWith(bot.config.prefix || '@')) return;
27
50
 
@@ -51,7 +74,7 @@ function handleIncomingCommand(type, username, message) {
51
74
  if (argDef.type === 'number') {
52
75
  const numValue = parseFloat(value);
53
76
  if (isNaN(numValue)) {
54
- bot.api.sendMessage(type, `Ошибка: Аргумент "${argDef.description}" должен быть числом.`, username);
77
+ bot.api.sendMessage(type, `Ошибка: Аргумент \"${argDef.description}\" должен быть числом.`, username);
55
78
  return;
56
79
  }
57
80
  value = numValue;
@@ -181,7 +204,7 @@ process.on('message', async (message) => {
181
204
  }
182
205
  });
183
206
  }
184
- sendLog(`[API] Команда "${commandInstance.name}" от плагина "${commandInstance.owner}" зарегистрирована в процессе.`);
207
+ sendLog(`[API] Команда \"${commandInstance.name}\" от плагина \"${commandInstance.owner}\" зарегистрирована в процессе.`);
185
208
  },
186
209
  performUserAction: (username, action, data = {}) => {
187
210
  return new Promise((resolve, reject) => {
@@ -283,6 +306,26 @@ process.on('message', async (message) => {
283
306
  sendLog(`[CRITICAL] Критическая ошибка при создании бота: ${err.stack}`);
284
307
  process.exit(1);
285
308
  }
309
+ } else if (message.type === 'config:reload') {
310
+ sendLog('[System] Received config:reload command. Reloading configuration...');
311
+ try {
312
+ const newConfig = await fetchNewConfig(bot.config.id);
313
+ if (newConfig) {
314
+ bot.config = { ...bot.config, ...newConfig };
315
+
316
+ const newCommands = await loadCommands();
317
+ const newPlugins = bot.config.plugins;
318
+
319
+ bot.commands = newCommands;
320
+ await initializePlugins(bot, newPlugins, true);
321
+
322
+ sendLog('[System] Bot configuration and plugins reloaded successfully.');
323
+ } else {
324
+ sendLog('[System] Failed to fetch new configuration.');
325
+ }
326
+ } catch (error) {
327
+ sendLog(`[System] Error reloading configuration: ${error.message}`);
328
+ }
286
329
  } else if (message.type === 'stop') {
287
330
  if (bot) bot.quit();
288
331
  else process.exit(0);
@@ -340,4 +383,4 @@ process.on('unhandledRejection', (reason, promise) => {
340
383
  sendLog(errorMsg);
341
384
  console.error(errorMsg, promise);
342
385
  process.exit(1);
343
- });
386
+ });
@@ -12,6 +12,7 @@ const serverRoutes = require('./api/routes/servers');
12
12
  const permissionsRoutes = require('./api/routes/permissions');
13
13
  const taskRoutes = require('./api/routes/tasks');
14
14
  const authRoutes = require('./api/routes/auth');
15
+ const searchRoutes = require('./api/routes/search');
15
16
  const BotManager = require('./core/BotManager');
16
17
  const TaskScheduler = require('./core/TaskScheduler');
17
18
  const panelRoutes = require('./api/routes/panel');
@@ -51,6 +52,7 @@ app.use('/api/bots', botRoutes);
51
52
  app.use('/api/plugins', pluginRoutes);
52
53
  app.use('/api/servers', serverRoutes);
53
54
  app.use('/api/permissions', permissionsRoutes);
55
+ app.use('/api/search', searchRoutes);
54
56
  app.use('/api/panel', panelRoutes);
55
57
 
56
58
  app.use(express.static(frontendPath));