Merge pull request #120 from AJ-Ferguson/dimension

Dimension Switching and Respawning
This commit is contained in:
Redned 2019-12-30 10:57:48 -06:00 committed by GitHub
commit 8ae1c4d70a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 220 additions and 89 deletions

View file

@ -29,6 +29,7 @@ import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.exception.request.RequestException;
import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.MinecraftProtocol;
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.packet.ingame.server.ServerRespawnPacket;
import com.github.steveice10.packetlib.Client; import com.github.steveice10.packetlib.Client;
import com.github.steveice10.packetlib.event.session.ConnectedEvent; import com.github.steveice10.packetlib.event.session.ConnectedEvent;
import com.github.steveice10.packetlib.event.session.DisconnectedEvent; import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
@ -56,7 +57,7 @@ import org.geysermc.connector.entity.PlayerEntity;
import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.inventory.PlayerInventory;
import org.geysermc.connector.network.session.cache.*; import org.geysermc.connector.network.session.cache.*;
import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.Registry;
import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.utils.ChunkUtils;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.Toolbox;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -97,6 +98,11 @@ public class GeyserSession implements Player {
@Setter @Setter
private GameMode gameMode = GameMode.SURVIVAL; private GameMode gameMode = GameMode.SURVIVAL;
@Setter
private boolean switchingDimension = false;
private boolean manyDimPackets = false;
private ServerRespawnPacket lastDimPacket = null;
public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
this.connector = connector; this.connector = connector;
this.upstream = new UpstreamSession(bedrockServerSession); this.upstream = new UpstreamSession(bedrockServerSession);
@ -121,25 +127,8 @@ public class GeyserSession implements Player {
public void connect(RemoteServer remoteServer) { public void connect(RemoteServer remoteServer) {
startGame(); startGame();
this.remoteServer = remoteServer; this.remoteServer = remoteServer;
if (!(connector.getConfig().getRemote().getAuthType().hashCode() == "online".hashCode())) {
connector.getLogger().info("Attempting to login using offline mode... authentication is disabled.");
authenticate(authenticationData.getName());
}
Vector3f pos = Vector3f.ZERO; ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
int chunkX = pos.getFloorX() >> 4;
int chunkZ = pos.getFloorZ() >> 4;
NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket();
chunkPublisherUpdatePacket.setPosition(pos.toInt());
chunkPublisherUpdatePacket.setRadius(renderDistance << 4);
upstream.sendPacket(chunkPublisherUpdatePacket);
LevelChunkPacket data = new LevelChunkPacket();
data.setChunkX(chunkX);
data.setChunkZ(chunkZ);
data.setSubChunksLength(0);
data.setData(TranslatorsInit.EMPTY_LEVEL_CHUNK_DATA);
upstream.sendPacket(data);
BiomeDefinitionListPacket biomePacket = new BiomeDefinitionListPacket(); BiomeDefinitionListPacket biomePacket = new BiomeDefinitionListPacket();
biomePacket.setTag(CompoundTag.EMPTY); biomePacket.setTag(CompoundTag.EMPTY);
@ -198,6 +187,16 @@ public class GeyserSession implements Player {
@Override @Override
public void packetReceived(PacketReceivedEvent event) { public void packetReceived(PacketReceivedEvent event) {
if (!closed) { if (!closed) {
//handle consecutive respawn packets
if (event.getPacket().getClass().equals(ServerRespawnPacket.class)) {
manyDimPackets = lastDimPacket != null;
lastDimPacket = event.getPacket();
return;
} else if (lastDimPacket != null) {
Registry.JAVA.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this);
lastDimPacket = null;
}
Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this);
} }
} }

View file

@ -25,10 +25,7 @@
package org.geysermc.connector.network.session.cache; package org.geysermc.connector.network.session.cache;
import it.unimi.dsi.fastutil.longs.Long2LongMap; import it.unimi.dsi.fastutil.longs.*;
import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import lombok.Getter; import lombok.Getter;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.PlayerEntity;
@ -45,9 +42,9 @@ public class EntityCache {
private GeyserSession session; private GeyserSession session;
@Getter @Getter
private Long2ObjectMap<Entity> entities = new Long2ObjectOpenHashMap<>(); private Long2ObjectMap<Entity> entities = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>());
private Long2LongMap entityIdTranslations = new Long2LongOpenHashMap(); private Long2LongMap entityIdTranslations = Long2LongMaps.synchronize(new Long2LongOpenHashMap());
private Map<UUID, PlayerEntity> playerEntities = new HashMap<>(); private Map<UUID, PlayerEntity> playerEntities = Collections.synchronizedMap(new HashMap<>());
private Map<UUID, Long> bossbars = new HashMap<>(); private Map<UUID, Long> bossbars = new HashMap<>();
@Getter @Getter
@ -76,6 +73,13 @@ public class EntityCache {
return false; return false;
} }
public void removeAllEntities() {
List<Entity> entities = new ArrayList<>(session.getEntityCache().getEntities().values());
for (Entity entity : entities) {
session.getEntityCache().removeEntity(entity, false);
}
}
public Entity getEntityByGeyserId(long geyserId) { public Entity getEntityByGeyserId(long geyserId) {
return entities.get(geyserId); return entities.get(geyserId);
} }

View file

@ -156,6 +156,7 @@ public class TranslatorsInit {
Registry.registerBedrock(SetLocalPlayerAsInitializedPacket.class, new BedrockPlayerInitializedTranslator()); Registry.registerBedrock(SetLocalPlayerAsInitializedPacket.class, new BedrockPlayerInitializedTranslator());
Registry.registerBedrock(InteractPacket.class, new BedrockInteractTranslator()); Registry.registerBedrock(InteractPacket.class, new BedrockInteractTranslator());
Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator()); Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator());
Registry.registerBedrock(RespawnPacket.class, new BedrockRespawnTranslator());
itemTranslator = new ItemTranslator(); itemTranslator = new ItemTranslator();
blockTranslator = new BlockTranslator(); blockTranslator = new BlockTranslator();

View file

@ -34,6 +34,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlaye
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket;
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.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket; import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -53,7 +54,7 @@ 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 // Don't put anything here as respawn is already handled
// in JavaPlayerSetHealthTranslator // in BedrockRespawnTranslator
break; break;
case START_GLIDE: case START_GLIDE:
case STOP_GLIDE: case STOP_GLIDE:
@ -105,6 +106,14 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
case STOP_BREAK: case STOP_BREAK:
// Handled in BedrockInventoryTransactionTranslator // Handled in BedrockInventoryTransactionTranslator
break; break;
case DIMENSION_CHANGE_SUCCESS:
session.setSwitchingDimension(false);
//sometimes the client doesn't feel like loading
PlayStatusPacket spawnPacket = new PlayStatusPacket();
spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
session.getUpstream().sendPacket(spawnPacket);
entity.updateBedrockAttributes(session);
break;
} }
} }
} }

