Try new method to handle skins

This commit is contained in:
libraryaddict 2020-09-15 21:54:29 +12:00
parent c295011015
commit ebb6d2030d
2 changed files with 163 additions and 17 deletions

View File

@ -0,0 +1,153 @@
package me.libraryaddict.disguise.utilities.listeners;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalCause;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.events.UndisguiseEvent;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Created by libraryaddict on 15/09/2020.
*/
public class PlayerSkinHandler implements Listener {
@RequiredArgsConstructor
private static class PlayerSkin {
private final long firstPacketSent = System.currentTimeMillis();
@Getter
private final WeakReference<PlayerDisguise> disguise;
public boolean canRemove() {
return firstPacketSent + (DisguiseConfig.getTablistRemoveDelay() * 50) < System.currentTimeMillis();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PlayerSkin that = (PlayerSkin) o;
return getDisguise().get() == that.getDisguise().get();
}
}
@Getter
private final Cache<Player, List<PlayerSkin>> cache =
CacheBuilder.newBuilder().weakKeys().expireAfterWrite(1, TimeUnit.MINUTES).removalListener((event) -> {
if (event.getCause() != RemovalCause.EXPIRED) {
return;
}
List<PlayerSkin> skins = (List<PlayerSkin>) event.getValue();
for (PlayerSkin skin : skins) {
PlayerDisguise disguise = skin.disguise.get();
if (disguise == null) {
return;
}
doPacketRemoval((Player) event.getKey(), disguise);
}
skins.clear();
}).build();
public void addPlayerSkin(Player player, PlayerDisguise disguise) {
List<PlayerSkin> skins = getCache().getIfPresent(player);
if (skins == null) {
skins = new ArrayList<>();
}
skins.add(new PlayerSkin(new WeakReference<>(disguise)));
getCache().put(player, skins);
}
@EventHandler(priority = EventPriority.MONITOR,
ignoreCancelled = true)
private void onUndisguise(UndisguiseEvent event) {
if (!event.getDisguise().isPlayerDisguise()) {
return;
}
PlayerDisguise disguise = (PlayerDisguise) event.getDisguise();
for (Player player : DisguiseUtilities.getPerverts(disguise)) {
List<PlayerSkin> skins = getCache().getIfPresent(player);
if (skins == null) {
continue;
}
PlayerSkin skin = skins.stream().filter(s -> s.getDisguise().get() == disguise).findAny().orElse(null);
if (skin == null) {
continue;
}
doPacketRemoval(player, disguise);
if (skins.size() == 1) {
getCache().invalidate(player);
} else {
skins.remove(skin);
}
}
}
private void doPacketRemoval(Player player, PlayerDisguise disguise) {
PacketContainer packetContainer =
DisguiseUtilities.getTabPacket(disguise, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@EventHandler
public void onMove(PlayerMoveEvent event) {
List<PlayerSkin> skins = getCache().getIfPresent(event.getPlayer());
if (skins == null) {
return;
}
skins.removeIf(skin -> {
if (!skin.canRemove()) {
return false;
}
doPacketRemoval(event.getPlayer(), skin.getDisguise().get());
return true;
});
if (!skins.isEmpty()) {
return;
}
getCache().invalidate(event.getPlayer());
}
}

View File

@ -8,6 +8,7 @@ import com.comphenix.protocol.wrappers.WrappedAttribute;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.mojang.datafixers.util.Pair;
import lombok.Getter;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.*;
@ -16,12 +17,14 @@ import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.DisguiseValues;
import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.listeners.PlayerSkinHandler;
import me.libraryaddict.disguise.utilities.packets.IPacketHandler;
import me.libraryaddict.disguise.utilities.packets.LibsPackets;
import me.libraryaddict.disguise.utilities.packets.PacketsHandler;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
@ -31,7 +34,6 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import java.util.ArrayList;
@ -44,9 +46,15 @@ import java.util.UUID;
*/
public class PacketHandlerSpawn implements IPacketHandler {
private PacketsHandler packetsHandler;
@Getter
private PlayerSkinHandler skinHandler;
public PacketHandlerSpawn(PacketsHandler packetsHandler) {
this.packetsHandler = packetsHandler;
skinHandler = new PlayerSkinHandler();
Bukkit.getPluginManager().registerEvents(skinHandler, LibsDisguises.getInstance());
}
@Override
@ -193,22 +201,7 @@ public class PacketHandlerSpawn implements IPacketHandler {
if (LibsPremium.getPaidInformation() == null ||
LibsPremium.getPaidInformation().getBuildNumber().matches("#[0-9]+")) {
if (!observer.hasMetadata("ld_loggedin")) {
ArrayList<PacketContainer> toSend;
if (observer.hasMetadata("ld_tabsend") && !observer.getMetadata("ld_tabsend").isEmpty()) {
toSend = (ArrayList<PacketContainer>) observer.getMetadata("ld_tabsend").get(0).value();
} else {
toSend = new ArrayList<>();
observer.setMetadata("ld_tabsend",
new FixedMetadataValue(LibsDisguises.getInstance(), toSend));
}
toSend.add(deleteTab);
} else {
packets.addDelayedPacket(deleteTab, DisguiseConfig.getTablistRemoveDelay());
}
getSkinHandler().addPlayerSkin(observer, playerDisguise);
}
}