blockmine 1.0.6 → 1.0.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.
@@ -22,8 +22,8 @@
22
22
  "mineflayer": "^4.20.1",
23
23
  "multer": "^2.0.1",
24
24
  "pidusage": "^3.0.2",
25
+ "prisma": "^5.14.0",
25
26
  "semver": "^7.6.2",
26
- "simple-git": "^3.25.0",
27
27
  "socket.io": "^4.7.5",
28
28
  "socks": "^2.8.5"
29
29
  },
@@ -1,16 +1,15 @@
1
1
 
2
- const { simpleGit } = require('simple-git');
3
2
  const path = require('path');
4
3
  const fs = require('fs/promises');
5
4
  const { PrismaClient } = require('@prisma/client');
6
- const prisma = new PrismaClient();
5
+ const AdmZip = require('adm-zip');
7
6
  const semver = require('semver');
8
7
 
8
+ const prisma = new PrismaClient();
9
9
  const PLUGINS_BASE_DIR = path.resolve(__dirname, '../../storage/plugins');
10
10
 
11
11
  class PluginManager {
12
12
  constructor() {
13
- this.git = simpleGit();
14
13
  this.ensureBaseDirExists();
15
14
  }
16
15
 
@@ -25,34 +24,61 @@ class PluginManager {
25
24
  async installFromGithub(botId, repoUrl, prismaClient = prisma) {
26
25
  const botPluginsDir = path.join(PLUGINS_BASE_DIR, `bot_${botId}`);
27
26
  await fs.mkdir(botPluginsDir, { recursive: true });
28
- const repoName = path.basename(repoUrl, '.git');
29
- const localPath = path.join(botPluginsDir, repoName);
30
-
27
+
31
28
  const existing = await prismaClient.installedPlugin.findFirst({ where: { botId, sourceUri: repoUrl } });
32
29
  if (existing) throw new Error(`Плагин из ${repoUrl} уже установлен.`);
33
30
 
34
31
  try {
35
- await this.git.clone(repoUrl, localPath);
36
- const git = simpleGit(localPath);
37
- const response = await fetch("https://raw.githubusercontent.com/blockmineJS/official-plugins-list/main/index.json");
38
- const catalog = await response.json();
39
- const catalogInfo = catalog.find(p => p.repoUrl === repoUrl);
40
- if (catalogInfo && catalogInfo.latestTag) {
41
- await git.fetch(['--tags', '--force']);
42
- await git.checkout(catalogInfo.latestTag, ['-f']);
32
+ const url = new URL(repoUrl);
33
+ const repoPath = url.pathname.replace(/^\/|\.git$/g, '');
34
+ const archiveUrlMain = `https://github.com/${repoPath}/archive/refs/heads/main.zip`;
35
+ const archiveUrlMaster = `https://github.com/${repoPath}/archive/refs/heads/master.zip`;
36
+
37
+ let response = await fetch(archiveUrlMain);
38
+ if (!response.ok) {
39
+ console.log(`[PluginManager] Ветка 'main' не найдена для ${repoUrl}, пробую 'master'...`);
40
+ response = await fetch(archiveUrlMaster);
41
+ if (!response.ok) {
42
+ throw new Error(`Не удалось скачать архив плагина. Статус: ${response.status}`);
43
+ }
44
+ }
45
+ const buffer = await response.arrayBuffer();
46
+
47
+ const zip = new AdmZip(Buffer.from(buffer));
48
+ const zipEntries = zip.getEntries();
49
+ if (zipEntries.length === 0) {
50
+ throw new Error('Скачанный архив плагина пуст.');
43
51
  }
52
+ const rootFolderName = zipEntries[0].entryName.split('/')[0];
53
+ const repoName = path.basename(repoPath);
54
+ const localPath = path.join(botPluginsDir, repoName);
55
+
56
+ zip.extractAllTo(botPluginsDir, true);
57
+
58
+ await fs.rename(path.join(botPluginsDir, rootFolderName), localPath);
59
+
44
60
  return await this.registerPlugin(botId, localPath, 'GITHUB', repoUrl, prismaClient);
61
+
45
62
  } catch (error) {
46
- await fs.rm(localPath, { recursive: true, force: true }).catch(() => {});
63
+ console.error(`[PluginManager] Ошибка установки с GitHub: ${error.message}`);
64
+ if (error.message.includes('fetch')) {
65
+ throw new Error(`Не удалось подключиться к GitHub или репозиторий не найден. Проверьте ссылку и ваше интернет-соединение.`);
66
+ }
47
67
  throw error;
48
68
  }
49
69
  }
50
70
 
51
71
  async registerPlugin(botId, directoryPath, sourceType, sourceUri, prismaClient = prisma) {
52
72
  const packageJsonPath = path.join(directoryPath, 'package.json');
53
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
73
+ let packageJson;
74
+ try {
75
+ packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
76
+ } catch (e) {
77
+ throw new Error(`Не удалось прочитать или распарсить package.json в плагине по пути: ${directoryPath}`);
78
+ }
79
+
54
80
  if (!packageJson.name || !packageJson.version) {
55
- throw new Error('package.json не содержит name и version');
81
+ throw new Error('package.json не содержит обязательных полей name и version');
56
82
  }
57
83
 
58
84
  const pluginData = {
@@ -77,6 +103,8 @@ class PluginManager {
77
103
  const mainFile = manifest.main || 'index.js';
78
104
  const entryPointPath = path.join(plugin.path, mainFile);
79
105
 
106
+ await fs.access(entryPointPath);
107
+
80
108
  const pluginModule = require(entryPointPath);
81
109
 
82
110
  if (pluginModule && typeof pluginModule.onUnload === 'function') {
@@ -89,7 +117,9 @@ class PluginManager {
89
117
  }
90
118
 
91
119
  if (plugin.sourceType === 'GITHUB' || plugin.sourceType === 'IMPORTED') {
92
- await fs.rm(plugin.path, { recursive: true, force: true });
120
+ await fs.rm(plugin.path, { recursive: true, force: true }).catch(err => {
121
+ console.error(`Не удалось удалить папку плагина ${plugin.path}:`, err);
122
+ });
93
123
  }
94
124
  await prisma.installedPlugin.delete({ where: { id: pluginId } });
95
125
  }
@@ -106,8 +136,8 @@ class PluginManager {
106
136
  const catalogInfo = catalogMap.get(plugin.sourceUri);
107
137
  if (!catalogInfo || !catalogInfo.latestTag) continue;
108
138
 
109
- const localVersion = plugin.version;
110
- const recommendedVersion = semver.clean(catalogInfo.latestTag);
139
+ const localVersion = semver.coerce(plugin.version)?.version || plugin.version;
140
+ const recommendedVersion = semver.coerce(catalogInfo.latestTag)?.version || catalogInfo.latestTag;
111
141
 
112
142
  if (semver.gt(recommendedVersion, localVersion)) {
113
143
  updatesAvailable.push({
@@ -131,30 +161,15 @@ class PluginManager {
131
161
  throw new Error('Плагин не найден или не является GitHub-плагином.');
132
162
  }
133
163
 
134
- const pluginDirectory = plugin.path;
135
- try {
136
- const git = simpleGit(pluginDirectory);
137
- const response = await fetch("https://raw.githubusercontent.com/blockmineJS/official-plugins-list/main/index.json");
138
- const catalog = await response.json();
139
- const catalogInfo = catalog.find(p => p.repoUrl === plugin.sourceUri);
140
-
141
- if (!catalogInfo || !catalogInfo.latestTag) {
142
- throw new Error('Не найдена информация о проверенной версии в каталоге.');
143
- }
144
- const recommendedTag = catalogInfo.latestTag;
145
- await git.fetch(['--tags', '--force']);
146
- await git.checkout(recommendedTag, ['-f']);
147
-
148
- console.log(`[PluginManager] Плагин ${plugin.name} успешно обновлен до версии ${recommendedTag}.`);
149
-
150
- await prisma.installedPlugin.delete({ where: { id: plugin.id } });
151
- return await this.registerPlugin(plugin.botId, pluginDirectory, 'GITHUB', plugin.sourceUri);
152
-
153
- } catch (error) {
154
- console.error(`[PluginManager] Ошибка обновления плагина ${plugin.name}:`, error.message);
155
- try { await simpleGit(pluginDirectory).checkout('main', ['-f']); } catch(e) { }
156
- throw new Error(`Не удалось обновить плагин: ${error.message}`);
157
- }
164
+ console.log(`[PluginManager] Начало обновления плагина ${plugin.name}...`);
165
+
166
+ const repoUrl = plugin.sourceUri;
167
+ const botId = plugin.botId;
168
+
169
+ await this.deletePlugin(pluginId);
170
+ console.log(`[PluginManager] Старая версия ${plugin.name} удалена, устанавливаем новую...`);
171
+
172
+ return await this.installFromGithub(botId, repoUrl);
158
173
  }
159
174
  }
160
175
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  {
3
3
  "name": "blockmine",
4
- "version": "1.0.6",
4
+ "version": "1.0.7",
5
5
  "description": "Мощная панель управления ботами для Майнкрафта.",
6
6
  "author": "merka",
7
7
  "license": "MIT",