package openmods.sync;
import com.google.common.io.ByteStreams;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import openmods.api.IValueProvider;
import openmods.liquids.GenericTank;
import openmods.utils.ByteUtils;
public class SyncableTank extends GenericTank implements ISyncableObject, IValueProvider<FluidStack> {
private boolean dirty = false;
public SyncableTank(int capacity) {
super(capacity);
}
public SyncableTank(int capacity, Fluid... acceptableFluids) {
super(capacity, acceptableFluids);
}
public SyncableTank(int capacity, FluidStack... acceptableFluids) {
super(capacity, acceptableFluids);
}
@Override
public boolean isDirty() {
return dirty;
}
@Override
public void markClean() {
dirty = false;
}
@Override
public void markDirty() {
dirty = true;
}
@Override
public void readFromStream(DataInputStream stream) throws IOException {
if (stream.readBoolean()) {
int fluidId = ByteUtils.readVLI(stream);
Fluid fluid = FluidRegistry.getFluid(fluidId);
int fluidAmount = stream.readInt();
this.fluid = new FluidStack(fluid, fluidAmount);
final int tagSize = ByteUtils.readVLI(stream);
if (tagSize > 0) {
this.fluid.tag = CompressedStreamTools.readCompressed(ByteStreams.limit(stream, tagSize));
}
} else {
this.fluid = null;
}
}
@Override
public void writeToStream(DataOutputStream stream) throws IOException {
if (fluid != null) {
stream.writeBoolean(true);
ByteUtils.writeVLI(stream, fluid.getFluidID());
stream.writeInt(fluid.amount);
if (fluid.tag != null) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
CompressedStreamTools.writeCompressed(fluid.tag, buffer);
byte[] bytes = buffer.toByteArray();
ByteUtils.writeVLI(stream, bytes.length);
stream.write(bytes);
} else {
stream.writeByte(0);
}
} else {
stream.writeBoolean(false);
}
}
@Override
public void writeToNBT(NBTTagCompound tag, String name) {
final NBTTagCompound tankTag = new NBTTagCompound();
this.writeToNBT(tankTag);
tag.setTag(name, tankTag);
}
@Override
public void readFromNBT(NBTTagCompound tag, String name) {
if (tag.hasKey(name, Constants.NBT.TAG_COMPOUND)) {
final NBTTagCompound tankTag = tag.getCompoundTag(name);
this.readFromNBT(tankTag);
} else {
// For legacy worlds - tag was saved in wrong place due to bug
this.readFromNBT(tag);
}
}
@Override
public int fill(FluidStack resource, boolean doFill) {
int filled = super.fill(resource, doFill);
if (doFill && filled > 0) markDirty();
return filled;
}
@Override
public FluidStack drain(FluidStack stack, boolean doDrain) {
FluidStack drained = super.drain(stack, doDrain);
if (doDrain && drained != null) markDirty();
return drained;
}
@Override
public FluidStack drain(int maxDrain, boolean doDrain) {
FluidStack drained = super.drain(maxDrain, doDrain);
if (doDrain && drained != null) markDirty();
return drained;
}
@Override
public FluidStack getValue() {
FluidStack stack = super.getFluid();
return stack != null? stack.copy() : null;
}
}