Compare commits
2
Commits
b51852c15b
...
4399ce1523
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4399ce1523 | ||
|
|
770cdec7f9 |
No files matched your search
@@ -1,11 +1,13 @@
|
|||||||
package com.pengu.thaumcraft.additions.entity;
|
package com.pengu.thaumcraft.additions.entity;
|
||||||
|
|
||||||
import com.pengu.thaumcraft.additions.api.integration.ThaumicAdditionsDamage;
|
import com.pengu.thaumcraft.additions.api.integration.ThaumicAdditionsDamage;
|
||||||
|
import com.pengu.thaumcraft.additions.misc.TerritoryGuard;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.boss.EntityDragon;
|
import net.minecraft.entity.boss.EntityDragon;
|
||||||
import net.minecraft.entity.boss.EntityWither;
|
import net.minecraft.entity.boss.EntityWither;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.item.EntityItem;
|
import net.minecraft.entity.item.EntityItem;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -58,7 +60,7 @@ public class EntitySingularity extends EntityAlumentum {
|
|||||||
++this.ticksExisted;
|
++this.ticksExisted;
|
||||||
if(this.ticksExisted >= 2000 || this.suckedItems >= 2000.0F) {
|
if(this.ticksExisted >= 2000 || this.suckedItems >= 2000.0F) {
|
||||||
for(p = 0; p < 5; ++p) {
|
for(p = 0; p < 5; ++p) {
|
||||||
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, this.suckedItems / 200.0F, true);
|
this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, this.suckedItems / 200.0F, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing"));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
this.setDead();
|
||||||
@@ -137,7 +139,7 @@ public class EntitySingularity extends EntityAlumentum {
|
|||||||
i = (int)this.posX + this.worldObj.rand.nextInt(this.radius) - this.worldObj.rand.nextInt(this.radius);
|
i = (int)this.posX + this.worldObj.rand.nextInt(this.radius) - this.worldObj.rand.nextInt(this.radius);
|
||||||
var22 = (int)this.posY + this.worldObj.rand.nextInt(this.radius) - this.worldObj.rand.nextInt(this.radius);
|
var22 = (int)this.posY + this.worldObj.rand.nextInt(this.radius) - this.worldObj.rand.nextInt(this.radius);
|
||||||
var23 = (int)this.posZ + this.worldObj.rand.nextInt(this.radius) - this.worldObj.rand.nextInt(this.radius);
|
var23 = (int)this.posZ + this.worldObj.rand.nextInt(this.radius) - this.worldObj.rand.nextInt(this.radius);
|
||||||
if(this.worldObj.getBlock(i, var22, var23) != Blocks.air && this.worldObj.getBlock(i, var22, var23).getBlockHardness(this.worldObj, i, var22, var23) > -1.0F && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) {
|
if(this.worldObj.getBlock(i, var22, var23) != Blocks.air && this.worldObj.getBlock(i, var22, var23).getBlockHardness(this.worldObj, i, var22, var23) > -1.0F && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing") && this.canDestroy(i, var22, var23)) {
|
||||||
this.worldObj.getBlock(i, var22, var23).breakBlock(this.worldObj, i, var22, var23, this.worldObj.getBlock(i, var22, var23), 1);
|
this.worldObj.getBlock(i, var22, var23).breakBlock(this.worldObj, i, var22, var23, this.worldObj.getBlock(i, var22, var23), 1);
|
||||||
this.worldObj.playSoundEffect((double)i, (double)var22, (double)var23, this.worldObj.getBlock(i, var22, var23).stepSound.getBreakSound(), this.worldObj.getBlock(i, var22, var23).stepSound.getVolume(), this.worldObj.getBlock(i, var22, var23).stepSound.getPitch());
|
this.worldObj.playSoundEffect((double)i, (double)var22, (double)var23, this.worldObj.getBlock(i, var22, var23).stepSound.getBreakSound(), this.worldObj.getBlock(i, var22, var23).stepSound.getVolume(), this.worldObj.getBlock(i, var22, var23).stepSound.getPitch());
|
||||||
if(!this.worldObj.isRemote) {
|
if(!this.worldObj.isRemote) {
|
||||||
@@ -188,6 +190,17 @@ public class EntitySingularity extends EntityAlumentum {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The player who threw it, or null (dispenser, merged singularity). Protection plugins read this by name. */
|
||||||
|
public EntityPlayer getOwnerEntity() {
|
||||||
|
EntityLivingBase t = this.getThrower();
|
||||||
|
return t instanceof EntityPlayer ? (EntityPlayer)t : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Island/territory check: a BreakEvent as the thrower, or as a fake player when nobody threw it. */
|
||||||
|
private boolean canDestroy(int x, int y, int z) {
|
||||||
|
return TerritoryGuard.canRemoveBlock(this.worldObj, x, y, z, this.getOwnerEntity());
|
||||||
|
}
|
||||||
|
|
||||||
protected void onImpact(MovingObjectPosition m) {
|
protected void onImpact(MovingObjectPosition m) {
|
||||||
this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "thaumicadditions:singularity", 16.0F, 1.0F);
|
this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "thaumicadditions:singularity", 16.0F, 1.0F);
|
||||||
this.inGround = true;
|
this.inGround = true;
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.pengu.thaumcraft.additions.misc;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldServer;
|
||||||
|
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
|
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard cancellable BlockEvent.BreakEvent gate for block removal that no player performs directly
|
||||||
|
* (void entity, hungry blocks, ...). Island and territory plugins receive the contract they already handle for player
|
||||||
|
* mining; the actor is the responsible player when there is one, otherwise a per-world fake player (which the
|
||||||
|
* protection layer judges as an unattributed machine). With no receiver nothing changes.
|
||||||
|
*/
|
||||||
|
public final class TerritoryGuard {
|
||||||
|
|
||||||
|
private static WeakReference<EntityPlayer> fallback = new WeakReference<>(null);
|
||||||
|
|
||||||
|
/** @param actor the player responsible for the removal, or null when there is none */
|
||||||
|
public static boolean canRemoveBlock(World world, int x, int y, int z, EntityPlayer actor) {
|
||||||
|
EntityPlayer who = resolveActor(world, actor);
|
||||||
|
if (who == null) {
|
||||||
|
// no world to attribute the event to (client world): nothing to protect
|
||||||
|
return !(world instanceof WorldServer);
|
||||||
|
}
|
||||||
|
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
z,
|
||||||
|
world,
|
||||||
|
world.getBlock(x, y, z),
|
||||||
|
world.getBlockMetadata(x, y, z),
|
||||||
|
who);
|
||||||
|
return !MinecraftForge.EVENT_BUS.post(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EntityPlayer resolveActor(World world, EntityPlayer actor) {
|
||||||
|
if (actor != null) return actor;
|
||||||
|
if (world instanceof WorldServer) {
|
||||||
|
EntityPlayer player = fallback.get();
|
||||||
|
if (player == null || player.worldObj != world) {
|
||||||
|
FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer) world);
|
||||||
|
player = fake;
|
||||||
|
fallback = new WeakReference<>(player);
|
||||||
|
}
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TerritoryGuard() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""The singularity must ask the protection layer before removing a block and respect mobGriefing for its blast."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[2]
|
||||||
|
SRC = (ROOT / "src/main/java/com/pengu/thaumcraft/additions/entity/EntitySingularity.java").read_text(encoding="utf-8")
|
||||||
|
GUARD = (ROOT / "src/main/java/com/pengu/thaumcraft/additions/misc/TerritoryGuard.java").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
assert "new BlockEvent.BreakEvent(" in GUARD and "EVENT_BUS.post(event)" in GUARD
|
||||||
|
assert "FakePlayerFactory.getMinecraft" in GUARD
|
||||||
|
|
||||||
|
# the block-eating branch is gated by the guard before any breakBlock / setBlockToAir
|
||||||
|
gate = SRC.index("this.canDestroy(i, var22, var23)")
|
||||||
|
assert gate < SRC.index(".breakBlock(this.worldObj, i, var22, var23"), "guard must precede breakBlock"
|
||||||
|
assert gate < SRC.index("this.worldObj.setBlockToAir(i, var22, var23)")
|
||||||
|
assert "TerritoryGuard.canRemoveBlock(this.worldObj, x, y, z, this.getOwnerEntity())" in SRC
|
||||||
|
|
||||||
|
# explosion attribution accessor, plus the end-of-life blast no longer ignores mobGriefing
|
||||||
|
assert "public EntityPlayer getOwnerEntity()" in SRC
|
||||||
|
assert 'this.suckedItems / 200.0F, true)' not in SRC
|
||||||
|
print("ok")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in new issue
Block a user