blockmine 1.5.7 → 1.5.9

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.
@@ -160,6 +160,7 @@ process.on('message', async (message) => {
160
160
  version: config.server.version,
161
161
  auth: 'offline',
162
162
  hideErrors: false,
163
+ chat: 'enabled',
163
164
  };
164
165
 
165
166
  if (config.proxyHost && config.proxyPort) {
@@ -484,6 +485,10 @@ process.on('message', async (message) => {
484
485
  }
485
486
  });
486
487
 
488
+ bot.on('death', () => {
489
+ sendEvent('botDied', { user: { username: bot.username } });
490
+ });
491
+
487
492
  bot.on('kicked', (reason) => {
488
493
  let reasonText;
489
494
  try { reasonText = JSON.parse(reason).text || reason; } catch (e) { reasonText = reason; }
@@ -149,6 +149,9 @@ class EventGraphManager {
149
149
  case 'playerLeft':
150
150
  context.user = args.user;
151
151
  break;
152
+ case 'botDied':
153
+ context.user = args.user;
154
+ break;
152
155
  case 'tick':
153
156
  break;
154
157
  case 'entitySpawn':
@@ -536,18 +536,27 @@ class GraphExecutionEngine {
536
536
  }
537
537
 
538
538
  case 'string:contains': {
539
- const haystack = String(await this.resolvePinValue(node, 'haystack', ''));
540
- const needle = String(await this.resolvePinValue(node, 'needle', ''));
541
- const caseSensitive = await this.resolvePinValue(node, 'case_sensitive', true);
542
- result = caseSensitive ? haystack.includes(needle) : haystack.toLowerCase().includes(needle.toLowerCase());
539
+ if (pinId === 'result') {
540
+ const haystack = String(await this.resolvePinValue(node, 'haystack', ''));
541
+ const needle = String(await this.resolvePinValue(node, 'needle', ''));
542
+ const caseSensitive = await this.resolvePinValue(node, 'case_sensitive', false);
543
+
544
+ if (caseSensitive) {
545
+ return haystack.includes(needle);
546
+ } else {
547
+ return haystack.toLowerCase().includes(needle.toLowerCase());
548
+ }
549
+ }
543
550
  break;
544
551
  }
545
552
  case 'string:matches': {
546
- const str = String(await this.resolvePinValue(node, 'input', ''));
547
- const regexStr = String(await this.resolvePinValue(node, 'regex', ''));
548
- try {
549
- result = new RegExp(regexStr).test(str);
550
- } catch (e) { result = false; }
553
+ if (pinId === 'result') {
554
+ const str = String(await this.resolvePinValue(node, 'string', ''));
555
+ const regexStr = String(await this.resolvePinValue(node, 'regex', ''));
556
+ try {
557
+ result = new RegExp(regexStr).test(str);
558
+ } catch (e) { result = false; }
559
+ }
551
560
  break;
552
561
  }
553
562
  case 'data:string_literal':
@@ -876,6 +876,20 @@ class NodeRegistry {
876
876
  }
877
877
  });
878
878
 
879
+ this.registerNodeType({
880
+ type: 'event:botDied',
881
+ label: '💀 Бот умер',
882
+ category: 'События',
883
+ description: 'Срабатывает, когда бот умирает.',
884
+ graphType: event,
885
+ pins: {
886
+ inputs: [],
887
+ outputs: [
888
+ { id: 'exec', name: 'Выполнить', type: 'Exec' },
889
+ ]
890
+ }
891
+ });
892
+
879
893
  console.log(`NodeRegistry: Registered ${this.nodes.size} base nodes`);
880
894
  }
881
895
 
@@ -1,9 +1,7 @@
1
1
  const cron = require('node-cron');
2
- const { PrismaClient } = require('@prisma/client');
2
+ const prisma = require('../lib/prisma');
3
3
  const BotManager = require('./BotManager');
4
4
 
5
- const prisma = new PrismaClient();
6
-
7
5
  class TaskScheduler {
8
6
  constructor() {
9
7
  this.scheduledJobs = new Map();
@@ -112,6 +110,13 @@ class TaskScheduler {
112
110
  this.scheduleTask(updatedTask);
113
111
  }
114
112
  }
113
+
114
+ shutdown() {
115
+ console.log('[TaskScheduler] Остановка всех запланированных задач...');
116
+ this.scheduledJobs.forEach(job => job.stop());
117
+ this.scheduledJobs.clear();
118
+ console.log('[TaskScheduler] Все задачи остановлены.');
119
+ }
115
120
  }
116
121
 
117
122
  module.exports = new TaskScheduler();
@@ -0,0 +1,5 @@
1
+ const { PrismaClient } = require('@prisma/client');
2
+
3
+ const prisma = new PrismaClient();
4
+
5
+ module.exports = prisma;
@@ -5,27 +5,25 @@ let io;
5
5
 
6
6
  function initializeSocket(httpServer) {
7
7
  const corsOptions = {
8
- methods: ["GET", "POST"]
8
+ origin: true,
9
+ methods: ["GET", "POST"],
10
+ credentials: true
9
11
  };
10
12
 
11
- if (config.server.allowExternalAccess) {
12
- corsOptions.origin = "*";
13
- } else {
14
- corsOptions.origin = "http://localhost:5173";
15
- }
16
-
17
13
  io = new Server(httpServer, {
18
- cors: corsOptions
14
+ cors: corsOptions,
15
+ transports: ['websocket', 'polling']
19
16
  });
20
17
 
21
18
  io.on('connection', (socket) => {
22
- console.log('Socket.IO: Пользователь подключен -', socket.id);
19
+ // console.log(`[Socket.IO] Пользователь подключен: ${socket.id}. Всего клиентов: ${io.engine.clientsCount}`);
20
+
23
21
  socket.on('disconnect', () => {
24
- console.log('Socket.IO: Пользователь отключен -', socket.id);
22
+ // console.log(`[Socket.IO] Пользователь отключен: ${socket.id}. Всего клиентов: ${io.engine.clientsCount}`);
25
23
  });
26
24
  });
27
25
 
28
- console.log('Socket.IO инициализирован с CORS для:', corsOptions.origin);
26
+ // console.log('Socket.IO инициализирован с динамическим CORS.');
29
27
  return io;
30
28
  }
31
29
 
@@ -3,7 +3,7 @@ const http = require('http');
3
3
  const path = require('path');
4
4
  const fs = require('fs');
5
5
  const os = require('os');
6
- const { PrismaClient } = require('@prisma/client');
6
+ const prisma = require('./lib/prisma');
7
7
 
8
8
  const config = require('./config');
9
9
  const { initializeSocket } = require('./real-time/socketHandler');
@@ -57,6 +57,7 @@ app.use('/api/bots', botRoutes);
57
57
  app.use('/api/plugins', pluginRoutes);
58
58
  app.use('/api/servers', serverRoutes);
59
59
  app.use('/api/permissions', permissionsRoutes);
60
+ app.use('/api/search', searchRoutes);
60
61
  app.use('/api/panel', panelRoutes);
61
62
 
62
63
  app.use(express.static(frontendPath));
@@ -75,9 +76,7 @@ app.get(/^(?!\/api).*/, (req, res) => {
75
76
  });
76
77
 
77
78
  async function runStartupMigrations() {
78
- const prisma = new PrismaClient();
79
79
  try {
80
- // 1. Migrate legacy '*' permission for Admin role
81
80
  const adminRole = await prisma.panelRole.findUnique({ where: { name: 'Admin' } });
82
81
  if (adminRole) {
83
82
  const permissions = JSON.parse(adminRole.permissions);
@@ -93,7 +92,6 @@ async function runStartupMigrations() {
93
92
  }
94
93
  }
95
94
 
96
- // 2. Ensure root user (ID 1) has all permissions
97
95
  const rootUser = await prisma.panelUser.findUnique({ where: { id: 1 }, include: { role: true } });
98
96
  if (rootUser && rootUser.role) {
99
97
  const allPermissions = ALL_PERMISSIONS.map(p => p.id).filter(id => id !== '*');
@@ -109,8 +107,6 @@ async function runStartupMigrations() {
109
107
  }
110
108
  } catch (error) {
111
109
  console.error('[Migration] Ошибка во время миграции прав:', error);
112
- } finally {
113
- await prisma.$disconnect();
114
110
  }
115
111
  }
116
112
 
@@ -145,26 +141,35 @@ async function startServer() {
145
141
  });
146
142
  }
