diff --git a/.gitignore b/.gitignore index be85d62..b603449 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules test/npm-debug.log test/server +package-lock.json diff --git a/doc/README.md b/doc/README.md index b650d44..a023bde 100644 --- a/doc/README.md +++ b/doc/README.md @@ -21,6 +21,9 @@ automatically logged in and validated against mojang's auth. * customPackets (optional) : an object index by version/state/direction/name, see client_custom_packet for an example * errorHandler : A way to override the default error handler for client errors. A function that takes a Client and an error. The default kicks the client. + * stream : a stream to use as connection + * connect : a function taking the client as parameter and that should client.setSocket(socket) + and client.emit('connect') when appropriate (see the proxy examples for an example of use) ## mc.Server(version,[customPackets]) diff --git a/examples/client_http_proxy/client_http_proxy.js b/examples/client_http_proxy/client_http_proxy.js new file mode 100644 index 0000000..68e5185 --- /dev/null +++ b/examples/client_http_proxy/client_http_proxy.js @@ -0,0 +1,49 @@ +const mc = require('minecraft-protocol'); +const Http = require("http"); + +if(process.argv.length < 6 || process.argv.length > 8) { + console.log("Usage : node client_http_proxy.js [] []"); + process.exit(1); +} + +const proxyHost=process.argv[4]; +const proxyPort=process.argv[5]; + +const client = mc.createClient({ + connect:(client) => { + const req = Http.request({ + host: proxyHost, + port: proxyPort, + method: 'CONNECT', + path: process.argv[2] + ":" + parseInt(process.argv[3]) + }); + req.end(); + + req.on("connect", function(res, stream) { + client.setSocket(stream); + client.emit('connect'); + }); + }, + username: process.argv[6] ? process.argv[6] : "echo", + password: process.argv[7] +}); + +client.on('connect', function() { + console.info('connected'); +}); +client.on('disconnect', function(packet) { + console.log('disconnected: '+ packet.reason); +}); +client.on('end', function(err) { + console.log('Connection lost'); +}); +client.on('chat', function(packet) { + const jsonMsg = JSON.parse(packet.message); + if(jsonMsg.translate === 'chat.type.announcement' || jsonMsg.translate === 'chat.type.text') { + const username = jsonMsg.with[0].text; + const msg = jsonMsg.with[1]; + if(username === client.username) return; + client.write('chat', {message: msg}); + } +}); + diff --git a/examples/client_http_proxy/package.json b/examples/client_http_proxy/package.json new file mode 100644 index 0000000..15ca434 --- /dev/null +++ b/examples/client_http_proxy/package.json @@ -0,0 +1,7 @@ +{ + "name": "node-minecraft-protocol-example", + "version": "0.0.0", + "private": true, + "dependencies": {}, + "description": "A node-minecraft-protocol example" +} diff --git a/examples/client_socks_proxy/client_socks_proxy.js b/examples/client_socks_proxy/client_socks_proxy.js new file mode 100644 index 0000000..383cc5a --- /dev/null +++ b/examples/client_socks_proxy/client_socks_proxy.js @@ -0,0 +1,55 @@ +const mc = require('minecraft-protocol'); +const socks = require("socks"); + +if(process.argv.length < 6 || process.argv.length > 8) { + console.log("Usage : node client_socks_proxy.js [] []"); + process.exit(1); +} + +const proxyHost=process.argv[4]; +const proxyPort=process.argv[5]; + +const client = mc.createClient({ + connect: client => { + socks.createConnection({ + proxy: { + ipaddress: proxyHost, + port: proxyPort, + type: 5 + }, + target: { + host: process.argv[2], + port: parseInt(process.argv[3]) + }, + }, function(err, socket) { + if (err) { + console.log(err); + return; + } + + client.setSocket(socket); + client.emit('connect'); + }); + }, + username: process.argv[6] ? process.argv[6] : "echo", + password: process.argv[7] +}); + +client.on('connect', function() { + console.info('connected'); +}); +client.on('disconnect', function(packet) { + console.log('disconnected: '+ packet.reason); +}); +client.on('end', function(err) { + console.log('Connection lost'); +}); +client.on('chat', function(packet) { + const jsonMsg = JSON.parse(packet.message); + if(jsonMsg.translate === 'chat.type.announcement' || jsonMsg.translate === 'chat.type.text') { + const username = jsonMsg.with[0].text; + const msg = jsonMsg.with[1]; + if(username === client.username) return; + client.write('chat', {message: msg}); + } +}); diff --git a/examples/client_socks_proxy/package.json b/examples/client_socks_proxy/package.json new file mode 100644 index 0000000..95671a6 --- /dev/null +++ b/examples/client_socks_proxy/package.json @@ -0,0 +1,9 @@ +{ + "name": "node-minecraft-protocol-example", + "version": "0.0.0", + "private": true, + "dependencies": { + "socks": "^1.1.10" + }, + "description": "A node-minecraft-protocol example" +} diff --git a/src/client/autoVersion.js b/src/client/autoVersion.js index 23293cb..71f435a 100644 --- a/src/client/autoVersion.js +++ b/src/client/autoVersion.js @@ -9,9 +9,8 @@ const minecraft_data = require('minecraft-data'); module.exports = function(client, options) { client.wait_connect = true; // don't let src/client/setProtocol proceed on socket 'connect' until 'connect_allowed' debug('pinging',options.host); - const pingOptions = {host: options.host, port: options.port}; // TODO: use 0xfe ping instead for better compatibility/performance? https://github.com/deathcap/node-minecraft-ping - ping(pingOptions, function(err, response) { + ping(options, function(err, response) { if (err) throw err; // hmm debug('ping response',response); // TODO: could also use ping pre-connect to save description, type, max players, etc. diff --git a/src/client/tcp_dns.js b/src/client/tcp_dns.js index f0b5c33..110e4f8 100644 --- a/src/client/tcp_dns.js +++ b/src/client/tcp_dns.js @@ -5,9 +5,11 @@ module.exports = function(client, options) { options.port = options.port || 25565; options.host = options.host || 'localhost'; - options.connect = (client) => { + if(!options.connect) + options.connect = (client) => { if (options.stream) { client.setSocket(options.stream); + client.emit('connect'); } else if (options.port == 25565 && net.isIP(options.host) === 0) { dns.resolveSrv("_minecraft._tcp." + options.host, function(err, addresses) { if(addresses && addresses.length > 0) {