Spaces:
Sleeping
Sleeping
File size: 4,498 Bytes
2bf7a2b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | require('dotenv').config();
const express = require('express');
const path = require('path');
const { WebSocketServer } = require('ws');
const http = require('http');
const Database = require('./database');
const ConnectionManager = require('./websocket');
const { verifyApiKey, requireAdminKey, requireServerKey, requireAnyKey } = require('./auth');
const createKeysRouter = require('./routes/keys');
const createEventsRouter = require('./routes/events');
const createHealthRouter = require('./routes/health');
const createServerRouter = require('./routes/server');
const HOST = process.env.SERVER_HOST || '0.0.0.0';
const PORT = parseInt(process.env.SERVER_PORT || '8000');
const app = express();
const server = http.createServer(app);
const wss = new WebSocketServer({ noServer: true });
const db = new Database(process.env.DATABASE_PATH || 'minecraft_ws.db');
const manager = new ConnectionManager();
app.use(express.json());
app.use('/dashboard', express.static(path.join(__dirname, '../dashboard/public')));
app.get('/', (req, res) => {
res.json({
message: 'Minecraft WebSocket API Server (Node.js)',
dashboard: '/dashboard',
websocket: 'ws://' + req.get('host') + '/ws',
version: '1.0.0'
});
});
app.use('/manage/keys', verifyApiKey(db), requireAdminKey, createKeysRouter(db, requireAdminKey));
app.use('/api/events', verifyApiKey(db), requireAnyKey, createEventsRouter(db, manager, requireAnyKey));
app.use('/health', createHealthRouter(db, manager));
server.on('upgrade', async (request, socket, head) => {
const url = new URL(request.url, `http://${request.headers.host}`);
if (url.pathname === '/ws') {
const apiKey = url.searchParams.get('api_key');
if (!apiKey) {
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}
const result = await db.verifyApiKey(apiKey);
if (!result) {
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request, result);
});
} else {
socket.destroy();
}
});
wss.on('connection', (ws, request, apiKeyInfo) => {
manager.connect(ws, apiKeyInfo.id);
ws.on('message', (data) => {
try {
const msg = JSON.parse(data.toString());
if (msg.type === 'ping') {
ws.send(JSON.stringify({ type: 'pong' }));
}
} catch (error) {
}
});
ws.on('close', () => {
manager.disconnect(ws);
});
ws.on('error', () => {
manager.disconnect(ws);
});
});
async function startServer() {
console.log('🚀 启动Minecraft WebSocket API服务器...');
console.log('='.repeat(50));
await db.init();
const adminKeyInfo = await db.ensureInitialAdminKey();
if (adminKeyInfo) {
console.log('='.repeat(60));
console.log('重要: 已生成新的Admin Key!');
console.log(` 名称: ${adminKeyInfo.name}`);
console.log(` 密钥: ${adminKeyInfo.key}`);
console.log('请复制并安全保存此密钥。');
console.log('您需要使用它来管理API密钥。');
console.log('如果丢失此密钥且没有其他Admin Key,您可能失去管理员访问权限。');
console.log('='.repeat(60));
} else {
console.log('信息: 已找到现有Admin Key或Admin Key检查已执行。');
}
server.listen(PORT, HOST, () => {
console.log(`服务器地址: http://${HOST}:${PORT}`);
console.log(`WebSocket端点: ws://${HOST}:${PORT}/ws`);
console.log(`健康检查: http://${HOST}:${PORT}/health`);
console.log('='.repeat(50));
console.log();
console.log('💡 首次使用提示:');
console.log('1. 使用CLI工具创建API密钥:');
console.log(' node cli/cli.js create-key "MyServer"');
console.log();
console.log('2. 生成Minecraft插件配置文件:');
console.log(' node cli/cli.js generate-config');
console.log();
console.log('3. 将API密钥配置到Minecraft插件中');
console.log('='.repeat(50));
});
}
startServer().catch(error => {
console.error('❌ 启动失败:', error);
process.exit(1);
});
|