View file

@ -42,7 +42,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
@Override @Override
public void translate(MovePlayerPacket packet, GeyserSession session) { public void translate(MovePlayerPacket packet, GeyserSession session) {
PlayerEntity entity = session.getPlayerEntity(); PlayerEntity entity = session.getPlayerEntity();
if (entity == null || !session.isSpawned()) return; if (entity == null || !session.isSpawned() || session.isSwitchingDimension()) return;
if (!session.getUpstream().isInitialized()) { if (!session.getUpstream().isInitialized()) {
MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket(); MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket();

View file

@ -13,6 +13,11 @@ public class BedrockPlayerInitializedTranslator extends PacketTranslator<SetLoca
if (!session.getUpstream().isInitialized()) { if (!session.getUpstream().isInitialized()) {
session.getUpstream().setInitialized(true); session.getUpstream().setInitialized(true);
if (!(session.getConnector().getConfig().getRemote().getAuthType().hashCode() == "online".hashCode())) {
session.getConnector().getLogger().info("Attempting to login using offline mode... authentication is disabled.");
session.authenticate(session.getAuthenticationData().getName());
}
for (PlayerEntity entity : session.getEntityCache().getEntitiesByType(PlayerEntity.class)) { for (PlayerEntity entity : session.getEntityCache().getEntitiesByType(PlayerEntity.class)) {
if (!entity.isValid()) { if (!entity.isValid()) {
// async skin loading // async skin loading

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2019 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.network.translators.bedrock;
import com.github.steveice10.mc.protocol.data.game.ClientRequest;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator;
public class BedrockRespawnTranslator extends PacketTranslator<RespawnPacket> {
@Override
public void translate(RespawnPacket packet, GeyserSession session) {
if (packet.getSpawnState() == RespawnPacket.State.CLIENT_READY) {
RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.setRuntimeEntityId(0);
respawnPacket.setPosition(Vector3f.ZERO);
respawnPacket.setSpawnState(RespawnPacket.State.SERVER_SEARCHING);
session.getUpstream().sendPacket(respawnPacket);
ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN);
session.getDownstream().getSession().send(javaRespawnPacket);
}
}
}

View file

@ -26,22 +26,20 @@
package org.geysermc.connector.network.translators.java; package org.geysermc.connector.network.translators.java;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
import com.nukkitx.protocol.bedrock.packet.ChunkRadiusUpdatedPacket;
import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
import com.nukkitx.protocol.bedrock.packet.*;
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;
import org.geysermc.connector.world.chunk.ChunkPosition; import org.geysermc.connector.utils.DimensionUtils;
public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacket> { public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacket> {
@Override @Override
public void translate(ServerJoinGamePacket packet, GeyserSession session) { public void translate(ServerJoinGamePacket packet, GeyserSession session) {
PlayerEntity entity = session.getPlayerEntity();
entity.setEntityId(packet.getEntityId());
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket(); AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId()); bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId());
bedrockPacket.setPlayerPermission(1); bedrockPacket.setPlayerPermission(1);
@ -51,9 +49,6 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS);
// session.getUpstream().sendPacket(playStatus); // session.getUpstream().sendPacket(playStatus);
PlayerEntity entity = session.getPlayerEntity();
entity.setEntityId(packet.getEntityId());
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
playerGameTypePacket.setGamemode(packet.getGameMode().ordinal()); playerGameTypePacket.setGamemode(packet.getGameMode().ordinal());
session.getUpstream().sendPacket(playerGameTypePacket); session.getUpstream().sendPacket(playerGameTypePacket);
@ -71,6 +66,8 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
chunkRadiusPacket.setRadius(session.getRenderDistance()); chunkRadiusPacket.setRadius(session.getRenderDistance());
session.getUpstream().sendPacket(chunkRadiusPacket); session.getUpstream().sendPacket(chunkRadiusPacket);
session.setSpawned(true); if (DimensionUtils.javaToBedrock(packet.getDimension()) != entity.getDimension()) {
DimensionUtils.switchDimension(session, packet.getDimension(), false);
}
} }
} }

View file

@ -26,12 +26,12 @@
package org.geysermc.connector.network.translators.java; package org.geysermc.connector.network.translators.java;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket;
import com.nukkitx.protocol.bedrock.packet.ChangeDimensionPacket; import com.nukkitx.protocol.bedrock.packet.*;
import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.attribute.AttributeType;
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;
import org.geysermc.connector.utils.DimensionUtils;
public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> { public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> {
@ -41,37 +41,25 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
if (entity == null) if (entity == null)
return; return;
if (entity.getDimension() == getDimension(packet.getDimension())) float maxHealth = entity.getAttributes().containsKey(AttributeType.MAX_HEALTH) ? entity.getAttributes().get(AttributeType.MAX_HEALTH).getValue() : 20f;
return; // Max health must be divisible by two in bedrock
entity.getAttributes().put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(maxHealth, (maxHealth % 2 == 1 ? maxHealth + 1 : maxHealth)));
entity.setDimension(getDimension(packet.getDimension()));
ChangeDimensionPacket changeDimensionPacket = new ChangeDimensionPacket();
changeDimensionPacket.setDimension(getDimension(packet.getDimension()));
changeDimensionPacket.setRespawn(false);
changeDimensionPacket.setPosition(entity.getPosition());
session.getUpstream().sendPacket(changeDimensionPacket);
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
playerGameTypePacket.setGamemode(packet.getGamemode().ordinal()); playerGameTypePacket.setGamemode(packet.getGamemode().ordinal());
session.getUpstream().sendPacket(playerGameTypePacket); session.getUpstream().sendPacket(playerGameTypePacket);
session.setGameMode(packet.getGamemode()); session.setGameMode(packet.getGamemode());
/* if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) {
PlayStatusPacket playStatusPacket = new PlayStatusPacket(); DimensionUtils.switchDimension(session, packet.getDimension(), false);
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); } else {
session.getUpstream().sendPacket(playStatusPacket); // Handled in JavaPlayerPositionRotationTranslator
*/ session.setSpawned(false);
} if (session.isManyDimPackets()) { //reloading world
int fakeDim = entity.getDimension() == 0 ? -1 : 0;
private int getDimension(int javaDimension) { DimensionUtils.switchDimension(session, fakeDim, true);
switch (javaDimension) { DimensionUtils.switchDimension(session, packet.getDimension(), false);
case -1: }
return 1; }
case 1:
return 2;
}
return javaDimension;
} }
} }

View file

@ -25,11 +25,7 @@
package org.geysermc.connector.network.translators.java.entity.player; package org.geysermc.connector.network.translators.java.entity.player;
import com.github.steveice10.mc.protocol.data.game.ClientRequest;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
import com.nukkitx.protocol.bedrock.packet.SetHealthPacket; import com.nukkitx.protocol.bedrock.packet.SetHealthPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.attribute.AttributeType;
@ -44,8 +40,9 @@ public class JavaPlayerHealthTranslator extends PacketTranslator<ServerPlayerHea
if (entity == null) if (entity == null)
return; return;
int health = (int) Math.ceil(packet.getHealth());
SetHealthPacket setHealthPacket = new SetHealthPacket(); SetHealthPacket setHealthPacket = new SetHealthPacket();
setHealthPacket.setHealth((int) Math.ceil(packet.getHealth())); setHealthPacket.setHealth(health);
session.getUpstream().sendPacket(setHealthPacket); session.getUpstream().sendPacket(setHealthPacket);
float maxHealth = entity.getAttributes().containsKey(AttributeType.MAX_HEALTH) ? entity.getAttributes().get(AttributeType.MAX_HEALTH).getValue() : 20f; float maxHealth = entity.getAttributes().containsKey(AttributeType.MAX_HEALTH) ? entity.getAttributes().get(AttributeType.MAX_HEALTH).getValue() : 20f;
@ -54,20 +51,9 @@ public class JavaPlayerHealthTranslator extends PacketTranslator<ServerPlayerHea
maxHealth += 1; maxHealth += 1;
} }
entity.getAttributes().put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(packet.getHealth(), maxHealth)); entity.getAttributes().put(AttributeType.HEALTH, AttributeType.HEALTH.getAttribute(health, maxHealth));
entity.getAttributes().put(AttributeType.HUNGER, AttributeType.HUNGER.getAttribute(packet.getFood())); entity.getAttributes().put(AttributeType.HUNGER, AttributeType.HUNGER.getAttribute(packet.getFood()));
entity.getAttributes().put(AttributeType.SATURATION, AttributeType.SATURATION.getAttribute(packet.getSaturation())); entity.getAttributes().put(AttributeType.SATURATION, AttributeType.SATURATION.getAttribute(packet.getSaturation()));
entity.updateBedrockAttributes(session); entity.updateBedrockAttributes(session);
if (packet.getHealth() <= 0) {
RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.setRuntimeEntityId(entity.getGeyserId());
respawnPacket.setPosition(Vector3f.from(0, 72, 0));
respawnPacket.setSpawnState(RespawnPacket.State.SERVER_SEARCHING);
session.getUpstream().sendPacket(respawnPacket);
ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN);
session.getDownstream().getSession().send(javaRespawnPacket);
}
} }
} }

