mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-05 23:10:30 +00:00
Add a more strict form of IPocketAccess.getEntity
Before IPocketAccess.getEntity would return the entity which last held
fthis computer, even if not holding it any more. As
ba823bae13
describes, this caused
pocket.equip/pocket.unequip to dupe items.
We move the validation from the PocketAPI into the main IPocketAccess
implementation, to ensure this issue does not occur elsewhere. Note, we
require a separate method, as this is no longer thread-safe.
We also now return ok, err instead of throwing an exception, in order to
be consistent with the turtle functions. See dan200/ComputerCraft#328.
This commit is contained in:
parent
ba823bae13
commit
259665d9f1
@ -24,10 +24,22 @@ public interface IPocketAccess
|
|||||||
* Gets the entity holding this item.
|
* Gets the entity holding this item.
|
||||||
*
|
*
|
||||||
* @return The holding entity. This may be {@code null}.
|
* @return The holding entity. This may be {@code null}.
|
||||||
|
* @deprecated Use {@link #getValidEntity()} where possible.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@Deprecated
|
||||||
Entity getEntity();
|
Entity getEntity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity holding this item with additional safety checks.
|
||||||
|
*
|
||||||
|
* This must be called on the server thread.
|
||||||
|
*
|
||||||
|
* @return The holding entity, or {@code null} if none exists.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Entity getValidEntity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the colour of this pocket computer as a RGB number.
|
* Get the colour of this pocket computer as a RGB number.
|
||||||
*
|
*
|
||||||
|
@ -12,9 +12,9 @@ import dan200.computercraft.api.lua.LuaException;
|
|||||||
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
import dan200.computercraft.api.pocket.IPocketUpgrade;
|
||||||
import dan200.computercraft.shared.PocketUpgrades;
|
import dan200.computercraft.shared.PocketUpgrades;
|
||||||
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
|
||||||
import dan200.computercraft.shared.util.InventoryUtil;
|
import dan200.computercraft.shared.util.InventoryUtil;
|
||||||
import dan200.computercraft.shared.util.WorldUtil;
|
import dan200.computercraft.shared.util.WorldUtil;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@ -59,20 +59,10 @@ public class PocketAPI implements ILuaAPI
|
|||||||
// equipBack
|
// equipBack
|
||||||
return context.executeMainThreadTask( () ->
|
return context.executeMainThreadTask( () ->
|
||||||
{
|
{
|
||||||
if( !(m_computer.getEntity() instanceof EntityPlayer) )
|
Entity entity = m_computer.getValidEntity();
|
||||||
{
|
if( !(entity instanceof EntityPlayer) ) return new Object[] { false, "Cannot find player" };
|
||||||
throw new LuaException( "Cannot find player" );
|
EntityPlayer player = (EntityPlayer) entity;
|
||||||
}
|
|
||||||
|
|
||||||
EntityPlayer player = (EntityPlayer) m_computer.getEntity();
|
|
||||||
InventoryPlayer inventory = player.inventory;
|
InventoryPlayer inventory = player.inventory;
|
||||||
|
|
||||||
int computerID = m_computer.getID();
|
|
||||||
if ( !pocketComputerExists( inventory.mainInventory, computerID ) && !pocketComputerExists( inventory.offHandInventory, computerID ) )
|
|
||||||
{
|
|
||||||
throw new LuaException( "Cannot find pocket computer" );
|
|
||||||
}
|
|
||||||
|
|
||||||
IPocketUpgrade previousUpgrade = m_computer.getUpgrade();
|
IPocketUpgrade previousUpgrade = m_computer.getUpgrade();
|
||||||
|
|
||||||
// Attempt to find the upgrade, starting in the main segment, and then looking in the opposite
|
// Attempt to find the upgrade, starting in the main segment, and then looking in the opposite
|
||||||
@ -82,7 +72,7 @@ public class PocketAPI implements ILuaAPI
|
|||||||
{
|
{
|
||||||
newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade );
|
newUpgrade = findUpgrade( inventory.offHandInventory, 0, previousUpgrade );
|
||||||
}
|
}
|
||||||
if( newUpgrade == null ) throw new LuaException( "Cannot find a valid upgrade" );
|
if( newUpgrade == null ) return new Object[] { false, "Cannot find a valid upgrade" };
|
||||||
|
|
||||||
// Remove the current upgrade
|
// Remove the current upgrade
|
||||||
if( previousUpgrade != null )
|
if( previousUpgrade != null )
|
||||||
@ -101,30 +91,20 @@ public class PocketAPI implements ILuaAPI
|
|||||||
// Set the new upgrade
|
// Set the new upgrade
|
||||||
m_computer.setUpgrade( newUpgrade );
|
m_computer.setUpgrade( newUpgrade );
|
||||||
|
|
||||||
return null;
|
return new Object[] { true };
|
||||||
} );
|
} );
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// unequipBack
|
// unequipBack
|
||||||
return context.executeMainThreadTask( () ->
|
return context.executeMainThreadTask( () ->
|
||||||
{
|
{
|
||||||
if( !(m_computer.getEntity() instanceof EntityPlayer) )
|
Entity entity = m_computer.getValidEntity();
|
||||||
{
|
if( !(entity instanceof EntityPlayer) ) return new Object[] { false, "Cannot find player" };
|
||||||
throw new LuaException( "Cannot find player" );
|
EntityPlayer player = (EntityPlayer) entity;
|
||||||
}
|
|
||||||
|
|
||||||
EntityPlayer player = (EntityPlayer) m_computer.getEntity();
|
|
||||||
InventoryPlayer inventory = player.inventory;
|
InventoryPlayer inventory = player.inventory;
|
||||||
|
|
||||||
int computerID = m_computer.getID();
|
|
||||||
if ( !pocketComputerExists( inventory.mainInventory, computerID ) && !pocketComputerExists( inventory.offHandInventory, computerID ) )
|
|
||||||
{
|
|
||||||
throw new LuaException( "Cannot find pocket computer" );
|
|
||||||
}
|
|
||||||
|
|
||||||
IPocketUpgrade previousUpgrade = m_computer.getUpgrade();
|
IPocketUpgrade previousUpgrade = m_computer.getUpgrade();
|
||||||
|
|
||||||
if( previousUpgrade == null ) throw new LuaException( "Nothing to unequip" );
|
if( previousUpgrade == null ) return new Object[] { false, "Nothing to unequip" };
|
||||||
|
|
||||||
m_computer.setUpgrade( null );
|
m_computer.setUpgrade( null );
|
||||||
|
|
||||||
@ -138,7 +118,7 @@ public class PocketAPI implements ILuaAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return new Object[] { true };
|
||||||
} );
|
} );
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
@ -168,20 +148,4 @@ public class PocketAPI implements ILuaAPI
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean pocketComputerExists( NonNullList<ItemStack> inv, int computerID )
|
|
||||||
{
|
|
||||||
for( ItemStack invStack : inv )
|
|
||||||
{
|
|
||||||
if( !invStack.isEmpty() && invStack.getItem() instanceof ItemPocketComputer )
|
|
||||||
{
|
|
||||||
if( ComputerCraft.Items.pocketComputer.getComputerID( invStack ) == computerID )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import dan200.computercraft.shared.computer.core.ComputerFamily;
|
|||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
@ -46,6 +47,29 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
|||||||
return m_entity;
|
return m_entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Entity getValidEntity()
|
||||||
|
{
|
||||||
|
Entity entity = m_entity;
|
||||||
|
if( entity == null || m_stack == null || entity.isDead ) return null;
|
||||||
|
|
||||||
|
if( m_entity instanceof EntityPlayer )
|
||||||
|
{
|
||||||
|
InventoryPlayer inventory = ((EntityPlayer) m_entity).inventory;
|
||||||
|
return inventory.mainInventory.contains( m_stack ) || inventory.offHandInventory.contains( m_stack ) ? entity : null;
|
||||||
|
}
|
||||||
|
else if( m_entity instanceof EntityLivingBase )
|
||||||
|
{
|
||||||
|
EntityLivingBase living = (EntityLivingBase) m_entity;
|
||||||
|
return living.getHeldItemMainhand() == m_stack || living.getHeldItemOffhand() == m_stack ? entity : null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColour()
|
public int getColour()
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ public class PocketModem extends AbstractPocketUpgrade
|
|||||||
{
|
{
|
||||||
if( !(peripheral instanceof PocketModemPeripheral) ) return;
|
if( !(peripheral instanceof PocketModemPeripheral) ) return;
|
||||||
|
|
||||||
Entity entity = access.getEntity();
|
Entity entity = access.getValidEntity();
|
||||||
|
|
||||||
PocketModemPeripheral modem = (PocketModemPeripheral) peripheral;
|
PocketModemPeripheral modem = (PocketModemPeripheral) peripheral;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public class PocketSpeaker extends AbstractPocketUpgrade
|
|||||||
|
|
||||||
PocketSpeakerPeripheral speaker = (PocketSpeakerPeripheral) peripheral;
|
PocketSpeakerPeripheral speaker = (PocketSpeakerPeripheral) peripheral;
|
||||||
|
|
||||||
Entity entity = access.getEntity();
|
Entity entity = access.getValidEntity();
|
||||||
if( entity instanceof EntityLivingBase )
|
if( entity instanceof EntityLivingBase )
|
||||||
{
|
{
|
||||||
EntityLivingBase player = (EntityLivingBase) entity;
|
EntityLivingBase player = (EntityLivingBase) entity;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
local ok, err = pcall( pocket.equipBack )
|
local ok, err = pocket.equipBack()
|
||||||
if not ok then
|
if not ok then
|
||||||
printError( "Nothing to equip" )
|
printError( err )
|
||||||
else
|
else
|
||||||
print( "Item equipped" )
|
print( "Item equipped" )
|
||||||
end
|
end
|
@ -1,6 +1,6 @@
|
|||||||
local ok, err = pcall( pocket.unequipBack )
|
local ok, err = pocket.unequipBack()
|
||||||
if not ok then
|
if not ok then
|
||||||
printError( "Nothing to unequip" )
|
printError( err )
|
||||||
else
|
else
|
||||||
print( "Item unequipped" )
|
print( "Item unequipped" )
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user