mirror of
https://github.com/xnite/MCSeeker.git
synced 2026-05-02 12:54:50 -07:00
initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
package-lock.json
|
||||||
|
node_modules/
|
||||||
35
README.md
Normal file
35
README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# What is this?
|
||||||
|
This scans for MineCraft servers... really really fast!
|
||||||
|
|
||||||
|
# Getting Started
|
||||||
|
* Clone this repository somewhere.
|
||||||
|
* Run `npm install` from within this directory.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Run `node ./scanner.js [options] --ip <ip range>`
|
||||||
|
|
||||||
|
### Example
|
||||||
|
`node ./scanner.js --ip 192.168.1.0/24 --port 25565-25569 --show-desc --min-players 1 --max-players 100 --out report.csv`
|
||||||
|
|
||||||
|
### CLI Options
|
||||||
|
* `--ip <ip>` - IP Address or Range of IP Addresses with CIDR notation (eg- 192.168.1.0/24)
|
||||||
|
* `--port <ports>` - Ports to look for minecraft servers on. (Default: `25565-25566`)
|
||||||
|
* `--show-desc` - Enable showing of server description in output.
|
||||||
|
* `--quiet` - Silence terminal output.
|
||||||
|
* `--min-players <count>` - Minimum number of players to display.
|
||||||
|
* `--max-players <count>` - Only show servers with max player count or below.
|
||||||
|
* `--out <filename>` - Output to CSV file (Can be opened as a spreadsheet in MS Office, Google Docs, etc.)
|
||||||
|
|
||||||
|
## By really fast, I mean really fast!
|
||||||
|
# time node ./scanner.js --ip 135.148.60.0/24 --show-desc --quiet --out example.csv
|
||||||
|
Scanning ports 25565-25566 on 135.148.60.0/24
|
||||||
|
Scan finished!
|
||||||
|
|
||||||
|
real 0m3.183s
|
||||||
|
user 0m0.825s
|
||||||
|
sys 0m0.334s
|
||||||
|
At this speed, a full /16 (123.45.0.0 - 123.45.255.255) will take about 13 and a half minutes to scan.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
* Fails to scan more than a /16 without kicking the bucket... so you should probably stick to that or smaller ranges.
|
||||||
|
* Working on a Minecraft bot client... doesn't work though... you can see how badly it doesn't work by using `--enable-client` flag... it is totally broken. **Don't use it**.
|
||||||
8
package.json
Normal file
8
package.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"commandos": "^0.10.1",
|
||||||
|
"evilscan": "^1.8.1",
|
||||||
|
"minecraft-status": "^1.1.0",
|
||||||
|
"mineflayer": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
125
scanner.js
Normal file
125
scanner.js
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
var Scanner = require('evilscan');
|
||||||
|
var status = require('minecraft-status').MinecraftServerListPing;
|
||||||
|
var mc = require('mineflayer');
|
||||||
|
var fs = require('fs');
|
||||||
|
//var mcClient = require('minecraft-protocol');
|
||||||
|
process.params = (require('commandos')).parse(process.argv);
|
||||||
|
var MINECRAFT_DEFAULT_PORT = '25565-25566';
|
||||||
|
var SCAN_MIN_PLAYERS = (process.params['min-players'] || 0);
|
||||||
|
var SCAN_OPTS_HOSTS = (process.params['ip']||'0.0.0.0/0').toString();
|
||||||
|
var SCAN_OPTS_PORTS = (process.params['port'] || MINECRAFT_DEFAULT_PORT).toString();
|
||||||
|
var SCAN_OPTS_OUTPUT_CSV = (process.params['out']||null);
|
||||||
|
var CLIENT_TOKEN;
|
||||||
|
|
||||||
|
if(process.params['quiet'] && !SCAN_OPTS_OUTPUT_CSV)
|
||||||
|
{
|
||||||
|
console.log("Error:\tYou have asked for --quiet output, but did not specify an --out file. This scan is pointless!\nRefusing to run a pointless operation.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(process.params['enable-client'] && !process.params['client-token'])
|
||||||
|
{
|
||||||
|
const https = require('https');
|
||||||
|
|
||||||
|
https.get("https://api.thealtening.com/free/generate", res => {
|
||||||
|
let data = [];
|
||||||
|
res.on('data', chunk => {
|
||||||
|
data.push(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on('end', () => {
|
||||||
|
var fullBuffer = Buffer.concat(data);
|
||||||
|
var output;
|
||||||
|
try {
|
||||||
|
output = JSON.parse((fullBuffer || '{}').toString());
|
||||||
|
} catch(e) {
|
||||||
|
console.log(fullBuffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT_TOKEN = ((output||{}).token||null);
|
||||||
|
console.log(CLIENT_TOKEN||"No token!");
|
||||||
|
});
|
||||||
|
}).on('error', err => {
|
||||||
|
//console.log('Error: ', err.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Scanning ports " + SCAN_OPTS_PORTS + " on " + SCAN_OPTS_HOSTS);
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
target: SCAN_OPTS_HOSTS,
|
||||||
|
port: SCAN_OPTS_PORTS,
|
||||||
|
states: 'O',
|
||||||
|
banner: false,
|
||||||
|
concurrency: 255
|
||||||
|
}
|
||||||
|
var scan = new Scanner(options);
|
||||||
|
|
||||||
|
function placeTabs(string)
|
||||||
|
{
|
||||||
|
var count = Math.floor(string.length / 4);
|
||||||
|
for(i=0; i <= count; i++)
|
||||||
|
{
|
||||||
|
string += "\t";
|
||||||
|
}
|
||||||
|
if(count <= 1)
|
||||||
|
{
|
||||||
|
string += "\t\t";
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
scan.on('result', function(data){
|
||||||
|
//console.log(data);
|
||||||
|
status.ping(757, data.ip, data.port, (process.params['timeout']||15)*1000).then(function(pingRes){
|
||||||
|
if (pingRes.players.online >= SCAN_MIN_PLAYERS && (!process.params['max-players'] || (process.params['max-players'] && pingRes.players.max <= process.params['max-players'])))
|
||||||
|
{
|
||||||
|
var theText = data.ip + ":" + data.port + "\t" + pingRes.version.name + "\t" + pingRes.players.online + " of " + pingRes.players.max + " players";
|
||||||
|
if(process.params['show-desc'])
|
||||||
|
{
|
||||||
|
theText += "\t"+pingRes.description.text;
|
||||||
|
}
|
||||||
|
if (SCAN_OPTS_OUTPUT_CSV)
|
||||||
|
{
|
||||||
|
fs.appendFileSync(SCAN_OPTS_OUTPUT_CSV, data.ip+":"+data.port+","+pingRes.version.name.replace(/\,/g, '+')+","+pingRes.players.online+"/"+pingRes.players.max+"\n");
|
||||||
|
}
|
||||||
|
if(!process.params['quiet'])
|
||||||
|
{
|
||||||
|
console.log(theText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(process.params['enable-client'] && (CLIENT_TOKEN||process.params['client-token']))
|
||||||
|
{
|
||||||
|
var client = mc.createBot({
|
||||||
|
host: data.ip, // optional
|
||||||
|
port: data.port, // optional
|
||||||
|
token: (CLIENT_TOKEN||process.params['client-token']),
|
||||||
|
auth: 'mojang', // optional; by default uses mojang, if using a microsoft account, set to 'microsoft'
|
||||||
|
protocol: pingRes.version.protocol
|
||||||
|
});
|
||||||
|
client.on('chat', function (packet) {
|
||||||
|
// Listen for chat messages and echo them back.
|
||||||
|
var jsonMsg = JSON.parse(packet.message);
|
||||||
|
if (jsonMsg.translate == 'chat.type.announcement' || jsonMsg.translate == 'chat.type.text') {
|
||||||
|
var username = jsonMsg.with[0].text;
|
||||||
|
var msg = jsonMsg.with[1];
|
||||||
|
if (username === client.username) return;
|
||||||
|
console.log(msg);
|
||||||
|
//client.write('chat', { message: msg.text });
|
||||||
|
client.end("Logout");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch(function(error){
|
||||||
|
//console.log(error);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
scan.on('error', err => {
|
||||||
|
//console.log(err.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
scan.on('done', () => {
|
||||||
|
console.log("Scan finished!");
|
||||||
|
});
|
||||||
|
scan.run();
|
||||||
Reference in New Issue
Block a user