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-25 20:03:43 +02:00
|
|
|
import fr.themode.minestom.data.Data;
|
2019-08-26 00:29:40 +02:00
|
|
|
import fr.themode.minestom.entity.property.Attribute;
|
2019-08-23 23:55:09 +02:00
|
|
|
import fr.themode.minestom.event.*;
|
2019-08-25 20:03:43 +02:00
|
|
|
import fr.themode.minestom.instance.Chunk;
|
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-27 20:49:11 +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-26 04:39:58 +02:00
|
|
|
import fr.themode.minestom.utils.*;
|
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-27 20:49:11 +02:00
|
|
|
protected boolean onGround;
|
|
|
|
|
2019-08-26 00:29:40 +02:00
|
|
|
private static InstanceContainer instanceContainer;
|
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
static {
|
|
|
|
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
|
|
|
|
//instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data"));
|
|
|
|
instanceContainer = Main.getInstanceManager().createInstanceContainer();
|
|
|
|
instanceContainer.enableAutoChunkLoad(true);
|
|
|
|
instanceContainer.setChunkGenerator(chunkGeneratorDemo);
|
2019-08-26 04:39:58 +02:00
|
|
|
int loopStart = -2;
|
|
|
|
int loopEnd = 2;
|
2019-08-25 20:03:43 +02:00
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
for (int x = loopStart; x < loopEnd; x++)
|
|
|
|
for (int z = loopStart; z < loopEnd; z++) {
|
|
|
|
instanceContainer.loadChunk(x, z);
|
|
|
|
}
|
|
|
|
System.out.println("Time to load all chunks: " + (System.currentTimeMillis() - time) + " ms");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Set<Entity> viewableEntity = new CopyOnWriteArraySet<>();
|
|
|
|
|
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-26 00:29:40 +02:00
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
private int food;
|
2019-08-26 00:29:40 +02:00
|
|
|
private float foodSaturation;
|
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-23 23:55:09 +02:00
|
|
|
protected boolean spawned;
|
|
|
|
|
2019-08-11 03:40:34 +02:00
|
|
|
public Player(UUID uuid, String username, PlayerConnection playerConnection) {
|
2019-08-27 20:49:11 +02:00
|
|
|
super(100);
|
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-26 00:29:40 +02:00
|
|
|
playerConnection.sendPacket(getPropertiesPacket()); // Send default properties
|
2019-08-25 20:03:43 +02:00
|
|
|
refreshHealth();
|
|
|
|
|
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) {
|
2019-08-27 20:49:11 +02:00
|
|
|
((EntityCreature) entity).damage(-1);
|
|
|
|
Vector velocity = getPosition().clone().getDirection().multiply(6);
|
|
|
|
velocity.setY(4f);
|
|
|
|
entity.setVelocity(velocity, 150);
|
|
|
|
sendMessage("You attacked 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);
|
2019-08-25 20:03:43 +02:00
|
|
|
player.damage(2);
|
2019-08-24 20:34:01 +02:00
|
|
|
sendMessage("ATTACK");
|
2019-08-21 16:50:52 +02:00
|
|
|
}
|
|
|
|
});
|
2019-08-22 14:52:32 +02:00
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
setEventCallback(PlayerBlockPlaceEvent.class, event -> {
|
2019-08-26 00:29:40 +02:00
|
|
|
/*sendMessage("Placed block! " + event.getHand());
|
2019-08-25 20:03:43 +02:00
|
|
|
int value = getData().getOrDefault("test", 0);
|
|
|
|
getData().set("test", value + 1, DataType.INTEGER);
|
2019-08-23 23:55:09 +02:00
|
|
|
|
2019-08-26 00:29:40 +02:00
|
|
|
System.out.println("OLD DATA VALUE: " + value);*/
|
2019-08-23 23:55:09 +02:00
|
|
|
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
|
|
|
});*/
|
|
|
|
|
2019-08-26 00:29:40 +02:00
|
|
|
for (Player player : instance.getPlayers()) {
|
2019-08-25 20:03:43 +02:00
|
|
|
if (player != this)
|
|
|
|
player.teleport(getPosition());
|
2019-08-26 00:29:40 +02:00
|
|
|
}
|
2019-08-24 20:34:01 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
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-25 20:03:43 +02:00
|
|
|
setData(new Data());
|
2019-08-23 23:55:09 +02:00
|
|
|
});
|
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
setEventCallback(PlayerSpawnEvent.class, event -> {
|
2019-08-26 04:39:58 +02:00
|
|
|
System.out.println("SPAWN");
|
2019-08-27 05:23:25 +02:00
|
|
|
setGameMode(GameMode.SURVIVAL);
|
2019-08-23 23:55:09 +02:00
|
|
|
teleport(new Position(0, 66, 0));
|
2019-08-25 20:03:43 +02:00
|
|
|
|
2019-08-29 02:15:52 +02:00
|
|
|
/*ChickenCreature chickenCreature = new ChickenCreature();
|
2019-08-25 20:03:43 +02:00
|
|
|
chickenCreature.refreshPosition(2, 65, 2);
|
|
|
|
chickenCreature.setInstance(getInstance());
|
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));
|
2019-08-27 20:49:11 +02:00
|
|
|
itemEntity.refreshPosition(ix, 68, 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-29 02:15:52 +02:00
|
|
|
}*/
|
|
|
|
|
|
|
|
getInventory().addItemStack(new ItemStack(1, (byte) 100));
|
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-26 00:29:40 +02:00
|
|
|
|
2019-08-26 04:39:58 +02:00
|
|
|
setAttribute(Attribute.MAX_HEALTH, 40);
|
2019-08-26 00:29:40 +02:00
|
|
|
heal();
|
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-25 20:03:43 +02:00
|
|
|
instance.breakBlock(this, targetBlockPosition);
|
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
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-08-27 20:49:11 +02:00
|
|
|
@Override
|
|
|
|
public boolean isOnGround() {
|
|
|
|
return onGround;
|
|
|
|
}
|
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
@Override
|
|
|
|
public void remove() {
|
|
|
|
clearBossBars();
|
|
|
|
if (getOpenInventory() != null)
|
|
|
|
getOpenInventory().removeViewer(this);
|
|
|
|
this.viewableEntity.forEach(entity -> entity.removeViewer(this));
|
|
|
|
super.remove();
|
|
|
|
}
|
|
|
|
|
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()) {
|
2019-08-26 00:29:40 +02:00
|
|
|
player.playerConnection.sendPacket(getEquipmentPacket(slot));
|
2019-08-20 22:40:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@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;
|
2019-08-26 00:29:40 +02:00
|
|
|
refreshIsDead(true);
|
|
|
|
EntityStatusPacket entityStatusPacket = new EntityStatusPacket();
|
|
|
|
entityStatusPacket.entityId = getEntityId();
|
|
|
|
entityStatusPacket.status = 3; // Death sound/animation
|
|
|
|
sendPacketToViewers(entityStatusPacket);
|
|
|
|
DeathEvent deathEvent = new DeathEvent();
|
|
|
|
callEvent(DeathEvent.class, deathEvent);
|
2019-08-24 20:34:01 +02:00
|
|
|
}
|
|
|
|
|
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-27 20:49:11 +02:00
|
|
|
@Override
|
|
|
|
public void damage(float value) {
|
2019-08-26 00:29:40 +02:00
|
|
|
if (getGameMode() == GameMode.CREATIVE)
|
|
|
|
return;
|
|
|
|
|
2019-08-27 20:49:11 +02:00
|
|
|
super.damage(value);
|
2019-08-25 20:03:43 +02:00
|
|
|
}
|
|
|
|
|
2019-08-26 00:29:40 +02:00
|
|
|
@Override
|
|
|
|
public void setAttribute(Attribute attribute, float value) {
|
|
|
|
super.setAttribute(attribute, value);
|
|
|
|
if (playerConnection != null)
|
|
|
|
playerConnection.sendPacket(getPropertiesPacket());
|
2019-08-25 20:03:43 +02:00
|
|
|
}
|
|
|
|
|
2019-08-26 00:29:40 +02:00
|
|
|
@Override
|
2019-08-25 20:03:43 +02:00
|
|
|
public void setHealth(float health) {
|
2019-08-26 00:29:40 +02:00
|
|
|
super.setHealth(health);
|
2019-08-25 20:03:43 +02:00
|
|
|
sendUpdateHealthPacket();
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getFood() {
|
|
|
|
return food;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setFood(int food) {
|
|
|
|
this.food = food;
|
|
|
|
sendUpdateHealthPacket();
|
|
|
|
}
|
|
|
|
|
|
|
|
public float getFoodSaturation() {
|
|
|
|
return foodSaturation;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setFoodSaturation(float foodSaturation) {
|
|
|
|
this.foodSaturation = foodSaturation;
|
|
|
|
sendUpdateHealthPacket();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void respawn() {
|
|
|
|
if (!isDead())
|
|
|
|
return;
|
|
|
|
|
|
|
|
refreshHealth();
|
|
|
|
RespawnPacket respawnPacket = new RespawnPacket();
|
|
|
|
respawnPacket.dimension = getDimension();
|
|
|
|
respawnPacket.gameMode = getGameMode();
|
|
|
|
respawnPacket.levelType = getLevelType();
|
|
|
|
getPlayerConnection().sendPacket(respawnPacket);
|
|
|
|
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(getPosition());
|
|
|
|
callEvent(PlayerRespawnEvent.class, respawnEvent);
|
|
|
|
refreshIsDead(false);
|
|
|
|
|
|
|
|
// Runnable called when teleportation is successfull (after loading and sending necessary chunk)
|
|
|
|
teleport(respawnEvent.getRespawnPosition(), () -> {
|
|
|
|
getInventory().update();
|
|
|
|
|
|
|
|
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
|
|
|
|
spawnPlayerPacket.entityId = getEntityId();
|
|
|
|
spawnPlayerPacket.playerUuid = getUuid();
|
|
|
|
spawnPlayerPacket.position = getPosition();
|
|
|
|
sendPacketToViewers(spawnPlayerPacket);
|
2019-08-26 00:29:40 +02:00
|
|
|
playerConnection.sendPacket(getPropertiesPacket());
|
|
|
|
sendUpdateHealthPacket();
|
2019-08-25 20:03:43 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void refreshHealth() {
|
2019-08-26 00:29:40 +02:00
|
|
|
heal();
|
2019-08-25 20:03:43 +02:00
|
|
|
this.food = 20;
|
|
|
|
this.foodSaturation = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void sendUpdateHealthPacket() {
|
|
|
|
UpdateHealthPacket updateHealthPacket = new UpdateHealthPacket();
|
2019-08-26 04:39:58 +02:00
|
|
|
updateHealthPacket.health = getHealth();
|
2019-08-25 20:03:43 +02:00
|
|
|
updateHealthPacket.food = food;
|
|
|
|
updateHealthPacket.foodSaturation = foodSaturation;
|
|
|
|
playerConnection.sendPacket(updateHealthPacket);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void onChunkChange(Chunk lastChunk, Chunk newChunk) {
|
2019-08-26 04:39:58 +02:00
|
|
|
float dx = newChunk.getChunkX() - lastChunk.getChunkX();
|
|
|
|
float dz = newChunk.getChunkZ() - lastChunk.getChunkZ();
|
|
|
|
double distance = Math.sqrt(dx * dx + dz * dz);
|
|
|
|
boolean isFar = distance >= Main.CHUNK_VIEW_DISTANCE / 2;
|
|
|
|
|
2019-08-27 05:23:25 +02:00
|
|
|
long[] lastVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), Main.CHUNK_VIEW_DISTANCE);
|
|
|
|
long[] updatedVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), Main.CHUNK_VIEW_DISTANCE);
|
2019-08-26 04:39:58 +02:00
|
|
|
int[] oldChunks = ArrayUtils.getDifferencesBetweenArray(lastVisibleChunks, updatedVisibleChunks);
|
|
|
|
int[] newChunks = ArrayUtils.getDifferencesBetweenArray(updatedVisibleChunks, lastVisibleChunks);
|
2019-08-25 20:03:43 +02:00
|
|
|
|
|
|
|
// Unload old chunks
|
2019-08-26 04:39:58 +02:00
|
|
|
for (int index : oldChunks) {
|
|
|
|
int[] chunkPos = ChunkUtils.getChunkCoord(lastVisibleChunks[index]);
|
|
|
|
UnloadChunkPacket unloadChunkPacket = new UnloadChunkPacket();
|
|
|
|
unloadChunkPacket.chunkX = chunkPos[0];
|
|
|
|
unloadChunkPacket.chunkZ = chunkPos[1];
|
|
|
|
playerConnection.sendPacket(unloadChunkPacket);
|
2019-08-25 20:03:43 +02:00
|
|
|
}
|
|
|
|
|
2019-08-26 04:39:58 +02:00
|
|
|
updateViewPosition(newChunk);
|
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
// Load new chunks
|
2019-08-26 04:39:58 +02:00
|
|
|
for (int i = 0; i < newChunks.length; i++) {
|
|
|
|
boolean isLast = i == newChunks.length - 1;
|
|
|
|
int index = newChunks[i];
|
|
|
|
int[] chunkPos = ChunkUtils.getChunkCoord(updatedVisibleChunks[index]);
|
|
|
|
instance.loadOptionalChunk(chunkPos[0], chunkPos[1], chunk -> {
|
|
|
|
if (chunk == null) {
|
2019-08-27 05:23:25 +02:00
|
|
|
return; // Cannot load chunk (auto load not enabled)
|
2019-08-25 20:03:43 +02:00
|
|
|
}
|
2019-08-26 04:39:58 +02:00
|
|
|
instance.sendChunk(this, chunk);
|
2019-08-27 05:23:25 +02:00
|
|
|
if (isFar && isLast) {
|
2019-08-26 04:39:58 +02:00
|
|
|
updatePlayerPosition();
|
2019-08-27 05:23:25 +02:00
|
|
|
}
|
2019-08-26 04:39:58 +02:00
|
|
|
});
|
2019-08-25 20:03:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-21 16:50:52 +02:00
|
|
|
@Override
|
2019-08-25 20:03:43 +02:00
|
|
|
public void teleport(Position position, Runnable callback) {
|
|
|
|
super.teleport(position, () -> {
|
2019-08-27 20:49:11 +02:00
|
|
|
if (!instance.hasEnabledAutoChunkLoad() && ChunkUtils.isChunkUnloaded(instance, position.getX(), position.getZ()))
|
2019-08-25 20:03:43 +02:00
|
|
|
return;
|
2019-08-26 04:39:58 +02:00
|
|
|
updatePlayerPosition();
|
2019-08-25 20:03:43 +02:00
|
|
|
if (callback != null)
|
|
|
|
callback.run();
|
|
|
|
});
|
|
|
|
}
|
2019-08-22 14:52:32 +02:00
|
|
|
|
2019-08-25 20:03:43 +02:00
|
|
|
@Override
|
|
|
|
public void teleport(Position position) {
|
|
|
|
teleport(position, null);
|
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();
|
2019-08-27 05:23:25 +02:00
|
|
|
openWindowPacket.windowId = inventory.getWindowId();
|
2019-08-13 17:52:09 +02:00
|
|
|
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 {
|
2019-08-27 05:23:25 +02:00
|
|
|
closeWindowPacket.windowId = openInventory.getWindowId();
|
2019-08-13 17:52:09 +02:00
|
|
|
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-25 20:03:43 +02:00
|
|
|
public void clearBossBars() {
|
|
|
|
this.bossBars.forEach(bossBar -> bossBar.removeViewer(this));
|
|
|
|
}
|
|
|
|
|
2019-08-20 22:40:57 +02:00
|
|
|
public void syncEquipment(EntityEquipmentPacket.Slot slot) {
|
2019-08-26 00:29:40 +02:00
|
|
|
sendPacketToViewers(getEquipmentPacket(slot));
|
|
|
|
}
|
|
|
|
|
|
|
|
protected EntityEquipmentPacket getEquipmentPacket(EntityEquipmentPacket.Slot slot) {
|
2019-08-20 22:40:57 +02:00
|
|
|
EntityEquipmentPacket equipmentPacket = new EntityEquipmentPacket();
|
|
|
|
equipmentPacket.entityId = getEntityId();
|
|
|
|
equipmentPacket.slot = slot;
|
|
|
|
equipmentPacket.itemStack = inventory.getEquipment(slot);
|
2019-08-26 00:29:40 +02:00
|
|
|
return equipmentPacket;
|
|
|
|
}
|
|
|
|
|
2019-08-27 05:23:25 +02:00
|
|
|
public void updateViewPosition(Chunk chunk) {
|
2019-08-26 00:29:40 +02:00
|
|
|
UpdateViewPositionPacket updateViewPositionPacket = new UpdateViewPositionPacket(chunk);
|
|
|
|
playerConnection.sendPacket(updateViewPositionPacket);
|
2019-08-20 22:40:57 +02:00
|
|
|
}
|
|
|
|
|
2019-08-26 04:39:58 +02:00
|
|
|
protected void updatePlayerPosition() {
|
|
|
|
PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
|
|
|
|
positionAndLookPacket.position = position;
|
|
|
|
positionAndLookPacket.flags = 0x00;
|
|
|
|
positionAndLookPacket.teleportId = 67;
|
|
|
|
playerConnection.sendPacket(positionAndLookPacket);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|