Hi, I'm actually devlopping a plugin in wich I need to make spawn NPC. I can make them spawn esealy but I can't assign a skin from a real player to them. Thanks for help
This is my code: I get a random player uuid/name from my database Code (Text): try { MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer(); ResultSet data = Database.query("SELECT uuid, lastname FROM pnjserv_players ORDER BY RAND() LIMIT 1;"); if(data.next()){ String uuid = data.getString("uuid"); String name = data.getString("lastname"); GameProfile gameProfile = new GameProfile(UUID.fromString(uuid), name); HttpURLConnection connection = (HttpURLConnection) new URL("https://sessionserver.mojang.com/session/minecraft/profile/"+uuid.replace("-", "")).openConnection(); JSONArray response = (JSONArray)((JSONObject) jsonParser.parse(new InputStreamReader(connection.getInputStream()))).get("properties"); JSONObject a = (JSONObject) response.get(0); gameProfile.getProperties().put("textures", new Property((String) a.get("name"), (String) a.get("value"))); WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle(); EntityPlayer npc = new EntityPlayer(server, world, gameProfile, new NPCInteractManager(world)); npc.setLocation(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player.getLocation().getYaw(), player.getLocation().getPitch()); for(Player pls : Bukkit.getOnlinePlayers()) { PlayerConnection connection = ((CraftPlayer) pls).getHandle().playerConnection; connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc)); connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc)); } } } catch (SQLException e) { e.printStackTrace(); }
So your issue is that the npc doens't have a skin applied? Have you made some outputs for the texture values? Because the sessionservers won't allow requests that are done several times in some seconds Edit: And maybe also outputs from your uuid if that is maybe called wrong
I try with me and broadcast the results: My uuid is: b8621ff7-bd32-4231-9911-1200ab9a840c My username is: nitnoq a.get("name") return: "textures" a.get("value") return: "eyJ0aW1lc3RhbXAiOjE0OTM2NDcxOTU0MDYsInByb2ZpbGVJZCI6ImI4NjIxZmY3YmQzMjQyMzE5OTExMTIwMGFiOWE4NDBjIiwicHJvZmlsZU5hbWUiOiJuaXRub3EiLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWVlMDQ5YjgyZGMyYmNiYmEzYjIxOGU4YTNlOTMzNDI5N2I2MTEzNWM3ODQ5ZGI0NTY5M2Y0Y2QzYyJ9fX0=" So I don't think there are a problem during the mojang servers request EDIT: gameProfile.getProperties().put("textures", new Property((String) a.get("name"), (String) a.get("value"))); I'm not shure about the utilisation of this
I'm making a request to mojang servers: https://sessionserver.mojang.com/session/minecraft/profile/b8621ff7bd32423199111200ab9a840c And it return this: Code (Text): { "id": "b8621ff7bd32423199111200ab9a840c", "name": "nitnoq", "properties": [{ "name": "textures", "value": "eyJ0aW1lc3RhbXAiOjE0OTM2Njc3NTQ3ODEsInByb2ZpbGVJZCI6ImI4NjIxZmY3YmQzMjQyMzE5OTExMTIwMGFiOWE4NDBjIiwicHJvZmlsZU5hbWUiOiJuaXRub3EiLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWVlMDQ5YjgyZGMyYmNiYmEzYjIxOGU4YTNlOTMzNDI5N2I2MTEzNWM3ODQ5ZGI0NTY5M2Y0Y2QzYyJ9fX0=" }] }
Maybe let the player force respawn after you apply the skin (that's what i had to do at one of my old Nick systems)
Here is my 1_11 FakePlayer class. Feel free to use it. It's MIT. It works off of a in-game player, so you'd just need to change that for a skin as shown above. 1_11_R1 Class Code (Java): import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v1_11_R1.CraftServer; import org.bukkit.craftbukkit.v1_11_R1.CraftWorld; import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; import com.mojang.authlib.GameProfile; import net.minecraft.server.v1_11_R1.EntityPlayer; import net.minecraft.server.v1_11_R1.EnumItemSlot; import net.minecraft.server.v1_11_R1.ItemStack; import net.minecraft.server.v1_11_R1.MinecraftServer; import net.minecraft.server.v1_11_R1.PacketPlayOutNamedEntitySpawn; import net.minecraft.server.v1_11_R1.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_11_R1.PlayerConnection; import net.minecraft.server.v1_11_R1.PlayerInteractManager; import net.minecraft.server.v1_11_R1.WorldServer; import net.minecraft.server.v1_11_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction; /************************* * * Copyright (c) 2017 Jordan Thompson (WASasquatch) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * *************************/ public class FakePlayer_v1_11_R1 implements FakePlayer { public void spawnFakePlayer(Player player, Location location, String displayName) { MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer(); WorldServer world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle(); EntityPlayer npc = new EntityPlayer(server, world, new GameProfile(player.getUniqueId(), displayName), new PlayerInteractManager(world)); npc.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); ItemStack feet = CraftItemStack.asNMSCopy(player.getInventory().getBoots()); ItemStack legs = CraftItemStack.asNMSCopy(player.getInventory().getLeggings()); ItemStack chest = CraftItemStack.asNMSCopy(player.getInventory().getChestplate()); ItemStack head = CraftItemStack.asNMSCopy(player.getInventory().getHelmet()); ItemStack mainHand = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); ItemStack offHand = CraftItemStack.asNMSCopy(player.getInventory().getItemInOffHand()); npc.setEquipment(EnumItemSlot.FEET, feet); npc.setEquipment(EnumItemSlot.LEGS, legs); npc.setEquipment(EnumItemSlot.CHEST, chest); npc.setEquipment(EnumItemSlot.HEAD, head); npc.setEquipment(EnumItemSlot.MAINHAND, mainHand); npc.setEquipment(EnumItemSlot.OFFHAND, offHand); for (Player p : Bukkit.getOnlinePlayers()) { PlayerConnection connection = ((CraftPlayer)p).getHandle().playerConnection; connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc)); connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc)); } } } Interface Code (Java): import org.bukkit.Location; import org.bukkit.entity.Player; /************************* * * Copyright (c) 2017 Jordan Thompson (WASasquatch) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * *************************/ public interface FakePlayer { public void spawnFakePlayer(Player player, Location location, String displayName); } Example Main Code (Java): import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import wa.was.fakeplayer.Main; import wa.was.fakeplayer.events.OnJoin; import wa.was.fakeplayer.nms.FakePlayer; import wa.was.fakeplayer.nms.FakePlayer_v1_11_R1; import wa.was.fakeplayer.utils.ConsoleColor; /************************* * * Copyright (c) 2017 Jordan Thompson (WASasquatch) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * *************************/ public class Main extends JavaPlugin { private static FakePlayer fakePlayer; private static Main instance; @Override public void onEnable() { instance = this; determineFakePlayerInstance(); getServer().getPluginManager().registerEvents(new OnJoin(), this); } public void determineFakePlayerInstance() { String version = ""; try { version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; } catch (ArrayIndexOutOfBoundsException whatVersionAreYouUsingException) { getLogger().severe("Could not determine server version!" + ConsoleColor.RED + ConsoleColor.BOLD + " Disabling!" + ConsoleColor.RESET); getServer().getPluginManager().disablePlugin(this); } getLogger().info("Your server is running version " + version); switch (version) { case "v1_11_R1": fakePlayer = new FakePlayer_v1_11_R1(); break; default: getLogger().severe("Could not determine server version!" + ConsoleColor.RED + ConsoleColor.BOLD + " Disabling!" + ConsoleColor.RESET); getServer().getPluginManager().disablePlugin(this); break; } } public static FakePlayer getFakePlayer() { return fakePlayer; } public static Main getInstance() { return instance; } } Example Usage (Create mock player on join. Just example) Code (Java): private FakePlayer fakePlayer; public OnJoin() { fakePlayer = Main.getFakePlayer(); } @EventHandler public void onJoin(PlayerJoinEvent e) { final Player player = e.getPlayer(); new BukkitRunnable() { @Override public void run() { if (player != null && player.isOnline()) { fakePlayer.spawnFakePlayer(player, player.getLocation().add(1.0, 0, 1.0), player.getDisplayName()); } } }.runTaskLater(Main.getInstance(), 3); } Bonus that ConsoleColor.class I am using Code (Java): /************************* * * Copyright (c) 2017 Jordan Thompson (WASasquatch) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * *************************/ public class ConsoleColor { public static final String RESET = "\u001B[0m"; public static final String BOLD = "\u001B[1m"; public static final String ITALIC = "\u001B[3m"; public static final String UNDERLINE = "\u001B[4m"; public static final String NORMAL = "\u001B[22m"; public static final String BLACK = "\u001B[30m"; public static final String RED = "\u001B[31m"; public static final String GREEN = "\u001B[32m"; public static final String YELLOW = "\u001B[33m"; public static final String BLUE = "\u001B[34m"; public static final String PURPLE = "\u001B[35m"; public static final String CYAN = "\u001B[36m"; public static final String WHITE = "\u001B[37m"; public static final String BLACK_BACKGROUND = "\u001B[40m"; public static final String RED_BACKGROUND = "\u001B[41m"; public static final String GREEN_BACKGROUND = "\u001B[42m"; public static final String YELLOW_BACKGROUND = "\u001B[43m"; public static final String BLUE_BACKGROUND = "\u001B[44m"; public static final String PURPLE_BACKGROUND = "\u001B[45m"; public static final String CYAN_BACKGROUND = "\u001B[46m"; public static final String WHITE_BACKGROUND = "\u001B[47m"; }
I'm sorry, I don't quite understand. You mean right clicking the fake player to trigger an event? If so, yes, that should work. It should be an instance of a entity in the world (I believe).
I mean the fakePlayer exists because with packets its only client sided (The server dont know if there is a FakePlayer) so dont fire evetns
Oh I see. I'd imagine you just bind the entity location with a invisible entity of your choosing (with no AI, and probably representing the correct size. A armorstand probably be best).