Fixed mismatched predictions due to NBT key order differences

this is a pain :(
It appears the client always sorts the keys in alphabetical order due to use of std::map. However I'm not sure of the exact ordering behaviour, so it needs to be investigated.
This commit is contained in:
Dylan K. Taylor
2024-02-27 16:07:43 +00:00
parent 6872118355
commit a0cca53f52
3 changed files with 56 additions and 8 deletions

View File

@ -444,9 +444,18 @@ class InGamePacketHandler extends PacketHandler{
return false;
}
$serverItemStack = $this->session->getTypeConverter()->coreItemStackToNet($sourceSlotItem);
//because the client doesn't tell us the expected itemstack ID, we have to deep-compare our known
//itemstack info with the one the client sent. This is costly, but we don't have any other option :(
if(!$serverItemStack->equals($clientItemStack)){
//Sadly we don't have itemstack IDs here, so we have to compare the basic item properties to ensure that we're
//dropping the item the client expects (inventory might be out of sync with the client).
if(
$serverItemStack->getId() !== $clientItemStack->getId() ||
$serverItemStack->getMeta() !== $clientItemStack->getMeta() ||
$serverItemStack->getCount() !== $clientItemStack->getCount() ||
$serverItemStack->getBlockRuntimeId() !== $clientItemStack->getBlockRuntimeId()
//Raw extraData may not match because of TAG_Compound key ordering differences, and decoding it to compare
//is costly. Assume that we're in sync if id+meta+count+runtimeId match.
//NB: Make sure $clientItemStack isn't used to create the dropped item, as that would allow the client
//to change the item NBT since we're not validating it.
){
return false;
}