198 lines
6.3 KiB
Java
198 lines
6.3 KiB
Java
/*
|
|
* 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.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 appeng.api.storage.data.IAEItemStack;
|
|
import appeng.client.gui.implementations.GuiController;
|
|
import appeng.client.gui.implementations.GuiCraftConfirm;
|
|
import appeng.client.gui.implementations.GuiCraftingCPU;
|
|
import appeng.client.gui.implementations.GuiMEMonitorable;
|
|
import appeng.client.gui.implementations.GuiNetworkStatus;
|
|
import appeng.core.AELog;
|
|
import appeng.core.sync.AppEngPacket;
|
|
import appeng.core.sync.network.INetworkInfo;
|
|
import appeng.util.item.AEItemStack;
|
|
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
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;
|
|
|
|
public class PacketMEInventoryUpdate 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<IAEItemStack> 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 PacketMEInventoryUpdate(final ByteBuf stream) throws IOException {
|
|
this.data = null;
|
|
this.compressFrame = null;
|
|
this.list = new LinkedList<IAEItemStack>();
|
|
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(AEItemStack.loadItemStackFromPacket(uncompressed));
|
|
}
|
|
|
|
this.empty = this.list.isEmpty();
|
|
}
|
|
|
|
// api
|
|
public PacketMEInventoryUpdate() throws IOException {
|
|
this((byte) 0);
|
|
}
|
|
|
|
// api
|
|
public PacketMEInventoryUpdate(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 {
|
|
PacketMEInventoryUpdate.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 GuiCraftConfirm) {
|
|
((GuiCraftConfirm) gs).postUpdate(this.list, this.ref);
|
|
}
|
|
|
|
if (gs instanceof GuiCraftingCPU) {
|
|
((GuiCraftingCPU) gs).postUpdate(this.list, this.ref);
|
|
}
|
|
|
|
if (gs instanceof GuiMEMonitorable) {
|
|
((GuiMEMonitorable) gs).postUpdate(this.list);
|
|
}
|
|
|
|
if (gs instanceof GuiNetworkStatus) {
|
|
((GuiNetworkStatus) gs).postUpdate(this.list);
|
|
}
|
|
|
|
if (gs instanceof GuiController) {
|
|
((GuiController) 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 appendItem(final IAEItemStack is)
|
|
throws IOException, BufferOverflowException {
|
|
final ByteBuf tmp = Unpooled.buffer(OPERATION_BYTE_LIMIT);
|
|
is.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;
|
|
}
|
|
}
|