Fix rowing from Java to Bedrock (#1943)

Rowing apparently broke in possibly the 1.16 update and nobody noticed until now.
This commit is contained in:
Camotoy 2021-02-25 13:12:25 -05:00 committed by GitHub
parent 9f5a356180
commit 325b8ab4d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -28,6 +28,7 @@ package org.geysermc.connector.entity;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
@ -105,27 +106,38 @@ public class BoatEntity extends Entity {
metadata.put(EntityData.VARIANT, entityMetadata.getValue());
} else if (entityMetadata.getId() == 11) {
isPaddlingLeft = (boolean) entityMetadata.getValue();
if (!isPaddlingLeft) {
metadata.put(EntityData.ROW_TIME_LEFT, 0f);
}
else {
if (isPaddlingLeft) {
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
// This is an asynchronous method that emulates Bedrock rowing until "false" is sent.
paddleTimeLeft = 0f;
session.getConnector().getGeneralThreadPool().execute(() ->
updateLeftPaddle(session, entityMetadata)
);
if (!this.passengers.isEmpty()) {
// Get the entity by the first stored passenger and convey motion in this manner
Entity entity = session.getEntityCache().getEntityByJavaId(this.passengers.iterator().nextLong());
if (entity != null) {
session.getConnector().getGeneralThreadPool().execute(() ->
updateLeftPaddle(session, entity)
);
}
}
} else {
// Indicate that the row position should be reset
metadata.put(EntityData.ROW_TIME_LEFT, 0.0f);
}
}
else if (entityMetadata.getId() == 12) {
isPaddlingRight = (boolean) entityMetadata.getValue();
if (!isPaddlingRight) {
metadata.put(EntityData.ROW_TIME_RIGHT, 0f);
} else {
if (isPaddlingRight) {
paddleTimeRight = 0f;
session.getConnector().getGeneralThreadPool().execute(() ->
updateRightPaddle(session, entityMetadata)
);
if (!this.passengers.isEmpty()) {
Entity entity = session.getEntityCache().getEntityByJavaId(this.passengers.iterator().nextLong());
if (entity != null) {
session.getConnector().getGeneralThreadPool().execute(() ->
updateRightPaddle(session, entity)
);
}
}
} else {
metadata.put(EntityData.ROW_TIME_RIGHT, 0.0f);
}
} else if (entityMetadata.getId() == 13) {
// Possibly - I don't think this does anything?
@ -135,27 +147,46 @@ public class BoatEntity extends Entity {
super.updateBedrockMetadata(entityMetadata, session);
}
public void updateLeftPaddle(GeyserSession session, EntityMetadata entityMetadata) {
@Override
public void updateBedrockMetadata(GeyserSession session) {
super.updateBedrockMetadata(session);
// As these indicate to reset rowing, remove them until it is time to send them out again.
metadata.remove(EntityData.ROW_TIME_LEFT);
metadata.remove(EntityData.ROW_TIME_RIGHT);
}
private void updateLeftPaddle(GeyserSession session, Entity rower) {
if (isPaddlingLeft) {
paddleTimeLeft += ROWING_SPEED;
metadata.put(EntityData.ROW_TIME_LEFT, paddleTimeLeft);
super.updateBedrockMetadata(entityMetadata, session);
sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_LEFT, paddleTimeLeft);
session.getConnector().getGeneralThreadPool().schedule(() ->
updateLeftPaddle(session, entityMetadata),
updateLeftPaddle(session, rower),
100,
TimeUnit.MILLISECONDS
);
}}
}
}
public void updateRightPaddle(GeyserSession session, EntityMetadata entityMetadata) {
private void updateRightPaddle(GeyserSession session, Entity rower) {
if (isPaddlingRight) {
paddleTimeRight += ROWING_SPEED;
metadata.put(EntityData.ROW_TIME_RIGHT, paddleTimeRight);
super.updateBedrockMetadata(entityMetadata, session);
sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_RIGHT, paddleTimeRight);
session.getConnector().getGeneralThreadPool().schedule(() ->
updateRightPaddle(session, entityMetadata),
updateRightPaddle(session, rower),
100,
TimeUnit.MILLISECONDS
);
}}
}
}
private void sendAnimationPacket(GeyserSession session, Entity rower, AnimatePacket.Action action, float rowTime) {
AnimatePacket packet = new AnimatePacket();
packet.setRuntimeEntityId(rower.getGeyserId());
packet.setAction(action);
packet.setRowingTime(rowTime);
session.sendUpstreamPacket(packet);
}
}