backport 0bdc408e950fe787277d1e48be61ebf928127429

This commit is contained in:
Salomão
2021-03-31 20:53:26 -03:00
parent ca7ce33f34
commit 011b3a4b94
12 changed files with 524 additions and 600 deletions
@@ -32,6 +32,7 @@ import io.netty.buffer.ByteBuf;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
@@ -216,18 +217,6 @@ public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFlu
return dup;
}
@Override
public boolean isItem()
{
return false;
}
@Override
public boolean isFluid()
{
return true;
}
@Override
public IStorageChannel<IAEFluidStack> getChannel()
{
@@ -318,17 +307,17 @@ public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFlu
}
@Override
public void writeToPacket( final ByteBuf buffer ) throws IOException
public void writeToPacket( final ByteBuf i ) throws IOException
{
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this
.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
buffer.writeByte( mask );
i.writeByte( mask );
this.writeToStream( buffer );
this.writeToStream( i );
this.putPacketValue( buffer, this.getStackSize() );
this.putPacketValue( buffer, this.getCountRequestable() );
this.putPacketValue( i, this.getStackSize() );
this.putPacketValue( i, this.getCountRequestable() );
}
private void writeToStream( final ByteBuf buffer ) throws IOException
@@ -0,0 +1,51 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util;
import java.util.regex.Pattern;
/**
* Regex wrapper for {@link java.util.UUID}s to not rely on try catch
*/
public final class UUIDMatcher
{
/**
* String which is the regular expression for {@link java.util.UUID}s
*/
private static final String UUID_REGEX = "[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}";
/**
* Pattern which pre-compiles the {@link appeng.util.UUIDMatcher#UUID_REGEX}
*/
private static final Pattern PATTERN = Pattern.compile( UUID_REGEX );
/**
* Checks if a potential {@link java.util.UUID} is an {@link java.util.UUID} by applying a regular expression on it.
*
* @param potential to be checked potential {@link java.util.UUID}
*
* @return true, if the potential {@link java.util.UUID} is indeed an {@link java.util.UUID}
*/
public boolean isUUID( final CharSequence potential )
{
return PATTERN.matcher( potential ).matches();
}
}
+222 -284
View File
@@ -1,6 +1,6 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
* Copyright (c) 2013 - 2020, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -18,7 +18,6 @@
package appeng.util.item;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -26,348 +25,287 @@ import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.ItemHandlerHelper;
import appeng.api.AEApi;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.Platform;
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack {
public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemStack
{
private AESharedItemStack sharedStack;
private Optional<OreReference> oreReference;
private final AESharedItemStack sharedStack;
private Optional<OreReference> oreReference;
@SideOnly( Side.CLIENT )
private String displayName;
@SideOnly( Side.CLIENT )
private List<String> tooltip;
@SideOnly( Side.CLIENT )
private ResourceLocation uniqueID;
@SideOnly( Side.CLIENT )
private String displayName;
@SideOnly( Side.CLIENT )
private List<String> tooltip;
private AEItemStack( final AEItemStack is )
{
this.setStackSize( is.getStackSize() );
this.setCraftable( is.isCraftable() );
this.setCountRequestable( is.getCountRequestable() );
this.sharedStack = is.sharedStack;
this.oreReference = is.oreReference;
}
private AEItemStack(final AEItemStack is) {
this.setStackSize(is.getStackSize());
this.setCraftable(is.isCraftable());
this.setCountRequestable(is.getCountRequestable());
this.sharedStack = is.sharedStack;
this.oreReference = is.oreReference;
}
private AEItemStack( final AESharedItemStack is, long size )
{
this.sharedStack = is;
this.setStackSize( size );
this.setCraftable( false );
this.setCountRequestable( 0 );
this.oreReference = OreHelper.INSTANCE.getOre( is.getDefinition() );
}
private AEItemStack(final AESharedItemStack is, long size) {
this.sharedStack = is;
this.setStackSize(size);
this.setCraftable(false);
this.setCountRequestable(0);
this.oreReference = OreHelper.INSTANCE.getOre( is.getDefinition() );
}
@Nullable
public static AEItemStack fromItemStack( @Nonnull final ItemStack stack )
{
if( stack.isEmpty() )
{
return null;
}
@Nullable
public static AEItemStack fromItemStack(@Nonnull final ItemStack stack) {
if (stack.isEmpty()) {
return null;
}
return new AEItemStack( AEItemStackRegistry.getRegisteredStack( stack ), stack.getCount() );
}
return new AEItemStack(AEItemStackRegistry.getRegisteredStack(stack), stack.getCount());
}
public static IAEItemStack fromNBT( final NBTTagCompound i )
{
if( i == null )
{
return null;
}
public static IAEItemStack fromNBT( final NBTTagCompound i )
{
if( i == null )
{
return null;
}
final ItemStack itemstack = new ItemStack( i );
if( itemstack.isEmpty() )
{
return null;
}
final ItemStack itemstack = new ItemStack( i );
if( itemstack.isEmpty() )
{
return null;
}
final AEItemStack item = AEItemStack.fromItemStack( itemstack );
item.setStackSize( i.getLong( "Cnt" ) );
item.setCountRequestable( i.getLong( "Req" ) );
item.setCraftable( i.getBoolean( "Craft" ) );
return item;
}
final AEItemStack item = AEItemStack.fromItemStack( itemstack );
item.setStackSize( i.getLong( "Cnt" ) );
item.setCountRequestable( i.getLong( "Req" ) );
item.setCraftable( i.getBoolean( "Craft" ) );
return item;
}
@Override
public void writeToNBT( final NBTTagCompound i )
{
this.getDefinition().writeToNBT( i );
i.setLong( "Cnt", this.getStackSize() );
i.setLong( "Req", this.getCountRequestable() );
i.setBoolean( "Craft", this.isCraftable() );
}
@Override
public void writeToNBT( final NBTTagCompound i )
{
this.getDefinition().writeToNBT( i );
i.setLong( "Cnt", this.getStackSize() );
i.setLong( "Req", this.getCountRequestable() );
i.setBoolean( "Craft", this.isCraftable() );
}
public static AEItemStack fromPacket( final ByteBuf data )
{
final byte mask = data.readByte();
final byte stackType = (byte) ( ( mask & 0x0C ) >> 2 );
final byte countReqType = (byte) ( ( mask & 0x30 ) >> 4 );
final boolean isCraftable = ( mask & 0x40 ) > 0;
public static AEItemStack fromPacket( final ByteBuf data )
{
final byte mask = data.readByte();
final byte stackType = (byte) ( ( mask & 0x0C ) >> 2 );
final byte countReqType = (byte) ( ( mask & 0x30 ) >> 4 );
final boolean isCraftable = ( mask & 0x40 ) > 0;
final ItemStack itemstack = new ItemStack( ByteBufUtils.readTag( data ) );
final long stackSize = getPacketValue( stackType, data );
final long countRequestable = getPacketValue( countReqType, data );
final ItemStack itemstack = new ItemStack( ByteBufUtils.readTag( data ) );
final long stackSize = getPacketValue( stackType, data );
final long countRequestable = getPacketValue( countReqType, data );
if( itemstack.isEmpty() )
{
return null;
}
if( itemstack.isEmpty() )
{
return null;
}
final AEItemStack item = new AEItemStack( AEItemStackRegistry.getRegisteredStack( itemstack ), stackSize );
item.setCountRequestable( countRequestable );
item.setCraftable( isCraftable );
return item;
}
final AEItemStack item = new AEItemStack( AEItemStackRegistry.getRegisteredStack( itemstack ), stackSize );
item.setCountRequestable( countRequestable );
item.setCraftable( isCraftable );
return item;
}
@Override
public void writeToPacket( final ByteBuf i )
{
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this
.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
@Override
public void writeToPacket( final ByteBuf i )
{
final byte mask = (byte) ( ( this.getType( this.getStackSize() ) << 2 ) | ( this
.getType( this.getCountRequestable() ) << 4 ) | ( (byte) ( this.isCraftable() ? 1 : 0 ) << 6 ) | ( this.hasTagCompound() ? 1 : 0 ) << 7 );
i.writeByte( mask );
ByteBufUtils.writeTag( i, this.getDefinition().serializeNBT() );
this.putPacketValue( i, this.getStackSize() );
this.putPacketValue( i, this.getCountRequestable() );
}
i.writeByte( mask );
ByteBufUtils.writeTag( i, this.getDefinition().serializeNBT() );
this.putPacketValue( i, this.getStackSize() );
this.putPacketValue( i, this.getCountRequestable() );
}
@Override
public void add( final IAEItemStack option )
{
if( option == null )
{
return;
}
/**
* We're assuming that using capNBT here is safe, because {@link #getDefinition()} should have been created by
* {@link ItemStack#copy()}, and then never mutated. Copying an item stack will automatically serialize the
* capabilities of the source stack and initialize the target stacks capNBT field using that tag, which we are then
* reusing here.
*/
this.incStackSize( option.getStackSize() );
this.setCountRequestable( this.getCountRequestable() + option.getCountRequestable() );
this.setCraftable( this.isCraftable() || option.isCraftable() );
}
@Override
public void add(final IAEItemStack option) {
if (option == null) {
return;
}
@Override
public boolean fuzzyComparison( final IAEItemStack other, final FuzzyMode mode )
{
if( mode == FuzzyMode.IGNORE_ALL && OreHelper.INSTANCE.sameOre( this, other ) )
{
return true;
}
this.incStackSize(option.getStackSize());
this.setCountRequestable(this.getCountRequestable() + option.getCountRequestable());
this.setCraftable(this.isCraftable() || option.isCraftable());
}
final ItemStack itemStack = this.getDefinition();
final ItemStack otherStack = other.getDefinition();
@Override
public boolean fuzzyComparison(final IAEItemStack other, final FuzzyMode mode) {
final ItemStack itemStack = this.getDefinition();
final ItemStack otherStack = other.getDefinition();
return this.fuzzyItemStackComparison( itemStack, otherStack, mode );
}
return this.fuzzyItemStackComparison(itemStack, otherStack, mode);
}
@Override
public IAEItemStack copy()
{
return new AEItemStack( this );
}
@Override
public IAEItemStack copy() {
return new AEItemStack(this);
}
@Override
public boolean isItem()
{
return true;
}
@Override
public IStorageChannel<IAEItemStack> getChannel() {
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
}
@Override
public boolean isFluid()
{
return false;
}
@Override
public ItemStack createItemStack() {
return ItemHandlerHelper.copyStackWithSize(this.getDefinition(),
(int) Math.min(Integer.MAX_VALUE, this.getStackSize()));
}
@Override
public IStorageChannel<IAEItemStack> getChannel()
{
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
}
@Override
public Item getItem() {
return this.getDefinition().getItem();
}
@Override
public ItemStack createItemStack()
{
return ItemHandlerHelper.copyStackWithSize( this.getDefinition(), (int) Math.min( Integer.MAX_VALUE, this.getStackSize() ) );
}
@Override
public int getItemDamage() {
return this.sharedStack.getItemDamage();
}
@Override
public Item getItem()
{
return this.getDefinition().getItem();
}
public Optional<OreReference> getOre()
{
return this.oreReference;
}
@Override
public int getItemDamage()
{
return this.sharedStack.getItemDamage();
}
@Override
public boolean sameOre( final IAEItemStack is )
{
return OreHelper.INSTANCE.sameOre( this, is );
}
@Override
public boolean sameOre( final IAEItemStack is )
{
return OreHelper.INSTANCE.sameOre( this, is );
}
@Override
public boolean isSameType(final IAEItemStack otherStack) {
if (otherStack == null) {
return false;
}
@Override
public boolean isSameType( final IAEItemStack otherStack )
{
if( otherStack == null )
{
return false;
}
return Objects.equals(this.sharedStack, ((AEItemStack) otherStack).sharedStack);
}
return Objects.equals( this.sharedStack, ( (AEItemStack) otherStack ).sharedStack );
}
@Override
public boolean isSameType(final ItemStack otherStack) {
if (otherStack.isEmpty()) {
return false;
}
int oldSize = otherStack.getCount();
@Override
public boolean isSameType( final ItemStack otherStack )
{
if( otherStack.isEmpty() )
{
return false;
}
int oldSize = otherStack.getCount();
otherStack.setCount(1);
boolean ret = ItemStack.areItemStacksEqual(this.getDefinition(), otherStack);
otherStack.setCount(oldSize);
otherStack.setCount( 1 );
boolean ret = ItemStack.areItemStacksEqual( this.getDefinition(), otherStack );
otherStack.setCount( oldSize );
return ret;
}
return ret;
}
@Override
public int hashCode() {
return this.sharedStack.hashCode();
}
@Override
public int hashCode()
{
return this.sharedStack.hashCode();
}
@Override
public boolean equals(final Object ia) {
if (ia instanceof AEItemStack) {
return this.isSameType((AEItemStack) ia);
} else if (ia instanceof ItemStack) {
// this actually breaks the equals contract (being equals to unrelated classes)
return equals((ItemStack) ia);
}
return false;
}
@Override
public boolean equals( final Object ia )
{
if( ia instanceof AEItemStack )
{
return this.isSameType( (AEItemStack) ia );
}
else if( ia instanceof ItemStack )
{
return this.isSameType( (ItemStack) ia );
}
return false;
}
@Override
public String toString() {
return this.getStackSize() + "x" + this.getDefinition().getItem().getRegistryName();
}
@Override
public String toString()
{
return this.getStackSize() + "x" + this.getDefinition().getItem().getUnlocalizedName() + "@" + this.getDefinition().getItemDamage();
}
@SideOnly( Side.CLIENT )
public List<String> getToolTip() {
if (this.tooltip == null) {
this.tooltip = Platform.getTooltip(this.asItemStackRepresentation());
}
return this.tooltip;
}
@SideOnly( Side.CLIENT )
public List<String> getToolTip()
{
if( this.tooltip == null )
{
this.tooltip = Platform.getTooltip( this.asItemStackRepresentation() );
}
return this.tooltip;
}
@SideOnly( Side.CLIENT )
public String getDisplayName() {
if (this.displayName == null) {
this.displayName = Platform.getItemDisplayName(this.asItemStackRepresentation());
}
return this.displayName;
}
@SideOnly( Side.CLIENT )
public String getDisplayName()
{
if( this.displayName == null )
{
this.displayName = Platform.getItemDisplayName( this.asItemStackRepresentation() );
}
return this.displayName;
}
@SideOnly( Side.CLIENT )
public String getModID() {
return this.getDefinition().getItem().getRegistryName().getResourceDomain();
}
@SideOnly( Side.CLIENT )
public String getModID()
{
if( this.uniqueID == null )
{
this.uniqueID = Item.REGISTRY.getNameForObject( this.getDefinition().getItem() );
}
@Override
public boolean hasTagCompound() {
return this.getDefinition().hasTagCompound();
}
if( this.uniqueID == null )
{
return "** Null";
}
@Override
public ItemStack asItemStackRepresentation() {
return this.getDefinition().copy();
}
return this.uniqueID.getResourceDomain() == null ? "** Null" : this.uniqueID.getResourceDomain();
}
@Override
public ItemStack getDefinition() {
return this.sharedStack.getDefinition();
}
public Optional<OreReference> getOre()
{
return this.oreReference;
}
public boolean equals(final ItemStack is) {
return this.isSameType(is);
}
@Override
public boolean hasTagCompound()
{
return this.getDefinition().hasTagCompound();
}
AESharedItemStack getSharedStack() {
return this.sharedStack;
}
@Override
public ItemStack asItemStackRepresentation()
{
return this.getDefinition().copy();
}
private boolean fuzzyItemStackComparison(ItemStack a, ItemStack b, FuzzyMode mode) {
if (a.getItem() == b.getItem()) {
if (a.getItem().isDamageable()) {
if (mode == FuzzyMode.IGNORE_ALL) {
return true;
} else if (mode == FuzzyMode.PERCENT_99) {
return (a.getItemDamage() > 1) == (b.getItemDamage() > 1);
} else {
final float percentDamageOfA = (float) a.getItemDamage() / a.getMaxDamage();
final float percentDamageOfB = (float) b.getItemDamage() / b.getMaxDamage();
@Override
public ItemStack getDefinition()
{
return this.sharedStack.getDefinition();
}
AESharedItemStack getSharedStack()
{
return this.sharedStack;
}
private boolean fuzzyItemStackComparison( ItemStack a, ItemStack b, FuzzyMode mode )
{
if( a.getItem() == b.getItem() )
{
if( a.getItem().isDamageable() )
{
if( mode == FuzzyMode.IGNORE_ALL )
{
return true;
}
else if( mode == FuzzyMode.PERCENT_99 )
{
return ( a.getItemDamage() > 1 ) == ( b.getItemDamage() > 1 );
}
else
{
final float percentDamageOfA = (float) a.getItemDamage() / (float) a.getMaxDamage();
final float percentDamageOfB = (float) b.getItemDamage() / (float) b.getMaxDamage();
return ( percentDamageOfA > mode.breakPoint ) == ( percentDamageOfB > mode.breakPoint );
}
}
return a.getMetadata() == b.getMetadata();
}
return false;
}
return (percentDamageOfA > mode.breakPoint) == (percentDamageOfB > mode.breakPoint);
}
}
}
return false;
}
}
@@ -23,7 +23,6 @@
package appeng.util.item;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
@@ -31,56 +30,34 @@ import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import appeng.util.Platform;
public final class AEItemStackRegistry {
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> REGISTRY = new WeakHashMap<>();
private AEItemStackRegistry() {
}
public final class AEItemStackRegistry
{
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> SERVER_REGISTRY = new WeakHashMap<>();
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> CLIENT_REGISTRY = new WeakHashMap<>();
static synchronized AESharedItemStack getRegisteredStack(final @Nonnull ItemStack itemStack) {
if (itemStack.isEmpty()) {
throw new IllegalArgumentException("stack cannot be empty");
}
private AEItemStackRegistry()
{
}
int oldStackSize = itemStack.getCount();
itemStack.setCount(1);
private static WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> registry()
{
if( Platform.isClient() )
{
return CLIENT_REGISTRY;
}
else
{
return SERVER_REGISTRY;
}
}
AESharedItemStack search = new AESharedItemStack(itemStack);
WeakReference<AESharedItemStack> weak = REGISTRY.get(search);
AESharedItemStack ret = null;
static synchronized AESharedItemStack getRegisteredStack( final @Nonnull ItemStack itemStack )
{
if( itemStack.isEmpty() )
{
throw new IllegalArgumentException( "stack cannot be empty" );
}
if (weak != null) {
ret = weak.get();
}
int oldStackSize = itemStack.getCount();
itemStack.setCount( 1 );
if (ret == null) {
ret = new AESharedItemStack(itemStack.copy());
REGISTRY.put(ret, new WeakReference<>(ret));
}
itemStack.setCount(oldStackSize);
AESharedItemStack search = new AESharedItemStack( itemStack );
WeakReference<AESharedItemStack> weak = registry().get( search );
AESharedItemStack ret = null;
if( weak != null )
{
ret = weak.get();
}
if( ret == null )
{
ret = new AESharedItemStack( itemStack.copy() );
registry().put( ret, new WeakReference<>( ret ) );
}
itemStack.setCount( oldStackSize );
return ret;
}
return ret;
}
}
@@ -18,7 +18,6 @@
package appeng.util.item;
import java.util.Objects;
import com.google.common.base.Preconditions;
@@ -33,32 +32,32 @@ final class AESharedItemStack {
private final int itemDamage;
private final int hashCode;
private final ItemStack itemStack;
private final int itemId;
private final int itemDamage;
private final int hashCode;
public AESharedItemStack(final ItemStack itemStack) {
this(itemStack, itemStack.getItemDamage());
}
public AESharedItemStack( final ItemStack itemStack )
{
this.itemStack = itemStack;
this.itemId = Item.getIdFromItem( itemStack.getItem() );
this.itemDamage = itemStack.getItemDamage();
this.hashCode = this.makeHashCode();
}
/**
* A constructor to explicitly set the damage value and not fetch it from the {@link ItemStack}
*
* @param itemStack The {@link ItemStack} to filter
* @param damage The damage of the item
*/
private AESharedItemStack(ItemStack itemStack, int damage) {
this.itemStack = itemStack;
this.itemId = Item.getIdFromItem(itemStack.getItem());
this.itemDamage = damage;
Bounds getBounds( final FuzzyMode fuzzy, final boolean ignoreMeta )
{
return new Bounds( this.itemStack, fuzzy, ignoreMeta );
}
// Ensure this is always called last.
this.hashCode = this.makeHashCode();
}
ItemStack getDefinition() {
return this.itemStack;
}
int getItemID()
{
return this.itemId;
}
int getItemDamage() {
return this.itemDamage;
}
@Override
public int hashCode() {
@@ -88,7 +87,7 @@ final class AESharedItemStack {
return Objects.hash(
this.itemId,
this.itemDamage,
this.itemStack.hasTag() ? this.itemStack.getTag() : 0);
this.itemStack.hasTagCompound() ? this.itemStack.getTagCompound() : 0);
}
}
+126 -143
View File
@@ -18,169 +18,152 @@
package appeng.util.item;
import appeng.api.storage.data.IAEStack;
import io.netty.buffer.ByteBuf;
import appeng.api.storage.data.IAEStack;
public abstract class AEStack<T extends IAEStack<T>> implements IAEStack<T> {
public abstract class AEStack<StackType extends IAEStack<StackType>> implements IAEStack<StackType>
{
private boolean isCraftable;
private long stackSize;
private long countRequestable;
private boolean isCraftable;
private long stackSize;
private long countRequestable;
@Override
public long getStackSize() {
return this.stackSize;
}
protected static long getPacketValue( final byte type, final ByteBuf tag )
{
if( type == 0 )
{
long l = tag.readByte();
l -= Byte.MIN_VALUE;
return l;
}
else if( type == 1 )
{
long l = tag.readShort();
l -= Short.MIN_VALUE;
return l;
}
else if( type == 2 )
{
long l = tag.readInt();
l -= Integer.MIN_VALUE;
return l;
}
@Override
public T setStackSize(final long ss) {
this.stackSize = ss;
return (T) this;
}
return tag.readLong();
}
@Override
public long getCountRequestable() {
return this.countRequestable;
}
@Override
public long getStackSize()
{
return this.stackSize;
}
@Override
public T setCountRequestable(final long countRequestable) {
this.countRequestable = countRequestable;
return (T) this;
}
@Override
public StackType setStackSize( final long ss )
{
this.stackSize = ss;
return (StackType) this;
}
@Override
public boolean isCraftable() {
return this.isCraftable;
}
@Override
public long getCountRequestable()
{
return this.countRequestable;
}
@Override
public T setCraftable(final boolean isCraftable) {
this.isCraftable = isCraftable;
return (T) this;
}
@Override
public StackType setCountRequestable( final long countRequestable )
{
this.countRequestable = countRequestable;
return (StackType) this;
}
@Override
public T reset() {
this.stackSize = 0;
this.setCountRequestable(0);
this.setCraftable(false);
return (T) this;
}
@Override
public boolean isCraftable()
{
return this.isCraftable;
}
@Override
public T empty() {
final T dup = this.copy();
dup.reset();
return dup;
}
@Override
public StackType setCraftable( final boolean isCraftable )
{
this.isCraftable = isCraftable;
return (StackType) this;
}
@Override
public boolean isMeaningful() {
return this.stackSize != 0 || this.countRequestable > 0 || this.isCraftable;
}
@Override
public StackType reset()
{
this.stackSize = 0;
// priority = Integer.MIN_VALUE;
this.setCountRequestable( 0 );
this.setCraftable( false );
return (StackType) this;
}
@Override
public void incStackSize(final long i) {
this.stackSize += i;
}
@Override
public StackType empty()
{
final StackType dup = this.copy();
dup.reset();
return dup;
}
@Override
public void decStackSize(final long i) {
this.stackSize -= i;
}
@Override
public boolean isMeaningful()
{
return this.stackSize != 0 || this.countRequestable > 0 || this.isCraftable;
}
@Override
public void incCountRequestable(final long i) {
this.countRequestable += i;
}
@Override
public void incStackSize( final long i )
{
this.stackSize += i;
}
@Override
public void decCountRequestable(final long i) {
this.countRequestable -= i;
}
@Override
public void decStackSize( final long i )
{
this.stackSize -= i;
}
protected abstract boolean hasTagCompound();
@Override
public void incCountRequestable( final long i )
{
this.countRequestable += i;
}
protected static long getPacketValue( final byte type, final ByteBuf tag )
{
if( type == 0 )
{
long l = tag.readByte();
l -= Byte.MIN_VALUE;
return l;
}
else if( type == 1 )
{
long l = tag.readShort();
l -= Short.MIN_VALUE;
return l;
}
else if( type == 2 )
{
long l = tag.readInt();
l -= Integer.MIN_VALUE;
return l;
}
@Override
public void decCountRequestable( final long i )
{
this.countRequestable -= i;
}
return tag.readLong();
}
protected byte getType( final long num )
{
if( num <= 255 )
{
return 0;
}
else if( num <= 65535 )
{
return 1;
}
else if( num <= 4294967295L )
{
return 2;
}
else
{
return 3;
}
}
protected void putPacketValue( final ByteBuf tag, final long num )
{
if( num <= 255 )
{
tag.writeByte( (byte) ( num + Byte.MIN_VALUE ) );
}
else if( num <= 65535 )
{
tag.writeShort( (short) ( num + Short.MIN_VALUE ) );
}
else if( num <= 4294967295L )
{
tag.writeInt( (int) ( num + Integer.MIN_VALUE ) );
}
else
{
tag.writeLong( num );
}
}
protected abstract boolean hasTagCompound();
protected void putPacketValue( final ByteBuf tag, final long num )
{
if( num <= 255 )
{
tag.writeByte( (byte) ( num + Byte.MIN_VALUE ) );
}
else if( num <= 65535 )
{
tag.writeShort( (short) ( num + Short.MIN_VALUE ) );
}
else if( num <= 4294967295L )
{
tag.writeInt( (int) ( num + Integer.MIN_VALUE ) );
}
else
{
tag.writeLong( num );
}
}
protected byte getType( final long num )
{
if( num <= 255 )
{
return 0;
}
else if( num <= 65535 )
{
return 1;
}
else if( num <= 4294967295L )
{
return 2;
}
else
{
return 3;
}
}
}
@@ -145,14 +145,14 @@ class FuzzyItemVariantList extends ItemVariantList {
* higher number than the upper bound.
*/
static ItemDamageBound makeLowerBound(final ItemStack stack, final FuzzyMode fuzzy) {
Preconditions.checkState(stack.isDamageable(), "ItemStack#isDamageable() has to be true");
Preconditions.checkState(((stack.getMaxDamage() == 0 && stack.getItemDamage() > 0 ) || stack.isItemStackDamageable()), "ItemStack#isDamageable() has to be true");
int damage;
if (fuzzy == FuzzyMode.IGNORE_ALL) {
damage = stack.getMaxDamage();
} else {
final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage());
damage = stack.getDamage() <= breakpoint ? breakpoint : stack.getMaxDamage();
damage = stack.getItemDamage() <= breakpoint ? breakpoint : stack.getMaxDamage();
}
return new ItemDamageBound(damage);
@@ -163,14 +163,14 @@ class FuzzyItemVariantList extends ItemVariantList {
* lower number than the lower bound. It also is exclusive.
*/
static ItemDamageBound makeUpperBound(final ItemStack stack, final FuzzyMode fuzzy) {
Preconditions.checkState(stack.isDamageable(), "ItemStack#isDamageable() has to be true");
Preconditions.checkState(((stack.getMaxDamage() == 0 && stack.getItemDamage() > 0 ) || stack.isItemStackDamageable()), "ItemStack#isDamageable() has to be true");
int damage;
if (fuzzy == FuzzyMode.IGNORE_ALL) {
damage = MIN_DAMAGE_VALUE;
} else {
final int breakpoint = fuzzy.calculateBreakPoint(stack.getMaxDamage());
damage = stack.getDamage() <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
damage = stack.getItemDamage() <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
}
return new ItemDamageBound(damage);
+38 -43
View File
@@ -1,6 +1,6 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
* Copyright (c) 2013 - 2020, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -18,8 +18,6 @@
package appeng.util.item;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
@@ -27,13 +25,16 @@ import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicInteger;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraft.item.Item;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.util.item.AESharedItemStack.Bounds;
public final class ItemList implements IItemList<IAEItemStack> {
private final Reference2ObjectMap<Item, ItemVariantList> records = new Reference2ObjectOpenHashMap<>();
/**
@@ -53,18 +54,20 @@ import appeng.util.item.AESharedItemStack.Bounds;
return record != null ? record.findPrecise(itemStack) : null;
}
if( st != null )
{
st.add( option );
return;
}
@Override
public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
if (filter == null) {
return Collections.emptyList();
}
ItemVariantList record = this.records.get(filter.getItem());
return record != null ? record.findFuzzy(filter, fuzzy) : Collections.emptyList();
}
this.putItemRecord( opt );
}
@Override
public boolean isEmpty() {
return !this.iterator().hasNext();
}
@Override
public void add(final IAEItemStack itemStack) {
@@ -74,8 +77,8 @@ import appeng.util.item.AESharedItemStack.Bounds;
return;
}
return this.records.get( ( (AEItemStack) itemStack ).getSharedStack() );
}
this.getOrCreateRecord(itemStack.getItem()).add(itemStack);
}
@Override
public void addStorage(final IAEItemStack itemStack) {
@@ -85,7 +88,8 @@ import appeng.util.item.AESharedItemStack.Bounds;
return;
}
final AEItemStack ais = (AEItemStack) filter;
this.getOrCreateRecord(itemStack.getItem()).addStorage(itemStack);
}
@Override
public void addCrafting(final IAEItemStack itemStack) {
@@ -95,11 +99,8 @@ import appeng.util.item.AESharedItemStack.Bounds;
return;
}
return this.findFuzzyDamage( is, fuzzy, is.getItemDamage() == OreDictionary.WILDCARD_VALUE );
}
else
{
final Collection<IAEItemStack> output = new ArrayList<>();
this.getOrCreateRecord(itemStack.getItem()).addCrafting(itemStack);
}
@Override
public void addRequestable(final IAEItemStack itemStack) {
@@ -109,24 +110,17 @@ import appeng.util.item.AESharedItemStack.Bounds;
return;
}
return output;
}
} ).orElse( this.findFuzzyDamage( ais, fuzzy, false ) );
}
this.getOrCreateRecord(itemStack.getItem()).addRequestable(itemStack);
}
@Override
public boolean isEmpty()
{
return !this.iterator().hasNext();
}
@Override
public IAEItemStack getFirstItem() {
for (final IAEItemStack stackType : this) {
return stackType;
}
@Override
public void addStorage( final IAEItemStack option )
{
if( option == null )
{
return;
}
return null;
}
@Override
public int size() {
@@ -135,19 +129,20 @@ import appeng.util.item.AESharedItemStack.Bounds;
size += entry.size();
}
if( st != null )
{
st.incStackSize( option.getStackSize() );
return;
}
return size;
}
@Override
public Iterator<IAEItemStack> iterator() {
return new ChainedIterator(this.records.values().iterator(), version);
}
this.putItemRecord( opt );
}
@Override
public void resetStatus() {
for (final IAEItemStack i : this) {
i.reset();
}
}
private ItemVariantList getOrCreateRecord(Item item) {
return this.records.computeIfAbsent(item, this::makeRecordMap);
@@ -43,13 +43,11 @@ public class MeaningfulItemIterator<T extends IAEItemStack> implements Iterator<
return this.next != null;
}
@Override
public T next()
{
if( this.next == null )
{
throw new NoSuchElementException();
}
@Override
public T next() {
if (this.next == null) {
throw new NoSuchElementException();
}
T result = this.next;
this.next = this.seekNext();