diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java new file mode 100644 index 000000000..84439b77d --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/DisguiseCommand.java @@ -0,0 +1,467 @@ +package mineplex.hub.commands; + +import java.lang.reflect.Field; +import java.util.UUID; + +import mineplex.core.account.CoreClient; +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.common.util.ProfileLoader; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.disguise.disguises.DisguisePlayer; +import mineplex.core.gadget.event.GadgetEnableEvent; +import mineplex.core.gadget.types.GadgetType; +import mineplex.core.treasure.event.TreasureStartEvent; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.HubManager; +import net.minecraft.server.v1_8_R3.ChatComponentText; +import net.minecraft.server.v1_8_R3.EntityHuman; +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.EnumDifficulty; +import net.minecraft.server.v1_8_R3.IChatBaseComponent; +import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation; +import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo; +import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.EnumPlayerInfoAction; +import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.PlayerInfoData; +import net.minecraft.server.v1_8_R3.PacketPlayOutRespawn; +import net.minecraft.server.v1_8_R3.WorldSettings.EnumGamemode; +import net.minecraft.server.v1_8_R3.WorldType; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.scoreboard.Team; + +import com.mojang.authlib.GameProfile; + +public class DisguiseCommand extends CommandBase implements Listener +{ + + private NautHashMap _disguisedPlayers = new NautHashMap<>(); + private NautHashMap _disguisedPlayersNames = new NautHashMap<>(); + private NautHashMap _disguisedPlayerDisguises = new NautHashMap<>(); + + public DisguiseCommand(HubManager plugin) + { + super(plugin, Rank.JNR_DEV, new Rank[] {Rank.YOUTUBE, Rank.TWITCH, Rank.YOUTUBE_SMALL}, "disguise"); + + plugin.getPluginManager().registerEvents(this, Plugin.getPlugin()); + } + + @Override + public void Execute(final Player caller, final String[] args) + { + if(args == null || args.length == 0) + { + if(!Plugin.GetDisguise().isDisguised(caller)) + { + UtilPlayer.message(caller, F.main("Disguise", "please use /disguise first")); + return; + } + try + { + GameProfile profile = _disguisedPlayers.get(caller); + _disguisedPlayers.remove(caller); + _disguisedPlayerDisguises.remove(caller); + Plugin.GetDisguise().undisguise(caller); + String playerName = _disguisedPlayersNames.get(caller); + + CoreClient client = Plugin.GetClients().Get(caller); + client.setDisguisedRank(null); + client.setDisguisedAs(null); + client.setDisguised(false); + + changeName(caller, playerName, true); + + for(Player other : UtilServer.getPlayers()) + updateTabInfo(((CraftPlayer) caller).getProfile(), profile, other, false); + + Field field; + try + { + field = GameProfile.class.getDeclaredField("id"); + field.setAccessible(true); + UUID old = ((CraftPlayer) caller).getProfile().getId(); + UUID newUUID = profile.getId(); + field.set(profile, old); + field.set(((CraftPlayer) caller).getProfile(), newUUID); + } + catch(Exception e) + { + e.printStackTrace(); + } + + PacketPlayOutRespawn packet = new PacketPlayOutRespawn(0, EnumDifficulty.getById(caller.getWorld().getDifficulty().getValue()), WorldType.NORMAL, EnumGamemode.getById(caller.getGameMode().getValue())); + UtilPlayer.sendPacket(caller, packet); + + for(Player other : UtilServer.getPlayers()) + { + for(Team team : other.getScoreboard().getTeams()) + { + team.removePlayer(caller); + } + other.getScoreboard().getTeam(Plugin.GetClients().Get(caller).GetRank().Name).addPlayer(caller); + } + + UtilPlayer.message(caller, F.main("Disguise", "You are no longer disguised!")); + return; + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + if(args != null && args.length > 1) + { + UtilPlayer.message(caller, F.main("Disguise", "/disguise ")); + return; + } + + Bukkit.getServer().getScheduler().runTaskAsynchronously(Plugin.getPlugin(), new Runnable() + { + @Override + public void run() + { + if(Plugin.GetDisguise().isDisguised(caller)) + { + UtilPlayer.message(caller, F.main("Disguise", "please use /disguise first")); + return; + } + for(Player other : UtilServer.getPlayers()) + { + if(other.getName().equalsIgnoreCase(args[0])) + { + UtilPlayer.message(caller, C.cRed + F.main("Disguise", "this name is already in use!")); + return; + } + } + if(_disguisedPlayersNames.containsValue(args[0])) + { + UtilPlayer.message(caller, C.cRed + F.main("Disguise", "this name is already in use!")); + return; + } + if(args[0].length() > 16) + { + UtilPlayer.message(caller, F.main("Disguise", "Invalid Disguise Name: " + ChatColor.RESET + args[0])); + return; + } + + try + { + CoreClient client = Plugin.GetClients().Get(caller); + UUID uuid = UUID.randomUUID(); + GameProfile profile = null; + try + { + uuid = UUIDFetcher.getUUIDOf(args[0]); + profile = new ProfileLoader(uuid.toString(), args[0]).loadProfile(); + } catch (Exception e) + { + uuid = UUID.randomUUID(); + profile = new ProfileLoader(null, args[0]).loadProfile(); + } + + Rank otherRank = Rank.ALL; + try + { + CoreClient other = new CoreClient(args[0]); + Plugin.GetClients().LoadClient(other, uuid, caller.getAddress().getAddress().getAddress().toString()); + otherRank = other.GetRank(); + } catch(NullPointerException exception) + {} + if(otherRank.has(Rank.TWITCH)) + { + UtilPlayer.message(caller, F.main("Disguise", "You can't disguise as staff!")); + return; + } + _disguisedPlayers.put(caller, profile); + _disguisedPlayersNames.put(caller, caller.getName()); + client.setDisguisedRank(otherRank); + client.setDisguised(true); + + client.setDisguisedAs(args[0]); + + changeName(caller, args[0], true); + + Plugin.GetGadget().removeGadgetType(caller, GadgetType.Item); + + Bukkit.broadcastMessage(ChatColor.DARK_GRAY + "Quit> " + ChatColor.GRAY + _disguisedPlayersNames.get(caller)); + UtilPlayer.message(caller, F.main("Disguise", "Disguise Active: " + ChatColor.RESET + args[0])); + + Field field; + try + { + field = GameProfile.class.getDeclaredField("id"); + field.setAccessible(true); + UUID old = ((CraftPlayer) caller).getProfile().getId(); + UUID newUUID = profile.getId(); + field.set(profile, old); + field.set(((CraftPlayer) caller).getProfile(), newUUID); + } + catch(Exception e) + { + e.printStackTrace(); + } + + PacketPlayOutRespawn packet = new PacketPlayOutRespawn(0, EnumDifficulty.getById(caller.getWorld().getDifficulty().getValue()), WorldType.NORMAL, EnumGamemode.getById(caller.getGameMode().getValue())); + UtilPlayer.sendPacket(caller, packet); + + tablistRefresh(caller); + } catch(Exception e) + { + e.printStackTrace(); + UtilPlayer.message(caller, F.main("Disguise", "Invalid Disguise Name: " + ChatColor.RESET + args[0])); + return; + } + } + }); + } + + @EventHandler + public void refreshTabNames(UpdateEvent event) + { + if(event.getType() != UpdateType.FAST) + return; + + for(Player player : _disguisedPlayers.keySet()) + { + if(!player.isOnline()) + return; + + tablistRefresh(player); + } + } + + public void tablistRefresh(Player player) + { + for (Player other : UtilServer.getPlayers()) + { + if (player.canSee(other)) + { + updateTabInfo(_disguisedPlayers.get(player), ((CraftPlayer) player).getProfile(), other, false); + } + } + } + + public void updateTabInfo(GameProfile profileToAdd, GameProfile profileToRemove, Player target, boolean refreshOnly) + { + ChatColor team = ChatColor.WHITE; + Player player = Bukkit.getPlayer(profileToAdd.getName()); + EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); + String tag = Plugin.GetClients().Get(player).GetRank().getTag(true, true) + " "; + if(Plugin.GetClients().Get(player).isDisguised()) + { + tag = Plugin.GetClients().Get(player).getDisguisedRank().getTag(true, true) + " "; + } + + IChatBaseComponent component = new ChatComponentText(tag + team + player.getName()); + + if(!refreshOnly) + { + PacketPlayOutPlayerInfo removePacket = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER); + PlayerInfoData removeData = removePacket.new PlayerInfoData(profileToRemove, entityPlayer.ping, EnumGamemode.SURVIVAL, component); + removePacket.b.add(removeData); + UtilPlayer.sendPacket(target, removePacket); + + PacketPlayOutPlayerInfo addPacket = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER); + PlayerInfoData addData = addPacket.new PlayerInfoData(profileToAdd, entityPlayer.ping, EnumGamemode.SURVIVAL, component); + addPacket.b.add(addData); + UtilPlayer.sendPacket(target, addPacket); + } + + PacketPlayOutPlayerInfo updatePacket = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.UPDATE_DISPLAY_NAME); + PlayerInfoData updateData = updatePacket.new PlayerInfoData(profileToAdd, entityPlayer.ping, EnumGamemode.SURVIVAL, component); + updatePacket.b.add(updateData); + UtilPlayer.sendPacket(target, updatePacket); + } + + @EventHandler + public void updateDisguises(UpdateEvent event) + { + if(event.getType() != UpdateType.FASTEST) + return; + + for(final Player player : UtilServer.getPlayers()) + { + if(!_disguisedPlayers.containsKey(player)) + continue; + + for(Player other : UtilServer.getPlayers()) + { + try + { + if(other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).getPlayers().contains(player)) + { + other.getScoreboard().getTeam(Plugin.GetClients().Get(player).GetRank().Name).removePlayer(player); + other.getScoreboard().getTeam(Plugin.GetClients().Get(player).getDisguisedRank().Name).addPlayer(player); + } + } catch(NullPointerException exp) + {} + } + + if(Plugin.GetDisguise().isDisguised(player)) + continue; + + DisguisePlayer playerDisguise = new DisguisePlayer(player, _disguisedPlayers.get(player)); + _disguisedPlayerDisguises.put(player, playerDisguise); + Plugin.GetDisguise().disguise(playerDisguise); + } + } + + public void changeName(final Player player, String changedName, boolean skin) + { + try + { + GameProfile gameProfile = ((CraftPlayer) player).getProfile(); + + Field name = GameProfile.class.getDeclaredField("name"); + name.setAccessible(true); + name.set(gameProfile, changedName); + name.setAccessible(false); + + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Quit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + + if(_disguisedPlayers.containsKey(player)) + { + try + { + _disguisedPlayers.remove(player); + _disguisedPlayerDisguises.remove(player); + Plugin.GetDisguise().undisguise(player); + String playerName = _disguisedPlayersNames.get(player); + _disguisedPlayersNames.remove(player); + + CoreClient client = Plugin.GetClients().Get(player); + client.setDisguisedRank(null); + client.setDisguisedAs(null); + client.setDisguised(false); + + changeName(player, playerName, true); + } catch(Exception ex) + { + ex.printStackTrace(); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void Join(PlayerLoginEvent event) + { + for(Player player : _disguisedPlayers.keySet()) + { + if(player.getName().equalsIgnoreCase(event.getPlayer().getName())) + { + event.disallow(Result.KICK_OTHER, "There is already the same account playing. this probably happened because of /disguise"); + } + } + } + + @EventHandler + public void gadget(GadgetEnableEvent event) + { + if(!event.getGadget().GetName().equalsIgnoreCase("Coin Party Bomb") && event.getGadget().getGadgetType() != GadgetType.Morph) + return; + + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + event.setCancelled(true); + } + } + + @EventHandler + public void chest(TreasureStartEvent event) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + UtilPlayer.message(event.getPlayer(), F.main("Disguise", "You cant open Treasure Chests while you are disguised!")); + event.setCancelled(true); + } + } + + @EventHandler + public void onPlayerSneak(PlayerToggleSneakEvent event) + { + Player player = event.getPlayer(); + + if(_disguisedPlayers.containsKey(player)) + { + DisguisePlayer dp = _disguisedPlayerDisguises.get(player); + + dp.setSneaking(!dp.getSneaking()); + } + } + + @EventHandler + public void onPlayerLeftClick(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + if(_disguisedPlayers.containsKey(player)) + { + EntityHuman human = (((CraftHumanEntity) ((CraftPlayer) player)).getHandle()); + human.world.broadcastEntityEffect(human, (byte) 0); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onDPlayerChat(AsyncPlayerChatEvent event) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + event.setFormat(" *" + event.getMessage()); + } + } + + @EventHandler + public void on(PlayerInteractEvent event) + { + if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) + { + if(_disguisedPlayers.containsKey(event.getPlayer())) + { + + Player player = event.getPlayer(); + + PacketPlayOutAnimation packet = new PacketPlayOutAnimation(); + packet.a = player.getEntityId(); + + for(Player p : Bukkit.getOnlinePlayers()) + { + if(p != player) + { + Plugin.getPacketHandler().getPacketVerifier((Player) p).bypassProcess(packet); + } + } + } + } + } +}