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.func_98234_c("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}