mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 19:18:12 +01:00
Multiplayer synchronization
This commit is contained in:
parent
729d82abd4
commit
9d8e4e7ea2
@ -8,14 +8,13 @@ import fr.adamaq01.ozao.net.server.backend.tcp.TCPServer;
|
||||
import fr.themode.minestom.entity.EntityManager;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.BlockManager;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.instance.InstanceManager;
|
||||
import fr.themode.minestom.instance.demo.StoneBlock;
|
||||
import fr.themode.minestom.listener.PacketListenerManager;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
import fr.themode.minestom.net.PacketProcessor;
|
||||
import fr.themode.minestom.net.packet.server.play.DestroyEntitiesPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.KeepAlivePacket;
|
||||
import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket;
|
||||
import fr.themode.minestom.net.protocol.MinecraftProtocol;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -59,18 +58,13 @@ public class Main {
|
||||
if (connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)) != null) {
|
||||
Player player = connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection));
|
||||
player.remove();
|
||||
connectionManager.removePlayer(packetProcessor.getPlayerConnection(connection));
|
||||
|
||||
PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.REMOVE_PLAYER);
|
||||
playerInfoPacket.playerInfos.add(new PlayerInfoPacket.RemovePlayer(player.getUuid()));
|
||||
DestroyEntitiesPacket destroyEntitiesPacket = new DestroyEntitiesPacket();
|
||||
destroyEntitiesPacket.entityIds = new int[]{player.getEntityId()};
|
||||
for (Player onlinePlayer : connectionManager.getOnlinePlayers()) {
|
||||
if (!onlinePlayer.equals(player)) {
|
||||
onlinePlayer.getPlayerConnection().sendPacket(destroyEntitiesPacket);
|
||||
onlinePlayer.getPlayerConnection().sendPacket(playerInfoPacket);
|
||||
}
|
||||
Instance instance = player.getInstance();
|
||||
if (instance != null) {
|
||||
instance.removeEntity(player);
|
||||
}
|
||||
|
||||
connectionManager.removePlayer(packetProcessor.getPlayerConnection(connection));
|
||||
}
|
||||
packetProcessor.removePlayerConnection(connection);
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import fr.themode.minestom.event.Event;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.DestroyEntitiesPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.EntityMetaDataPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SetPassengersPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
@ -38,6 +40,7 @@ public abstract class Entity implements Viewable {
|
||||
protected double lastX, lastY, lastZ;
|
||||
protected double x, y, z;
|
||||
protected float yaw, pitch;
|
||||
protected float lastYaw, lastPitch;
|
||||
private int id;
|
||||
|
||||
protected Entity vehicle;
|
||||
@ -90,7 +93,9 @@ public abstract class Entity implements Viewable {
|
||||
if (!viewers.contains(player))
|
||||
return;
|
||||
this.viewers.remove(player);
|
||||
// TODO send packet to remove entity
|
||||
DestroyEntitiesPacket destroyEntitiesPacket = new DestroyEntitiesPacket();
|
||||
destroyEntitiesPacket.entityIds = new int[]{getEntityId()};
|
||||
player.getPlayerConnection().sendPacket(destroyEntitiesPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +188,11 @@ public abstract class Entity implements Viewable {
|
||||
return Collections.unmodifiableSet(passengers);
|
||||
}
|
||||
|
||||
public void setOnFire(boolean fire) {
|
||||
this.onFire = fire;
|
||||
sendMetadata(0);
|
||||
}
|
||||
|
||||
public void refreshPosition(double x, double y, double z) {
|
||||
this.lastX = this.x;
|
||||
this.lastY = this.y;
|
||||
@ -206,6 +216,23 @@ public abstract class Entity implements Viewable {
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshView(float yaw, float pitch) {
|
||||
this.lastYaw = this.yaw;
|
||||
this.lastPitch = this.pitch;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public void refreshSneaking(boolean sneaking) {
|
||||
this.crouched = sneaking;
|
||||
sendMetadata(0);
|
||||
}
|
||||
|
||||
public void refreshSprinting(boolean sprinting) {
|
||||
this.sprinting = sprinting;
|
||||
sendMetadata(0);
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
@ -230,30 +257,36 @@ public abstract class Entity implements Viewable {
|
||||
this.shouldRemove = true;
|
||||
}
|
||||
|
||||
protected void sendPacketToViewers(ServerPacket packet) {
|
||||
public void sendPacketToViewers(ServerPacket packet) {
|
||||
getViewers().forEach(player -> player.getPlayerConnection().sendPacket(packet));
|
||||
}
|
||||
|
||||
public void sendPacketsToViewers(ServerPacket... packets) {
|
||||
getViewers().forEach(player -> {
|
||||
for (ServerPacket packet : packets)
|
||||
player.getPlayerConnection().sendPacket(packet);
|
||||
});
|
||||
}
|
||||
|
||||
public Buffer getMetadataBuffer() {
|
||||
Buffer buffer = Buffer.create();
|
||||
fillMetadataIndex(buffer, 0);
|
||||
/*Utils.writeVarInt(buffer, 0);
|
||||
Utils.writeString(buffer, customName);
|
||||
buffer.putBoolean(silent);
|
||||
buffer.putBoolean(noGravity);
|
||||
Utils.writeVarInt(buffer, pose.ordinal());*/
|
||||
|
||||
// Chicken test
|
||||
/*buffer.putByte((byte) 0); // Hand states
|
||||
buffer.putFloat(10f); // Health
|
||||
Utils.writeVarInt(buffer, 0); // Potion effect color
|
||||
buffer.putBoolean(false); // Potion effect ambient
|
||||
Utils.writeVarInt(buffer, 0); // Arrow count in entity
|
||||
buffer.putByte((byte) 0); // (Insentient)
|
||||
buffer.putBoolean(false); // baby (Ageable)*/
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected void sendMetadata(int index) {
|
||||
Buffer buffer = Buffer.create();
|
||||
fillMetadataIndex(buffer, index);
|
||||
|
||||
EntityMetaDataPacket metaDataPacket = new EntityMetaDataPacket();
|
||||
metaDataPacket.entityId = getEntityId();
|
||||
metaDataPacket.data = buffer;
|
||||
sendPacketToViewers(metaDataPacket);
|
||||
if (this instanceof Player) {
|
||||
((Player) this).getPlayerConnection().sendPacket(metaDataPacket);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillMetadataIndex(Buffer buffer, int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
|
@ -1,9 +1,7 @@
|
||||
package fr.themode.minestom.entity;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.bossbar.BossBar;
|
||||
import fr.themode.minestom.chat.Chat;
|
||||
import fr.themode.minestom.event.BlockPlaceEvent;
|
||||
import fr.themode.minestom.event.PickupItemEvent;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.CustomBlock;
|
||||
@ -11,14 +9,15 @@ import fr.themode.minestom.inventory.Inventory;
|
||||
import fr.themode.minestom.inventory.PlayerInventory;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.*;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class Player extends LivingEntity {
|
||||
@ -27,7 +26,7 @@ public class Player extends LivingEntity {
|
||||
|
||||
private String username;
|
||||
private PlayerConnection playerConnection;
|
||||
private ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
|
||||
private LinkedList<ClientPlayPacket> packets = new LinkedList<>();
|
||||
|
||||
private GameMode gameMode;
|
||||
private PlayerInventory inventory;
|
||||
@ -40,13 +39,16 @@ public class Player extends LivingEntity {
|
||||
|
||||
private Set<BossBar> bossBars = new CopyOnWriteArraySet<>();
|
||||
|
||||
// Synchronization
|
||||
private long synchronizationDelay = 1000; // In ms
|
||||
private long lastSynchronizationTime;
|
||||
|
||||
// Vehicle
|
||||
private float sideways;
|
||||
private float forward;
|
||||
|
||||
// TODO set proper UUID
|
||||
public Player(UUID uuid, String username, PlayerConnection playerConnection) {
|
||||
super(93); // TODO correct ?
|
||||
super(93); // FIXME verify
|
||||
this.uuid = uuid;
|
||||
this.username = username;
|
||||
this.playerConnection = playerConnection;
|
||||
@ -65,18 +67,20 @@ public class Player extends LivingEntity {
|
||||
sendMessage("Cancelled: " + cancel);
|
||||
});*/
|
||||
|
||||
setEventCallback(BlockPlaceEvent.class, event -> {
|
||||
/*setEventCallback(BlockPlaceEvent.class, event -> {
|
||||
event.setCancelled(true);
|
||||
sendMessage("CANCELLED");
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
synchronized (packets) {
|
||||
while (!packets.isEmpty()) {
|
||||
ClientPlayPacket packet = packets.remove();
|
||||
ClientPlayPacket packet = packets.pollFirst();
|
||||
packet.process(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Target block stage
|
||||
if (instance != null && targetCustomBlock != null) {
|
||||
@ -86,15 +90,14 @@ public class Player extends LivingEntity {
|
||||
byte stage = (byte) (since / (timeBreak / animationCount));
|
||||
sendBlockBreakAnimation(targetBlockPosition, stage);// TODO send to all near players
|
||||
if (stage > 9) {
|
||||
instance.setBlock(targetBlockPosition.getX(), targetBlockPosition.getY(), targetBlockPosition.getZ(), (short) 0);
|
||||
testParticle(targetBlockPosition.getX() + 0.5f, targetBlockPosition.getY(), targetBlockPosition.getZ() + 0.5f, targetCustomBlock.getType());
|
||||
instance.breakBlock(this, targetBlockPosition, targetCustomBlock);
|
||||
resetTargetBlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Item pickup
|
||||
if (instance != null) {
|
||||
Chunk chunk = instance.getChunkAt(getX(), getZ());
|
||||
Chunk chunk = instance.getChunkAt(getX(), getZ()); // TODO check surrounding chunks
|
||||
Set<ObjectEntity> objectEntities = chunk.getObjectEntities();
|
||||
for (ObjectEntity objectEntity : objectEntities) {
|
||||
if (objectEntity instanceof ItemEntity) {
|
||||
@ -125,19 +128,117 @@ public class Player extends LivingEntity {
|
||||
|
||||
|
||||
// Multiplayer sync
|
||||
EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
|
||||
entityTeleportPacket.entityId = getEntityId();
|
||||
entityTeleportPacket.x = x;
|
||||
entityTeleportPacket.y = y;
|
||||
entityTeleportPacket.z = z;
|
||||
entityTeleportPacket.yaw = yaw;
|
||||
entityTeleportPacket.pitch = pitch;
|
||||
entityTeleportPacket.onGround = true;
|
||||
for (Player onlinePlayer : Main.getConnectionManager().getOnlinePlayers()) {
|
||||
if (!onlinePlayer.equals(this))
|
||||
onlinePlayer.getPlayerConnection().sendPacket(entityTeleportPacket);
|
||||
boolean positionChanged = x != lastX || z != lastZ || y != lastY;
|
||||
boolean viewChanged = yaw != lastYaw || pitch != lastPitch;
|
||||
ServerPacket updatePacket = null;
|
||||
ServerPacket optionalUpdatePacket = null;
|
||||
if (positionChanged && viewChanged) {
|
||||
EntityLookAndRelativeMovePacket entityLookAndRelativeMovePacket = new EntityLookAndRelativeMovePacket();
|
||||
entityLookAndRelativeMovePacket.entityId = getEntityId();
|
||||
entityLookAndRelativeMovePacket.deltaX = (short) ((x * 32 - lastX * 32) * 128);
|
||||
entityLookAndRelativeMovePacket.deltaY = (short) ((y * 32 - lastY * 32) * 128);
|
||||
entityLookAndRelativeMovePacket.deltaZ = (short) ((z * 32 - lastZ * 32) * 128);
|
||||
entityLookAndRelativeMovePacket.yaw = yaw;
|
||||
entityLookAndRelativeMovePacket.pitch = pitch;
|
||||
entityLookAndRelativeMovePacket.onGround = onGround;
|
||||
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = yaw;
|
||||
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
lastZ = z;
|
||||
lastYaw = yaw;
|
||||
lastPitch = pitch;
|
||||
updatePacket = entityLookAndRelativeMovePacket;
|
||||
optionalUpdatePacket = entityHeadLookPacket;
|
||||
} else if (positionChanged) {
|
||||
EntityRelativeMovePacket entityRelativeMovePacket = new EntityRelativeMovePacket();
|
||||
entityRelativeMovePacket.entityId = getEntityId();
|
||||
entityRelativeMovePacket.deltaX = (short) ((x * 32 - lastX * 32) * 128);
|
||||
entityRelativeMovePacket.deltaY = (short) ((y * 32 - lastY * 32) * 128);
|
||||
entityRelativeMovePacket.deltaZ = (short) ((z * 32 - lastZ * 32) * 128);
|
||||
entityRelativeMovePacket.onGround = onGround;
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
lastZ = z;
|
||||
updatePacket = entityRelativeMovePacket;
|
||||
} else if (viewChanged) {
|
||||
EntityLookPacket entityLookPacket = new EntityLookPacket();
|
||||
entityLookPacket.entityId = getEntityId();
|
||||
entityLookPacket.yaw = yaw;
|
||||
entityLookPacket.pitch = pitch;
|
||||
entityLookPacket.onGround = onGround;
|
||||
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = yaw;
|
||||
|
||||
lastYaw = yaw;
|
||||
lastPitch = pitch;
|
||||
updatePacket = entityLookPacket;
|
||||
optionalUpdatePacket = entityHeadLookPacket;
|
||||
}
|
||||
if (updatePacket != null) {
|
||||
if (optionalUpdatePacket != null) {
|
||||
sendPacketsToViewers(updatePacket, optionalUpdatePacket);
|
||||
} else {
|
||||
sendPacketToViewers(updatePacket);
|
||||
}
|
||||
}
|
||||
playerConnection.sendPacket(new UpdateViewPositionPacket(Math.floorDiv((int) x, 16), Math.floorDiv((int) z, 16)));
|
||||
|
||||
// Synchronization
|
||||
long time = System.currentTimeMillis();
|
||||
if (time - lastSynchronizationTime >= synchronizationDelay) {
|
||||
lastSynchronizationTime = System.currentTimeMillis();
|
||||
for (Player viewer : getViewers()) {
|
||||
EntityTeleportPacket teleportPacket = new EntityTeleportPacket();
|
||||
teleportPacket.entityId = viewer.getEntityId();
|
||||
teleportPacket.x = viewer.getX();
|
||||
teleportPacket.y = viewer.getY();
|
||||
teleportPacket.z = viewer.getZ();
|
||||
teleportPacket.onGround = viewer.onGround;
|
||||
playerConnection.sendPacket(teleportPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewer(Player player) {
|
||||
super.addViewer(player);
|
||||
PlayerConnection connection = player.getPlayerConnection();
|
||||
String property = "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19";
|
||||
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
|
||||
spawnPlayerPacket.entityId = getEntityId();
|
||||
spawnPlayerPacket.playerUuid = getUuid();
|
||||
spawnPlayerPacket.x = x;
|
||||
spawnPlayerPacket.y = y;
|
||||
spawnPlayerPacket.z = z;
|
||||
spawnPlayerPacket.yaw = yaw;
|
||||
spawnPlayerPacket.pitch = pitch;
|
||||
|
||||
PlayerInfoPacket pInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
||||
PlayerInfoPacket.AddPlayer addP = new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), GameMode.CREATIVE, 10);
|
||||
PlayerInfoPacket.AddPlayer.Property p = new PlayerInfoPacket.AddPlayer.Property("textures", property);//new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(onlinePlayer.getUsername()));
|
||||
addP.properties.add(p);
|
||||
pInfoPacket.playerInfos.add(addP);
|
||||
|
||||
connection.sendPacket(pInfoPacket);
|
||||
connection.sendPacket(spawnPlayerPacket);
|
||||
|
||||
for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) {
|
||||
syncEquipment(slot); // TODO only send packets to "player" and not all viewers
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewer(Player player) {
|
||||
super.removeViewer(player);
|
||||
PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.REMOVE_PLAYER);
|
||||
playerInfoPacket.playerInfos.add(new PlayerInfoPacket.RemovePlayer(getUuid()));
|
||||
player.playerConnection.sendPacket(playerInfoPacket);
|
||||
}
|
||||
|
||||
public void sendBlockBreakAnimation(Position blockPosition, byte destroyStage) {
|
||||
@ -146,22 +247,7 @@ public class Player extends LivingEntity {
|
||||
breakAnimationPacket.blockPosition = blockPosition;
|
||||
breakAnimationPacket.destroyStage = destroyStage;
|
||||
playerConnection.sendPacket(breakAnimationPacket);
|
||||
}
|
||||
|
||||
private void testParticle(float x, float y, float z, int blockId) {
|
||||
ParticlePacket particlePacket = new ParticlePacket();
|
||||
particlePacket.particleId = 3; // Block particle
|
||||
particlePacket.longDistance = false;
|
||||
particlePacket.x = x;
|
||||
particlePacket.y = y;
|
||||
particlePacket.z = z;
|
||||
particlePacket.offsetX = 0.4f;
|
||||
particlePacket.offsetY = 0.65f;
|
||||
particlePacket.offsetZ = 0.4f;
|
||||
particlePacket.particleData = 0.3f;
|
||||
particlePacket.particleCount = 75;
|
||||
particlePacket.blockId = blockId;
|
||||
playerConnection.sendPacket(particlePacket);
|
||||
sendPacketToViewers(breakAnimationPacket);
|
||||
}
|
||||
|
||||
public void sendMessage(String message) {
|
||||
@ -197,6 +283,13 @@ public class Player extends LivingEntity {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
public void kick(String message) {
|
||||
DisconnectPacket disconnectPacket = new DisconnectPacket();
|
||||
disconnectPacket.message = message;
|
||||
playerConnection.sendPacket(disconnectPacket);
|
||||
playerConnection.getConnection().close();
|
||||
}
|
||||
|
||||
public void setGameMode(GameMode gameMode) {
|
||||
ChangeGameStatePacket changeGameStatePacket = new ChangeGameStatePacket();
|
||||
changeGameStatePacket.reason = ChangeGameStatePacket.Reason.CHANGE_GAMEMODE;
|
||||
@ -218,10 +311,6 @@ public class Player extends LivingEntity {
|
||||
return heldSlot;
|
||||
}
|
||||
|
||||
public ItemStack getHeldItemStack() {
|
||||
return inventory.getItemStack(heldSlot);
|
||||
}
|
||||
|
||||
public Inventory getOpenInventory() {
|
||||
return openInventory;
|
||||
}
|
||||
@ -273,37 +362,35 @@ public class Player extends LivingEntity {
|
||||
inventory.update();
|
||||
}
|
||||
|
||||
public void syncEquipment(EntityEquipmentPacket.Slot slot) {
|
||||
EntityEquipmentPacket equipmentPacket = new EntityEquipmentPacket();
|
||||
equipmentPacket.entityId = getEntityId();
|
||||
equipmentPacket.slot = slot;
|
||||
equipmentPacket.itemStack = inventory.getEquipment(slot);
|
||||
sendPacketToViewers(equipmentPacket);
|
||||
}
|
||||
|
||||
public void addPacketToQueue(ClientPlayPacket packet) {
|
||||
synchronized (packets) {
|
||||
this.packets.add(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshGameMode(GameMode gameMode) {
|
||||
this.gameMode = gameMode;
|
||||
}
|
||||
|
||||
public void refreshView(float yaw, float pitch) {
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public void refreshOnGround(boolean onGround) {
|
||||
this.onGround = onGround;
|
||||
}
|
||||
|
||||
public void refreshSneaking(boolean sneaking) {
|
||||
sneaking = sneaking;
|
||||
}
|
||||
|
||||
public void refreshSprinting(boolean sprinting) {
|
||||
sprinting = sprinting;
|
||||
}
|
||||
|
||||
public void refreshKeepAlive(long lastKeepAlive) {
|
||||
this.lastKeepAlive = lastKeepAlive;
|
||||
}
|
||||
|
||||
public void refreshHeldSlot(short slot) {
|
||||
this.heldSlot = slot;
|
||||
syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
|
||||
}
|
||||
|
||||
public void refreshOpenInventory(Inventory openInventory) {
|
||||
|
16
src/main/java/fr/themode/minestom/event/BlockBreakEvent.java
Normal file
16
src/main/java/fr/themode/minestom/event/BlockBreakEvent.java
Normal file
@ -0,0 +1,16 @@
|
||||
package fr.themode.minestom.event;
|
||||
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
public class BlockBreakEvent extends CancellableEvent {
|
||||
|
||||
private Position position;
|
||||
|
||||
public BlockBreakEvent(Position position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
@ -4,8 +4,10 @@ import fr.themode.minestom.entity.Entity;
|
||||
import fr.themode.minestom.entity.EntityCreature;
|
||||
import fr.themode.minestom.entity.ObjectEntity;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.event.BlockBreakEvent;
|
||||
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.DestroyEntitiesPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
||||
import fr.themode.minestom.utils.GroupedCollections;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
@ -49,6 +51,37 @@ public class Instance implements BlockModifier {
|
||||
}
|
||||
}
|
||||
|
||||
public void breakBlock(Player player, Position position, short blockId) {
|
||||
BlockBreakEvent blockBreakEvent = new BlockBreakEvent(position);
|
||||
player.callEvent(BlockBreakEvent.class, blockBreakEvent);
|
||||
if (!blockBreakEvent.isCancelled()) {
|
||||
int x = position.getX();
|
||||
int y = position.getY();
|
||||
int z = position.getZ();
|
||||
setBlock(x, y, z, (short) 0);
|
||||
ParticlePacket particlePacket = new ParticlePacket(); // TODO change by a proper particle API
|
||||
particlePacket.particleId = 3; // Block particle
|
||||
particlePacket.longDistance = false;
|
||||
particlePacket.x = x + 0.5f;
|
||||
particlePacket.y = y;
|
||||
particlePacket.z = z + 0.5f;
|
||||
particlePacket.offsetX = 0.4f;
|
||||
particlePacket.offsetY = 0.65f;
|
||||
particlePacket.offsetZ = 0.4f;
|
||||
particlePacket.particleData = 0.3f;
|
||||
particlePacket.particleCount = 75;
|
||||
particlePacket.blockId = blockId;
|
||||
player.getPlayerConnection().sendPacket(particlePacket);
|
||||
player.sendPacketToViewers(particlePacket);
|
||||
} else {
|
||||
sendChunkUpdate(player, getChunkAt(position));
|
||||
}
|
||||
}
|
||||
|
||||
public void breakBlock(Player player, Position position, CustomBlock customBlock) {
|
||||
breakBlock(player, position, customBlock.getType());
|
||||
}
|
||||
|
||||
public Chunk loadChunk(int chunkX, int chunkZ) {
|
||||
Chunk chunk = getChunk(chunkX, chunkZ);
|
||||
return chunk == null ? createChunk(chunkX, chunkZ) : chunk; // TODO load from file
|
||||
@ -59,6 +92,10 @@ public class Instance implements BlockModifier {
|
||||
return chunk.getBlockId((byte) (x % 16), (byte) y, (byte) (z % 16));
|
||||
}
|
||||
|
||||
public short getBlockId(Position position) {
|
||||
return getBlockId(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
public CustomBlock getCustomBlock(int x, int y, int z) {
|
||||
Chunk chunk = getChunkAt(x, z);
|
||||
return chunk.getCustomBlock((byte) (x % 16), (byte) y, (byte) (z % 16));
|
||||
@ -96,13 +133,14 @@ public class Instance implements BlockModifier {
|
||||
lastInstance.removeEntity(entity);
|
||||
}
|
||||
|
||||
// TODO based on distance with players
|
||||
getPlayers().forEach(p -> entity.addViewer(p));
|
||||
|
||||
if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
sendChunks(player);
|
||||
getCreatures().forEach(entityCreature -> entityCreature.addViewer(player));
|
||||
} else {
|
||||
// TODO based on distance with players
|
||||
getPlayers().forEach(p -> entity.addViewer(p));
|
||||
getPlayers().forEach(p -> p.addViewer(player));
|
||||
}
|
||||
|
||||
Chunk chunk = getChunkAt(entity.getX(), entity.getZ());
|
||||
@ -114,12 +152,13 @@ public class Instance implements BlockModifier {
|
||||
if (entityInstance == null || entityInstance != this)
|
||||
return;
|
||||
|
||||
entity.getViewers().forEach(p -> entity.removeViewer(p));
|
||||
|
||||
if (!(entity instanceof Player)) {
|
||||
DestroyEntitiesPacket destroyEntitiesPacket = new DestroyEntitiesPacket();
|
||||
destroyEntitiesPacket.entityIds = new int[]{entity.getEntityId()};
|
||||
|
||||
entity.getViewers().forEach(p -> p.getPlayerConnection().sendPacket(destroyEntitiesPacket)); // TODO destroy batch
|
||||
entity.getViewers().forEach(p -> entity.removeViewer(p));
|
||||
}
|
||||
|
||||
Chunk chunk = getChunkAt(entity.getX(), entity.getZ());
|
||||
|
@ -2,6 +2,7 @@ package fr.themode.minestom.inventory;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.server.play.EntityEquipmentPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SetSlotPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.WindowItemsPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
@ -80,28 +81,58 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setHelmet(ItemStack itemStack) {
|
||||
safeItemInsert(HELMET_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setChestplate(ItemStack itemStack) {
|
||||
safeItemInsert(CHESTPLATE_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setLeggings(ItemStack itemStack) {
|
||||
safeItemInsert(LEGGINGS_SLOT, itemStack);
|
||||
}
|
||||
|
||||
public void setBoots(ItemStack itemStack) {
|
||||
safeItemInsert(BOOTS_SLOT, itemStack);
|
||||
public ItemStack getItemInMainHand() {
|
||||
return getItemStack(player.getHeldSlot());
|
||||
}
|
||||
|
||||
public void setItemInMainHand(ItemStack itemStack) {
|
||||
safeItemInsert(player.getHeldSlot(), itemStack);
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
|
||||
}
|
||||
|
||||
public ItemStack getItemInOffHand() {
|
||||
return getItemStack(OFFHAND_SLOT);
|
||||
}
|
||||
|
||||
public void setItemInOffHand(ItemStack itemStack) {
|
||||
safeItemInsert(OFFHAND_SLOT, itemStack);
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.OFF_HAND);
|
||||
}
|
||||
|
||||
public ItemStack getHelmet() {
|
||||
return getItemStack(HELMET_SLOT);
|
||||
}
|
||||
|
||||
public void setHelmet(ItemStack itemStack) {
|
||||
safeItemInsert(HELMET_SLOT, itemStack);
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.HELMET);
|
||||
}
|
||||
|
||||
public ItemStack getChestplate() {
|
||||
return getItemStack(CHESTPLATE_SLOT);
|
||||
}
|
||||
|
||||
public void setChestplate(ItemStack itemStack) {
|
||||
safeItemInsert(CHESTPLATE_SLOT, itemStack);
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.CHESTPLATE);
|
||||
}
|
||||
|
||||
public ItemStack getLeggings() {
|
||||
return getItemStack(LEGGINGS_SLOT);
|
||||
}
|
||||
|
||||
public void setLeggings(ItemStack itemStack) {
|
||||
safeItemInsert(LEGGINGS_SLOT, itemStack);
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.LEGGINGS);
|
||||
}
|
||||
|
||||
public ItemStack getBoots() {
|
||||
return getItemStack(BOOTS_SLOT);
|
||||
}
|
||||
|
||||
public void setBoots(ItemStack itemStack) {
|
||||
safeItemInsert(BOOTS_SLOT, itemStack);
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.BOOTS);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
@ -121,6 +152,24 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
||||
this.cursorItem = cursorItem;
|
||||
}
|
||||
|
||||
public ItemStack getEquipment(EntityEquipmentPacket.Slot slot) {
|
||||
switch (slot) {
|
||||
case MAIN_HAND:
|
||||
return getItemInMainHand();
|
||||
case OFF_HAND:
|
||||
return getItemInOffHand();
|
||||
case HELMET:
|
||||
return getHelmet();
|
||||
case CHESTPLATE:
|
||||
return getChestplate();
|
||||
case LEGGINGS:
|
||||
return getLeggings();
|
||||
case BOOTS:
|
||||
return getBoots();
|
||||
}
|
||||
return ItemStack.AIR_ITEM;
|
||||
}
|
||||
|
||||
private void safeItemInsert(int slot, ItemStack itemStack) {
|
||||
synchronized (this) {
|
||||
itemStack = itemStack == null ? ItemStack.AIR_ITEM : itemStack;
|
||||
@ -128,6 +177,19 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
||||
// System.out.println("INSERT: " + slot);
|
||||
//sendSlotRefresh((short) slot, itemStack);
|
||||
update();
|
||||
if (slot == player.getHeldSlot()) {
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
|
||||
} else if (slot == OFFHAND_SLOT) {
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.OFF_HAND);
|
||||
} else if (slot == HELMET_SLOT) {
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.HELMET);
|
||||
} else if (slot == CHESTPLATE_SLOT) {
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.CHESTPLATE);
|
||||
} else if (slot == LEGGINGS_SLOT) {
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.LEGGINGS);
|
||||
} else if (slot == BOOTS_SLOT) {
|
||||
player.syncEquipment(EntityEquipmentPacket.Slot.BOOTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
package fr.themode.minestom.listener;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientAnimationPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.AnimationPacket;
|
||||
|
||||
public class AnimationListener {
|
||||
|
||||
public static void animationListener(ClientAnimationPacket packet, Player player) {
|
||||
AnimationPacket animationPacket = new AnimationPacket();
|
||||
animationPacket.playerId = player.getEntityId();
|
||||
animationPacket.animation = packet.hand == Player.Hand.MAIN ? AnimationPacket.Animation.SWING_MAIN_ARM : AnimationPacket.Animation.SWING_OFF_HAND;
|
||||
player.sendPacketToViewers(animationPacket);
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,13 @@
|
||||
package fr.themode.minestom.listener;
|
||||
|
||||
import fr.themode.minestom.chat.Chat;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientKeepAlivePacket;
|
||||
import fr.themode.minestom.net.packet.server.play.DisconnectPacket;
|
||||
|
||||
public class KeepAliveListener {
|
||||
|
||||
public static void listener(ClientKeepAlivePacket packet, Player player) {
|
||||
if (packet.id != player.getLastKeepAlive()) {
|
||||
player.getPlayerConnection().sendPacket(new DisconnectPacket(Chat.rawText("Bad Keep Alive packet")));
|
||||
player.getPlayerConnection().getConnection().close();
|
||||
player.kick("Bad Keep Alive packet");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ public class PacketListenerManager {
|
||||
addListener(ClientPlayerPositionPacket.class, PlayerPositionListener::playerPositionListener);
|
||||
addListener(ClientPlayerPositionAndLookPacket.class, PlayerPositionListener::playerPositionAndLookListener);
|
||||
addListener(ClientPlayerDiggingPacket.class, PlayerDiggingListener::playerDiggingListener);
|
||||
addListener(ClientAnimationPacket.class, AnimationListener::animationListener);
|
||||
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@ public class PlayerDiggingListener {
|
||||
}
|
||||
break;
|
||||
case CANCELLED_DIGGING:
|
||||
// TODO BlockBreakEvent
|
||||
player.sendBlockBreakAnimation(position, (byte) -1);
|
||||
player.resetTargetBlock();
|
||||
removeEffect(player);
|
||||
@ -53,7 +52,8 @@ public class PlayerDiggingListener {
|
||||
} else {
|
||||
Instance instance = player.getInstance();
|
||||
if (instance != null) {
|
||||
instance.setBlock(position.getX(), position.getY(), position.getZ(), (short) 0);
|
||||
short blockId = instance.getBlockId(position);
|
||||
instance.breakBlock(player, position, blockId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -11,8 +11,6 @@ import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.entity.demo.ChickenCreature;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.instance.demo.ChunkGeneratorDemo;
|
||||
import fr.themode.minestom.inventory.Inventory;
|
||||
import fr.themode.minestom.inventory.InventoryType;
|
||||
import fr.themode.minestom.inventory.PlayerInventory;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
@ -22,13 +20,11 @@ import fr.themode.minestom.net.packet.server.login.JoinGamePacket;
|
||||
import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.PlayerPositionAndLookPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SpawnPlayerPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
import fr.themode.minestom.world.Dimension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LoginStartPacket implements ClientPreplayPacket {
|
||||
@ -54,23 +50,29 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
|
||||
@Override
|
||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||
HashMap<String, UUID> uuids = new HashMap<>();
|
||||
String property = "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19";
|
||||
/*HashMap<String, UUID> uuids = new HashMap<>();
|
||||
uuids.put("TheMode911", UUID.fromString("ab70ecb4-2346-4c14-a52d-7a091507c24e"));
|
||||
uuids.put("Adamaq01", UUID.fromString("58ffa9d8-aee1-4587-8b79-41b754f6f238"));
|
||||
HashMap<String, String> properties = new HashMap<>();
|
||||
properties.put("TheMode911", "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19");
|
||||
properties.put("Adamaq01", "eyJ0aW1lc3RhbXAiOjE1NjU0NzgyODU4MTksInByb2ZpbGVJZCI6IjU4ZmZhOWQ4YWVlMTQ1ODc4Yjc5NDFiNzU0ZjZmMjM4IiwicHJvZmlsZU5hbWUiOiJBZGFtYXEwMSIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lMTNiNmMyMjNlMTFiYjM1Nzc5OTdkZWY3YzA2ZDUwZmM4NzMxYjBkZWQyOTRlZDQ2ZmM4ZDczNDI1NGM5ZTkifSwiQ0FQRSI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2IwY2MwODg0MDcwMDQ0NzMyMmQ5NTNhMDJiOTY1ZjFkNjVhMTNhNjAzYmY2NGIxN2M4MDNjMjE0NDZmZTE2MzUifX19");
|
||||
properties.put("Adamaq01", "eyJ0aW1lc3RhbXAiOjE1NjU0NzgyODU4MTksInByb2ZpbGVJZCI6IjU4ZmZhOWQ4YWVlMTQ1ODc4Yjc5NDFiNzU0ZjZmMjM4IiwicHJvZmlsZU5hbWUiOiJBZGFtYXEwMSIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lMTNiNmMyMjNlMTFiYjM1Nzc5OTdkZWY3YzA2ZDUwZmM4NzMxYjBkZWQyOTRlZDQ2ZmM4ZDczNDI1NGM5ZTkifSwiQ0FQRSI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2IwY2MwODg0MDcwMDQ0NzMyMmQ5NTNhMDJiOTY1ZjFkNjVhMTNhNjAzYmY2NGIxN2M4MDNjMjE0NDZmZTE2MzUifX19");*/
|
||||
|
||||
// TODO send encryption request OR directly login success
|
||||
LoginSuccessPacket successPacket = new LoginSuccessPacket(uuids.get(username), username);
|
||||
UUID playerUuid = UUID.randomUUID();//UUID.fromString("OfflinePlayer:" + username);
|
||||
LoginSuccessPacket successPacket = new LoginSuccessPacket(playerUuid, username);//new LoginSuccessPacket(uuids.get(username), username);
|
||||
connection.sendPacket(successPacket);
|
||||
|
||||
connection.setConnectionState(ConnectionState.PLAY);
|
||||
connectionManager.createPlayer(uuids.get(username), username, connection);
|
||||
connectionManager.createPlayer(playerUuid, username, connection);
|
||||
Player player = connectionManager.getPlayer(connection);
|
||||
GameMode gameMode = GameMode.SURVIVAL;
|
||||
float x = 5;
|
||||
float y = 5;
|
||||
float z = 5;
|
||||
|
||||
player.refreshGameMode(gameMode);
|
||||
player.refreshPosition(x, y, z);
|
||||
|
||||
// TODO complete login sequence with optionals packets
|
||||
JoinGamePacket joinGamePacket = new JoinGamePacket();
|
||||
@ -89,8 +91,6 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
|
||||
// TODO player abilities
|
||||
|
||||
player.setInstance(instance);
|
||||
|
||||
|
||||
SpawnPositionPacket spawnPositionPacket = new SpawnPositionPacket();
|
||||
spawnPositionPacket.x = 0;
|
||||
@ -99,9 +99,9 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
connection.sendPacket(spawnPositionPacket);
|
||||
|
||||
PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket();
|
||||
playerPositionAndLookPacket.x = 0;
|
||||
playerPositionAndLookPacket.y = 5;
|
||||
playerPositionAndLookPacket.z = 0;
|
||||
playerPositionAndLookPacket.x = x;
|
||||
playerPositionAndLookPacket.y = y;
|
||||
playerPositionAndLookPacket.z = z;
|
||||
playerPositionAndLookPacket.yaw = 0;
|
||||
playerPositionAndLookPacket.pitch = 0;
|
||||
playerPositionAndLookPacket.flags = 0;
|
||||
@ -109,70 +109,43 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
connection.sendPacket(playerPositionAndLookPacket);
|
||||
|
||||
PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
||||
PlayerInfoPacket.AddPlayer addPlayer = new PlayerInfoPacket.AddPlayer(uuids.get(username), username, GameMode.CREATIVE, 10);
|
||||
PlayerInfoPacket.AddPlayer.Property property = new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(username));
|
||||
addPlayer.properties.add(property);
|
||||
PlayerInfoPacket.AddPlayer addPlayer = new PlayerInfoPacket.AddPlayer(player.getUuid(), username, GameMode.CREATIVE, 10);
|
||||
PlayerInfoPacket.AddPlayer.Property prop = new PlayerInfoPacket.AddPlayer.Property("textures", property); //new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(username));
|
||||
addPlayer.properties.add(prop);
|
||||
playerInfoPacket.playerInfos.add(addPlayer);
|
||||
connection.sendPacket(playerInfoPacket);
|
||||
|
||||
for (int x = 0; x < 4; x++)
|
||||
for (int z = 0; z < 4; z++) {
|
||||
player.setInstance(instance);
|
||||
|
||||
for (int cx = 0; cx < 4; cx++)
|
||||
for (int cz = 0; cz < 4; cz++) {
|
||||
ChickenCreature chickenCreature = new ChickenCreature();
|
||||
chickenCreature.refreshPosition(0 + (double) x * 1, 5, 0 + (double) z * 1);
|
||||
chickenCreature.refreshPosition(0 + (double) cx * 1, 5, 0 + (double) cz * 1);
|
||||
chickenCreature.setOnFire(true);
|
||||
chickenCreature.setInstance(instance);
|
||||
if (x == 3 && z == 3) {
|
||||
if (cx == 3 && cz == 3) {
|
||||
//chickenCreature.addPassenger(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
|
||||
spawnPlayerPacket.entityId = player.getEntityId();
|
||||
spawnPlayerPacket.playerUuid = uuids.get(username);
|
||||
spawnPlayerPacket.x = 0;
|
||||
spawnPlayerPacket.y = 5;
|
||||
spawnPlayerPacket.z = 0;
|
||||
for (Player onlinePlayer : connectionManager.getOnlinePlayers()) {
|
||||
if (onlinePlayer.getUsername().equals(username)) continue;
|
||||
onlinePlayer.getPlayerConnection().sendPacket(playerInfoPacket);
|
||||
onlinePlayer.getPlayerConnection().sendPacket(spawnPlayerPacket);
|
||||
|
||||
SpawnPlayerPacket spawnPacket = new SpawnPlayerPacket();
|
||||
spawnPacket.entityId = onlinePlayer.getEntityId();
|
||||
spawnPacket.playerUuid = uuids.get(onlinePlayer.getUsername());
|
||||
spawnPacket.x = onlinePlayer.getX();
|
||||
spawnPacket.y = onlinePlayer.getY();
|
||||
spawnPacket.z = onlinePlayer.getZ();
|
||||
|
||||
PlayerInfoPacket pInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
||||
PlayerInfoPacket.AddPlayer addP = new PlayerInfoPacket.AddPlayer(uuids.get(onlinePlayer.getUsername()), onlinePlayer.getUsername(), GameMode.CREATIVE, 10);
|
||||
PlayerInfoPacket.AddPlayer.Property p = new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(onlinePlayer.getUsername()));
|
||||
addP.properties.add(p);
|
||||
pInfoPacket.playerInfos.add(addP);
|
||||
connection.sendPacket(pInfoPacket);
|
||||
connection.sendPacket(spawnPacket);
|
||||
}
|
||||
//System.out.println("HAHAHAHHAHHAH " + player.getUuid());
|
||||
|
||||
PlayerInventory inventory = player.getInventory();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
inventory.addItemStack(new ItemStack(1, (byte) 64));
|
||||
}
|
||||
|
||||
Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre");
|
||||
/*Inventory inv = new Inventory(InventoryType.WINDOW_3X3, "Salut je suis le titre");
|
||||
inv.setItemStack(0, new ItemStack(1, (byte) 1));
|
||||
player.openInventory(inv);
|
||||
inv.setItemStack(1, new ItemStack(1, (byte) 2));
|
||||
//inv.updateItems();
|
||||
inv.setItemStack(1, new ItemStack(1, (byte) 2));*/
|
||||
|
||||
BossBar bossBar = new BossBar("Le titre", BarColor.BLUE, BarDivision.SEGMENT_12);
|
||||
bossBar.setProgress(0.75f);
|
||||
bossBar.addViewer(player);
|
||||
|
||||
for (int x = 0; x < 4; x++)
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int ix = 0; ix < 4; ix++)
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
ItemEntity itemEntity = new ItemEntity(new ItemStack(1, (byte) 32));
|
||||
itemEntity.refreshPosition(x, 5, z);
|
||||
itemEntity.refreshPosition(ix, 5, iz);
|
||||
itemEntity.setInstance(instance);
|
||||
//itemEntity.remove();
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class AnimationPacket implements ServerPacket {
|
||||
|
||||
public int playerId; // FIXME verify if this is only player?
|
||||
public Animation animation;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, playerId);
|
||||
buffer.putByte((byte) animation.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x06;
|
||||
}
|
||||
|
||||
public enum Animation {
|
||||
SWING_MAIN_ARM,
|
||||
TAKE_DAMAGE,
|
||||
LEAVE_BED,
|
||||
SWING_OFF_HAND,
|
||||
CRITICAL_EFFECT,
|
||||
MAGICAL_CRITICAL_EFFECT;
|
||||
}
|
||||
}
|
@ -1,20 +1,17 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.chat.Chat;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class DisconnectPacket implements ServerPacket {
|
||||
|
||||
private String message;
|
||||
|
||||
public DisconnectPacket(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
public String message;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeString(buffer, this.message);
|
||||
Utils.writeString(buffer, Chat.rawText(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,35 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class EntityEquipmentPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public Slot slot;
|
||||
public ItemStack itemStack;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, entityId);
|
||||
Utils.writeVarInt(buffer, slot.ordinal());
|
||||
Utils.writeItemStack(buffer, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x46;
|
||||
}
|
||||
|
||||
public enum Slot {
|
||||
MAIN_HAND,
|
||||
OFF_HAND,
|
||||
BOOTS,
|
||||
LEGGINGS,
|
||||
CHESTPLATE,
|
||||
HELMET;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class EntityHeadLookPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public float yaw;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, entityId);
|
||||
buffer.putByte((byte) (this.yaw * 256 / 360));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x3B;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class EntityLookPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public float yaw, pitch;
|
||||
public boolean onGround;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, entityId);
|
||||
buffer.putByte((byte) (this.yaw * 256 / 360));
|
||||
buffer.putByte((byte) (this.pitch * 256 / 360));
|
||||
buffer.putBoolean(onGround);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x2A;
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
return 0x33;
|
||||
}
|
||||
|
||||
public static enum Action {
|
||||
public enum Action {
|
||||
|
||||
ADD_PLAYER(AddPlayer.class),
|
||||
UPDATE_GAMEMODE(UpdateGamemode.class),
|
||||
|
@ -13,8 +13,8 @@ public class SpawnPlayerPacket implements ServerPacket {
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
// public float yaw;
|
||||
// public float pitch;
|
||||
public float yaw;
|
||||
public float pitch;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
@ -24,8 +24,8 @@ public class SpawnPlayerPacket implements ServerPacket {
|
||||
buffer.putDouble(x);
|
||||
buffer.putDouble(y);
|
||||
buffer.putDouble(z);
|
||||
buffer.getData().writeByte(0);
|
||||
buffer.getData().writeByte(0);
|
||||
buffer.putByte((byte) (yaw * 256 / 360));
|
||||
buffer.putByte((byte) (pitch * 256 / 360));
|
||||
buffer.putByte((byte) 0xff); // TODO Metadata
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user