    001package net.minecraft.network.packet;
    002
    003import java.io.ByteArrayOutputStream;
    004import java.io.DataInputStream;
    005import java.io.DataOutputStream;
    006import java.io.IOException;
    007import net.minecraft.world.World;
    008import net.minecraft.world.chunk.Chunk;
    009import net.minecraftforge.common.ForgeDummyContainer;
    010import net.minecraftforge.common.MinecraftForge;
    011
    012public class Packet52MultiBlockChange extends Packet
    013{
    014    /** Chunk X position. */
    015    public int xPosition;
    016
    017    /** Chunk Z position. */
    018    public int zPosition;
    019
    020    /** The metadata for each block changed. */
    021    public byte[] metadataArray;
    022
    023    /** The size of the arrays. */
    024    public int size;
    025    private static byte[] field_73449_e = new byte[0];
    026
    027    public Packet52MultiBlockChange()
    028    {
    029        this.isChunkDataPacket = true;
    030    }
    031
    032    public Packet52MultiBlockChange(int par1, int par2, short[] par3ArrayOfShort, int par4, World par5World)
    033    {
    034        this.isChunkDataPacket = true;
    035        this.xPosition = par1;
    036        this.zPosition = par2;
    037        this.size = par4;
    038        int l = 4 * par4;
    039        Chunk chunk = par5World.getChunkFromChunkCoords(par1, par2);
    040
    041        try
    042        {
    043            if (par4 >= ForgeDummyContainer.clumpingThreshold)
    044            {
    045                if (field_73449_e.length < l)
    046                {
    047                    field_73449_e = new byte[l];
    048                }
    049            }
    050            else
    051            {
    052                ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(l);
    053                DataOutputStream dataoutputstream = new DataOutputStream(bytearrayoutputstream);
    054
    055                for (int i1 = 0; i1 < par4; ++i1)
    056                {
    057                    int j1 = par3ArrayOfShort[i1] >> 12 & 15;
    058                    int k1 = par3ArrayOfShort[i1] >> 8 & 15;
    059                    int l1 = par3ArrayOfShort[i1] & 255;
    060                    dataoutputstream.writeShort(par3ArrayOfShort[i1]);
    061                    dataoutputstream.writeShort((short)((chunk.getBlockID(j1, l1, k1) & 4095) << 4 | chunk.getBlockMetadata(j1, l1, k1) & 15));
    062                }
    063
    064                this.metadataArray = bytearrayoutputstream.toByteArray();
    065
    066                if (this.metadataArray.length != l)
    067                {
    068                    throw new RuntimeException("Expected length " + l + " doesn\'t match received length " + this.metadataArray.length);
    069                }
    070            }
    071        }
    072        catch (IOException ioexception)
    073        {
    074            this.field_98193_m.logSevereException("Couldn\'t create chunk packet", ioexception);
    075            this.metadataArray = null;
    076        }
    077    }
    078
    079    /**
    080     * Abstract. Reads the raw packet data from the data stream.
    081     */
    082    public void readPacketData(DataInputStream par1DataInputStream) throws IOException
    083    {
    084        this.xPosition = par1DataInputStream.readInt();
    085        this.zPosition = par1DataInputStream.readInt();
    086        this.size = par1DataInputStream.readShort() & 65535;
    087        int i = par1DataInputStream.readInt();
    088
    089        if (i > 0)
    090        {
    091            this.metadataArray = new byte[i];
    092            par1DataInputStream.readFully(this.metadataArray);
    093        }
    094    }
    095
    096    /**
    097     * Abstract. Writes the raw packet data to the data stream.
    098     */
    099    public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
    100    {
    101        par1DataOutputStream.writeInt(this.xPosition);
    102        par1DataOutputStream.writeInt(this.zPosition);
    103        par1DataOutputStream.writeShort((short)this.size);
    104
    105        if (this.metadataArray != null)
    106        {
    107            par1DataOutputStream.writeInt(this.metadataArray.length);
    108            par1DataOutputStream.write(this.metadataArray);
    109        }
    110        else
    111        {
    112            par1DataOutputStream.writeInt(0);
    113        }
    114    }
    115
    116    /**
    117     * Passes this Packet on to the NetHandler for processing.
    118     */
    119    public void processPacket(NetHandler par1NetHandler)
    120    {
    121        par1NetHandler.handleMultiBlockChange(this);
    122    }
    123
    124    /**
    125     * Abstract. Return the size of the packet (not counting the header).
    126     */
    127    public int getPacketSize()
    128    {
    129        return 10 + this.size * 4;
    130    }
    131}