为了我的迷你项目的目的,我需要在客户端和某个服务器之间有一个代理服务器。这段代码可以工作,但又不起作用。它开始连接,通过登录并在加密时停止,然后一段时间后超时,我不明白为什么。我一直在重读 Minecraft 协议(https://wiki.vg/Protocol#Handshake)和握手,但我仍然不明白为什么它不起作用。 console.log() 用于调试,我从中推断出,无论出于何种原因,服务器永远不会发送设置的压缩/登录成功数据包。
var net = require('net');
var mcip = "mc.hypixel.net";
var mcport = 25565;
var server = net.createServer((socket) =>{
var remoteAddress = socket.remoteAddress + ':' + socket.remotePort;
console.log('new client connection from %s' + remoteAddress);
socket.on('data', (d)=>{
var client = net.connect(mcport,mcip, ()=>{
console.log("connected to server");
client.on("data", (data)=>{
socket.write(data);
console.log(data);
console.log("S -> C");
client.end();
});
client.write(d);
console.log(d);
console.log("C -> S");
});
});
});
server.listen(25565);
这里的一个大问题是,每次客户端发送数据时,您都会重新连接到 Hypixel!当您的客户端连接到您时,您需要重新安排它以仅连接到服务器一次。
socket.on('data', (d)=>{
var client = net.connect(mcport,mcip, ()=>{
console.log("connected to server");
client.on("data", (data)=>{
socket.write(data);
console.log(data);
console.log("S -> C");
client.end();
});
client.write(d);
console.log(d);
console.log("C -> S");
});
});
变成这样:
var client = net.connect(mcport,mcip, ()=>{
console.log("connected to server");
client.on("data", (data)=>{
socket.write(data);
console.log(data);
console.log("S -> C");
});
});
socket.on('data', (d)=>{
client.write(d);
console.log(d);
console.log("C -> S");
});
请注意,现在我们不会终止与 Hypixel 的连接,我们保持其打开状态并继续发送客户端数据。 (当客户端断开连接时,您应该在
socket.on('close', (hadError)=>{...})
处理程序中处理关闭连接)
完成此更改后,代理开始工作,但 Hypixel 会立即踢掉您,因为您没有通过正确的地址进行连接。在握手数据包中,您的连接 Minecraft 客户端会将服务器地址设置为您的代理服务器的地址,因为就其而言,这就是它所连接的地址。 Hypixel 发现这不是“mc.hypixel.net”并踢了客户端。
即使情况并非如此,一旦连接达到播放状态,您将无法看到任何有意义的数据(正如我怀疑您想要的那样),因为它全部由 aes CFB-8 流密码加密,使用 RSA 将密钥从 MC 客户端传递到服务器(您无法实际获取它)。
不要因此而灰心,这是有可能的。只是涉及更多。<->