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);
});