144 lines
5.8 KiB
Java
144 lines
5.8 KiB
Java
/*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.gmail.filoghost.holographicdisplays.nms.v1_8_R3;
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.util.Map;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
|
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
|
|
import com.gmail.filoghost.holographicdisplays.api.line.ItemLine;
|
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.ItemPickupManager;
|
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
|
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSArmorStand;
|
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSEntityBase;
|
|
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSItem;
|
|
import com.gmail.filoghost.holographicdisplays.util.ConsoleLogger;
|
|
import com.gmail.filoghost.holographicdisplays.util.Validator;
|
|
import com.gmail.filoghost.holographicdisplays.util.reflection.ReflectField;
|
|
|
|
import net.minecraft.server.v1_8_R3.Entity;
|
|
import net.minecraft.server.v1_8_R3.EntityTypes;
|
|
import net.minecraft.server.v1_8_R3.MathHelper;
|
|
import net.minecraft.server.v1_8_R3.World;
|
|
import net.minecraft.server.v1_8_R3.WorldServer;
|
|
|
|
public class NmsManagerImpl implements NMSManager {
|
|
|
|
private static final ReflectField<Map<Class<?>, String>> ENTITY_NAMES_BY_CLASS_FIELD = new ReflectField<Map<Class<?>, String>>(EntityTypes.class, "d");
|
|
private static final ReflectField<Map<Class<?>, Integer>> ENTITY_IDS_BY_CLASS_FIELD = new ReflectField<Map<Class<?>, Integer>>(EntityTypes.class, "f");
|
|
|
|
private Method validateEntityMethod;
|
|
|
|
@Override
|
|
public void setup() throws Exception {
|
|
registerCustomEntity(EntityNMSArmorStand.class, "ArmorStand", 30);
|
|
registerCustomEntity(EntityNMSItem.class, "Item", 1);
|
|
registerCustomEntity(EntityNMSSlime.class, "Slime", 55);
|
|
|
|
validateEntityMethod = World.class.getDeclaredMethod("a", Entity.class);
|
|
validateEntityMethod.setAccessible(true);
|
|
}
|
|
|
|
public void registerCustomEntity(Class<?> entityClass, String name, int id) throws Exception {
|
|
ENTITY_NAMES_BY_CLASS_FIELD.getStatic().put(entityClass, name);
|
|
ENTITY_IDS_BY_CLASS_FIELD.getStatic().put(entityClass, Integer.valueOf(id));
|
|
}
|
|
|
|
@Override
|
|
public NMSItem spawnNMSItem(org.bukkit.World bukkitWorld, double x, double y, double z, ItemLine parentPiece, ItemStack stack, ItemPickupManager itemPickupManager) {
|
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
|
EntityNMSItem customItem = new EntityNMSItem(nmsWorld, parentPiece, itemPickupManager);
|
|
customItem.setLocationNMS(x, y, z);
|
|
customItem.setItemStackNMS(stack);
|
|
if (!addEntityToWorld(nmsWorld, customItem)) {
|
|
ConsoleLogger.handleSpawnFail(parentPiece);
|
|
}
|
|
return customItem;
|
|
}
|
|
|
|
@Override
|
|
public EntityNMSSlime spawnNMSSlime(org.bukkit.World bukkitWorld, double x, double y, double z, HologramLine parentPiece) {
|
|
WorldServer nmsWorld = ((CraftWorld) bukkitWorld).getHandle();
|
|
EntityNMSSlime touchSlime = new EntityNMSSlime(nmsWorld, parentPiece);
|
|
touchSlime.setLocationNMS(x, y, z);
|
|
if (!addEntityToWorld(nmsWorld, touchSlime)) {
|
|
ConsoleLogger.handleSpawnFail(parentPiece);
|
|
}
|
|
return touchSlime;
|
|
}
|
|
|
|
@Override
|
|
public NMSArmorStand spawnNMSArmorStand(org.bukkit.World world, double x, double y, double z, HologramLine parentPiece) {
|
|
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
|
EntityNMSArmorStand invisibleArmorStand = new EntityNMSArmorStand(nmsWorld, parentPiece);
|
|
invisibleArmorStand.setLocationNMS(x, y, z);
|
|
if (!addEntityToWorld(nmsWorld, invisibleArmorStand)) {
|
|
ConsoleLogger.handleSpawnFail(parentPiece);
|
|
}
|
|
return invisibleArmorStand;
|
|
}
|
|
|
|
private boolean addEntityToWorld(WorldServer nmsWorld, Entity nmsEntity) {
|
|
Validator.isTrue(Bukkit.isPrimaryThread(), "Async entity add");
|
|
|
|
if (validateEntityMethod == null) {
|
|
return nmsWorld.addEntity(nmsEntity, SpawnReason.CUSTOM);
|
|
}
|
|
|
|
final int chunkX = MathHelper.floor(nmsEntity.locX / 16.0);
|
|
final int chunkZ = MathHelper.floor(nmsEntity.locZ / 16.0);
|
|
|
|
if (!nmsWorld.chunkProviderServer.isChunkLoaded(chunkX, chunkZ)) {
|
|
// This should never happen
|
|
nmsEntity.dead = true;
|
|
return false;
|
|
}
|
|
|
|
nmsWorld.getChunkAt(chunkX, chunkZ).a(nmsEntity);
|
|
nmsWorld.entityList.add(nmsEntity);
|
|
|
|
try {
|
|
validateEntityMethod.invoke(nmsWorld, nmsEntity);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
|
return ((CraftEntity) bukkitEntity).getHandle() instanceof NMSEntityBase;
|
|
}
|
|
|
|
@Override
|
|
public NMSEntityBase getNMSEntityBase(org.bukkit.entity.Entity bukkitEntity) {
|
|
|
|
Entity nmsEntity = ((CraftEntity) bukkitEntity).getHandle();
|
|
if (nmsEntity instanceof NMSEntityBase) {
|
|
return ((NMSEntityBase) nmsEntity);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
}
|