mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Edited PlayerInit behavior and updated protocol lib to 2.3.0
This commit is contained in:
parent
a7bd9da644
commit
15506cf5b4
36 changed files with 320 additions and 514 deletions
|
@ -75,7 +75,7 @@
|
|||
<dependency>
|
||||
<groupId>com.nukkitx.protocol</groupId>
|
||||
<artifactId>bedrock-v361</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<version>2.3.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPropertiesPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityDataDictionary;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
||||
|
@ -116,17 +116,17 @@ public class Entity {
|
|||
}
|
||||
|
||||
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch) {
|
||||
moveRelative(relX, relY, relZ, new Vector3f(yaw, pitch, yaw));
|
||||
moveRelative(relX, relY, relZ, Vector3f.from(yaw, pitch, yaw));
|
||||
}
|
||||
|
||||
public void moveRelative(double relX, double relY, double relZ, Vector3f rotation) {
|
||||
setRotation(rotation);
|
||||
this.position = new Vector3f(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
||||
this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ);
|
||||
this.movePending = true;
|
||||
}
|
||||
|
||||
public void moveAbsolute(Vector3f position, float yaw, float pitch) {
|
||||
moveAbsolute(position, new Vector3f(yaw, pitch, yaw));
|
||||
moveAbsolute(position, Vector3f.from(yaw, pitch, yaw));
|
||||
}
|
||||
|
||||
public void moveAbsolute(Vector3f position, Vector3f rotation) {
|
||||
|
@ -137,7 +137,7 @@ public class Entity {
|
|||
|
||||
public EntityDataDictionary getMetadata() {
|
||||
EntityFlags flags = new EntityFlags();
|
||||
flags.setFlag(EntityFlag.HAS_GRAVITY, !is(PlayerEntity.class) || as(PlayerEntity.class).isGravity());
|
||||
flags.setFlag(EntityFlag.HAS_GRAVITY, true);
|
||||
flags.setFlag(EntityFlag.HAS_COLLISION, true);
|
||||
flags.setFlag(EntityFlag.CAN_SHOW_NAME, true);
|
||||
flags.setFlag(EntityFlag.CAN_CLIMB, true);
|
||||
|
@ -199,7 +199,7 @@ public class Entity {
|
|||
* x = Pitch, y = HeadYaw, z = Yaw
|
||||
*/
|
||||
public Vector3f getBedrockRotation() {
|
||||
return new Vector3f(rotation.getY(), rotation.getZ(), rotation.getX());
|
||||
return Vector3f.from(rotation.getY(), rotation.getZ(), rotation.getX());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.connector.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.SpawnExperienceOrbPacket;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.geysermc.connector.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddPaintingPacket;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
|
|
@ -25,16 +25,18 @@
|
|||
|
||||
package org.geysermc.connector.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -45,7 +47,6 @@ public class PlayerEntity extends Entity {
|
|||
private String username;
|
||||
private long lastSkinUpdate = -1;
|
||||
private boolean playerList = true;
|
||||
private boolean gravity = false;
|
||||
|
||||
private ItemData helmet;
|
||||
private ItemData chestplate;
|
||||
|
@ -76,17 +77,6 @@ public class PlayerEntity extends Entity {
|
|||
session.getUpstream().sendPacket(armorEquipmentPacket);
|
||||
}
|
||||
|
||||
public void enableGravity(GeyserSession session) {
|
||||
if (!gravity && session.getPlayerEntity().getGeyserId() == getGeyserId()) {
|
||||
gravity = true;
|
||||
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(geyserId);
|
||||
entityDataPacket.getMetadata().putAll(getMetadata());
|
||||
session.getUpstream().sendPacket(entityDataPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean despawnEntity(GeyserSession session) {
|
||||
super.despawnEntity(session);
|
||||
|
@ -118,4 +108,31 @@ public class PlayerEntity extends Entity {
|
|||
valid = true;
|
||||
session.getUpstream().sendPacket(addPlayerPacket);
|
||||
}
|
||||
|
||||
public void sendPlayer(GeyserSession session) {
|
||||
if (getLastSkinUpdate() == -1) {
|
||||
if (playerList) {
|
||||
PlayerListPacket playerList = new PlayerListPacket();
|
||||
playerList.setType(PlayerListPacket.Type.ADD);
|
||||
playerList.getEntries().add(SkinUtils.buildDefaultEntry(profile, geyserId));
|
||||
session.getUpstream().sendPacket(playerList);
|
||||
}
|
||||
}
|
||||
|
||||
if (session.getUpstream().isInitialized() && session.getEntityCache().getEntityByGeyserId(geyserId) == null) {
|
||||
session.getEntityCache().spawnEntity(this);
|
||||
} else {
|
||||
spawnEntity(session);
|
||||
}
|
||||
|
||||
if (!playerList) {
|
||||
// remove from playerlist if player isn't on playerlist
|
||||
Geyser.getGeneralThreadPool().execute(() -> {
|
||||
PlayerListPacket playerList = new PlayerListPacket();
|
||||
playerList.setType(PlayerListPacket.Type.REMOVE);
|
||||
playerList.getEntries().add(new PlayerListPacket.Entry(uuid));
|
||||
session.getUpstream().sendPacket(playerList);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
package org.geysermc.connector.network.session;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2f;
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.github.steveice10.mc.auth.exception.request.RequestException;
|
||||
import com.github.steveice10.mc.protocol.MinecraftProtocol;
|
||||
|
@ -40,6 +36,10 @@ import com.github.steveice10.packetlib.event.session.PacketReceivedEvent;
|
|||
import com.github.steveice10.packetlib.event.session.SessionAdapter;
|
||||
import com.github.steveice10.packetlib.packet.Packet;
|
||||
import com.github.steveice10.packetlib.tcp.TcpSessionFactory;
|
||||
import com.nukkitx.math.vector.Vector2f;
|
||||
import com.nukkitx.math.vector.Vector2i;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
||||
import com.nukkitx.protocol.bedrock.data.GamePublishSetting;
|
||||
import com.nukkitx.protocol.bedrock.data.GameRule;
|
||||
|
@ -257,15 +257,15 @@ public class GeyserSession implements Player {
|
|||
startGamePacket.setUniqueEntityId(playerEntity.getGeyserId());
|
||||
startGamePacket.setRuntimeEntityId(playerEntity.getGeyserId());
|
||||
startGamePacket.setPlayerGamemode(0);
|
||||
startGamePacket.setPlayerPosition(new Vector3f(0, 69, 0));
|
||||
startGamePacket.setRotation(new Vector2f(1, 1));
|
||||
startGamePacket.setPlayerPosition(Vector3f.from(0, 69, 0));
|
||||
startGamePacket.setRotation(Vector2f.from(1, 1));
|
||||
|
||||
startGamePacket.setSeed(0);
|
||||
startGamePacket.setDimensionId(playerEntity.getDimension());
|
||||
startGamePacket.setGeneratorId(1);
|
||||
startGamePacket.setLevelGamemode(0);
|
||||
startGamePacket.setDifficulty(1);
|
||||
startGamePacket.setDefaultSpawn(new Vector3i(0, 0, 0));
|
||||
startGamePacket.setDefaultSpawn(Vector3i.ZERO);
|
||||
startGamePacket.setAcheivementsDisabled(true);
|
||||
startGamePacket.setTime(0);
|
||||
startGamePacket.setEduLevel(false);
|
||||
|
@ -304,7 +304,5 @@ public class GeyserSession implements Player {
|
|||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||
upstream.sendPacket(playStatusPacket);
|
||||
|
||||
upstream.setFrozen(true); // will freeze until the client decides it is ready
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,46 +5,24 @@ import com.nukkitx.protocol.bedrock.BedrockServerSession;
|
|||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.api.Geyser;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class UpstreamSession {
|
||||
@Getter private final BedrockServerSession session;
|
||||
private Queue<BedrockPacket> packets = new ConcurrentLinkedQueue<>();
|
||||
@Getter private boolean frozen = false;
|
||||
private boolean queueCleared = true;
|
||||
@Getter @Setter
|
||||
private boolean initialized = false;
|
||||
|
||||
public void sendPacket(@NonNull BedrockPacket packet) {
|
||||
if (frozen || !packets.isEmpty()) {
|
||||
packets.add(packet);
|
||||
} else {
|
||||
session.sendPacket(packet);
|
||||
}
|
||||
session.sendPacket(packet);
|
||||
}
|
||||
|
||||
public void sendPacketImmediately(@NonNull BedrockPacket packet) {
|
||||
session.sendPacketImmediately(packet);
|
||||
}
|
||||
|
||||
public void setFrozen(boolean frozen) {
|
||||
if (this.frozen != frozen) {
|
||||
this.frozen = frozen;
|
||||
|
||||
if (!frozen) {
|
||||
Geyser.getGeneralThreadPool().execute(() -> {
|
||||
BedrockPacket packet;
|
||||
while ((packet = packets.poll()) != null) {
|
||||
session.sendPacket(packet);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect(String reason) {
|
||||
session.disconnect(reason);
|
||||
}
|
||||
|
@ -56,20 +34,4 @@ public class UpstreamSession {
|
|||
public InetSocketAddress getAddress() {
|
||||
return session.getAddress();
|
||||
}
|
||||
|
||||
public boolean hasQueue() {
|
||||
return !packets.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true the first time this method is called after the queue is empty.<br>
|
||||
* This will enable gravity because now the client is ready to explore
|
||||
*/
|
||||
public boolean isQueueCleared() {
|
||||
if (!hasQueue() && queueCleared) {
|
||||
queueCleared = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,7 @@ import org.geysermc.connector.entity.Entity;
|
|||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
|
@ -84,6 +82,16 @@ public class EntityCache {
|
|||
return entities.get(entityIdTranslations.get(javaId));
|
||||
}
|
||||
|
||||
public <T extends Entity> Set<T> getEntitiesByType(Class<T> entityType) {
|
||||
Set<T> entitiesOfType = new HashSet<>();
|
||||
for (Entity entity : (entityType == PlayerEntity.class ? playerEntities : entities).values()) {
|
||||
if (entity.is(entityType)) {
|
||||
entitiesOfType.add(entity.as(entityType));
|
||||
}
|
||||
}
|
||||
return entitiesOfType;
|
||||
}
|
||||
|
||||
public void addPlayerEntity(PlayerEntity entity) {
|
||||
playerEntities.put(entity.getUuid(), entity);
|
||||
}
|
||||
|
|
|
@ -54,10 +54,7 @@ import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
|||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.network.translators.java.*;
|
||||
import org.geysermc.connector.network.translators.java.entity.*;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerActionAckTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerHealthTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerPositionRotationTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.JavaPlayerSetExperienceTranslator;
|
||||
import org.geysermc.connector.network.translators.java.entity.player.*;
|
||||
import org.geysermc.connector.network.translators.java.entity.spawn.*;
|
||||
import org.geysermc.connector.network.translators.java.scoreboard.JavaDisplayScoreboardTranslator;
|
||||
import org.geysermc.connector.network.translators.java.scoreboard.JavaScoreboardObjectiveTranslator;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||
|
@ -34,6 +33,7 @@ import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
|||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
|
|
@ -25,21 +25,11 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.InteractPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
|
@ -44,9 +45,15 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
|||
if (entity == null || !session.isSpawned()) return;
|
||||
|
||||
// can cause invalid moves when packet queue is not empty
|
||||
if (session.getUpstream().hasQueue()) return;
|
||||
if (session.getUpstream().isQueueCleared()) {
|
||||
entity.enableGravity(session);
|
||||
if (!session.getUpstream().isInitialized()) {
|
||||
MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket();
|
||||
moveEntityBack.setRuntimeEntityId(entity.getGeyserId());
|
||||
moveEntityBack.setPosition(entity.getPosition());
|
||||
moveEntityBack.setRotation(entity.getBedrockRotation());
|
||||
moveEntityBack.setTeleported(true);
|
||||
moveEntityBack.setOnGround(true);
|
||||
session.getUpstream().sendPacketImmediately(moveEntityBack);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isValidMove(session, packet.getMode(), entity.getPosition(), packet.getPosition())) {
|
||||
|
@ -62,7 +69,10 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
|||
packet.getPosition().getZ(), packet.getRotation().getY(), packet.getRotation().getX()
|
||||
);
|
||||
|
||||
entity.moveAbsolute(packet.getPosition().sub(0, EntityType.PLAYER.getOffset(), 0), packet.getRotation());
|
||||
// head yaw, pitch, head yaw
|
||||
Vector3f rotation = Vector3f.from(packet.getRotation().getY(), packet.getRotation().getX(), packet.getRotation().getY());
|
||||
|
||||
entity.moveAbsolute(packet.getPosition().sub(0, EntityType.PLAYER.getOffset(), 0), rotation);
|
||||
|
||||
boolean colliding = false;
|
||||
Position position = new Position((int) packet.getPosition().getX(),
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import com.nukkitx.protocol.bedrock.packet.SetLocalPlayerAsInitializedPacket;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
|
||||
public class BedrockPlayerInitializedTranslator extends PacketTranslator<SetLocalPlayerAsInitializedPacket> {
|
||||
@Override
|
||||
public void translate(SetLocalPlayerAsInitializedPacket packet, GeyserSession session) {
|
||||
if (session.getPlayerEntity().getGeyserId() == packet.getRuntimeEntityId()) {
|
||||
session.getUpstream().setFrozen(false);
|
||||
if (!session.getUpstream().isInitialized()) {
|
||||
session.getUpstream().setInitialized(true);
|
||||
|
||||
for (PlayerEntity entity : session.getEntityCache().getEntitiesByType(PlayerEntity.class)) {
|
||||
if (!entity.isValid()) {
|
||||
entity.sendPlayer(session);
|
||||
// async skin loading
|
||||
SkinUtils.requestAndHandleSkinAndCape(entity, session, skinAndCape -> entity.sendPlayer(session));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.inventory;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
|
||||
|
@ -46,7 +46,7 @@ public class GenericInventoryTranslator extends InventoryTranslator {
|
|||
ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket();
|
||||
containerOpenPacket.setWindowId((byte) inventory.getId());
|
||||
containerOpenPacket.setType((byte) 0);
|
||||
containerOpenPacket.setBlockPosition(new Vector3i(0, 0, 0));
|
||||
containerOpenPacket.setBlockPosition(Vector3i.ZERO);
|
||||
session.getUpstream().sendPacket(containerOpenPacket);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.geysermc.connector.network.translators.java;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerBossBarPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.BossEventPacket;
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityHeadLookPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -43,7 +43,7 @@ public class JavaEntityHeadLookTranslator extends PacketTranslator<ServerEntityH
|
|||
|
||||
if (entity == null) return;
|
||||
|
||||
entity.setRotation(new Vector3f(entity.getRotation().getX(), entity.getRotation().getY(), packet.getHeadYaw()));
|
||||
entity.setRotation(Vector3f.from(entity.getRotation().getX(), entity.getRotation().getY(), packet.getHeadYaw()));
|
||||
|
||||
MoveEntityAbsolutePacket moveEntityAbsolutePacket = new MoveEntityAbsolutePacket();
|
||||
moveEntityAbsolutePacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -42,7 +42,7 @@ public class JavaEntityTeleportTranslator extends PacketTranslator<ServerEntityT
|
|||
}
|
||||
if (entity == null) return;
|
||||
|
||||
entity.moveAbsolute(new Vector3f(packet.getX(), packet.getY(), packet.getZ()), packet.getYaw(), packet.getPitch());
|
||||
entity.moveAbsolute(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()), packet.getYaw(), packet.getPitch());
|
||||
|
||||
if (entity.isMovePending()) {
|
||||
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -42,7 +42,7 @@ public class JavaEntityVelocityTranslator extends PacketTranslator<ServerEntityV
|
|||
}
|
||||
if (entity == null) return;
|
||||
|
||||
entity.setMotion(new Vector3f(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ()));
|
||||
entity.setMotion(Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ()));
|
||||
|
||||
SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
|
||||
entityMotionPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.player;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerActionAckPacket;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.player;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
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.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.RespawnPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetHealthPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
|
@ -61,7 +61,7 @@ public class JavaPlayerHealthTranslator extends PacketTranslator<ServerPlayerHea
|
|||
|
||||
if (packet.getHealth() <= 0) {
|
||||
RespawnPacket respawnPacket = new RespawnPacket();
|
||||
respawnPacket.setPosition(new Vector3f(0, 72, 0));
|
||||
respawnPacket.setPosition(Vector3f.from(0, 72, 0));
|
||||
session.getUpstream().sendPacket(new RespawnPacket());
|
||||
|
||||
ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN);
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
package org.geysermc.connector.network.translators.java.entity.player;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
|
||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPlayerListEntryPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.utils.SkinProvider;
|
||||
|
||||
public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayerListEntryPacket> {
|
||||
@Override
|
||||
|
@ -16,16 +15,15 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayer
|
|||
if (packet.getAction() != PlayerListEntryAction.ADD_PLAYER && packet.getAction() != PlayerListEntryAction.REMOVE_PLAYER) return;
|
||||
|
||||
PlayerListPacket translate = new PlayerListPacket();
|
||||
translate.setType(packet.getAction() == PlayerListEntryAction.ADD_PLAYER ? PlayerListPacket.Type.ADD : PlayerListPacket.Type.REMOVE);
|
||||
translate.setType(PlayerListPacket.Type.REMOVE);
|
||||
|
||||
for (PlayerListEntry entry : packet.getEntries()) {
|
||||
PlayerListPacket.Entry entry1 = new PlayerListPacket.Entry(entry.getProfile().getId());
|
||||
|
||||
if (packet.getAction() == PlayerListEntryAction.ADD_PLAYER) {
|
||||
boolean self = entry.getProfile().getId().equals(session.getPlayerEntity().getUuid());
|
||||
|
||||
PlayerEntity playerEntity = session.getPlayerEntity();
|
||||
if (!self) {
|
||||
if (self) playerEntity.setProfile(entry.getProfile());
|
||||
else {
|
||||
playerEntity = new PlayerEntity(
|
||||
entry.getProfile(),
|
||||
-1,
|
||||
|
@ -38,16 +36,6 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayer
|
|||
|
||||
session.getEntityCache().addPlayerEntity(playerEntity);
|
||||
playerEntity.setPlayerList(true);
|
||||
|
||||
entry1.setName(entry.getProfile().getName());
|
||||
entry1.setEntityId(playerEntity.getGeyserId());
|
||||
entry1.setSkinId(entry.getProfile().getIdAsString());
|
||||
entry1.setSkinData(SkinProvider.STEVE_SKIN);
|
||||
entry1.setCapeData(new byte[0]);
|
||||
entry1.setGeometryName("geometry.humanoid");
|
||||
entry1.setGeometryData("");
|
||||
entry1.setXuid("");
|
||||
entry1.setPlatformChatId("");
|
||||
} else {
|
||||
PlayerEntity entity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
||||
if (entity != null && entity.isValid()) {
|
||||
|
@ -57,9 +45,12 @@ public class JavaPlayerListEntryTranslator extends PacketTranslator<ServerPlayer
|
|||
// just remove it from caching
|
||||
session.getEntityCache().removePlayerEntity(entry.getProfile().getId());
|
||||
}
|
||||
translate.getEntries().add(new PlayerListPacket.Entry(entry.getProfile().getId()));
|
||||
}
|
||||
translate.getEntries().add(entry1);
|
||||
}
|
||||
session.getUpstream().sendPacket(translate);
|
||||
|
||||
if (packet.getAction() == PlayerListEntryAction.REMOVE_PLAYER) {
|
||||
session.getUpstream().sendPacket(translate);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.player;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
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.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.connector.console.GeyserLogger;
|
||||
|
@ -48,7 +48,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
|
|||
return;
|
||||
|
||||
if (!session.isSpawned()) {
|
||||
entity.moveAbsolute(new Vector3f(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()), packet.getYaw(), packet.getPitch());
|
||||
entity.moveAbsolute(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()), packet.getYaw(), packet.getPitch());
|
||||
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
|
@ -57,8 +57,8 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
|
|||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
movePlayerPacket.setPosition(new Vector3f(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()));
|
||||
movePlayerPacket.setRotation(new Vector3f(packet.getPitch(), packet.getYaw(), 0));
|
||||
movePlayerPacket.setPosition(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()));
|
||||
movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0));
|
||||
movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET);
|
||||
movePlayerPacket.setOnGround(true);
|
||||
entity.setMovePending(false);
|
||||
|
@ -70,12 +70,12 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
|
|||
return;
|
||||
}
|
||||
|
||||
entity.moveAbsolute(new Vector3f(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()), packet.getYaw(), packet.getPitch());
|
||||
entity.moveAbsolute(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()), packet.getYaw(), packet.getPitch());
|
||||
|
||||
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
|
||||
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
movePlayerPacket.setPosition(new Vector3f(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.01f, packet.getZ()));
|
||||
movePlayerPacket.setRotation(new Vector3f(packet.getPitch(), packet.getYaw(), 0));
|
||||
movePlayerPacket.setPosition(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.01f, packet.getZ()));
|
||||
movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0));
|
||||
movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL);
|
||||
movePlayerPacket.setOnGround(true);
|
||||
entity.setMovePending(false);
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnExpOrbPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.ExpOrbEntity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
|
@ -37,7 +37,7 @@ public class JavaSpawnExpOrbTranslator extends PacketTranslator<ServerSpawnExpOr
|
|||
|
||||
@Override
|
||||
public void translate(ServerSpawnExpOrbPacket packet, GeyserSession session) {
|
||||
Vector3f position = new Vector3f(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||
|
||||
Entity entity = new ExpOrbEntity(
|
||||
packet.getExp(), packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnGlobalEntityPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -36,7 +36,7 @@ public class JavaSpawnGlobalEntityTranslator extends PacketTranslator<ServerSpaw
|
|||
|
||||
@Override
|
||||
public void translate(ServerSpawnGlobalEntityPacket packet, GeyserSession session) {
|
||||
Vector3f position = new Vector3f(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||
|
||||
// Currently GlobalEntityType only has a lightning bolt
|
||||
Entity entity = new Entity(
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnMobPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.connector.console.GeyserLogger;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
|
@ -38,9 +38,9 @@ public class JavaSpawnMobTranslator extends PacketTranslator<ServerSpawnMobPacke
|
|||
|
||||
@Override
|
||||
public void translate(ServerSpawnMobPacket packet, GeyserSession session) {
|
||||
Vector3f position = new Vector3f(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f motion = new Vector3f(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
|
||||
Vector3f rotation = new Vector3f(packet.getYaw(), packet.getPitch(), packet.getHeadYaw());
|
||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
|
||||
Vector3f rotation = Vector3f.from(packet.getYaw(), packet.getPitch(), packet.getHeadYaw());
|
||||
|
||||
EntityType type = EntityUtils.toBedrockEntity(packet.getType());
|
||||
if (type == null) {
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.object.ObjectType;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnObjectPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.connector.console.GeyserLogger;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
|
@ -42,9 +42,9 @@ public class JavaSpawnObjectTranslator extends PacketTranslator<ServerSpawnObjec
|
|||
if (packet.getType() == ObjectType.ITEM_FRAME)
|
||||
return;
|
||||
|
||||
Vector3f position = new Vector3f(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f motion = new Vector3f(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
|
||||
Vector3f rotation = new Vector3f(packet.getYaw(), packet.getPitch(), 0);
|
||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||
Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
|
||||
Vector3f rotation = Vector3f.from(packet.getYaw(), packet.getPitch(), 0);
|
||||
|
||||
EntityType type = EntityUtils.toBedrockEntity(packet.getType());
|
||||
if (type == null) {
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPaintingPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.entity.PaintingEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -37,7 +37,7 @@ public class JavaSpawnPaintingTranslator extends PacketTranslator<ServerSpawnPai
|
|||
|
||||
@Override
|
||||
public void translate(ServerSpawnPaintingPacket packet, GeyserSession session) {
|
||||
Vector3f position = new Vector3f(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ());
|
||||
Vector3f position = Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ());
|
||||
|
||||
Geyser.getGeneralThreadPool().execute(() -> { // #slowdownbrother, just don't execute it directly
|
||||
PaintingEntity entity = new PaintingEntity(
|
||||
|
|
|
@ -25,27 +25,21 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.entity.spawn;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.utils.SkinProvider;
|
||||
|
||||
import java.util.Base64;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
|
||||
public class JavaSpawnPlayerTranslator extends PacketTranslator<ServerSpawnPlayerPacket> {
|
||||
|
||||
@Override
|
||||
public void translate(ServerSpawnPlayerPacket packet, GeyserSession session) {
|
||||
Vector3f position = new Vector3f(packet.getX(), packet.getY() - EntityType.PLAYER.getOffset(), packet.getZ());
|
||||
Vector3f rotation = new Vector3f(packet.getYaw(), packet.getPitch(), packet.getYaw());
|
||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY() - EntityType.PLAYER.getOffset(), packet.getZ());
|
||||
Vector3f rotation = Vector3f.from(packet.getYaw(), packet.getPitch(), packet.getYaw());
|
||||
|
||||
PlayerEntity entity = session.getEntityCache().getPlayerEntity(packet.getUUID());
|
||||
if (entity == null) {
|
||||
|
@ -57,64 +51,8 @@ public class JavaSpawnPlayerTranslator extends PacketTranslator<ServerSpawnPlaye
|
|||
entity.setPosition(position);
|
||||
entity.setRotation(rotation);
|
||||
|
||||
session.getEntityCache().spawnEntity(entity);
|
||||
|
||||
// request skin and cape
|
||||
|
||||
Geyser.getGeneralThreadPool().execute(() -> {
|
||||
GameProfile.Property skinProperty = entity.getProfile().getProperty("textures");
|
||||
|
||||
JsonObject skinObject = SkinProvider.GSON.fromJson(new String(Base64.getDecoder().decode(skinProperty.getValue()), Charsets.UTF_8), JsonObject.class);
|
||||
JsonObject textures = skinObject.getAsJsonObject("textures");
|
||||
|
||||
JsonObject skinTexture = textures.getAsJsonObject("SKIN");
|
||||
String skinUrl = skinTexture.get("url").getAsString();
|
||||
|
||||
boolean isAlex = skinTexture.has("metadata");
|
||||
|
||||
String capeUrl = null;
|
||||
if (textures.has("CAPE")) {
|
||||
JsonObject capeTexture = textures.getAsJsonObject("CAPE");
|
||||
capeUrl = capeTexture.get("url").getAsString();
|
||||
}
|
||||
|
||||
SkinProvider.requestAndHandleSkinAndCape(entity.getUuid(), skinUrl, capeUrl)
|
||||
.whenCompleteAsync((skinAndCape, throwable) -> {
|
||||
SkinProvider.Skin skin = skinAndCape.getSkin();
|
||||
SkinProvider.Cape cape = skinAndCape.getCape();
|
||||
|
||||
if (cape.isFailed() && SkinProvider.ALLOW_THIRD_PARTY_CAPES) {
|
||||
cape = SkinProvider.getOrDefault(SkinProvider.requestAndHandleUnofficialCape(
|
||||
cape, entity.getUuid(),
|
||||
entity.getUsername(), false
|
||||
), SkinProvider.EMPTY_CAPE, SkinProvider.UnofficalCape.VALUES.length * 3);
|
||||
}
|
||||
|
||||
if (entity.getLastSkinUpdate() < skin.getRequestedOn()) {
|
||||
entity.setLastSkinUpdate(skin.getRequestedOn());
|
||||
|
||||
PlayerListPacket.Entry updatedEntry = new PlayerListPacket.Entry(skin.getSkinOwner());
|
||||
updatedEntry.setName(entity.getUsername());
|
||||
updatedEntry.setEntityId(entity.getGeyserId());
|
||||
updatedEntry.setSkinId(entity.getUuid().toString());
|
||||
updatedEntry.setSkinData(skin.getSkinData());
|
||||
updatedEntry.setCapeData(cape.getCapeData());
|
||||
updatedEntry.setGeometryName("geometry.humanoid.custom" + (isAlex ? "Slim" : ""));
|
||||
updatedEntry.setGeometryData("");
|
||||
updatedEntry.setXuid("");
|
||||
updatedEntry.setPlatformChatId("");
|
||||
|
||||
PlayerListPacket playerRemovePacket = new PlayerListPacket();
|
||||
playerRemovePacket.setType(PlayerListPacket.Type.REMOVE);
|
||||
playerRemovePacket.getEntries().add(updatedEntry);
|
||||
session.getUpstream().sendPacket(playerRemovePacket);
|
||||
|
||||
PlayerListPacket playerAddPacket = new PlayerListPacket();
|
||||
playerAddPacket.setType(PlayerListPacket.Type.ADD);
|
||||
playerAddPacket.getEntries().add(updatedEntry);
|
||||
session.getUpstream().sendPacket(playerAddPacket);
|
||||
}
|
||||
}).isCompletedExceptionally();
|
||||
});
|
||||
entity.sendPlayer(session);
|
||||
// async skin loading
|
||||
SkinUtils.requestAndHandleSkinAndCape(entity, session, skinAndCape -> entity.sendPlayer(session));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerBlockChangePacket;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -16,10 +16,11 @@ public class JavaBlockChangeTranslator extends PacketTranslator<ServerBlockChang
|
|||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||
BlockChangeRecord record = packet.getRecord();
|
||||
updateBlockPacket.setDataLayer(0);
|
||||
updateBlockPacket.setBlockPosition(new Vector3i(
|
||||
updateBlockPacket.setBlockPosition(Vector3i.from(
|
||||
record.getPosition().getX(),
|
||||
record.getPosition().getY(),
|
||||
record.getPosition().getZ()));
|
||||
record.getPosition().getZ()
|
||||
));
|
||||
|
||||
BedrockItem bedrockItem = TranslatorsInit.getBlockTranslator().getBedrockBlock(record.getBlock());
|
||||
updateBlockPacket.setRuntimeId(GlobalBlockPalette.getOrCreateRuntimeId(bedrockItem.hashCode()));
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerChunkDataPacket;
|
||||
import com.nukkitx.math.vector.Vector2i;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.network.VarInts;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerMultiBlockChangePacket;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -42,10 +42,11 @@ public class JavaMultiBlockChangeTranslator extends PacketTranslator<ServerMulti
|
|||
for (BlockChangeRecord record : packet.getRecords()) {
|
||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||
updateBlockPacket.setDataLayer(0);
|
||||
updateBlockPacket.setBlockPosition(new Vector3i(
|
||||
updateBlockPacket.setBlockPosition(Vector3i.from(
|
||||
record.getPosition().getX(),
|
||||
record.getPosition().getY(),
|
||||
record.getPosition().getZ()));
|
||||
record.getPosition().getZ()
|
||||
));
|
||||
|
||||
BedrockItem bedrockItem = TranslatorsInit.getBlockTranslator().getBedrockBlock(record.getBlock());
|
||||
updateBlockPacket.setRuntimeId(GlobalBlockPalette.getOrCreateRuntimeId(bedrockItem.hashCode()));
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3f;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.ShowCreditsPacket;
|
||||
|
@ -46,14 +46,14 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
|
|||
LevelEventPacket startRainPacket = new LevelEventPacket();
|
||||
startRainPacket.setEvent(LevelEventPacket.Event.START_RAIN);
|
||||
startRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000);
|
||||
startRainPacket.setPosition(new Vector3f(0, 0, 0));
|
||||
startRainPacket.setPosition(Vector3f.ZERO);
|
||||
session.getUpstream().sendPacket(startRainPacket);
|
||||
break;
|
||||
case STOP_RAIN:
|
||||
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
||||
stopRainPacket.setEvent(LevelEventPacket.Event.STOP_RAIN);
|
||||
stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000);
|
||||
stopRainPacket.setPosition(new Vector3f(0, 0, 0));
|
||||
stopRainPacket.setPosition(Vector3f.ZERO);
|
||||
session.getUpstream().sendPacket(stopRainPacket);
|
||||
break;
|
||||
case CHANGE_GAMEMODE:
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnPositionPacket;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetSpawnPositionPacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -36,7 +36,7 @@ public class JavaSpawnPositionTranslator extends PacketTranslator<ServerSpawnPos
|
|||
@Override
|
||||
public void translate(ServerSpawnPositionPacket packet, GeyserSession session) {
|
||||
SetSpawnPositionPacket spawnPositionPacket = new SetSpawnPositionPacket();
|
||||
spawnPositionPacket.setBlockPosition(new Vector3i(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ()));
|
||||
spawnPositionPacket.setBlockPosition(Vector3i.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ()));
|
||||
spawnPositionPacket.setSpawnForced(true);
|
||||
spawnPositionPacket.setSpawnType(SetSpawnPositionPacket.Type.PLAYER_SPAWN);
|
||||
session.getUpstream().sendPacket(spawnPositionPacket);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import com.flowpowered.math.vector.Vector3d;
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.nukkitx.math.vector.Vector2i;
|
||||
import com.nukkitx.math.vector.Vector3d;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
|
||||
|
@ -13,43 +13,28 @@ import java.util.UUID;
|
|||
import java.util.function.*;
|
||||
|
||||
public class GeyserUtils {
|
||||
|
||||
public static final int FLAG_RUNTIME = 1;
|
||||
|
||||
public static final int GLOBAL_PALETTE_BITS_PER_BLOCK = 14;
|
||||
|
||||
public static final int SECTION_COUNT_BLOCKS = 16;
|
||||
|
||||
public static final int SECTION_COUNT_LIGHT = 18;
|
||||
|
||||
public static final int BLOCKS_IN_SECTION = 16 * 16 * 16;
|
||||
|
||||
public static final int LIGHT_DATA_LENGTH = BLOCKS_IN_SECTION / 2;
|
||||
|
||||
public static final int EMPTY_SUBCHUNK_BYTES = BLOCKS_IN_SECTION / 8;
|
||||
|
||||
public static final int SUBCHUNK_VERSION = 8;
|
||||
|
||||
public static void writeEmpty(ByteBuf to) {
|
||||
|
||||
to.writeByte(storageHeader(1));
|
||||
|
||||
to.writeZero(EMPTY_SUBCHUNK_BYTES);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected static final int storageHeader(int bitsPerBlock) {
|
||||
|
||||
return (bitsPerBlock << 1) | FLAG_RUNTIME;
|
||||
|
||||
}
|
||||
|
||||
public static void writeEmptySubChunk(ByteBuf out) {
|
||||
|
||||
out.writeBytes(new byte[4096 + 4096]);
|
||||
|
||||
}
|
||||
|
||||
public static void skipPosition(ByteBuf from) {
|
||||
|
@ -58,7 +43,7 @@ public class GeyserUtils {
|
|||
|
||||
public static Vector3d readPosition(ByteBuf from) {
|
||||
long l = from.readLong();
|
||||
return new Vector3d(
|
||||
return Vector3d.from(
|
||||
(int) (l >> 38), (int) (l & 0xFFF), (int) ((l << 26) >> 38)
|
||||
);
|
||||
}
|
||||
|
@ -70,7 +55,7 @@ public class GeyserUtils {
|
|||
}
|
||||
|
||||
public static Vector3d readLegacyPositionI(ByteBuf from) {
|
||||
return new Vector3d(from.readInt(), from.readInt(), from.readInt());
|
||||
return Vector3d.from(from.readInt(), from.readInt(), from.readInt());
|
||||
}
|
||||
|
||||
public static void writePosition(ByteBuf to, Vector3i position) {
|
||||
|
@ -106,11 +91,11 @@ public class GeyserUtils {
|
|||
}
|
||||
|
||||
public static Vector2i readIntChunkCoord(ByteBuf from) {
|
||||
return new Vector2i(from.readInt(), from.readInt());
|
||||
return Vector2i.from(from.readInt(), from.readInt());
|
||||
}
|
||||
|
||||
public static Vector2i readVarIntChunkCoord(ByteBuf from) {
|
||||
return new Vector2i(readVarInt(from), readVarInt(from));
|
||||
return Vector2i.from(readVarInt(from), readVarInt(from));
|
||||
}
|
||||
|
||||
public static void writeIntChunkCoord(ByteBuf to, Vector2i chunk) {
|
||||
|
@ -119,7 +104,7 @@ public class GeyserUtils {
|
|||
}
|
||||
|
||||
public static Vector2i readPEChunkCoord(ByteBuf from) {
|
||||
return new Vector2i(readSVarInt(from), readSVarInt(from));
|
||||
return Vector2i.from(readSVarInt(from), readSVarInt(from));
|
||||
}
|
||||
|
||||
public static void writePEChunkCoord(ByteBuf to, Vector2i chunk) {
|
||||
|
@ -140,513 +125,269 @@ public class GeyserUtils {
|
|||
writeVarInt(to, chunk.getY());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final int MAX_LENGTH = 5;
|
||||
|
||||
|
||||
public static final int MAX_VARINT_LENGTH = 5;
|
||||
|
||||
public static void writeFixedSizeVarInt(ByteBuf to, int i) {
|
||||
|
||||
int writerIndex = to.writerIndex();
|
||||
|
||||
while ((i & 0xFFFFFF80) != 0x0) {
|
||||
|
||||
to.writeByte(i | 0x80);
|
||||
|
||||
i >>>= 7;
|
||||
|
||||
}
|
||||
|
||||
int paddingBytes = MAX_LENGTH - (to.writerIndex() - writerIndex) - 1;
|
||||
int paddingBytes = MAX_VARINT_LENGTH - (to.writerIndex() - writerIndex) - 1;
|
||||
|
||||
if (paddingBytes == 0) {
|
||||
|
||||
to.writeByte(i);
|
||||
|
||||
} else {
|
||||
|
||||
to.writeByte(i | 0x80);
|
||||
|
||||
while (--paddingBytes > 0) {
|
||||
|
||||
to.writeByte(0x80);
|
||||
|
||||
}
|
||||
|
||||
to.writeByte(0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int readVarInt(ByteBuf from) {
|
||||
|
||||
int value = 0;
|
||||
|
||||
int length = 0;
|
||||
|
||||
byte part;
|
||||
|
||||
do {
|
||||
|
||||
part = from.readByte();
|
||||
|
||||
value |= (part & 0x7F) << (length++ * 7);
|
||||
|
||||
if (length > MAX_LENGTH) {
|
||||
|
||||
if (length > MAX_VARINT_LENGTH) {
|
||||
throw new DecoderException("VarInt too big");
|
||||
|
||||
}
|
||||
|
||||
} while (part < 0);
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeVarInt(ByteBuf to, int i) {
|
||||
|
||||
while ((i & 0xFFFFFF80) != 0x0) {
|
||||
|
||||
to.writeByte(i | 0x80);
|
||||
|
||||
i >>>= 7;
|
||||
|
||||
}
|
||||
|
||||
to.writeByte(i);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int readSVarInt(ByteBuf from) {
|
||||
|
||||
int varint = readVarInt(from);
|
||||
|
||||
return (varint >> 1) ^ -(varint & 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeSVarInt(ByteBuf to, int varint) {
|
||||
|
||||
writeVarInt(to, (varint << 1) ^ (varint >> 31));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static long readVarLong(ByteBuf from) {
|
||||
|
||||
long varlong = 0L;
|
||||
|
||||
int length = 0;
|
||||
|
||||
byte part;
|
||||
|
||||
do {
|
||||
|
||||
part = from.readByte();
|
||||
|
||||
varlong |= (part & 0x7F) << (length++ * 7);
|
||||
|
||||
if (length > 10) {
|
||||
|
||||
throw new RuntimeException("VarLong too big");
|
||||
|
||||
}
|
||||
|
||||
} while ((part & 0x80) == 0x80);
|
||||
|
||||
return varlong;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeVarLong(ByteBuf to, long varlong) {
|
||||
|
||||
while ((varlong & 0xFFFFFFFFFFFFFF80L) != 0x0L) {
|
||||
|
||||
to.writeByte((int) (varlong & 0x7FL) | 0x80);
|
||||
|
||||
varlong >>>= 7;
|
||||
|
||||
}
|
||||
|
||||
to.writeByte((int) varlong);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static long readSVarLong(ByteBuf from) {
|
||||
|
||||
long varlong = readVarLong(from);
|
||||
|
||||
return (varlong >> 1) ^ -(varlong & 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeSVarLong(ByteBuf to, long varlong) {
|
||||
|
||||
writeVarLong(to, (varlong << 1) ^ (varlong >> 63));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static ByteBuf readShortByteArraySlice(ByteBuf from, int limit) {
|
||||
|
||||
int length = from.readShort();
|
||||
|
||||
checkLimit(length, limit);
|
||||
|
||||
return from.readSlice(length);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public static <T> T[] readShortTArray(ByteBuf from, Class<T> tclass, Function<ByteBuf, T> elementReader) {
|
||||
|
||||
T[] array = (T[]) Array.newInstance(tclass, from.readShort());
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
|
||||
array[i] = elementReader.apply(from);
|
||||
|
||||
}
|
||||
|
||||
return array;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte[] readVarIntByteArray(ByteBuf from) {
|
||||
|
||||
return readBytes(from, readVarInt(from));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ByteBuf readVarIntByteArraySlice(ByteBuf from, int limit) {
|
||||
|
||||
int length = readVarInt(from);
|
||||
|
||||
checkLimit(length, limit);
|
||||
|
||||
return from.readSlice(length);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ByteBuf readVarIntByteArraySlice(ByteBuf from) {
|
||||
|
||||
return from.readSlice(readVarInt(from));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
public static <T> T[] readVarIntTArray(ByteBuf from, Class<T> tclass, Function<ByteBuf, T> elementReader) {
|
||||
|
||||
T[] array = (T[]) Array.newInstance(tclass, readVarInt(from));
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
|
||||
array[i] = elementReader.apply(from);
|
||||
|
||||
}
|
||||
|
||||
return array;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int[] readVarIntVarIntArray(ByteBuf from) {
|
||||
|
||||
int[] array = new int[readVarInt(from)];
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
|
||||
array[i] = readVarInt(from);
|
||||
|
||||
}
|
||||
|
||||
return array;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void writeShortByteArray(ByteBuf to, ByteBuf data) {
|
||||
|
||||
to.writeShort(data.readableBytes());
|
||||
|
||||
to.writeBytes(data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeShortByteArray(ByteBuf to, byte[] data) {
|
||||
|
||||
to.writeShort(data.length);
|
||||
|
||||
to.writeBytes(data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeShortByteArray(ByteBuf to, Consumer<ByteBuf> dataWriter) {
|
||||
|
||||
writeLengthPrefixedBytes(to, (lTo, length) -> lTo.writeShort(length), dataWriter);
|
||||
|
||||
writeLengthPrefixedBytes(to, ByteBuf::writeShort, dataWriter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> void writeShortTArray(ByteBuf to, T[] array, BiConsumer<ByteBuf, T> elementWriter) {
|
||||
|
||||
to.writeShort(array.length);
|
||||
|
||||
for (T element : array) {
|
||||
|
||||
elementWriter.accept(to, element);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void writeVarIntByteArray(ByteBuf to, ByteBuf data) {
|
||||
|
||||
writeVarInt(to, data.readableBytes());
|
||||
|
||||
to.writeBytes(data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeVarIntByteArray(ByteBuf to, byte[] data) {
|
||||
|
||||
writeVarInt(to, data.length);
|
||||
|
||||
to.writeBytes(data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeVarIntByteArray(ByteBuf to, Consumer<ByteBuf> dataWriter) {
|
||||
|
||||
writeLengthPrefixedBytes(to, GeyserUtils::writeFixedSizeVarInt, dataWriter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeVarIntTArray(ByteBuf to, ToIntFunction<ByteBuf> arrayWriter) {
|
||||
|
||||
writeSizePrefixedData(to, GeyserUtils::writeFixedSizeVarInt, arrayWriter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> void writeVarIntTArray(ByteBuf to, T[] array, BiConsumer<ByteBuf, T> elementWriter) {
|
||||
|
||||
writeVarInt(to, array.length);
|
||||
|
||||
for (T element : array) {
|
||||
|
||||
elementWriter.accept(to, element);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> void writeVarIntTArray(ByteBuf to, List<T> array, BiConsumer<ByteBuf, T> elementWriter) {
|
||||
|
||||
writeVarInt(to, array.size());
|
||||
|
||||
for (T element : array) {
|
||||
|
||||
elementWriter.accept(to, element);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void writeVarIntEnum(ByteBuf to, Enum<?> e) {
|
||||
|
||||
writeVarInt(to, e.ordinal());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeByteEnum(ByteBuf to, Enum<?> e) {
|
||||
|
||||
to.writeByte(e.ordinal());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static UUID readUUID(ByteBuf from) {
|
||||
|
||||
return new UUID(from.readLong(), from.readLong());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeUUID(ByteBuf to, UUID uuid) {
|
||||
|
||||
to.writeLong(uuid.getMostSignificantBits());
|
||||
|
||||
to.writeLong(uuid.getLeastSignificantBits());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writePEUUID(ByteBuf to, UUID uuid) {
|
||||
|
||||
to.writeLongLE(uuid.getMostSignificantBits());
|
||||
|
||||
to.writeLongLE(uuid.getLeastSignificantBits());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] readAllBytes(ByteBuf buf) {
|
||||
|
||||
return readBytes(buf, buf.readableBytes());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ByteBuf readAllBytesSlice(ByteBuf from) {
|
||||
|
||||
return from.readSlice(from.readableBytes());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ByteBuf readAllBytesSlice(ByteBuf buf, int limit) {
|
||||
|
||||
checkLimit(buf.readableBytes(), limit);
|
||||
|
||||
return readAllBytesSlice(buf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] readBytes(ByteBuf buf, int length) {
|
||||
|
||||
byte[] result = new byte[length];
|
||||
|
||||
buf.readBytes(result);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected static void checkLimit(int length, int limit) {
|
||||
|
||||
if (length > limit) {
|
||||
|
||||
throw new DecoderException(MessageFormat.format("Size {0} is bigger than allowed {1}", length, limit));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeLengthPrefixedBytes(ByteBuf to, ObjIntConsumer<ByteBuf> lengthWriter, Consumer<ByteBuf> dataWriter) {
|
||||
|
||||
int lengthWriterIndex = to.writerIndex();
|
||||
|
||||
lengthWriter.accept(to, 0);
|
||||
|
||||
int writerIndexDataStart = to.writerIndex();
|
||||
|
||||
dataWriter.accept(to);
|
||||
|
||||
int writerIndexDataEnd = to.writerIndex();
|
||||
|
||||
to.writerIndex(lengthWriterIndex);
|
||||
|
||||
lengthWriter.accept(to, writerIndexDataEnd - writerIndexDataStart);
|
||||
|
||||
to.writerIndex(writerIndexDataEnd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void writeSizePrefixedData(ByteBuf to, ObjIntConsumer<ByteBuf> sizeWriter, ToIntFunction<ByteBuf> dataWriter) {
|
||||
|
||||
int sizeWriterIndex = to.writerIndex();
|
||||
|
||||
sizeWriter.accept(to, 0);
|
||||
|
||||
int size = dataWriter.applyAsInt(to);
|
||||
|
||||
int writerIndexDataEnd = to.writerIndex();
|
||||
|
||||
to.writerIndex(sizeWriterIndex);
|
||||
|
||||
sizeWriter.accept(to, size);
|
||||
|
||||
to.writerIndex(writerIndexDataEnd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static int getAnvilIndex(int x, int y, int z) {
|
||||
|
||||
return (y << 8) + (z << 4) + x;
|
||||
|
||||
}
|
||||
|
||||
public static <T> boolean instanceOf(Class<T> clazz, Object o) {
|
||||
|
@ -657,6 +398,4 @@ public class GeyserUtils {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -49,13 +49,13 @@ public class SkinProvider {
|
|||
return cachedCapes.get(capeUrl);
|
||||
}
|
||||
|
||||
public static CompletableFuture<SkinAndCape> requestAndHandleSkinAndCape(UUID playerId, String skinUrl, String capeUrl) {
|
||||
public static CompletableFuture<SkinAndCape> requestSkinAndCape(UUID playerId, String skinUrl, String capeUrl) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
SkinAndCape skinAndCape = new SkinAndCape(
|
||||
getOrDefault(requestAndHandleSkin(playerId, skinUrl, false), EMPTY_SKIN, 5),
|
||||
getOrDefault(requestAndHandleCape(capeUrl, false), EMPTY_CAPE, 5)
|
||||
getOrDefault(requestSkin(playerId, skinUrl, false), EMPTY_SKIN, 5),
|
||||
getOrDefault(requestCape(capeUrl, false), EMPTY_CAPE, 5)
|
||||
);
|
||||
|
||||
Geyser.getLogger().debug("Took " + (System.currentTimeMillis() - time) + "ms for " + playerId);
|
||||
|
@ -63,7 +63,7 @@ public class SkinProvider {
|
|||
}, EXECUTOR_SERVICE);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Skin> requestAndHandleSkin(UUID playerId, String textureUrl, boolean newThread) {
|
||||
public static CompletableFuture<Skin> requestSkin(UUID playerId, String textureUrl, boolean newThread) {
|
||||
if (textureUrl == null || textureUrl.isEmpty()) return CompletableFuture.completedFuture(EMPTY_SKIN);
|
||||
if (requestedSkins.containsKey(playerId)) return requestedSkins.get(playerId); // already requested
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class SkinProvider {
|
|||
return future;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Cape> requestAndHandleCape(String capeUrl, boolean newThread) {
|
||||
public static CompletableFuture<Cape> requestCape(String capeUrl, boolean newThread) {
|
||||
if (capeUrl == null || capeUrl.isEmpty()) return CompletableFuture.completedFuture(EMPTY_CAPE);
|
||||
if (requestedCapes.containsKey(capeUrl)) return requestedCapes.get(capeUrl); // already requested
|
||||
|
||||
|
@ -119,12 +119,12 @@ public class SkinProvider {
|
|||
return future;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Cape> requestAndHandleUnofficialCape(Cape officialCape, UUID playerId,
|
||||
String username, boolean newThread) {
|
||||
public static CompletableFuture<Cape> requestUnofficialCape(Cape officialCape, UUID playerId,
|
||||
String username, boolean newThread) {
|
||||
if (officialCape.isFailed() && ALLOW_THIRD_PARTY_CAPES) {
|
||||
for (UnofficalCape cape : UnofficalCape.VALUES) {
|
||||
Cape cape1 = getOrDefault(
|
||||
requestAndHandleCape(cape.getUrlFor(playerId, username), newThread),
|
||||
requestCape(cape.getUrlFor(playerId, username), newThread),
|
||||
EMPTY_CAPE, 4
|
||||
);
|
||||
if (!cape1.isFailed()) {
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
package org.geysermc.connector.utils;
|
||||
|
||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.connector.entity.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SkinUtils {
|
||||
public static PlayerListPacket.Entry buildCachedEntry(GameProfile profile, long geyserId) {
|
||||
GameProfileData data = GameProfileData.from(profile);
|
||||
|
||||
return buildEntryManually(
|
||||
profile.getId(),
|
||||
profile.getName(),
|
||||
geyserId,
|
||||
profile.getIdAsString(),
|
||||
SkinProvider.getCachedSkin(profile.getId()).getSkinData(),
|
||||
SkinProvider.getCachedCape(data.getCapeUrl()).getCapeData(),
|
||||
"geometry.humanoid.custom" + (data.isAlex() ? "Slim" : ""),
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
public static PlayerListPacket.Entry buildDefaultEntry(GameProfile profile, long geyserId) {
|
||||
return buildEntryManually(
|
||||
profile.getId(),
|
||||
profile.getName(),
|
||||
geyserId,
|
||||
profile.getIdAsString(),
|
||||
SkinProvider.STEVE_SKIN,
|
||||
SkinProvider.EMPTY_CAPE.getCapeData(),
|
||||
"geometry.humanoid",
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
public static PlayerListPacket.Entry buildEntryManually(UUID uuid, String username, long geyserId,
|
||||
String skinId, byte[] skinData, byte[] capeData,
|
||||
String geometryName, String geometryData) {
|
||||
PlayerListPacket.Entry entry = new PlayerListPacket.Entry(uuid);
|
||||
entry.setName(username);
|
||||
entry.setEntityId(geyserId);
|
||||
entry.setSkinId(skinId);
|
||||
entry.setSkinData(skinData != null ? skinData : SkinProvider.STEVE_SKIN);
|
||||
entry.setCapeData(capeData);
|
||||
entry.setGeometryName(geometryName);
|
||||
entry.setGeometryData(geometryData);
|
||||
entry.setXuid("");
|
||||
entry.setPlatformChatId("");
|
||||
return entry;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static class GameProfileData {
|
||||
private String skinUrl;
|
||||
private String capeUrl;
|
||||
private boolean alex;
|
||||
|
||||
public static GameProfileData from(GameProfile profile) {
|
||||
GameProfile.Property skinProperty = profile.getProperty("textures");
|
||||
|
||||
JsonObject skinObject = SkinProvider.GSON.fromJson(new String(Base64.getDecoder().decode(skinProperty.getValue()), Charsets.UTF_8), JsonObject.class);
|
||||
JsonObject textures = skinObject.getAsJsonObject("textures");
|
||||
|
||||
JsonObject skinTexture = textures.getAsJsonObject("SKIN");
|
||||
String skinUrl = skinTexture.get("url").getAsString();
|
||||
|
||||
boolean isAlex = skinTexture.has("metadata");
|
||||
|
||||
String capeUrl = null;
|
||||
if (textures.has("CAPE")) {
|
||||
JsonObject capeTexture = textures.getAsJsonObject("CAPE");
|
||||
capeUrl = capeTexture.get("url").getAsString();
|
||||
}
|
||||
|
||||
return new GameProfileData(skinUrl, capeUrl, isAlex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void requestAndHandleSkinAndCape(PlayerEntity entity, GeyserSession session,
|
||||
Consumer<SkinProvider.SkinAndCape> skinAndCapeConsumer) {
|
||||
Geyser.getGeneralThreadPool().execute(() -> {
|
||||
SkinUtils.GameProfileData data = SkinUtils.GameProfileData.from(entity.getProfile());
|
||||
|
||||
SkinProvider.requestSkinAndCape(entity.getUuid(), data.getSkinUrl(), data.getCapeUrl())
|
||||
.whenCompleteAsync((skinAndCape, throwable) -> {
|
||||
try {
|
||||
SkinProvider.Skin skin = skinAndCape.getSkin();
|
||||
SkinProvider.Cape cape = skinAndCape.getCape();
|
||||
|
||||
if (cape.isFailed() && SkinProvider.ALLOW_THIRD_PARTY_CAPES) {
|
||||
cape = SkinProvider.getOrDefault(SkinProvider.requestUnofficialCape(
|
||||
cape, entity.getUuid(),
|
||||
entity.getUsername(), false
|
||||
), SkinProvider.EMPTY_CAPE, SkinProvider.UnofficalCape.VALUES.length * 3);
|
||||
}
|
||||
|
||||
if (entity.getLastSkinUpdate() < skin.getRequestedOn()) {
|
||||
entity.setLastSkinUpdate(skin.getRequestedOn());
|
||||
|
||||
if (session.getUpstream().isInitialized()) {
|
||||
PlayerListPacket.Entry updatedEntry = SkinUtils.buildEntryManually(
|
||||
entity.getUuid(),
|
||||
entity.getUsername(),
|
||||
entity.getGeyserId(),
|
||||
entity.getUuid().toString(),
|
||||
skin.getSkinData(),
|
||||
cape.getCapeData(),
|
||||
"geometry.humanoid.custom" + (data.isAlex() ? "Slim" : ""),
|
||||
""
|
||||
);
|
||||
|
||||
PlayerListPacket playerRemovePacket = new PlayerListPacket();
|
||||
playerRemovePacket.setType(PlayerListPacket.Type.REMOVE);
|
||||
playerRemovePacket.getEntries().add(updatedEntry);
|
||||
session.getUpstream().sendPacket(playerRemovePacket);
|
||||
|
||||
PlayerListPacket playerAddPacket = new PlayerListPacket();
|
||||
playerAddPacket.setType(PlayerListPacket.Type.ADD);
|
||||
playerAddPacket.getEntries().add(updatedEntry);
|
||||
session.getUpstream().sendPacket(playerAddPacket);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Geyser.getLogger().error("Failed getting skin for " + entity.getUuid(), e);
|
||||
}
|
||||
|
||||
if (skinAndCapeConsumer != null) skinAndCapeConsumer.accept(skinAndCape);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue