Spawner check use mixin
This commit is contained in:
@@ -136,6 +136,6 @@ public class ParallelRegistry {
|
|||||||
STAGE_BLOCK_BASE.shutdown(); // This must after STAGE_BLOCK terminated
|
STAGE_BLOCK_BASE.shutdown(); // This must after STAGE_BLOCK terminated
|
||||||
STAGE_BLOCK_BASE.awaitTermination(TERMINATION_IN_SEC, TimeUnit.SECONDS);
|
STAGE_BLOCK_BASE.awaitTermination(TERMINATION_IN_SEC, TimeUnit.SECONDS);
|
||||||
|
|
||||||
STAGE_STANDALONE.awaitTermination(TERMINATION_IN_SEC, TimeUnit.SECONDS); // Behind the shutdown of BLOCK_BASE should be faster
|
STAGE_STANDALONE.awaitTermination(TERMINATION_IN_SEC, TimeUnit.SECONDS); // Behind the shutdown of BLOCK_BASE should faster
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package io.akarin.server.mixin.core;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.lib.Opcodes;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import io.akarin.server.core.AkarinGlobalConfig;
|
||||||
|
import net.minecraft.server.Block;
|
||||||
|
import net.minecraft.server.Blocks;
|
||||||
|
import net.minecraft.server.ItemMonsterEgg;
|
||||||
|
|
||||||
|
@Mixin(value = ItemMonsterEgg.class, remap = false)
|
||||||
|
public class MonsterEggGuardian {
|
||||||
|
|
||||||
|
@Redirect(method = "a", at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
target = "net/minecraft/server/Blocks.MOB_SPAWNER:Lnet/minecraft/server/Block;",
|
||||||
|
opcode = Opcodes.GETSTATIC
|
||||||
|
))
|
||||||
|
private boolean configurable(Block target) {
|
||||||
|
return target == Blocks.MOB_SPAWNER && AkarinGlobalConfig.allowSpawnerModify;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
package io.akarin.server.mixin.core;
|
package io.akarin.server.mixin.core;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import net.minecraft.server.BlockPosition;
|
||||||
import net.minecraft.server.World;
|
import net.minecraft.server.World;
|
||||||
import net.minecraft.server.WorldGenBigTree;
|
import net.minecraft.server.WorldGenBigTree;
|
||||||
|
|
||||||
@@ -16,8 +19,8 @@ import net.minecraft.server.WorldGenBigTree;
|
|||||||
public class WeakBigTree {
|
public class WeakBigTree {
|
||||||
@Shadow private World l;
|
@Shadow private World l;
|
||||||
|
|
||||||
@Inject(method = "generate(Lnet/minecraft/server/World;Ljava/util/Random;Lnet/minecraft/server/BlockPosition;)Z", at = @At("RETURN"))
|
@Inject(method = "generate", at = @At("RETURN"))
|
||||||
private void clearWorldRef(CallbackInfo info) {
|
private void clearWorldRef(World world, Random random, BlockPosition pos, CallbackInfoReturnable<?> info) {
|
||||||
l = null; // Akarin - remove references to world objects to avoid memory leaks
|
l = null; // Akarin - remove references to world objects to avoid memory leaks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,256 +0,0 @@
|
|||||||
package net.minecraft.server;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import io.akarin.server.core.AkarinGlobalConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>Akarin Changes Note</b><br>
|
|
||||||
* <br>
|
|
||||||
* 1) Add configuration check<br>
|
|
||||||
* @author cakoyo
|
|
||||||
*/
|
|
||||||
public class ItemMonsterEgg extends Item {
|
|
||||||
|
|
||||||
public ItemMonsterEgg() {
|
|
||||||
this.b(CreativeModeTab.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String b(ItemStack itemstack) {
|
|
||||||
String s = ("" + LocaleI18n.get(this.getName() + ".name")).trim();
|
|
||||||
String s1 = EntityTypes.a(h(itemstack));
|
|
||||||
|
|
||||||
if (s1 != null) {
|
|
||||||
s = s + " " + LocaleI18n.get("entity." + s1 + ".name");
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnumInteractionResult a(EntityHuman entityhuman, World world, BlockPosition blockposition, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) {
|
|
||||||
ItemStack itemstack = entityhuman.b(enumhand);
|
|
||||||
|
|
||||||
if (world.isClientSide) {
|
|
||||||
return EnumInteractionResult.SUCCESS;
|
|
||||||
} else if (!entityhuman.a(blockposition.shift(enumdirection), enumdirection, itemstack)) {
|
|
||||||
return EnumInteractionResult.FAIL;
|
|
||||||
} else {
|
|
||||||
IBlockData iblockdata = world.getType(blockposition);
|
|
||||||
Block block = iblockdata.getBlock();
|
|
||||||
|
|
||||||
if (block == Blocks.MOB_SPAWNER && AkarinGlobalConfig.allowSpawnerModify) { // Akarin
|
|
||||||
TileEntity tileentity = world.getTileEntity(blockposition);
|
|
||||||
|
|
||||||
if (tileentity instanceof TileEntityMobSpawner) {
|
|
||||||
MobSpawnerAbstract mobspawnerabstract = ((TileEntityMobSpawner) tileentity).getSpawner();
|
|
||||||
|
|
||||||
mobspawnerabstract.setMobName(h(itemstack));
|
|
||||||
tileentity.update();
|
|
||||||
world.notify(blockposition, iblockdata, iblockdata, 3);
|
|
||||||
if (!entityhuman.abilities.canInstantlyBuild) {
|
|
||||||
itemstack.subtract(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EnumInteractionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockPosition blockposition1 = blockposition.shift(enumdirection);
|
|
||||||
double d0 = this.a(world, blockposition1);
|
|
||||||
Entity entity = a(world, h(itemstack), blockposition1.getX() + 0.5D, blockposition1.getY() + d0, blockposition1.getZ() + 0.5D);
|
|
||||||
|
|
||||||
if (entity != null) {
|
|
||||||
if (entity instanceof EntityLiving && itemstack.hasName()) {
|
|
||||||
entity.setCustomName(itemstack.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
a(world, entityhuman, itemstack, entity);
|
|
||||||
if (!entityhuman.abilities.canInstantlyBuild) {
|
|
||||||
itemstack.subtract(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return EnumInteractionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double a(World world, BlockPosition blockposition) {
|
|
||||||
AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockposition)).b(0.0D, -1.0D, 0.0D);
|
|
||||||
List list = world.getCubes((Entity) null, axisalignedbb);
|
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
return 0.0D;
|
|
||||||
} else {
|
|
||||||
double d0 = axisalignedbb.b;
|
|
||||||
|
|
||||||
AxisAlignedBB axisalignedbb1;
|
|
||||||
|
|
||||||
for (Iterator iterator = list.iterator(); iterator.hasNext(); d0 = Math.max(axisalignedbb1.e, d0)) {
|
|
||||||
axisalignedbb1 = (AxisAlignedBB) iterator.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return d0 - blockposition.getY();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void a(World world, @Nullable EntityHuman entityhuman, ItemStack itemstack, @Nullable Entity entity) {
|
|
||||||
MinecraftServer minecraftserver = world.getMinecraftServer();
|
|
||||||
|
|
||||||
if (minecraftserver != null && entity != null) {
|
|
||||||
NBTTagCompound nbttagcompound = itemstack.getTag();
|
|
||||||
|
|
||||||
if (nbttagcompound != null && nbttagcompound.hasKeyOfType("EntityTag", 10)) {
|
|
||||||
if (!world.isClientSide && entity.bC() && (entityhuman == null || !minecraftserver.getPlayerList().isOp(entityhuman.getProfile()))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NBTTagCompound nbttagcompound1 = entity.save(new NBTTagCompound());
|
|
||||||
UUID uuid = entity.getUniqueID();
|
|
||||||
|
|
||||||
// Paper start - Filter out position and motion information
|
|
||||||
final NBTTagCompound entityTag = nbttagcompound.getCompound("EntityTag");
|
|
||||||
if (world.paperConfig.filterNBTFromSpawnEgg) {
|
|
||||||
entityTag.remove("Pos");
|
|
||||||
entityTag.remove("Motion");
|
|
||||||
}
|
|
||||||
nbttagcompound1.a(entityTag);
|
|
||||||
// Paper end
|
|
||||||
entity.a(uuid);
|
|
||||||
entity.f(nbttagcompound1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
|
|
||||||
ItemStack itemstack = entityhuman.b(enumhand);
|
|
||||||
|
|
||||||
if (world.isClientSide) {
|
|
||||||
return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack);
|
|
||||||
} else {
|
|
||||||
MovingObjectPosition movingobjectposition = this.a(world, entityhuman, true);
|
|
||||||
|
|
||||||
if (movingobjectposition != null && movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) {
|
|
||||||
BlockPosition blockposition = movingobjectposition.a();
|
|
||||||
|
|
||||||
if (!(world.getType(blockposition).getBlock() instanceof BlockFluids)) {
|
|
||||||
return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack);
|
|
||||||
} else if (world.a(entityhuman, blockposition) && entityhuman.a(blockposition, movingobjectposition.direction, itemstack)) {
|
|
||||||
Entity entity = a(world, h(itemstack), blockposition.getX() + 0.5D, blockposition.getY() + 0.5D, blockposition.getZ() + 0.5D);
|
|
||||||
|
|
||||||
if (entity == null) {
|
|
||||||
return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack);
|
|
||||||
} else {
|
|
||||||
if (entity instanceof EntityLiving && itemstack.hasName()) {
|
|
||||||
entity.setCustomName(itemstack.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
a(world, entityhuman, itemstack, entity);
|
|
||||||
if (!entityhuman.abilities.canInstantlyBuild) {
|
|
||||||
itemstack.subtract(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
entityhuman.b(StatisticList.b(this));
|
|
||||||
return new InteractionResultWrapper(EnumInteractionResult.SUCCESS, itemstack);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new InteractionResultWrapper(EnumInteractionResult.FAIL, itemstack);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static Entity a(World world, @Nullable MinecraftKey minecraftkey, double d0, double d1, double d2) {
|
|
||||||
return spawnCreature(world, minecraftkey, d0, d1, d2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static Entity spawnCreature(World world, @Nullable MinecraftKey minecraftkey, double d0, double d1, double d2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
|
||||||
if (minecraftkey != null && EntityTypes.eggInfo.containsKey(minecraftkey)) {
|
|
||||||
Entity entity = null;
|
|
||||||
|
|
||||||
for (int i = 0; i < 1; ++i) {
|
|
||||||
entity = EntityTypes.a(minecraftkey, world);
|
|
||||||
if (entity instanceof EntityInsentient) {
|
|
||||||
EntityInsentient entityinsentient = (EntityInsentient) entity;
|
|
||||||
|
|
||||||
entity.setPositionRotation(d0, d1, d2, MathHelper.g(world.random.nextFloat() * 360.0F), 0.0F);
|
|
||||||
entityinsentient.aP = entityinsentient.yaw;
|
|
||||||
entityinsentient.aN = entityinsentient.yaw;
|
|
||||||
entityinsentient.prepare(world.D(new BlockPosition(entityinsentient)), (GroupDataEntity) null);
|
|
||||||
// CraftBukkit start - don't return an entity when CreatureSpawnEvent is canceled
|
|
||||||
if (!world.addEntity(entity, spawnReason)) {
|
|
||||||
entity = null;
|
|
||||||
} else {
|
|
||||||
entityinsentient.D();
|
|
||||||
}
|
|
||||||
// CraftBukkit end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void a(CreativeModeTab creativemodetab, NonNullList<ItemStack> nonnulllist) {
|
|
||||||
if (this.a(creativemodetab)) {
|
|
||||||
Iterator iterator = EntityTypes.eggInfo.values().iterator();
|
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
EntityTypes.MonsterEggInfo entitytypes_monsteregginfo = (EntityTypes.MonsterEggInfo) iterator.next();
|
|
||||||
ItemStack itemstack = new ItemStack(this, 1);
|
|
||||||
|
|
||||||
a(itemstack, entitytypes_monsteregginfo.a);
|
|
||||||
nonnulllist.add(itemstack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void a(ItemStack itemstack, MinecraftKey minecraftkey) {
|
|
||||||
NBTTagCompound nbttagcompound = itemstack.hasTag() ? itemstack.getTag() : new NBTTagCompound();
|
|
||||||
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
|
||||||
|
|
||||||
nbttagcompound1.setString("id", minecraftkey.toString());
|
|
||||||
nbttagcompound.set("EntityTag", nbttagcompound1);
|
|
||||||
itemstack.setTag(nbttagcompound);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static MinecraftKey h(ItemStack itemstack) {
|
|
||||||
NBTTagCompound nbttagcompound = itemstack.getTag();
|
|
||||||
|
|
||||||
if (nbttagcompound == null) {
|
|
||||||
return null;
|
|
||||||
} else if (!nbttagcompound.hasKeyOfType("EntityTag", 10)) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("EntityTag");
|
|
||||||
|
|
||||||
if (!nbttagcompound1.hasKeyOfType("id", 8)) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
String s = nbttagcompound1.getString("id");
|
|
||||||
MinecraftKey minecraftkey = new MinecraftKey(s);
|
|
||||||
|
|
||||||
if (!s.contains(":")) {
|
|
||||||
nbttagcompound1.setString("id", minecraftkey.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return minecraftkey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"core.WeakBigTree",
|
"core.WeakBigTree",
|
||||||
"core.DesyncCatcher",
|
"core.DesyncCatcher",
|
||||||
"core.MixinCraftServer",
|
"core.MixinCraftServer",
|
||||||
|
"core.MonsterEggGuardian",
|
||||||
"core.MixinVersionCommand",
|
"core.MixinVersionCommand",
|
||||||
"core.MixinMinecraftServer",
|
"core.MixinMinecraftServer",
|
||||||
"core.MixinChunkIOExecutor",
|
"core.MixinChunkIOExecutor",
|
||||||
|
|||||||
Reference in New Issue
Block a user