/* * This file is part of Project-Zed. Project-Zed is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Project-Zed 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 General Public License for more details. You should have received a copy of the GNU General Public License along * with Project-Zed. If not, see <http://www.gnu.org/licenses/> * */ package com.projectzed.mod.handler.message; import com.hockeyhurd.hcorelib.api.math.Vector3; import com.hockeyhurd.hcorelib.api.math.VectorHelper; import com.hockeyhurd.hcorelib.api.util.StringUtils; import com.projectzed.api.fluid.container.IFluidContainer; import com.projectzed.mod.tileentity.container.TileEntityRefinery; import io.netty.buffer.ByteBuf; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import java.util.ArrayList; import java.util.List; /** * TileEntityRefinery message handler for packets. * * @author hockeyhurd * @version 8/10/2015. */ public class MessageTileEntityRefinery implements IMessage, IMessageHandler<MessageTileEntityRefinery, IMessage> { private TileEntityRefinery te; private Vector3<Integer> vec; private List<TankData> tanks; private int numTanks; private int storedPower; private boolean powerMode; private EnumFacing facing; @Deprecated public MessageTileEntityRefinery() { vec = Vector3.zero.getVector3i(); } public MessageTileEntityRefinery(TileEntityRefinery te) { this.te = te; this.vec = te.worldVec(); numTanks = te.getNumTanks(); powerMode = te.isPowered(); storedPower = te.getEnergyStored(); facing = te.getCurrentFacing(); tanks = new ArrayList<TankData>(numTanks); FluidTank current; for (int i = 0; i < numTanks; i++) { current = te.getTank(i); if (current == null || current.getFluid() == null) tanks.add(new TankData(i, null, 0)); else tanks.add(new TankData(i, current.getFluid().getFluid().getName(), current.getFluidAmount())); } } @Override public void fromBytes(ByteBuf buf) { this.vec.x = buf.readInt(); this.vec.y = buf.readInt(); this.vec.z = buf.readInt(); this.numTanks = buf.readInt(); this.storedPower = buf.readInt(); this.powerMode = buf.readBoolean(); this.facing = EnumFacing.getFront(buf.readInt()); if (this.numTanks == 0) return; // no need to continue if we have no tanks! if (tanks == null) tanks = new ArrayList<TankData>(this.numTanks); for (int i = 0; i < this.numTanks; i++) { tanks.add(TankData.readFromTankData(buf)); } } @Override public void toBytes(ByteBuf buf) { buf.writeInt(vec.x); buf.writeInt(vec.y); buf.writeInt(vec.z); buf.writeInt(numTanks); buf.writeInt(storedPower); buf.writeBoolean(powerMode); buf.writeInt(facing.ordinal()); if (tanks != null && !tanks.isEmpty()) { for (TankData data : tanks) { // ProjectZed.logHelper.info(data.toString()); data.writeTankData(buf); } } } @Override public IMessage onMessage(MessageTileEntityRefinery message, MessageContext ctx) { TileEntity tileEntity = FMLClientHandler.instance().getClient().theWorld.getTileEntity(VectorHelper.toBlockPos(message.vec)); if (tileEntity != null && tileEntity instanceof TileEntityRefinery) { TileEntityRefinery te = (TileEntityRefinery) tileEntity; te.setEnergyStored(message.storedPower); te.setPowered(message.powerMode); te.setFrontFacing(message.facing); if (message.tanks != null && !message.tanks.isEmpty()) { FluidStack fluidStack; for (TankData data : message.tanks) { fluidStack = data.getFluidStack(); // if (fluidStack != null && fluidStack.getFluid() != null) ProjectZed.logHelper.info(data.tankID, fluidStack.getUnlocalizedName()); te.getTank(data.tankID).setFluid(fluidStack); } } } return null; } /** * Small helper class for storing TankData more effectively. * * @author hockeyhurd * @version 8/10/2015 */ private static final class TankData { int tankID, fluidAmount; int fluidIDLen; String fluidID; private TankData() { } TankData(int tankID, String fluidID, int fluidAmount) { this.tankID = tankID; this.fluidID = fluidID; this.fluidIDLen = fluidID != null && !fluidID.isEmpty() ? fluidID.length() : -1; this.fluidAmount = fluidAmount; } FluidTank generateFluidTank(IFluidContainer cont) { final FluidTank fluidTank = new FluidTank(cont.getTank().getCapacity()); if (StringUtils.nullCheckString(fluidID) && fluidAmount > 0) fluidTank.setFluid(new FluidStack(FluidRegistry.getFluid(fluidID), fluidAmount)); return fluidTank; } FluidStack getFluidStack() { return StringUtils.nullCheckString(fluidID) && fluidAmount > 0 ? new FluidStack(FluidRegistry.getFluid(fluidID), fluidAmount) : null; } void writeTankData(ByteBuf buf) { buf.writeInt(tankID); buf.writeInt(fluidIDLen); if (fluidIDLen > 0) { for (char c : fluidID.toCharArray()) buf.writeChar(c); } buf.writeInt(fluidAmount); } static TankData readFromTankData(ByteBuf buf) { // TankData ret = new TankData(); // ret.tankID = buf.readInt(); // ret.fluidID = buf.readInt(); // ret.fluidAmount = buf.readInt(); int tankID = buf.readInt(); int fluidIDLen = buf.readInt(); String fluidID; if (fluidIDLen > 0) { char[] arr = new char[fluidIDLen]; for (int i = 0; i < fluidIDLen; i++) arr[i] = buf.readChar(); fluidID = new String(arr); } else fluidID = "<empty>"; int fluidAmount = buf.readInt(); return new TankData(tankID, fluidID, fluidAmount); } @Override public String toString() { return String.format("tankID: %d, fluidID: %d, fluidAmount: %d", tankID, fluidID, fluidAmount); } } }