View file

@ -28,8 +28,7 @@ package org.geysermc.connector.network.translators.java.entity.player;
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.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.*;
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.console.GeyserLogger;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
@ -48,7 +47,20 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
return; return;
if (!session.isSpawned()) { if (!session.isSpawned()) {
entity.moveAbsolute(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()), packet.getYaw(), packet.getPitch()); Vector3f pos = Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ());
entity.moveAbsolute(pos, packet.getYaw(), packet.getPitch());
RespawnPacket respawnPacket = new RespawnPacket();
respawnPacket.setRuntimeEntityId(0);
respawnPacket.setPosition(pos);
respawnPacket.setSpawnState(RespawnPacket.State.SERVER_READY);
session.getUpstream().sendPacket(respawnPacket);
EntityEventPacket eventPacket = new EntityEventPacket();
eventPacket.setRuntimeEntityId(entity.getGeyserId());
eventPacket.setEvent(EntityEventPacket.Event.RESPAWN);
eventPacket.setData(0);
session.getUpstream().sendPacket(eventPacket);
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
@ -57,7 +69,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
movePlayerPacket.setPosition(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ())); movePlayerPacket.setPosition(pos);
movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0)); movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0));
movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET); movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET);
movePlayerPacket.setOnGround(true); movePlayerPacket.setOnGround(true);

