diff --git a/config.yml b/config.yml index e953df47..3cc147c0 100644 --- a/config.yml +++ b/config.yml @@ -5,41 +5,23 @@ NotifyUpdate: true # 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 +SaveGameProfiles: 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 +UpdateGameProfiles: 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 +# If you are using the dev builds, place your premium version of Lib's Disguises.jar inside the LibsDisguises folder 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 +# Does the player keep their disguise after they die? KeepDisguises: - EntityDespawn: false PlayerDeath: false # How should the plugin handle self disguises scoreboards? diff --git a/src/me/libraryaddict/disguise/DisguiseConfig.java b/src/me/libraryaddict/disguise/DisguiseConfig.java index 1f25f511..d1b0a238 100644 --- a/src/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/me/libraryaddict/disguise/DisguiseConfig.java @@ -38,9 +38,7 @@ public class DisguiseConfig { private static boolean hideDisguisedPlayers; private static boolean hidingArmor; private static boolean hidingHeldItem; - private static boolean keepDisguiseEntityDespawn; private static boolean keepDisguisePlayerDeath; - private static boolean keepDisguisePlayerLogout; private static int maxClonedDisguises; private static boolean maxHealthIsDisguisedEntity; private static boolean miscDisguisesForLivingEnabled; @@ -62,32 +60,6 @@ public class DisguiseConfig { 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 getCustomDisguise(String disguise) { for (Entry entry : customDisguises.entrySet()) { @@ -149,19 +121,19 @@ public class DisguiseConfig { return updateNotificationPermission; } - public static boolean isSaveCache() { + public static boolean isSaveGameProfiles() { return saveCache; } - public static void setSaveCache(boolean doCache) { + public static void setSaveGameProfiles(boolean doCache) { saveCache = doCache; } - public static boolean isUpdatePlayerCache() { + public static boolean isUpdateGameProfiles() { return updatePlayerCache; } - public static void setUpdatePlayerCache(boolean setUpdatePlayerCache) { + public static void setUpdateGameProfiles(boolean setUpdatePlayerCache) { updatePlayerCache = setUpdatePlayerCache; } @@ -183,8 +155,6 @@ public class DisguiseConfig { setDisguiseBlownOnAttack(config.getBoolean("BlowDisguises")); setDisguiseBlownMessage(ChatColor.translateAlternateColorCodes('&', config.getString("BlownDisguiseMessage"))); setKeepDisguiseOnPlayerDeath(config.getBoolean("KeepDisguises.PlayerDeath")); - setKeepDisguiseOnPlayerLogout(config.getBoolean("KeepDisguises.PlayerLogout")); - setKeepDisguiseOnEntityDespawn(config.getBoolean("KeepDisguises.EntityDespawn")); setMiscDisguisesForLivingEnabled(config.getBoolean("MiscDisguisesForLiving")); setMovementPacketsEnabled(config.getBoolean("PacketsEnabled.Movement")); setWitherSkullPacketsEnabled(config.getBoolean("PacketsEnabled.WitherSkull")); @@ -206,15 +176,10 @@ public class DisguiseConfig { setHideDisguisedPlayers(config.getBoolean("HideDisguisedPlayersFromTab")); setShowDisguisedPlayersInTab(config.getBoolean("ShowPlayerDisguisesInTab")); setDisabledInvisibility(config.getBoolean("DisableInvisibility")); - setSaveCache(config.getBoolean("SaveCache")); - setUpdatePlayerCache(config.getBoolean("UpdatePlayerCache")); - setSaveEntityDisguises(config.getBoolean("SaveDisguises.Entities")); + setSaveGameProfiles(config.getBoolean("SaveGameProfiles")); + setUpdateGameProfiles(config.getBoolean("UpdateGameProfiles")); 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 + setSaveEntityDisguises(config.getBoolean("SaveDisguises.Entities")); try { String option = config.getString("SelfDisguisesScoreboard", @@ -330,18 +295,10 @@ public class DisguiseConfig { return hidingHeldItem; } - public static boolean isKeepDisguiseOnEntityDespawn() { - return keepDisguiseEntityDespawn; - } - public static boolean isKeepDisguiseOnPlayerDeath() { return keepDisguisePlayerDeath; } - public static boolean isKeepDisguiseOnPlayerLogout() { - return keepDisguisePlayerLogout; - } - public static boolean isMaxHealthDeterminedByDisguisedEntity() { return maxHealthIsDisguisedEntity; } @@ -526,18 +483,10 @@ public class DisguiseConfig { } } - public static void setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { - keepDisguiseEntityDespawn = keepDisguise; - } - public static void setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { keepDisguisePlayerDeath = keepDisguise; } - public static void setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { - keepDisguisePlayerLogout = keepDisguise; - } - public static void setMaxClonedDisguises(int newMax) { maxClonedDisguises = newMax; } diff --git a/src/me/libraryaddict/disguise/DisguiseListener.java b/src/me/libraryaddict/disguise/DisguiseListener.java index a152db30..7bf5557b 100644 --- a/src/me/libraryaddict/disguise/DisguiseListener.java +++ b/src/me/libraryaddict/disguise/DisguiseListener.java @@ -1,37 +1,5 @@ package me.libraryaddict.disguise; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; - -import com.comphenix.protocol.wrappers.WrappedGameProfile; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityTargetEvent; -import org.bukkit.event.player.PlayerChangedWorldEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.event.player.PlayerTeleportEvent; -import org.bukkit.event.vehicle.VehicleEnterEvent; -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.BukkitTask; - import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; @@ -39,7 +7,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; import com.comphenix.protocol.wrappers.PlayerInfoData; import com.comphenix.protocol.wrappers.WrappedChatComponent; - +import com.comphenix.protocol.wrappers.WrappedGameProfile; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; @@ -49,8 +17,34 @@ import me.libraryaddict.disguise.utilities.DisguiseParser; import me.libraryaddict.disguise.utilities.DisguiseParser.DisguiseParseException; import me.libraryaddict.disguise.utilities.DisguiseParser.DisguisePerm; import me.libraryaddict.disguise.utilities.DisguiseUtilities; -import me.libraryaddict.disguise.utilities.ReflectionManager; import me.libraryaddict.disguise.utilities.UpdateChecker; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.player.*; +import org.bukkit.event.vehicle.VehicleEnterEvent; +import org.bukkit.event.vehicle.VehicleExitEvent; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; public class DisguiseListener implements Listener { @@ -106,6 +100,23 @@ public class DisguiseListener implements Listener { }, 0, (20 * 60 * 60 * 6)); // Check every 6 hours // 20 ticks * 60 seconds * 60 minutes * 6 hours } + + if (!DisguiseConfig.isSaveEntityDisguises()) + return; + + for (World world : Bukkit.getWorlds()) { + for (Entity entity : world.getEntities()) { + Disguise[] disguises = DisguiseUtilities.getSavedDisguises(entity.getUniqueId(), true); + + if (disguises.length <= 0) + continue; + + for (Disguise disguise : disguises) { + disguise.setEntity(entity); + disguise.startDisguise(); + } + } + } } public void cleanup() { @@ -208,13 +219,49 @@ public class DisguiseListener implements Listener { } } + @EventHandler + public void onChunkUnload(WorldUnloadEvent event) { + if (!DisguiseConfig.isSaveEntityDisguises()) + return; + + for (Entity entity : event.getWorld().getEntities()) { + if (entity instanceof Player) + continue; + + 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()); + Disguise[] disguises = DisguiseUtilities.getSavedDisguises(entity.getUniqueId(), true); + + if (disguises.length <= 0) + continue; + + for (Disguise disguise : disguises) { + disguise.setEntity(entity); + disguise.startDisguise(); + } + } + } + + @EventHandler + public void onWorldLoad(WorldLoadEvent event) { + if (!DisguiseConfig.isSaveEntityDisguises()) + return; + + for (Entity entity : event.getWorld().getEntities()) { + Disguise[] disguises = DisguiseUtilities.getSavedDisguises(entity.getUniqueId(), true); if (disguises.length <= 0) continue; @@ -238,7 +285,7 @@ public class DisguiseListener implements Listener { chunkMove(p, p.getLocation(), null); } - if (DisguiseConfig.isSaveCache() && DisguiseConfig.isUpdatePlayerCache() && DisguiseUtilities.hasCacheEntry( + if (DisguiseConfig.isSaveGameProfiles() && DisguiseConfig.isUpdateGameProfiles() && DisguiseUtilities.hasGameProfile( p.getName())) { WrappedGameProfile profile = WrappedGameProfile.fromPlayer(p); @@ -248,7 +295,7 @@ public class DisguiseListener implements Listener { } if (DisguiseConfig.isSavePlayerDisguises()) { - Disguise[] disguises = DisguiseUtilities.getSavedDisguises(p.getUniqueId()); + Disguise[] disguises = DisguiseUtilities.getSavedDisguises(p.getUniqueId(), true); for (Disguise disguise : disguises) { disguise.setEntity(p); diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index 484d479e..b3b9f7a7 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -134,6 +134,11 @@ public class LibsDisguises extends JavaPlugin { } } + @Override + public void onDisable() { + DisguiseUtilities.saveDisguises(); + } + private void registerCommand(String commandName, CommandExecutor executioner) { PluginCommand command = getCommand(commandName); diff --git a/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java b/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java index 8c928529..9351fb6f 100644 --- a/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java +++ b/src/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.LibVersion; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; @@ -51,13 +53,13 @@ public class LibsDisguisesCommand implements CommandExecutor, TabCompleter { @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if (args.length == 0) { - sender.sendMessage(ChatColor.DARK_GREEN + "This server is running " + "Lib's Disguises v." + sender.sendMessage(ChatColor.DARK_GREEN + "This server is running " + "Lib's Disguises v" + Bukkit.getPluginManager().getPlugin("LibsDisguises").getDescription().getVersion() + " by libraryaddict, formerly maintained by Byteflux and NavidK0.\n" + "Use " + ChatColor.GREEN + "/libsdisguises reload" + ChatColor.DARK_GREEN + " to reload the config. All disguises will be blown by doing this."); - if (!"%%__USER__%%".contains("__USER__")) { + if (LibVersion.isPremium()) { sender.sendMessage(ChatColor.DARK_GREEN + "This server supports the plugin developer!"); } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java index 2549d9c7..85c148a8 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -33,8 +33,8 @@ import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.*; -public abstract class Disguise implements Serializable { - private transient static List viewSelf = new ArrayList<>(); +public abstract class Disguise { + private static List viewSelf = new ArrayList<>(); /** * Returns the list of people who have /disguiseViewSelf toggled on @@ -51,15 +51,13 @@ public abstract class Disguise implements Serializable { private boolean hearSelfDisguise = DisguiseConfig.isSelfDisguisesSoundsReplaced(); private boolean hideArmorFromSelf = DisguiseConfig.isHidingArmorFromSelf(); private boolean hideHeldItemFromSelf = DisguiseConfig.isHidingHeldItemFromSelf(); - private boolean keepDisguiseEntityDespawn = DisguiseConfig.isKeepDisguiseOnEntityDespawn(); private boolean keepDisguisePlayerDeath = DisguiseConfig.isKeepDisguiseOnPlayerDeath(); - private boolean keepDisguisePlayerLogout = DisguiseConfig.isKeepDisguiseOnPlayerLogout(); private boolean modifyBoundingBox = DisguiseConfig.isModifyBoundingBox(); private boolean playerHiddenFromTab = DisguiseConfig.isHideDisguisedPlayers(); private boolean replaceSounds = DisguiseConfig.isSoundEnabled(); private boolean showName; private transient BukkitTask task; - private transient Runnable velocityRunnable; + private Runnable velocityRunnable; private boolean velocitySent = DisguiseConfig.isVelocitySent(); private boolean viewSelfDisguise = DisguiseConfig.isViewDisguises(); private FlagWatcher watcher; @@ -93,7 +91,7 @@ public abstract class Disguise implements Serializable { if (getWatcher() == null) { try { // Construct the FlagWatcher from the stored class - setWatcher((FlagWatcher) getType().getWatcherClass().getConstructor(Disguise.class).newInstance(this)); + setWatcher(getType().getWatcherClass().getConstructor(Disguise.class).newInstance(this)); } catch (Exception e) { e.printStackTrace(); @@ -110,7 +108,9 @@ public abstract class Disguise implements Serializable { ((ZombieWatcher) getWatcher()).setBaby(true); } } + } + private void createRunnable() { final boolean alwaysSendVelocity; switch (getType()) { @@ -418,18 +418,10 @@ public abstract class Disguise implements Serializable { return hideHeldItemFromSelf; } - public boolean isKeepDisguiseOnEntityDespawn() { - return this.keepDisguiseEntityDespawn; - } - public boolean isKeepDisguiseOnPlayerDeath() { return this.keepDisguisePlayerDeath; } - public boolean isKeepDisguiseOnPlayerLogout() { - return this.keepDisguisePlayerLogout; - } - public boolean isMiscDisguise() { return false; } @@ -450,9 +442,8 @@ public abstract class Disguise implements Serializable { * Internal use */ public boolean isRemoveDisguiseOnDeath() { - return getEntity() == null || (getEntity() instanceof Player ? - (!((Player) getEntity()).isOnline() ? !isKeepDisguiseOnPlayerLogout() : - !isKeepDisguiseOnPlayerDeath()) : (!isKeepDisguiseOnEntityDespawn() || getEntity().isDead())); + return getEntity() == null || (getEntity() instanceof Player ? !isKeepDisguiseOnPlayerDeath() : + getEntity().isDead()); } public boolean isSelfDisguiseSoundsReplaced() { @@ -651,24 +642,12 @@ public abstract class Disguise implements Serializable { playerHiddenFromTab = hidePlayerInTab; } - public Disguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { - this.keepDisguiseEntityDespawn = keepDisguise; - - return this; - } - public Disguise setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { this.keepDisguisePlayerDeath = keepDisguise; return this; } - public Disguise setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { - this.keepDisguisePlayerLogout = keepDisguise; - - return this; - } - public Disguise setModifyBoundingBox(boolean modifyBox) { if (((TargetedDisguise) this).getDisguiseTarget() != TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { throw new RuntimeException( @@ -788,6 +767,10 @@ public abstract class Disguise implements Serializable { disguiseInUse = true; + if (velocityRunnable == null) { + createRunnable(); + } + task = Bukkit.getScheduler().runTaskTimer(LibsDisguises.getInstance(), velocityRunnable, 1, 1); if (this instanceof PlayerDisguise) { diff --git a/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java index cf0cbe11..6c99666b 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java @@ -20,11 +20,10 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import java.io.IOException; -import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.*; -public class FlagWatcher implements Serializable { +public class FlagWatcher { private boolean addEntityAnimations = DisguiseConfig.isEntityAnimationsAdded(); /** * These are the entity values I need to add else it could crash them.. @@ -37,20 +36,6 @@ public class FlagWatcher implements Serializable { private boolean[] modifiedEntityAnimations = new boolean[8]; private transient List 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) { this.disguise = (TargetedDisguise) disguise; this.setData(MetaIndex.ENTITY_AIR_TICKS, 0); @@ -188,7 +173,7 @@ public class FlagWatcher implements Serializable { public void run() { try { DisguiseUtilities.sendSelfDisguise((Player) getDisguise().getEntity(), - disguise); + getDisguise()); } catch (Exception ex) { ex.printStackTrace(); @@ -545,5 +530,6 @@ public class FlagWatcher implements Serializable { protected void setDisguise(TargetedDisguise disguise) { this.disguise = disguise; + equipment.setFlagWatcher(this); } } diff --git a/src/me/libraryaddict/disguise/disguisetypes/LibsEquipment.java b/src/me/libraryaddict/disguise/disguisetypes/LibsEquipment.java index 8a97c0d9..820097c7 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/LibsEquipment.java +++ b/src/me/libraryaddict/disguise/disguisetypes/LibsEquipment.java @@ -7,14 +7,18 @@ import org.bukkit.inventory.ItemStack; import java.io.Serializable; -public class LibsEquipment implements EntityEquipment, Serializable { +public class LibsEquipment implements EntityEquipment { private ItemStack[] equipment = new ItemStack[EquipmentSlot.values().length]; - private FlagWatcher flagWatcher; + private transient FlagWatcher flagWatcher; public LibsEquipment(FlagWatcher flagWatcher) { this.flagWatcher = flagWatcher; } + protected void setFlagWatcher(FlagWatcher flagWatcher) { + this.flagWatcher = flagWatcher; + } + public LibsEquipment clone(FlagWatcher flagWatcher) { LibsEquipment newEquip = new LibsEquipment(flagWatcher); @@ -114,9 +118,7 @@ public class LibsEquipment implements EntityEquipment, Serializable { @Override public ItemStack[] getArmorContents() { - return new ItemStack[] { - getBoots(), getLeggings(), getChestplate(), getHelmet() - }; + return new ItemStack[]{getBoots(), getLeggings(), getChestplate(), getHelmet()}; } @Override @@ -209,5 +211,4 @@ public class LibsEquipment implements EntityEquipment, Serializable { public Entity getHolder() { throw new UnsupportedOperationException("This is not supported on a disguise"); } - } diff --git a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java index ef72388f..0323f88a 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MiscDisguise.java @@ -27,9 +27,9 @@ public class MiscDisguise extends TargetedDisguise { super(disguiseType); if (!disguiseType.isMisc()) { - throw new InvalidParameterException("Expected a non-living DisguiseType while constructing MiscDisguise. Received " - + disguiseType + " instead. Please use " + (disguiseType.isPlayer() ? "PlayerDisguise" : "MobDisguise") - + " instead"); + throw new InvalidParameterException( + "Expected a non-living DisguiseType while constructing MiscDisguise. Received " + disguiseType + " instead. Please use " + ( + disguiseType.isPlayer() ? "PlayerDisguise" : "MobDisguise") + " instead"); } createDisguise(); @@ -37,33 +37,34 @@ public class MiscDisguise extends TargetedDisguise { this.id = getType().getTypeId(); this.data = getType().getDefaultData(); switch (disguiseType) { - // The only disguises which should use a custom data. - case PAINTING: - ((PaintingWatcher) getWatcher()).setArt(Art.values()[Math.max(0, id) % Art.values().length]); - break; - case FALLING_BLOCK: - ((FallingBlockWatcher) getWatcher()).setBlock(new ItemStack(Math.max(1, id), 1, (short) Math.max(0, data))); - break; - case SPLASH_POTION: - ((SplashPotionWatcher) getWatcher()).setPotionId(Math.max(0, id)); - break; - case DROPPED_ITEM: + // The only disguises which should use a custom data. + case PAINTING: + ((PaintingWatcher) getWatcher()).setArt(Art.values()[Math.max(0, id) % Art.values().length]); + break; + case FALLING_BLOCK: + ((FallingBlockWatcher) getWatcher()).setBlock( + new ItemStack(Math.max(1, id), 1, (short) Math.max(0, data))); + break; + case SPLASH_POTION: + ((SplashPotionWatcher) getWatcher()).setPotionId(Math.max(0, id)); + break; + case DROPPED_ITEM: - if (id > 0) { - ((DroppedItemWatcher) getWatcher()).setItemStack(new ItemStack(id, Math.max(1, data))); - } - break; - case FISHING_HOOK: // Entity ID of whoever is holding fishing rod - case ARROW: // Entity ID of shooter. Used for "Is he on this scoreboard team and do I render it moving through his body?" - case TIPPED_ARROW: - case SPECTRAL_ARROW: - case SMALL_FIREBALL: // Unknown. Uses entity id of shooter. 0 if no shooter - case FIREBALL: // Unknown. Uses entity id of shooter. 0 if no shooter - case WITHER_SKULL: // Unknown. Uses entity id of shooter. 0 if no shooter - this.data = id; - break; - default: - break; + if (id > 0) { + ((DroppedItemWatcher) getWatcher()).setItemStack(new ItemStack(id, Math.max(1, data))); + } + break; + case FISHING_HOOK: // Entity ID of whoever is holding fishing rod + case ARROW: // Entity ID of shooter. Used for "Is he on this scoreboard team and do I render it moving through his body?" + case TIPPED_ARROW: + case SPECTRAL_ARROW: + case SMALL_FIREBALL: // Unknown. Uses entity id of shooter. 0 if no shooter + case FIREBALL: // Unknown. Uses entity id of shooter. 0 if no shooter + case WITHER_SKULL: // Unknown. Uses entity id of shooter. 0 if no shooter + this.data = id; + break; + default: + break; } } @@ -99,14 +100,14 @@ public class MiscDisguise extends TargetedDisguise { */ public int getData() { switch (getType()) { - case FALLING_BLOCK: - return (int) ((FallingBlockWatcher) getWatcher()).getBlock().getDurability(); - case PAINTING: - return ((PaintingWatcher) getWatcher()).getArt().getId(); - case SPLASH_POTION: - return ((SplashPotionWatcher) getWatcher()).getPotionId(); - default: - return data; + case FALLING_BLOCK: + return (int) ((FallingBlockWatcher) getWatcher()).getBlock().getDurability(); + case PAINTING: + return ((PaintingWatcher) getWatcher()).getArt().getId(); + case SPLASH_POTION: + return ((SplashPotionWatcher) getWatcher()).getPotionId(); + default: + return data; } } @@ -160,21 +161,11 @@ public class MiscDisguise extends TargetedDisguise { return (MiscDisguise) super.setHideHeldItemFromSelf(hideHeldItem); } - @Override - public MiscDisguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { - return (MiscDisguise) super.setKeepDisguiseOnEntityDespawn(keepDisguise); - } - @Override public MiscDisguise setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { return (MiscDisguise) super.setKeepDisguiseOnPlayerDeath(keepDisguise); } - @Override - public MiscDisguise setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { - return (MiscDisguise) super.setKeepDisguiseOnPlayerLogout(keepDisguise); - } - @Override public MiscDisguise setModifyBoundingBox(boolean modifyBox) { return (MiscDisguise) super.setModifyBoundingBox(modifyBox); @@ -209,5 +200,4 @@ public class MiscDisguise extends TargetedDisguise { public MiscDisguise silentlyRemovePlayer(String playername) { return (MiscDisguise) super.silentlyRemovePlayer(playername); } - } diff --git a/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java index 07d2e146..787e9094 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/MobDisguise.java @@ -20,9 +20,9 @@ public class MobDisguise extends TargetedDisguise { super(disguiseType); if (!disguiseType.isMob()) { - throw new InvalidParameterException("Expected a living DisguiseType while constructing MobDisguise. Received " - + disguiseType + " instead. Please use " + (disguiseType.isPlayer() ? "PlayerDisguise" : "MiscDisguise") - + " instead"); + throw new InvalidParameterException( + "Expected a living DisguiseType while constructing MobDisguise. Received " + disguiseType + " instead. Please use " + ( + disguiseType.isPlayer() ? "PlayerDisguise" : "MiscDisguise") + " instead"); } this.isAdult = isAdult; @@ -70,8 +70,7 @@ public class MobDisguise extends TargetedDisguise { if (getWatcher() != null) { if (getWatcher() instanceof AgeableWatcher) { return ((AgeableWatcher) getWatcher()).isAdult(); - } - else if (getWatcher() instanceof ZombieWatcher) { + } else if (getWatcher() instanceof ZombieWatcher) { return ((ZombieWatcher) getWatcher()).isAdult(); } return true; @@ -119,21 +118,11 @@ public class MobDisguise extends TargetedDisguise { return (MobDisguise) super.setHideHeldItemFromSelf(hideHeldItem); } - @Override - public MobDisguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { - return (MobDisguise) super.setKeepDisguiseOnEntityDespawn(keepDisguise); - } - @Override public MobDisguise setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { return (MobDisguise) super.setKeepDisguiseOnPlayerDeath(keepDisguise); } - @Override - public MobDisguise setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { - return (MobDisguise) super.setKeepDisguiseOnPlayerLogout(keepDisguise); - } - @Override public MobDisguise setModifyBoundingBox(boolean modifyBox) { return (MobDisguise) super.setModifyBoundingBox(modifyBox); diff --git a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index b63d7171..394d87eb 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -12,7 +12,6 @@ import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsProfileLookup; -import me.libraryaddict.disguise.utilities.WrappedProfile; import me.libraryaddict.disguise.utilities.ReflectionManager; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -25,7 +24,7 @@ import java.util.UUID; public class PlayerDisguise extends TargetedDisguise { private transient LibsProfileLookup currentLookup; - private WrappedProfile gameProfile; + private WrappedGameProfile gameProfile; private String playerName; private String skinToUse; private UUID uuid = UUID.randomUUID(); @@ -65,8 +64,7 @@ public class PlayerDisguise extends TargetedDisguise { setName(gameProfile.getName()); - this.gameProfile = new WrappedProfile( - ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile)); + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile); createDisguise(); } @@ -76,7 +74,7 @@ public class PlayerDisguise extends TargetedDisguise { setName(gameProfile.getName()); - this.gameProfile = new WrappedProfile(ReflectionManager.getGameProfile(uuid, gameProfile.getName())); + this.gameProfile = ReflectionManager.getGameProfile(uuid, gameProfile.getName()); setSkin(skinToUse); @@ -101,9 +99,8 @@ public class PlayerDisguise extends TargetedDisguise { if (currentLookup == null && gameProfile != null) { disguise.skinToUse = getSkin(); - disguise.gameProfile = new WrappedProfile( - ReflectionManager.getGameProfileWithThisSkin(disguise.uuid, getGameProfile().getName(), - getGameProfile())); + disguise.gameProfile = ReflectionManager.getGameProfileWithThisSkin(disguise.uuid, + getGameProfile().getName(), getGameProfile()); } else { disguise.setSkin(getSkin()); } @@ -128,14 +125,14 @@ public class PlayerDisguise extends TargetedDisguise { public WrappedGameProfile getGameProfile() { if (gameProfile == null) { if (getSkin() != null) { - gameProfile = new WrappedProfile(ReflectionManager.getGameProfile(uuid, getName())); + gameProfile = ReflectionManager.getGameProfile(uuid, getName()); } else { - gameProfile = new WrappedProfile(ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), - DisguiseUtilities.getProfileFromMojang(this))); + gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), + DisguiseUtilities.getProfileFromMojang(this)); } } - return gameProfile.getProfile(); + return gameProfile; } public String getName() { @@ -185,8 +182,7 @@ public class PlayerDisguise extends TargetedDisguise { } public void setGameProfile(WrappedGameProfile gameProfile) { - this.gameProfile = new WrappedProfile( - ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile)); + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, gameProfile.getName(), gameProfile); } @Override @@ -204,21 +200,11 @@ public class PlayerDisguise extends TargetedDisguise { return (PlayerDisguise) super.setHideHeldItemFromSelf(hideHeldItem); } - @Override - public PlayerDisguise setKeepDisguiseOnEntityDespawn(boolean keepDisguise) { - return (PlayerDisguise) super.setKeepDisguiseOnEntityDespawn(keepDisguise); - } - @Override public PlayerDisguise setKeepDisguiseOnPlayerDeath(boolean keepDisguise) { return (PlayerDisguise) super.setKeepDisguiseOnPlayerDeath(keepDisguise); } - @Override - public PlayerDisguise setKeepDisguiseOnPlayerLogout(boolean keepDisguise) { - return (PlayerDisguise) super.setKeepDisguiseOnPlayerLogout(keepDisguise); - } - @Override public PlayerDisguise setModifyBoundingBox(boolean modifyBox) { return (PlayerDisguise) super.setModifyBoundingBox(modifyBox); @@ -306,8 +292,7 @@ public class PlayerDisguise extends TargetedDisguise { currentLookup = null; this.skinToUse = gameProfile.getName(); - this.gameProfile = new WrappedProfile( - ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile)); + this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile); if (DisguiseUtilities.isDisguiseInUse(this)) { if (isDisplayedInTab()) { diff --git a/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java b/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java index ce4ea22c..7e6166ba 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java +++ b/src/me/libraryaddict/disguise/disguisetypes/TargetedDisguise.java @@ -31,7 +31,7 @@ public abstract class TargetedDisguise extends Disguise { HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS, SHOW_TO_EVERYONE_BUT_THESE_PLAYERS } - private List disguiseViewers = new ArrayList<>(); + private ArrayList disguiseViewers = new ArrayList<>(); private TargetType targetType = TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS; public TargetedDisguise addPlayer(Player player) { @@ -57,8 +57,8 @@ public abstract class TargetedDisguise extends Disguise { deleteTab.getPlayerInfoAction().write(0, canSee(player) ? PlayerInfoAction.REMOVE_PLAYER : PlayerInfoAction.ADD_PLAYER); - deleteTab.getPlayerInfoDataLists().write(0, - Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, + deleteTab.getPlayerInfoDataLists().write(0, Arrays.asList( + new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName())))); @@ -120,8 +120,8 @@ public abstract class TargetedDisguise extends Disguise { deleteTab.getPlayerInfoAction().write(0, canSee(player) ? PlayerInfoAction.ADD_PLAYER : PlayerInfoAction.REMOVE_PLAYER); - deleteTab.getPlayerInfoDataLists().write(0, - Arrays.asList(new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, + deleteTab.getPlayerInfoDataLists().write(0, Arrays.asList( + new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(((Player) getEntity()).getDisplayName())))); diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/SheepWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/SheepWatcher.java index 86f9a8db..ec16766a 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/SheepWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/SheepWatcher.java @@ -6,49 +6,37 @@ import me.libraryaddict.disguise.disguisetypes.AnimalColor; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.MetaIndex; -public class SheepWatcher extends AgeableWatcher -{ +public class SheepWatcher extends AgeableWatcher { - public SheepWatcher(Disguise disguise) - { + public SheepWatcher(Disguise disguise) { super(disguise); - - setData(MetaIndex.SHEEP_WOOL, (byte) 0); } - public AnimalColor getColor() - { + public AnimalColor getColor() { return AnimalColor.getColor(((int) getData(MetaIndex.SHEEP_WOOL) & 15)); } - public boolean isSheared() - { - return ((byte) getData(MetaIndex.SHEEP_WOOL) & 16) != 0; + public boolean isSheared() { + return (getData(MetaIndex.SHEEP_WOOL) & 16) != 0; } - public void setColor(AnimalColor color) - { + public void setColor(AnimalColor color) { setColor(DyeColor.getByWoolData((byte) color.getId())); } - public void setColor(DyeColor color) - { - byte b0 = (byte) getData(MetaIndex.SHEEP_WOOL); + public void setColor(DyeColor color) { + byte b0 = getData(MetaIndex.SHEEP_WOOL); setData(MetaIndex.SHEEP_WOOL, (byte) (b0 & 240 | color.getWoolData() & 15)); sendData(MetaIndex.SHEEP_WOOL); } - public void setSheared(boolean flag) - { - byte b0 = (byte) getData(MetaIndex.SHEEP_WOOL); + public void setSheared(boolean flag) { + byte b0 = getData(MetaIndex.SHEEP_WOOL); - if (flag) - { + if (flag) { setData(MetaIndex.SHEEP_WOOL, (byte) (b0 | 16)); - } - else - { + } else { setData(MetaIndex.SHEEP_WOOL, (byte) (b0 & -17)); } diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 1cf272eb..3265a963 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -7,24 +7,26 @@ import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.WrappedBlockData; import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.PropertyMap; 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.*; 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; +import me.libraryaddict.disguise.utilities.json.*; import org.bukkit.*; import org.bukkit.block.BlockFace; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Ageable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -39,11 +41,13 @@ import org.bukkit.scoreboard.Team.Option; import org.bukkit.scoreboard.Team.OptionStatus; import org.bukkit.util.Vector; -import java.io.*; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.PrintWriter; +import java.lang.reflect.*; +import java.net.URL; +import java.net.URLClassLoader; import java.util.*; import java.util.regex.Pattern; @@ -69,62 +73,22 @@ public class DisguiseUtilities { private static HashMap preDisguiseTeam = new HashMap<>(); private static File profileCache = new File("plugins/LibsDisguises/GameProfiles"), savedDisguises = new File( "plugins/LibsDisguises/SavedDisguises"); + private static Gson gson; - static { - try { - Object server = ReflectionManager.getNmsMethod("MinecraftServer", "getServer").invoke(null); - Object world = ((List) server.getClass().getField("worlds").get(server)).get(0); + public static void saveDisguises() { + Iterator> itel = disguisesInUse.values().iterator(); - Object bedChunk = ReflectionManager.getNmsClass("Chunk").getConstructor( - ReflectionManager.getNmsClass("World"), int.class, int.class).newInstance(world, 0, 0); + while (itel.hasNext()) { + HashSet list = itel.next(); - Field cSection = bedChunk.getClass().getDeclaredField("sections"); - cSection.setAccessible(true); + if (list.isEmpty()) + continue; - Object chunkSection = ReflectionManager.getNmsClass("ChunkSection").getConstructor(int.class, - boolean.class).newInstance(0, true); - - Object block = ReflectionManager.getNmsClass("Block").getMethod("getById", int.class).invoke(null, - Material.BED_BLOCK.getId()); - - Method fromLegacyData = block.getClass().getMethod("fromLegacyData", int.class); - Method setType = chunkSection.getClass().getMethod("setType", int.class, int.class, int.class, - ReflectionManager.getNmsClass("IBlockData")); - Method setSky = chunkSection.getClass().getMethod("a", int.class, int.class, int.class, int.class); - Method setEmitted = chunkSection.getClass().getMethod("b", int.class, int.class, int.class, int.class); - - for (BlockFace face : new BlockFace[]{BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}) { - int x = 1 + face.getModX(); - - int z = 1 + face.getModZ(); - - setType.invoke(chunkSection, x, 0, z, fromLegacyData.invoke(block, face.ordinal())); - - setSky.invoke(chunkSection, x, 0, z, 0); - - setEmitted.invoke(chunkSection, x, 0, z, 0); - } - - Object[] array = (Object[]) Array.newInstance(chunkSection.getClass(), 16); - - array[0] = chunkSection; - - cSection.set(bedChunk, array); - - spawnChunk = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, - bedChunk, 65535).createPacket(bedChunk, 65535); - - Field threadField = ReflectionManager.getNmsField("MinecraftServer", "primaryThread"); - threadField.setAccessible(true); - - mainThread = (Thread) threadField.get(ReflectionManager.getMinecraftServer()); - } - catch (Exception ex) { - ex.printStackTrace(); + saveDisguises(list.iterator().next().getEntity().getUniqueId(), list.toArray(new Disguise[0])); } } - public static boolean hasCacheEntry(String playername) { + public static boolean hasGameProfile(String playername) { return cachedNames.contains(playername.toLowerCase()); } @@ -163,14 +127,14 @@ public class DisguiseUtilities { player.sendMessage(ChatColor.RED + "Example usage: /disguise " + reference); } else { player.sendMessage( - ChatColor.RED + "Failed to store the reference, too many cloned disguises. Please raise the " + - "maximum cloned disguises, or lower the time they last"); + 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) { + if (!LibVersion.isPremium()) + return; + try { File disguiseFile = new File(savedDisguises, owningEntity.toString()); @@ -190,18 +154,12 @@ public class DisguiseUtilities { disguises[i] = dis; } - FileOutputStream files = new FileOutputStream(disguiseFile); - ObjectOutputStream obj = new ObjectOutputStream(files); - - obj.writeObject(disguises); + PrintWriter writer = new PrintWriter(disguiseFile); + writer.write(gson.toJson(disguises)); + writer.close(); savedDisguiseList.add(owningEntity); - - obj.close(); - files.close(); } - - savedDisguises.save(new File(libsDisguises.getDataFolder(), "saveddisguises.yml")); } catch (Exception e) { e.printStackTrace(); @@ -213,29 +171,29 @@ public class DisguiseUtilities { } public static Disguise[] getSavedDisguises(UUID entityUUID, boolean remove) { - if (isSavedDisguise(entityUUID)) + if (!isSavedDisguise(entityUUID) || !LibVersion.isPremium()) return new Disguise[0]; - String cached = savedDisguises.getString(entityUUID.toString()); + File disguiseFile = new File(savedDisguises, entityUUID.toString()); - if (cached == null) { - cachedNames.remove(entityUUID.toString()); + if (!disguiseFile.exists()) { + savedDisguiseList.remove(entityUUID); return new Disguise[0]; } try { - ObjectInputStream outputStream = new ObjectInputStream(new ByteArrayInputStream(cached.getBytes())); - - Disguise[] toReturn = (Disguise[]) outputStream.readObject(); + BufferedReader reader = new BufferedReader(new FileReader(disguiseFile)); + String cached = reader.readLine(); + reader.close(); if (remove) { removeSavedDisguise(entityUUID); } - return toReturn; + return gson.fromJson(cached, Disguise[].class); } catch (Exception e) { - System.out.println("Error while loading Entity Disguises, malformed config?"); + System.out.println("Malformed disguise for " + entityUUID); e.printStackTrace(); } @@ -246,14 +204,9 @@ public class DisguiseUtilities { if (!savedDisguiseList.remove(entityUUID)) return; - savedDisguises.set(entityUUID.toString(), null); + File disguiseFile = new File(savedDisguises, entityUUID.toString()); - try { - savedDisguises.save(new File(libsDisguises.getDataFolder(), "saveddisguises.yml")); - } - catch (IOException e) { - e.printStackTrace(); - } + disguiseFile.delete(); } public static boolean isSavedDisguise(UUID entityUUID) { @@ -330,16 +283,12 @@ public class DisguiseUtilities { public static void addGameProfile(String string, WrappedGameProfile gameProfile) { try { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - ObjectOutputStream obj = new ObjectOutputStream(bytes); - obj.writeObject(new WrappedProfile(gameProfile)); + File file = new File(profileCache, string.toLowerCase()); + PrintWriter writer = new PrintWriter(file); + writer.write(gson.toJson(gameProfile)); + writer.close(); - 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(); @@ -602,17 +551,19 @@ public class DisguiseUtilities { if (!cachedNames.contains(playerName.toLowerCase())) return null; - String cached = gameProfileCache.getString(playerName.toLowerCase()); + File file = new File(profileCache, playerName.toLowerCase()); - if (cached == null) { + if (!file.exists()) { cachedNames.remove(playerName.toLowerCase()); return null; } try { - ObjectInputStream outputStream = new ObjectInputStream(new ByteArrayInputStream(cached.getBytes())); + BufferedReader reader = new BufferedReader(new FileReader(file)); + String cached = reader.readLine(); + reader.close(); - return ((WrappedProfile) outputStream.readObject()).getProfile(); + return gson.fromJson(cached, WrappedGameProfile.class); } catch (Exception e) { e.printStackTrace(); @@ -820,22 +771,84 @@ public class DisguiseUtilities { return selfDisguised; } - public static boolean hasGameProfile(String playerName) { - return getGameProfile(playerName) != null; - } - public static void init(LibsDisguises disguises) { libsDisguises = disguises; - gameProfileCache = YamlConfiguration.loadConfiguration(new File(disguises.getDataFolder(), "cache.yml")); + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.registerTypeAdapter(MetaIndex.class, new SerializerMetaIndex()); + gsonBuilder.registerTypeAdapter(WrappedGameProfile.class, new SerializerGameProfile()); + gsonBuilder.registerTypeAdapter(WrappedBlockData.class, new SerializerWrappedBlockData()); + gsonBuilder.registerTypeAdapter(Disguise.class, new SerializerDisguise()); + gsonBuilder.registerTypeAdapter(FlagWatcher.class, new SerializerFlagWatcher()); + gsonBuilder.registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()); - cachedNames.addAll(gameProfileCache.getKeys(false)); + gson = gsonBuilder.create(); - savedDisguises = YamlConfiguration.loadConfiguration(new File(disguises.getDataFolder(), "saveddisguises.yml")); + if (!profileCache.exists()) + profileCache.mkdirs(); - for (String key : savedDisguises.getKeys(false)) { + if (!savedDisguises.exists()) + savedDisguises.mkdirs(); + + try { + Object server = ReflectionManager.getNmsMethod("MinecraftServer", "getServer").invoke(null); + Object world = ((List) server.getClass().getField("worlds").get(server)).get(0); + + Object bedChunk = ReflectionManager.getNmsClass("Chunk").getConstructor( + ReflectionManager.getNmsClass("World"), int.class, int.class).newInstance(world, 0, 0); + + Field cSection = bedChunk.getClass().getDeclaredField("sections"); + cSection.setAccessible(true); + + Object chunkSection = ReflectionManager.getNmsClass("ChunkSection").getConstructor(int.class, + boolean.class).newInstance(0, true); + + Object block = ReflectionManager.getNmsClass("Block").getMethod("getById", int.class).invoke(null, + Material.BED_BLOCK.getId()); + + Method fromLegacyData = block.getClass().getMethod("fromLegacyData", int.class); + Method setType = chunkSection.getClass().getMethod("setType", int.class, int.class, int.class, + ReflectionManager.getNmsClass("IBlockData")); + Method setSky = chunkSection.getClass().getMethod("a", int.class, int.class, int.class, int.class); + Method setEmitted = chunkSection.getClass().getMethod("b", int.class, int.class, int.class, int.class); + + for (BlockFace face : new BlockFace[]{BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH}) { + int x = 1 + face.getModX(); + + int z = 1 + face.getModZ(); + + setType.invoke(chunkSection, x, 0, z, fromLegacyData.invoke(block, face.ordinal())); + + setSky.invoke(chunkSection, x, 0, z, 0); + + setEmitted.invoke(chunkSection, x, 0, z, 0); + } + + Object[] array = (Object[]) Array.newInstance(chunkSection.getClass(), 16); + + array[0] = chunkSection; + + cSection.set(bedChunk, array); + + spawnChunk = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, + bedChunk, 65535).createPacket(bedChunk, 65535); + + Field threadField = ReflectionManager.getNmsField("MinecraftServer", "primaryThread"); + threadField.setAccessible(true); + + mainThread = (Thread) threadField.get(ReflectionManager.getMinecraftServer()); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + cachedNames.addAll(Arrays.asList(profileCache.list())); + + for (String key : savedDisguises.list()) { savedDisguiseList.add(UUID.fromString(key)); } + + LibVersion.check(libsDisguises); } public static boolean isDisguiseInUse(Disguise disguise) { @@ -1088,16 +1101,10 @@ public class DisguiseUtilities { public static void removeGameProfile(String string) { 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(); - } - } + File file = new File(profileCache, string.toLowerCase()); + + file.delete(); } public static void removeSelfDisguise(Player player) { diff --git a/src/me/libraryaddict/disguise/utilities/LibVersion.java b/src/me/libraryaddict/disguise/utilities/LibVersion.java new file mode 100644 index 00000000..488b5b20 --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/LibVersion.java @@ -0,0 +1,65 @@ +package me.libraryaddict.disguise.utilities; + +import me.libraryaddict.disguise.LibsDisguises; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +/** + * Created by libraryaddict on 2/06/2017. + */ +public class LibVersion { + /** + * If you're seriously going to modify this to get the premium stuff for free, can you at least not + * distribute it? You didn't pay for it despite how cheap it is. You spend $8 on a trip to McDonalds + * but you balk at the idea of actually supporting someone when you can just steal it for free. + * Is the only reason you don't rob McDonalds because they can catch you? Is the only reason you don't rob your + * Grandma being that she knows who was in her house? If you see someone's credit card drop out their pocket, + * you planning on taking it and going shopping? + * Do you really have the right to give someones work away for free? + * You know enough to start coding, but you resist the idea of contributing to this plugin. Its even + * open-source, no one is stopping you. You're the guy who files a bug report because the hacked version has + * malware installed. + * I'd hate to work with you. + */ + private static Boolean thisPluginIsPaidFor; + + /** + * Don't even think about disabling this unless you purchased the premium plugin. It will uh, corrupt your server + * and stuff. Also my dog will cry because I can't afford to feed him. And my sister will be beaten by my dad + * again because I'm not bringing enough money in. + */ + public static Boolean isPremium() { + return thisPluginIsPaidFor == null ? !"%%__USER__%%".contains("__USER__") : thisPluginIsPaidFor; + } + + public static void check(LibsDisguises disguises) { + thisPluginIsPaidFor = isPremium(); + + if (!isPremium() && disguises.getDescription().getVersion().contains("SNAPSHOT")) { + for (File file : new File("plugins/LibsDisguises/").listFiles()) { + if (!file.isFile()) + continue; + + if (!file.getName().endsWith(".jar")) + continue; + + try { + ClassLoader cl = new URLClassLoader(new URL[]{file.toURI().toURL()}); + Class c = cl.loadClass(LibVersion.class.getName()); + + Method m = c.getMethod("isPremium"); + thisPluginIsPaidFor = (Boolean) m.invoke(null); + + if (isPremium()) + break; + } + catch (Exception ex) { + // Don't print off errors + } + } + } + } +} diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java index c3d13b86..f6cfc3b8 100644 --- a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java @@ -861,7 +861,8 @@ public class ReflectionManager { } } else if (value instanceof ItemStack) { return getNmsItem((ItemStack) value); - } + } else if (value instanceof Double) + return ((Double) value).floatValue(); return value; } diff --git a/src/me/libraryaddict/disguise/utilities/WrappedProfile.java b/src/me/libraryaddict/disguise/utilities/WrappedProfile.java deleted file mode 100644 index 24a158d5..00000000 --- a/src/me/libraryaddict/disguise/utilities/WrappedProfile.java +++ /dev/null @@ -1,48 +0,0 @@ -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 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())); - } - } -} diff --git a/src/me/libraryaddict/disguise/utilities/json/SerializerDisguise.java b/src/me/libraryaddict/disguise/utilities/json/SerializerDisguise.java new file mode 100644 index 00000000..e0eabab2 --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/json/SerializerDisguise.java @@ -0,0 +1,66 @@ +package me.libraryaddict.disguise.utilities.json; + +import com.google.gson.*; +import me.libraryaddict.disguise.disguisetypes.*; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +/** + * Created by libraryaddict on 1/06/2017. + */ +public class SerializerDisguise implements JsonDeserializer, JsonSerializer, InstanceCreator { + + @Override + public Disguise deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + JsonObject obj = (JsonObject) json; + DisguiseType type = DisguiseType.valueOf(obj.get("disguiseType").getAsString()); + TargetedDisguise disg; + + if (type.isPlayer()) { + disg = context.deserialize(json, PlayerDisguise.class); + } else if (type.isMob()) { + disg = context.deserialize(json, MobDisguise.class); + } else if (type.isMisc()) { + disg = context.deserialize(json, MiscDisguise.class); + } else + return null; + + try { + Method method = FlagWatcher.class.getDeclaredMethod("setDisguise", TargetedDisguise.class); + method.setAccessible(true); + method.invoke(disg.getWatcher(), disg); + } + catch (Exception e) { + e.printStackTrace(); + } + + return disg; + } + + @Override + public Disguise createInstance(Type type) { + if (type == PlayerDisguise.class) + return new PlayerDisguise("SaveDisgError"); + else if (type == MobDisguise.class) + return new MobDisguise(DisguiseType.SHEEP); + else if (type == MiscDisguise.class) + return new MiscDisguise(DisguiseType.BOAT); + + return null; + } + + @Override + public JsonElement serialize(Disguise src, Type typeOfSrc, JsonSerializationContext context) { + if (src.isPlayerDisguise()) + return context.serialize(src, PlayerDisguise.class); + else if (src.isMobDisguise()) + return context.serialize(src, MobDisguise.class); + else if (src.isMiscDisguise()) + return context.serialize(src, MiscDisguise.class); + + return null; + } +} diff --git a/src/me/libraryaddict/disguise/utilities/json/SerializerFlagWatcher.java b/src/me/libraryaddict/disguise/utilities/json/SerializerFlagWatcher.java new file mode 100644 index 00000000..e2d94c10 --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/json/SerializerFlagWatcher.java @@ -0,0 +1,97 @@ +package me.libraryaddict.disguise.utilities.json; + +import com.google.gson.*; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagWatcher; +import me.libraryaddict.disguise.disguisetypes.MetaIndex; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by libraryaddict on 1/06/2017. + */ +public class SerializerFlagWatcher implements JsonDeserializer, JsonSerializer, InstanceCreator { + + @Override + public FlagWatcher deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + try { + FlagWatcher watcher = context.deserialize(json, + Class.forName(((JsonObject) json).get("flagType").getAsString())); + + DisguiseType entity = DisguiseType.valueOf(((JsonObject) json).get("entityType").getAsString()); + + correct(watcher, watcher.getClass(), "entityValues"); + correct(watcher, entity.getWatcherClass(), "backupEntityValues"); + + return watcher; + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + private void correct(FlagWatcher watcher, Class flagWatcher, + String name) throws NoSuchFieldException, IllegalAccessException { + Field field = FlagWatcher.class.getDeclaredField(name); + field.setAccessible(true); + HashMap map = (HashMap) field.get(watcher); + + for (Map.Entry entry : map.entrySet()) { + if (!(entry.getValue() instanceof Double)) + continue; + + MetaIndex index = MetaIndex.getFlag(flagWatcher, entry.getKey()); + + Object def = index.getDefault(); + + if (def instanceof Long) + entry.setValue(((Double) entry.getValue()).longValue()); + else if (def instanceof Float) + entry.setValue(((Double) entry.getValue()).floatValue()); + else if (def instanceof Integer) + entry.setValue(((Double) entry.getValue()).intValue()); + else if (def instanceof Short) + entry.setValue(((Double) entry.getValue()).shortValue()); + else if (def instanceof Byte) + entry.setValue(((Double) entry.getValue()).byteValue()); + } + } + + @Override + public FlagWatcher createInstance(Type type) { + try { + return (FlagWatcher) type.getClass().getConstructor(Disguise.class).newInstance(null); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public JsonElement serialize(FlagWatcher src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject obj = (JsonObject) context.serialize(src); + + obj.addProperty("flagType", src.getClass().getName()); + try { + Method method = FlagWatcher.class.getDeclaredMethod("getDisguise"); + method.setAccessible(true); + Disguise disguise = (Disguise) method.invoke(src); + obj.addProperty("entityType", disguise.getType().name()); + } + catch (Exception ex) { + ex.printStackTrace(); + } + + return obj; + } +} diff --git a/src/me/libraryaddict/disguise/utilities/json/SerializerGameProfile.java b/src/me/libraryaddict/disguise/utilities/json/SerializerGameProfile.java new file mode 100644 index 00000000..dcabf0a4 --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/json/SerializerGameProfile.java @@ -0,0 +1,25 @@ +package me.libraryaddict.disguise.utilities.json; + +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.google.gson.*; +import com.mojang.authlib.GameProfile; + +import java.lang.reflect.Type; + +/** + * Created by libraryaddict on 1/06/2017. + */ +public class SerializerGameProfile implements JsonSerializer, JsonDeserializer { + + @Override + public JsonElement serialize(WrappedGameProfile src, Type typeOfSrc, JsonSerializationContext context) { + System.out.println(src.getHandle().toString()); + return context.serialize(src.getHandle(), GameProfile.class); + } + + @Override + public WrappedGameProfile deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + return WrappedGameProfile.fromHandle(context.deserialize(json, GameProfile.class)); + } +} diff --git a/src/me/libraryaddict/disguise/utilities/json/SerializerMetaIndex.java b/src/me/libraryaddict/disguise/utilities/json/SerializerMetaIndex.java new file mode 100644 index 00000000..09dbf4aa --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/json/SerializerMetaIndex.java @@ -0,0 +1,42 @@ +package me.libraryaddict.disguise.utilities.json; + +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.google.gson.*; +import com.mojang.authlib.GameProfile; +import me.libraryaddict.disguise.disguisetypes.MetaIndex; + +import java.lang.reflect.Type; + +/** + * Created by libraryaddict on 1/06/2017. + */ +public class SerializerMetaIndex implements JsonSerializer, JsonDeserializer { + + @Override + public JsonElement serialize(MetaIndex src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject obj = new JsonObject(); + obj.addProperty("index", src.getIndex()); + obj.addProperty("flagwatcher", src.getFlagWatcher().getSimpleName()); + return obj; + } + + @Override + public MetaIndex deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + JsonObject obj = json.getAsJsonObject(); + String name = obj.get("flagwatcher").getAsString(); + int index = obj.get("index").getAsInt(); + + for (MetaIndex i : MetaIndex.values()) { + if (i.getIndex() != index) + continue; + + if (!i.getFlagWatcher().getSimpleName().equals(name)) + continue; + + return i; + } + + return null; + } +} diff --git a/src/me/libraryaddict/disguise/utilities/json/SerializerWrappedBlockData.java b/src/me/libraryaddict/disguise/utilities/json/SerializerWrappedBlockData.java new file mode 100644 index 00000000..012ba398 --- /dev/null +++ b/src/me/libraryaddict/disguise/utilities/json/SerializerWrappedBlockData.java @@ -0,0 +1,31 @@ +package me.libraryaddict.disguise.utilities.json; + +import com.comphenix.protocol.wrappers.WrappedBlockData; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.google.gson.*; +import com.mojang.authlib.GameProfile; +import org.bukkit.Material; + +import java.lang.reflect.Type; + +/** + * Created by libraryaddict on 1/06/2017. + */ +public class SerializerWrappedBlockData implements JsonSerializer, JsonDeserializer { + + @Override + public JsonElement serialize(WrappedBlockData src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject obj = new JsonObject(); + obj.addProperty("type", src.getType().name()); + obj.addProperty("data", src.getData()); + return obj; + } + + @Override + public WrappedBlockData deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + JsonObject obj = json.getAsJsonObject(); + + return WrappedBlockData.createData(Material.valueOf(obj.get("type").getAsString()), obj.get("data").getAsInt()); + } +}