This commit is contained in:
LOOHP
2021-04-06 21:14:05 +08:00
parent 05cfdb73a9
commit 6d14314bd9
126 changed files with 191394 additions and 0 deletions
@@ -0,0 +1,261 @@
package com.loohp.limbo.player;
import java.io.IOException;
import java.util.UUID;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.events.player.PlayerChatEvent;
import com.loohp.limbo.events.player.PlayerTeleportEvent;
import com.loohp.limbo.server.ClientConnection;
import com.loohp.limbo.server.packets.PacketPlayOutChat;
import com.loohp.limbo.server.packets.PacketPlayOutGameState;
import com.loohp.limbo.server.packets.PacketPlayOutHeldItemChange;
import com.loohp.limbo.server.packets.PacketPlayOutPositionAndLook;
import com.loohp.limbo.server.packets.PacketPlayOutRespawn;
import com.loohp.limbo.commands.CommandSender;
import com.loohp.limbo.entity.DataWatcher;
import com.loohp.limbo.entity.EntityType;
import com.loohp.limbo.entity.LivingEntity;
import com.loohp.limbo.entity.DataWatcher.WatchableField;
import com.loohp.limbo.entity.DataWatcher.WatchableObjectType;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.utils.GameMode;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class Player extends LivingEntity implements CommandSender {
public final ClientConnection clientConnection;
public final PlayerInteractManager playerInteractManager;
protected final String username;
protected GameMode gamemode;
protected DataWatcher watcher;
protected byte selectedSlot;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT)
protected float additionalHearts = 0.0F;
@WatchableField(MetadataIndex = 15, WatchableObjectType = WatchableObjectType.VARINT)
protected int score = 0;
@WatchableField(MetadataIndex = 16, WatchableObjectType = WatchableObjectType.BYTE)
protected byte skinLayers = 0;
@WatchableField(MetadataIndex = 17, WatchableObjectType = WatchableObjectType.BYTE)
protected byte mainHand = 1;
//@WatchableField(MetadataIndex = 18, WatchableObjectType = WatchableObjectType.NBT)
//protected Entity leftShoulder = null;
//@WatchableField(MetadataIndex = 19, WatchableObjectType = WatchableObjectType.NBT)
//protected Entity rightShoulder = null;
public Player(ClientConnection clientConnection, String username, UUID uuid, int entityId, Location location, PlayerInteractManager playerInteractManager) throws IllegalArgumentException, IllegalAccessException {
super(EntityType.PLAYER, entityId, uuid, location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
this.clientConnection = clientConnection;
this.username = username;
this.entityId = entityId;
this.playerInteractManager = playerInteractManager;
this.playerInteractManager.setPlayer(this);
this.watcher = new DataWatcher(this);
this.watcher.update();
}
public byte getSelectedSlot() {
return selectedSlot;
}
public void setSelectedSlot(byte slot) {
if(slot == selectedSlot)
return;
try {
PacketPlayOutHeldItemChange state = new PacketPlayOutHeldItemChange(slot);
clientConnection.sendPacket(state);
} catch (IOException e) {
e.printStackTrace();
}
this.selectedSlot = slot;
}
public GameMode getGamemode() {
return gamemode;
}
public void setGamemode(GameMode gamemode) {
if (!this.gamemode.equals(gamemode)) {
try {
PacketPlayOutGameState state = new PacketPlayOutGameState(3, gamemode.getId());
clientConnection.sendPacket(state);
} catch (IOException e) {
e.printStackTrace();
}
}
this.gamemode = gamemode;
}
@Deprecated
protected void setEntityId(int entityId) {
this.entityId = entityId;
}
public float getAdditionalHearts() {
return additionalHearts;
}
public void setAdditionalHearts(float additionalHearts) {
this.additionalHearts = additionalHearts;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public byte getSkinLayers() {
return skinLayers;
}
public void setSkinLayers(byte skinLayers) {
this.skinLayers = skinLayers;
}
public byte getMainHand() {
return mainHand;
}
public void setMainHand(byte mainHand) {
this.mainHand = mainHand;
}
@Override
public DataWatcher getDataWatcher() {
return watcher;
}
@Override
public boolean isValid() {
return Limbo.getInstance().getPlayers().contains(this);
}
@Override
public void remove() {
}
/*
public Entity getLeftShoulder() {
return leftShoulder;
}
public void setLeftShoulder(Entity leftShoulder) {
this.leftShoulder = leftShoulder;
}
public Entity getRightShoulder() {
return rightShoulder;
}
public void setRightShoulder(Entity rightShoulder) {
this.rightShoulder = rightShoulder;
}
*/
@Override
public String getName() {
return username;
}
@Override
public boolean hasPermission(String permission) {
return Limbo.getInstance().getPermissionsManager().hasPermission(this, permission);
}
@Override
public void teleport(Location location) {
PlayerTeleportEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerTeleportEvent(this, getLocation(), location));
if (!event.isCancelled()) {
location = event.getTo();
super.teleport(location);
try {
if (!world.equals(location.getWorld())) {
PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), Limbo.getInstance().getDimensionRegistry().getCodec(), 0, gamemode, false, false, true);
clientConnection.sendPacket(respawn);
}
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1);
clientConnection.sendPacket(positionLook);
} catch (IOException e) {
e.printStackTrace();
}
}
}
protected void setLocation(Location location) {
super.teleport(location);
}
public void sendMessage(String message, UUID uuid) {
sendMessage(TextComponent.fromLegacyText(message), uuid);
}
public void sendMessage(BaseComponent component, UUID uuid) {
sendMessage(new BaseComponent[] { component }, uuid);
}
@Override
public void sendMessage(BaseComponent[] component, UUID uuid) {
try {
PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, uuid);
clientConnection.sendPacket(chat);
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String message) {
sendMessage(TextComponent.fromLegacyText(message));
}
public void sendMessage(BaseComponent component) {
sendMessage(new BaseComponent[] { component });
}
@Override
public void sendMessage(BaseComponent[] component) {
try {
PacketPlayOutChat chat = new PacketPlayOutChat(ComponentSerializer.toString(component), 0, new UUID(0, 0));
clientConnection.sendPacket(chat);
} catch (IOException e) {
e.printStackTrace();
}
}
public void disconnect() {
disconnect("Disconnected!");
}
public void disconnect(String reason) {
disconnect(TextComponent.fromLegacyText(reason));
}
public void disconnect(BaseComponent reason) {
disconnect(new BaseComponent[] {reason});
}
public void disconnect(BaseComponent[] reason) {
clientConnection.disconnect(reason);
}
public void chat(String message) {
String prefix = "<" + username + "> ";
PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, prefix, message, false));
if (!event.isCancelled()) {
String chat = event.getPrefix() + event.getMessage();
Limbo.getInstance().getConsole().sendMessage(chat);
for (Player each : Limbo.getInstance().getPlayers()) {
each.sendMessage(chat, uuid);
}
}
}
}
@@ -0,0 +1,135 @@
package com.loohp.limbo.player;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.server.packets.PacketPlayOutEntityDestroy;
import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata;
import com.loohp.limbo.server.packets.PacketPlayOutLightUpdate;
import com.loohp.limbo.server.packets.PacketPlayOutMapChunk;
import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntity;
import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntityLiving;
import com.loohp.limbo.server.packets.PacketPlayOutUnloadChunk;
import com.loohp.limbo.entity.Entity;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.world.World;
import net.querz.mca.Chunk;
public class PlayerInteractManager {
private Player player;
private Set<Entity> entities;
private Map<Chunk, World> chunks;
public PlayerInteractManager() {
this.player = null;
this.entities = new HashSet<>();
this.chunks = new HashMap<>();
}
protected void setPlayer(Player player) {
if (this.player == null) {
this.player = player;
} else {
throw new RuntimeException("Player in PlayerInteractManager cannot be changed once created");
}
}
public Player getPlayer() {
return player;
}
public void update() throws IOException {
int viewDistanceChunks = Limbo.getInstance().getServerProperties().getViewDistance();
int viewDistanceBlocks = viewDistanceChunks << 4;
Location location = player.getLocation();
Set<Entity> entitiesInRange = player.getWorld().getEntities().stream().filter(each -> each.getLocation().distanceSquared(location) < viewDistanceBlocks * viewDistanceBlocks).collect(Collectors.toSet());
for (Entity entity : entitiesInRange) {
if (!entities.contains(entity)) {
if (entity.getType().isAlive()) {
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch(), entity.getPitch(), (short) 0, (short) 0, (short) 0);
player.clientConnection.sendPacket(packet);
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
player.clientConnection.sendPacket(meta);
} else {
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(entity.getEntityId(), entity.getUniqueId(), entity.getType(), entity.getX(), entity.getY(), entity.getZ(), entity.getPitch(), entity.getYaw(), (short) 0, (short) 0, (short) 0);
player.clientConnection.sendPacket(packet);
PacketPlayOutEntityMetadata meta = new PacketPlayOutEntityMetadata(entity);
player.clientConnection.sendPacket(meta);
}
}
}
List<Integer> ids = new ArrayList<>();
for (Entity entity : entities) {
if (!entitiesInRange.contains(entity)) {
ids.add(entity.getEntityId());
}
}
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids.stream().mapToInt(each -> each).toArray());
player.clientConnection.sendPacket(packet);
entities = entitiesInRange;
int playerChunkX = (int) location.getX() >> 4;
int playerChunkZ = (int) location.getZ() >> 4;
World world = location.getWorld();
Set<Chunk> chunksInRange = new HashSet<>();
for (int x = playerChunkX - viewDistanceChunks; x < playerChunkX + viewDistanceChunks; x++) {
for (int z = playerChunkZ - viewDistanceChunks; z < playerChunkZ + viewDistanceChunks; z++) {
Chunk chunk = world.getChunkAt(x, z);
if (chunk != null) {
chunksInRange.add(chunk);
}
}
}
for (Entry<Chunk, World> entry : chunks.entrySet()) {
Chunk chunk = entry.getKey();
if (location.getWorld().getChunkXZ(chunk) == null) {
World world0 = entry.getValue();
int[] chunkPos = world0.getChunkXZ(chunk);
PacketPlayOutUnloadChunk packet0 = new PacketPlayOutUnloadChunk(chunkPos[0], chunkPos[1]);
player.clientConnection.sendPacket(packet0);
}
}
for (Chunk chunk : chunksInRange) {
if (!chunks.containsKey(chunk)) {
int[] chunkPos = world.getChunkXZ(chunk);
PacketPlayOutMapChunk packet0 = new PacketPlayOutMapChunk(chunkPos[0], chunkPos[1], chunk, world.getEnvironment());
player.clientConnection.sendPacket(packet0);
List<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]);
if (blockChunk == null) {
blockChunk = new ArrayList<>();
}
List<Byte[]> skyChunk = null;
if (world.hasSkyLight()) {
skyChunk = world.getLightEngineSky().getSkyLightBitMask(chunkPos[0], chunkPos[1]);
}
if (skyChunk == null) {
skyChunk = new ArrayList<>();
}
PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(chunkPos[0], chunkPos[1], true, skyChunk, blockChunk);
player.clientConnection.sendPacket(chunkdata);
}
}
chunks = chunksInRange.stream().collect(Collectors.toMap(each -> each, each -> world));
}
}
@@ -0,0 +1,31 @@
package com.loohp.limbo.player;
import com.loohp.limbo.location.Location;
import com.loohp.limbo.utils.GameMode;
@Deprecated
public class Unsafe {
private Unsafe() {}
@Deprecated
public void a(Player a, GameMode b) {
a.gamemode = b;
}
@Deprecated
public void a(Player a, int b) {
a.setEntityId(b);
}
@Deprecated
public void a(Player a, Location b) {
a.setLocation(b);
}
@Deprecated
public void a(Player a, byte b) {
a.selectedSlot = b;
}
}