Skip to content

Commit

Permalink
NPC
Browse files Browse the repository at this point in the history
  • Loading branch information
Luuuuuis committed Sep 11, 2020
1 parent fe97a0d commit 2ff1311
Show file tree
Hide file tree
Showing 5 changed files with 397 additions and 16 deletions.
31 changes: 21 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,22 @@
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<relocations>
<relocation>
<pattern>net.jitse.npclib</pattern>
<shadedPattern>de.luuuuuis.privateserver</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase>
<goals>
<goal>single</goal>
<goal>shade</goal>
</goals>
</execution>
</executions>
Expand All @@ -64,8 +67,8 @@
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>

Expand All @@ -88,10 +91,18 @@
<!--Spigot API-->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<artifactId>spigot</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

<!-- https://github.com/MinecraftLibraries/NPCLib -->
<dependency>
<groupId>net.jitse</groupId>
<artifactId>npclib-plugin</artifactId>
<version>2.10-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import de.luuuuuis.privateserver.spigot.events.JoinListener;
import de.luuuuuis.privateserver.spigot.events.NPCListener;
import de.luuuuuis.privateserver.spigot.util.Config;
import de.luuuuuis.privateserver.spigot.util.Owner;
import net.jitse.npclib.NPCLib;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

Expand All @@ -13,6 +15,7 @@ public class PrivateServer extends JavaPlugin {
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static PrivateServer instance;
private Owner owner;
private NPCLib npcLib;

public static PrivateServer getInstance() {
return instance;
Expand All @@ -22,6 +25,7 @@ public static PrivateServer getInstance() {
public void onEnable() {
super.onEnable();
instance = this;
npcLib = new NPCLib(this);

// init Config
Config.init(getDataFolder());
Expand All @@ -30,16 +34,15 @@ public void onEnable() {
owner = new Owner();

PluginManager pluginManager = getServer().getPluginManager();
if (owner.getUuid() == null) {
// This is not a private server
System.err.println("[PrivateServer] This is not a privateserver. Disabling plugin.");
pluginManager.disablePlugin(this);
return;
}
pluginManager.registerEvents(new JoinListener(), this);
pluginManager.registerEvents(new NPCListener(this), this);
}

public Owner getOwner() {
return owner;
}

public NPCLib getNpcLib() {
return npcLib;
}
}
127 changes: 127 additions & 0 deletions src/main/java/de/luuuuuis/privateserver/spigot/events/NPCListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package de.luuuuuis.privateserver.spigot.events;

import de.luuuuuis.privateserver.spigot.PrivateServer;
import de.luuuuuis.privateserver.spigot.util.reflections.NMSUtils;
import de.luuuuuis.privateserver.spigot.util.reflections.Reflections;
import net.jitse.npclib.api.NPC;
import net.jitse.npclib.api.events.NPCInteractEvent;
import net.jitse.npclib.api.skin.Skin;
import net.jitse.npclib.internal.NPCBase;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class NPCListener implements Listener {

private final PrivateServer privateServer;
private final Map<Player, NPC> npcs = new HashMap<>();

public NPCListener(PrivateServer privateServer) {
this.privateServer = privateServer;
}

@EventHandler
public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();

Location location = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY(), p.getLocation().getZ());
NPC npc = privateServer.getNpcLib().createNPC(Collections.singletonList("§aPrivate Server"));
npc.setLocation(location);

Objects.requireNonNull(NMSUtils.getProfile(p)).getProperties().get("textures").stream()
.findFirst().ifPresent(playerProperty -> npc.setSkin(new Skin(playerProperty.getValue(), playerProperty.getSignature())));

npc.create();
npc.show(p);

npcs.put(p, npc);

// Sets head rotation for the npc if the player is in a range of 15 blocks
// Author: @yanjulang
new BukkitRunnable() {

@Override
public void run() {
if (!p.isOnline()) {
cancel();
return;
}

if (npc.getLocation().getWorld() == p.getWorld() && p.getLocation().distance(npc.getLocation()) < 15) {
Vector look = p.getLocation().toVector().add(new Vector(0, 1, 0)).subtract(npc.getLocation().toVector().add(new Vector(0, 1.54, 0)));
float[] rots = vecToRots(look);

if (rots[0] > 180) {
rots[0] -= 360;
}

Object packet = null;
try {
packet = Objects.requireNonNull(NMSUtils.getNMSClass("PacketPlayOutEntityHeadRotation")).getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException instantiationException) {
instantiationException.printStackTrace();
}

Reflections.setValue(packet, "a", ((NPCBase) npc).getEntityId());
Reflections.setValue(packet, "b", toAngle(rots[0]));
NMSUtils.sendPacket(p, packet);
NMSUtils.sendPacket(p, new PacketPlayOutEntity.PacketPlayOutEntityLook(((NPCBase) npc).getEntityId(), toAngle(rots[0]), toAngle(rots[1]), true));
}
}

private float[] vecToRots(Vector vector) {
double x = vector.getX();
double z = vector.getZ();
if (x == 0.0D && z == 0.0D) {
return new float[]{0f, (float) (vector.getY() > 0.0D ? -90 : 90)};
} else {
double theta = Math.atan2(-x, z);
float yaw = (float) Math.toDegrees((theta + 6.283185307179586D) % 6.283185307179586D);
double x2 = NumberConversions.square(x);
double z2 = NumberConversions.square(z);
double xz = Math.sqrt(x2 + z2);
float pitch = (float) Math.toDegrees(Math.atan(-vector.getY() / xz));
return new float[]{yaw, pitch};
}
}

public byte toAngle(float value) {
return (byte) ((int) (value * 256.0F / 360.0F));
}
}.runTaskTimerAsynchronously(privateServer, 0, 2);

}

@EventHandler
public void onQuit(PlayerQuitEvent e) {
Player p = e.getPlayer();

NPC npc = npcs.get(p);
npc.destroy();

npcs.remove(p);
}

@EventHandler
public void onInteract(NPCInteractEvent e) {
NPC npc = npcs.get(e.getWhoClicked());

if (e.getNPC().equals(npc)) {

}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package de.luuuuuis.privateserver.spigot.util.reflections;

import com.mojang.authlib.GameProfile;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import java.lang.reflect.InvocationTargetException;
import java.util.Objects;

public class NMSUtils {

/**
* Send a packet to a player without using direct nms imports
*
* @param player to send the packet to
* @param packet to send
*/
public static void sendPacket(Player player, Object packet) {
try {
Object handle = player.getClass().getMethod("getHandle").invoke(player);
Object connection = handle.getClass().getField("playerConnection").get(handle);
connection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(connection, packet);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException | NoSuchFieldException e) {
e.printStackTrace();
}
}

/**
* Get an NMS Class by its Name
* Class Path: Net.Ninecraft.Server.<VersionString>.ClassName
*
* @param name of the Class
* @return Class
*/
public static Class<?> getNMSClass(String name) {
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try {
return Class.forName("net.minecraft.server." + version + "." + name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}

/**
* Get an CraftBukkit Class by its Name
* Class Path: org.bukkit.craftbukkit.<VersionString>.ClassName
*
* @param name of the Class
* @return Class
*/
public static Class<?> getCraftBukkitClass(String name) {
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try {
return Class.forName("org.bukkit.craftbukkit." + version + "." + name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}

/**
* Get the NMS Version String from Bukkit.getServer() - package
*
* @return String
*/
public static String getVersion() {
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
}

/**
* Get the {@link GameProfile} from a player
*
* @param player to get the GameProfile from
* @return GameProfile
*/
public static GameProfile getProfile(Player player) {
try {
return (GameProfile) Objects.requireNonNull(NMSUtils.getHandle(player)).getClass().getMethod("getProfile").invoke(NMSUtils.getHandle(player));
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException e) {
e.printStackTrace();
return null;
}
}

/**
* Get an NMS - EntityPlayer - Object by a org.bukkit.Player - Object
*
* @param player (Bukkit Player)
* @return NMS EntityPlayer Object
*/
public static Object getHandle(Player player) {
try {
return player.getClass().getMethod("getHandle").invoke(player);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
| SecurityException e) {
return null;
}
}
}
Loading

0 comments on commit 2ff1311

Please sign in to comment.