Push player skin fix may need good testing

This commit is contained in:
libraryaddict 2020-10-01 09:47:42 +13:00
parent 02171b60b6
commit 166658b99b
8 changed files with 260 additions and 116 deletions

View File

@ -20,6 +20,7 @@ import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.LibsPremium; import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.listeners.DisguiseListener; import me.libraryaddict.disguise.utilities.listeners.DisguiseListener;
import me.libraryaddict.disguise.utilities.listeners.PaperDisguiseListener; import me.libraryaddict.disguise.utilities.listeners.PaperDisguiseListener;
import me.libraryaddict.disguise.utilities.listeners.PlayerSkinHandler;
import me.libraryaddict.disguise.utilities.metrics.MetricsInitalizer; import me.libraryaddict.disguise.utilities.metrics.MetricsInitalizer;
import me.libraryaddict.disguise.utilities.packets.PacketsManager; import me.libraryaddict.disguise.utilities.packets.PacketsManager;
import me.libraryaddict.disguise.utilities.parser.DisguiseParser; import me.libraryaddict.disguise.utilities.parser.DisguiseParser;
@ -50,6 +51,8 @@ public class LibsDisguises extends JavaPlugin {
private boolean reloaded; private boolean reloaded;
@Getter @Getter
private final UpdateChecker updateChecker = new UpdateChecker(); private final UpdateChecker updateChecker = new UpdateChecker();
@Getter
private final PlayerSkinHandler skinHandler = new PlayerSkinHandler();
@Override @Override
public void onLoad() { public void onLoad() {
@ -139,10 +142,8 @@ public class LibsDisguises extends JavaPlugin {
getLogger().severe("!! May I have your attention please !!"); getLogger().severe("!! May I have your attention please !!");
getLogger().severe("Update your ProtocolLib! You are running " + version + getLogger().severe("Update your ProtocolLib! You are running " + version +
" but the minimum version you should be on is " + requiredProtocolLib + "!"); " but the minimum version you should be on is " + requiredProtocolLib + "!");
getLogger() getLogger().severe("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/target" +
.severe("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/target" + "/ProtocolLib" + ".jar");
"/ProtocolLib" +
".jar");
getLogger().severe("Or! Use /ld updateprotocollib - To update to the latest development build"); getLogger().severe("Or! Use /ld updateprotocollib - To update to the latest development build");
getLogger() getLogger()
.severe("This message is on repeat due to the sheer number of people who don't see this."); .severe("This message is on repeat due to the sheer number of people who don't see this.");
@ -178,6 +179,8 @@ public class LibsDisguises extends JavaPlugin {
listener = new DisguiseListener(this); listener = new DisguiseListener(this);
Bukkit.getPluginManager().registerEvents(getSkinHandler(), LibsDisguises.getInstance());
if (DisguiseUtilities.isRunningPaper()) { if (DisguiseUtilities.isRunningPaper()) {
Bukkit.getPluginManager().registerEvents(new PaperDisguiseListener(), this); Bukkit.getPluginManager().registerEvents(new PaperDisguiseListener(), this);
} }

View File

@ -242,7 +242,8 @@ public class DisguiseUtilities {
Team team = Bukkit.getScoreboardManager().getMainScoreboard().getEntryTeam(playerName); Team team = Bukkit.getScoreboardManager().getMainScoreboard().getEntryTeam(playerName);
if (team != null && (team.getColor() != ChatColor.RESET || !StringUtils.isEmpty(team.getPrefix()) || !StringUtils.isEmpty(team.getSuffix()))) { if (team != null && (team.getColor() != ChatColor.RESET || !StringUtils.isEmpty(team.getPrefix()) ||
!StringUtils.isEmpty(team.getSuffix()))) {
return team.getPrefix() + team.getColor() + playerName + team.getSuffix(); return team.getPrefix() + team.getColor() + playerName + team.getSuffix();
} }
@ -254,7 +255,8 @@ public class DisguiseUtilities {
team = Bukkit.getScoreboardManager().getMainScoreboard().getEntryTeam(player.getUniqueId().toString()); team = Bukkit.getScoreboardManager().getMainScoreboard().getEntryTeam(player.getUniqueId().toString());
if (team == null || (team.getColor() != ChatColor.RESET || StringUtils.isEmpty(team.getPrefix()) && StringUtils.isEmpty(team.getSuffix()))) { if (team == null || (team.getColor() != ChatColor.RESET ||
StringUtils.isEmpty(team.getPrefix()) && StringUtils.isEmpty(team.getSuffix()))) {
String name = player.getDisplayName(); String name = player.getDisplayName();
if (name.equals(playerName)) { if (name.equals(playerName)) {
@ -2568,13 +2570,35 @@ public class DisguiseUtilities {
transformed.addPacket(packet); transformed.addPacket(packet);
} }
LibsPackets newPackets = new LibsPackets(disguise);
for (PacketContainer p : transformed.getPackets()) { for (PacketContainer p : transformed.getPackets()) {
p = p.deepClone();
p.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); p.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
newPackets.addPacket(p);
}
for (Map.Entry<Integer, ArrayList<PacketContainer>> entry : transformed.getDelayedPacketsMap().entrySet()) {
for (PacketContainer newPacket : entry.getValue()) {
if (newPacket.getType() != Server.PLAYER_INFO && newPacket.getType() != Server.ENTITY_DESTROY &&
newPacket.getIntegers().read(0) == player.getEntityId()) {
newPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
}
newPackets.addDelayedPacket(newPacket, entry.getKey());
}
}
if (disguise.isPlayerDisguise()) {
LibsDisguises.getInstance().getSkinHandler()
.handlePackets(player, (PlayerDisguise) disguise, newPackets);
}
for (PacketContainer p : newPackets.getPackets()) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, p, false); ProtocolLibrary.getProtocolManager().sendServerPacket(player, p, false);
} }
transformed.sendDelayed(player); newPackets.sendDelayed(player);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -1,5 +1,7 @@
package me.libraryaddict.disguise.utilities.listeners; package me.libraryaddict.disguise.utilities.listeners;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.EnumWrappers;
@ -8,20 +10,26 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalCause; import com.google.common.cache.RemovalCause;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.Setter;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.events.UndisguiseEvent; import me.libraryaddict.disguise.events.UndisguiseEvent;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.packets.LibsPackets;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@ -29,13 +37,22 @@ import java.util.concurrent.TimeUnit;
*/ */
public class PlayerSkinHandler implements Listener { public class PlayerSkinHandler implements Listener {
@RequiredArgsConstructor @RequiredArgsConstructor
private static class PlayerSkin { public static class PlayerSkin {
private final long firstPacketSent = System.currentTimeMillis(); private final long firstPacketSent = System.currentTimeMillis();
@Getter @Getter
private final WeakReference<PlayerDisguise> disguise; private final WeakReference<PlayerDisguise> disguise;
@Getter
private final HashMap<Integer, ArrayList<PacketContainer>> sleptPackets = new HashMap<>();
@Getter
@Setter
private boolean doTabList = true;
@Getter
@Setter
private boolean sleepPackets;
public boolean canRemove() { public boolean canRemove(boolean onMoved) {
return firstPacketSent + (DisguiseConfig.getTablistRemoveDelay() * 50) < System.currentTimeMillis(); return firstPacketSent + (DisguiseConfig.getTablistRemoveDelay() * 50) +
(onMoved ? 0 : TimeUnit.SECONDS.toMillis(5)) < System.currentTimeMillis();
} }
@Override @Override
@ -61,20 +78,14 @@ public class PlayerSkinHandler implements Listener {
List<PlayerSkin> skins = (List<PlayerSkin>) event.getValue(); List<PlayerSkin> skins = (List<PlayerSkin>) event.getValue();
for (PlayerSkin skin : skins) { for (PlayerSkin skin : skins) {
PlayerDisguise disguise = skin.disguise.get(); doPacketRemoval((Player) event.getKey(), skin);
if (disguise == null) {
return;
}
doPacketRemoval((Player) event.getKey(), disguise);
} }
skins.clear(); skins.clear();
}).build(); }).build();
public void addPlayerSkin(Player player, PlayerDisguise disguise) { public PlayerSkin addPlayerSkin(Player player, PlayerDisguise disguise) {
tryProcess(player); tryProcess(player, false);
List<PlayerSkin> skins = getCache().getIfPresent(player); List<PlayerSkin> skins = getCache().getIfPresent(player);
@ -82,8 +93,49 @@ public class PlayerSkinHandler implements Listener {
skins = new ArrayList<>(); skins = new ArrayList<>();
} }
skins.add(new PlayerSkin(new WeakReference<>(disguise))); PlayerSkin toReturn = new PlayerSkin(new WeakReference<>(disguise));
skins.add(toReturn);
getCache().put(player, skins); getCache().put(player, skins);
return toReturn;
}
public void handlePackets(Player player, PlayerDisguise disguise, LibsPackets packets) {
List<PlayerSkin> skins = getCache().getIfPresent(player);
if (skins == null) {
return;
}
PlayerSkin skin = skins.stream().filter(s -> s.getDisguise().get() == disguise).findAny().orElse(null);
if (skin == null || !skin.isSleepPackets()) {
return;
}
packets.getPackets().removeIf(packet -> isRemove(skin, packet));
packets.getDelayedPacketsMap().entrySet().removeIf(entry -> {
entry.getValue().removeIf(packet -> isRemove(skin, packet));
return entry.getValue().isEmpty();
});
}
private boolean isRemove(PlayerSkin skin, PacketContainer packetContainer) {
PacketType type = packetContainer.getType();
if (type != Server.ENTITY_EQUIPMENT && type != Server.ENTITY_METADATA) {
return false;
}
// Only do equip atm
if (type == Server.ENTITY_EQUIPMENT) {
skin.getSleptPackets().computeIfAbsent(0, (a) -> new ArrayList<>()).add(packetContainer);
}
return true;
} }
@EventHandler(priority = EventPriority.MONITOR, @EventHandler(priority = EventPriority.MONITOR,
@ -108,7 +160,7 @@ public class PlayerSkinHandler implements Listener {
continue; continue;
} }
doPacketRemoval(player, disguise); doPacketRemoval(player, skin);
if (skins.size() == 1) { if (skins.size() == 1) {
getCache().invalidate(player); getCache().invalidate(player);
@ -118,40 +170,69 @@ public class PlayerSkinHandler implements Listener {
} }
} }
private void doPacketRemoval(Player player, PlayerDisguise disguise) { private void doPacketRemoval(Player player, PlayerSkin skin) {
PlayerDisguise disguise = skin.getDisguise().get();
if (disguise == null) { if (disguise == null) {
return; return;
} }
PacketContainer packetContainer =
DisguiseUtilities.getTabPacket(disguise, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
try { try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer); for (Map.Entry<Integer, ArrayList<PacketContainer>> entry : skin.getSleptPackets().entrySet()) {
if (entry.getKey() == 0) {
for (PacketContainer packet : entry.getValue()) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
}
} else {
new BukkitRunnable() {
@Override
public void run() {
try {
if (!disguise.isDisguiseInUse()) {
return;
}
for (PacketContainer packet : entry.getValue()) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}.runTaskLater(LibsDisguises.getInstance(), entry.getKey());
}
}
if (skin.isDoTabList()) {
PacketContainer packetContainer =
DisguiseUtilities.getTabPacket(disguise, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer);
}
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private void tryProcess(Player player) { private void tryProcess(Player player, boolean onMove) {
List<PlayerSkin> skins = getCache().getIfPresent(player); List<PlayerSkin> skins = getCache().getIfPresent(player);
if (skins == null) { if (skins == null) {
return; return;
} }
ArrayList<PlayerDisguise> removed = new ArrayList<>(); ArrayList<PlayerSkin> removed = new ArrayList<>();
skins.removeIf(skin -> { skins.removeIf(skin -> {
if (!skin.canRemove()) { if (!skin.canRemove(onMove)) {
return false; return false;
} }
removed.add(skin.getDisguise().get()); removed.add(skin);
return true; return true;
}); });
removed.forEach(disguise -> doPacketRemoval(player, disguise)); removed.forEach(skin -> doPacketRemoval(player, skin));
if (!skins.isEmpty()) { if (!skins.isEmpty()) {
return; return;
@ -162,6 +243,6 @@ public class PlayerSkinHandler implements Listener {
@EventHandler @EventHandler
public void onMove(PlayerMoveEvent event) { public void onMove(PlayerMoveEvent event) {
tryProcess(event.getPlayer()); tryProcess(event.getPlayer(), true);
} }
} }

View File

@ -5,6 +5,9 @@ import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
@ -21,23 +24,14 @@ import java.util.*;
/** /**
* Created by libraryaddict on 3/01/2019. * Created by libraryaddict on 3/01/2019.
*/ */
@Getter
@RequiredArgsConstructor
public class LibsPackets { public class LibsPackets {
private ArrayList<PacketContainer> packets = new ArrayList<>(); private final ArrayList<PacketContainer> packets = new ArrayList<>();
private HashMap<Integer, ArrayList<PacketContainer>> delayedPackets = new HashMap<>(); private final HashMap<Integer, ArrayList<PacketContainer>> delayedPacketsMap = new HashMap<>();
private Disguise disguise; private final Disguise disguise;
private boolean doNothing; @Setter
private boolean unhandled;
public LibsPackets(Disguise disguise) {
this.disguise = disguise;
}
public void setUnhandled() {
doNothing = true;
}
public boolean isUnhandled() {
return doNothing;
}
public Disguise getDisguise() { public Disguise getDisguise() {
return disguise; return disguise;
@ -56,24 +50,21 @@ public class LibsPackets {
} }
public void addDelayedPacket(PacketContainer packet, int ticksDelayed) { public void addDelayedPacket(PacketContainer packet, int ticksDelayed) {
if (!delayedPackets.containsKey(ticksDelayed)) if (!delayedPacketsMap.containsKey(ticksDelayed)) {
delayedPackets.put(ticksDelayed, new ArrayList<>()); delayedPacketsMap.put(ticksDelayed, new ArrayList<>());
}
delayedPackets.get(ticksDelayed).add(packet); delayedPacketsMap.get(ticksDelayed).add(packet);
} }
public ArrayList<PacketContainer> getPackets() { public ArrayList<PacketContainer> getPackets() {
return packets; return packets;
} }
public Collection<ArrayList<PacketContainer>> getDelayedPackets() {
return delayedPackets.values();
}
public void sendDelayed(final Player observer) { public void sendDelayed(final Player observer) {
for (Map.Entry<Integer, ArrayList<PacketContainer>> entry : delayedPackets.entrySet()) { for (Map.Entry<Integer, ArrayList<PacketContainer>> entry : getDelayedPacketsMap().entrySet()) {
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> { Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> {
if (!disguise.isDisguiseInUse()) { if (!getDisguise().isDisguiseInUse()) {
ArrayList<PacketContainer> packets = entry.getValue(); ArrayList<PacketContainer> packets = entry.getValue();
if (packets.stream().noneMatch(p -> p.getType() == PacketType.Play.Server.PLAYER_INFO)) { if (packets.stream().noneMatch(p -> p.getType() == PacketType.Play.Server.PLAYER_INFO)) {
@ -87,8 +78,7 @@ public class LibsPackets {
for (PacketContainer packet : entry.getValue()) { for (PacketContainer packet : entry.getValue()) {
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false); ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false);
} }
} } catch (InvocationTargetException e) {
catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
}, entry.getKey()); }, entry.getKey());
@ -97,11 +87,11 @@ public class LibsPackets {
private PacketContainer createPacket(EquipmentSlot slot) { private PacketContainer createPacket(EquipmentSlot slot) {
// Get what the disguise wants to show for its armor // Get what the disguise wants to show for its armor
ItemStack itemToSend = disguise.getWatcher().getItemStack(slot); ItemStack itemToSend = getDisguise().getWatcher().getItemStack(slot);
// If the disguise armor isn't visible // If the disguise armor isn't visible
if (itemToSend == null) { if (itemToSend == null) {
itemToSend = ReflectionManager.getEquipment(slot, disguise.getEntity()); itemToSend = ReflectionManager.getEquipment(slot, getDisguise().getEntity());
// If natural armor isn't sent either // If natural armor isn't sent either
if (itemToSend == null || itemToSend.getType() == Material.AIR) { if (itemToSend == null || itemToSend.getType() == Material.AIR) {
@ -115,7 +105,7 @@ public class LibsPackets {
StructureModifier<Object> mods = packet.getModifier(); StructureModifier<Object> mods = packet.getModifier();
mods.write(0, disguise.getEntity().getEntityId()); mods.write(0, getDisguise().getEntity().getEntityId());
if (NmsVersion.v1_16.isSupported()) { if (NmsVersion.v1_16.isSupported()) {
List<Pair<Object, Object>> list = new ArrayList<>(); List<Pair<Object, Object>> list = new ArrayList<>();

View File

@ -72,7 +72,7 @@ public class PacketsHandler {
} }
} }
packets.setUnhandled(); packets.setUnhandled(true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -8,7 +8,6 @@ import com.comphenix.protocol.wrappers.WrappedAttribute;
import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import lombok.Getter;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.*; import me.libraryaddict.disguise.disguisetypes.*;
@ -24,7 +23,6 @@ import me.libraryaddict.disguise.utilities.packets.PacketsHandler;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.bukkit.Art; import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
@ -46,15 +44,9 @@ import java.util.UUID;
*/ */
public class PacketHandlerSpawn implements IPacketHandler { public class PacketHandlerSpawn implements IPacketHandler {
private PacketsHandler packetsHandler; private PacketsHandler packetsHandler;
@Getter
private PlayerSkinHandler skinHandler;
public PacketHandlerSpawn(PacketsHandler packetsHandler) { public PacketHandlerSpawn(PacketsHandler packetsHandler) {
this.packetsHandler = packetsHandler; this.packetsHandler = packetsHandler;
skinHandler = new PlayerSkinHandler();
Bukkit.getPluginManager().registerEvents(skinHandler, LibsDisguises.getInstance());
} }
@Override @Override
@ -181,6 +173,7 @@ public class PacketHandlerSpawn implements IPacketHandler {
playerDisguise.getGameProfile()); playerDisguise.getGameProfile());
int entityId = disguisedEntity.getEntityId(); int entityId = disguisedEntity.getEntityId();
PlayerSkinHandler.PlayerSkin skin;
if (!playerDisguise.isDisplayedInTab() || !playerDisguise.isNameVisible()) { if (!playerDisguise.isDisplayedInTab() || !playerDisguise.isNameVisible()) {
// Send player info along with the disguise // Send player info along with the disguise
@ -199,10 +192,16 @@ public class PacketHandlerSpawn implements IPacketHandler {
PacketContainer deleteTab = sendTab.shallowClone(); PacketContainer deleteTab = sendTab.shallowClone();
deleteTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(4)); deleteTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(4));
if (LibsPremium.getPaidInformation() == null || skin = LibsDisguises.getInstance().getSkinHandler().addPlayerSkin(observer, playerDisguise);
LibsPremium.getPaidInformation().getBuildNumber().matches("#[0-9]+")) {
getSkinHandler().addPlayerSkin(observer, playerDisguise); if (LibsPremium.getPaidInformation() != null &&
!LibsPremium.getPaidInformation().getBuildNumber().matches("#[0-9]+")) {
skin.getSleptPackets().computeIfAbsent(0, (a) -> new ArrayList<>())
.add(new PacketContainer(PacketType.Play.Server.HELD_ITEM_SLOT));
} }
} else {
skin = LibsDisguises.getInstance().getSkinHandler().addPlayerSkin(observer, playerDisguise);
skin.setDoTabList(false);
} }
// Spawn the player // Spawn the player
@ -211,9 +210,15 @@ public class PacketHandlerSpawn implements IPacketHandler {
spawnPlayer.getIntegers().write(0, entityId); // Id spawnPlayer.getIntegers().write(0, entityId); // Id
spawnPlayer.getModifier().write(1, spawnProfile.getUUID()); spawnPlayer.getModifier().write(1, spawnProfile.getUUID());
Location spawnAt = disguisedEntity.getLocation(); boolean spawnFarAway = observer == disguisedEntity ||
observer.getLocation().distanceSquared(disguisedEntity.getLocation()) >
observer.getLocation().add(observer.getLocation().getDirection())
.distanceSquared(disguisedEntity.getLocation());
boolean selfDisguise = observer == disguisedEntity; skin.setSleepPackets(!spawnFarAway);
Location spawnAt = spawnFarAway ? disguisedEntity.getLocation() :
observer.getLocation().add(observer.getLocation().getDirection().normalize().multiply(50));
// Spawn him in front of the observer // Spawn him in front of the observer
StructureModifier<Double> doubles = spawnPlayer.getDoubles(); StructureModifier<Double> doubles = spawnPlayer.getDoubles();
@ -227,18 +232,49 @@ public class PacketHandlerSpawn implements IPacketHandler {
packets.addPacket(spawnPlayer); packets.addPacket(spawnPlayer);
WrappedDataWatcher newWatcher = DisguiseUtilities WrappedDataWatcher dataWatcher = DisguiseUtilities
.createSanitizedDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), .createSanitizedDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity),
disguise.getWatcher()); disguise.getWatcher());
WrappedDataWatcher toSend = dataWatcher;
if (!spawnFarAway) {
toSend = new WrappedDataWatcher();
WrappedDataWatcher.WrappedDataWatcherObject obj =
ReflectionManager.createDataWatcherObject(MetaIndex.ENTITY_META, (byte) 32);
// Set invis
toSend.setObject(obj, (byte) 32);
}
if (NmsVersion.v1_15.isSupported()) { if (NmsVersion.v1_15.isSupported()) {
PacketContainer metaPacket = ProtocolLibrary.getProtocolManager() PacketContainer metaPacket = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, entityId, newWatcher, true) .createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, entityId, toSend, true)
.createPacket(entityId, newWatcher, true); .createPacket(entityId, toSend, true);
packets.addPacket(metaPacket); packets.addPacket(metaPacket);
} else { } else {
spawnPlayer.getDataWatcherModifier().write(0, newWatcher); spawnPlayer.getDataWatcherModifier().write(0, toSend);
}
if (!spawnFarAway) {
PacketContainer metaPacket = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, entityId, dataWatcher, true)
.createPacket(entityId, dataWatcher, true);
PacketContainer teleport = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
StructureModifier<Object> mods = teleport.getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, loc.getX());
mods.write(2, loc.getY());
mods.write(3, loc.getZ());
mods.write(4, yaw);
mods.write(5, pitch);
skin.getSleptPackets().computeIfAbsent(0, (a) -> new ArrayList<>()).add(teleport);
skin.getSleptPackets().computeIfAbsent(2, (a) -> new ArrayList<>()).add(metaPacket);
} }
} else if (disguise.isMobDisguise() || disguise.getType() == DisguiseType.ARMOR_STAND) { } else if (disguise.isMobDisguise() || disguise.getType() == DisguiseType.ARMOR_STAND) {
Vector vec = disguisedEntity.getVelocity(); Vector vec = disguisedEntity.getVelocity();

View File

@ -9,6 +9,7 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.packets.LibsPackets; import me.libraryaddict.disguise.utilities.packets.LibsPackets;
import me.libraryaddict.disguise.utilities.packets.PacketsManager; import me.libraryaddict.disguise.utilities.packets.PacketsManager;
@ -50,6 +51,11 @@ public class PacketListenerMain extends PacketAdapter {
try { try {
packets = PacketsManager.getPacketsHandler() packets = PacketsManager.getPacketsHandler()
.transformPacket(event.getPacket(), disguise, observer, disguise.getEntity()); .transformPacket(event.getPacket(), disguise, observer, disguise.getEntity());
if (disguise.isPlayerDisguise()) {
LibsDisguises.getInstance().getSkinHandler()
.handlePackets(observer, (PlayerDisguise) disguise, packets);
}
} }
catch (Throwable ex) { catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();

View File

@ -13,16 +13,19 @@ import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.MetaIndex; import me.libraryaddict.disguise.disguisetypes.MetaIndex;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.LibsPremium; import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.packets.LibsPackets; import me.libraryaddict.disguise.utilities.packets.LibsPackets;
import me.libraryaddict.disguise.utilities.packets.PacketsManager; import me.libraryaddict.disguise.utilities.packets.PacketsManager;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
public class PacketListenerViewSelfDisguise extends PacketAdapter { public class PacketListenerViewSelfDisguise extends PacketAdapter {
public PacketListenerViewSelfDisguise(LibsDisguises plugin) { public PacketListenerViewSelfDisguise(LibsDisguises plugin) {
@ -53,14 +56,6 @@ public class PacketListenerViewSelfDisguise extends PacketAdapter {
} }
if (!DisguiseAPI.isSelfDisguised(observer)) { if (!DisguiseAPI.isSelfDisguised(observer)) {
if (event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) {
Disguise disguise = DisguiseAPI.getDisguise(observer, observer);
if (disguise != null && DisguiseUtilities.getSelfDisguised().contains(observer.getUniqueId())) {
event.setCancelled(true);
}
}
return; return;
} }
@ -78,38 +73,45 @@ public class PacketListenerViewSelfDisguise extends PacketAdapter {
transformed.addPacket(packet); transformed.addPacket(packet);
} }
LibsPackets selfTransformed = new LibsPackets(disguise);
for (PacketContainer newPacket : transformed.getPackets()) { for (PacketContainer newPacket : transformed.getPackets()) {
if (newPacket.getType() != Server.PLAYER_INFO && newPacket.getType() != Server.ENTITY_DESTROY && if (newPacket.getType() != Server.PLAYER_INFO && newPacket.getType() != Server.ENTITY_DESTROY &&
newPacket.getIntegers().read(0) == observer.getEntityId()) { newPacket.getIntegers().read(0) == observer.getEntityId()) {
newPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
}
selfTransformed.addPacket(newPacket);
}
for (Map.Entry<Integer, ArrayList<PacketContainer>> entry : transformed.getDelayedPacketsMap().entrySet()) {
for (PacketContainer newPacket : entry.getValue()) {
if (newPacket == packet) { if (newPacket == packet) {
newPacket = newPacket.shallowClone(); newPacket = newPacket.shallowClone();
} }
newPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); if (newPacket.getType() != Server.PLAYER_INFO && newPacket.getType() != Server.ENTITY_DESTROY) {
} newPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
}
try { selfTransformed.addDelayedPacket(newPacket, entry.getKey());
}
}
if (disguise.isPlayerDisguise()) {
LibsDisguises.getInstance().getSkinHandler()
.handlePackets(observer, (PlayerDisguise) disguise, selfTransformed);
}
try {
for (PacketContainer newPacket : selfTransformed.getPackets()) {
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, newPacket, false); ProtocolLibrary.getProtocolManager().sendServerPacket(observer, newPacket, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
} }
} catch (InvocationTargetException e) {
e.printStackTrace();
} }
for (ArrayList<PacketContainer> packets : transformed.getDelayedPackets()) { selfTransformed.sendDelayed(observer);
for (PacketContainer newPacket : packets) {
if (newPacket.getType() == Server.PLAYER_INFO || newPacket.getType() == Server.ENTITY_DESTROY) {
continue;
}
if (newPacket.equals(packet)) {
newPacket = newPacket.shallowClone();
}
newPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
}
}
transformed.sendDelayed(observer);
if (event.getPacketType() == Server.ENTITY_METADATA) { if (event.getPacketType() == Server.ENTITY_METADATA) {
if (!LibsPremium.getPluginInformation().isPremium() || LibsPremium.getPaidInformation() != null || if (!LibsPremium.getPluginInformation().isPremium() || LibsPremium.getPaidInformation() != null ||
@ -118,14 +120,16 @@ public class PacketListenerViewSelfDisguise extends PacketAdapter {
} }
for (WrappedWatchableObject watch : packet.getWatchableCollectionModifier().read(0)) { for (WrappedWatchableObject watch : packet.getWatchableCollectionModifier().read(0)) {
if (watch.getIndex() == 0) { if (watch.getIndex() != 0) {
byte b = (byte) watch.getValue(); continue;
// Add invisibility, remove glowing
byte a = (byte) ((b | 1 << 5) & ~(1 << 6));
watch.setValue(a);
} }
byte b = (byte) watch.getValue();
// Add invisibility, remove glowing
byte a = (byte) ((b | 1 << 5) & ~(1 << 6));
watch.setValue(a);
} }
} else if (event.getPacketType() == Server.NAMED_ENTITY_SPAWN) { } else if (event.getPacketType() == Server.NAMED_ENTITY_SPAWN) {
event.setCancelled(true); event.setCancelled(true);