This repository has been archived by the owner on Feb 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
139 lines (117 loc) · 5.11 KB
/
index.js
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
const { Client, MessageEmbed, MessageAttachment } = require('discord.js');
const MongoClient = require('mongodb').MongoClient;
const net = require('net');
const { PacketOutUtil, PacketInUtil } = require('./util/NetworkUtil');
const { token, mongoURI } = require('./config.json');
const client = new Client();
function pingServer(host, port, protocol, timeout) {
return new Promise((resolve, reject) => {
let connectTime;
const socket = new net.createConnection({host: host, port: port});
socket.setNoDelay(true);
const timeoutHandler = setTimeout(() => {
socket.emit('error', new Error('No response from server.'));
}, timeout);
socket.on('connect', () => {
// See: https://wiki.vg/Server_List_Ping
const handshake = new PacketOutUtil(); // Handshake packet first
handshake.writeVarInt(0);
handshake.writeVarInt(protocol);
handshake.writeString(host);
handshake.writeUShort(port);
handshake.writeVarInt(1);
socket.write(handshake.build());
const request = new PacketOutUtil(); // Then the request packet
request.writeVarInt(0);
socket.write(request.build());
connectTime = new Date();
});
const response = new PacketInUtil();
socket.on('data', (data) => {
response.concat(data);
if(!response.isReady()) {
return;
}
clearTimeout(timeoutHandler);
socket.destroy();
const latency = Math.floor((new Date() - connectTime) / 2);
const packetId = response.readVarInt();
if(packetId !== 0) { // Handshake should be 0.
reject(new Error("Invalid packet id sent: " + packetId));
return;
}
const jsonResponse = JSON.parse(response.readString());
jsonResponse.ip = host.toLowerCase() + ":" + port;
jsonResponse.latency = latency;
resolve(jsonResponse);
// Mongo Logging
if(mongoURI && mongoURI.length > 0) {
MongoClient.connect(mongoURI, { useUnifiedTopology: true }, (err, db) => {
if(err)
throw err;
const dbo = db.db('discord-bot');
dbo.collection('pings').replaceOne({ ip: jsonResponse.ip }, jsonResponse, { upsert: true }, (err, result) => {
if(err)
throw err;
db.close();
});
});
}
});
socket.on('error', (error) => {
clearTimeout(timeoutHandler);
socket.destroy();
reject(error);
});
});
}
function faviconToBuffer(favicon) {
const matches = favicon.match(/^data:.+\/(.+);base64,(.*)$/);
return Buffer.from(matches[2], 'base64');
}
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', message => {
const msg = message.content.trim().toLowerCase();
if(msg.substr(0, 6) === '!ping ') {
const ip = msg.substr(6);
const validIpAddressRegex = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
const validHostnameRegex = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
if(!(ip.match(validIpAddressRegex) || ip.match(validHostnameRegex))) {
message.channel.send(`${message.author} I can\'t ping that. Sorry!`);
return;
}
console.log(`${message.author.tag}: Ping ${ip}`);
pingServer(ip, 25565, 753, 3000)
.then(result => {
const embed = new MessageEmbed();
if(result.favicon) {
const attachment = new MessageAttachment(faviconToBuffer(result.favicon));
embed.attachFiles(attachment);
}
embed.setTimestamp(Date.now());
embed.setURL(`https://${ip}`);
embed.setTitle(ip);
embed.setAuthor(`${result.players.online} / ${result.players.max}`)
embed.setFooter(result.version.name + " • " + result.latency + "ms");
const colorCodeCleaner = /§./g;
let color = null;
const desc = [result.description.text];
if(result.description.extra) {
for(let part of result.description.extra) {
if(part.text)
desc.push(part.text);
if(!color && part.color)
color = part.color.toUpperCase();
}
}
embed.setColor(color ? color : `RANDOM`);
embed.setDescription(desc.join("").replace(colorCodeCleaner, ''));
message.channel.send(embed);
}).catch(error => {
message.channel.send(`${ip} -> ` + error.toString().substring(0, 2000));
});
}
});
client.login(token);