1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-24 06:03:28 +00:00

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.
This commit is contained in:
SquidDev 2018-02-04 21:35:21 +00:00
parent 3b3dd8071b
commit 4c0fa1fabe
8 changed files with 86 additions and 13 deletions

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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<TurtleCommandQueueEntry> 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 )
{

View File

@ -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;
}

View File

@ -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 )

View File

@ -118,7 +118,7 @@ public ArrayList<ItemStack> 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 );

View File

@ -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<ItemStack> items = getBlockDropped( world, newPosition, turtlePlayer );
if( items != null && items.size() > 0 )