mirror of
https://github.com/GSManagerXZ/GameServerManager.git
synced 2026-05-30 17:39:45 +08:00
完善mc部署2
This commit is contained in:
@@ -319,6 +319,44 @@ const GameDeploymentPage: React.FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 取消Minecraft下载
|
||||
const cancelMinecraftDownload = async () => {
|
||||
if (!currentDownloadId.current) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
title: '取消失败',
|
||||
message: '没有正在进行的下载任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiClient.cancelMinecraftDownload(currentDownloadId.current)
|
||||
|
||||
if (response.success) {
|
||||
// 重置下载状态
|
||||
setMinecraftDownloading(false)
|
||||
setDownloadProgress(null)
|
||||
currentDownloadId.current = null
|
||||
|
||||
addNotification({
|
||||
type: 'info',
|
||||
title: '下载已取消',
|
||||
message: 'Minecraft服务端下载已取消'
|
||||
})
|
||||
} else {
|
||||
throw new Error(response.message || '取消下载失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('取消下载失败:', error)
|
||||
addNotification({
|
||||
type: 'error',
|
||||
title: '取消失败',
|
||||
message: error.message || '无法取消下载'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 创建Minecraft实例
|
||||
const createMinecraftInstance = async () => {
|
||||
if (!instanceName.trim() || !downloadResult) {
|
||||
@@ -782,28 +820,41 @@ const GameDeploymentPage: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* 下载按钮 */}
|
||||
<button
|
||||
onClick={downloadMinecraftServer}
|
||||
disabled={
|
||||
!selectedServer ||
|
||||
!selectedVersion ||
|
||||
!minecraftInstallPath.trim() ||
|
||||
minecraftDownloading
|
||||
}
|
||||
className="w-full bg-green-600 hover:bg-green-700 disabled:bg-gray-400 text-white py-3 px-4 rounded-lg transition-colors flex items-center justify-center space-x-2"
|
||||
>
|
||||
{minecraftDownloading ? (
|
||||
<>
|
||||
<Loader className="w-4 h-4 animate-spin" />
|
||||
<span>下载中...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Download className="w-4 h-4" />
|
||||
<span>下载服务端</span>
|
||||
</>
|
||||
<div className="space-y-2">
|
||||
<button
|
||||
onClick={downloadMinecraftServer}
|
||||
disabled={
|
||||
!selectedServer ||
|
||||
!selectedVersion ||
|
||||
!minecraftInstallPath.trim() ||
|
||||
minecraftDownloading
|
||||
}
|
||||
className="w-full bg-green-600 hover:bg-green-700 disabled:bg-gray-400 text-white py-3 px-4 rounded-lg transition-colors flex items-center justify-center space-x-2"
|
||||
>
|
||||
{minecraftDownloading ? (
|
||||
<>
|
||||
<Loader className="w-4 h-4 animate-spin" />
|
||||
<span>下载中...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Download className="w-4 h-4" />
|
||||
<span>下载服务端</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{/* 取消下载按钮 */}
|
||||
{minecraftDownloading && (
|
||||
<button
|
||||
onClick={cancelMinecraftDownload}
|
||||
className="w-full bg-red-600 hover:bg-red-700 text-white py-2 px-4 rounded-lg transition-colors flex items-center justify-center space-x-2"
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
<span>取消下载</span>
|
||||
</button>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 下载进度 */}
|
||||
{(downloadProgress || minecraftDownloading) && (
|
||||
|
||||
@@ -413,6 +413,10 @@ class ApiClient {
|
||||
return this.post('/minecraft/download', data)
|
||||
}
|
||||
|
||||
async cancelMinecraftDownload(downloadId: string) {
|
||||
return this.post('/minecraft/cancel-download', { downloadId })
|
||||
}
|
||||
|
||||
async createMinecraftInstance(data: {
|
||||
name: string
|
||||
description?: string
|
||||
|
||||
@@ -406,10 +406,37 @@ export class FileManager {
|
||||
export class MinecraftServerDownloader {
|
||||
private onProgress?: ProgressCallback;
|
||||
private onLog?: LogCallback;
|
||||
private cancelled: boolean = false;
|
||||
private downloadId?: string;
|
||||
|
||||
constructor(onProgress?: ProgressCallback, onLog?: LogCallback) {
|
||||
constructor(onProgress?: ProgressCallback, onLog?: LogCallback, downloadId?: string) {
|
||||
this.onProgress = onProgress;
|
||||
this.onLog = onLog;
|
||||
this.downloadId = downloadId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消下载
|
||||
*/
|
||||
cancel(): void {
|
||||
this.cancelled = true;
|
||||
if (this.onLog) {
|
||||
this.onLog('下载已被用户取消', 'warn');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已取消
|
||||
*/
|
||||
isCancelled(): boolean {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载ID
|
||||
*/
|
||||
getDownloadId(): string | undefined {
|
||||
return this.downloadId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,6 +456,11 @@ export class MinecraftServerDownloader {
|
||||
const log = silent ? undefined : this.onLog;
|
||||
|
||||
try {
|
||||
// 检查是否已取消
|
||||
if (this.cancelled) {
|
||||
throw new Error('下载已被取消');
|
||||
}
|
||||
|
||||
// 验证Java环境(除非跳过)
|
||||
if (!skipJavaCheck) {
|
||||
if (log) log('检查Java环境...', 'info');
|
||||
@@ -443,23 +475,43 @@ export class MinecraftServerDownloader {
|
||||
throw new Error('缺少必要参数:server 和 version');
|
||||
}
|
||||
|
||||
// 检查是否已取消
|
||||
if (this.cancelled) {
|
||||
throw new Error('下载已被取消');
|
||||
}
|
||||
|
||||
// 创建临时目录
|
||||
if (log) log('创建临时工作目录...', 'info');
|
||||
const tempDir = await FileManager.createTempDirectory();
|
||||
if (log) log(`临时目录创建成功: ${tempDir}`, 'success');
|
||||
|
||||
try {
|
||||
// 检查是否已取消
|
||||
if (this.cancelled) {
|
||||
throw new Error('下载已被取消');
|
||||
}
|
||||
|
||||
// 获取下载地址
|
||||
if (log) log('正在获取下载地址...', 'info');
|
||||
const downloadData = await ApiService.getDownloadUrl(server, version);
|
||||
if (log) log('下载地址获取成功。', 'success');
|
||||
|
||||
// 检查是否已取消
|
||||
if (this.cancelled) {
|
||||
throw new Error('下载已被取消');
|
||||
}
|
||||
|
||||
// 下载服务端核心
|
||||
const jarPath = FileManager.getServerJarPath(server, version);
|
||||
if (log) log(`正在下载服务端核心到: ${jarPath}`, 'info');
|
||||
await ApiService.downloadFile(downloadData.url, jarPath, this.onProgress, log);
|
||||
if (log) log('服务端核心下载完成。', 'success');
|
||||
|
||||
// 检查是否已取消
|
||||
if (this.cancelled) {
|
||||
throw new Error('下载已被取消');
|
||||
}
|
||||
|
||||
// 运行服务端直到EULA协议(除非跳过)
|
||||
if (!skipServerRun) {
|
||||
if (log) log('正在运行服务端核心...', 'info');
|
||||
@@ -468,6 +520,11 @@ export class MinecraftServerDownloader {
|
||||
if (log) log('服务端运行完成。', 'success');
|
||||
}
|
||||
|
||||
// 检查是否已取消
|
||||
if (this.cancelled) {
|
||||
throw new Error('下载已被取消');
|
||||
}
|
||||
|
||||
// 移动文件到目标目录
|
||||
if (log) log(`正在移动文件到目标目录: ${targetDirectory}`, 'info');
|
||||
await FileManager.moveFilesToTarget(targetDirectory, log);
|
||||
|
||||
@@ -10,6 +10,9 @@ const router = Router()
|
||||
let io: SocketIOServer
|
||||
let instanceManager: InstanceManager
|
||||
|
||||
// 全局下载器管理器
|
||||
const activeDownloads = new Map<string, MinecraftServerDownloader>()
|
||||
|
||||
// 设置Socket.IO和InstanceManager
|
||||
export function setMinecraftDependencies(socketIO: SocketIOServer, instManager: InstanceManager) {
|
||||
io = socketIO
|
||||
@@ -39,6 +42,50 @@ router.get('/server-categories', async (req: Request, res: Response) => {
|
||||
}
|
||||
})
|
||||
|
||||
// 取消Minecraft服务端下载
|
||||
router.post('/cancel-download', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { downloadId } = req.body
|
||||
|
||||
if (!downloadId) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '缺少下载ID参数'
|
||||
})
|
||||
}
|
||||
|
||||
// 查找活跃的下载任务
|
||||
const downloader = activeDownloads.get(downloadId)
|
||||
|
||||
if (!downloader) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '未找到指定的下载任务'
|
||||
})
|
||||
}
|
||||
|
||||
// 取消下载
|
||||
downloader.cancel()
|
||||
|
||||
// 从活跃下载列表中移除
|
||||
activeDownloads.delete(downloadId)
|
||||
|
||||
logger.info(`下载任务已取消: ${downloadId}`)
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '下载已取消'
|
||||
})
|
||||
|
||||
} catch (error: any) {
|
||||
logger.error('取消下载失败:', error)
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || '取消下载失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 获取指定服务端的可用版本
|
||||
router.get('/versions/:server', async (req: Request, res: Response) => {
|
||||
try {
|
||||
@@ -172,9 +219,14 @@ router.post('/download', async (req: Request, res: Response) => {
|
||||
})
|
||||
}
|
||||
logger.info(`[${type.toUpperCase()}] ${message}`)
|
||||
}
|
||||
},
|
||||
// 下载ID
|
||||
downloadId
|
||||
)
|
||||
|
||||
// 将下载器添加到活跃下载列表
|
||||
activeDownloads.set(downloadId, downloader)
|
||||
|
||||
// 执行下载
|
||||
await downloader.downloadServer({
|
||||
server,
|
||||
@@ -186,6 +238,9 @@ router.post('/download', async (req: Request, res: Response) => {
|
||||
|
||||
logger.info(`Minecraft服务端下载完成: ${server} ${version}`)
|
||||
|
||||
// 从活跃下载列表中移除
|
||||
activeDownloads.delete(downloadId)
|
||||
|
||||
// 下载完成,发送完成事件
|
||||
if (io && socketId) {
|
||||
io.to(socketId).emit('minecraft-download-complete', {
|
||||
@@ -203,6 +258,9 @@ router.post('/download', async (req: Request, res: Response) => {
|
||||
} catch (error: any) {
|
||||
logger.error('Minecraft服务端下载失败:', error)
|
||||
|
||||
// 从活跃下载列表中移除
|
||||
activeDownloads.delete(downloadId)
|
||||
|
||||
// 发送错误事件
|
||||
if (io && socketId) {
|
||||
io.to(socketId).emit('minecraft-download-error', {
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user