Initial Fluid Integration (#3510)
* Added Fluid Storage Cells * Added Fluid Import Bus * Added Fluid Export Bus * Added Fluid Storage Bus * Added Fluid Terminal. While holding a item with the FLUID_HANDLER_ITEM_CAPABILITY, such as a tank Left click on a fluid to extract the fluid Right click to insert the fluid
This commit is contained in:
@@ -36,6 +36,7 @@ import appeng.core.sync.packets.PacketCraftRequest;
|
||||
import appeng.core.sync.packets.PacketInventoryAction;
|
||||
import appeng.core.sync.packets.PacketJEIRecipe;
|
||||
import appeng.core.sync.packets.PacketLightning;
|
||||
import appeng.core.sync.packets.PacketMEFluidInventoryUpdate;
|
||||
import appeng.core.sync.packets.PacketMEInventoryUpdate;
|
||||
import appeng.core.sync.packets.PacketMatterCannon;
|
||||
import appeng.core.sync.packets.PacketMockExplosion;
|
||||
@@ -45,6 +46,7 @@ import appeng.core.sync.packets.PacketPatternSlot;
|
||||
import appeng.core.sync.packets.PacketProgressBar;
|
||||
import appeng.core.sync.packets.PacketSwapSlots;
|
||||
import appeng.core.sync.packets.PacketSwitchGuis;
|
||||
import appeng.core.sync.packets.PacketTargetFluidStack;
|
||||
import appeng.core.sync.packets.PacketTargetItemStack;
|
||||
import appeng.core.sync.packets.PacketTransitionEffect;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
@@ -64,6 +66,8 @@ public class AppEngPacketHandlerBase
|
||||
|
||||
PACKET_ME_INVENTORY_UPDATE( PacketMEInventoryUpdate.class ),
|
||||
|
||||
PACKET_ME_FLUID_INVENTORY_UPDATE( PacketMEFluidInventoryUpdate.class ),
|
||||
|
||||
PACKET_CONFIG_BUTTON( PacketConfigButton.class ),
|
||||
|
||||
PACKET_PART_PLACEMENT( PacketPartPlacement.class ),
|
||||
@@ -92,6 +96,8 @@ public class AppEngPacketHandlerBase
|
||||
|
||||
PACKET_TARGET_ITEM( PacketTargetItemStack.class ),
|
||||
|
||||
PACKET_TARGET_FLUID( PacketTargetFluidStack.class ),
|
||||
|
||||
PACKET_CRAFTING_REQUEST( PacketCraftRequest.class ),
|
||||
|
||||
PACKET_ASSEMBLER_ANIMATION( PacketAssemblerAnimation.class ),
|
||||
|
||||
@@ -62,6 +62,9 @@ import appeng.container.implementations.ContainerCraftingCPU;
|
||||
import appeng.container.implementations.ContainerCraftingStatus;
|
||||
import appeng.container.implementations.ContainerCraftingTerm;
|
||||
import appeng.container.implementations.ContainerDrive;
|
||||
import appeng.container.implementations.ContainerFluidIO;
|
||||
import appeng.container.implementations.ContainerFluidStorageBus;
|
||||
import appeng.container.implementations.ContainerFluidTerminal;
|
||||
import appeng.container.implementations.ContainerFormationPlane;
|
||||
import appeng.container.implementations.ContainerGrinder;
|
||||
import appeng.container.implementations.ContainerIOPort;
|
||||
@@ -86,6 +89,8 @@ import appeng.container.implementations.ContainerUpgradeable;
|
||||
import appeng.container.implementations.ContainerVibrationChamber;
|
||||
import appeng.container.implementations.ContainerWireless;
|
||||
import appeng.container.implementations.ContainerWirelessTerm;
|
||||
import appeng.fluids.parts.PartFluidStorageBus;
|
||||
import appeng.fluids.parts.PartSharedFluidBus;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.helpers.WirelessTerminalGuiObject;
|
||||
@@ -94,6 +99,7 @@ import appeng.parts.automation.PartFormationPlane;
|
||||
import appeng.parts.automation.PartLevelEmitter;
|
||||
import appeng.parts.misc.PartStorageBus;
|
||||
import appeng.parts.reporting.PartCraftingTerminal;
|
||||
import appeng.parts.reporting.PartFluidTerminal;
|
||||
import appeng.parts.reporting.PartInterfaceTerminal;
|
||||
import appeng.parts.reporting.PartPatternTerminal;
|
||||
import appeng.tile.crafting.TileCraftingTile;
|
||||
@@ -152,10 +158,14 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_BUS( ContainerUpgradeable.class, IUpgradeableHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_BUS_FLUID( ContainerFluidIO.class, PartSharedFluidBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_IOPORT( ContainerIOPort.class, TileIOPort.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
GUI_PRIORITY( ContainerPriority.class, IPriorityHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
@@ -166,6 +176,8 @@ public enum GuiBridge implements IGuiHandler
|
||||
|
||||
GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
|
||||
|
||||
GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, PartFluidTerminal.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
// extends (Container/Gui) + Bus
|
||||
GUI_LEVEL_EMITTER( ContainerLevelEmitter.class, PartLevelEmitter.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
|
||||
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2018, 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.core.sync.packets;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.client.gui.implementations.GuiFluidTerminal;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.util.item.AEFluidStack;
|
||||
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 22/05/2018
|
||||
* @since rv6 22/05/2018
|
||||
*/
|
||||
public class PacketMEFluidInventoryUpdate extends AppEngPacket
|
||||
{
|
||||
private static final int UNCOMPRESSED_PACKET_BYTE_LIMIT = 16 * 1024 * 1024;
|
||||
private static final int OPERATION_BYTE_LIMIT = 2 * 1024;
|
||||
private static final int TEMP_BUFFER_SIZE = 1024;
|
||||
private static final int STREAM_MASK = 0xff;
|
||||
|
||||
// input.
|
||||
@Nullable
|
||||
private final List<IAEFluidStack> list;
|
||||
// output...
|
||||
private final byte ref;
|
||||
|
||||
@Nullable
|
||||
private final ByteBuf data;
|
||||
@Nullable
|
||||
private final GZIPOutputStream compressFrame;
|
||||
|
||||
private int writtenBytes = 0;
|
||||
private boolean empty = true;
|
||||
|
||||
// automatic.
|
||||
public PacketMEFluidInventoryUpdate( final ByteBuf stream ) throws IOException
|
||||
{
|
||||
this.data = null;
|
||||
this.compressFrame = null;
|
||||
this.list = new LinkedList<>();
|
||||
this.ref = stream.readByte();
|
||||
|
||||
// int originalBytes = stream.readableBytes();
|
||||
|
||||
final GZIPInputStream gzReader = new GZIPInputStream( new InputStream()
|
||||
{
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
if( stream.readableBytes() <= 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return stream.readByte() & STREAM_MASK;
|
||||
}
|
||||
} );
|
||||
|
||||
final ByteBuf uncompressed = Unpooled.buffer( stream.readableBytes() );
|
||||
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
|
||||
while( gzReader.available() != 0 )
|
||||
{
|
||||
final int bytes = gzReader.read( tmp );
|
||||
if( bytes > 0 )
|
||||
{
|
||||
uncompressed.writeBytes( tmp, 0, bytes );
|
||||
}
|
||||
}
|
||||
gzReader.close();
|
||||
|
||||
// int uncompressedBytes = uncompressed.readableBytes();
|
||||
// AELog.info( "Receiver: " + originalBytes + " -> " + uncompressedBytes );
|
||||
|
||||
while( uncompressed.readableBytes() > 0 )
|
||||
{
|
||||
this.list.add( AEFluidStack.fromPacket( uncompressed ) );
|
||||
}
|
||||
|
||||
this.empty = this.list.isEmpty();
|
||||
}
|
||||
|
||||
// api
|
||||
public PacketMEFluidInventoryUpdate() throws IOException
|
||||
{
|
||||
this( (byte) 0 );
|
||||
}
|
||||
|
||||
// api
|
||||
public PacketMEFluidInventoryUpdate( final byte ref ) throws IOException
|
||||
{
|
||||
this.ref = ref;
|
||||
this.data = Unpooled.buffer( OPERATION_BYTE_LIMIT );
|
||||
this.data.writeInt( this.getPacketID() );
|
||||
this.data.writeByte( this.ref );
|
||||
|
||||
this.compressFrame = new GZIPOutputStream( new OutputStream()
|
||||
{
|
||||
@Override
|
||||
public void write( final int value ) throws IOException
|
||||
{
|
||||
PacketMEFluidInventoryUpdate.this.data.writeByte( value );
|
||||
}
|
||||
} );
|
||||
|
||||
this.list = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
public void clientPacketData( final INetworkInfo network, final AppEngPacket packet, final EntityPlayer player )
|
||||
{
|
||||
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
|
||||
|
||||
if( gs instanceof GuiFluidTerminal )
|
||||
{
|
||||
( (GuiFluidTerminal) gs ).postUpdate( this.list );
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FMLProxyPacket getProxy()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.compressFrame.close();
|
||||
|
||||
this.configureWrite( this.data );
|
||||
return super.getProxy();
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void appendFluid( final IAEFluidStack fs ) throws IOException, BufferOverflowException
|
||||
{
|
||||
final ByteBuf tmp = Unpooled.buffer( OPERATION_BYTE_LIMIT );
|
||||
fs.writeToPacket( tmp );
|
||||
|
||||
this.compressFrame.flush();
|
||||
if( this.writtenBytes + tmp.readableBytes() > UNCOMPRESSED_PACKET_BYTE_LIMIT )
|
||||
{
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.writtenBytes += tmp.readableBytes();
|
||||
this.compressFrame.write( tmp.array(), 0, tmp.readableBytes() );
|
||||
this.empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLength()
|
||||
{
|
||||
return this.data.readableBytes();
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return this.empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2018, 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.core.sync.packets;
|
||||
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import appeng.container.implementations.ContainerFluidTerminal;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.util.item.AEFluidStack;
|
||||
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 23/05/2018
|
||||
* @since rv6 23/05/2018
|
||||
*/
|
||||
public class PacketTargetFluidStack extends AppEngPacket
|
||||
{
|
||||
private AEFluidStack stack;
|
||||
|
||||
// automatic.
|
||||
public PacketTargetFluidStack( final ByteBuf stream )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( stream.readableBytes() > 0 )
|
||||
{
|
||||
this.stack = (AEFluidStack) AEFluidStack.fromPacket( stream );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.stack = null;
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
AELog.debug( ex );
|
||||
this.stack = null;
|
||||
}
|
||||
}
|
||||
|
||||
// api
|
||||
public PacketTargetFluidStack( AEFluidStack stack )
|
||||
{
|
||||
|
||||
this.stack = stack;
|
||||
|
||||
final ByteBuf data = Unpooled.buffer();
|
||||
data.writeInt( this.getPacketID() );
|
||||
if( stack != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
stack.writeToPacket( data );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
AELog.debug( ex );
|
||||
}
|
||||
}
|
||||
this.configureWrite( data );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverPacketData( final INetworkInfo manager, final AppEngPacket packet, final EntityPlayer player )
|
||||
{
|
||||
if( player.openContainer instanceof ContainerFluidTerminal )
|
||||
{
|
||||
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ import appeng.container.implementations.ContainerCellWorkbench;
|
||||
import appeng.container.implementations.ContainerCraftConfirm;
|
||||
import appeng.container.implementations.ContainerCraftingCPU;
|
||||
import appeng.container.implementations.ContainerCraftingStatus;
|
||||
import appeng.container.implementations.ContainerFluidStorageBus;
|
||||
import appeng.container.implementations.ContainerLevelEmitter;
|
||||
import appeng.container.implementations.ContainerNetworkTool;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
@@ -179,18 +180,31 @@ public class PacketValueConfig extends AppEngPacket
|
||||
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
|
||||
}
|
||||
}
|
||||
else if( this.Name.startsWith( "StorageBus." ) && c instanceof ContainerStorageBus )
|
||||
else if( this.Name.startsWith( "StorageBus." ) )
|
||||
{
|
||||
final ContainerStorageBus ccw = (ContainerStorageBus) c;
|
||||
if( this.Name.equals( "StorageBus.Action" ) )
|
||||
{
|
||||
if( this.Value.equals( "Partition" ) )
|
||||
{
|
||||
ccw.partition();
|
||||
if( c instanceof ContainerStorageBus )
|
||||
{
|
||||
( (ContainerStorageBus) c ).partition();
|
||||
}
|
||||
else if( c instanceof ContainerFluidStorageBus )
|
||||
{
|
||||
( (ContainerFluidStorageBus) c ).partition();
|
||||
}
|
||||
}
|
||||
else if( this.Value.equals( "Clear" ) )
|
||||
{
|
||||
ccw.clear();
|
||||
if( c instanceof ContainerStorageBus )
|
||||
{
|
||||
( (ContainerStorageBus) c ).clear();
|
||||
}
|
||||
else if( c instanceof ContainerFluidStorageBus )
|
||||
{
|
||||
( (ContainerFluidStorageBus) c ).clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user