PrismarineJS / PrismarineJS/node-minecraft-protocol

Entity Effect proxy

Open
#1,304 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

possible bug
Dominant language
JavaScript
Stars
1.4k
Forks
290
Avg merge
4d 8h
Merged PRs (30d)
7

Description

Versions

  • minecraft-protocol: #.#.#
  • server: vanilla/spigot/paper 1.16.5
  • node: 21.7.1

Current code

const mc = require('minecraft-protocol')

const states = mc.states
function printHelpAndExit (exitCode) {
  console.log('usage: node proxy.js [<options>...] <target_srv> <version>')
  console.log('options:')
  console.log('  --dump name')
  console.log('    print to stdout messages with the specified name.')
  console.log('  --dump-all')
  console.log('    print to stdout all messages, except those specified with -x.')
  console.log('  -x name')
  console.log('    do not print messages with this name.')
  console.log('  name')
  console.log('    a packet name as defined in protocol.json')
  console.log('examples:')
  console.log('  node proxy.js --dump-all -x keep_alive -x update_time -x entity_velocity -x rel_entity_move -x entity_look -x entity_move_look -x entity_teleport -x entity_head_rotation -x position localhost 1.8')
  console.log('    print all messages except for some of the most prolific.')
  console.log('  node examples/proxy.js --dump open_window --dump close_window --dump set_slot --dump window_items --dump craft_progress_bar --dump transaction --dump close_window --dump window_click --dump set_creative_slot --dump enchant_item localhost 1.8')
  console.log('    print messages relating to inventory management.')

  process.exit(exitCode)
}

if (process.argv.length < 4) {
  console.log('Too few arguments!')
  printHelpAndExit(1)
}

process.argv.forEach(function (val) {
  if (val === '-h') {
    printHelpAndExit(0)
  }
})

const args = process.argv.slice(2)
let host
let port = 25565
let version

let printAllNames = false
const printNameWhitelist = {}
const printNameBlacklist = {};
(function () {
  let i = 0
  for (i = 0; i < args.length; i++) {
    const option = args[i]
    if (!/^-/.test(option)) break
    if (option === '--dump-all') {
      printAllNames = true
      continue
    }
    i++
    const name = args[i]
    if (option === '--dump') {
      printNameWhitelist[name] = 'io'
    } else if (option === '-x') {
      printNameBlacklist[name] = 'io'
    } else {
      printHelpAndExit(1)
    }
  }
  if (!(i + 2 <= args.length && args.length <= i + 4)) printHelpAndExit(1)
  host = args[i++]
  version = args[i++]
})()

if (host.indexOf(':') !== -1) {
  port = host.substring(host.indexOf(':') + 1)
  host = host.substring(0, host.indexOf(':'))
}

