I am trying to convert the following PHP code to Node.JS code:
PHP
$TimeStart = microtime(true); // for read timeout purposes
// See http://wiki.vg/Protocol (Status Ping)
$Data = "\x00"; // packet ID = 0 (varint)
$Data .= "\x04"; // Protocol version (varint)
$Data .= Pack( 'c', StrLen( $this->ServerAddress ) ) . $this->ServerAddress; // Server (varint len + UTF-8 addr)
$Data .= Pack( 'n', $this->ServerPort ); // Server port (unsigned short)
$Data .= "\x01"; // Next state: status (varint)
$Data = Pack( 'c', StrLen( $Data ) ) . $Data; // prepend length of packet ID + data
fwrite( $this->Socket, $Data ); // handshake
fwrite( $this->Socket, "\x01\x00" ); // status ping
$Length = $this->ReadVarInt( ); // full packet length
if( $Length < 10 )
{
return FALSE;
}
fgetc( $this->Socket ); // packet type, in server ping it's 0
$Length = $this->ReadVarInt( ); // string length
$Data = "";
do
{
if (microtime(true) - $TimeStart > $this->Timeout)
{
//exception
}
$Remainder = $Length - StrLen( $Data );
$block = fread( $this->Socket, $Remainder ); // and finally the json string
// abort if there is no progress
if (!$block)
{
//exception
}
$Data .= $block;
} while( StrLen($Data) < $Length );
This is what i thought it was but apparently it's not the same as i dont get any data returned.
var socket = new net.Socket();
socket = net.connect(port, host, function(){
console.log('Connected');
/*
Returns data but protocol is not correctly folllowed
-----------------------------------------------------*/
var PACKET_HEAD = new Buffer([
0, // Packet ID 0
4 // Version 4 (1.7.2), 5 is 1.7.6
]);
var PACKET_PORT = new Buffer(2);
var PACKET_NEXTSTATE = new Buffer([1]);
var PACKET_STATUS_REQ = new Buffer([1, 0]);
host = new Buffer(host);
var addrLen = new Buffer(varint.encode(host.length));
PACKET_PORT.writeUInt16BE(port, 0);
var packetLength = 2 + addrLen.length + host.length + 2 + 1;
var lengthBuffer = new Buffer(varint.encode(packetLength));
var packet = Buffer.concat([
lengthBuffer,
PACKET_HEAD,
addrLen,
host,
PACKET_PORT,
PACKET_NEXTSTATE,
PACKET_STATUS_REQ
], packetLength + 3);
socket.write(packet);
/*
TRY 1
------*/
var packet;
packet = "\x00";
packet += "\x04";
packet += bufferpack.pack('c', host.length.toString()) + host;
packet += bufferpack.pack('n', port.toString());
packet += "\x01";
packet = bufferpack.pack('c', packet.length.toString()) + packet;
socket.write(packet);
socket.write("\x01\x00");
/*TRY 2
-------*/
var packet;
packet = packData(
'\x00\x00'
+ packData(host.toString('utf8'))
+ packPort(port)
+ '\x01'
);
socket.write(packet);
socket.write(packData('\x00'));
});
socket.on('error', function(err){
console.log(errorHandler(err));
socket.end();
});
socket.on('data', function(data){
console.log(data);
socket.end();
});
setTimeout(function(){
console.log("Timeout");
socket.end();
socket.destroy();
}, 1000);
function char(value) {
return value.toString().charCodeAt(0);
}
function packData(data) {
return varint.encode(data.length) + data;
}
function packPort(data) {
return bufferpack.pack('>H', data.toString());
}
I have tried numerous ways to replicate the php code to nodejs end ended up using libraries that mimic the pack behavior (bufferpack).
I think i am missing something but i can't figure out what it is.
Maybe a bit late, but I've made your code working for me.
The module I've used: https://github.com/ryanrolds/bufferpack
installing using: npm install bufferpack
This is the plain code (copied)
var _connection;
var connect = function(port, host, callback) {
_connection = new net.Socket();
_connection.connect(port, host, function() {
system.log('Connected to the server, authenticating now.');
var PACKET_HEAD = new Buffer([
0, // Packet ID 0
47 // Version 4 (1.7.2), 5 is 1.7.6
]);
var PACKET_PORT = new Buffer(2);
var PACKET_NEXTSTATE = new Buffer([1]);
var PACKET_STATUS_REQ = new Buffer([1, 0]);
host = new Buffer(host);
var addrLen = new Buffer(varint.encode(host.length));
PACKET_PORT.writeUInt16BE(port, 0);
var packetLength = 2 + addrLen.length + host.length + 2 + 1;
var lengthBuffer = new Buffer(varint.encode(packetLength));
var packet = Buffer.concat([
lengthBuffer,
PACKET_HEAD,
addrLen,
host,
PACKET_PORT,
PACKET_NEXTSTATE,
PACKET_STATUS_REQ
], packetLength + 3);
_connection.write(packet);
/*
TRY 1
------*/
var packet;
packet = "\x00";
packet += "\x04";
packet += bufferpack.pack('c', host.length.toString()) + host;
packet += bufferpack.pack('n', port.toString());
packet += "\x01";
packet = bufferpack.pack('c', packet.length.toString()) + packet;
_connection.write(packet);
_connection.write("\x01\x00");
/*TRY 2
-------*/
var packet;
packet = packData(
'\x00\x00'
+ packData(host.toString('utf8'))
+ packPort(port)
+ '\x01'
);
_connection.write(packet);
_connection.write(packData('\x00'));
});
_connection.on('error', function(err){
system.log(err);
_connection.end();
});
_connection.on('data', function(data){
system.log(data);
});
};
exports.connect = connect;
function packData(data) {
return varint.encode(data.length) + data;
}
function packPort(data) {
return bufferpack.pack('>H', data.toString());
}
My github repo: https://github.com/AtlasDev/NodeCraft
This part is in libs/connection.js
Hope this still helps, AtlasDev