protected void SendMessage(byte PlayerID, string message)
        {
            packet pa = new packet();

            for (int i = 0; i < 10; i++) {
                message = message.Replace("%" + i, "&" + i);
                message = message.Replace("&" + i + " &", "&");
            }
            for (char ch = 'a'; ch <= 'f'; ch++) {
                message = message.Replace("%" + ch, "&" + ch);
                message = message.Replace("&" + ch + " &", "&");
            }
            message = Server.DefaultColor + message;

            pa.Add(packet.types.Message);
            pa.Add(PlayerID);

            try {
                foreach (string line in LineWrapping(message)) {
                    if (pa.bytes.Length < 64)
                        pa.Add(line, 64);
                    else
                        pa.Set(2, line, 64);

                    SendPacket(pa);
                }
            }
            catch (Exception e) {
                Logger.LogError(e);
            }
        }
        protected void UpdatePosition(bool ForceTp)
        {
            byte changed = 0;   //Denotes what has changed (x,y,z, rotation-x, rotation-y)

            Vector3 tempOldPos = oldPos;
            Vector3 tempPos = Pos;
            byte[] tempRot = Rot;
            byte[] tempOldRot = oldRot;

            oldPos = Pos;
            oldRot = Rot;

            int diffX = tempPos.x - tempOldPos.x;
            int diffZ = tempPos.z - tempOldPos.z;
            int diffY = tempPos.y - tempOldPos.y;
            int diffR0 = tempRot[0] - tempRot[0];
            int diffR1 = tempRot[1] - tempRot[1];

            if (ForceTp)
                changed = 4;
            else {
                //TODO rewrite local pos change code
                if (diffX == 0 && diffY == 0 && diffZ == 0 && diffR0 == 0 && diffR1 == 0) {
                    return; //No changes
                }
                if (Math.Abs(diffX) > 100 || Math.Abs(diffY) > 100 || Math.Abs(diffZ) > 100) {
                    changed = 4; //Teleport Required
                }
                else if (diffR0 == 0 && diffR1 == 0) {
                    changed = 1; //Pos Update Required
                }
                else {
                    changed += 2; //Rot Update Required

                    if (diffX != 0 || diffY != 0 || diffZ != 0) {
                        changed += 1;
                    }
                }
            }

            packet pa = new packet();

            switch (changed) {
                case 1: //Pos Change
                    pa.Add(packet.types.SendPosChange);
                    pa.Add(id);
                    pa.Add((sbyte)(diffX));
                    pa.Add((sbyte)(diffY));
                    pa.Add((sbyte)(diffZ));
                    break;
                case 2: //Rot Change
                    pa.Add(packet.types.SendRotChange);
                    pa.Add(id);
                    pa.Add(new byte[2] { (byte)diffR0, (byte)diffR1 });
                    break;
                case 3: //Pos AND Rot Change
                    pa.Add(packet.types.SendPosANDRotChange);
                    pa.Add(id);
                    pa.Add(diffX);
                    pa.Add(diffY);
                    pa.Add(diffZ);
                    pa.Add(new byte[2] { (byte)diffR0, (byte)diffR1 });
                    break;
                case 4: //Teleport Required
                    pa.Add(packet.types.SendTeleport);
                    pa.Add(id);
                    pa.Add(tempPos.x);
                    pa.Add(tempPos.y);
                    pa.Add(tempPos.z);
                    pa.Add(Rot);
                    break;
            }

            Server.ForeachPlayer(delegate(Player p) {
                if (p != this && p.Level == Level && p.IsLoggedIn && !p.IsLoading) {
                    p.SendPacket(pa);
                }
            });
        }
 protected void SendKick(string message)
 {
     packet pa = new packet();
     pa.Add(packet.types.SendKick);
     pa.Add(message, 64);
     SendPacket(pa);
 }
        protected void SendMap()
        {
            try {
                SendPacket(mapSendStartPacket); //Send the pre-fab map start packet

                packet pa = new packet(); //Create a packet to handle the data for the map
                pa.Add(Level.TotalBlocks); //Add the total amount of blocks to the packet
                byte[] blocks = new byte[Level.TotalBlocks]; //Temporary byte array so we dont have to keep modding the packet array

                byte block; //A block byte outside the loop, we save cycles by not making this for every loop iteration
                Level.ForEachBlock(pos => {
                    //Here we loop through the whole map and check/convert the blocks as necesary
                    //We then add them to our blocks array so we can send them to the player
                    block = Level.Data[pos];
                    //TODO ADD CHECKING
                    blocks[pos] = block;
                });

                pa.Add(blocks); //add the blocks to the packet
                pa.GZip(); //GZip the packet

                int number = (int)Math.Ceiling(((double)(pa.bytes.Length)) / 1024); //The magic number for this packet

                for (int i = 1; pa.bytes.Length > 0; ++i) {
                    short length = (short)Math.Min(pa.bytes.Length, 1024);
                    byte[] send = new byte[1027];
                    packet.HTNO(length).CopyTo(send, 0);
                    Buffer.BlockCopy(pa.bytes, 0, send, 2, length);
                    byte[] tempbuffer = new byte[pa.bytes.Length - length];
                    Buffer.BlockCopy(pa.bytes, length, tempbuffer, 0, pa.bytes.Length - length);
                    pa.bytes = tempbuffer;
                    send[1026] = (byte)(i * 100 / number);

                    packet Send = new packet(send);
                    Send.AddStart(new byte[1] { (byte)packet.types.MapData });

                    SendPacket(Send);
                }

                pa = new packet();
                pa.Add(packet.types.MapEnd);
                pa.Add((short)Level.Size.x);
                pa.Add((short)Level.Size.y);
                pa.Add((short)Level.Size.z);
                SendPacket(pa);

                IsLoading = false;
            }
            catch (Exception e) {
                Logger.LogError(e);
            }
        }
        /// <summary>
        /// Sends the specified player to the specified coordinates.
        /// </summary>
        /// <param name="_pos"></param>Vector3 coordinate to send to.
        /// <param name="_rot"></param>Rot to send to.
        public void SendToPos(Vector3 _pos, byte[] _rot)
        {
            oldPos = Pos; oldRot = Rot;
            _pos.x = (_pos.x < 0) ? (short)32 : (_pos.x > Level.Size.x * 32) ? (short)(Level.Size.x * 32 - 32) : (_pos.x > 32767) ? (short)32730 : _pos.x;
            _pos.z = (_pos.z < 0) ? (short)32 : (_pos.z > Level.Size.z * 32) ? (short)(Level.Size.z * 32 - 32) : (_pos.z > 32767) ? (short)32730 : _pos.z;
            _pos.y = (_pos.y < 0) ? (short)32 : (_pos.y > Level.Size.y * 32) ? (short)(Level.Size.y * 32 - 32) : (_pos.y > 32767) ? (short)32730 : _pos.y;

            packet pa = new packet();
            pa.Add(packet.types.SendTeleport);
            pa.Add(unchecked((byte)-1)); //If the ID is not greater than one it doesn't work :c
            pa.Add(_pos.x);
            pa.Add(_pos.y);
            pa.Add(_pos.z);
            pa.Add(Rot);

            Server.ForeachPlayer(delegate(Player p) {
                if (p.Level == Level && p.IsLoggedIn && !p.IsLoading) {
                    p.SendPacket(pa);
                }
            });
        }
 /// <summary>
 /// Exactly what the function name is, it might be useful to change this players pos first ;)
 /// </summary>
 public void SendThisPlayerTheirOwnPos()
 {
     packet pa = new packet();
     pa.Add((byte)8);
     pa.Add(Pos.x);
     pa.Add(Pos.y);
     pa.Add(Pos.z);
     pa.Add(Rot);
     SendPacket(pa);
 }
        public void SendSpawn(Player p)
        {
            byte ID = 0xFF;
            if (p != this)
                ID = p.id;

            packet pa = new packet();
            pa.Add(packet.types.SendSpawn);
            pa.Add((byte)ID);
            pa.Add(p.Username, 64);
            pa.Add(p.Pos.x);
            pa.Add(p.Pos.y);
            pa.Add(p.Pos.z);
            pa.Add(p.Rot);
            SendPacket(pa);
        }
        /// <summary>
        /// This send a blockchange to the player only. (Not other players)
        /// </summary>
        /// <param name="x"></param> The position the block will be placed in (x)
        /// <param name="z"></param> The position the block will be placed in (z)
        /// <param name="y"></param> The position the block will be placed in (y)
        /// <param name="type"></param> The type of block that will be placed.
        public void SendBlockChange(ushort x, ushort z, ushort y, byte type)
        {
            if (x < 0 || y < 0 || z < 0 || x >= Level.Size.x || y >= Level.Size.y || z >= Level.Size.z) return;

            packet pa = new packet();
            pa.Add(packet.types.SendBlockchange);
            pa.Add(x);
            pa.Add(y);
            pa.Add(z);

            //if (type > 49) type = Block.CustomBlocks[type].VisibleType;
            pa.Add(type);

            SendPacket(pa);
        }
        internal void UpdatePosition(bool ForceTp)
        {
            Vector3S tempOldPos = new Vector3S(oldPos);
            Vector3S tempPos = new Vector3S(Pos);
            byte[] tempRot = Rot;
            byte[] tempOldRot = oldRot;
            if (tempOldRot == null) tempOldRot = new byte[2];
            if (IsHeadFlipped)
                tempRot[1] = 80;

            oldPos = tempPos;
            oldRot = tempRot;

            short diffX = (short)(tempPos.x - tempOldPos.x);
            short diffZ = (short)(tempPos.z - tempOldPos.z);
            short diffY = (short)(tempPos.y - tempOldPos.y);
            int diffR0 = tempRot[0] - tempOldRot[0];
            int diffR1 = tempRot[1] - tempOldRot[1];

            //TODO rewrite local pos change code
            if (diffX == 0 && diffY == 0 && diffZ == 0 && diffR0 == 0 && diffR1 == 0) {
                return; //No changes
            }
            bool teleport = ForceTp || (Math.Abs(diffX) >= 127 || Math.Abs(diffY) >= 127 || Math.Abs(diffZ) >= 127);

            packet pa = new packet();
            if (teleport) {
                pa.Add(packet.types.SendTeleport);
                pa.Add(id);
                pa.Add(tempPos.x);
                pa.Add(tempPos.y);
                pa.Add(tempPos.z);
                pa.Add(tempRot);
            }
            else {
                bool rotupdate = diffR0 != 0 || diffR1 != 0;
                bool posupdate = diffX != 0 || diffY != 0 || diffZ != 0;
                if (rotupdate && posupdate) {
                    pa.Add(packet.types.SendPosANDRotChange);
                    pa.Add(id);
                    pa.Add((sbyte)diffX);
                    pa.Add((sbyte)diffY);
                    pa.Add((sbyte)diffZ);
                    pa.Add(tempRot);
                }
                else if (rotupdate) {
                    pa.Add(packet.types.SendRotChange);
                    pa.Add(id);
                    pa.Add(tempRot);
                }
                else if (posupdate) {
                    pa.Add(packet.types.SendPosChange);
                    pa.Add(id);
                    pa.Add((sbyte)(diffX));
                    pa.Add((sbyte)(diffY));
                    pa.Add((sbyte)(diffZ));
                }
                else return;
            }

            Server.ForeachPlayer(delegate(Player p) {
                if (p != this && p.Level == Level && p.IsLoggedIn && !p.IsLoading) {
                    p.SendPacket(pa);
                }
            });
        }