Initial work

This commit is contained in:
libraryaddict 2017-05-28 10:23:15 +12:00
parent 7a9f1bd4cd
commit 3b1465d329
15 changed files with 887 additions and 425 deletions

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: cglib:cglib-nodep:2.2.2">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/cglib/cglib-nodep/2.2.2/cglib-nodep-2.2.2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.comphenix.executors:BukkitExecutors:1.1-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/comphenix/executors/BukkitExecutors/1.1-SNAPSHOT/BukkitExecutors-1.1-20170429.151522-2.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/comphenix/executors/BukkitExecutors/1.1-SNAPSHOT/BukkitExecutors-1.1-20170429.151522-2-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/comphenix/executors/BukkitExecutors/1.1-SNAPSHOT/BukkitExecutors-1.1-20170429.151522-2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.comphenix.protocol:ProtocolLib-API:4.2.0-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/comphenix/protocol/ProtocolLib-API/4.2.0-SNAPSHOT/ProtocolLib-API-4.2.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/comphenix/protocol/ProtocolLib-API/4.2.0-SNAPSHOT/ProtocolLib-API-4.2.0-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/comphenix/protocol/ProtocolLib-API/4.2.0-SNAPSHOT/ProtocolLib-API-4.2.0-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@ -1,6 +1,47 @@
# Shall I notify people of a LibsDisguises update? # Shall I notify people of a LibsDisguises update?
NotifyUpdate: true NotifyUpdate: true
# The disguise plugin stores all GameProfiles inside a file called 'cache.yml'
# This means that the plugin doesn't need to constantly call Mojang just to find a skin for an offline player
# However some people may prefer to disable this.
# Even if you disable this, if there was disguises in the cache already then it will use them
SaveCache: true
# This option is useless if you don't enable SaveCache!
# If a player has been disguised before and their skin saved into the cache
# When they join the server will automatically update the cache incase they changed their skin
UpdatePlayersCache: true
# Should the server save the disguises so that when they are alive again, they are disguised again
# Players - Are player disguises saved
# Entities - Are entities disguises saved
SaveDisguises:
Players: false
Entities: false
# Where does it save the disguises and gameprofiles to
SaveData:
# If this is true, then it saves to mysql. If this is false, then it saves to file
# I do not provide help for setting up Mysql or the databases, there are guides online for that
UseMySQL: false
# What is the IP and Port required to connect
IP: 'localhost:3306'
User: 'root'
Password: 'password'
Database: 'LibsDisguises'
# What is the table for GameProfiles called? You shouldn't need to touch this
GameProfiles: 'GameProfileCache'
# What is the table for disguises called?
Disguises: 'DisguisesCache'
# This I don't really recommend turning on as it can make a memory leak..
# These disguises, as normal will not persist after a server restart.
# There is also no EntityDeath option as entities do not revive after death.
# The EntityDespawn option is when you leave the chunk the entity is and the chunk is unloaded
KeepDisguises:
EntityDespawn: false
PlayerDeath: false
# How should the plugin handle self disguises scoreboards? # How should the plugin handle self disguises scoreboards?
# MODIFY_SCOREBOARD - Modifies the player's current team if possible, otherwise assigns them to a new scoreboard team # MODIFY_SCOREBOARD - Modifies the player's current team if possible, otherwise assigns them to a new scoreboard team
# IGNORE_SCOREBOARD - Doesn't touch scoreboards at all, effectively means that if you didn't disable pushing in their scoreboard team; They will still be pushed around # IGNORE_SCOREBOARD - Doesn't touch scoreboards at all, effectively means that if you didn't disable pushing in their scoreboard team; They will still be pushed around
@ -68,6 +109,7 @@ NameAboveHeadAlwaysVisible: true
# This WILL conflict with NoCheatPlus. Other plugins may also get problems. # This WILL conflict with NoCheatPlus. Other plugins may also get problems.
# This shouldn't really be enabled for players as it also interferes with their movement because the server thinks the player is larger than he really is. # This shouldn't really be enabled for players as it also interferes with their movement because the server thinks the player is larger than he really is.
# That makes the player unable to approach this building because the server thinks he is trying to glitch inside blocks. # That makes the player unable to approach this building because the server thinks he is trying to glitch inside blocks.
# This feature is highly experimental and is garanteed to cause problems for players who are disguised
ModifyBoundingBox: false ModifyBoundingBox: false
# This prevents disguised players from being targeted by monsters. # This prevents disguised players from being targeted by monsters.
@ -93,15 +135,6 @@ DisguiseCloneExpire: 10
# Max disguises to store at a time with the DisguiseClone command # Max disguises to store at a time with the DisguiseClone command
DisguiseCloneSize: 3 DisguiseCloneSize: 3
# This I don't really recommend turning on as it can make a memory leak..
# These disguises, as normal will not persist after a server restart.
# There is also no EntityDeath option as entities do not revive after death.
# The EntityDespawn option is when you leave the chunk the entity is and the chunk is unloaded
KeepDisguises:
EntityDespawn: false
PlayerDeath: false
PlayerLogout: false
# This controls if a entitys max health is determined by the entity, or by the disguise. # This controls if a entitys max health is determined by the entity, or by the disguise.
# Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health. # Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health.
# Else it will be 1/20 of the boss bar when he is full health. # Else it will be 1/20 of the boss bar when he is full health.

View File

