node-minecraft-protocol icon indicating copy to clipboard operation
node-minecraft-protocol copied to clipboard

Deserialize without client or server

Open hhoughgg opened this issue 5 years ago • 9 comments

I have a very simple tcp proxy setup similar to https://gist.github.com/kfox/2313683

It listens on ip address and forwards the packets to the minecraft server listening on localhost.

I don't care about most of the packets I just want to parse the handshake packet as well as ping packets. Is there a way to do this with the library without creating an entire client or server.

I have tried with the code below but I get errors on ping packet or connection as listed below. The variable data below is the raw buffer from the remote connection.

Thanks

const parse = mc.createDeserializer({ state: 'handshaking', isServer: false, version: '1.13.1' })
console.log('parse: ', parse.parsePacketBuffer(data))

Error: Read error for name : 20 is not in the mappings value

hhoughgg avatar Sep 15 '18 03:09 hhoughgg

You also need the other transform. At least splitter and possibly compressor. Look at client.js code to see how to plug them.

On Sat, Sep 15, 2018, 05:39 Harry Hough [email protected] wrote:

I have a very simple tcp proxy setup similar to https://gist.github.com/kfox/2313683

It listens on ip address and forwards the packets to the minecraft server listening on localhost.

I don't care about most of the packets I just want to parse the handshake packet as well as ping packets. Is there a way to do this with the library without creating an entire client or server.

I have tried with the code below but I get errors on ping packet or connection as listed below. The variable data below is the raw buffer from the remote connection.

Thanks

` const parse = mc.createDeserializer({ state: 'handshaking', isServer: false, version: '1.13.1' }) console.log('parse: ', parse.parsePacketBuffer(data))

Error: Read error for name : 20 is not in the mappings value `

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PrismarineJS/node-minecraft-protocol/issues/591, or mute the thread https://github.com/notifications/unsubscribe-auth/ACPN_gvoEg-qnLpMUxMZs1rYjq0dpbr_ks5ubHaAgaJpZM4WqLWv .

rom1504 avatar Sep 15 '18 08:09 rom1504

socket -> decipher -> splitter -> decompressor -> deserializer

most but not all servers need the decipher and decompressor.

why not use a nmp server as a proxy?

plexigras avatar Sep 15 '18 12:09 plexigras

Basically my use case is that I am directing different people connecting with their minecraft client to different minecraft servers on localhost ports based on the dns used for connection. All connections are to serverip:25565.

All I really want to be able to do is parse ping packets and initial connection packets and respond to ping packets without hitting the actual minecraft server.

I tried to proxy example but I assume I need to set my minecraft server to offline mode where the nmp server proxy handles login? Do this mean my minecraft server is actually still effectively in online mode?

This is where I am at now and this is the result of my minecraft client sending a ping packet. It definately looks closer than it was before but I'm unsure why its failing. The ping packets don't look compressed or encrypted.

const parse = mc.createDeserializer({ state: 'status', isServer: true, version: '1.13.1' })

const server = net.createServer((remotesocket) => {
  const splitter = createSplitter()
  remotesocket.pipe(splitter).pipe(parse)

  remotesocket.on('data', (data) => {
    console.log('data', data)
    console.log('data string: ', data.toString())

    //> Chunk size is 20 but only 1 was read ; partial packet : {"name":"ping_start","params":{}};
  });
})

Thanks for the explanations so far.

hhoughgg avatar Sep 16 '18 00:09 hhoughgg

The initial state is handshaking not status, that's your (current) problem.

rom1504 avatar Sep 16 '18 00:09 rom1504

yes you need to wait for the right state

here in this proxy example we wait for the state to be play to connect the client to the remote.

const version = '1.9.4'

const nmp   = require('minecraft-protocol')

const server = nmp.createServer({ port:25566, version })

server.on('login', connect)

function connect(client) {
  const remote = nmp.createClient({
    username: client.username,
    version,
    keepAlive: false
  })

  remote.on('raw', (buffer, metadata) => {
    if (metadata.state !== 'play') return
    client.writeRaw(buffer)
  })
  client.on('raw', (buffer, metadata) => {
    remote.writeRaw(buffer)
  })
}

plexigras avatar Sep 16 '18 07:09 plexigras

@bluestreek18 Is there a need to pipe this through your own software?

Basically my use case is that I am directing different people connecting with their minecraft client to different minecraft servers on localhost ports based on the dns used for connection.

This use case can already be handled natively by Minecraft clients through the use of SRV records (if you make the servers accessible by internet)

DeliciousJaffa avatar Jan 25 '19 16:01 DeliciousJaffa

I'm looking into doing this too (Parsing packets without actually creating a server/client) but am struggling a bit with the process of getting it working. Would you be able to give me a idea of how I am meant to pipe the data from the socket to get a properly parsed packet with the meta etc similar to what you can get from client.on('packet',function(data, meta){})?

Inrixia avatar Apr 16 '19 11:04 Inrixia

@Inrixia I use this to parse a packet read from a file (assumes decrypted and decompressed etc):

const mc=require('minecraft-protocol');
const d=mc.createDeserializer({version:"1.12.2", state:mc.states.PLAY});
d.on('data',(parsed)=>{
  console.log(JSON.stringify(parsed, null, ''));
  console.log(parsed.data.params);
});
d.write(require('fs').readFileSync('last-packet'));

iceiix avatar May 12 '19 22:05 iceiix

@iceiix Thanks. Was actually able to get the whole thing somewhat working after a few days. Just stuck on the encryption/decryption now but have been taking a break for the past few weeks as have had other priorities. Ill leave a post here once I get a fully working thing going I guess.

Inrixia avatar May 12 '19 22:05 Inrixia