View file

@ -3,9 +3,10 @@ package org.geysermc.connector.utils;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.chunk.Column;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.TranslatorsInit; import org.geysermc.connector.network.translators.TranslatorsInit;
@ -72,6 +73,36 @@ public class ChunkUtils {
session.getUpstream().sendPacket(waterPacket); session.getUpstream().sendPacket(waterPacket);
} }
public static void sendEmptyChunks(GeyserSession session, Vector3i position, int radius, boolean forceUpdate) {
int chunkX = position.getX() >> 4;
int chunkZ = position.getZ() >> 4;
NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket();
chunkPublisherUpdatePacket.setPosition(position);
chunkPublisherUpdatePacket.setRadius(radius + 1 << 4);
session.getUpstream().sendPacket(chunkPublisherUpdatePacket);
session.setLastChunkPosition(null);
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
LevelChunkPacket data = new LevelChunkPacket();
data.setChunkX(chunkX + x);
data.setChunkZ(chunkZ + z);
data.setSubChunksLength(0);
data.setData(TranslatorsInit.EMPTY_LEVEL_CHUNK_DATA);
data.setCachingEnabled(false);
session.getUpstream().sendPacket(data);
if (forceUpdate) {
Vector3i pos = Vector3i.from(chunkX + x << 4, 80, chunkZ + z << 4);
UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setBlockPosition(pos);
blockPacket.setDataLayer(1);
blockPacket.setRuntimeId(1);
session.getUpstream().sendPacket(blockPacket);
}
}
}
}
public static final class ChunkData { public static final class ChunkData {
public ChunkSection[] sections; public ChunkSection[] sections;

View file

@ -0,0 +1,49 @@
package org.geysermc.connector.utils;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.packet.*;
import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.network.session.GeyserSession;
public class DimensionUtils {
public static void switchDimension(GeyserSession session, int javaDimension, boolean fake) {
int bedrockDimension = javaToBedrock(javaDimension);
Entity player = session.getPlayerEntity();
if (bedrockDimension == player.getDimension())
return;
Vector3i pos = Vector3i.from(0, Short.MAX_VALUE, 0);
session.getEntityCache().removeAllEntities();
ChangeDimensionPacket changeDimensionPacket = new ChangeDimensionPacket();
changeDimensionPacket.setDimension(bedrockDimension);
changeDimensionPacket.setRespawn(true);
changeDimensionPacket.setPosition(pos.toFloat());
session.getUpstream().sendPacket(changeDimensionPacket);
player.setDimension(bedrockDimension);
//let java server handle portal travel sound
StopSoundPacket stopSoundPacket = new StopSoundPacket();
stopSoundPacket.setStoppingAllSound(true);
stopSoundPacket.setSoundName("");
session.getUpstream().sendPacket(stopSoundPacket);
if (fake) {
ChunkUtils.sendEmptyChunks(session, pos, 2, true);
}
session.setSpawned(false);
session.setSwitchingDimension(true);
}
public static int javaToBedrock(int javaDimension) {
switch (javaDimension) {
case -1:
return 1;
case 1:
return 2;
default:
return javaDimension;
}
}
}