Added a slew of options to disable packets for performance gains

This commit is contained in:
libraryaddict 2014-05-23 08:14:46 +12:00
parent ecae8b3400
commit 72d07e7f62
9 changed files with 273 additions and 67 deletions

View File

@ -61,6 +61,34 @@ BlownDisguiseMessage: '&cYour disguise was blown!'
# These disguises, as normal will not persist after a server restart. # These disguises, as normal will not persist after a server restart.
# There is also no EntityDeath option as entities do not revive after death. # There is also no EntityDeath option as entities do not revive after death.
KeepDisguises: KeepDisguises:
EntityDespawn: false
PlayerDeath: false PlayerDeath: false
PlayerLogout: false PlayerLogout: false
EntityDespawn: false
# This here is a option to turn off misc disguises.
# This means you can not have a living entity disguise as a non-living entity.
# This disables the Attributes packet, Non-living entities can still disguise as other non-living
MiscDisguisesForLiving: true
# This will help performance, especially with CPU
# Due to safety reasons, self disguises can never have their packets disabled.
PacketsEnabled:
# This disables the animation packet. If a disguised entity sends a animation packet and they are using a non-living disguise. People will crash.
# Disabling this also means that if a player disguised as a non-player leaves a bug. People will crash
Animation: true
# Disabling this means that you can't use the setSleeping option on a player disguise. Also you will crash anyone watching when you try to sleep in a bed
Bed: true
# This disguises the collect packet. If a living entity disguised as a non-living entity picks up a item. People will crash. This fixes it
# This also fixes people crashing if a item disguised as a sleeping player is picked up - Only true if Bed is enabled as well
Collect: true
# This disables a fix for when a disguised entity wearing armor dies, if the disguise can wear armor. It drops unpickupable items to anyone watching.
EntityStatus: true
# Entity enquipment is the packets that are sent to ensure that a disguise has or doesn't have armor, and their held item.
# Disabling this means that any disguises which can wear armor or hold items will show the armor/held item that the disguised is wearing.
Enquipment: true
# Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up
Movement: true
# Disable this if you don't mind crashing everytime you see someone riding something disguised as a non-living entity
Riding: true
# When disguised as a wither skull, it sends a look packet every tick so that the wither skull is facing the right way.
WitherSkull: true

View File

@ -3,6 +3,8 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>LibsDisguises</groupId> <groupId>LibsDisguises</groupId>
<artifactId>LibsDisguises</artifactId> <artifactId>LibsDisguises</artifactId>
<version>8.2.0-SNAPSHOT</version>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
<defaultGoal>clean package</defaultGoal> <defaultGoal>clean package</defaultGoal>
@ -84,7 +86,6 @@
<version>3.1.0</version> <version>3.1.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
<version>8.2.0-SNAPSHOT</version>
<distributionManagement> <distributionManagement>
<repository> <repository>

View File

