Fix slow drifting in FullReplaySender replay time (fixes #451)
This commit is contained in:
@@ -339,9 +339,8 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int currentTimeStamp() {
|
public int currentTimeStamp() {
|
||||||
if (asyncMode) {
|
if (asyncMode && !paused()) {
|
||||||
int timePassed = (int) (System.currentTimeMillis() - lastPacketSent);
|
return (int) ((System.currentTimeMillis() - realTimeStart) * realTimeStartSpeed);
|
||||||
return lastTimeStamp + (int) (timePassed * getReplaySpeed());
|
|
||||||
} else {
|
} else {
|
||||||
return lastTimeStamp;
|
return lastTimeStamp;
|
||||||
}
|
}
|
||||||
@@ -864,7 +863,11 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setReplaySpeed(final double d) {
|
public void setReplaySpeed(final double d) {
|
||||||
if(d != 0) this.replaySpeed = d;
|
if (d != 0) {
|
||||||
|
this.replaySpeed = d;
|
||||||
|
this.realTimeStartSpeed = d;
|
||||||
|
this.realTimeStart = System.currentTimeMillis() - (long) (lastTimeStamp / d);
|
||||||
|
}
|
||||||
TimerAccessor timer = (TimerAccessor) ((MinecraftAccessor) mc).getTimer();
|
TimerAccessor timer = (TimerAccessor) ((MinecraftAccessor) mc).getTimer();
|
||||||
//#if MC>=11200
|
//#if MC>=11200
|
||||||
timer.setTickLength(WrappedTimer.DEFAULT_MS_PER_TICK / (float) d);
|
timer.setTickLength(WrappedTimer.DEFAULT_MS_PER_TICK / (float) d);
|
||||||
@@ -878,9 +881,18 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The real time at which the last packet was sent in milliseconds.
|
* Timestamp in milliseconds of when we started (or would have started when taking pauses and speed into account)
|
||||||
|
* the playback of the replay.
|
||||||
|
* Updated only when replay speed changes or on pause/unpause but definitely not on every packet to prevent gradual
|
||||||
|
* drifting.
|
||||||
*/
|
*/
|
||||||
private long lastPacketSent;
|
private long realTimeStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The replay speed used for {@link #realTimeStart}.
|
||||||
|
* If the target speed differs from this one, the timestamp is recalculated.
|
||||||
|
*/
|
||||||
|
private double realTimeStartSpeed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There is no waiting performed until a packet with at least this timestamp is reached (but not yet sent).
|
* There is no waiting performed until a packet with at least this timestamp is reached (but not yet sent).
|
||||||
@@ -936,15 +948,13 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
// If we aren't jumping and the world has already been loaded (no dirt-screens) then wait
|
// If we aren't jumping and the world has already been loaded (no dirt-screens) then wait
|
||||||
// the required amount to get proper packet timing
|
// the required amount to get proper packet timing
|
||||||
if (!isHurrying() && hasWorldLoaded) {
|
if (!isHurrying() && hasWorldLoaded) {
|
||||||
// How much time should have passed
|
// Timestamp of when the next packet should be sent
|
||||||
int timeWait = (int) Math.round((nextTimeStamp - lastTimeStamp) / replaySpeed);
|
long expectedTime = realTimeStart + (long) (nextTimeStamp / replaySpeed);
|
||||||
// How much time did pass
|
long now = System.currentTimeMillis();
|
||||||
long timeDiff = System.currentTimeMillis() - lastPacketSent;
|
// If the packet should not yet be sent, wait a bit
|
||||||
// How much time we need to wait to make up for the difference
|
if (expectedTime > now) {
|
||||||
long timeToSleep = Math.max(0, timeWait - timeDiff);
|
Thread.sleep(expectedTime - now);
|
||||||
|
}
|
||||||
Thread.sleep(timeToSleep);
|
|
||||||
lastPacketSent = System.currentTimeMillis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process packet
|
// Process packet
|
||||||
@@ -961,7 +971,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
|
|
||||||
replayHandler.moveCameraToTargetPosition();
|
replayHandler.moveCameraToTargetPosition();
|
||||||
|
|
||||||
// Pause after jumping
|
// Pause after jumping (this will also reset realTimeStart accordingly)
|
||||||
setReplaySpeed(0);
|
setReplaySpeed(0);
|
||||||
}
|
}
|
||||||
} catch (EOFException eof) {
|
} catch (EOFException eof) {
|
||||||
@@ -988,7 +998,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
loginPhase = true;
|
loginPhase = true;
|
||||||
startFromBeginning = false;
|
startFromBeginning = false;
|
||||||
nextPacket = null;
|
nextPacket = null;
|
||||||
lastPacketSent = System.currentTimeMillis();
|
realTimeStart = System.currentTimeMillis();
|
||||||
if (replayIn != null) {
|
if (replayIn != null) {
|
||||||
replayIn.close();
|
replayIn.close();
|
||||||
replayIn = null;
|
replayIn = null;
|
||||||
@@ -1133,7 +1143,7 @@ public class FullReplaySender extends ChannelDuplexHandler implements ReplaySend
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This might be required if we change to async mode anytime soon
|
// This might be required if we change to async mode anytime soon
|
||||||
lastPacketSent = System.currentTimeMillis();
|
realTimeStart = System.currentTimeMillis() - (long) (timestamp / replaySpeed);
|
||||||
lastTimeStamp = timestamp;
|
lastTimeStamp = timestamp;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user