Convert morph to packets

This commit is contained in:
samczsun 2016-12-24 01:46:45 -05:00
parent 0aec8889fa
commit eacbdfdb02

View File

@ -2,54 +2,73 @@ package mineplex.core.gadget.gadgets.morph;
import java.time.Month;
import java.time.YearMonth;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
import net.minecraft.server.v1_8_R3.DataWatcher;
import net.minecraft.server.v1_8_R3.EntityArmorStand;
import net.minecraft.server.v1_8_R3.EntitySlime;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutNamedEntitySpawn;
import net.minecraft.server.v1_8_R3.PacketPlayOutNewAttachEntity;
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
import net.minecraft.server.v1_8_R3.World;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import com.mojang.authlib.GameProfile;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.DummyEntity;
import mineplex.core.common.Rank;
import mineplex.core.common.skin.SkinData;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilText;
import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.event.StackerEvent;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.event.ItemGadgetUseEvent;
import mineplex.core.gadget.event.PlayerToggleSwimEvent;
import mineplex.core.gadget.gadgets.item.ItemEtherealPearl;
import mineplex.core.gadget.gadgets.morph.managers.UtilMorph;
import mineplex.core.gadget.types.GadgetType;
import mineplex.core.gadget.types.MorphGadget;
import mineplex.core.mount.event.MountActivateEvent;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.utils.UtilGameProfile;
public class MorphDinnerbone extends MorphGadget
import static mineplex.core.common.util.UtilServer.runSync;
public class MorphDinnerbone extends MorphGadget implements IPacketHandler
{
private Map<UUID, ArmorStand> _armorStands = new HashMap<>();
private static final String NAME = "Dinnerbone";
private final CoreClientManager _coreClientManager = Managers.require(CoreClientManager.class);
// Maps player to map of player and the id for the armorstand nametag
private final Map<Integer, Map<UUID, Integer>> _armorStandIds = new HashMap<>();
// Maps player to map of player and all ids that it owns
private final Map<Integer, Map<UUID, List<Integer>>> _allIds = new HashMap<>();
public MorphDinnerbone(GadgetManager manager)
{
super(manager, "Over Easy Morph", UtilText.splitLinesToArray(new String[]{
C.cGray + "This morph lets you walk around in your head. But be careful! While you're upside down some other cosmetics will be disabled.",
"",
C.cRedB + "You cannot right click mobs while using this morph!"
}, LineFormat.LORE),
C.cGray + "This morph lets you walk around in your head. But be careful! While you're upside down some other cosmetics will be disabled.",
"",
C.cRedB + "You cannot right click mobs while using this morph!"
}, LineFormat.LORE),
-14, Material.EGG, (byte) 0, YearMonth.of(2017, Month.JANUARY));
Managers.require(PacketHandler.class).addPacketHandler(this, PacketHandler.ListenerPriority.LOW, PacketPlayOutNamedEntitySpawn.class, PacketPlayOutEntityDestroy.class);
}
@Override
@ -58,30 +77,18 @@ public class MorphDinnerbone extends MorphGadget
applyArmor(player, message);
UtilGameProfile.getProfileByName(NAME, true, requestedProfile ->
{
Consumer<GameProfile> skinConsumer = requestedProfileSkin ->
{
SkinData skinData = SkinData.constructFromGameProfile(requestedProfileSkin, true, true);
requestedProfile.getProperties().clear();
requestedProfile.getProperties().put("textures", skinData.getProperty());
UtilGameProfile.getProfileByName(player.getName(), true, requestedProfileSkin ->
{
SkinData skinData = SkinData.constructFromGameProfile(requestedProfileSkin, true, true);
requestedProfile.getProperties().clear();
requestedProfile.getProperties().put("textures", skinData.getProperty());
DisguisePlayer disguisePlayer = new DisguisePlayer(player, requestedProfile);
disguisePlayer.setSendSkinDataToSelf(false);
disguisePlayer.setReplaceOriginalName(false, 500);
disguisePlayer.showInTabList(true, 0);
UtilMorph.disguise(player, disguisePlayer, Manager);
};
UtilGameProfile.getProfileByName(player.getName(), true, skinConsumer);
});
ArmorStand nameTag = player.getWorld().spawn(player.getLocation(), ArmorStand.class);
nameTag.setVisible(false);
nameTag.setGravity(false);
nameTag.setSmall(true);
setName(player, nameTag, player.getName(), Manager.getClientManager().Get(player).getRealOrDisguisedRank());
player.setPassenger(nameTag);
_armorStands.put(player.getUniqueId(), nameTag);
DisguisePlayer disguisePlayer = new DisguisePlayer(player, requestedProfile);
disguisePlayer.setSendSkinDataToSelf(false);
disguisePlayer.setReplaceOriginalName(false, 500);
disguisePlayer.showInTabList(true, 0);
UtilMorph.disguise(player, disguisePlayer, Manager);
}));
}
@Override
@ -90,16 +97,204 @@ public class MorphDinnerbone extends MorphGadget
removeArmor(player);
UtilMorph.undisguise(player, Manager.getDisguiseManager());
}
if (_armorStands.containsKey(player.getUniqueId()))
@Override
public void handle(PacketInfo packetInfo)
{
if (packetInfo.isCancelled())
return;
if (packetInfo.getPacket() instanceof PacketPlayOutNamedEntitySpawn)
{
_armorStands.get(player.getUniqueId()).remove();
_armorStands.remove(player.getUniqueId());
PacketPlayOutNamedEntitySpawn packet = (PacketPlayOutNamedEntitySpawn) packetInfo.getPacket();
Player owner = (Player) UtilEnt.getEntityById(packet.a);
if (Manager.getActive(owner, GadgetType.MORPH) == this)
{
summonForEntity(packetInfo.getPlayer(), owner);
}
}
else if (packetInfo.getPacket() instanceof PacketPlayOutEntityDestroy)
{
PacketPlayOutEntityDestroy packet = (PacketPlayOutEntityDestroy) packetInfo.getPacket();
for (int id : packet.a)
{
destroyForEntity(packetInfo.getPlayer(), id);
}
}
}
private void setName(Player player, ArmorStand stand, String name, Rank rank)
private void summonForEntity(Player receiver, Player player)
{
switch (UtilPlayer.getVersion(receiver))
{
case Version1_9:
summonForEntity19(receiver, player);
break;
case Version1_8:
summonForEntity18(receiver, player);
break;
case ALL:
// do nothing
break;
}
}
private void summonForEntity19(Player receiver, Player player)
{
World world = ((CraftWorld) receiver.getWorld()).getHandle();
DataWatcher armorStandWatcher = getArmorStandWatcher(player);
armorStandWatcher.a(10, (byte) 0x10, EntityArmorStand.META_ARMOR_OPTION, (byte) 0x10); // Small
DataWatcher squidWatcher = new DataWatcher(new DummyEntity(world));
squidWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20);
PacketPlayOutSpawnEntityLiving spawnSquid = new PacketPlayOutSpawnEntityLiving();
spawnSquid.a = UtilEnt.getNewEntityId();
spawnSquid.b = EntityType.SQUID.getTypeId();
spawnSquid.c = MathHelper.floor(player.getLocation().getX() * 32.0D);
spawnSquid.d = -150;
spawnSquid.e = MathHelper.floor(player.getLocation().getZ() * 32.0D);
spawnSquid.i = 0;
spawnSquid.j = 0;
spawnSquid.k = 0;
spawnSquid.f = 0;
spawnSquid.g = 0;
spawnSquid.h = 0;
spawnSquid.uuid = UUID.randomUUID();
spawnSquid.l = squidWatcher;
PacketPlayOutSpawnEntityLiving spawnArmorStand = new PacketPlayOutSpawnEntityLiving();
spawnArmorStand.a = UtilEnt.getNewEntityId();
spawnArmorStand.b = EntityType.ARMOR_STAND.getTypeId();
spawnArmorStand.c = MathHelper.floor(player.getLocation().getX() * 32.0D);
spawnArmorStand.d = -150;
spawnArmorStand.e = MathHelper.floor(player.getLocation().getZ() * 32.0D);
spawnArmorStand.i = 0;
spawnArmorStand.j = 0;
spawnArmorStand.k = 0;
spawnArmorStand.f = 0;
spawnArmorStand.g = 0;
spawnArmorStand.h = 0;
spawnArmorStand.uuid = UUID.randomUUID();
spawnArmorStand.l = armorStandWatcher;
PacketPlayOutNewAttachEntity attachSquidtoPlayer = new PacketPlayOutNewAttachEntity(player.getEntityId(), new int[]{spawnSquid.a});
PacketPlayOutNewAttachEntity attachArmorStandToSquid = new PacketPlayOutNewAttachEntity(spawnSquid.a, new int[]{spawnArmorStand.a});
_armorStandIds.computeIfAbsent(player.getEntityId(), key -> new HashMap<>()).put(receiver.getUniqueId(), spawnArmorStand.a);
_allIds.computeIfAbsent(player.getEntityId(), key -> new HashMap<>()).put(receiver.getUniqueId(), Arrays.asList(spawnSquid.a, spawnArmorStand.a));
runSync(() ->
{
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(spawnSquid);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(spawnArmorStand);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(attachSquidtoPlayer);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(attachArmorStandToSquid);
});
}
private void summonForEntity18(Player receiver, Player player)
{
World world = ((CraftWorld) receiver.getWorld()).getHandle();
DataWatcher armorStandWatcher = getArmorStandWatcher(player);
armorStandWatcher.a(10, (byte) 0x10, EntityArmorStand.META_ARMOR_OPTION, (byte) 0x10); // Small
DataWatcher squidWatcher = new DataWatcher(new DummyEntity(world));
squidWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20);
PacketPlayOutSpawnEntityLiving spawnSquid = new PacketPlayOutSpawnEntityLiving();
spawnSquid.a = UtilEnt.getNewEntityId();
spawnSquid.b = EntityType.WOLF.getTypeId();
spawnSquid.c = MathHelper.floor(player.getLocation().getX() * 32.0D);
spawnSquid.d = -150;
spawnSquid.e = MathHelper.floor(player.getLocation().getZ() * 32.0D);
spawnSquid.i = 0;
spawnSquid.j = 0;
spawnSquid.k = 0;
spawnSquid.f = 0;
spawnSquid.g = 0;
spawnSquid.h = 0;
spawnSquid.uuid = UUID.randomUUID();
spawnSquid.l = squidWatcher;
PacketPlayOutSpawnEntityLiving spawnArmorStand = new PacketPlayOutSpawnEntityLiving();
spawnArmorStand.a = UtilEnt.getNewEntityId();
spawnArmorStand.b = EntityType.ARMOR_STAND.getTypeId();
spawnArmorStand.c = MathHelper.floor(player.getLocation().getX() * 32.0D);
spawnArmorStand.d = -150;
spawnArmorStand.e = MathHelper.floor(player.getLocation().getZ() * 32.0D);
spawnArmorStand.i = 0;
spawnArmorStand.j = 0;
spawnArmorStand.k = 0;
spawnArmorStand.f = 0;
spawnArmorStand.g = 0;
spawnArmorStand.h = 0;
spawnArmorStand.uuid = UUID.randomUUID();
spawnArmorStand.l = armorStandWatcher;
PacketPlayOutAttachEntity attachSquidtoPlayer = new PacketPlayOutAttachEntity();
attachSquidtoPlayer.a = 0;
attachSquidtoPlayer.b = spawnSquid.a;
attachSquidtoPlayer.c = player.getEntityId();
PacketPlayOutAttachEntity attachArmorStandToSquid = new PacketPlayOutAttachEntity();
attachArmorStandToSquid.a = 0;
attachArmorStandToSquid.b = spawnArmorStand.a;
attachArmorStandToSquid.c = spawnSquid.a;
_armorStandIds.computeIfAbsent(player.getEntityId(), key -> new HashMap<>()).put(receiver.getUniqueId(), spawnArmorStand.a);
_allIds.computeIfAbsent(player.getEntityId(), key -> new HashMap<>()).put(receiver.getUniqueId(), Arrays.asList(spawnSquid.a, spawnArmorStand.a));
runSync(() ->
{
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(spawnSquid);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(spawnArmorStand);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(attachSquidtoPlayer);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(attachArmorStandToSquid);
});
}
private void destroyForEntity(Player receiver, int id)
{
Map<UUID, Integer> innerMap = _armorStandIds.get(id);
if (innerMap != null)
{
innerMap.remove(receiver.getUniqueId());
if (innerMap.isEmpty())
{
_armorStandIds.remove(id);
}
}
Map<UUID, List<Integer>> allIdsMap = _allIds.get(id);
if (allIdsMap != null)
{
List<Integer> ids = allIdsMap.remove(receiver.getUniqueId());
if (ids != null)
{
int[] idsArr = ids.stream().mapToInt(Integer::intValue).toArray();
PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(idsArr);
((CraftPlayer) receiver).getHandle().playerConnection.networkManager.handle(destroy);
}
if (allIdsMap.isEmpty())
{
_allIds.remove(id);
}
}
}
private DataWatcher getArmorStandWatcher(Player ownerOfTrack)
{
Rank rank = _coreClientManager.Get(ownerOfTrack).getRealOrDisguisedRank();
String name = ownerOfTrack.getName();
if (rank != null)
{
if (rank.has(Rank.ULTRA))
@ -108,82 +303,15 @@ public class MorphDinnerbone extends MorphGadget
}
}
stand.setCustomName(name);
stand.setCustomNameVisible(true);
World world = ((CraftWorld) ownerOfTrack.getWorld()).getHandle();
DataWatcher armorStandWatcher = new DataWatcher(new DummyEntity(world));
armorStandWatcher.a(0, (byte) 0x20, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0x20);
armorStandWatcher.a(1, (short) 300, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
armorStandWatcher.a(2, name, net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME, name);
armorStandWatcher.a(3, (byte) 1, net.minecraft.server.v1_8_R3.Entity.META_CUSTOMNAME_VISIBLE, true);
return armorStandWatcher;
}
@EventHandler
public void onDismount(StackerEvent event)
{
if (!(event.getEntity() instanceof Player))
return;
Player player = (Player) event.getEntity();
if (isActive(player))
event.setCancelled(true);
}
@EventHandler
public void onToggleSwim(PlayerToggleSwimEvent event)
{
if (!isActive(event.getPlayer()))
return;
// Disables morph if player is swimming or in lava
if (event.isSwimming() || event.isInLava())
{
disable(event.getPlayer());
}
}
@EventHandler
public void onVoid(EntityDamageEvent event)
{
if (event.getEntity() instanceof Player)
{
Player player = (Player) event.getEntity();
if (isActive(player))
{
if (event.getCause() == EntityDamageEvent.DamageCause.VOID)
{
disable(player);
}
}
}
}
@EventHandler
public void useEnderpearl(ItemGadgetUseEvent event)
{
if (event.getGadget() instanceof ItemEtherealPearl)
{
if (isActive(event.getPlayer()))
{
event.setCancelledMessage("You cannot use this item while morphed as " + getName() + "!");
event.setCancelled(true);
}
}
}
@EventHandler
public void activateMount(MountActivateEvent event)
{
if (isActive(event.getPlayer()))
{
event.setCancelled(true);
UtilPlayer.message(event.getPlayer(), F.main("Cosmetics", "You cannot use mounts while morphed as " + getName() + "!"));
}
}
@EventHandler
public void onTeleport(PlayerTeleportEvent event)
{
if (isActive(event.getPlayer()))
{
disable(event.getPlayer());
UtilPlayer.message(event.getPlayer(), F.main("Cosmetics", "You were unmorphed from " + getName() + "!"));
}
}
}