/* * Copyright (c) 2018 univento.eu - All rights reserved * You are not allowed to use, distribute or modify this code */ package eu.univento.core.api.player; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.mojang.authlib.GameProfile; import eu.univento.commons.player.DatabasePlayer; import eu.univento.commons.player.language.MessageConstant; import eu.univento.commons.player.rank.Rank; import eu.univento.commons.player.warn.WarnReason; import eu.univento.commons.server.ServerType; import eu.univento.core.Core; import eu.univento.core.api.Hologram; import eu.univento.core.api.chat.DefaultFontInfo; import eu.univento.core.api.effects.Blackscreen; import eu.univento.core.api.effects.Effects; import eu.univento.core.api.gui.hologram.HologramData; import eu.univento.core.api.quest.Quest; import eu.univento.core.api.server.ServerSettings; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.Setter; import net.md_5.bungee.api.chat.TextComponent; import net.minecraft.server.v1_12_R1.*; import org.bukkit.*; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; import org.bukkit.attribute.AttributeModifier; import org.bukkit.block.Chest; import org.bukkit.block.DoubleChest; import org.bukkit.block.EnderChest; import org.bukkit.block.ShulkerBox; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarFlag; import org.bukkit.boss.BarStyle; import org.bukkit.boss.BossBar; import org.bukkit.craftbukkit.v1_12_R1.CraftServer; import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; public class CustomPlayer extends CraftPlayer { private static final HashMap PLAYERS = new HashMap<>(); private static final Map nickedPlayers = new HashMap<>(); private final Player PLAYER; private final DatabasePlayer DATABASE_PLAYER; @Getter @Setter private boolean openInventory; private final GameProfile gameProfile; @Getter private HologramData hologramData; private CustomPlayer(Player player) { super((CraftServer) Bukkit.getServer(), ((CraftPlayer) player).getHandle()); DATABASE_PLAYER = new DatabasePlayer(player.getUniqueId()); PLAYERS.put(player.getUniqueId(), this); PLAYER = player; gameProfile = ((CraftPlayer) player).getProfile(); hologramData = new HologramData(this); } public void onLeave() { DATABASE_PLAYER.setInDatabase("lastOnline", Instant.now().toString()); HashMap location = new HashMap<>(); location.put("X", getLocation().getX()); location.put("Y", getLocation().getY()); location.put("Z", getLocation().getZ()); location.put("Yaw", String.valueOf(getLocation().getYaw())); location.put("Pitch", String.valueOf(getLocation().getPitch())); if (ServerSettings.isLobby()) DATABASE_PLAYER.setInDatabase("Pos", location); if (PLAYERS.containsKey(getUniqueId())) PLAYERS.remove(getUniqueId()); getDatabasePlayer().save(); } public static CustomPlayer getPlayer(String player) { if (Bukkit.getPlayer(player) == null) return null; Player p = Bukkit.getPlayer(player); if (PLAYERS.containsKey(p.getUniqueId())) { return PLAYERS.get(p.getUniqueId()); } else { return new CustomPlayer(p); } } public static CustomPlayer getPlayer(UUID player) { if (PLAYERS.containsKey(player)) { return PLAYERS.get(player); } else { Player p = Bukkit.getPlayer(player); return p == null ? null : new CustomPlayer(p); } } public static CustomPlayer getPlayer(Player player) { return getPlayer(player.getUniqueId()); } public Player getPlayer() { return PLAYER; } public DatabasePlayer getDatabasePlayer() { return DATABASE_PLAYER; } /* Chat */ public void sendMessage(MessageConstant constant) { sendMessage(ChatColor.translateAlternateColorCodes('&', getDatabasePlayer().getLanguage().getMessage(constant))); } public void sendCentredMessage(String message) { if (message == null || message.equals("")) { sendMessage(""); return; } message = ChatColor.translateAlternateColorCodes('&', message); int messagePxSize = 0; boolean previousCode = false; boolean isBold = false; for (char c : message.toCharArray()) { if (c == 'ยง') { previousCode = true; } else if (previousCode) { previousCode = false; isBold = c == 'l' || c == 'L'; } else { DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); messagePxSize++; } } int CENTER_PX = 154; int halvedMessageSize = messagePxSize / 2; int toCompensate = CENTER_PX - halvedMessageSize; int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; int compensated = 0; StringBuilder sb = new StringBuilder(); while (compensated < toCompensate) { sb.append(" "); compensated += spaceLength; } sendMessage(sb.toString() + message); } /* Graphical User Interface */ public void sendActionBar(String text) { IChatBaseComponent cbc = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + text + "\"}"); PacketPlayOutChat ppoc = new PacketPlayOutChat(cbc, ChatMessageType.a((byte) 2)); sendPacket(ppoc); } public void sendTitle(int fadeIn, int stay, int fadeOut, String title, String subtitle) { PacketPlayOutTitle packetPlayOutTimes = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, null, fadeIn, stay, fadeOut); sendPacket(packetPlayOutTimes); if (subtitle != null) { subtitle = ChatColor.translateAlternateColorCodes('&', subtitle); IChatBaseComponent titleSub = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + subtitle + "\"}"); PacketPlayOutTitle packetPlayOutSubTitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.SUBTITLE, titleSub); sendPacket(packetPlayOutSubTitle); } if (title != null) { title = ChatColor.translateAlternateColorCodes('&', title); IChatBaseComponent titleMain = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + title + "\"}"); PacketPlayOutTitle packetPlayOutTitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, titleMain); sendPacket(packetPlayOutTitle); } } public BossBar sendBossBar(String text, BarColor color, BarStyle style, BarFlag flag) { BossBar bar = Bukkit.createBossBar(text, color, style, flag); bar.addPlayer(PLAYER); return bar; } @Deprecated public Hologram sendHologram(ItemStack item, Location location, String... text) { Hologram hologram = new Hologram(item, text, location); hologram.showPlayer(this); return hologram; } public void sendTabHeaderAndFooter(String header, String footer) { if (header == null) header = ""; header = ChatColor.translateAlternateColorCodes('&', header); if (footer == null) footer = ""; footer = ChatColor.translateAlternateColorCodes('&', footer); header = header.replaceAll("%player%", getDisplayName()); footer = footer.replaceAll("%player%", getDisplayName()); PLAYER.setPlayerListHeaderFooter(new TextComponent(header), new TextComponent(footer)); } /* Cloud */ public void connectToServer(String server) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF("Connect"); out.writeUTF(server); sendPluginMessage(Core.getInstance(), "BungeeCord", out.toByteArray()); } public void connectToServer(ServerType type) { Core.getCloudAPI().getOptimalServer(this, type).whenComplete((s, throwable) -> connectToServer(s)); } /* Inventory */ public boolean hasEmptyInventory() { return getInventory().firstEmpty() != -1; } /* Effects */ /** * @param location location for effect * @param effect particle effect * @param id the id * @param data the data * @param offsetX offset in x direction * @param offsetY offset in y direction * @param offsetZ offset in z direction * @param speed particle speed * @param particleCount count of showed particles * @param radius effect radius */ public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) { if (DATABASE_PLAYER.getSettings().hasEffectsEnabled()) { PLAYER.spigot().playEffect(location, effect, id, data, offsetX, offsetY, offsetZ, speed, particleCount, radius); } } @Deprecated public void playParticle(Location loc, EnumParticle ep, float f, int count) { if (DATABASE_PLAYER.getSettings().hasEffectsEnabled()) Effects.playEffectToPlayer(PLAYER, loc, ep, f, count); } /* Combat */ public void setAttackSpeed(double speed) { AttributeModifier modifier = new AttributeModifier(Core.getInstance().getName(), speed, AttributeModifier.Operation.ADD_NUMBER); getAttribute(Attribute.GENERIC_ATTACK_SPEED).addModifier(modifier); } private double getAttackSpeed() { return getAttribute(Attribute.GENERIC_ATTACK_SPEED).getValue(); } public void resetAttackSpeed() { AttributeModifier modifier = new AttributeModifier(Core.getInstance().getName(), getAttackSpeed(), AttributeModifier.Operation.ADD_NUMBER); getAttribute(Attribute.GENERIC_ATTACK_SPEED).removeModifier(modifier); AttributeInstance instance = getAttribute(Attribute.GENERIC_ATTACK_SPEED); instance.setBaseValue(16.0D); } /* Nick */ public void setNickName(String name) { if (name.length() > 16) { sendMessage("Disguised name can only be less the 16 characters."); return; } if (isNicked()) { sendMessage("You are already disguised!"); return; } if (Bukkit.getOnlinePlayers().stream().filter(p -> p.getName().equals(name)).count() != 0) { sendMessage("The name you chose is already online."); return; } nickedPlayers.put(getUniqueId(), new NickedPlayer(this, name)); setGameProfile(name, new GameProfile(getUniqueId(), name)); } private void setGameProfile(String name, GameProfile profile) { getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, getHandle())); setDisplayName(name); setPlayerListName(name); try { Field gp2 = getHandle().getClass().getSuperclass().getDeclaredField("bT"); gp2.setAccessible(true); gp2.set(getHandle(), profile); gp2.setAccessible(false); } catch (Exception e) { e.printStackTrace(); removeNickName(); return; } Core.getOnlinePlayers().stream().filter(p -> p.getUniqueId() != getUniqueId()).forEach(p -> { if (p.getDatabasePlayer().isAllowed(Rank.Admin)) return; p.sendPacket(new PacketPlayOutEntityDestroy(getEntityId())); p.sendPacket(new PacketPlayOutNamedEntitySpawn(getHandle())); if (p.canSee(this)) { p.hidePlayer(this); p.showPlayer(this); } }); //respawn sendPacket(new PacketPlayOutRespawn(getWorld().getEnvironment().getId(), getHandle().getWorld().getDifficulty(), getHandle().getWorld().getWorldData().getType(), getHandle().playerInteractManager.getGameMode())); getHandle().playerConnection.teleport(new Location(getWorld(), getHandle().locX, getHandle().locY, getHandle().locZ, getHandle().yaw, getHandle().pitch)); sendPacket(new PacketPlayOutSpawnPosition(getHandle().getWorld().getSpawn())); sendPacket(new PacketPlayOutExperience(getHandle().exp, getHandle().expTotal, getHandle().expLevel)); getHandle().updateInventory(getHandle().defaultContainer); updateScaledHealth(); sendPacket(new PacketPlayOutHeldItemSlot(getHandle().inventory.itemInHandIndex)); getHandle().updateAbilities(); for (MobEffect effect : getHandle().getEffects()) sendPacket(new PacketPlayOutEntityEffect(getHandle().getId(), effect)); if (this.gameProfile != profile) { for (CustomPlayer player : Core.getOnlinePlayers()) { if (player.getDatabasePlayer().isAllowed(Rank.Admin)) return; player.initScoreboard(); player.getDatabasePlayer().getRankAsync().whenComplete((rank, throwable) -> getScoreboard().getTeam(rank.getTeam()).addEntry(player.getDisplayName())); player.getScoreboard().getTeam(Rank.Premium.getTeam()).addEntry(getDisplayName()); } } else { for (CustomPlayer player : Core.getOnlinePlayers()) { player.initScoreboard(); getDatabasePlayer().getRankAsync().whenComplete((rank, throwable) -> player.getScoreboard().getTeam(rank.getTeam()).addEntry(getDisplayName())); player.getDatabasePlayer().getRankAsync().whenComplete((rank, throwable) -> getScoreboard().getTeam(rank.getTeam()).addEntry(player.getDisplayName())); } } } public void removeNickName() { if (isNicked()) { nickedPlayers.remove(getUniqueId()); setGameProfile(getName(), gameProfile); } } public boolean isNicked() { return nickedPlayers.containsKey(getUniqueId()); } /* Quest */ @Getter private Quest quest; /* Miscellaneous */ /** * open or close chests for player * * @param loc location, block at location must be a type of chest * @param open open or close the chest */ public void changeChestState(Location loc, boolean open) { if (!(loc.getBlock() instanceof Chest) && !(loc.getBlock() instanceof ShulkerBox) && !(loc.getBlock() instanceof EnderChest) && !(loc.getBlock() instanceof DoubleChest)) return; BlockPosition position = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); PacketPlayOutBlockAction blockActionPacket = new PacketPlayOutBlockAction(position, Block.getById(loc.getBlock().getTypeId()), 1, (open) ? 1 : 0); sendPacket(blockActionPacket); } /** * sets the amount of arrows that are in the body of the player * * @param count arrow count */ public void setArrowsInBody(int count) { getHandle().getDataWatcher().set(new DataWatcherObject<>(10, DataWatcherRegistry.b), count); } public int getArrowsInBody() { return getHandle().getDataWatcher().get(new DataWatcherObject<>(10, DataWatcherRegistry.b)); } /** * sends packets for item cooldown, items won't be disabled * * @param item item to have a cooldown * @param time time in seconds */ public void setItemCooldown(ItemStack item, int time) { sendPacket(new PacketPlayOutSetCooldown(CraftItemStack.asNMSCopy(item).getItem(), time)); } public void hideToAll() { for (CustomPlayer p : Core.getOnlinePlayers()) { p.hidePlayer(this); } } public void showToAll() { for (CustomPlayer p : Core.getOnlinePlayers()) { p.showPlayer(this); } } public void strikeLightning(Location loc) { net.minecraft.server.v1_12_R1.World nmsWorld = ((CraftWorld) loc.getWorld()).getHandle(); EntityLightning lightning = new EntityLightning(nmsWorld, loc.getX(), loc.getY(), loc.getZ(), true); sendPacket(new PacketPlayOutSpawnEntityWeather(lightning)); playSound(loc, Sound.ENTITY_LIGHTNING_IMPACT, 20.0F, 1.0F); playSound(loc, Sound.ENTITY_LIGHTNING_THUNDER, 20.0F, 1.0F); } public void setBlackScreen(int seconds) { Blackscreen.setBlack(this, seconds); } public void setStoryResourcePack() { setResourcePack("http://download1053.mediafireuserdownload.com/azvfl4fchheg/czy67lcvstrl9r5/TSF+Resource+Pack+v1.3.2.zip"); //setResourcePack("http://univento.eu/storyPack.zip"); } public void initScoreboard() { Scoreboard board = getScoreboard(); board.getTeams().forEach(Team::unregister); for (Rank rank : Rank.values()) { Team team = board.registerNewTeam(rank.getTeam()); team.setPrefix(rank.getTab()); team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS); } } public void setLabyModFeatures(HashMap list) { HashMap temp = new HashMap<>(); for (LabyMod feature : list.keySet()) temp.put(feature.name(), list.get(feature)); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); try { ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(temp); ByteBuf byteBuf = Unpooled.copiedBuffer(byteOut.toByteArray()); PacketDataSerializer packetDataSerializer = new PacketDataSerializer(byteBuf); PacketPlayOutCustomPayload packet = new PacketPlayOutCustomPayload("LABYMOD", packetDataSerializer); sendPacket(packet); } catch (IOException e) { e.printStackTrace(); } } /** * crashes the players client */ public void crashClient() { sendPacket(new PacketPlayOutExplosion(9999999999D, 9999999999D, 9999999999D, 9999999999F, new ArrayList<>(), new Vec3D(9999999999D, 9999999999D, 9999999999D))); } /* Packets */ public void sendPacket(Packet packet) { getHandle().playerConnection.sendPacket(packet); } private Field getField(Class clazz, String name) { try { Field field = clazz.getDeclaredField(name); field.setAccessible(true); return field; } catch (Exception ex) { ex.printStackTrace(); } return null; } /* Other */ public CompletableFuture getLastLocation() { CompletableFuture future = new CompletableFuture<>(); DATABASE_PLAYER.getObjectFromDatabase().whenComplete((entries, throwable) -> { JsonObject json = entries.getJsonObject("Pos"); future.complete(new Location(Bukkit.getWorld("world"), json.getDouble("X"), json.getDouble("Y"), json.getDouble("Z"), Float.parseFloat(json.getString("Yaw")), Float.parseFloat(json.getString("Pitch")))); }); return future; } public void warn(WarnReason reason, CustomPlayer warner, String proof) { DATABASE_PLAYER.warn(reason, warner.getUniqueId().toString(), proof); } public void clearPotionEffects() { for(PotionEffect potion : getActivePotionEffects()) { removePotionEffect(potion.getType()); } } }