2019-08-03 15:25:24 +02:00
|
|
|
package fr.themode.minestom.entity;
|
|
|
|
|
2019-08-23 23:55:09 +02:00
|
|
|
import fr.themode.minestom.Main;
|
2019-08-19 17:04:19 +02:00
|
|
|
import fr.themode.minestom.bossbar.BossBar;
|
|
|
|
import fr.themode.minestom.chat.Chat;
|
2019-08-23 23:55:09 +02:00
|
|
|
import fr.themode.minestom.entity.demo.ChickenCreature;
|
|
|
|
import fr.themode.minestom.event.*;
|
2019-08-18 23:52:11 +02:00
|
|
|
import fr.themode.minestom.instance.CustomBlock;
|
2019-08-23 23:55:09 +02:00
|
|
|
import fr.themode.minestom.instance.Instance;
|
2019-08-24 21:41:43 +02:00
|
|
|
import fr.themode.minestom.instance.InstanceContainer;
|
2019-08-23 23:55:09 +02:00
|
|
|
import fr.themode.minestom.instance.demo.ChunkGeneratorDemo;
|
2019-08-13 17:52:09 +02:00
|
|
|
import fr.themode.minestom.inventory.Inventory;
|
2019-08-12 08:30:59 +02:00
|
|
|
import fr.themode.minestom.inventory.PlayerInventory;
|
2019-08-24 21:41:43 +02:00
|
|
|
import fr.themode.minestom.item.ItemStack;
|
2019-08-20 17:41:07 +02:00
|
|
|
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
2019-08-20 22:40:57 +02:00
|
|
|
import fr.themode.minestom.net.packet.server.ServerPacket;
|
2019-08-12 08:30:59 +02:00
|
|
|
import fr.themode.minestom.net.packet.server.play.*;
|
2019-08-03 15:25:24 +02:00
|
|
|
import fr.themode.minestom.net.player.PlayerConnection;
|
2019-08-21 16:50:52 +02:00
|
|
|
import fr.themode.minestom.utils.BlockPosition;
|
2019-08-18 20:38:09 +02:00
|
|
|
import fr.themode.minestom.utils.Position;
|
2019-08-24 20:34:01 +02:00
|
|
|
import fr.themode.minestom.utils.Vector;
|
2019-08-21 16:50:52 +02:00
|
|
|
import fr.themode.minestom.world.Dimension;
|
|
|
|
import fr.themode.minestom.world.LevelType;
|
2019-08-03 15:25:24 +02:00
|
|
|
|
2019-08-19 17:04:19 +02:00
|
|
|
import java.util.Collections;
|
2019-08-24 20:34:01 +02:00
|
|
|
import java.util.Random;
|
2019-08-19 17:04:19 +02:00
|
|
|
import java.util.Set;
|
2019-08-11 03:40:34 +02:00
|
|
|
import java.util.UUID;
|
2019-08-23 15:37:38 +02:00
|
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
2019-08-19 17:04:19 +02:00
|
|
|
import java.util.concurrent.CopyOnWriteArraySet;
|
2019-08-11 03:40:34 +02:00
|
|
|
|
2019-08-10 08:44:35 +02:00
|
|
|
public class Player extends LivingEntity {
|
|
|
|
|
2019-08-10 04:47:19 +02:00
|
|
|
private long lastKeepAlive;
|
2019-08-10 04:16:01 +02:00
|
|
|
|
2019-08-11 03:40:34 +02:00
|
|
|
private String username;
|
2019-08-03 15:25:24 +02:00
|
|
|
private PlayerConnection playerConnection;
|
2019-08-23 15:37:38 +02:00
|
|
|
private ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
|
2019-08-03 15:25:24 +02:00
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
private Dimension dimension;
|
2019-08-12 08:30:59 +02:00
|
|
|
private GameMode gameMode;
|
2019-08-21 16:50:52 +02:00
|
|
|
private LevelType levelType;
|
2019-08-24 20:34:01 +02:00
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
private PlayerSettings settings;
|
2019-08-12 08:30:59 +02:00
|
|
|
private PlayerInventory inventory;
|
|
|
|
private short heldSlot;
|
2019-08-13 17:52:09 +02:00
|
|
|
private Inventory openInventory;
|
2019-08-12 08:30:59 +02:00
|
|
|
|
2019-08-18 23:52:11 +02:00
|
|
|
private CustomBlock targetCustomBlock;
|
2019-08-21 16:50:52 +02:00
|
|
|
private BlockPosition targetBlockPosition;
|
2019-08-18 20:38:09 +02:00
|
|
|
private long targetBlockTime;
|
2019-08-22 14:52:32 +02:00
|
|
|
private byte targetLastStage;
|
2019-08-18 20:38:09 +02:00
|
|
|
|
2019-08-19 17:04:19 +02:00
|
|
|
private Set<BossBar> bossBars = new CopyOnWriteArraySet<>();
|
|
|
|
|
2019-08-20 17:41:07 +02:00
|
|
|
// Vehicle
|
|
|
|
private float sideways;
|
|
|
|
private float forward;
|
|
|
|
|
2019-08-24 21:41:43 +02:00
|
|
|
private static InstanceContainer instanceContainer;
|
2019-08-24 20:34:01 +02:00
|
|
|
|
2019-08-23 23:55:09 +02:00
|
|
|
static {
|
|
|
|
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
|
2019-08-24 20:34:01 +02:00
|
|
|
//instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data"));
|
2019-08-24 21:41:43 +02:00
|
|
|
instanceContainer = Main.getInstanceManager().createInstanceContainer();
|
|
|
|
instanceContainer.setChunkGenerator(chunkGeneratorDemo);
|
2019-08-23 23:55:09 +02:00
|
|
|
int loopStart = -2;
|
|
|
|
int loopEnd = 2;
|
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
for (int x = loopStart; x < loopEnd; x++)
|
|
|
|
for (int z = loopStart; z < loopEnd; z++) {
|
2019-08-24 21:41:43 +02:00
|
|
|
instanceContainer.loadChunk(x, z);
|
2019-08-23 23:55:09 +02:00
|
|
|
}
|
|
|
|
System.out.println("Time to load all chunks: " + (System.currentTimeMillis() - time) + " ms");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean spawned;
|
|
|
|
|
2019-08-11 03:40:34 +02:00
|
|
|
public Player(UUID uuid, String username, PlayerConnection playerConnection) {
|
2019-08-20 22:40:57 +02:00
|
|
|
super(93); // FIXME verify
|
2019-08-11 03:40:34 +02:00
|
|
|
this.uuid = uuid;
|
|
|
|
this.username = username;
|
2019-08-10 04:47:19 +02:00
|
|
|
this.playerConnection = playerConnection;
|
2019-08-12 08:30:59 +02:00
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
this.settings = new PlayerSettings();
|
2019-08-12 08:30:59 +02:00
|
|
|
this.inventory = new PlayerInventory(this);
|
2019-08-20 17:41:07 +02:00
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
setCanPickupItem(true); // By default
|
2019-08-21 16:50:52 +02:00
|
|
|
|
|
|
|
setEventCallback(AttackEvent.class, event -> {
|
|
|
|
Entity entity = event.getTarget();
|
|
|
|
if (entity instanceof EntityCreature) {
|
|
|
|
((EntityCreature) entity).kill();
|
|
|
|
sendMessage("You killed an entity!");
|
2019-08-24 20:34:01 +02:00
|
|
|
} else if (entity instanceof Player) {
|
|
|
|
Player player = (Player) entity;
|
|
|
|
Vector velocity = getPosition().clone().getDirection().multiply(6);
|
|
|
|
velocity.setY(3.5f);
|
|
|
|
player.setVelocity(velocity, 150);
|
|
|
|
|
|
|
|
AnimationPacket animationPacket = new AnimationPacket();
|
|
|
|
animationPacket.entityId = player.getEntityId();
|
|
|
|
animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE;
|
|
|
|
sendPacketToViewersAndSelf(animationPacket);
|
|
|
|
|
|
|
|
sendMessage("ATTACK");
|
2019-08-21 16:50:52 +02:00
|
|
|
}
|
|
|
|
/*UpdateHealthPacket updateHealthPacket = new UpdateHealthPacket();
|
|
|
|
updateHealthPacket.health = -1f;
|
|
|
|
updateHealthPacket.food = 5;
|
|
|
|
updateHealthPacket.foodSaturation = 0;
|
|
|
|
playerConnection.sendPacket(updateHealthPacket);*/
|
|
|
|
});
|
2019-08-22 14:52:32 +02:00
|
|
|
|
|
|
|
setEventCallback(BlockPlaceEvent.class, event -> {
|
2019-08-23 23:55:09 +02:00
|
|
|
/*sendMessage("Placed block! " + event.getHand());
|
|
|
|
Data data = new Data();
|
|
|
|
data.set("test", 5, DataType.INTEGER);
|
|
|
|
setData(data);
|
|
|
|
|
|
|
|
sendMessage("Data: " + getData().get("test"));*/
|
|
|
|
if (event.getHand() != Hand.MAIN)
|
|
|
|
return;
|
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
/*sendMessage("Save chunk data...");
|
2019-08-23 23:55:09 +02:00
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
getInstance().saveToFolder(() -> {
|
|
|
|
sendMessage("Saved in " + (System.currentTimeMillis() - time) + " ms");
|
2019-08-24 20:34:01 +02:00
|
|
|
});*/
|
|
|
|
|
|
|
|
for (Player player : Main.getConnectionManager().getOnlinePlayers()) {
|
|
|
|
player.teleport(getPosition());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
setEventCallback(PickupItemEvent.class, event -> {
|
|
|
|
event.setCancelled(!getInventory().addItemStack(event.getItemStack())); // Cancel event if player does not have enough inventory space
|
2019-08-23 23:55:09 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
setEventCallback(PlayerLoginEvent.class, event -> {
|
2019-08-24 21:41:43 +02:00
|
|
|
event.setSpawningInstance(instanceContainer);
|
2019-08-23 23:55:09 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
setEventCallback(PlayerSpawnPacket.class, event -> {
|
2019-08-24 20:34:01 +02:00
|
|
|
setGameMode(GameMode.SURVIVAL);
|
2019-08-23 23:55:09 +02:00
|
|
|
teleport(new Position(0, 66, 0));
|
|
|
|
for (int cx = 0; cx < 4; cx++)
|
|
|
|
for (int cz = 0; cz < 4; cz++) {
|
|
|
|
ChickenCreature chickenCreature = new ChickenCreature();
|
|
|
|
chickenCreature.refreshPosition(0 + (float) cx * 1, 65, 0 + (float) cz * 1);
|
|
|
|
//chickenCreature.setOnFire(true);
|
2019-08-24 21:41:43 +02:00
|
|
|
chickenCreature.setInstance(getInstance());
|
2019-08-23 23:55:09 +02:00
|
|
|
//chickenCreature.addPassenger(player);
|
|
|
|
}
|
2019-08-24 20:34:01 +02:00
|
|
|
|
2019-08-24 21:41:43 +02:00
|
|
|
for (int ix = 0; ix < 4; ix++)
|
2019-08-24 20:34:01 +02:00
|
|
|
for (int iz = 0; iz < 4; iz++) {
|
|
|
|
ItemEntity itemEntity = new ItemEntity(new ItemStack(1, (byte) 32));
|
|
|
|
itemEntity.refreshPosition(ix, 66, iz);
|
|
|
|
itemEntity.setNoGravity(true);
|
2019-08-24 21:41:43 +02:00
|
|
|
itemEntity.setInstance(getInstance());
|
2019-08-24 20:34:01 +02:00
|
|
|
//itemEntity.remove();
|
2019-08-24 21:41:43 +02:00
|
|
|
}
|
2019-08-24 20:34:01 +02:00
|
|
|
|
|
|
|
TeamsPacket teamsPacket = new TeamsPacket();
|
|
|
|
teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100);
|
|
|
|
teamsPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
|
|
|
teamsPacket.teamDisplayName = Chat.rawText("WOWdisplay");
|
|
|
|
teamsPacket.nameTagVisibility = "always";
|
|
|
|
teamsPacket.teamColor = 2;
|
|
|
|
teamsPacket.teamPrefix = Chat.rawText("pre");
|
|
|
|
teamsPacket.teamSuffix = Chat.rawText("suf");
|
|
|
|
teamsPacket.collisionRule = "never";
|
|
|
|
teamsPacket.entities = new String[]{getUsername()};
|
|
|
|
sendPacketToViewersAndSelf(teamsPacket);
|
2019-08-22 14:52:32 +02:00
|
|
|
});
|
2019-08-10 04:47:19 +02:00
|
|
|
}
|
|
|
|
|
2019-08-10 08:44:35 +02:00
|
|
|
@Override
|
|
|
|
public void update() {
|
2019-08-24 20:34:01 +02:00
|
|
|
|
|
|
|
playerConnection.flush();
|
|
|
|
|
|
|
|
ClientPlayPacket packet;
|
2019-08-23 15:37:38 +02:00
|
|
|
while ((packet = packets.poll()) != null) {
|
|
|
|
packet.process(this);
|
2019-08-20 17:41:07 +02:00
|
|
|
}
|
2019-08-18 20:38:09 +02:00
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
super.update(); // Super update (item pickup)
|
|
|
|
|
2019-08-18 20:38:09 +02:00
|
|
|
// Target block stage
|
2019-08-23 23:55:09 +02:00
|
|
|
if (targetCustomBlock != null) {
|
2019-08-18 23:52:11 +02:00
|
|
|
int timeBreak = targetCustomBlock.getBreakDelay(this);
|
2019-08-18 20:38:09 +02:00
|
|
|
int animationCount = 10;
|
|
|
|
long since = System.currentTimeMillis() - targetBlockTime;
|
|
|
|
byte stage = (byte) (since / (timeBreak / animationCount));
|
2019-08-22 14:52:32 +02:00
|
|
|
if (stage != targetLastStage) {
|
|
|
|
sendBlockBreakAnimation(targetBlockPosition, stage);
|
|
|
|
}
|
|
|
|
this.targetLastStage = stage;
|
2019-08-18 20:38:09 +02:00
|
|
|
if (stage > 9) {
|
2019-08-20 22:40:57 +02:00
|
|
|
instance.breakBlock(this, targetBlockPosition, targetCustomBlock);
|
2019-08-18 23:52:11 +02:00
|
|
|
resetTargetBlock();
|
2019-08-18 20:38:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Multiplayer sync
|
2019-08-21 16:50:52 +02:00
|
|
|
Position position = getPosition();
|
|
|
|
boolean positionChanged = position.getX() != lastX || position.getZ() != lastZ || position.getY() != lastY;
|
|
|
|
boolean viewChanged = position.getYaw() != lastYaw || position.getPitch() != lastPitch;
|
2019-08-20 22:40:57 +02:00
|
|
|
ServerPacket updatePacket = null;
|
|
|
|
ServerPacket optionalUpdatePacket = null;
|
|
|
|
if (positionChanged && viewChanged) {
|
|
|
|
EntityLookAndRelativeMovePacket entityLookAndRelativeMovePacket = new EntityLookAndRelativeMovePacket();
|
|
|
|
entityLookAndRelativeMovePacket.entityId = getEntityId();
|
2019-08-21 16:50:52 +02:00
|
|
|
entityLookAndRelativeMovePacket.deltaX = (short) ((position.getX() * 32 - lastX * 32) * 128);
|
|
|
|
entityLookAndRelativeMovePacket.deltaY = (short) ((position.getY() * 32 - lastY * 32) * 128);
|
|
|
|
entityLookAndRelativeMovePacket.deltaZ = (short) ((position.getZ() * 32 - lastZ * 32) * 128);
|
|
|
|
entityLookAndRelativeMovePacket.yaw = position.getYaw();
|
|
|
|
entityLookAndRelativeMovePacket.pitch = position.getPitch();
|
2019-08-20 22:40:57 +02:00
|
|
|
entityLookAndRelativeMovePacket.onGround = onGround;
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
lastX = position.getX();
|
|
|
|
lastY = position.getY();
|
|
|
|
lastZ = position.getZ();
|
|
|
|
lastYaw = position.getYaw();
|
|
|
|
lastPitch = position.getPitch();
|
2019-08-20 22:40:57 +02:00
|
|
|
updatePacket = entityLookAndRelativeMovePacket;
|
|
|
|
} else if (positionChanged) {
|
|
|
|
EntityRelativeMovePacket entityRelativeMovePacket = new EntityRelativeMovePacket();
|
|
|
|
entityRelativeMovePacket.entityId = getEntityId();
|
2019-08-21 16:50:52 +02:00
|
|
|
entityRelativeMovePacket.deltaX = (short) ((position.getX() * 32 - lastX * 32) * 128);
|
|
|
|
entityRelativeMovePacket.deltaY = (short) ((position.getY() * 32 - lastY * 32) * 128);
|
|
|
|
entityRelativeMovePacket.deltaZ = (short) ((position.getZ() * 32 - lastZ * 32) * 128);
|
2019-08-20 22:40:57 +02:00
|
|
|
entityRelativeMovePacket.onGround = onGround;
|
2019-08-21 16:50:52 +02:00
|
|
|
lastX = position.getX();
|
|
|
|
lastY = position.getY();
|
|
|
|
lastZ = position.getZ();
|
2019-08-20 22:40:57 +02:00
|
|
|
updatePacket = entityRelativeMovePacket;
|
|
|
|
} else if (viewChanged) {
|
|
|
|
EntityLookPacket entityLookPacket = new EntityLookPacket();
|
|
|
|
entityLookPacket.entityId = getEntityId();
|
2019-08-21 16:50:52 +02:00
|
|
|
entityLookPacket.yaw = position.getYaw();
|
|
|
|
entityLookPacket.pitch = position.getPitch();
|
2019-08-20 22:40:57 +02:00
|
|
|
entityLookPacket.onGround = onGround;
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
lastYaw = position.getYaw();
|
|
|
|
lastPitch = position.getPitch();
|
2019-08-20 22:40:57 +02:00
|
|
|
updatePacket = entityLookPacket;
|
2019-08-24 20:34:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (viewChanged) {
|
|
|
|
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
|
|
|
entityHeadLookPacket.entityId = getEntityId();
|
|
|
|
entityHeadLookPacket.yaw = position.getYaw();
|
2019-08-20 22:40:57 +02:00
|
|
|
optionalUpdatePacket = entityHeadLookPacket;
|
|
|
|
}
|
2019-08-24 20:34:01 +02:00
|
|
|
|
2019-08-20 22:40:57 +02:00
|
|
|
if (updatePacket != null) {
|
|
|
|
if (optionalUpdatePacket != null) {
|
|
|
|
sendPacketsToViewers(updatePacket, optionalUpdatePacket);
|
|
|
|
} else {
|
|
|
|
sendPacketToViewers(updatePacket);
|
|
|
|
}
|
2019-08-11 03:40:34 +02:00
|
|
|
}
|
2019-08-24 20:34:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void spawn() {
|
2019-08-20 22:40:57 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@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();
|
2019-08-21 16:50:52 +02:00
|
|
|
spawnPlayerPacket.position = getPosition();
|
2019-08-20 22:40:57 +02:00
|
|
|
|
|
|
|
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);
|
2019-08-24 20:34:01 +02:00
|
|
|
connection.sendPacket(getMetadataPacket());
|
2019-08-20 22:40:57 +02:00
|
|
|
|
|
|
|
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);
|
2019-08-11 03:40:34 +02:00
|
|
|
}
|
|
|
|
|
2019-08-23 23:55:09 +02:00
|
|
|
@Override
|
|
|
|
public void setInstance(Instance instance) {
|
|
|
|
if (!spawned)
|
|
|
|
throw new IllegalStateException("Player#setInstance is only available during and after PlayerSpawnEvent");
|
|
|
|
|
|
|
|
super.setInstance(instance);
|
|
|
|
}
|
|
|
|
|
2019-08-24 20:34:01 +02:00
|
|
|
@Override
|
|
|
|
public void kill() {
|
|
|
|
this.isDead = true;
|
|
|
|
// TODO set health to -1
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public void sendBlockBreakAnimation(BlockPosition blockPosition, byte destroyStage) {
|
2019-08-18 23:52:11 +02:00
|
|
|
BlockBreakAnimationPacket breakAnimationPacket = new BlockBreakAnimationPacket();
|
|
|
|
breakAnimationPacket.entityId = getEntityId() + 1;
|
|
|
|
breakAnimationPacket.blockPosition = blockPosition;
|
|
|
|
breakAnimationPacket.destroyStage = destroyStage;
|
2019-08-22 14:52:32 +02:00
|
|
|
sendPacketToViewersAndSelf(breakAnimationPacket);
|
2019-08-18 23:52:11 +02:00
|
|
|
}
|
|
|
|
|
2019-08-18 20:38:09 +02:00
|
|
|
public void sendMessage(String message) {
|
2019-08-19 17:04:19 +02:00
|
|
|
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(Chat.rawText(message), ChatMessagePacket.Position.CHAT);
|
2019-08-18 20:38:09 +02:00
|
|
|
playerConnection.sendPacket(chatMessagePacket);
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
@Override
|
|
|
|
public void teleport(Position position) {
|
2019-08-24 20:34:01 +02:00
|
|
|
super.teleport(position); // Send new position to all viewers directly
|
2019-08-22 14:52:32 +02:00
|
|
|
if (isChunkUnloaded(position.getX(), position.getZ()))
|
|
|
|
return;
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
refreshPosition(position.getX(), position.getY(), position.getZ());
|
|
|
|
refreshView(position.getYaw(), position.getPitch());
|
2019-08-11 13:57:23 +02:00
|
|
|
PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
|
2019-08-21 16:50:52 +02:00
|
|
|
positionAndLookPacket.position = position;
|
2019-08-11 13:57:23 +02:00
|
|
|
positionAndLookPacket.flags = 0x00;
|
|
|
|
positionAndLookPacket.teleportId = 67;
|
2019-08-22 14:52:32 +02:00
|
|
|
playerConnection.sendPacket(positionAndLookPacket);
|
2019-08-11 09:33:27 +02:00
|
|
|
}
|
|
|
|
|
2019-08-11 03:40:34 +02:00
|
|
|
public String getUsername() {
|
|
|
|
return username;
|
2019-08-10 08:44:35 +02:00
|
|
|
}
|
|
|
|
|
2019-08-03 15:25:24 +02:00
|
|
|
public PlayerConnection getPlayerConnection() {
|
|
|
|
return playerConnection;
|
|
|
|
}
|
2019-08-10 04:16:01 +02:00
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public PlayerSettings getSettings() {
|
|
|
|
return settings;
|
|
|
|
}
|
|
|
|
|
2019-08-12 08:30:59 +02:00
|
|
|
public PlayerInventory getInventory() {
|
|
|
|
return inventory;
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public Dimension getDimension() {
|
|
|
|
return dimension;
|
|
|
|
}
|
|
|
|
|
2019-08-12 08:30:59 +02:00
|
|
|
public GameMode getGameMode() {
|
|
|
|
return gameMode;
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public void setDimension(Dimension dimension) {
|
|
|
|
if (dimension == null)
|
|
|
|
throw new IllegalArgumentException("Dimension cannot be null!");
|
|
|
|
if (dimension.equals(getDimension()))
|
|
|
|
return;
|
|
|
|
RespawnPacket respawnPacket = new RespawnPacket();
|
|
|
|
respawnPacket.dimension = dimension;
|
|
|
|
respawnPacket.gameMode = gameMode;
|
|
|
|
respawnPacket.levelType = levelType;
|
|
|
|
playerConnection.sendPacket(respawnPacket);
|
|
|
|
}
|
|
|
|
|
2019-08-20 22:40:57 +02:00
|
|
|
public void kick(String message) {
|
|
|
|
DisconnectPacket disconnectPacket = new DisconnectPacket();
|
|
|
|
disconnectPacket.message = message;
|
|
|
|
playerConnection.sendPacket(disconnectPacket);
|
|
|
|
playerConnection.getConnection().close();
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public LevelType getLevelType() {
|
|
|
|
return levelType;
|
|
|
|
}
|
|
|
|
|
2019-08-12 08:30:59 +02:00
|
|
|
public void setGameMode(GameMode gameMode) {
|
|
|
|
ChangeGameStatePacket changeGameStatePacket = new ChangeGameStatePacket();
|
|
|
|
changeGameStatePacket.reason = ChangeGameStatePacket.Reason.CHANGE_GAMEMODE;
|
|
|
|
changeGameStatePacket.value = gameMode.getId();
|
|
|
|
playerConnection.sendPacket(changeGameStatePacket);
|
|
|
|
refreshGameMode(gameMode);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setHeldItemSlot(short slot) {
|
|
|
|
if (slot < 0 || slot > 8)
|
|
|
|
throw new IllegalArgumentException("Slot has to be between 0 and 8");
|
|
|
|
HeldItemChangePacket heldItemChangePacket = new HeldItemChangePacket();
|
|
|
|
heldItemChangePacket.slot = slot;
|
|
|
|
playerConnection.sendPacket(heldItemChangePacket);
|
|
|
|
refreshHeldSlot(slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
public short getHeldSlot() {
|
|
|
|
return heldSlot;
|
|
|
|
}
|
|
|
|
|
2019-08-13 17:52:09 +02:00
|
|
|
public Inventory getOpenInventory() {
|
|
|
|
return openInventory;
|
|
|
|
}
|
|
|
|
|
2019-08-18 23:52:11 +02:00
|
|
|
public CustomBlock getCustomBlockTarget() {
|
|
|
|
return targetCustomBlock;
|
|
|
|
}
|
|
|
|
|
2019-08-19 17:04:19 +02:00
|
|
|
public Set<BossBar> getBossBars() {
|
|
|
|
return Collections.unmodifiableSet(bossBars);
|
|
|
|
}
|
|
|
|
|
2019-08-20 17:41:07 +02:00
|
|
|
public float getVehicleSideways() {
|
|
|
|
return sideways;
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getVehicleForward() {
|
|
|
|
return forward;
|
|
|
|
}
|
|
|
|
|
2019-08-13 17:52:09 +02:00
|
|
|
public void openInventory(Inventory inventory) {
|
|
|
|
if (inventory == null)
|
|
|
|
throw new IllegalArgumentException("Inventory cannot be null, use Player#closeInventory() to close current");
|
|
|
|
|
|
|
|
if (getOpenInventory() != null) {
|
|
|
|
getOpenInventory().removeViewer(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
OpenWindowPacket openWindowPacket = new OpenWindowPacket();
|
|
|
|
openWindowPacket.windowId = inventory.getUniqueId();
|
|
|
|
openWindowPacket.windowType = inventory.getInventoryType().getWindowType();
|
|
|
|
openWindowPacket.title = inventory.getTitle();
|
|
|
|
playerConnection.sendPacket(openWindowPacket);
|
|
|
|
inventory.addViewer(this);
|
|
|
|
refreshOpenInventory(inventory);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void closeInventory() {
|
|
|
|
Inventory openInventory = getOpenInventory();
|
|
|
|
CloseWindowPacket closeWindowPacket = new CloseWindowPacket();
|
|
|
|
if (openInventory == null) {
|
|
|
|
closeWindowPacket.windowId = 0;
|
|
|
|
} else {
|
|
|
|
closeWindowPacket.windowId = openInventory.getUniqueId();
|
|
|
|
openInventory.removeViewer(this);
|
|
|
|
refreshOpenInventory(null);
|
|
|
|
}
|
|
|
|
playerConnection.sendPacket(closeWindowPacket);
|
2019-08-14 06:50:03 +02:00
|
|
|
inventory.update();
|
2019-08-13 17:52:09 +02:00
|
|
|
}
|
|
|
|
|
2019-08-20 22:40:57 +02:00
|
|
|
public void syncEquipment(EntityEquipmentPacket.Slot slot) {
|
|
|
|
EntityEquipmentPacket equipmentPacket = new EntityEquipmentPacket();
|
|
|
|
equipmentPacket.entityId = getEntityId();
|
|
|
|
equipmentPacket.slot = slot;
|
|
|
|
equipmentPacket.itemStack = inventory.getEquipment(slot);
|
|
|
|
sendPacketToViewers(equipmentPacket);
|
|
|
|
}
|
|
|
|
|
2019-08-20 17:41:07 +02:00
|
|
|
public void addPacketToQueue(ClientPlayPacket packet) {
|
2019-08-23 15:37:38 +02:00
|
|
|
this.packets.add(packet);
|
2019-08-20 17:41:07 +02:00
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public void refreshDimension(Dimension dimension) {
|
|
|
|
this.dimension = dimension;
|
|
|
|
}
|
|
|
|
|
2019-08-12 08:30:59 +02:00
|
|
|
public void refreshGameMode(GameMode gameMode) {
|
|
|
|
this.gameMode = gameMode;
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public void refreshLevelType(LevelType levelType) {
|
|
|
|
this.levelType = levelType;
|
|
|
|
}
|
|
|
|
|
2019-08-10 04:16:01 +02:00
|
|
|
public void refreshOnGround(boolean onGround) {
|
|
|
|
this.onGround = onGround;
|
|
|
|
}
|
|
|
|
|
2019-08-10 04:47:19 +02:00
|
|
|
public void refreshKeepAlive(long lastKeepAlive) {
|
|
|
|
this.lastKeepAlive = lastKeepAlive;
|
|
|
|
}
|
|
|
|
|
2019-08-12 08:30:59 +02:00
|
|
|
public void refreshHeldSlot(short slot) {
|
|
|
|
this.heldSlot = slot;
|
2019-08-20 22:40:57 +02:00
|
|
|
syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
|
2019-08-12 08:30:59 +02:00
|
|
|
}
|
|
|
|
|
2019-08-13 17:52:09 +02:00
|
|
|
public void refreshOpenInventory(Inventory openInventory) {
|
|
|
|
this.openInventory = openInventory;
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
public void refreshTargetBlock(CustomBlock targetCustomBlock, BlockPosition targetBlockPosition) {
|
2019-08-18 23:52:11 +02:00
|
|
|
this.targetCustomBlock = targetCustomBlock;
|
2019-08-18 20:38:09 +02:00
|
|
|
this.targetBlockPosition = targetBlockPosition;
|
|
|
|
this.targetBlockTime = targetBlockPosition == null ? 0 : System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
|
2019-08-18 23:52:11 +02:00
|
|
|
public void resetTargetBlock() {
|
|
|
|
this.targetCustomBlock = null;
|
|
|
|
this.targetBlockPosition = null;
|
|
|
|
this.targetBlockTime = 0;
|
|
|
|
}
|
|
|
|
|
2019-08-19 17:04:19 +02:00
|
|
|
public void refreshAddBossbar(BossBar bossBar) {
|
|
|
|
this.bossBars.add(bossBar);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void refreshRemoveBossbar(BossBar bossBar) {
|
|
|
|
this.bossBars.remove(bossBar);
|
|
|
|
}
|
|
|
|
|
2019-08-20 17:41:07 +02:00
|
|
|
public void refreshVehicleSteer(float sideways, float forward) {
|
|
|
|
this.sideways = sideways;
|
|
|
|
this.forward = forward;
|
|
|
|
}
|
|
|
|
|
2019-08-10 04:47:19 +02:00
|
|
|
public long getLastKeepAlive() {
|
|
|
|
return lastKeepAlive;
|
|
|
|
}
|
2019-08-11 03:40:34 +02:00
|
|
|
|
|
|
|
public enum Hand {
|
|
|
|
MAIN,
|
|
|
|
OFF
|
|
|
|
}
|
2019-08-21 16:50:52 +02:00
|
|
|
|
|
|
|
public enum MainHand {
|
|
|
|
LEFT,
|
|
|
|
RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum ChatMode {
|
|
|
|
ENABLED,
|
|
|
|
COMMANDS_ONLY,
|
|
|
|
HIDDEN;
|
|
|
|
}
|
|
|
|
|
|
|
|
public class PlayerSettings {
|
|
|
|
|
|
|
|
private String locale;
|
|
|
|
private byte viewDistance;
|
|
|
|
private ChatMode chatMode;
|
|
|
|
private boolean chatColors;
|
|
|
|
private byte displayedSkinParts;
|
|
|
|
private MainHand mainHand;
|
|
|
|
|
|
|
|
public String getLocale() {
|
|
|
|
return locale;
|
|
|
|
}
|
|
|
|
|
|
|
|
public byte getViewDistance() {
|
|
|
|
return viewDistance;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ChatMode getChatMode() {
|
|
|
|
return chatMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasChatColors() {
|
|
|
|
return chatColors;
|
|
|
|
}
|
|
|
|
|
|
|
|
public byte getDisplayedSkinParts() {
|
|
|
|
return displayedSkinParts;
|
|
|
|
}
|
|
|
|
|
|
|
|
public MainHand getMainHand() {
|
|
|
|
return mainHand;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void refresh(String locale, byte viewDistance, ChatMode chatMode, boolean chatColors, byte displayedSkinParts, MainHand mainHand) {
|
|
|
|
this.locale = locale;
|
|
|
|
this.viewDistance = viewDistance;
|
|
|
|
this.chatMode = chatMode;
|
|
|
|
this.chatColors = chatColors;
|
|
|
|
this.displayedSkinParts = displayedSkinParts;
|
|
|
|
this.mainHand = mainHand;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-03 15:25:24 +02:00
|
|
|
}
|