From 730241b0858ff7118862440345c2d9b041ebd82a Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Tue, 15 Aug 2023 11:36:10 -0400 Subject: [PATCH] Fixed to send an intermediary PU message whenver a MOVE chain takes the player more than 16 tiles away from where their last PU message occured. This prevents out-of-date player status (like what they are holding/riding/wearing) from being presented to other players when they move back into range using a long move chain after being out of range, when their status changed while they were out of range. Before, no PU message would be sent until the very end of a long move chain. No more players zipping onto the screen and suddenly having their delivery truck appear around them. No more players squeaking into view with a hand cart that they are no longer actually holding, and then suddenly seeing the hand cart disappear when they stop moving. This still might be an issue on modded clients with a zoomed out view, because the threshold is only 16 tiles, but it seems to work fine in all cases on the official client. Fixes #906 --- server/server.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/server/server.cpp b/server/server.cpp index 7a373eb5..0d1f1710 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -764,6 +764,25 @@ typedef struct LiveObject { char newMove; + // Absolute position used when generating last PU sent out about this + // player. + // If they are making a very long chained move, and their status + // isn't changing, they might not generate a PU message for a very + // long time. This becomes a problem when them move out/in range + // of another player. If their status (held item, etc) has changed + // while they are out of range, the other player won't see that + // status change when they come back in range (because the PU + // happened when they were out of range) and the long chained move + // isn't generating any PU messages now that they are back in range. + // Since modded clients might make very long MOVEs for each part + // of a MOVE chain (since they are zoomed out), we can't just count + // MOVE messages sent since the las PU message went out. + // We use this position to determine how far they've moved away + // from their last PU position, and send an intermediary PU if + // they get too far away + GridPos lastPlayerUpdateAbsolutePos; + + // heat map that player carries around with them // every time they stop moving, it is updated to compute // their local temp @@ -6307,6 +6326,9 @@ static UpdateRecord getUpdateRecord( inPlayer->posForced ); r.absolutePosX = x; r.absolutePosY = y; + + inPlayer->lastPlayerUpdateAbsolutePos.x = x; + inPlayer->lastPlayerUpdateAbsolutePos.y = y; } SimpleVector clothingListBuffer; @@ -8145,6 +8167,10 @@ int processLoggedInPlayer( char inAllowReconnect, newObject.deathLogged = false; newObject.newMove = false; + newObject.lastPlayerUpdateAbsolutePos.x = 0; + newObject.lastPlayerUpdateAbsolutePos.y = 0; + + newObject.posForced = false; newObject.waitingForForceResponse = false; @@ -15939,6 +15965,19 @@ int main() { nextPlayer->xd = m.extraPos[ m.numExtraPos - 1].x; nextPlayer->yd = m.extraPos[ m.numExtraPos - 1].y; + + if( distance( nextPlayer->lastPlayerUpdateAbsolutePos, + m.extraPos[ m.numExtraPos - 1] ) + > + getMaxChunkDimension() / 2 ) { + // they have moved a long way since their + // last PU was sent + // Send one now, mid-move + + playerIndicesToSendUpdatesAbout.push_back( i ); + } + + if( nextPlayer->xd == nextPlayer->xs && nextPlayer->yd == nextPlayer->ys ) {