-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathping.js
More file actions
152 lines (145 loc) · 6.3 KB
/
ping.js
File metadata and controls
152 lines (145 loc) · 6.3 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
const dgram = require('dgram');
const varint = require('varint');
const minecraftData = require('minecraft-data');
const send = require('./send.js')
function createHandshake(ip, port, protocol, nextState) {
let packet = Buffer.concat([
Buffer.from([0x00]), // packet ID
Buffer.from(varint.encode(protocol)), //protocol version
Buffer.from([ip.length]),
Buffer.from(ip, 'utf-8'), // server address
Buffer.from(new Uint16Array([port]).buffer).reverse(), // server port
Buffer.from([nextState])
]);
var packetLength = Buffer.alloc(1);
packetLength.writeUInt8(packet.length);
return Buffer.concat([packetLength, packet]);
}
const magic = Buffer.from('00ffff00fefefefefdfdfdfd12345678', 'hex');
const timeBuffer = Buffer.allocUnsafe(8);
timeBuffer.writeBigInt64BE(BigInt(Date.now()), 0);
const clientGUID = Buffer.allocUnsafe(8);
for (let i = 0; i < 8; i++) clientGUID.writeUInt8(Math.floor(Math.random() * 256), i);
const bedrockPacket = Buffer.concat([Buffer.from([0x01]), timeBuffer, magic, clientGUID]);
module.exports = {
ping: async (ip, port, protocol, timeout) => {
try {
let packet = Buffer.concat([
createHandshake(ip, port, protocol, 1),
Buffer.from([0x01]), // second packet length
Buffer.from([0x00]) // status request
]);
let response = await send(ip, port, packet, timeout);
if (typeof response == 'string') {
return response;
}
if (response[0] != 0) {
return 'not minecraft';
}
response = response.subarray(1);
const fieldLength = varint.decode(response);
response = response.subarray(varint.decode.bytes, fieldLength + varint.decode.bytes).toString();
try {
return JSON.parse(response);
} catch (error) {
//console.log(error.toString(), response)
return 'error';
}
} catch (error) {
return 'error';
}
},
bedrockPing: (ip, port, protocol, timeout) => {
return new Promise((resolve, reject) => {
const timeoutCheck = setTimeout(() => {
client.close();
resolve('timeout');
}, timeout);
const magic = Buffer.from('00ffff00fefefefefdfdfdfd12345678', 'hex');
const timeBuffer = Buffer.allocUnsafe(8);
timeBuffer.writeBigInt64BE(BigInt(Date.now()), 0);
const clientGUID = Buffer.allocUnsafe(8);
for (let i = 0; i < 8; i++) clientGUID.writeUInt8(Math.floor(Math.random() * 256), i);
const packet = Buffer.concat([Buffer.from([0x01]), timeBuffer, magic, clientGUID]);
const client = dgram.createSocket('udp4');
client.on('error', (err) => {
console.log(`Error: ${err}`);
client.close();
clearTimeout(timeoutCheck);
resolve('error');
});
client.send(packet, port, ip, (err) => {
if (err) {
console.log('Error sending packet:', err);
client.close();
clearTimeout(timeoutCheck);
resolve('error');
}
});
client.on('message', (message, remote) => {
client.close();
clearTimeout(timeoutCheck);
try {
if (message[0] != 0x1c || message.length < 35) return resolve('invalid');
message = message.slice(33);
let len = message.slice(0, 2).readUint16BE();
if (message.length < len + 2) resolve('invalid');
message = message.slice(2, len + 2).toString();
let [edition, description, protocol, version, playerCount, maxPlayers, id, description2, gamemode, modeId, ipv4Port, ipv6Port] = message.split(';').map(a => a || null);
resolve({
edition,
version: {
name: version,
protocol
},
description,
description2,
players: {
online: playerCount,
max: maxPlayers
},
gamemode: {
name: gamemode,
id: modeId
},
port: {
ipv4: ipv4Port,
ipv6: ipv6Port
}
});
} catch (err) {
console.log(err)
resolve('error');
}
});
})
},
authCheck: async (ip, port, protocol, timeout) => {
try {
const mcData = minecraftData(protocol);
const username = 'Cornbread2100_';
const packetFormat = mcData.protocol.login.toServer.types.packet_login_start[1];
var buffers = [createHandshake(ip, port, protocol, 2), Buffer.from([0x00])];
for (var i = 0; i < packetFormat.length; i++) {
if (packetFormat[i].type.includes('option')) {
buffers.push(Buffer.from([0x00]));
} else {
switch (packetFormat[i].name) {
case 'username':
buffers.push(Buffer.from([username.length]));
buffers.push(Buffer.from(username, 'utf-8')); // username
break;
default:
break;
}
}
}
const startLoginPacket = Buffer.concat(buffers);
packetLength = Buffer.alloc(1);
packetLength.writeUInt8(startLoginPacket.length);
const response = await send(ip, port, Buffer.concat([buffer, packetLength, startLoginPacket]), 6000);
if (typeof response == 'string') return `Error: ${response}`;
else return response[0] == 0 ? 'unknown' : (response[0] != 1);
} catch (error) { return `Error: ${error}`; }
}
}