Started on 1.7.10 (v1_7_R4) support (#10).
The older version of Netty is causing a bug with TinyProtocol.
This commit is contained in:
@@ -4,6 +4,8 @@ cache:
|
|||||||
- $HOME/.m2/
|
- $HOME/.m2/
|
||||||
install:
|
install:
|
||||||
- wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
|
- wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
|
||||||
|
- wget https://github.com/Sarabveer/CraftBukkit-Spigot-Binary/blob/master/spigot-1.7.10-R0.1/spigot-1.7.10-R0.1-1649.jar
|
||||||
|
- mvn install:install-file -Dfile=spigot-1.7.10-R0.1-1649.jar -DgroupId=org.spigotmc -DartifactId=spigot -Dversion=1.7.10-R0.1-SNAPSHOT -Dpackaging=jar
|
||||||
- ls $HOME/.m2/repository/org/spigotmc/spigot/1.8-R0.1-SNAPSHOT >> /dev/null 2>&1 || java -jar BuildTools.jar --rev 1.8 >> /dev/null 2>&1
|
- ls $HOME/.m2/repository/org/spigotmc/spigot/1.8-R0.1-SNAPSHOT >> /dev/null 2>&1 || java -jar BuildTools.jar --rev 1.8 >> /dev/null 2>&1
|
||||||
- ls $HOME/.m2/repository/org/spigotmc/spigot/1.8.3-R0.1-SNAPSHOT >> /dev/null 2>&1 || java -jar BuildTools.jar --rev 1.8.3 >> /dev/null 2>&1
|
- ls $HOME/.m2/repository/org/spigotmc/spigot/1.8.3-R0.1-SNAPSHOT >> /dev/null 2>&1 || java -jar BuildTools.jar --rev 1.8.3 >> /dev/null 2>&1
|
||||||
- ls $HOME/.m2/repository/org/spigotmc/spigot/1.8.8-R0.1-SNAPSHOT >> /dev/null 2>&1 || java -jar BuildTools.jar --rev 1.8.8 >> /dev/null 2>&1
|
- ls $HOME/.m2/repository/org/spigotmc/spigot/1.8.8-R0.1-SNAPSHOT >> /dev/null 2>&1 || java -jar BuildTools.jar --rev 1.8.8 >> /dev/null 2>&1
|
||||||
|
|||||||
@@ -19,6 +19,12 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.jitse</groupId>
|
||||||
|
<artifactId>npclib-nms-v1_7_R4</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.jitse</groupId>
|
<groupId>net.jitse</groupId>
|
||||||
<artifactId>npclib-nms-v1_8_R1</artifactId>
|
<artifactId>npclib-nms-v1_8_R1</artifactId>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<artifactId>npclib-nms</artifactId>
|
<artifactId>npclib-nms</artifactId>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
<module>v1_7_R4</module>
|
||||||
<module>v1_8_R1</module>
|
<module>v1_8_R1</module>
|
||||||
<module>v1_8_R2</module>
|
<module>v1_8_R2</module>
|
||||||
<module>v1_8_R3</module>
|
<module>v1_8_R3</module>
|
||||||
|
|||||||
Executable
+35
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>net.jitse</groupId>
|
||||||
|
<artifactId>npclib-nms</artifactId>
|
||||||
|
<version>1.3</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>npclib-nms-v1_7_R4</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>1.7.10-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.8.5</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-all</artifactId>
|
||||||
|
<version>4.0.23.Final</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Jitse Boonstra
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.jitse.npclib.nms.v1_7_R4;
|
||||||
|
|
||||||
|
import net.jitse.npclib.api.NPC;
|
||||||
|
import net.jitse.npclib.nms.holograms.Hologram;
|
||||||
|
import net.jitse.npclib.nms.v1_7_R4.packets.PacketPlayOutEntityHeadRotationWrapper;
|
||||||
|
import net.jitse.npclib.nms.v1_7_R4.packets.PacketPlayOutNamedEntitySpawnWrapper;
|
||||||
|
import net.jitse.npclib.nms.v1_7_R4.packets.PacketPlayOutPlayerInfoWrapper;
|
||||||
|
import net.jitse.npclib.nms.v1_7_R4.packets.PacketPlayOutScoreboardTeamWrapper;
|
||||||
|
import net.jitse.npclib.skin.Skin;
|
||||||
|
import net.minecraft.server.v1_7_R4.*;
|
||||||
|
import net.minecraft.util.com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.util.com.mojang.authlib.properties.Property;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jitse Boonstra
|
||||||
|
*/
|
||||||
|
public class NPC_v1_7_R4 extends NPC {
|
||||||
|
|
||||||
|
private Hologram hologram;
|
||||||
|
private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn;
|
||||||
|
private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister, packetPlayOutScoreboardTeamUnregister;
|
||||||
|
private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove;
|
||||||
|
private PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation;
|
||||||
|
private PacketPlayOutEntityDestroy packetPlayOutEntityDestroy;
|
||||||
|
|
||||||
|
private GameProfile legacyGameProfile;
|
||||||
|
|
||||||
|
public NPC_v1_7_R4(JavaPlugin plugin, Skin skin, double autoHideDistance, List<String> lines) {
|
||||||
|
super(plugin, skin, autoHideDistance, lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createPackets() {
|
||||||
|
this.hologram = new Hologram(location.clone().add(0, 0.5, 0), lines);
|
||||||
|
hologram.generatePackets(false, false);
|
||||||
|
|
||||||
|
this.legacyGameProfile = generateLegacyGameProfile(uuid, name);
|
||||||
|
PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper();
|
||||||
|
|
||||||
|
// Packets for spawning the NPC:
|
||||||
|
this.packetPlayOutScoreboardTeamRegister = new PacketPlayOutScoreboardTeamWrapper()
|
||||||
|
.createRegisterTeam(name); // First packet to send.
|
||||||
|
|
||||||
|
this.packetPlayOutPlayerInfoAdd = packetPlayOutPlayerInfoWrapper
|
||||||
|
.create(0, legacyGameProfile, name); // Second packet to send.
|
||||||
|
|
||||||
|
this.packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawnWrapper()
|
||||||
|
.create(uuid, location, entityId); // Third packet to send.
|
||||||
|
|
||||||
|
this.packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotationWrapper()
|
||||||
|
.create(location, entityId); // Fourth packet to send.
|
||||||
|
|
||||||
|
this.packetPlayOutPlayerInfoRemove = packetPlayOutPlayerInfoWrapper
|
||||||
|
.create(4, legacyGameProfile, name); // Fifth packet to send (delayed).
|
||||||
|
|
||||||
|
// Packet for destroying the NPC:
|
||||||
|
this.packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(entityId); // First packet to send.
|
||||||
|
|
||||||
|
// Second packet to send is "packetPlayOutPlayerInfoRemove".
|
||||||
|
|
||||||
|
this.packetPlayOutScoreboardTeamUnregister = new PacketPlayOutScoreboardTeamWrapper()
|
||||||
|
.createUnregisterTeam(name); // Third packet to send.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendShowPackets(Player player) {
|
||||||
|
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||||
|
|
||||||
|
playerConnection.sendPacket(packetPlayOutScoreboardTeamRegister);
|
||||||
|
playerConnection.sendPacket(packetPlayOutPlayerInfoAdd);
|
||||||
|
playerConnection.sendPacket(packetPlayOutNamedEntitySpawn);
|
||||||
|
playerConnection.sendPacket(packetPlayOutEntityHeadRotation);
|
||||||
|
|
||||||
|
hologram.spawn(player);
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(plugin, () ->
|
||||||
|
playerConnection.sendPacket(packetPlayOutPlayerInfoRemove), 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendHidePackets(Player player, boolean scheduler) {
|
||||||
|
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||||
|
|
||||||
|
playerConnection.sendPacket(packetPlayOutEntityDestroy);
|
||||||
|
playerConnection.sendPacket(packetPlayOutPlayerInfoRemove);
|
||||||
|
|
||||||
|
hologram.destroy(player);
|
||||||
|
|
||||||
|
if (scheduler) {
|
||||||
|
// Sending this a bit later so the player doesn't see the name (for that split second).
|
||||||
|
Bukkit.getScheduler().runTaskLater(plugin, () ->
|
||||||
|
playerConnection.sendPacket(packetPlayOutScoreboardTeamUnregister), 5);
|
||||||
|
} else {
|
||||||
|
playerConnection.sendPacket(packetPlayOutScoreboardTeamUnregister);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameProfile generateLegacyGameProfile(UUID uuid, String name) {
|
||||||
|
GameProfile gameProfile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
|
if (skin != null) {
|
||||||
|
gameProfile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameProfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Jitse Boonstra
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.jitse.npclib.nms.v1_7_R4.packets;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import net.minecraft.server.v1_7_R4.PacketPlayOutEntityHeadRotation;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jitse Boonstra
|
||||||
|
*/
|
||||||
|
public class PacketPlayOutEntityHeadRotationWrapper {
|
||||||
|
|
||||||
|
public PacketPlayOutEntityHeadRotation create(Location location, int entityId) {
|
||||||
|
PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotation();
|
||||||
|
|
||||||
|
Reflection.getField(packetPlayOutEntityHeadRotation.getClass(), "a", int.class).
|
||||||
|
set(packetPlayOutEntityHeadRotation, entityId);
|
||||||
|
Reflection.getField(packetPlayOutEntityHeadRotation.getClass(), "b", byte.class)
|
||||||
|
.set(packetPlayOutEntityHeadRotation, (byte) ((int) location.getYaw() * 256.0F / 360.0F));
|
||||||
|
|
||||||
|
return packetPlayOutEntityHeadRotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Jitse Boonstra
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.jitse.npclib.nms.v1_7_R4.packets;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import net.minecraft.server.v1_7_R4.DataWatcher;
|
||||||
|
import net.minecraft.server.v1_7_R4.PacketPlayOutNamedEntitySpawn;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jitse Boonstra
|
||||||
|
*/
|
||||||
|
public class PacketPlayOutNamedEntitySpawnWrapper {
|
||||||
|
|
||||||
|
public PacketPlayOutNamedEntitySpawn create(UUID uuid, Location location, int entityId) {
|
||||||
|
PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawn();
|
||||||
|
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "a", int.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, entityId);
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "b", UUID.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, uuid);
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "c", int.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, (int) Math.floor(location.getX() * 32.0D));
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "d", int.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, (int) Math.floor(location.getY() * 32.0D));
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "e", int.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, (int) Math.floor(location.getZ() * 32.0D));
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "f", byte.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, (byte) ((int) (location.getYaw() * 256.0F / 360.0F)));
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "g", byte.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, (byte) ((int) (location.getPitch() * 256.0F / 360.0F)));
|
||||||
|
|
||||||
|
DataWatcher dataWatcher = new DataWatcher(null);
|
||||||
|
dataWatcher.a(10, (byte) 127);
|
||||||
|
|
||||||
|
Reflection.getField(packetPlayOutNamedEntitySpawn.getClass(), "i", DataWatcher.class)
|
||||||
|
.set(packetPlayOutNamedEntitySpawn, dataWatcher);
|
||||||
|
|
||||||
|
return packetPlayOutNamedEntitySpawn;
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Jitse Boonstra
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.jitse.npclib.nms.v1_7_R4.packets;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import net.minecraft.server.v1_7_R4.PacketPlayOutPlayerInfo;
|
||||||
|
import net.minecraft.util.com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jitse Boonstra
|
||||||
|
*/
|
||||||
|
public class PacketPlayOutPlayerInfoWrapper {
|
||||||
|
|
||||||
|
public PacketPlayOutPlayerInfo create(int action, GameProfile gameProfile, String name) {
|
||||||
|
PacketPlayOutPlayerInfo packetPlayOutPlayerInfo = new PacketPlayOutPlayerInfo();
|
||||||
|
|
||||||
|
// Action values:
|
||||||
|
// 0 = Add player
|
||||||
|
// 1 = Update gamemode
|
||||||
|
// 2 = Update latency
|
||||||
|
// 3 = Update display name
|
||||||
|
// 4 = Remove player
|
||||||
|
Reflection.getField(packetPlayOutPlayerInfo.getClass(), "action", int.class)
|
||||||
|
.set(packetPlayOutPlayerInfo, action);
|
||||||
|
Reflection.getField(packetPlayOutPlayerInfo.getClass(), "player", GameProfile.class)
|
||||||
|
.set(packetPlayOutPlayerInfo, gameProfile);
|
||||||
|
Reflection.getField(packetPlayOutPlayerInfo.getClass(), "username", String.class)
|
||||||
|
.set(packetPlayOutPlayerInfo, name);
|
||||||
|
Reflection.getField(packetPlayOutPlayerInfo.getClass(), "ping", int.class)
|
||||||
|
.set(packetPlayOutPlayerInfo, 0);
|
||||||
|
Reflection.getField(packetPlayOutPlayerInfo.getClass(), "gamemode", int.class)
|
||||||
|
.set(packetPlayOutPlayerInfo, 1);
|
||||||
|
|
||||||
|
return packetPlayOutPlayerInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Jitse Boonstra
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.jitse.npclib.nms.v1_7_R4.packets;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import net.minecraft.server.v1_7_R4.PacketPlayOutScoreboardTeam;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jitse Boonstra
|
||||||
|
*/
|
||||||
|
public class PacketPlayOutScoreboardTeamWrapper {
|
||||||
|
|
||||||
|
public PacketPlayOutScoreboardTeam createRegisterTeam(String name) {
|
||||||
|
PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = new PacketPlayOutScoreboardTeam();
|
||||||
|
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "h", int.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, 0);
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "b", String.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, name);
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "a", String.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, name);
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "e", String.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, "never");
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "i", int.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, 1);
|
||||||
|
// Could not get this working in the PacketPlayOutPlayerInfoWrapper class.
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "c", String.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, ChatColor.BLUE + "[NPC] ");
|
||||||
|
Reflection.FieldAccessor<Collection> collectionFieldAccessor = Reflection.getField(
|
||||||
|
packetPlayOutScoreboardTeam.getClass(), "g", Collection.class);
|
||||||
|
Collection collection = collectionFieldAccessor.get(packetPlayOutScoreboardTeam);
|
||||||
|
collection.add(name);
|
||||||
|
collectionFieldAccessor.set(packetPlayOutScoreboardTeam, collection);
|
||||||
|
|
||||||
|
return packetPlayOutScoreboardTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketPlayOutScoreboardTeam createUnregisterTeam(String name) {
|
||||||
|
PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeam = new PacketPlayOutScoreboardTeam();
|
||||||
|
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "h", int.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, 1);
|
||||||
|
Reflection.getField(packetPlayOutScoreboardTeam.getClass(), "a", String.class)
|
||||||
|
.set(packetPlayOutScoreboardTeam, name);
|
||||||
|
|
||||||
|
return packetPlayOutScoreboardTeam;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user