summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2016-05-18 23:57:51 +0300
committerAndrei Karas <akaras@inbox.ru>2016-05-18 23:57:51 +0300
commitd7de4533368a36b77dbc2dbe21269690d8dc5ee5 (patch)
tree66e83823b788015013834dcc7520b0b6bdba68b5
parentdc0102e6eb4ca9a202e190e6ee84b7141d4e0fe1 (diff)
downloadmv-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.tar.gz
mv-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.tar.bz2
mv-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.tar.xz
mv-d7de4533368a36b77dbc2dbe21269690d8dc5ee5.zip
Fix random one tile desync in SMSG_BEING_MOVE3 packet.
-rw-r--r--src/being/being.cpp6
-rw-r--r--src/being/being.h15
-rw-r--r--src/net/ea/beingrecv.cpp57
-rw-r--r--src/net/eathena/beingrecv.cpp8
-rw-r--r--src/net/tmwa/beingrecv.cpp4
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);
}