@ -58,6 +58,36 @@ public class DisguiseConfig {
private static boolean viewSelfDisguise; private static boolean viewSelfDisguise;
private static boolean witherSkullEnabled; private static boolean witherSkullEnabled;
private static DisguisePushing disablePushing = DisguisePushing.MODIFY_SCOREBOARD; private static DisguisePushing disablePushing = DisguisePushing.MODIFY_SCOREBOARD;
private static boolean saveCache;
private static boolean updatePlayerCache;
private static boolean savePlayerDisguises;
private static boolean saveEntityDisguises;
private static boolean useSQL;
private static String ip, database, user, pass, disguiseTable, profileTable;
public static String getDatabaseIP() {
return ip;
}
public static String getDatabase() {
return database;
}
public static String getDatabaseUser() {
return user;
}
public static String getDatabasePass() {
return pass;
}
public static String getDatabaseProfileTable() {
return disguiseTable;
}
public static String getDatabaseDisguiseTable() {
return profileTable;
}
public static Entry<String, Disguise> getCustomDisguise(String disguise) { public static Entry<String, Disguise> getCustomDisguise(String disguise) {
for (Entry<String, Disguise> entry : customDisguises.entrySet()) { for (Entry<String, Disguise> entry : customDisguises.entrySet()) {
@ -71,6 +101,22 @@ public class DisguiseConfig {
return null; return null;
} }
public static boolean isSavePlayerDisguises() {
return savePlayerDisguises;
}
public static boolean isSaveEntityDisguises() {
return saveEntityDisguises;
}
public static void setSavePlayerDisguises(boolean saveDisguises) {
savePlayerDisguises = saveDisguises;
}
public static void setSaveEntityDisguises(boolean saveDisguises) {
saveEntityDisguises = saveDisguises;
}
public static DisguisePushing getPushingOption() { public static DisguisePushing getPushingOption() {
return disablePushing; return disablePushing;
} }
@ -103,6 +149,22 @@ public class DisguiseConfig {
return updateNotificationPermission; return updateNotificationPermission;
} }
public static boolean isSaveCache() {
return saveCache;
}
public static void setSaveCache(boolean doCache) {
saveCache = doCache;
}
public static boolean isUpdatePlayerCache() {
return updatePlayerCache;
}
public static void setUpdatePlayerCache(boolean setUpdatePlayerCache) {
updatePlayerCache = setUpdatePlayerCache;
}
public static void initConfig(ConfigurationSection config) { public static void initConfig(ConfigurationSection config) {
setSoundsEnabled(config.getBoolean("DisguiseSounds")); setSoundsEnabled(config.getBoolean("DisguiseSounds"));
setVelocitySent(config.getBoolean("SendVelocity")); setVelocitySent(config.getBoolean("SendVelocity"));
@ -144,6 +206,15 @@ public class DisguiseConfig {
setHideDisguisedPlayers(config.getBoolean("HideDisguisedPlayersFromTab")); setHideDisguisedPlayers(config.getBoolean("HideDisguisedPlayersFromTab"));
setShowDisguisedPlayersInTab(config.getBoolean("ShowPlayerDisguisesInTab")); setShowDisguisedPlayersInTab(config.getBoolean("ShowPlayerDisguisesInTab"));
setDisabledInvisibility(config.getBoolean("DisableInvisibility")); setDisabledInvisibility(config.getBoolean("DisableInvisibility"));
setSaveCache(config.getBoolean("SaveCache"));
setUpdatePlayerCache(config.getBoolean("UpdatePlayerCache"));
setSaveEntityDisguises(config.getBoolean("SaveDisguises.Entities"));
setSavePlayerDisguises(config.getBoolean("SaveDisguises.Players"));
useSQL = config.getBoolean("SaveData.UseMySQL", false);
ip = config.getString("SaveData.IP", "localhost:3306");
user = config.getString("SaveData.User", "root");
pass = config.getString("SaveData.Password", "password");
database
try { try {
String option = config.getString("SelfDisguisesScoreboard", String option = config.getString("SelfDisguisesScoreboard",
@ -193,7 +264,8 @@ public class DisguiseConfig {
} }
catch (DisguiseParseException e) { catch (DisguiseParseException e) {
System.err.println( System.err.println(
"[LibsDisguises] Error while loading custom disguise '" + key + "'" + (e.getMessage() == null ? "" : ": " + e.getMessage())); "[LibsDisguises] Error while loading custom disguise '" + key + "'" + (e.getMessage() == null ?
"" : ": " + e.getMessage()));
if (e.getMessage() == null) if (e.getMessage() == null)
e.printStackTrace(); e.printStackTrace();
@ -204,7 +276,8 @@ public class DisguiseConfig {
} }
System.out.println( System.out.println(
"[LibsDisguises] Loaded " + customDisguises.size() + " custom disguise" + (customDisguises.size() == 1 ? "" : "s")); "[LibsDisguises] Loaded " + customDisguises.size() + " custom disguise" + (customDisguises.size() == 1 ?
"" : "s"));
} }
public static boolean isAnimationPacketsEnabled() { public static boolean isAnimationPacketsEnabled() {

View File

@ -6,6 +6,7 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
@ -26,6 +27,8 @@ import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
@ -89,14 +92,15 @@ public class DisguiseListener implements Listener {
continue; continue;
} }
p.sendMessage( p.sendMessage(String.format(DisguiseConfig.getUpdateMessage(), currentVersion,
String.format(DisguiseConfig.getUpdateMessage(), currentVersion, latestVersion)); latestVersion));
} }
} }
}); });
} }
catch (Exception ex) { catch (Exception ex) {
System.out.print(String.format("[LibsDisguises] Failed to check for update: %s", ex.getMessage())); System.out.print(
String.format("[LibsDisguises] Failed to check for update: %s", ex.getMessage()));
} }
} }
}, 0, (20 * 60 * 60 * 6)); // Check every 6 hours }, 0, (20 * 60 * 60 * 6)); // Check every 6 hours
@ -189,6 +193,39 @@ public class DisguiseListener implements Listener {
} }
} }
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
if (!DisguiseConfig.isSaveEntityDisguises())
return;
for (Entity entity : event.getChunk().getEntities()) {
Disguise[] disguises = DisguiseAPI.getDisguises(entity);
if (disguises.length <= 0)
continue;
DisguiseUtilities.saveDisguises(entity.getUniqueId(), disguises);
}
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
if (!DisguiseConfig.isSaveEntityDisguises())
return;
for (Entity entity : event.getChunk().getEntities()) {
Disguise[] disguises = DisguiseUtilities.getSavedDisguises(entity.getUniqueId());
if (disguises.length <= 0)
continue;
for (Disguise disguise : disguises) {
disguise.setEntity(entity);
disguise.startDisguise();
}
}
}
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
@ -201,6 +238,24 @@ public class DisguiseListener implements Listener {
chunkMove(p, p.getLocation(), null); chunkMove(p, p.getLocation(), null);
} }
if (DisguiseConfig.isSaveCache() && DisguiseConfig.isUpdatePlayerCache() && DisguiseUtilities.hasCacheEntry(
p.getName())) {
WrappedGameProfile profile = WrappedGameProfile.fromPlayer(p);
if (!profile.getProperties().isEmpty()) {
DisguiseUtilities.addGameProfile(p.getName(), profile);
}
}
if (DisguiseConfig.isSavePlayerDisguises()) {
Disguise[] disguises = DisguiseUtilities.getSavedDisguises(p.getUniqueId());
for (Disguise disguise : disguises) {
disguise.setEntity(p);
disguise.startDisguise();
}
}
for (HashSet<TargetedDisguise> disguiseList : DisguiseUtilities.getDisguises().values()) { for (HashSet<TargetedDisguise> disguiseList : DisguiseUtilities.getDisguises().values()) {
for (TargetedDisguise targetedDisguise : disguiseList) { for (TargetedDisguise targetedDisguise : disguiseList) {
if (targetedDisguise.getEntity() == null) if (targetedDisguise.getEntity() == null)
@ -239,8 +294,9 @@ public class DisguiseListener implements Listener {
PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Arrays.asList(new PlayerInfoData(disguise.getGameProfile(), 0, addTab.getPlayerInfoDataLists().write(0, Arrays.asList(
NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(disguise.getGameProfile().getName())))); new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getGameProfile().getName()))));
ProtocolLibrary.getProtocolManager().sendServerPacket(p, addTab); ProtocolLibrary.getProtocolManager().sendServerPacket(p, addTab);
} }
@ -261,8 +317,9 @@ public class DisguiseListener implements Listener {
Location to = event.getTo(); Location to = event.getTo();
Location from = event.getFrom(); Location from = event.getFrom();
if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(from.getBlockX()) if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(
|| DisguiseUtilities.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) { from.getBlockX()) || DisguiseUtilities.getChunkCord(
to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) {
chunkMove(event.getPlayer(), to, from); chunkMove(event.getPlayer(), to, from);
} }
} }
@ -286,7 +343,17 @@ public class DisguiseListener implements Listener {
@EventHandler @EventHandler
public void onQuit(PlayerQuitEvent event) { public void onQuit(PlayerQuitEvent event) {
ReflectionManager.removePlayer(event.getPlayer()); if (!DisguiseConfig.isSavePlayerDisguises())
return;
Player player = event.getPlayer();
Disguise[] disguises = DisguiseAPI.getDisguises(player);
if (disguises.length <= 0)
return;
DisguiseUtilities.saveDisguises(player.getUniqueId(), disguises);
} }
@EventHandler @EventHandler
@ -315,7 +382,8 @@ public class DisguiseListener implements Listener {
@EventHandler @EventHandler
public void onRightClick(PlayerInteractEntityEvent event) { public void onRightClick(PlayerInteractEntityEvent event) {
if (!disguiseEntity.containsKey(event.getPlayer().getName()) && !disguiseClone.containsKey(event.getPlayer().getName())) { if (!disguiseEntity.containsKey(event.getPlayer().getName()) && !disguiseClone.containsKey(
event.getPlayer().getName())) {
return; return;
} }
@ -329,8 +397,7 @@ public class DisguiseListener implements Listener {
if (entity instanceof Player && !disguiseClone.containsKey(p.getName())) { if (entity instanceof Player && !disguiseClone.containsKey(p.getName())) {
entityName = entity.getName(); entityName = entity.getName();
} } else {
else {
entityName = DisguiseType.getType(entity).toReadable(); entityName = DisguiseType.getType(entity).toReadable();
} }
@ -338,17 +405,14 @@ public class DisguiseListener implements Listener {
Boolean[] options = disguiseClone.remove(p.getName()); Boolean[] options = disguiseClone.remove(p.getName());
DisguiseUtilities.createClonedDisguise(p, entity, options); DisguiseUtilities.createClonedDisguise(p, entity, options);
} } else if (disguiseEntity.containsKey(p.getName())) {
else if (disguiseEntity.containsKey(p.getName())) {
Disguise disguise = disguiseEntity.remove(p.getName()); Disguise disguise = disguiseEntity.remove(p.getName());
if (disguise != null) { if (disguise != null) {
if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) {
&& entity instanceof LivingEntity) { p.sendMessage(
p.sendMessage(ChatColor.RED ChatColor.RED + "Can't disguise a living entity as a misc disguise. This has been disabled in the config!");
+ "Can't disguise a living entity as a misc disguise. This has been disabled in the config!"); } else {
}
else {
if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) {
if (disguise.getWatcher() instanceof LivingWatcher) { if (disguise.getWatcher() instanceof LivingWatcher) {
disguise.getWatcher().setCustomName(((Player) entity).getDisplayName()); disguise.getWatcher().setCustomName(((Player) entity).getDisplayName());
@ -365,33 +429,30 @@ public class DisguiseListener implements Listener {
if (disguise instanceof PlayerDisguise) { if (disguise instanceof PlayerDisguise) {
disguiseName = "the player " + ((PlayerDisguise) disguise).getName(); disguiseName = "the player " + ((PlayerDisguise) disguise).getName();
} } else {
else {
disguiseName += disguise.getType().toReadable(); disguiseName += disguise.getType().toReadable();
} }
if (disguise.isDisguiseInUse()) { if (disguise.isDisguiseInUse()) {
p.sendMessage(ChatColor.RED + "Disguised " + (entity instanceof Player ? "" : "the ") + entityName p.sendMessage(ChatColor.RED + "Disguised " + (entity instanceof Player ? "" :
+ " as " + disguiseName + "!"); "the ") + entityName + " as " + disguiseName + "!");
} } else {
else { p.sendMessage(ChatColor.RED + "Failed to disguise " + (entity instanceof Player ? "" :
p.sendMessage(ChatColor.RED + "Failed to disguise " + (entity instanceof Player ? "" : "the ") "the ") + entityName + " as " + disguiseName + "!");
+ entityName + " as " + disguiseName + "!");
} }
} }
} } else {
else {
if (DisguiseAPI.isDisguised(entity)) { if (DisguiseAPI.isDisguised(entity)) {
DisguiseAPI.undisguiseToAll(entity); DisguiseAPI.undisguiseToAll(entity);
p.sendMessage(ChatColor.RED + "Undisguised " + (entity instanceof Player ? "" : "the ") + entityName); p.sendMessage(
} ChatColor.RED + "Undisguised " + (entity instanceof Player ? "" : "the ") + entityName);
else { } else {
p.sendMessage(ChatColor.RED + (entity instanceof Player ? "" : "the") + entityName + " isn't disguised!"); p.sendMessage(
ChatColor.RED + (entity instanceof Player ? "" : "the") + entityName + " isn't disguised!");
} }
} }
} } else if (disguiseModify.containsKey(p.getName())) {
else if (disguiseModify.containsKey(p.getName())) {
String[] options = disguiseModify.remove(p.getName()); String[] options = disguiseModify.remove(p.getName());
Disguise disguise = DisguiseAPI.getDisguise(p, entity); Disguise disguise = DisguiseAPI.getDisguise(p, entity);
@ -410,8 +471,8 @@ public class DisguiseListener implements Listener {
} }
try { try {
DisguiseParser.callMethods(p, disguise, perms.get(new DisguisePerm(disguise.getType())), new ArrayList<String>(), DisguiseParser.callMethods(p, disguise, perms.get(new DisguisePerm(disguise.getType())),
options); new ArrayList<String>(), options);
p.sendMessage(ChatColor.RED + "Modified the disguise!"); p.sendMessage(ChatColor.RED + "Modified the disguise!");
} }
catch (DisguiseParseException ex) { catch (DisguiseParseException ex) {
@ -427,8 +488,8 @@ public class DisguiseListener implements Listener {
@EventHandler @EventHandler
public void onTarget(EntityTargetEvent event) { public void onTarget(EntityTargetEvent event) {
if (DisguiseConfig.isMonstersIgnoreDisguises() && event.getTarget() != null && event.getTarget() instanceof Player if (DisguiseConfig.isMonstersIgnoreDisguises() && event.getTarget() != null && event.getTarget() instanceof Player && DisguiseAPI.isDisguised(
&& DisguiseAPI.isDisguised(event.getTarget())) { event.getTarget())) {
switch (event.getReason()) { switch (event.getReason()) {
case TARGET_ATTACKED_ENTITY: case TARGET_ATTACKED_ENTITY:
case TARGET_ATTACKED_OWNER: case TARGET_ATTACKED_OWNER:
@ -449,8 +510,9 @@ public class DisguiseListener implements Listener {
Location from = event.getFrom(); Location from = event.getFrom();
if (DisguiseConfig.isBedPacketsEnabled()) { if (DisguiseConfig.isBedPacketsEnabled()) {
if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(from.getBlockX()) if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(
|| DisguiseUtilities.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) { from.getBlockX()) || DisguiseUtilities.getChunkCord(
to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) {
chunkMove(player, null, from); chunkMove(player, null, from);
Bukkit.getScheduler().runTask(plugin, new Runnable() { Bukkit.getScheduler().runTask(plugin, new Runnable() {
@ -466,8 +528,7 @@ public class DisguiseListener implements Listener {
return; return;
} }
if (DisguiseConfig.isUndisguiseOnWorldChange() && to.getWorld() != null && from.getWorld() != null if (DisguiseConfig.isUndisguiseOnWorldChange() && to.getWorld() != null && from.getWorld() != null && to.getWorld() != from.getWorld()) {
&& to.getWorld() != from.getWorld()) {
for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) {
disguise.removeDisguise(); disguise.removeDisguise();
} }
@ -476,7 +537,8 @@ public class DisguiseListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVehicleEnter(VehicleEnterEvent event) { public void onVehicleEnter(VehicleEnterEvent event) {
if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) { if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(),
event.getEntered())) {
DisguiseUtilities.removeSelfDisguise((Player) event.getEntered()); DisguiseUtilities.removeSelfDisguise((Player) event.getEntered());
((Player) event.getEntered()).updateInventory(); ((Player) event.getEntered()).updateInventory();
@ -515,8 +577,7 @@ public class DisguiseListener implements Listener {
for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) {
disguise.removeDisguise(); disguise.removeDisguise();
} }
} } else {
else {
// Stupid hack to fix worldswitch invisibility bug // Stupid hack to fix worldswitch invisibility bug
final boolean viewSelfToggled = DisguiseAPI.isViewSelfToggled(event.getPlayer()); final boolean viewSelfToggled = DisguiseAPI.isViewSelfToggled(event.getPlayer());
@ -597,5 +658,4 @@ public class DisguiseListener implements Listener {
disguiseRunnable.put(player, runnable); disguiseRunnable.put(player, runnable);
disguiseModify.put(player, args); disguiseModify.put(player, args);
} }
} }

View File

@ -1,22 +1,5 @@
package me.libraryaddict.disguise.disguisetypes; package me.libraryaddict.disguise.disguisetypes;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
@ -26,7 +9,6 @@ import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData; import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedChatComponent;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
@ -39,9 +21,20 @@ import me.libraryaddict.disguise.events.UndisguiseEvent;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.PacketsManager; import me.libraryaddict.disguise.utilities.PacketsManager;
import me.libraryaddict.disguise.utilities.ReflectionManager; import me.libraryaddict.disguise.utilities.ReflectionManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
public abstract class Disguise { import java.io.Serializable;
private static List<UUID> viewSelf = new ArrayList<>(); import java.lang.reflect.InvocationTargetException;
import java.util.*;
public abstract class Disguise implements Serializable {
private transient static List<UUID> viewSelf = new ArrayList<>();
/** /**
* Returns the list of people who have /disguiseViewSelf toggled on * Returns the list of people who have /disguiseViewSelf toggled on
@ -52,9 +45,9 @@ public abstract class Disguise {
return viewSelf; return viewSelf;
} }
private boolean disguiseInUse; private transient boolean disguiseInUse;
private DisguiseType disguiseType; private DisguiseType disguiseType;
private Entity entity; private transient Entity entity;
private boolean hearSelfDisguise = DisguiseConfig.isSelfDisguisesSoundsReplaced(); private boolean hearSelfDisguise = DisguiseConfig.isSelfDisguisesSoundsReplaced();
private boolean hideArmorFromSelf = DisguiseConfig.isHidingArmorFromSelf(); private boolean hideArmorFromSelf = DisguiseConfig.isHidingArmorFromSelf();
private boolean hideHeldItemFromSelf = DisguiseConfig.isHidingHeldItemFromSelf(); private boolean hideHeldItemFromSelf = DisguiseConfig.isHidingHeldItemFromSelf();
@ -65,8 +58,8 @@ public abstract class Disguise {
private boolean playerHiddenFromTab = DisguiseConfig.isHideDisguisedPlayers(); private boolean playerHiddenFromTab = DisguiseConfig.isHideDisguisedPlayers();
private boolean replaceSounds = DisguiseConfig.isSoundEnabled(); private boolean replaceSounds = DisguiseConfig.isSoundEnabled();
private boolean showName; private boolean showName;
private BukkitTask task; private transient BukkitTask task;
private Runnable velocityRunnable; private transient Runnable velocityRunnable;
private boolean velocitySent = DisguiseConfig.isVelocitySent(); private boolean velocitySent = DisguiseConfig.isVelocitySent();
private boolean viewSelfDisguise = DisguiseConfig.isViewDisguises(); private boolean viewSelfDisguise = DisguiseConfig.isViewDisguises();
private FlagWatcher watcher; private FlagWatcher watcher;
@ -81,13 +74,12 @@ public abstract class Disguise {
/** /**
* Seems I do this method so I can make cleaner constructors on disguises.. * Seems I do this method so I can make cleaner constructors on disguises..
* *
* @param newType * @param newType The disguise
* The disguise
*/ */
protected void createDisguise() { protected void createDisguise() {
if (getType().getEntityType() == null) { if (getType().getEntityType() == null) {
throw new RuntimeException("DisguiseType " + getType() throw new RuntimeException(
+ " was used in a futile attempt to construct a disguise, but this Minecraft version does not have that entity"); "DisguiseType " + getType() + " was used in a futile attempt to construct a disguise, but this Minecraft version does not have that entity");
} }
// Get if they are a adult now.. // Get if they are a adult now..
@ -106,14 +98,15 @@ public abstract class Disguise {
catch (Exception e) { catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} else {
getWatcher().setDisguise((TargetedDisguise) this);
} }
// Set the disguise if its a baby or not // Set the disguise if its a baby or not
if (!isAdult) { if (!isAdult) {
if (getWatcher() instanceof AgeableWatcher) { if (getWatcher() instanceof AgeableWatcher) {
((AgeableWatcher) getWatcher()).setBaby(true); ((AgeableWatcher) getWatcher()).setBaby(true);
} } else if (getWatcher() instanceof ZombieWatcher) {
else if (getWatcher() instanceof ZombieWatcher) {
((ZombieWatcher) getWatcher()).setBaby(true); ((ZombieWatcher) getWatcher()).setBaby(true);
} }
} }
@ -209,16 +202,14 @@ public abstract class Disguise {
if (isRemoveDisguiseOnDeath()) { if (isRemoveDisguiseOnDeath()) {
removeDisguise(); removeDisguise();
} } else {
else {
entity = null; entity = null;
watcher = getWatcher().clone(disguise); watcher = getWatcher().clone(disguise);
task.cancel(); task.cancel();
task = null; task = null;
} }
} }
} } else {
else {
deadTicks = 0; deadTicks = 0;
// If the disguise type is tnt, we need to resend the entity packet else it will turn invisible // If the disguise type is tnt, we need to resend the entity packet else it will turn invisible
@ -230,8 +221,7 @@ public abstract class Disguise {
DisguiseUtilities.refreshTrackers(disguise); DisguiseUtilities.refreshTrackers(disguise);
} }
} } else if (getType() == DisguiseType.EVOKER_FANGS) {
else if (getType() == DisguiseType.EVOKER_FANGS) {
refreshDisguise++; refreshDisguise++;
if (refreshDisguise == 23) { if (refreshDisguise == 23) {
@ -239,14 +229,12 @@ public abstract class Disguise {
DisguiseUtilities.refreshTrackers(disguise); DisguiseUtilities.refreshTrackers(disguise);
} }
} } else if (getType() == DisguiseType.ITEM_FRAME) {
else if (getType() == DisguiseType.ITEM_FRAME) {
Location loc = getEntity().getLocation(); Location loc = getEntity().getLocation();
int newFacing = (((int) loc.getYaw() + 720 + 45) / 90) % 4; int newFacing = (((int) loc.getYaw() + 720 + 45) / 90) % 4;
if (loc.getBlockX() != blockX || loc.getBlockY() != blockY || loc.getBlockZ() != blockZ if (loc.getBlockX() != blockX || loc.getBlockY() != blockY || loc.getBlockZ() != blockZ || newFacing != facing) {
|| newFacing != facing) {
blockX = loc.getBlockX(); blockX = loc.getBlockX();
blockY = loc.getBlockY(); blockY = loc.getBlockY();
blockZ = loc.getBlockZ(); blockZ = loc.getBlockZ();
@ -289,7 +277,8 @@ public abstract class Disguise {
mods.write(4, PacketsManager.getYaw(getType(), getEntity().getType(), mods.write(4, PacketsManager.getYaw(getType(), getEntity().getType(),
(byte) Math.floor(loc.getYaw() * 256.0F / 360.0F))); (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
mods.write(5, PacketsManager.getPitch(getType(), DisguiseType.getType(getEntity().getType()), mods.write(5,
PacketsManager.getPitch(getType(), DisguiseType.getType(getEntity().getType()),
(byte) Math.floor(loc.getPitch() * 256.0F / 360.0F))); (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
if (isSelfDisguiseVisible() && getEntity() instanceof Player) { if (isSelfDisguiseVisible() && getEntity() instanceof Player) {
@ -322,19 +311,20 @@ public abstract class Disguise {
} }
mods.write(0, DisguiseAPI.getSelfDisguiseId()); mods.write(0, DisguiseAPI.getSelfDisguiseId());
} } else {
else {
mods.write(0, getEntity().getEntityId()); mods.write(0, getEntity().getEntityId());
} }
mods.write(2, (int) (8000D * (vectorY * ReflectionManager.getPing(player)) * 0.069D)); mods.write(2,
(int) (8000D * (vectorY * ReflectionManager.getPing(player)) * 0.069D));
if (lookPacket != null && player != getEntity()) { if (lookPacket != null && player != getEntity()) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, lookPacket, false); ProtocolLibrary.getProtocolManager().sendServerPacket(player, lookPacket,
false);
} }
ProtocolLibrary.getProtocolManager().sendServerPacket(player, velocityPacket.shallowClone(), ProtocolLibrary.getProtocolManager().sendServerPacket(player,
false); velocityPacket.shallowClone(), false);
} }
} }
catch (Exception e) { catch (Exception e) {
@ -352,15 +342,14 @@ public abstract class Disguise {
for (Player player : DisguiseUtilities.getPerverts(disguise)) { for (Player player : DisguiseUtilities.getPerverts(disguise)) {
if (getEntity() != player) { if (getEntity() != player) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
} } else if (isSelfDisguiseVisible()) {
else if (isSelfDisguiseVisible()) {
PacketContainer selfPacket = packet.shallowClone(); PacketContainer selfPacket = packet.shallowClone();
selfPacket.getModifier().write(0, DisguiseAPI.getSelfDisguiseId()); selfPacket.getModifier().write(0, DisguiseAPI.getSelfDisguiseId());
try { try {
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) getEntity(), selfPacket, ProtocolLibrary.getProtocolManager().sendServerPacket((Player) getEntity(),
false); selfPacket, false);
} }
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
@ -461,9 +450,9 @@ public abstract class Disguise {
* Internal use * Internal use
*/ */
public boolean isRemoveDisguiseOnDeath() { public boolean isRemoveDisguiseOnDeath() {
return getEntity() == null || (getEntity() instanceof Player return getEntity() == null || (getEntity() instanceof Player ?
? (!((Player) getEntity()).isOnline() ? !isKeepDisguiseOnPlayerLogout() : !isKeepDisguiseOnPlayerDeath()) (!((Player) getEntity()).isOnline() ? !isKeepDisguiseOnPlayerLogout() :
: (!isKeepDisguiseOnEntityDespawn() || getEntity().isDead())); !isKeepDisguiseOnPlayerDeath()) : (!isKeepDisguiseOnEntityDespawn() || getEntity().isDead()));
} }
public boolean isSelfDisguiseSoundsReplaced() { public boolean isSelfDisguiseSoundsReplaced() {
@ -525,8 +514,8 @@ public abstract class Disguise {
if (disguise.isDisplayedInTab()) { if (disguise.isDisplayedInTab()) {
PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
deleteTab.getPlayerInfoDataLists().write(0, deleteTab.getPlayerInfoDataLists().write(0, Arrays.asList(
Arrays.asList(new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL, new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getName())))); WrappedChatComponent.fromText(disguise.getName()))));
try { try {
@ -546,8 +535,8 @@ public abstract class Disguise {
if (isHidePlayer() && getEntity() instanceof Player) { if (isHidePlayer() && getEntity() instanceof Player) {
PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
deleteTab.getPlayerInfoDataLists().write(0, deleteTab.getPlayerInfoDataLists().write(0, Arrays.asList(
Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0,
NativeGameMode.SURVIVAL, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName())))); WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName()))));
@ -574,13 +563,11 @@ public abstract class Disguise {
// Better refresh the entity to undisguise it // Better refresh the entity to undisguise it
if (getEntity().isValid()) { if (getEntity().isValid()) {
DisguiseUtilities.refreshTrackers((TargetedDisguise) this); DisguiseUtilities.refreshTrackers((TargetedDisguise) this);
} } else {
else {
DisguiseUtilities.destroyEntity((TargetedDisguise) this); DisguiseUtilities.destroyEntity((TargetedDisguise) this);
} }
} }
} } else {
else {
// Loop through the disguises because it could be used with a unknown entity id. // Loop through the disguises because it could be used with a unknown entity id.
HashMap<Integer, HashSet<TargetedDisguise>> future = DisguiseUtilities.getFutureDisguises(); HashMap<Integer, HashSet<TargetedDisguise>> future = DisguiseUtilities.getFutureDisguises();
@ -595,22 +582,6 @@ public abstract class Disguise {
} }
} }
if (isPlayerDisguise()) {
String name = ((PlayerDisguise) this).getName();
if (!DisguiseUtilities.getAddedByPlugins().contains(name.toLowerCase())) {
for (HashSet<TargetedDisguise> disguise : disguises.values()) {
for (Disguise d : disguise) {
if (d.isPlayerDisguise() && ((PlayerDisguise) d).getName().equals(name)) {
return true;
}
}
}
DisguiseUtilities.getGameProfiles().remove(name.toLowerCase());
}
}
return true; return true;
} }
} }
@ -640,7 +611,9 @@ public abstract class Disguise {
this.entity = entity; this.entity = entity;
if (entity != null) {
setupWatcher(); setupWatcher();
}
return this; return this;
} }
@ -731,7 +704,8 @@ public abstract class Disguise {
*/ */
private void setupWatcher() { private void setupWatcher() {
ArrayList<MetaIndex> disguiseFlags = MetaIndex.getFlags(getType().getWatcherClass()); ArrayList<MetaIndex> disguiseFlags = MetaIndex.getFlags(getType().getWatcherClass());
ArrayList<MetaIndex> entityFlags = MetaIndex.getFlags(DisguiseType.getType(getEntity().getType()).getWatcherClass()); ArrayList<MetaIndex> entityFlags = MetaIndex.getFlags(
DisguiseType.getType(getEntity().getType()).getWatcherClass());
for (MetaIndex flag : entityFlags) { for (MetaIndex flag : entityFlags) {
if (disguiseFlags.contains(flag)) if (disguiseFlags.contains(flag))
@ -770,8 +744,7 @@ public abstract class Disguise {
if (DisguiseAPI.getDisguise((Player) getEntity(), getEntity()) == this) { if (DisguiseAPI.getDisguise((Player) getEntity(), getEntity()) == this) {
if (isSelfDisguiseVisible()) { if (isSelfDisguiseVisible()) {
DisguiseUtilities.setupFakeDisguise(this); DisguiseUtilities.setupFakeDisguise(this);
} } else {
else {
DisguiseUtilities.removeSelfDisguise((Player) getEntity()); DisguiseUtilities.removeSelfDisguise((Player) getEntity());
} }
} }
@ -783,8 +756,8 @@ public abstract class Disguise {
public Disguise setWatcher(FlagWatcher newWatcher) { public Disguise setWatcher(FlagWatcher newWatcher) {
if (!getType().getWatcherClass().isInstance(newWatcher)) { if (!getType().getWatcherClass().isInstance(newWatcher)) {
throw new IllegalArgumentException(newWatcher.getClass().getSimpleName() + " is not a instance of " throw new IllegalArgumentException(
+ getType().getWatcherClass().getSimpleName() + " for DisguiseType " + getType().name()); newWatcher.getClass().getSimpleName() + " is not a instance of " + getType().getWatcherClass().getSimpleName() + " for DisguiseType " + getType().name());
} }
watcher = newWatcher; watcher = newWatcher;
@ -823,8 +796,9 @@ public abstract class Disguise {
if (disguise.isDisplayedInTab()) { if (disguise.isDisplayedInTab()) {
PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Arrays.asList(new PlayerInfoData(disguise.getGameProfile(), 0, addTab.getPlayerInfoDataLists().write(0, Arrays.asList(
NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(disguise.getName())))); new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getName()))));
try { try {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
@ -861,8 +835,8 @@ public abstract class Disguise {
if (isHidePlayer() && getEntity() instanceof Player) { if (isHidePlayer() && getEntity() instanceof Player) {
PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); addTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
addTab.getPlayerInfoDataLists().write(0, addTab.getPlayerInfoDataLists().write(0, Arrays.asList(
Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0,
NativeGameMode.SURVIVAL, WrappedChatComponent.fromText("")))); NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(""))));
try { try {

View File

@ -1,12 +1,17 @@
package me.libraryaddict.disguise.disguisetypes; package me.libraryaddict.disguise.disguisetypes;
import java.lang.reflect.InvocationTargetException; import com.comphenix.protocol.PacketType.Play.Server;
import java.util.ArrayList; import com.comphenix.protocol.ProtocolLibrary;
import java.util.Arrays; import com.comphenix.protocol.events.PacketContainer;
import java.util.HashMap; import com.comphenix.protocol.reflect.StructureModifier;
import java.util.HashSet; import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import java.util.List; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.ReflectionManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,30 +19,37 @@ import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.PacketType.Play.Server; import java.io.IOException;
import com.comphenix.protocol.ProtocolLibrary; import java.io.Serializable;
import com.comphenix.protocol.events.PacketContainer; import java.lang.reflect.InvocationTargetException;
import com.comphenix.protocol.reflect.StructureModifier; import java.util.*;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import me.libraryaddict.disguise.DisguiseAPI; public class FlagWatcher implements Serializable {
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.ReflectionManager;
public class FlagWatcher {
private boolean addEntityAnimations = DisguiseConfig.isEntityAnimationsAdded(); private boolean addEntityAnimations = DisguiseConfig.isEntityAnimationsAdded();
/** /**
* These are the entity values I need to add else it could crash them.. * These are the entity values I need to add else it could crash them..
*/ */
private HashMap<Integer, Object> backupEntityValues = new HashMap<>(); private HashMap<Integer, Object> backupEntityValues = new HashMap<>();
private TargetedDisguise disguise; private transient TargetedDisguise disguise;
private HashMap<Integer, Object> entityValues = new HashMap<>(); private HashMap<Integer, Object> entityValues = new HashMap<>();
private LibsEquipment equipment; private LibsEquipment equipment;
private boolean hasDied; private boolean hasDied;
private boolean[] modifiedEntityAnimations = new boolean[8]; private boolean[] modifiedEntityAnimations = new boolean[8];
private List<WrappedWatchableObject> watchableObjects; private transient List<WrappedWatchableObject> watchableObjects;
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.writeBoolean(isEntityAnimationsAdded());
out.
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
profile = new WrappedGameProfile((UUID) in.readObject(), in.readUTF());
for (int i = in.readByte(); i > 0; i--) {
profile.getProperties().put(in.readUTF(),
new WrappedSignedProperty(in.readUTF(), in.readUTF(), in.readUTF()));
}
}
public FlagWatcher(Disguise disguise) { public FlagWatcher(Disguise disguise) {
this.disguise = (TargetedDisguise) disguise; this.disguise = (TargetedDisguise) disguise;
@ -97,8 +109,7 @@ public class FlagWatcher {
} }
value = entityValues.get(id); value = entityValues.get(id);
} } else if (backupEntityValues.containsKey(id)) {
else if (backupEntityValues.containsKey(id)) {
if (backupEntityValues.get(id) == null) { if (backupEntityValues.get(id) == null) {
continue; continue;
} }
@ -121,8 +132,7 @@ public class FlagWatcher {
if (!isDirty) { if (!isDirty) {
watch.setDirtyState(false); watch.setDirtyState(false);
} }
} } else {
else {
boolean isDirty = watch.getDirtyState(); boolean isDirty = watch.getDirtyState();
watch = ReflectionManager.createWatchable(id, watch.getValue()); watch = ReflectionManager.createWatchable(id, watch.getValue());
@ -160,8 +170,7 @@ public class FlagWatcher {
} }
} }
// Here we check for if there is a health packet that says they died. // Here we check for if there is a health packet that says they died.
if (getDisguise().isSelfDisguiseVisible() && getDisguise().getEntity() != null if (getDisguise().isSelfDisguiseVisible() && getDisguise().getEntity() != null && getDisguise().getEntity() instanceof Player) {
&& getDisguise().getEntity() instanceof Player) {
for (WrappedWatchableObject watch : newList) { for (WrappedWatchableObject watch : newList) {
// Its a health packet // Its a health packet
if (watch.getIndex() == 6) { if (watch.getIndex() == 6) {
@ -173,19 +182,20 @@ public class FlagWatcher {
if (newHealth > 0 && hasDied) { if (newHealth > 0 && hasDied) {
hasDied = false; hasDied = false;
Bukkit.getScheduler().scheduleSyncDelayedTask(DisguiseUtilities.getPlugin(), new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(DisguiseUtilities.getPlugin(),
new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
DisguiseUtilities.sendSelfDisguise((Player) getDisguise().getEntity(), disguise); DisguiseUtilities.sendSelfDisguise((Player) getDisguise().getEntity(),
disguise);
} }
catch (Exception ex) { catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
} }
}, 2); }, 2);
} } else if (newHealth <= 0 && !hasDied) {
else if (newHealth <= 0 && !hasDied) {
hasDied = true; hasDied = true;
} }
} }
@ -300,11 +310,9 @@ public class FlagWatcher {
if (entityValues.containsKey(i) && entityValues.get(i) != null) { if (entityValues.containsKey(i) && entityValues.get(i) != null) {
watchable = ReflectionManager.createWatchable(i, entityValues.get(i)); watchable = ReflectionManager.createWatchable(i, entityValues.get(i));
} } else if (backupEntityValues.containsKey(i) && backupEntityValues.get(i) != null) {
else if (backupEntityValues.containsKey(i) && backupEntityValues.get(i) != null) {
watchable = ReflectionManager.createWatchable(i, backupEntityValues.get(i)); watchable = ReflectionManager.createWatchable(i, backupEntityValues.get(i));
} } else {
else {
continue; continue;
} }
@ -330,7 +338,8 @@ public class FlagWatcher {
Object value = entityValues.get(data.getIndex()); Object value = entityValues.get(data.getIndex());
if (isEntityAnimationsAdded() && DisguiseConfig.isMetadataPacketsEnabled() && data == MetaIndex.ENTITY_META) { if (isEntityAnimationsAdded() && DisguiseConfig.isMetadataPacketsEnabled() && data == MetaIndex.ENTITY_META) {
value = addEntityAnimations((byte) value, WrappedDataWatcher.getEntityWatcher(disguise.getEntity()).getByte(0)); value = addEntityAnimations((byte) value,
WrappedDataWatcher.getEntityWatcher(disguise.getEntity()).getByte(0));
} }
WrappedWatchableObject watch = ReflectionManager.createWatchable(data.getIndex(), value); WrappedWatchableObject watch = ReflectionManager.createWatchable(data.getIndex(), value);
@ -356,8 +365,7 @@ public class FlagWatcher {
temp.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); temp.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
ProtocolLibrary.getProtocolManager().sendServerPacket(player, temp); ProtocolLibrary.getProtocolManager().sendServerPacket(player, temp);
} } else {
else {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
} }
} }
@ -407,8 +415,7 @@ public class FlagWatcher {
if (flag) { if (flag) {
setData(MetaIndex.ENTITY_META, (byte) (b0 | 1 << byteValue)); setData(MetaIndex.ENTITY_META, (byte) (b0 | 1 << byteValue));
} } else {
else {
setData(MetaIndex.ENTITY_META, (byte) (b0 & ~(1 << byteValue))); setData(MetaIndex.ENTITY_META, (byte) (b0 & ~(1 << byteValue)));
} }
} }
@ -453,8 +460,8 @@ public class FlagWatcher {
} }
protected void sendItemStack(EquipmentSlot slot, ItemStack itemStack) { protected void sendItemStack(EquipmentSlot slot, ItemStack itemStack) {
if (!DisguiseAPI.isDisguiseInUse(getDisguise()) || getDisguise().getWatcher() != this if (!DisguiseAPI.isDisguiseInUse(
|| getDisguise().getEntity() == null) getDisguise()) || getDisguise().getWatcher() != this || getDisguise().getEntity() == null)
return; return;
if (itemStack == null && getDisguise().getEntity() instanceof LivingEntity) { if (itemStack == null && getDisguise().getEntity() instanceof LivingEntity) {
@ -536,4 +543,7 @@ public class FlagWatcher {
} }
} }
protected void setDisguise(TargetedDisguise disguise) {
this.disguise = disguise;
}
} }

View File

@ -5,7 +5,9 @@ import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class LibsEquipment implements EntityEquipment { import java.io.Serializable;
public class LibsEquipment implements EntityEquipment, Serializable {
private ItemStack[] equipment = new ItemStack[EquipmentSlot.values().length]; private ItemStack[] equipment = new ItemStack[EquipmentSlot.values().length];
private FlagWatcher flagWatcher; private FlagWatcher flagWatcher;

View File

@ -1,14 +1,5 @@
package me.libraryaddict.disguise.disguisetypes; package me.libraryaddict.disguise.disguisetypes;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.UUID;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
@ -17,16 +8,24 @@ import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData; import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.LibsProfileLookup; import me.libraryaddict.disguise.utilities.LibsProfileLookup;
import me.libraryaddict.disguise.utilities.WrappedProfile;
import me.libraryaddict.disguise.utilities.ReflectionManager; import me.libraryaddict.disguise.utilities.ReflectionManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.UUID;
public class PlayerDisguise extends TargetedDisguise { public class PlayerDisguise extends TargetedDisguise {
private LibsProfileLookup currentLookup; private transient LibsProfileLookup currentLookup;
private WrappedGameProfile gameProfile; private WrappedProfile gameProfile;
private String playerName; private String playerName;
private String skinToUse; private String skinToUse;
private UUID uuid = UUID.randomUUID(); private UUID uuid = UUID.randomUUID();
@ -66,7 +65,8 @@ public class PlayerDisguise extends TargetedDisguise {
setName(gameProfile.getName()); setName(gameProfile.getName());
this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile); this.gameProfile = new WrappedProfile(
ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile));
createDisguise(); createDisguise();
} }
@ -76,7 +76,7 @@ public class PlayerDisguise extends TargetedDisguise {
setName(gameProfile.getName()); setName(gameProfile.getName());
this.gameProfile = ReflectionManager.getGameProfile(uuid, gameProfile.getName()); this.gameProfile = new WrappedProfile(ReflectionManager.getGameProfile(uuid, gameProfile.getName()));
setSkin(skinToUse); setSkin(skinToUse);
@ -101,8 +101,9 @@ public class PlayerDisguise extends TargetedDisguise {
if (currentLookup == null && gameProfile != null) { if (currentLookup == null && gameProfile != null) {
disguise.skinToUse = getSkin(); disguise.skinToUse = getSkin();
disguise.gameProfile = ReflectionManager.getGameProfileWithThisSkin(disguise.uuid, disguise.gameProfile = new WrappedProfile(
getGameProfile().getName(), getGameProfile()); ReflectionManager.getGameProfileWithThisSkin(disguise.uuid, getGameProfile().getName(),
getGameProfile()));
} else { } else {
disguise.setSkin(getSkin()); disguise.setSkin(getSkin());
} }
@ -127,14 +128,14 @@ public class PlayerDisguise extends TargetedDisguise {
public WrappedGameProfile getGameProfile() { public WrappedGameProfile getGameProfile() {
if (gameProfile == null) { if (gameProfile == null) {
if (getSkin() != null) { if (getSkin() != null) {
gameProfile = ReflectionManager.getGameProfile(uuid, getName()); gameProfile = new WrappedProfile(ReflectionManager.getGameProfile(uuid, getName()));
} else { } else {
gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile = new WrappedProfile(ReflectionManager.getGameProfileWithThisSkin(uuid, getName(),
DisguiseUtilities.getProfileFromMojang(this)); DisguiseUtilities.getProfileFromMojang(this)));
} }
} }
return gameProfile; return gameProfile.getProfile();
} }
public String getName() { public String getName() {
@ -184,7 +185,8 @@ public class PlayerDisguise extends TargetedDisguise {
} }
public void setGameProfile(WrappedGameProfile gameProfile) { public void setGameProfile(WrappedGameProfile gameProfile) {
this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile); this.gameProfile = new WrappedProfile(
ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile));
} }
@Override @Override
@ -304,7 +306,8 @@ public class PlayerDisguise extends TargetedDisguise {
currentLookup = null; currentLookup = null;
this.skinToUse = gameProfile.getName(); this.skinToUse = gameProfile.getName();
this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile); this.gameProfile = new WrappedProfile(
ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile));
if (DisguiseUtilities.isDisguiseInUse(this)) { if (DisguiseUtilities.isDisguiseInUse(this)) {
if (isDisplayedInTab()) { if (isDisplayedInTab()) {

View File

@ -1,27 +1,30 @@
package me.libraryaddict.disguise.utilities; package me.libraryaddict.disguise.utilities;
import java.lang.reflect.Array; import com.comphenix.protocol.PacketType;
import java.lang.reflect.Field; import com.comphenix.protocol.PacketType.Play.Server;
import java.lang.reflect.InvocationTargetException; import com.comphenix.protocol.ProtocolLibrary;
import java.lang.reflect.Method; import com.comphenix.protocol.ProtocolManager;
import java.util.ArrayList; import com.comphenix.protocol.events.PacketContainer;
import java.util.HashMap; import com.comphenix.protocol.reflect.StructureModifier;
import java.util.HashSet; import com.comphenix.protocol.wrappers.BlockPosition;
import java.util.Iterator; import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import java.util.LinkedHashMap; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import java.util.List; import me.libraryaddict.disguise.DisguiseAPI;
import java.util.Map; import me.libraryaddict.disguise.DisguiseConfig;
import java.util.Random; import me.libraryaddict.disguise.DisguiseConfig.DisguisePushing;
import java.util.Set; import me.libraryaddict.disguise.LibsDisguises;
import java.util.UUID; import me.libraryaddict.disguise.disguisetypes.Disguise;
import java.util.regex.Pattern; import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import org.bukkit.Bukkit; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
import org.bukkit.ChatColor; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
import org.bukkit.Location; import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import org.bukkit.Material; import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
import org.bukkit.World; import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets;
import org.bukkit.*;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Ageable; import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -36,37 +39,16 @@ import org.bukkit.scoreboard.Team.Option;
import org.bukkit.scoreboard.Team.OptionStatus; import org.bukkit.scoreboard.Team.OptionStatus;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType; import java.io.*;
import com.comphenix.protocol.PacketType.Play.Server; import java.lang.reflect.Array;
import com.comphenix.protocol.ProtocolLibrary; import java.lang.reflect.Field;
import com.comphenix.protocol.ProtocolManager; import java.lang.reflect.InvocationTargetException;
import com.comphenix.protocol.events.PacketContainer; import java.lang.reflect.Method;
import com.comphenix.protocol.reflect.StructureModifier; import java.util.*;
import com.comphenix.protocol.wrappers.BlockPosition; import java.util.regex.Pattern;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.DisguiseConfig.DisguisePushing;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
import me.libraryaddict.disguise.utilities.PacketsManager.LibsPackets;
public class DisguiseUtilities { public class DisguiseUtilities {
public static final Random random = new Random(); public static final Random random = new Random();
/**
* This is a list of names which was called by other plugins. As such, don't remove from the gameProfiles as its the duty of
* the plugin to do that.
*/
private static HashSet<String> addedByPlugins = new HashSet<>();
private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<>(); private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<>();
/** /**
* A hashmap of the uuid's of entitys, alive and dead. And their disguises in use * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use
@ -77,16 +59,16 @@ public class DisguiseUtilities {
* a max of a second. * a max of a second.
*/ */
private static HashMap<Integer, HashSet<TargetedDisguise>> futureDisguises = new HashMap<>(); private static HashMap<Integer, HashSet<TargetedDisguise>> futureDisguises = new HashMap<>();
/** private static HashSet<UUID> savedDisguiseList = new HashSet<>();
* A hashmap storing the uuid and skin of a playername private static HashSet<String> cachedNames = new HashSet<>();
*/
private static HashMap<String, WrappedGameProfile> gameProfiles = new HashMap<>();
private static LibsDisguises libsDisguises; private static LibsDisguises libsDisguises;
private static HashMap<String, ArrayList<Object>> runnables = new HashMap<>(); private static HashMap<String, ArrayList<Object>> runnables = new HashMap<>();
private static HashSet<UUID> selfDisguised = new HashSet<>(); private static HashSet<UUID> selfDisguised = new HashSet<>();
private static Thread mainThread; private static Thread mainThread;
private static PacketContainer spawnChunk; private static PacketContainer spawnChunk;
private static HashMap<UUID, String> preDisguiseTeam = new HashMap<UUID, String>(); private static HashMap<UUID, String> preDisguiseTeam = new HashMap<>();
private static File profileCache = new File("plugins/LibsDisguises/GameProfiles"), savedDisguises = new File(
"plugins/LibsDisguises/SavedDisguises");
static { static {
try { try {
@ -142,6 +124,10 @@ public class DisguiseUtilities {
} }
} }
public static boolean hasCacheEntry(String playername) {
return cachedNames.contains(playername.toLowerCase());
}
public static void createClonedDisguise(Player player, Entity toClone, Boolean[] options) { public static void createClonedDisguise(Player player, Entity toClone, Boolean[] options) {
Disguise disguise = DisguiseAPI.getDisguise(player, toClone); Disguise disguise = DisguiseAPI.getDisguise(player, toClone);
@ -177,10 +163,103 @@ public class DisguiseUtilities {
player.sendMessage(ChatColor.RED + "Example usage: /disguise " + reference); player.sendMessage(ChatColor.RED + "Example usage: /disguise " + reference);
} else { } else {
player.sendMessage( player.sendMessage(
ChatColor.RED + "Failed to store the reference, too many cloned disguises. Please set this in the config"); ChatColor.RED + "Failed to store the reference, too many cloned disguises. Please raise the " +
"maximum cloned disguises, or lower the time they last");
} }
} }
private static void saveDisguiseToFile
public static void saveDisguises(UUID owningEntity, Disguise[] disguise) {
try {
File disguiseFile = new File(savedDisguises, owningEntity.toString());
if (disguise == null || disguise.length == 0) {
if (savedDisguiseList.contains(owningEntity)) {
disguiseFile.delete();
} else {
return;
}
} else {
Disguise[] disguises = new Disguise[disguise.length];
for (int i = 0; i < disguise.length; i++) {
Disguise dis = disguise[i].clone();
dis.setEntity(null);
disguises[i] = dis;
}
FileOutputStream files = new FileOutputStream(disguiseFile);
ObjectOutputStream obj = new ObjectOutputStream(files);
obj.writeObject(disguises);
savedDisguiseList.add(owningEntity);
obj.close();
files.close();
}
savedDisguises.save(new File(libsDisguises.getDataFolder(), "saveddisguises.yml"));
}
catch (Exception e) {
e.printStackTrace();
}
}
public static Disguise[] getSavedDisguises(UUID entityUUID) {
return getSavedDisguises(entityUUID, false);
}
public static Disguise[] getSavedDisguises(UUID entityUUID, boolean remove) {
if (isSavedDisguise(entityUUID))
return new Disguise[0];
String cached = savedDisguises.getString(entityUUID.toString());
if (cached == null) {
cachedNames.remove(entityUUID.toString());
return new Disguise[0];
}
try {
ObjectInputStream outputStream = new ObjectInputStream(new ByteArrayInputStream(cached.getBytes()));
Disguise[] toReturn = (Disguise[]) outputStream.readObject();
if (remove) {
removeSavedDisguise(entityUUID);
}
return toReturn;
}
catch (Exception e) {
System.out.println("Error while loading Entity Disguises, malformed config?");
e.printStackTrace();
}
return new Disguise[0];
}
public static void removeSavedDisguise(UUID entityUUID) {
if (!savedDisguiseList.remove(entityUUID))
return;
savedDisguises.set(entityUUID.toString(), null);
try {
savedDisguises.save(new File(libsDisguises.getDataFolder(), "saveddisguises.yml"));
}
catch (IOException e) {
e.printStackTrace();
}
}
public static boolean isSavedDisguise(UUID entityUUID) {
return savedDisguiseList.contains(entityUUID);
}
public static boolean addClonedDisguise(String key, Disguise disguise) { public static boolean addClonedDisguise(String key, Disguise disguise) {
if (DisguiseConfig.getMaxClonedDisguises() > 0) { if (DisguiseConfig.getMaxClonedDisguises() > 0) {
if (clonedDisguises.containsKey(key)) { if (clonedDisguises.containsKey(key)) {
@ -250,8 +329,21 @@ public class DisguiseUtilities {
} }
public static void addGameProfile(String string, WrappedGameProfile gameProfile) { public static void addGameProfile(String string, WrappedGameProfile gameProfile) {
getGameProfiles().put(string, gameProfile); try {
getAddedByPlugins().add(string.toLowerCase()); ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ObjectOutputStream obj = new ObjectOutputStream(bytes);
obj.writeObject(new WrappedProfile(gameProfile));
gameProfileCache.set(string.toLowerCase(), new String(bytes.toByteArray()));
cachedNames.add(string.toLowerCase());
if (DisguiseConfig.isSaveCache()) {
gameProfileCache.save(new File(libsDisguises.getDataFolder(), "cache.yml"));
}
}
catch (Exception ex) {
ex.printStackTrace();
}
} }
/** /**
@ -388,10 +480,6 @@ public class DisguiseUtilities {
} }
} }
public static HashSet<String> getAddedByPlugins() {
return addedByPlugins;
}
public static int getChunkCord(int blockCord) { public static int getChunkCord(int blockCord) {
int cord = (int) Math.floor(blockCord / 16D) - 17; int cord = (int) Math.floor(blockCord / 16D) - 17;
@ -511,11 +599,26 @@ public class DisguiseUtilities {
} }
public static WrappedGameProfile getGameProfile(String playerName) { public static WrappedGameProfile getGameProfile(String playerName) {
return gameProfiles.get(playerName.toLowerCase()); if (!cachedNames.contains(playerName.toLowerCase()))
return null;
String cached = gameProfileCache.getString(playerName.toLowerCase());
if (cached == null) {
cachedNames.remove(playerName.toLowerCase());
return null;
} }
public static HashMap<String, WrappedGameProfile> getGameProfiles() { try {
return gameProfiles; ObjectInputStream outputStream = new ObjectInputStream(new ByteArrayInputStream(cached.getBytes()));
return ((WrappedProfile) outputStream.readObject()).getProfile();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
} }
public static TargetedDisguise getMainDisguise(UUID entityId) { public static TargetedDisguise getMainDisguise(UUID entityId) {
@ -577,18 +680,13 @@ public class DisguiseUtilities {
public static WrappedGameProfile getProfileFromMojang(final PlayerDisguise disguise) { public static WrappedGameProfile getProfileFromMojang(final PlayerDisguise disguise) {
final String nameToFetch = disguise.getSkin() != null ? disguise.getSkin() : disguise.getName(); final String nameToFetch = disguise.getSkin() != null ? disguise.getSkin() : disguise.getName();
final boolean remove = getAddedByPlugins().contains(nameToFetch.toLowerCase());
return getProfileFromMojang(nameToFetch, new LibsProfileLookup() { return getProfileFromMojang(nameToFetch, new LibsProfileLookup() {
@Override @Override
public void onLookup(WrappedGameProfile gameProfile) { public void onLookup(WrappedGameProfile gameProfile) {
if (remove) {
getAddedByPlugins().remove(nameToFetch.toLowerCase());
}
if (DisguiseAPI.isDisguiseInUse(disguise) && (!gameProfile.getName().equals( if (DisguiseAPI.isDisguiseInUse(disguise) && (!gameProfile.getName().equals(
disguise.getSkin() != null ? disguise.getSkin() : disguise.getName()) || !gameProfile.getProperties().isEmpty())) { disguise.getSkin() != null ? disguise.getSkin() :
disguise.getName()) || !gameProfile.getProperties().isEmpty())) {
disguise.setGameProfile(gameProfile); disguise.setGameProfile(gameProfile);
DisguiseUtilities.refreshTrackers(disguise); DisguiseUtilities.refreshTrackers(disguise);
@ -634,37 +732,22 @@ public class DisguiseUtilities {
boolean contactMojang) { boolean contactMojang) {
final String playerName = origName.toLowerCase(); final String playerName = origName.toLowerCase();
if (gameProfiles.containsKey(playerName)) { if (cachedNames.contains(playerName)) {
if (gameProfiles.get(playerName) != null) { return getGameProfile(playerName);
return gameProfiles.get(playerName);
}
} else if (Pattern.matches("([A-Za-z0-9_]){1,16}", origName)) { } else if (Pattern.matches("([A-Za-z0-9_]){1,16}", origName)) {
getAddedByPlugins().add(playerName); final Player player = Bukkit.getPlayerExact(playerName);
Player player = Bukkit.getPlayerExact(playerName);
if (player != null) { if (player != null) {
WrappedGameProfile gameProfile = ReflectionManager.getGameProfile(player); WrappedGameProfile gameProfile = ReflectionManager.getGameProfile(player);
if (!gameProfile.getProperties().isEmpty()) { if (!gameProfile.getProperties().isEmpty()) {
gameProfiles.put(playerName, gameProfile); addGameProfile(playerName, gameProfile);
return gameProfile; return gameProfile;
} }
} }
if (runnable != null && (contactMojang || gameProfiles.containsKey(playerName))) { if (contactMojang && !runnables.containsKey(playerName)) {
if (!runnables.containsKey(playerName)) {
runnables.put(playerName, new ArrayList<>());
}
runnables.get(playerName).add(runnable);
}
if (contactMojang) {
// Add null so that if this is called again. I already know I'm doing something about it
gameProfiles.put(playerName, null);
Bukkit.getScheduler().runTaskAsynchronously(libsDisguises, new Runnable() { Bukkit.getScheduler().runTaskAsynchronously(libsDisguises, new Runnable() {
@Override @Override
public void run() { public void run() {
@ -678,9 +761,7 @@ public class DisguiseUtilities {
return; return;
} }
if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) { addGameProfile(playerName, gameProfile);
gameProfiles.put(playerName, gameProfile);
}
if (runnables.containsKey(playerName)) { if (runnables.containsKey(playerName)) {
for (Object obj : runnables.remove(playerName)) { for (Object obj : runnables.remove(playerName)) {
@ -695,10 +776,7 @@ public class DisguiseUtilities {
}); });
} }
catch (Exception e) { catch (Exception e) {
if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) { runnables.remove(playerName);
gameProfiles.remove(playerName);
getAddedByPlugins().remove(playerName);
}
System.out.print( System.out.print(
"[LibsDisguises] Error when fetching " + playerName + "'s uuid from mojang: " + e.getMessage()); "[LibsDisguises] Error when fetching " + playerName + "'s uuid from mojang: " + e.getMessage());
@ -706,6 +784,14 @@ public class DisguiseUtilities {
} }
}); });
if (runnable != null && contactMojang) {
if (!runnables.containsKey(playerName)) {
runnables.put(playerName, new ArrayList<>());
}
runnables.get(playerName).add(runnable);
}
return null; return null;
} }
} }
@ -740,6 +826,16 @@ public class DisguiseUtilities {
public static void init(LibsDisguises disguises) { public static void init(LibsDisguises disguises) {
libsDisguises = disguises; libsDisguises = disguises;
gameProfileCache = YamlConfiguration.loadConfiguration(new File(disguises.getDataFolder(), "cache.yml"));
cachedNames.addAll(gameProfileCache.getKeys(false));
savedDisguises = YamlConfiguration.loadConfiguration(new File(disguises.getDataFolder(), "saveddisguises.yml"));
for (String key : savedDisguises.getKeys(false)) {
savedDisguiseList.add(UUID.fromString(key));
}
} }
public static boolean isDisguiseInUse(Disguise disguise) { public static boolean isDisguiseInUse(Disguise disguise) {
@ -809,7 +905,7 @@ public class DisguiseUtilities {
for (final Object p : trackedPlayers) { for (final Object p : trackedPlayers) {
Player pl = (Player) ReflectionManager.getBukkitEntity(p); Player pl = (Player) ReflectionManager.getBukkitEntity(p);
if (!player.equalsIgnoreCase((pl).getName())) if (pl == null || !player.equalsIgnoreCase((pl).getName()))
continue; continue;
clear.invoke(entityTrackerEntry, p); clear.invoke(entityTrackerEntry, p);
@ -991,7 +1087,17 @@ public class DisguiseUtilities {
} }
public static void removeGameProfile(String string) { public static void removeGameProfile(String string) {
gameProfiles.remove(string.toLowerCase()); cachedNames.remove(string.toLowerCase());
gameProfileCache.set(string.toLowerCase(), null);
if (DisguiseConfig.isSaveCache()) {
try {
gameProfileCache.save(new File(libsDisguises.getDataFolder(), "cache.yml"));
}
catch (IOException e) {
e.printStackTrace();
}
}
} }
public static void removeSelfDisguise(Player player) { public static void removeSelfDisguise(Player player) {

View File

@ -297,15 +297,6 @@ public class PacketsManager {
String name = playerDisguise.getName(); String name = playerDisguise.getName();
int entityId = disguisedEntity.getEntityId(); int entityId = disguisedEntity.getEntityId();
boolean removeName = false;
if (!DisguiseUtilities.hasGameProfile(name)) {
removeName = !DisguiseUtilities.getAddedByPlugins().contains(name);
}
if (removeName) {
DisguiseUtilities.getAddedByPlugins().remove(name);
}
// Send player info along with the disguise // Send player info along with the disguise
PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO); PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO);

View File

@ -627,10 +627,6 @@ public class ReflectionManager {
return null; return null;
} }
public static void removePlayer(Player player) {
// Some future remove code if needed
}
public static void setBoundingBox(Entity entity, FakeBoundingBox newBox) { public static void setBoundingBox(Entity entity, FakeBoundingBox newBox) {
try { try {
Location loc = entity.getLocation(); Location loc = entity.getLocation();
@ -888,15 +884,18 @@ public class ReflectionManager {
if (value instanceof Optional) { if (value instanceof Optional) {
Optional opt = (Optional) value; Optional opt = (Optional) value;
serializer = Registry.get((opt.isPresent() ? getNmsClass("IBlockData").isInstance(opt.get()) ? getNmsClass( serializer = Registry.get((opt.isPresent() ?
"IBlockData") : opt.get().getClass() : UUID.class), true); getNmsClass("IBlockData").isInstance(opt.get()) ? getNmsClass("IBlockData") : opt.get().getClass() :
UUID.class), true);
} else { } else {
serializer = Registry.get(value.getClass()); serializer = Registry.get(value.getClass());
} }
if (serializer == null) { if (serializer == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException("Unable to find Serializer for " + value + (
"Unable to find Serializer for " + value + (value instanceof Optional && ((Optional) value).isPresent() ? " (" + ((Optional) value).get().getClass().getName() + ")" : "") + "! Are you running the latest version of ProtocolLib?"); value instanceof Optional && ((Optional) value).isPresent() ?
" (" + ((Optional) value).get().getClass().getName() + ")" :
"") + "! Are you running the latest version of ProtocolLib?");
} }
WrappedDataWatcherObject watcherObject = new WrappedDataWatcherObject(id, serializer); WrappedDataWatcherObject watcherObject = new WrappedDataWatcherObject(id, serializer);

View File

@ -0,0 +1,48 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;
/**
* Created by libraryaddict on 15/05/2017.
*/
public class WrappedProfile implements Serializable {
private WrappedGameProfile profile;
public WrappedProfile(WrappedGameProfile profile) {
this.profile = profile;
}
public WrappedGameProfile getProfile() {
return profile;
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.writeObject(profile.getUUID());
out.writeObject(profile.getName());
out.writeByte(profile.getProperties().size());
for (Map.Entry<String, WrappedSignedProperty> entry : profile.getProperties().entries()) {
WrappedSignedProperty property = entry.getValue();
out.writeUTF(entry.getKey());
out.writeUTF(property.getName());
out.writeUTF(property.getSignature());
out.writeUTF(property.getValue());
}
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
profile = new WrappedGameProfile((UUID) in.readObject(), in.readUTF());
for (int i = in.readByte(); i > 0; i--) {
profile.getProperties().put(in.readUTF(),
new WrappedSignedProperty(in.readUTF(), in.readUTF(), in.readUTF()));
}
}
}