const srv = mc.createServer({
  'online-mode': false,
  port: 25566,
  keepAlive: false,
  version
})
srv.on('login', function (client) {
  const addr = client.socket.remoteAddress
  console.log('Incoming connection', '(' + addr + ')')
  let endedClient = false
  let endedTargetClient = false
  client.on('end', function () {
    endedClient = true
    console.log('Connection closed by client', '(' + addr + ')')
    if (!endedTargetClient) { targetClient.end('End') }
  })
  client.on('error', function (err) {
    endedClient = true
    console.log('Connection error by client', '(' + addr + ')')
    console.log(err.stack)
    if (!endedTargetClient) { targetClient.end('Error') }
  })
  const targetClient = mc.createClient({
    host,
    port,
    username: client.username,
    keepAlive: false,
    version
  })
  client.on('chat', (data, metadata) => {
    let split = data.message.split(' ')
    if (split[0] === '/tpe') {
        const msg = {
          color: 'red',
          translate: 'commands.generic.selector_argument',
          with: [
            split[1]
          ]
        }
        client.write('chat', { message: msg })
        //client.write('chat', { message: JSON.stringify(msg), position: 0 })
      }
  })
  client.on('packet', function (data, meta) {
  if (targetClient.state === states.PLAY && meta.state === states.PLAY) {
    if (shouldDump(meta.name, 'o')) {
      console.log('client->server:',
        client.state + ' ' + meta.name + ' :',
        JSON.stringify(data))
    }
    if (!endedTargetClient) { targetClient.write(meta.name, data) }

    // Add the glowing effect logic here
    if (meta.name === 'chat') {
      const message = data.message;
      if (message.startsWith('/glow')) {
        const playerId = data.entityId; // Get the player ID who sent the command
        const effectId = 24; // Glowing effect ID
        const amplifier = 20; // Effect amplifier
        const duration = 1000; // Effect duration in ticks

        // Send the glowing effect packet to all online players
        const { PacketPlayOutEntityEffect } = require('minecraft-protocol');

        const packet = new PacketPlayOutEntityEffect();
        packet.entityId = playerId;
        packet.effectId = effectId;
        packet.amplifier = amplifier;
        packet.duration = duration;
        packet.flags = 0x03; // 0x03 = glowing effect
        client.write('entity_effect', packet);
      }
    }}
});
  targetClient.on('packet', function (data, meta) {
    if (meta.state === states.PLAY && client.state === states.PLAY) {
      if (shouldDump(meta.name, 'i')) {
        console.log('client<-server:',
          targetClient.state + '.' + meta.name + ' :' +
          JSON.stringify(data))
      }
      if (!endedClient) {
        client.write(meta.name, data)
        if (meta.name === 'set_compression') {
          client.compressionThreshold = data.threshold
        } // Set compression
      }
    }
  })
  const bufferEqual = require('buffer-equal')
  targetClient.on('raw', function (buffer, meta) {
    if (client.state !== states.PLAY || meta.state !== states.PLAY) { return }
    const packetData = targetClient.deserializer.parsePacketBuffer(buffer).data.params
    const packetBuff = client.serializer.createPacketBuffer({ name: meta.name, params: packetData })
    if (!bufferEqual(buffer, packetBuff)) {
      console.log('client<-server: Error in packet ' + meta.state + '.' + meta.name)
      console.log('received buffer', buffer.toString('hex'))
      console.log('produced buffer', packetBuff.toString('hex'))
      console.log('received length', buffer.length)
      console.log('produced length', packetBuff.length)
    }
    /* if (client.state === states.PLAY && brokenPackets.indexOf(packetId.value) !=== -1)
     {
     console.log(`client<-server: raw packet);
     console.log(packetData);
     if (!endedClient)
     client.writeRaw(buffer);
     } */
  })
  client.on('raw', function (buffer, meta) {
    if (meta.state !== states.PLAY || targetClient.state !== states.PLAY) { return }
    const packetData = client.deserializer.parsePacketBuffer(buffer).data.params
    const packetBuff = targetClient.serializer.createPacketBuffer({ name: meta.name, params: packetData })
    if (!bufferEqual(buffer, packetBuff)) {
      console.log('client->server: Error in packet ' + meta.state + '.' + meta.name)
      console.log('received buffer', buffer.toString('hex'))
      console.log('produced buffer', packetBuff.toString('hex'))
      console.log('received length', buffer.length)
      console.log('produced length', packetBuff.length)
    }
  })
  client.on('packet', function (data, meta) {
  if (meta.state === states.PLAY && meta.name === 'chat') {
    const message = data.message;
    if (message.startsWith('/glow')) {
      const playerId = data.entityId; // Get the player ID who sent the command
      const effectId = 24; // Glowing effect ID
      const amplifier = 20; // Effect amplifier
      const duration = 1000; // Effect duration in ticks

      // Send the glowing effect packet to all online players
      srv.clients.forEach((targetClient) => {
        if (targetClient.state === states.PLAY) {
          const packet = new mc.PacketPlayOutEntityEffect();
          packet.entityId = playerId;
          packet.effectId = effectId;
          packet.amplifier = amplifier;
          packet.duration = duration;
          packet.flags = 0x03; // 0x03 = glowing effect
          targetClient.write('entity_effect', packet);
        }
      });
    }
  }
  });
  targetClient.on('end', function () {
    endedTargetClient = true
    console.log('Connection closed by server', '(' + addr + ')')
    if (!endedClient) { client.end('End') }
  })
  targetClient.on('error', function (err) {
    endedTargetClient = true
    console.log('Connection error by server', '(' + addr + ') ', err)
    console.log(err.stack)
    if (!endedClient) { client.end('Error') }
  })
})

function shouldDump (name, direction) {
  if (matches(printNameBlacklist[name])) return false
  if (printAllNames) return true
  return matches(printNameWhitelist[name])

  function matches (result) {
    return result !== undefined && result !== null && result.indexOf(direction) !== -1
  }
}

I have tried many code variants in glow effect, but the error is, please help

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review the provided proxy code, especially the client packet listeners and the entity_effect packet construction in the /glow handling. Reproduce the reported error first, then determine whether the entity ID and packet fields are valid for the stated Minecraft version; done means the /glow command sends the intended effect without an error.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
networking
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.