diff options
author | Andrei Karas <akaras@inbox.ru> | 2016-05-18 23:57:51 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2016-05-18 23:57:51 +0300 |
commit | d7de4533368a36b77dbc2dbe21269690d8dc5ee5 (patch) | |
tree | 66e83823b788015013834dcc7520b0b6bdba68b5 | |
parent | dc0102e6eb4ca9a202e190e6ee84b7141d4e0fe1 (diff) | |
download | manaplus-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.tar.gz manaplus-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.tar.bz2 manaplus-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.tar.xz manaplus-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.zip |
Fix random one tile desync in SMSG_BEING_MOVE3 packet.
-rw-r--r-- | src/being/being.cpp | 6 | ||||
-rw-r--r-- | src/being/being.h | 15 | ||||
-rw-r--r-- | src/net/ea/beingrecv.cpp | 57 | ||||
-rw-r--r-- | src/net/eathena/beingrecv.cpp | 8 | ||||
-rw-r--r-- | src/net/tmwa/beingrecv.cpp | 4 |
5 files changed, 84 insertions, 6 deletions
diff --git a/src/being/being.cpp b/src/being/being.cpp index d7b00e1c6..f020de3da 100644 --- a/src/being/being.cpp +++ b/src/being/being.cpp @@ -214,6 +214,8 @@ Being::Being(const BeingId id, #endif mX(0), mY(0), + mCachedX(0), + mCachedY(0), mSortOffsetY(0), mPixelOffsetY(0), mFixedOffsetY(0), @@ -528,9 +530,9 @@ void Being::setPixelPositionF(const Vector &restrict pos) restrict2 } } -void Being::setDestination(const int dstX, const int dstY) restrict2 +void Being::setDestination(const int dstX, + const int dstY) restrict2 { - // We can't calculate anything without a map anyway. if (!mMap) return; diff --git a/src/being/being.h b/src/being/being.h index 0386f3290..296038876 100644 --- a/src/being/being.h +++ b/src/being/being.h @@ -136,7 +136,18 @@ class Being notfinal : public ActorSprite, /** * Creates a path for the being from current position to ex and ey */ - void setDestination(const int dstX, const int dstY) restrict2; + void setDestination(const int dstX, + const int dstY) restrict2; + + void setCachedDestination(const int dstX, + const int dstY) restrict2 + { mCachedX = dstX; mCachedY = dstY; } + + int getCachedX() const A_WARN_UNUSED + { return mCachedX; } + + int getCachedY() const A_WARN_UNUSED + { return mCachedY; } /** * Returns the destination for this being. @@ -1170,6 +1181,8 @@ class Being notfinal : public ActorSprite, int mX; // position in tiles int mY; // position in tiles + int mCachedX; + int mCachedY; int mSortOffsetY; // caculated offset in pixels based on mPixelOffsetY int mPixelOffsetY; // tile height offset in pixels // calculated between tiles diff --git a/src/net/ea/beingrecv.cpp b/src/net/ea/beingrecv.cpp index fa1f47c69..0a8168c6c 100644 --- a/src/net/ea/beingrecv.cpp +++ b/src/net/ea/beingrecv.cpp @@ -45,6 +45,8 @@ #include "net/messagein.h" #include "net/serverfeatures.h" +#include "utils/checkutils.h" + #include "debug.h" namespace Ea @@ -440,6 +442,9 @@ void BeingRecv::processBeingMove3(Net::MessageIn &msg) dstBeing->setAction(BeingAction::STAND, 0); dstBeing->setTileCoords(x, y); + if (dstBeing == localPlayer) + return; + const unsigned char *moves = msg.readBytes(len, "moving path"); Path path; if (moves) @@ -458,8 +463,60 @@ void BeingRecv::processBeingMove3(Net::MessageIn &msg) logger->log("bad move packet: %d", dir); } } + const int x1 = dstBeing->getCachedX(); + const int y1 = dstBeing->getCachedY(); + if (x1 != x || y1 != y) + { +// reportAlways("Found desync being move. " +// "Calculated target (%d,%d). " +// "Actual target (%d,%d).", +// static_cast<int>(x), +// static_cast<int>(y), +// static_cast<int>(x1), +// static_cast<int>(y1)); + if (len > 0) + { + const unsigned char dir = moves[0]; + uint16_t x0 = x; + uint16_t y0 = y; + + if (dir <= 7) + { + x0 -= dirx[0]; + y0 -= diry[0]; + if (x1 == x0 && y1 == y0) + { + path.erase(path.begin()); + logger->log("Fixed being moving desync by " + "removing one tile"); + } + else + { + x0 = x; + y0 = y; + if (abs(x0 - x1) < 2 && abs(y0 - y1) < 2) + { + path.push_back(Position(x1, y1)); + logger->log("Fixed being moving desync by " + "adding one tile"); + } + else + { + reportAlways("Error: being moving desync. " + "Calculated target (%d,%d). " + "Actual target (%d,%d).", + static_cast<int>(x), + static_cast<int>(y), + static_cast<int>(x1), + static_cast<int>(y1)); + } + } + } + } + } delete [] moves; } + dstBeing->setPath(path); BLOCK_END("BeingRecv::processBeingMove3") } diff --git a/src/net/eathena/beingrecv.cpp b/src/net/eathena/beingrecv.cpp index 85c276e46..5c5e18ce8 100644 --- a/src/net/eathena/beingrecv.cpp +++ b/src/net/eathena/beingrecv.cpp @@ -597,7 +597,9 @@ void BeingRecv::processBeingMove(Net::MessageIn &msg) dstBeing->setTileCoords(srcX, srcY); if (localPlayer) localPlayer->followMoveTo(dstBeing, srcX, srcY, dstX, dstY); - if (!serverFeatures->haveMove3()) + if (serverFeatures->haveMove3()) + dstBeing->setCachedDestination(dstX, dstY); + else dstBeing->setDestination(dstX, dstY); // because server don't send direction in move packet, we fixing it @@ -956,7 +958,9 @@ void BeingRecv::processBeingMove2(Net::MessageIn &msg) dstBeing->setTileCoords(srcX, srcY); if (localPlayer) localPlayer->followMoveTo(dstBeing, srcX, srcY, dstX, dstY); - if (!serverFeatures->haveMove3()) + if (serverFeatures->haveMove3()) + dstBeing->setCachedDestination(dstX, dstY); + else dstBeing->setDestination(dstX, dstY); if (dstBeing->getType() == ActorType::Player) dstBeing->setMoveTime(); diff --git a/src/net/tmwa/beingrecv.cpp b/src/net/tmwa/beingrecv.cpp index d5f1dbd6f..04c4a0444 100644 --- a/src/net/tmwa/beingrecv.cpp +++ b/src/net/tmwa/beingrecv.cpp @@ -1019,7 +1019,9 @@ void BeingRecv::processBeingMove(Net::MessageIn &msg) { dstBeing->setAction(BeingAction::STAND, 0); dstBeing->setTileCoords(srcX, srcY); - if (!serverFeatures->haveMove3()) + if (serverFeatures->haveMove3()) + dstBeing->setCachedDestination(dstX, dstY); + else dstBeing->setDestination(dstX, dstY); } |