From 4c0fa1fabe6bd53fb022e117c31ba5cc56a9eb7f Mon Sep 17 00:00:00 2001 From: SquidDev Date: Sun, 4 Feb 2018 21:35:21 +0000 Subject: [PATCH] Track which player "owns" a turtle When a player places a turtle, they are marked as its owner. Any actions they perform (such as breaking blocks, moving, etc...) are performed using this player's game profile. This allows turtles to work correctly with various permissions mods. Previously you would have to whitelist all turtles in order for them to function within a claim. --- .../api/turtle/ITurtleAccess.java | 11 +++++- .../shared/turtle/blocks/BlockTurtle.java | 7 +++- .../shared/turtle/blocks/TileTurtle.java | 8 +++- .../shared/turtle/core/TurtleBrain.java | 39 +++++++++++++++++++ .../turtle/core/TurtlePlaceCommand.java | 2 +- .../shared/turtle/core/TurtlePlayer.java | 22 +++++++++-- .../upgrades/TurtleInventoryCrafting.java | 2 +- .../shared/turtle/upgrades/TurtleTool.java | 8 ++-- 8 files changed, 86 insertions(+), 13 deletions(-) diff --git a/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java b/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java index 940adb89a..e65b293f9 100644 --- a/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java +++ b/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java @@ -6,6 +6,7 @@ package dan200.computercraft.api.turtle; +import com.mojang.authlib.GameProfile; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IPeripheral; @@ -135,6 +136,14 @@ public interface ITurtleAccess */ int getColour(); + /** + * Get the player who owns this turtle, namely whoever placed it. + * + * @return This turtle's owner. + */ + @Nonnull + GameProfile getOwningPlayer(); + /** * Get the inventory of this turtle * @@ -148,7 +157,7 @@ public interface ITurtleAccess * Get the inventory of this turtle as an {@link IItemHandlerModifiable}. * * @return This turtle's inventory - * @see #getInventory() + * @see #getInventory() * @see IItemHandlerModifiable * @see net.minecraftforge.items.CapabilityItemHandler#ITEM_HANDLER_CAPABILITY */ diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java index 32c2eeb46..10931e63c 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/BlockTurtle.java @@ -17,11 +17,12 @@ import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -169,6 +170,10 @@ public void onBlockPlacedBy( World world, BlockPos pos, IBlockState state, Entit { tile.setWorld( world ); // Not sure why this is necessary tile.setPos( pos ); // Not sure why this is necessary + if( player instanceof EntityPlayer ) + { + ((TileTurtle) tile).setOwningPlayer( ((EntityPlayer) player).getGameProfile() ); + } } // Set direction diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java index 569e2278d..04320c250 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.turtle.blocks; +import com.mojang.authlib.GameProfile; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleUpgrade; @@ -43,7 +44,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.List; import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY; @@ -448,6 +448,12 @@ public float getToolRenderAngle( TurtleSide side, float f ) return m_brain.getToolRenderAngle( side, f ); } + public void setOwningPlayer( GameProfile player ) + { + m_brain.setOwningPlayer( player ); + markDirty(); + } + // IInventory @Override diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java index 4813928ed..6512c86c9 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java @@ -7,6 +7,7 @@ package dan200.computercraft.shared.turtle.core; import com.google.common.base.Objects; +import com.mojang.authlib.GameProfile; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; @@ -104,6 +105,7 @@ public static void cleanupBrains() private static final int ANIM_DURATION = 8; private TileTurtle m_owner; + private GameProfile m_owningPlayer; private LinkedList m_commandQueue; private int m_commandsIssued; @@ -215,6 +217,20 @@ public void readFromNBT( NBTTagCompound nbttagcompound ) m_fuelLevel = 0; } + // Read owner + if( nbttagcompound.hasKey( "owner", Constants.NBT.TAG_COMPOUND ) ) + { + NBTTagCompound owner = nbttagcompound.getCompoundTag( "owner" ); + m_owningPlayer = new GameProfile( + new UUID( owner.getLong( "upper_id" ), owner.getLong( "lower_id" ) ), + owner.getString( "name" ) + ); + } + else + { + m_owningPlayer = null; + } + // Read colour m_colourHex = ColourUtils.getHexColour( nbttagcompound ); @@ -302,6 +318,17 @@ public NBTTagCompound writeToNBT( NBTTagCompound nbttagcompound ) nbttagcompound.setInteger( "selectedSlot", m_selectedSlot ); nbttagcompound.setInteger( "fuelLevel", m_fuelLevel ); + // Write owner + if( m_owningPlayer != null ) + { + NBTTagCompound owner = new NBTTagCompound(); + nbttagcompound.setTag( "owner", owner ); + + owner.setLong( "upper_id", m_owningPlayer.getId().getMostSignificantBits() ); + owner.setLong( "upper_id", m_owningPlayer.getId().getLeastSignificantBits() ); + owner.setString( "name", m_owningPlayer.getName() ); + } + // Write upgrades String leftUpgradeID = getUpgradeID( getUpgrade( TurtleSide.Left ) ); if( leftUpgradeID != null ) @@ -819,6 +846,18 @@ public int getColour() return m_colourHex; } + public void setOwningPlayer( GameProfile profile ) + { + m_owningPlayer = profile; + } + + @Nonnull + @Override + public GameProfile getOwningPlayer() + { + return m_owningPlayer; + } + @Override public ITurtleUpgrade getUpgrade( @Nonnull TurtleSide side ) { diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java index 26b1a4780..78ec64f0a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java @@ -163,7 +163,7 @@ public static ItemStack deploy( @Nonnull ItemStack stack, ITurtleAccess turtle, public static TurtlePlayer createPlayer( ITurtleAccess turtle, BlockPos position, EnumFacing direction ) { - TurtlePlayer turtlePlayer = new TurtlePlayer( (WorldServer)turtle.getWorld() ); + TurtlePlayer turtlePlayer = new TurtlePlayer( turtle ); orientPlayer( turtle, turtlePlayer, position, direction ); return turtlePlayer; } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java index a5362c531..ee295349a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java @@ -20,11 +20,12 @@ import net.minecraftforge.common.util.FakePlayer; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.UUID; public class TurtlePlayer extends FakePlayer { - private final static GameProfile s_profile = new GameProfile( + public final static GameProfile DEFAULT_PROFILE = new GameProfile( UUID.fromString( "0d0c4ca0-4ff1-11e4-916c-0800200c9a66" ), "ComputerCraft" ); @@ -32,12 +33,25 @@ public class TurtlePlayer extends FakePlayer @Deprecated public TurtlePlayer( World world ) { - this( (WorldServer) world ); + super( (WorldServer) world, DEFAULT_PROFILE ); + } + + public TurtlePlayer( ITurtleAccess turtle ) + { + super( (WorldServer) turtle.getWorld(), getProfile( turtle.getOwningPlayer() )); + + BlockPos position = turtle.getPosition(); + posX = position.getX() + 0.5; + posY = position.getY() + 0.5; + posZ = position.getZ() + 0.5; + + rotationYaw = turtle.getDirection().getHorizontalAngle(); + rotationPitch = 0.0f; } - public TurtlePlayer( WorldServer world ) + private static GameProfile getProfile( @Nullable GameProfile profile ) { - super( world, s_profile ); + return profile != null && profile.isComplete() ? profile : DEFAULT_PROFILE; } public void loadInventory( @Nonnull ItemStack currentStack ) diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java index 1c4dcb9f6..cdcb3c187 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java @@ -118,7 +118,7 @@ public ArrayList doCrafting( World world, int maxCount ) } // Do post-pickup stuff - TurtlePlayer turtlePlayer = new TurtlePlayer( (WorldServer)world ); + TurtlePlayer turtlePlayer = new TurtlePlayer( m_turtle ); result.onCrafting( world, turtlePlayer, numToCraft ); results.add( result ); diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java index 4f8738f54..eba701e21 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java @@ -32,7 +32,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ForgeEventFactory; @@ -148,10 +147,11 @@ protected boolean canBreakBlock( World world, BlockPos pos ) return !block.isAir( state, world, pos ) && block != Blocks.BEDROCK && state.getBlockHardness( world, pos ) > -1.0F; } - protected boolean canHarvestBlock( World world, BlockPos pos ) + protected boolean canHarvestBlock( ITurtleAccess turtleAccess, BlockPos pos ) { + World world = turtleAccess.getWorld(); Block block = world.getBlockState( pos ).getBlock(); - TurtlePlayer turtlePlayer = new TurtlePlayer( (WorldServer)world ); + TurtlePlayer turtlePlayer = new TurtlePlayer( turtleAccess ); turtlePlayer.loadInventory( m_item.copy() ); return ForgeHooks.canHarvestBlock( block, turtlePlayer, world, pos ); } @@ -267,7 +267,7 @@ private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction ) } // Consume the items the block drops - if( canHarvestBlock( world, newPosition ) ) + if( canHarvestBlock( turtle, newPosition ) ) { List items = getBlockDropped( world, newPosition, turtlePlayer ); if( items != null && items.size() > 0 )