Spawning player entity without any API?

Discussion in 'Plugin Development' started by Trevor1134, Jul 9, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Trevor1134

    I would like to spawn a simple entity that has a name, and can have a custom skin. Like a fake player. I would like to do this without using CitizensAPI, NPCFactory, or any other API. How difficult would this be to achieve? I understand it has to do with packets, but honestly I haven't done much w/packets and don't know whether or not this is a difficult task.

    Thanks!
     
  2. Offline

    TheMrGong

    Code:java
    1. //Only the player p will be able to see the fake player.
    2. //If you want everyone to see the player you have to loop through every
    3. //player and use spawnPlayer() on them
    4. //
    5. //Yaw/Pitch is the way the players head is turned.
    6. //A yaw of 0 or 360 represents the positive z direction.
    7. //A yaw of 180 represents the negative z direction.
    8. //A yaw of 90 represents the negative x direction.
    9. //A yaw of 270 represents the positive x direction.
    10. public void spawnPlayer(Player p, String name, float yaw, float pitch)
    11. {
    12. ProtocolManager manager = ProtocolLibrary.getProtocolManager();
    13. WrapperPlayServerNamedEntitySpawn spawned = new WrapperPlayServerNamedEntitySpawn();
    14.  
    15. Random ra = new Random();
    16. spawned.setEntityID(ra.nextInt(Integer.MAX_VALUE)+300);
    17. spawned.setPosition(p.getLocation().toVector());
    18. spawned.setPlayerName(name);
    19. spawned.setPlayerUUID(UUID.randomUUID().toString());
    20.  
    21. spawned.setYaw(yaw);
    22. spawned.setPitch(pitch);
    23.  
    24. // Documentation:
    25. // [url]http://mc.kev009.com/Entities#Entity_Metadata_Format[/url]
    26. WrappedDataWatcher watcher = new WrappedDataWatcher();
    27. watcher.setObject(0, (byte) 0);
    28. watcher.setObject(1, (short) 300);
    29. watcher.setObject(8, (byte) 6);
    30. spawned.setMetadata(watcher);
    31.  
    32. try {
    33. manager.sendServerPacket(p, spawned.getHandle());
    34. }
     
  3. Offline

    Trevor1134

    TheMrGong WrappedPlayerServerNamedEntitySpawn isn't appearing to be importable?
     
  4. Offline

    LordVakar

  5. Offline

    Trevor1134

  6. Offline

    TheMrGong

    Whoops here you go put this in a package that has the method I gave you.

    Class: WrapperPlayServerNamedEntitySpawn
    Code:java
    1. /*
    2. * PacketWrapper - Contains wrappers for each packet in Minecraft.
    3. * Copyright (C) 2012 Kristian S. Stangeland
    4. *
    5. * This program is free software; you can redistribute it and/or modify it under the terms of the
    6. * GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
    7. * the License, or (at your option) any later version.
    8. *
    9. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    11. * See the GNU General Public License for more details.
    12. *
    13. * You should have received a copy of the GNU General Public License along with this program;
    14. * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    15. * 02111-1307 USA
    16. */
    17.  
    18. package com.gong.main;
    19.  
    20. import org.bukkit.World;
    21. import org.bukkit.entity.Entity;
    22. import org.bukkit.entity.Player;
    23. import org.bukkit.util.Vector;
    24.  
    25. import com.comphenix.protocol.PacketType;
    26. import com.comphenix.protocol.ProtocolLibrary;
    27. import com.comphenix.protocol.events.PacketContainer;
    28. import com.comphenix.protocol.events.PacketEvent;
    29. import com.comphenix.protocol.injector.PacketConstructor;
    30. import com.comphenix.protocol.wrappers.WrappedDataWatcher;
    31. import com.comphenix.protocol.wrappers.WrappedGameProfile;
    32. import com.google.common.base.Preconditions;
    33.  
    34. public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket {
    35. public static final PacketType TYPE = PacketType.Play.Server.NAMED_ENTITY_SPAWN;
    36.  
    37. // For constructing packets from entities
    38. private static PacketConstructor entityConstructor;
    39.  
    40. public WrapperPlayServerNamedEntitySpawn() {
    41. super(new PacketContainer(TYPE), TYPE);
    42. handle.getModifier().writeDefaults();
    43. }
    44.  
    45. public WrapperPlayServerNamedEntitySpawn(PacketContainer packet) {
    46. super(packet, TYPE);
    47. }
    48.  
    49. public WrapperPlayServerNamedEntitySpawn(Player player) {
    50. super(fromPlayer(player), TYPE);
    51. }
    52.  
    53. // Useful constructor
    54. private static PacketContainer fromPlayer(Player player) {
    55. if (entityConstructor == null)
    56. entityConstructor = ProtocolLibrary.getProtocolManager().createPacketConstructor(TYPE, player);
    57. return entityConstructor.createPacket(player);
    58. }
    59.  
    60. /**
    61.   * Retrieve player ID.
    62.   * @return The current EID
    63.   */
    64. public int getEntityID() {
    65. return handle.getIntegers().read(0);
    66. }
    67.  
    68. /**
    69.   * Set player ID.
    70.   * @param value - new value.
    71.   */
    72. public void setEntityID(int value) {
    73. handle.getIntegers().write(0, value);
    74. }
    75.  
    76. /**
    77.   * Retrieve the player's entity object.
    78.   * @param world - the word the player has joined.
    79.   * @return The player's entity.
    80.   */
    81. public Entity getEntity(World world) {
    82. return handle.getEntityModifier(world).read(0);
    83. }
    84.  
    85. /**
    86.   * Retrieve the player's entity object.
    87.   * @param event - the packet event.
    88.   * @return The player's entity.
    89.   */
    90. public Entity getEntity(PacketEvent event) {
    91. return getEntity(event.getPlayer().getWorld());
    92. }
    93.  
    94. /**
    95.   * Retrieve the player name.
    96.   * <p>
    97.   * Max length of 16.
    98.   * @return The current player Name, or NULL if not set.
    99.   */
    100. public String getPlayerName() {
    101. WrappedGameProfile profile = getProfile();
    102. return profile != null ? profile.getName() : null;
    103. }
    104.  
    105. /**
    106.   * Set the player name.
    107.   * <p>
    108.   * Max length of 16.
    109.   * @param value - new value.
    110.   */
    111. public void setPlayerName(String value) {
    112. if (value != null && value.length() > 16)
    113. throw new IllegalArgumentException("Maximum player name lenght is 16 characters.");
    114. setProfile(new WrappedGameProfile(getPlayerUUID(), value));
    115. }
    116.  
    117. /**
    118.   * Retrieve the UUID of the player.
    119.   * @return The UUID, or NULL if not set.
    120.   */
    121. public String getPlayerUUID() {
    122. WrappedGameProfile profile = getProfile();
    123. return profile != null ? profile.getId() : null;
    124. }
    125.  
    126. /**
    127.   * Set the UUID of the player.
    128.   * @param uuid - the UUID.
    129.   */
    130. public void setPlayerUUID(String uuid) {
    131. setProfile(new WrappedGameProfile(uuid, getPlayerName()));
    132. }
    133.  
    134. /**
    135.   * Retrieve player's full profile.
    136.   * @return The spawner player's profile.
    137.   */
    138. public WrappedGameProfile getProfile() {
    139. return handle.getGameProfiles().read(0);
    140. }
    141.  
    142. /**
    143.   * Set the spawned player's profile.
    144.   * @param value - new profile.
    145.   */
    146. public void setProfile(WrappedGameProfile value) {
    147. handle.getGameProfiles().write(0, value);
    148. }
    149.  
    150. /**
    151.   * Retrieve the position of the spawned entity as a vector.
    152.   * @return The position as a vector.
    153.   */
    154. public Vector getPosition() {
    155. return new Vector(getX(), getY(), getZ());
    156. }
    157.  
    158. /**
    159.   * Set the position of the spawned entity using a vector.
    160.   * @param position - the new position.
    161.   */
    162. public void setPosition(Vector position) {
    163. setX(position.getX());
    164. setY(position.getY());
    165. setZ(position.getZ());
    166. }
    167.  
    168. /**
    169.   * Retrieve the x axis of the position.
    170.   * <p>
    171.   * Note that the coordinate is rounded off to the nearest 1/32 of a meter.
    172.   * @return The current X
    173.   */
    174. public double getX() {
    175. return handle.getIntegers().read(1) / 32.0D;
    176. }
    177.  
    178. /**
    179.   * Set the x axis of the position.
    180.   * @param value - new value.
    181.   */
    182. public void setX(double value) {
    183. handle.getIntegers().write(1, (int) Math.floor(value * 32.0D));
    184. }
    185.  
    186. /**
    187.   * Retrieve the y axis of the position.
    188.   * <p>
    189.   * Note that the coordinate is rounded off to the nearest 1/32 of a meter.
    190.   * @return The current y
    191.   */
    192. public double getY() {
    193. return handle.getIntegers().read(2) / 32.0D;
    194. }
    195.  
    196. /**
    197.   * Set the y axis of the position.
    198.   * @param value - new value.
    199.   */
    200. public void setY(double value) {
    201. handle.getIntegers().write(2, (int) Math.floor(value * 32.0D));
    202. }
    203.  
    204. /**
    205.   * Retrieve the z axis of the new position.
    206.   * <p>
    207.   * Note that the coordinate is rounded off to the nearest 1/32 of a meter.
    208.   * @return The current z
    209.   */
    210. public double getZ() {
    211. return handle.getIntegers().read(3) / 32.0D;
    212. }
    213.  
    214. /**
    215.   * Set the z axis of the new position.
    216.   * @param value - new value.
    217.   */
    218. public void setZ(double value) {
    219. handle.getIntegers().write(3, (int) Math.floor(value * 32.0D));
    220. }
    221.  
    222. /**
    223.   * Retrieve the yaw of the spawned entity.
    224.   * @return The current Yaw
    225.   */
    226. public float getYaw() {
    227. return (handle.getBytes().read(0) * 360.F) / 256.0F;
    228. }
    229.  
    230. /**
    231.   * Set the yaw of the spawned entity.
    232.   * @param value - new yaw.
    233.   */
    234. public void setYaw(float value) {
    235. handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
    236. }
    237.  
    238. /**
    239.   * Retrieve the pitch of the spawned entity.
    240.   * @return The current pitch
    241.   */
    242. public float getPitch() {
    243. return (handle.getBytes().read(1) * 360.F) / 256.0F;
    244. }
    245.  
    246. /**
    247.   * Set the pitch of the spawned entity.
    248.   * @param value - new pitch.
    249.   */
    250. public void setPitch(float value) {
    251. handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
    252. }
    253.  
    254. /**
    255.   * Retrieve the item the player is currently holding.
    256.   * <p>
    257.   * Note that this should be 0 for "no item", unlike -1 used in other packets. A negative value crashes clients.
    258.   * @return The current item.
    259.   */
    260. public short getCurrentItem() {
    261. return handle.getIntegers().read(4).shortValue();
    262. }
    263.  
    264. /**
    265.   * Set the item the player is currently holding.
    266.   * <p>
    267.   * Note that this should be 0 for "no item", unlike -1 used in other packets. A negative value crashes clients.
    268.   * @param value - new value.
    269.   */
    270. public void setCurrentItem(short value) {
    271. handle.getIntegers().write(4, (int) value);
    272. }
    273.  
    274. /**
    275.   * Retrieve the associated metadata object.
    276.   * <p>
    277.   * Note that the 1.3 client crashes on packets with no metadata, but the server can send any metadata
    278.   * key of 0, 1 or 8 and the client is fine.
    279.   * @return The current metadata.
    280.   */
    281. public WrappedDataWatcher getMetadata() {
    282. return handle.getDataWatcherModifier().read(0);
    283. }
    284.  
    285. /**
    286.   * Set the associated metadata object.
    287.   * <p>
    288.   * Note that the 1.3 client crashes on packets with no metadata, but the server can send any metadata
    289.   * key of 0, 1 or 8 and the client is fine..
    290.   * @param value - new value.
    291.   */
    292. public void setMetadata(WrappedDataWatcher value) {
    293. handle.getDataWatcherModifier().write(0, value);
    294. }
    295.  
    296. @Override
    297. public PacketContainer getHandle() {
    298. Preconditions.checkNotNull(getPlayerName(), "Must specify a player name.");
    299. Preconditions.checkNotNull(getPlayerUUID(), "Must specify a player UUID.");
    300. return super.getHandle();
    301. }
    302. }


    Class: Abstract Packet
    Code:java
    1. /*
    2. * PacketWrapper - Contains wrappers for each packet in Minecraft.
    3. * Copyright (C) 2012 Kristian S. Stangeland
    4. *
    5. * This program is free software; you can redistribute it and/or modify it under the terms of the
    6. * GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of
    7. * the License, or (at your option) any later version.
    8. *
    9. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    11. * See the GNU General Public License for more details.
    12. *
    13. * You should have received a copy of the GNU General Public License along with this program;
    14. * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    15. * 02111-1307 USA
    16. */
    17.  
    18. package com.gong.main;
    19.  
    20. import java.lang.reflect.InvocationTargetException;
    21.  
    22. import org.bukkit.entity.Player;
    23.  
    24. import com.comphenix.protocol.PacketType;
    25. import com.comphenix.protocol.ProtocolLibrary;
    26. import com.comphenix.protocol.events.PacketContainer;
    27. import com.google.common.base.Objects;
    28.  
    29. public abstract class AbstractPacket {
    30. // The packet we will be modifying
    31. protected PacketContainer handle;
    32.  
    33. /**
    34.   * Constructs a new strongly typed wrapper for the given packet.
    35.   * @param handle - handle to the raw packet data.
    36.   * @param type - the packet type.
    37.   */
    38. protected AbstractPacket(PacketContainer handle, PacketType type) {
    39. // Make sure we're given a valid packet
    40. if (handle == null)
    41. throw new IllegalArgumentException("Packet handle cannot be NULL.");
    42. if (!Objects.equal(handle.getType(), type))
    43. handle.getHandle() + " is not a packet of type " + type);
    44.  
    45. this.handle = handle;
    46. }
    47.  
    48. /**
    49.   * Retrieve a handle to the raw packet data.
    50.   * @return Raw packet data.
    51.   */
    52. public PacketContainer getHandle() {
    53. return handle;
    54. }
    55.  
    56. /**
    57.   * Send the current packet to the given receiver.
    58.   * @param receiver - the receiver.
    59.   * @throws RuntimeException If the packet cannot be sent.
    60.   */
    61. public void sendPacket(Player receiver) {
    62. try {
    63. ProtocolLibrary.getProtocolManager().sendServerPacket(receiver, getHandle());
    64. throw new RuntimeException("Cannot send packet.", e);
    65. }
    66. }
    67.  
    68. /**
    69.   * Simulate receiving the current packet from the given sender.
    70.   * @param sender - the sender.
    71.   * @throws RuntimeException If the packet cannot be received.
    72.   */
    73. public void recievePacket(Player sender) {
    74. try {
    75. ProtocolLibrary.getProtocolManager().recieveClientPacket(sender, getHandle());
    76. } catch (Exception e) {
    77. throw new RuntimeException("Cannot recieve packet.", e);
    78. }
    79. }
    80. }
     
  7. Offline

    LordVakar

  8. Offline

    Trevor1134

    TheMrGong Thank you. It now spawns! My only issue is that it won't set a custom skin?
     
  9. Offline

    TheMrGong

    The name is what skin is displayed. Such as, "TheMrGong" will display my skin, "seifnsei" will display some skin, etc.

    As far as I know you cant make a custom skin since skins come from minecrafts skin server.
     
  10. Offline

    Goblom

    TheMrGong NPCLibrary does this using NPCProfile (name does not match skin)
     
  11. Offline

    TheMrGong

    Goblom How would you spawn, lets say "TheMrGong" but with someone elses skin then?
     
  12. Offline

    LordVakar

    lenis0012 and Goblom like this.
  13. Offline

    TheMrGong

  14. Offline

    lenis0012

    Basicly its easier to shade my NPCFactory in to your project.
    It doesn't mean you need an extra download or jar, thats why its so fancy :)
     
Thread Status:
Not open for further replies.

Share This Page