147
143
 
148
- const gracefulShutdown = (signal) => {
149
- console.log(`[Shutdown] Получен сигнал ${signal}. Начинаем завершение...`);
150
-
144
+
145
+ const gracefulShutdown = async (signal) => {
146
+ console.log(`[Shutdown] Получен сигнал ${signal}. Начинаем корректное завершение...`);
147
+
148
+ TaskScheduler.shutdown();
149
+
151
150
  const botIds = Array.from(botManager.bots.keys());
152
151
  if (botIds.length > 0) {
153
152
  console.log(`[Shutdown] Остановка ${botIds.length} активных ботов...`);
154
- for (const botId of botIds) {
155
- botManager.stopBot(botId);
156
- }
153
+ await Promise.all(botIds.map(botId => botManager.stopBot(botId)));
154
+ console.log('[Shutdown] Все боты остановлены.');
157
155
  }
158
156
 
159
- server.close(() => {
160
- console.log('[Shutdown] HTTP сервер закрыт. Завершение процесса.');
161
- process.exit(0);
162
- });
157
+ const io = require('./real-time/socketHandler').getIO();
158
+ if (io) {
159
+ io.close(async () => {
160
+ console.log('[Shutdown] WebSocket сервер закрыт.');
161
+
162
+ await new Promise(resolve => server.close(resolve));
163
+ console.log('[Shutdown] HTTP сервер закрыт.');
164
+
165
+ const prisma = require('./lib/prisma');
166
+ await prisma.$disconnect();
167
+ console.log('[Shutdown] Соединение с БД закрыто.');
163
168
 
164
- setTimeout(() => {
165
- console.error('[Shutdown] Не удалось закрыть соединения вовремя, принудительное завершение.');
166
- process.exit(1);
167
- }, 5000);
169
+ console.log('[Shutdown] Корректное завершение выполнено.');
170
+ process.exit(0);
171
+ });
172
+ }
168
173
  };
169
174
 
170
175
  process.on('SIGUSR2', () => gracefulShutdown('SIGUSR2 (nodemon)'));