@ -3,34 +3,63 @@ package me.libraryaddict.disguise;
import me.libraryaddict.disguise.utilities.PacketsManager; import me.libraryaddict.disguise.utilities.PacketsManager;
public class DisguiseConfig { public class DisguiseConfig {
private static boolean animationEnabled;
private static boolean bedEnabled;
private static boolean blowDisguisesOnAttack; private static boolean blowDisguisesOnAttack;
private static boolean collectEnabled;
private static String disguiseBlownMessage; private static String disguiseBlownMessage;
private static boolean enquipmentEnabled;
private static boolean entityAnimationsAdded; private static boolean entityAnimationsAdded;
private static boolean entityStatusEnabled;
private static boolean hearSelfDisguise; private static boolean hearSelfDisguise;
private static boolean hidingArmor; private static boolean hidingArmor;
private static boolean hidingHeldItem; private static boolean hidingHeldItem;
private static boolean keepDisguiseEntityDespawn; private static boolean keepDisguiseEntityDespawn;
private static boolean keepDisguisePlayerDeath; private static boolean keepDisguisePlayerDeath;
private static boolean keepDisguisePlayerLogout; private static boolean keepDisguisePlayerLogout;
private static boolean miscDisguisesForLivingEnabled;
private static boolean modifyBoundingBox; private static boolean modifyBoundingBox;
private static boolean movementEnabled;
private static boolean removeUnseenDisguises; private static boolean removeUnseenDisguises;
private static boolean ridingEnabled;
private static boolean sendVelocity; private static boolean sendVelocity;
private static boolean showNameAboveHead; private static boolean showNameAboveHead;
private static boolean showNameAboveHeadAlwaysVisible; private static boolean showNameAboveHeadAlwaysVisible;
private static boolean targetDisguises; private static boolean targetDisguises;
private static boolean witherSkullEnabled;
public static String getDisguiseBlownMessage() { public static String getDisguiseBlownMessage() {
return disguiseBlownMessage; return disguiseBlownMessage;
} }
public static boolean isAnimationPacketsEnabled() {
return animationEnabled;
}
public static boolean isBedPacketsEnabled() {
return bedEnabled;
}
public static boolean isCollectPacketsEnabled() {
return collectEnabled;
}
public static boolean isDisguiseBlownOnAttack() { public static boolean isDisguiseBlownOnAttack() {
return blowDisguisesOnAttack; return blowDisguisesOnAttack;
} }
public static boolean isEnquipmentPacketsEnabled() {
return enquipmentEnabled;
}
public static boolean isEntityAnimationsAdded() { public static boolean isEntityAnimationsAdded() {
return entityAnimationsAdded; return entityAnimationsAdded;
} }
public static boolean isEntityStatusPacketsEnabled() {
return entityStatusEnabled;
}
/** /**
* Is the plugin modifying the inventory packets so that players when self disguised, do not see their armor floating around * Is the plugin modifying the inventory packets so that players when self disguised, do not see their armor floating around
*/ */
@ -57,6 +86,10 @@ public class DisguiseConfig {
return keepDisguisePlayerLogout; return keepDisguisePlayerLogout;
} }
public static boolean isMiscDisguisesForLivingEnabled() {
return miscDisguisesForLivingEnabled;
}
public static boolean isModifyBoundingBox() { public static boolean isModifyBoundingBox() {
return modifyBoundingBox; return modifyBoundingBox;
} }
@ -65,6 +98,10 @@ public class DisguiseConfig {
return targetDisguises; return targetDisguises;
} }
public static boolean isMovementPacketsEnabled() {
return movementEnabled;
}
public static boolean isNameAboveHeadAlwaysVisible() { public static boolean isNameAboveHeadAlwaysVisible() {
return showNameAboveHeadAlwaysVisible; return showNameAboveHeadAlwaysVisible;
} }
@ -73,6 +110,10 @@ public class DisguiseConfig {
return showNameAboveHead; return showNameAboveHead;
} }
public static boolean isRidingPacketsEnabled() {
return ridingEnabled;
}
public static boolean isSelfDisguisesSoundsReplaced() { public static boolean isSelfDisguisesSoundsReplaced() {
return hearSelfDisguise; return hearSelfDisguise;
} }
@ -102,10 +143,35 @@ public class DisguiseConfig {
return PacketsManager.isViewDisguisesListenerEnabled(); return PacketsManager.isViewDisguisesListenerEnabled();
} }
public static boolean isWitherSkullPacketsEnabled() {
return witherSkullEnabled;
}
public static void setAddEntityAnimations(boolean isEntityAnimationsAdded) { public static void setAddEntityAnimations(boolean isEntityAnimationsAdded) {
entityAnimationsAdded = isEntityAnimationsAdded; entityAnimationsAdded = isEntityAnimationsAdded;
} }
public static void setAnimationPacketsEnabled(boolean enabled) {
if (enabled != isAnimationPacketsEnabled()) {
animationEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
public static void setBedPacketsEnabled(boolean enabled) {
if (enabled != isBedPacketsEnabled()) {
bedEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
public static void setCollectPacketsEnabled(boolean enabled) {
if (enabled != isCollectPacketsEnabled()) {
collectEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
public static void setDisguiseBlownMessage(String newMessage) { public static void setDisguiseBlownMessage(String newMessage) {
disguiseBlownMessage = newMessage; disguiseBlownMessage = newMessage;
} }
@ -114,6 +180,20 @@ public class DisguiseConfig {
blowDisguisesOnAttack = blowDisguise; blowDisguisesOnAttack = blowDisguise;
} }
public static void setEnquipmentPacketsEnabled(boolean enabled) {
if (enabled != isEnquipmentPacketsEnabled()) {
enquipmentEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
public static void setEntityStatusPacketsEnabled(boolean enabled) {
if (enabled != isEntityStatusPacketsEnabled()) {
entityStatusEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
/** /**
* Can players hear their own disguises * Can players hear their own disguises
*/ */
@ -155,6 +235,13 @@ public class DisguiseConfig {
keepDisguisePlayerLogout = keepDisguise; keepDisguisePlayerLogout = keepDisguise;
} }
public static void setMiscDisguisesForLivingEnabled(boolean enabled) {
if (enabled != isMiscDisguisesForLivingEnabled()) {
miscDisguisesForLivingEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
public static void setModifyBoundingBox(boolean modifyBounding) { public static void setModifyBoundingBox(boolean modifyBounding) {
modifyBoundingBox = modifyBounding; modifyBoundingBox = modifyBounding;
} }
@ -163,6 +250,13 @@ public class DisguiseConfig {
targetDisguises = ignore; targetDisguises = ignore;
} }
public static void setMovementPacketsEnabled(boolean enabled) {
if (enabled != isMovementPacketsEnabled()) {
movementEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) { public static void setNameAboveHeadAlwaysVisible(boolean alwaysVisible) {
showNameAboveHeadAlwaysVisible = alwaysVisible; showNameAboveHeadAlwaysVisible = alwaysVisible;
} }
@ -171,6 +265,13 @@ public class DisguiseConfig {
showNameAboveHead = showNames; showNameAboveHead = showNames;
} }
public static void setRidingPacketsEnabled(boolean enabled) {
if (enabled != isRidingPacketsEnabled()) {
ridingEnabled = enabled;
PacketsManager.setupMainPacketsListener();
}
}
/** /**
* Set if the disguises play sounds when hurt * Set if the disguises play sounds when hurt
*/ */
@ -193,6 +294,10 @@ public class DisguiseConfig {
PacketsManager.setViewDisguisesListener(seeOwnDisguise); PacketsManager.setViewDisguisesListener(seeOwnDisguise);
} }
public static void setWitherSkullPacketsEnabled(boolean enabled) {
witherSkullEnabled = enabled;
}
private DisguiseConfig() { private DisguiseConfig() {
} }

View File

@ -23,6 +23,7 @@ import me.libraryaddict.disguise.utilities.DisguiseValues;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Ageable; import org.bukkit.entity.Ageable;
@ -46,14 +47,16 @@ public class LibsDisguises extends JavaPlugin {
stream = getClassLoader().getResource("config.yml").openStream(); stream = getClassLoader().getResource("config.yml").openStream();
YamlConfiguration internalConfig = YamlConfiguration.loadConfiguration(stream); YamlConfiguration internalConfig = YamlConfiguration.loadConfiguration(stream);
for (String option : internalConfig.getKeys(false)) { for (String option : internalConfig.getKeys(false)) {
if (!config.contains(option)) {
if (internalConfig.isConfigurationSection(option)) { if (internalConfig.isConfigurationSection(option)) {
for (String secondOption : internalConfig.getConfigurationSection(option).getKeys(false)) { ConfigurationSection section = internalConfig.getConfigurationSection(option);
config.set(option, getConfig().get(option + "." + secondOption)); for (String secondOption : section.getKeys(false)) {
if (!config.contains(secondOption)) {
config.set(option + "." + secondOption, section.get(secondOption));
needToSaveConfig = true;
} }
} else { }
} else if (!config.contains(option)) {
config.set(option, getConfig().get(option)); config.set(option, getConfig().get(option));
}
needToSaveConfig = true; needToSaveConfig = true;
} }
} }
@ -94,6 +97,15 @@ public class LibsDisguises extends JavaPlugin {
DisguiseConfig.setKeepDisguiseOnPlayerDeath(getConfig().getBoolean("KeepDisguises.PlayerDeath")); DisguiseConfig.setKeepDisguiseOnPlayerDeath(getConfig().getBoolean("KeepDisguises.PlayerDeath"));
DisguiseConfig.setKeepDisguiseOnPlayerLogout(getConfig().getBoolean("KeepDisguises.PlayerLogout")); DisguiseConfig.setKeepDisguiseOnPlayerLogout(getConfig().getBoolean("KeepDisguises.PlayerLogout"));
DisguiseConfig.setKeepDisguiseOnEntityDespawn(getConfig().getBoolean("KeepDisguises.EntityDespawn")); DisguiseConfig.setKeepDisguiseOnEntityDespawn(getConfig().getBoolean("KeepDisguises.EntityDespawn"));
DisguiseConfig.setMiscDisguisesForLivingEnabled(getConfig().getBoolean("MiscDisguisesForLiving"));
DisguiseConfig.setMovementPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Movement"));
DisguiseConfig.setWitherSkullPacketsEnabled(getConfig().getBoolean("PacketsEnabled.WitherSkull"));
DisguiseConfig.setEnquipmentPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Enquipment"));
DisguiseConfig.setAnimationPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Animation"));
DisguiseConfig.setBedPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Bed"));
DisguiseConfig.setRidingPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Riding"));
DisguiseConfig.setEntityStatusPacketsEnabled(getConfig().getBoolean("PacketsEnabled.EntityStatus"));
DisguiseConfig.setCollectPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Collect"));
try { try {
// Here I use reflection to set the plugin for Disguise.. // Here I use reflection to set the plugin for Disguise..
// Kind of stupid but I don't want open API calls for a commonly used object. // Kind of stupid but I don't want open API calls for a commonly used object.
@ -103,7 +115,7 @@ public class LibsDisguises extends JavaPlugin {
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
PacketsManager.addPacketListeners(this); PacketsManager.addPacketListeners();
DisguiseListener listener = new DisguiseListener(this); DisguiseListener listener = new DisguiseListener(this);
Bukkit.getPluginManager().registerEvents(listener, this); Bukkit.getPluginManager().registerEvents(listener, this);
getCommand("disguise").setExecutor(new DisguiseCommand()); getCommand("disguise").setExecutor(new DisguiseCommand());

View File

@ -21,6 +21,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Horse.Variant; import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -227,7 +228,7 @@ public abstract class Disguise {
// If disguise isn't a experience orb, or the entity isn't standing on the ground // If disguise isn't a experience orb, or the entity isn't standing on the ground
if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) { if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) {
PacketContainer lookPacket = null; PacketContainer lookPacket = null;
if (getType() == DisguiseType.WITHER_SKULL) { if (getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) {
lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK); lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
StructureModifier<Object> mods = lookPacket.getModifier(); StructureModifier<Object> mods = lookPacket.getModifier();
mods.write(0, getEntity().getEntityId()); mods.write(0, getEntity().getEntityId());
@ -454,6 +455,10 @@ public abstract class Disguise {
return; return;
throw new RuntimeException("This disguise is already in use! Try .clone()"); throw new RuntimeException("This disguise is already in use! Try .clone()");
} }
if (this.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) {
throw new RuntimeException(
"Cannot disguise a living entity with a misc disguise. Renable MiscDisguisesForLiving in the config to do this");
}
this.entity = entity; this.entity = entity;
setupWatcher(); setupWatcher();
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, velocityRunnable, 1, 1); taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, velocityRunnable, 1, 1);

View File

@ -102,11 +102,6 @@ public class MiscDisguise extends TargetedDisguise {
this(entityType, -1, -1); this(entityType, -1, -1);
} }
@Deprecated
public MiscDisguise(EntityType entityType, int id) {
this(entityType, id, -1);
}
@Deprecated @Deprecated
public MiscDisguise(EntityType entityType, boolean replaceSounds) { public MiscDisguise(EntityType entityType, boolean replaceSounds) {
this(entityType, replaceSounds, -1, -1); this(entityType, replaceSounds, -1, -1);
@ -117,6 +112,11 @@ public class MiscDisguise extends TargetedDisguise {
this(DisguiseType.getType(entityType), replaceSounds, id, data); this(DisguiseType.getType(entityType), replaceSounds, id, data);
} }
@Deprecated
public MiscDisguise(EntityType entityType, int id) {
this(entityType, id, -1);
}
@Deprecated @Deprecated
public MiscDisguise(EntityType disguiseType, int id, int data) { public MiscDisguise(EntityType disguiseType, int id, int data) {
this(DisguiseType.getType(disguiseType), id, data); this(DisguiseType.getType(disguiseType), id, data);

View File

@ -8,6 +8,7 @@ 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 me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
@ -44,7 +45,7 @@ public class PlayerWatcher extends LivingWatcher {
public void setSleeping(boolean sleep) { public void setSleeping(boolean sleep) {
if (sleep != isSleeping()) { if (sleep != isSleeping()) {
isInBed = sleep; isInBed = sleep;
if (DisguiseUtilities.isDisguiseInUse(getDisguise())) { if (DisguiseConfig.isBedPacketsEnabled() && DisguiseUtilities.isDisguiseInUse(getDisguise())) {
PacketContainer packet; PacketContainer packet;
if (isSleeping()) { if (isSleeping()) {
packet = new PacketContainer(PacketType.Play.Server.BED); packet = new PacketContainer(PacketType.Play.Server.BED);

View File

@ -43,6 +43,10 @@ public class DisguiseUtilities {
* the plugin to do that. * the plugin to do that.
*/ */
private static HashSet<String> addedByPlugins = new HashSet<String>(); private static HashSet<String> addedByPlugins = new HashSet<String>();
/**
* A hashmap of the uuid's of entitys, alive and dead. And their disguises in use
**/
private static HashMap<UUID, HashSet<TargetedDisguise>> disguisesInUse = new HashMap<UUID, HashSet<TargetedDisguise>>();
/** /**
* Disguises which are stored ready for a entity to be seen by a player Preferably, disguises in this should only stay in for * Disguises which are stored ready for a entity to be seen by a player Preferably, disguises in this should only stay in for
* a max of a second. * a max of a second.
@ -58,10 +62,6 @@ public class DisguiseUtilities {
* seeing as no one sees each others entity ID * seeing as no one sees each others entity ID
**/ **/
private static HashMap<UUID, Integer> selfDisguisesIds = new HashMap<UUID, Integer>(); private static HashMap<UUID, Integer> selfDisguisesIds = new HashMap<UUID, Integer>();
/**
* A hashmap of the uuid's of entitys, alive and dead. And their disguises in use
**/
private static HashMap<UUID, HashSet<TargetedDisguise>> disguisesInUse = new HashMap<UUID, HashSet<TargetedDisguise>>();
public static void addDisguise(UUID entityId, TargetedDisguise disguise) { public static void addDisguise(UUID entityId, TargetedDisguise disguise) {
if (!getDisguises().containsKey(entityId)) { if (!getDisguises().containsKey(entityId)) {

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig;
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.DisguiseType; import me.libraryaddict.disguise.disguisetypes.DisguiseType;
@ -32,12 +33,10 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie; import org.bukkit.entity.Zombie;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority; import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
@ -57,50 +56,18 @@ public class PacketsManager {
private static PacketListener inventoryListenerServer; private static PacketListener inventoryListenerServer;
private static boolean inventoryModifierEnabled; private static boolean inventoryModifierEnabled;
private static LibsDisguises libsDisguises; private static LibsDisguises libsDisguises;
private static PacketListener mainListener;
private static PacketListener soundsListener; private static PacketListener soundsListener;
private static PacketListener useEntityListener;
private static boolean soundsListenerEnabled; private static boolean soundsListenerEnabled;
private static PacketListener viewDisguisesListener; private static PacketListener viewDisguisesListener;
private static boolean viewDisguisesListenerEnabled; private static boolean viewDisguisesListenerEnabled;
public static void addPacketListeners(JavaPlugin libsDisguises) { public static void addPacketListeners() {
ProtocolManager manager = ProtocolLibrary.getProtocolManager(); // Add a client listener to cancel them interacting with uninteractable disguised entitys.
manager.addPacketListener(new PacketAdapter(libsDisguises, ListenerPriority.HIGH,
PacketType.Play.Server.NAMED_ENTITY_SPAWN, PacketType.Play.Server.ENTITY_METADATA,
PacketType.Play.Server.ANIMATION, PacketType.Play.Server.ENTITY_MOVE_LOOK, PacketType.Play.Server.ENTITY_LOOK,
PacketType.Play.Server.ENTITY_HEAD_ROTATION, PacketType.Play.Server.ENTITY_TELEPORT,
PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB, PacketType.Play.Server.SPAWN_ENTITY,
PacketType.Play.Server.SPAWN_ENTITY_LIVING, PacketType.Play.Server.SPAWN_ENTITY_PAINTING,
PacketType.Play.Server.COLLECT, PacketType.Play.Server.UPDATE_ATTRIBUTES,
PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.BED, PacketType.Play.Server.ENTITY_STATUS,
PacketType.Play.Server.ATTACH_ENTITY) {
@Override
public void onPacketSending(PacketEvent event) {
final Player observer = event.getPlayer();
// First get the entity, the one sending this packet
StructureModifier<Entity> entityModifer = event.getPacket().getEntityModifier(observer.getWorld());
org.bukkit.entity.Entity entity = entityModifer.read((PacketType.Play.Server.COLLECT == event.getPacketType()
|| PacketType.Play.Server.ATTACH_ENTITY == event.getPacketType() ? 1 : 0));
// If the entity is the same as the sender. Don't disguise!
// Prevents problems and there is no advantage to be gained.
if (entity == observer)
return;
PacketContainer[] packets = transformPacket(event.getPacket(), event.getPlayer(), entity);
if (packets != null) {
event.setCancelled(true);
try {
for (PacketContainer packet : packets) {
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false);
}
} catch (InvocationTargetException ex) {
ex.printStackTrace();
}
}
}
});
// Now add a client listener to cancel them interacting with uninteractable disguised entitys.
// You ain't supposed to be allowed to 'interact' with a item that cannot be clicked. // You ain't supposed to be allowed to 'interact' with a item that cannot be clicked.
// Because it kicks you for hacking. // Because it kicks you for hacking.
manager.addPacketListener(new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) { useEntityListener = new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) {
@Override @Override
public void onPacketReceiving(PacketEvent event) { public void onPacketReceiving(PacketEvent event) {
try { try {
@ -115,7 +82,10 @@ public class PacketsManager {
e.printStackTrace(); e.printStackTrace();
} }
} }
}); };
ProtocolLibrary.getProtocolManager().addPacketListener(useEntityListener);
// Now I call this and the main listener is registered!
setupMainPacketsListener();
} }
/** /**
@ -156,9 +126,12 @@ public class PacketsManager {
spawnPackets[i + 2] = packets.get(i); spawnPackets[i + 2] = packets.get(i);
} }
Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguise), 0); Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguise), 0);
byte yaw = getYaw(disguise.getType(), disguisedEntity.getType(), (byte) (int) (loc.getYaw() * 256.0F / 360.0F)); byte yaw = (byte) (int) (loc.getYaw() * 256.0F / 360.0F);
byte pitch = getPitch(disguise.getType(), DisguiseType.getType(disguisedEntity.getType()), byte pitch = (byte) (int) (loc.getPitch() * 256.0F / 360.0F);
(byte) (int) (loc.getPitch() * 256.0F / 360.0F)); if (DisguiseConfig.isMovementPacketsEnabled()) {
yaw = getYaw(disguise.getType(), disguisedEntity.getType(), yaw);
pitch = getPitch(disguise.getType(), DisguiseType.getType(disguisedEntity.getType()), pitch);
}
if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) {
@ -230,7 +203,7 @@ public class PacketsManager {
spawnPackets[0].getDataWatcherModifier().write(0, spawnPackets[0].getDataWatcherModifier().write(0,
createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher()));
if (((PlayerWatcher) disguise.getWatcher()).isSleeping()) { if (((PlayerWatcher) disguise.getWatcher()).isSleeping() && DisguiseConfig.isBedPacketsEnabled()) {
spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED); spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED);
StructureModifier<Integer> mods = spawnPackets[1].getIntegers(); StructureModifier<Integer> mods = spawnPackets[1].getIntegers();
mods.write(0, disguisedEntity.getEntityId()); mods.write(0, disguisedEntity.getEntityId());
@ -463,7 +436,7 @@ public class PacketsManager {
case WITHER_SKULL: case WITHER_SKULL:
return 0.7; return 0.7;
case PLAYER: case PLAYER:
if (((PlayerWatcher) disguise.getWatcher()).isSleeping()) { if (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) {
return 0.35; return 0.35;
} }
break; break;
@ -1078,6 +1051,85 @@ public class PacketsManager {
} }
} }
public static void setupMainPacketsListener() {
if (useEntityListener != null) {
if (mainListener != null) {
ProtocolLibrary.getProtocolManager().removePacketListener(mainListener);
}
List<PacketType> packetsToListen = new ArrayList<PacketType>();
// Add spawn packets
{
packetsToListen.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING);
}
// Add packets that always need to be enabled to ensure safety
{
packetsToListen.add(PacketType.Play.Server.ENTITY_METADATA);
}
if (DisguiseConfig.isRidingPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ATTACH_ENTITY);
}
if (DisguiseConfig.isCollectPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.COLLECT);
}
if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) {
packetsToListen.add(PacketType.Play.Server.UPDATE_ATTRIBUTES);
}
// The bed packet.
if (DisguiseConfig.isBedPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.BED);
}
// Add movement packets
if (DisguiseConfig.isMovementPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ENTITY_LOOK);
packetsToListen.add(PacketType.Play.Server.ENTITY_MOVE_LOOK);
packetsToListen.add(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
packetsToListen.add(PacketType.Play.Server.ENTITY_TELEPORT);
}
// Add enquipment packet
if (DisguiseConfig.isEnquipmentPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ENTITY_EQUIPMENT);
}
// Add the packet that ensures if they are sleeping or not
if (DisguiseConfig.isAnimationPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ANIMATION);
}
// Add the packet that makes sure that entities with armor do not send unpickupable armor on death
if (DisguiseConfig.isEntityStatusPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ENTITY_STATUS);
}
mainListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGH, packetsToListen) {
@Override
public void onPacketSending(PacketEvent event) {
final Player observer = event.getPlayer();
// First get the entity, the one sending this packet
StructureModifier<Entity> entityModifer = event.getPacket().getEntityModifier(observer.getWorld());
org.bukkit.entity.Entity entity = entityModifer.read((PacketType.Play.Server.COLLECT == event.getPacketType()
|| PacketType.Play.Server.ATTACH_ENTITY == event.getPacketType() ? 1 : 0));
// If the entity is the same as the sender. Don't disguise!
// Prevents problems and there is no advantage to be gained.
if (entity == observer)
return;
PacketContainer[] packets = transformPacket(event.getPacket(), event.getPlayer(), entity);
if (packets != null) {
event.setCancelled(true);
try {
for (PacketContainer packet : packets) {
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet, false);
}
} catch (InvocationTargetException ex) {
ex.printStackTrace();
}
}
}
};
ProtocolLibrary.getProtocolManager().addPacketListener(mainListener);
}
}
public static void setViewDisguisesListener(boolean enabled) { public static void setViewDisguisesListener(boolean enabled) {
if (viewDisguisesListenerEnabled != enabled) { if (viewDisguisesListenerEnabled != enabled) {
viewDisguisesListenerEnabled = enabled; viewDisguisesListenerEnabled = enabled;
@ -1151,7 +1203,8 @@ public class PacketsManager {
else if (sentPacket.getType() == PacketType.Play.Server.ANIMATION) { else if (sentPacket.getType() == PacketType.Play.Server.ANIMATION) {
if (disguise.getType().isMisc() if (disguise.getType().isMisc()
|| (packets[0].getIntegers().read(1) == (LibVersion.is1_7() ? 2 : 3) && (!disguise.getType() || (packets[0].getIntegers().read(1) == (LibVersion.is1_7() ? 2 : 3) && (!disguise.getType()
.isPlayer() || ((PlayerWatcher) disguise.getWatcher()).isSleeping()))) { .isPlayer() || (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise
.getWatcher()).isSleeping())))) {
packets = new PacketContainer[0]; packets = new PacketContainer[0];
} }
} }
@ -1159,7 +1212,8 @@ public class PacketsManager {
else if (sentPacket.getType() == PacketType.Play.Server.COLLECT) { else if (sentPacket.getType() == PacketType.Play.Server.COLLECT) {
if (disguise.getType().isMisc()) { if (disguise.getType().isMisc()) {
packets = new PacketContainer[0]; packets = new PacketContainer[0];
} else if (disguise.getType().isPlayer() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { } else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer()
&& ((PlayerWatcher) disguise.getWatcher()).isSleeping()) {
PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ANIMATION); PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ANIMATION);
StructureModifier<Integer> mods = newPacket.getIntegers(); StructureModifier<Integer> mods = newPacket.getIntegers();
mods.write(0, disguise.getEntity().getEntityId()); mods.write(0, disguise.getEntity().getEntityId());