Second Identity

- Deployers no longer fail to activate in chunks claimed or protected by the player that placed them
This commit is contained in:
simibubi 2023-03-30 15:04:05 +02:00
parent f45e22496e
commit 32f68d25c3
5 changed files with 88 additions and 9 deletions

View file

@ -12,8 +12,10 @@ import com.simibubi.create.foundation.block.IBE;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
@ -57,6 +59,13 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements IBE<De
return super.onWrenched(state, context);
}
@Override
public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
super.setPlacedBy(worldIn, pos, state, placer, stack);
if (placer instanceof ServerPlayer)
withBlockEntityDo(worldIn, pos, dbe -> dbe.owner = placer.getUUID());
}
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (!isMoving && !state.is(newState.getBlock()))

View file

@ -5,6 +5,7 @@ import static com.simibubi.create.content.contraptions.base.DirectionalKineticBl
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
@ -75,6 +76,7 @@ public class DeployerBlockEntity extends KineticBlockEntity {
protected List<ItemStack> overflowItems = new ArrayList<>();
protected FilteringBehaviour filtering;
protected boolean redstoneLocked;
protected UUID owner;
private LazyOptional<IItemHandlerModifiable> invHandler;
private ListTag deferredInventoryList;
@ -125,7 +127,7 @@ public class DeployerBlockEntity extends KineticBlockEntity {
if (invHandler != null)
return;
if (level instanceof ServerLevel sLevel) {
player = new DeployerFakePlayer(sLevel);
player = new DeployerFakePlayer(sLevel, owner);
if (deferredInventoryList != null) {
player.getInventory()
.load(deferredInventoryList);
@ -350,6 +352,8 @@ public class DeployerBlockEntity extends KineticBlockEntity {
mode = NBTHelper.readEnum(compound, "Mode", Mode.class);
timer = compound.getInt("Timer");
redstoneLocked = compound.getBoolean("Powered");
if (compound.contains("Owner"))
owner = compound.getUUID("Owner");
deferredInventoryList = compound.getList("Inventory", Tag.TAG_COMPOUND);
overflowItems = NBTHelper.readItemList(compound.getList("Overflow", Tag.TAG_COMPOUND));
@ -374,6 +378,8 @@ public class DeployerBlockEntity extends KineticBlockEntity {
NBTHelper.writeEnum(compound, "State", state);
compound.putInt("Timer", timer);
compound.putBoolean("Powered", redstoneLocked);
if (owner != null)
compound.putUUID("Owner", owner);
if (player != null) {
ListTag invNBT = new ListTag();
@ -489,8 +495,8 @@ public class DeployerBlockEntity extends KineticBlockEntity {
.forGoggles(tooltip);
if (!heldItem.isEmpty())
Lang.translate("tooltip.deployer.contains",
Components.translatable(heldItem.getDescriptionId()).getString(), heldItem.getCount())
Lang.translate("tooltip.deployer.contains", Components.translatable(heldItem.getDescriptionId())
.getString(), heldItem.getCount())
.style(ChatFormatting.GREEN)
.forGoggles(tooltip);

View file

@ -1,8 +1,11 @@
package com.simibubi.create.content.contraptions.components.deployer;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.UUID;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import com.mojang.authlib.GameProfile;
@ -23,6 +26,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
@ -33,6 +37,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.UsernameCache;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.entity.EntityEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
@ -46,16 +51,17 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
public class DeployerFakePlayer extends FakePlayer {
private static final Connection NETWORK_MANAGER = new Connection(PacketFlow.CLIENTBOUND);
public static final GameProfile DEPLOYER_PROFILE =
new GameProfile(UUID.fromString("9e2faded-cafe-4ec2-c314-dad129ae971d"), "Deployer");
public static final UUID fallbackID = UUID.fromString("9e2faded-cafe-4ec2-c314-dad129ae971d");
Pair<BlockPos, Float> blockBreakingProgress;
ItemStack spawnedItemEffects;
public boolean placedTracks;
public boolean onMinecartContraption;
private UUID owner;
public DeployerFakePlayer(ServerLevel world) {
super(world, DEPLOYER_PROFILE);
public DeployerFakePlayer(ServerLevel world, @Nullable UUID owner) {
super(world, new DeployerGameProfile(fallbackID, "Deployer", owner));
connection = new FakePlayNetHandler(world.getServer(), this);
this.owner = owner;
}
@Override
@ -95,6 +101,16 @@ public class DeployerFakePlayer extends FakePlayer {
return stack;
}
@Override
public boolean canBeAffected(MobEffectInstance pEffectInstance) {
return false;
}
@Override
public UUID getUUID() {
return owner == null ? super.getUUID() : owner;
}
@SubscribeEvent
public static void deployerHasEyesOnHisFeet(EntityEvent.Size event) {
if (event.getEntity() instanceof DeployerFakePlayer)
@ -156,6 +172,49 @@ public class DeployerFakePlayer extends FakePlayer {
}
}
// Credit to Mekanism for this approach. Helps fake players get past claims and
// protection by other mods
private static class DeployerGameProfile extends GameProfile {
private UUID owner;
public DeployerGameProfile(UUID id, String name, UUID owner) {
super(id, name);
this.owner = owner;
}
@Override
public UUID getId() {
return owner == null ? super.getId() : owner;
}
@Override
public String getName() {
if (owner == null)
return super.getName();
String lastKnownUsername = UsernameCache.getLastKnownUsername(owner);
return lastKnownUsername == null ? super.getName() : lastKnownUsername;
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (!(o instanceof GameProfile otherProfile))
return false;
return Objects.equals(getId(), otherProfile.getId()) && Objects.equals(getName(), otherProfile.getName());
}
@Override
public int hashCode() {
UUID id = getId();
String name = getName();
int result = id == null ? 0 : id.hashCode();
result = 31 * result + (name == null ? 0 : name.hashCode());
return result;
}
}
private static class FakePlayNetHandler extends ServerGamePacketListenerImpl {
public FakePlayNetHandler(MinecraftServer server, ServerPlayer playerIn) {
super(server, NETWORK_MANAGER, playerIn);

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.deployer;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
@ -274,7 +275,8 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
private DeployerFakePlayer getPlayer(MovementContext context) {
if (!(context.temporaryData instanceof DeployerFakePlayer) && context.world instanceof ServerLevel) {
DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerLevel) context.world);
UUID owner = context.blockEntityData.contains("Owner") ? context.blockEntityData.getUUID("Owner") : null;
DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerLevel) context.world, owner);
deployerFakePlayer.onMinecartContraption = context.contraption instanceof MountedContraption;
deployerFakePlayer.getInventory()
.load(context.blockEntityData.getList("Inventory", Tag.TAG_COMPOUND));

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.contraptions.components.deployer;
import java.util.UUID;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllItems;
@ -41,7 +43,8 @@ public class DeployerMovingInteraction extends MovingInteractionBehaviour {
DeployerFakePlayer fake = null;
if (!(ctx.temporaryData instanceof DeployerFakePlayer) && ctx.world instanceof ServerLevel) {
DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerLevel) ctx.world);
UUID owner = ctx.blockEntityData.contains("Owner") ? ctx.blockEntityData.getUUID("Owner") : null;
DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerLevel) ctx.world, owner);
deployerFakePlayer.onMinecartContraption = ctx.contraption instanceof MountedContraption;
deployerFakePlayer.getInventory()
.load(ctx.blockEntityData.getList("Inventory", Tag.TAG_COMPOUND));