Support immediate respawn gamerule (#970)

* Support immediate respawn gamerule

This commit now supports immediate respawn if the server enables it - both on the setting being applied on join and the setting being modified in-game. This also refactors the respawning process to more closely match BDS behavior - nothing broke in my testing but more testing is needed.

* Reuse spawned variable instead of creating new variable
This commit is contained in:
Camotoy 2020-07-30 16:31:12 -04:00 committed by GitHub
parent a4339be212
commit 238a3a8df1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 21 deletions

View file

@ -35,6 +35,8 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlaye
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket; import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
@ -60,8 +62,12 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
switch (packet.getAction()) { switch (packet.getAction()) {
case RESPAWN: case RESPAWN:
// Don't put anything here as respawn is already handled // Respawn process is finished and the server and client are both OK with respawning.
// in BedrockRespawnTranslator EntityEventPacket eventPacket = new EntityEventPacket();
eventPacket.setRuntimeEntityId(entity.getGeyserId());
eventPacket.setType(EntityEventType.RESPAWN);
eventPacket.setData(0);
session.sendUpstreamPacket(eventPacket);
break; break;
case START_SWIMMING: case START_SWIMMING:
ClientPlayerStatePacket startSwimPacket = new ClientPlayerStatePacket((int) entity.getEntityId(), PlayerState.START_SPRINTING); ClientPlayerStatePacket startSwimPacket = new ClientPlayerStatePacket((int) entity.getEntityId(), PlayerState.START_SPRINTING);

View file

@ -39,11 +39,13 @@ public class BedrockRespawnTranslator extends PacketTranslator<RespawnPacket> {
@Override @Override
public void translate(RespawnPacket packet, GeyserSession session) { public void translate(RespawnPacket packet, GeyserSession session) {
if (packet.getState() == RespawnPacket.State.CLIENT_READY) { if (packet.getState() == RespawnPacket.State.CLIENT_READY) {
RespawnPacket respawnPacket = new RespawnPacket(); if (!session.isSpawned()) { // Otherwise when immediate respawn is on the client never loads
respawnPacket.setRuntimeEntityId(0); RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.setPosition(Vector3f.ZERO); respawnPacket.setRuntimeEntityId(0);
respawnPacket.setState(RespawnPacket.State.SERVER_SEARCHING); respawnPacket.setPosition(Vector3f.ZERO);
session.sendUpstreamPacket(respawnPacket); respawnPacket.setState(RespawnPacket.State.SERVER_SEARCHING);
session.sendUpstreamPacket(respawnPacket);
}
ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN); ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN);
session.sendDownstreamPacket(javaRespawnPacket); session.sendDownstreamPacket(javaRespawnPacket);

View file

@ -30,11 +30,9 @@ import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility;
import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; import com.github.steveice10.mc.protocol.data.game.setting.SkinPart;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientSettingsPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientSettingsPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
import com.nukkitx.protocol.bedrock.data.GameRuleData;
import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; import com.nukkitx.protocol.bedrock.packet.*;
import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.PlayerEntity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.PacketTranslator;
@ -80,6 +78,11 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
entityDataPacket.getMetadata().putAll(entity.getMetadata()); entityDataPacket.getMetadata().putAll(entity.getMetadata());
session.sendUpstreamPacket(entityDataPacket); session.sendUpstreamPacket(entityDataPacket);
// Send if client should show respawn screen
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
gamerulePacket.getGameRules().add(new GameRuleData<>("doimmediaterespawn", !packet.isEnableRespawnScreen()));
session.sendUpstreamPacket(gamerulePacket);
session.setRenderDistance(packet.getViewDistance()); session.setRenderDistance(packet.getViewDistance());
// We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc // We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc

View file

@ -29,8 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
@ -61,17 +59,11 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
entity.setRotation(Vector3f.from(packet.getYaw(), packet.getPitch(), packet.getYaw())); entity.setRotation(Vector3f.from(packet.getYaw(), packet.getPitch(), packet.getYaw()));
RespawnPacket respawnPacket = new RespawnPacket(); RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.setRuntimeEntityId(entity.getGeyserId()); respawnPacket.setRuntimeEntityId(0); // Bedrock server behavior
respawnPacket.setPosition(entity.getPosition()); respawnPacket.setPosition(entity.getPosition());
respawnPacket.setState(RespawnPacket.State.SERVER_READY); respawnPacket.setState(RespawnPacket.State.SERVER_READY);
session.sendUpstreamPacket(respawnPacket); session.sendUpstreamPacket(respawnPacket);
EntityEventPacket eventPacket = new EntityEventPacket();
eventPacket.setRuntimeEntityId(entity.getGeyserId());
eventPacket.setType(EntityEventType.RESPAWN);
eventPacket.setData(0);
session.sendUpstreamPacket(eventPacket);
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().putAll(entity.getMetadata()); entityDataPacket.getMetadata().putAll(entity.getMetadata());
@ -81,7 +73,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
movePlayerPacket.setPosition(entity.getPosition()); movePlayerPacket.setPosition(entity.getPosition());
movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0)); movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0));
movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN); //TODO: PROBABLY RIGHT BUT STILL CHECK movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN);
session.sendUpstreamPacket(movePlayerPacket); session.sendUpstreamPacket(movePlayerPacket);
session.setSpawned(true); session.setSpawned(true);

View file

@ -28,10 +28,12 @@ package org.geysermc.connector.network.translators.java.world;
import com.github.steveice10.mc.protocol.data.game.ClientRequest; import com.github.steveice10.mc.protocol.data.game.ClientRequest;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValue; import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValue;
import com.github.steveice10.mc.protocol.data.game.world.notify.RespawnScreenValue;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.AdventureSetting; import com.nukkitx.protocol.bedrock.data.AdventureSetting;
import com.nukkitx.protocol.bedrock.data.GameRuleData;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.data.command.CommandPermission; import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
@ -129,6 +131,13 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
eventPacket.setData(0); eventPacket.setData(0);
eventPacket.setRuntimeEntityId(entity.getGeyserId()); eventPacket.setRuntimeEntityId(entity.getGeyserId());
session.sendUpstreamPacket(eventPacket); session.sendUpstreamPacket(eventPacket);
break;
case ENABLE_RESPAWN_SCREEN:
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
gamerulePacket.getGameRules().add(new GameRuleData<>("doimmediaterespawn",
packet.getValue() == RespawnScreenValue.IMMEDIATE_RESPAWN));
session.sendUpstreamPacket(gamerulePacket);
break;
default: default:
break; break;
} }