Jump to content

[1.12] (How) can I process one type of packet before another?


FredTargaryen

Recommended Posts

I have a custom packet that, when the player is moving towards a block, should break it before the player can collide with it.

However, currently the player collides then the block breaks.

In theory, when necessary I send a MessageBreakerMovement at the start of the client tick, which should break the block when received by the server, then the vanilla player packets are processed.

So is there a way I can force the MessageBreakerMovement to be processed first?

I'm guessing if the MessageBreakerMovement is sent first then it is processed first, so could I maybe force it to be sent first?

Or am I thinking about this all totally wrong and is there a better way?

Here is where I send the packet; I'm aware this is a pretty slow event handler:

@SubscribeEvent(priority = EventPriority.HIGHEST)
public void clientBreakCheck(TickEvent.ClientTickEvent event)
{
  if(event.phase == TickEvent.Phase.START)
  {
    Iterator<Entity> i = this.entities.iterator();
    boolean shouldBreak = false;
    while (!shouldBreak && i.hasNext()) {
      shouldBreak = this.shouldBreakNow(i.next());
    }
    if (shouldBreak)
    {
      MessageBreakerMovement mbm = new MessageBreakerMovement();
      mbm.blockx = this.pos.getX();
      mbm.blocky = this.pos.getY();
      mbm.blockz = this.pos.getZ();
      PacketHandler.INSTANCE.sendToServer(mbm);
    }
  }
}

Here's the packet's onMessage:

@Override
public IMessage onMessage(final MessageBreakerMovement message, MessageContext ctx)
{
  final IThreadListener serverWorld = ctx.getServerHandler().player.getServerWorld();
  serverWorld.addScheduledTask(() -> {
    WorldServer castedServerWorld = (WorldServer)serverWorld;
    castedServerWorld.destroyBlock(new BlockPos(message.blockx, message.blocky, message.blockz), false);
  });
  return null;
}

Thank you for reading.

Link to comment
Share on other sites

Maybe try using other event (i'm not sure wich one...) or maybe try instead of iterating over all entitis iterating only on all players or make it so that it breaks block that is in front of player also consider changing the handler and packet so that it does not send the data about the exact block pos it has to break but for example a uuid of player that needs to have a block broken because cheaters/hackers/whatever may change these values there is a golden rule in networking: never trust the client 

Link to comment
Share on other sites

My aim was to handle the earliest event possible to have the best chance of sending MessageBreakerMovement before any player packets. Idk any events which occur earlier on the client than ClientTickEvent but I'll try.

Awkwardly I need to iterate over all entities because some entities need to be able to break the blocks too. The event handler will get a rewrite without the iteration later though.

Later on the packet will contain the motionX, motionY and motionZ of the player and the server will decide what blocks break from that. From what I've read I have to get those values from the client because there's no good way of getting player motion from the server side. :/

 

 

Link to comment
Share on other sites

Haha yep, but like I say I'm changing it later to take the entity movement and the server will decide which blocks to break. I appreciate even this could probably be exploited, but to a smaller extent and I don't know any better ways to accurately get players' motion values. But currently, could I get that block to break before the server processes any other packets from the client?

Link to comment
Share on other sites

I'm using the ClientTickEvent because I guessed that would be the earliest event fired, and I wanted to deal with MessageBreakerMovement before the server checks if the player position/motion is valid.

I'm not using the server because from what I've read and tried, you can't get the player's motion reliably on the server.

I'm doing the code every tick because if a tick is allowed to pass, the player will collide with the block even if the block is supposed to break before the player can collide with it.

 

If there was a reliable way to get the motion from the server side (the way you can with entities, or a player on the client side), even just a way of handling player position packets immediately when they are received, I probably wouldn't have to send any extra packets at all...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.