/**
         * Update the specified player's Npcs.
         * @param p
         */
        public static void update(Player player) {

            //Creates a list of new players in area. [This only happens once.. no rebuilding like all runescape 2 servers.]
            player.getLocalEnvironment().updateNpcsInArea();
            //Attempt to skip a pointless update if possible.
            //Any current npcs on screen got a update for me, if no we just return this whole method.
            bool hasAppearanceUpdate = player.getLocalEnvironment().getSeenNpcs().Exists(new Predicate<Npc>(delegate(Npc n) { return n.getUpdateFlags().isUpdateRequired(); }));
            //No new pending npcs and no npcs pending to get removed from screen.
            bool hasAddRemoveUpdate = (player.getLocalEnvironment().getNewNpcs().Count > 0 || player.getLocalEnvironment().getRemovedNpcs().Count > 0);
            //no updates.. exit.
            if (!hasAppearanceUpdate && !hasAddRemoveUpdate) return;

		    PacketBuilder mainPacket = new PacketBuilder().setId(32).setSize(Packet.Size.VariableShort).initBitAccess();
		    PacketBuilder updateBlock = new PacketBuilder().setSize(Packet.Size.Bare);
		    mainPacket.addBits(8, player.getLocalEnvironment().getSeenNpcs().Count);

            //Send information of all the npcs in our own location.
            foreach (Npc n in player.getLocalEnvironment().getSeenNpcs())
            {
                if (player.getLocalEnvironment().getRemovedNpcs().Contains(n)) {
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 3); //delete npc.
                    continue;
                } else {
                    if (n.getSprites().getPrimarySprite() == -1)
                    {
                        if (n.getUpdateFlags().isUpdateRequired())
                        {
                            mainPacket.addBits(1, 1);
                            mainPacket.addBits(2, 0);
                        }
                        else
                        {
                            mainPacket.addBits(1, 0);
                        }
                    }
                    else if (n.getSprites().getSecondarySprite() == -1)
                    {
                        mainPacket.addBits(1, 1);
                        mainPacket.addBits(2, 1);
                        mainPacket.addBits(3, XLATE_DIRECTION_TO_CLIENT[n.getSprites().getPrimarySprite()]);
                        mainPacket.addBits(1, n.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                    else
                    {
                        mainPacket.addBits(1, 1);
                        mainPacket.addBits(2, 2);
                        mainPacket.addBits(3, n.getSprites().getPrimarySprite());
                        mainPacket.addBits(3, n.getSprites().getSecondarySprite());
                        mainPacket.addBits(1, n.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                    if (n.getUpdateFlags().isUpdateRequired())
                        appendUpdateBlock(n, updateBlock);
                }
            }

            //Send information of all the new npcs in our own location.
            foreach (Npc n in player.getLocalEnvironment().getNewNpcs())
            {
                int yPos = n.getLocation().getY() - player.getLocation().getY();
                int xPos = n.getLocation().getX() - player.getLocation().getX();

                mainPacket.addBits(15, n.getIndex());
                mainPacket.addBits(1, 1);
                mainPacket.addBits(3, n.getFaceDirection());
                mainPacket.addBits(1, n.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                mainPacket.addBits(5, yPos < 0 ? yPos + 32 : yPos);
                mainPacket.addBits(14, n.getId());
                mainPacket.addBits(5, xPos < 0 ? xPos + 32 : xPos);

                if (n.getUpdateFlags().isUpdateRequired())
                    appendUpdateBlock(n, updateBlock);
            }

		    if(updateBlock.getLength() >= 3) {
			    mainPacket.addBits(15, 32767);
		    }
		    mainPacket.finishBitAccess();
		    mainPacket.addBytes(updateBlock.toPacket().getData());
		    player.getConnection().SendPacket(mainPacket.toPacket());

            /**
             * Done with with all our updates.. time to refine our environment lists.
             * Remove npcs who either moved away from our location or hidden / dead etc..
             * Mix new npcs with old npcs into one npclist.
             * Clear new npc list, for more new npcs again
             */
            player.getLocalEnvironment().organizeNpcs();
	    }
        private static void appendAppearanceUpdate(Player p, PacketBuilder updateBlock) {
		    PacketBuilder playerProps = new PacketBuilder().setSize(Packet.Size.Bare);
		
		    Appearance app = p.getAppearance();
		    playerProps.addByte((byte) (app.getGender() & 0xFF));
		    if((app.getGender() & 0x2) == 2) {
			    playerProps.addByte((byte) 0);
			    playerProps.addByte((byte) 0);
		    }
		    playerProps.addByte((byte) p.getPrayers().getPkIcon());
		    playerProps.addByte((byte) p.getPrayers().getHeadIcon());
		    if (!app.isInvisible()) {
			    if(!app.isNpc()) {
				    for(int i = 0; i < 4; i++) {
					    if(p.getEquipment().getItemInSlot((ItemData.EQUIP)i) != -1) {
                            playerProps.addUShort(32768 + p.getEquipment().getSlot((ItemData.EQUIP)i).getDefinition().getEquipId());
					    } else {
						    playerProps.addByte((byte) 0);
					    }
				    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.CHEST) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.CHEST).getDefinition().getEquipId());
				    } else {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.AMULET));
				    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.SHIELD) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.SHIELD).getDefinition().getEquipId());
				    } else {
					    playerProps.addByte((byte) 0);
				    }
                    Item chest = p.getEquipment().getSlot(ItemData.EQUIP.CHEST);
                    if (chest != null && chest.getDefinition() != null)
                    {
					    if(!ItemData.isFullBody(chest.getDefinition())) {
                            playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.WEAPON));
					    } else {
						    playerProps.addByte((byte) 0);
					    }
				    } else {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.WEAPON));
				    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.LEGS) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.LEGS).getDefinition().getEquipId());
				    } else {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.SHIELD));
				    }
                    Item hat = p.getEquipment().getSlot(ItemData.EQUIP.HAT);
                    if (hat != null && hat.getDefinition() != null)
                    {
					    if(!ItemData.isFullHat(hat.getDefinition()) && !ItemData.isFullMask(hat.getDefinition())) {
                            playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.HAT));
					    } else {
						    playerProps.addByte((byte) 0);
					    }
				    } else {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.HAT));
				    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.HANDS) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.HANDS).getDefinition().getEquipId());
				    } else {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.CHEST));
				    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.FEET) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.FEET).getDefinition().getEquipId());
				    } else {
					    playerProps.addUShort(0x100 + app.getLook(6));
				    }
                    if (hat != null && hat.getDefinition() != null)
                    {
					    if(!ItemData.isFullMask(hat.getDefinition())) {
                            playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.CAPE));
					    } else {
						    playerProps.addByte((byte) 0);
					    }
				    } else {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.CAPE));
				    }
			    } else {
				    playerProps.addUShort(-1);
				    playerProps.addUShort(app.getNpcId());
				    playerProps.addByte((byte) 255);
			    }
		    } else {
			    for (int i = 0; i < 12; i++) {
				    playerProps.addByte((byte) 0);
			    }
		    }
		    foreach(int colour in app.getColoursArray()) {
			    playerProps.addByte((byte) colour);
		    }
		    playerProps.addUShort(p.getEquipment().getStandWalkAnimation());
		    playerProps.addLong(p.getLoginDetails().getLongName());
		    playerProps.addByte((byte) p.getSkills().getCombatLevel());
		    playerProps.addUShort(0);
		    playerProps.addByte((byte) 0);
		    updateBlock.addByteA((byte) (playerProps.getLength() & 0xFF));
		    updateBlock.addBytes(playerProps.toPacket().getData(), 0, playerProps.getLength());
	    }
        /**
         * Update the specified player.
         * @param p
         */
        public static void update(Player player)
        {

            //Creates a list of new players in area. [This only happens once.. no rebuilding like all runescape 2 servers.]
            player.getLocalEnvironment().updatePlayersInArea();

            //Attempt to skip a pointless update if possible.
            //Any current users on screen got a update for me.
            bool hasAppearanceUpdate = player.getLocalEnvironment().getSeenPlayers().Exists(new Predicate<Player>(delegate(Player p) { return p.getUpdateFlags().hasAnyUpdate(); }));
            //No new pending players and no players pending to get removed from screen.
            bool hasAddRemoveUpdate = (player.getLocalEnvironment().getNewPlayers().Count > 0 || player.getLocalEnvironment().getRemovedPlayers().Count > 0);
            //no updates.. exit.

            if (!hasAppearanceUpdate && !hasAddRemoveUpdate && !player.getUpdateFlags().hasAnyUpdate() && !player.getUpdateFlags().didMapRegionChange() && player.getConnection().getPingCount() < 7) return;

            player.getConnection().resetPingCount();

            if(player.getUpdateFlags().didMapRegionChange())
                player.getPackets().sendMapRegion();

            PacketBuilder mainPacket = new PacketBuilder().setId(225).setSize(Packet.Size.VariableShort).initBitAccess();
            PacketBuilder updateBlock = new PacketBuilder().setSize(Packet.Size.Bare);

            if (player.getUpdateFlags().isTeleporting()) { //teleport
                mainPacket.addBits(1, 1);
                mainPacket.addBits(2, 3);
                mainPacket.addBits(7, player.getLocation().getLocalY(player.getUpdateFlags().getLastRegion())); //currentX
                mainPacket.addBits(1, 1);
                mainPacket.addBits(2, player.getLocation().getZ()); //heightLevel
                mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                mainPacket.addBits(7, player.getLocation().getLocalX(player.getUpdateFlags().getLastRegion())); //currentY
            } else {
                if (player.getSprites().getPrimarySprite() == -1) { //no movement
                    mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    if (player.getUpdateFlags().isUpdateRequired())
                        mainPacket.addBits(2, 0);
                } else { //movement.
                    mainPacket.addBits(1, 1);
                    if (player.getSprites().getSecondarySprite() == -1) { //not running
                        mainPacket.addBits(2, 1);
                        mainPacket.addBits(3, player.getSprites().getPrimarySprite()); //walk
                        mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    } else {
                        mainPacket.addBits(2, 2);
                        mainPacket.addBits(1, 1);
                        mainPacket.addBits(3, player.getSprites().getPrimarySprite()); //walk
                        mainPacket.addBits(3, player.getSprites().getSecondarySprite()); //run
                        mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                }
            }
            if(player.getUpdateFlags().isUpdateRequired())
                appendUpdateBlock(player, updateBlock, false); //update my own updates.

            mainPacket.addBits(8, player.getLocalEnvironment().getSeenPlayers().Count); //All players I've seen already (not new players)

            //Send information of all the players in our own location.
            foreach (Player p in player.getLocalEnvironment().getSeenPlayers())
            {
                if (player.getLocalEnvironment().getRemovedPlayers().Contains(p)) {
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 3); //delete player.
                    continue;
                } else if (p.getSprites().getPrimarySprite() == -1) {
                    if(p.getUpdateFlags().isUpdateRequired()) {
				        mainPacket.addBits(1, 1); //update required.
				        mainPacket.addBits(2, 0); //finish
			        } else {
				        mainPacket.addBits(1, 0); //no update required, either region changed or no movement change.
			        }
                } else if (p.getSprites().getPrimarySprite() != -1 && p.getSprites().getSecondarySprite() == -1) {
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 1); //update just walk direction sprite
                    mainPacket.addBits(3, p.getSprites().getPrimarySprite());
                    mainPacket.addBits(1, p.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                } else if (p.getSprites().getPrimarySprite() != -1 && p.getSprites().getSecondarySprite() != -1) { //Bit 2 = 2, updates both sprites.
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 2); //update both walk & run sprites.
                    mainPacket.addBits(1, 1);
                    mainPacket.addBits(3, p.getSprites().getPrimarySprite());
                    mainPacket.addBits(3, p.getSprites().getSecondarySprite());
                    mainPacket.addBits(1, p.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                }
                if (p.getUpdateFlags().isUpdateRequired())
                    appendUpdateBlock(p, updateBlock, false);
             }

            //Send information of all the new players in our own location.
            foreach (Player p in player.getLocalEnvironment().getNewPlayers())
            {
                int yPos = p.getLocation().getY() - player.getLocation().getY();
                int xPos = p.getLocation().getX() - player.getLocation().getX();

                mainPacket.addBits(11, p.getIndex()); //playerId of new player.
                mainPacket.addBits(1, 1);
                mainPacket.addBits(5, xPos < 0 ? xPos + 32 : xPos);
                mainPacket.addBits(3, p.getWalkingQueue().getLastDirection());
                mainPacket.addBits(1, 1);
                mainPacket.addBits(5, yPos < 0 ? yPos + 32 : yPos);
                appendUpdateBlock(p, updateBlock, true); //force appearance update.
            }

            if (updateBlock.getLength() > 0)
                mainPacket.addBits(11, 2047); //2047 max players in server,area.
            mainPacket.finishBitAccess();
            if (updateBlock.getLength() > 0)
                mainPacket.addBytes(updateBlock.toPacket().getData());
            if (player.getConnection() != null)
                player.getConnection().SendPacket(mainPacket.toPacket());

            /**
             * Done with with all our updates.. fine to refine our environment lists.
             * Remove players who either moved away from our location or plain old disconnected.
             * Mix new players with old players into one playerlist.
             * Clear new players list, for more new players again
             */
            player.getLocalEnvironment().organizePlayers();
        }
Example #4
0
        /**
         * Update the specified player's Npcs.
         * @param p
         */
        public static void update(Player player)
        {
            //Creates a list of new players in area. [This only happens once.. no rebuilding like all runescape 2 servers.]
            player.getLocalEnvironment().updateNpcsInArea();
            //Attempt to skip a pointless update if possible.
            //Any current npcs on screen got a update for me, if no we just return this whole method.
            bool hasAppearanceUpdate = player.getLocalEnvironment().getSeenNpcs().Exists(new Predicate <Npc>(delegate(Npc n) { return(n.getUpdateFlags().isUpdateRequired()); }));
            //No new pending npcs and no npcs pending to get removed from screen.
            bool hasAddRemoveUpdate = (player.getLocalEnvironment().getNewNpcs().Count > 0 || player.getLocalEnvironment().getRemovedNpcs().Count > 0);

            //no updates.. exit.
            if (!hasAppearanceUpdate && !hasAddRemoveUpdate)
            {
                return;
            }

            PacketBuilder mainPacket  = new PacketBuilder().setId(32).setSize(Packet.Size.VariableShort).initBitAccess();
            PacketBuilder updateBlock = new PacketBuilder().setSize(Packet.Size.Bare);

            mainPacket.addBits(8, player.getLocalEnvironment().getSeenNpcs().Count);

            //Send information of all the npcs in our own location.
            foreach (Npc n in player.getLocalEnvironment().getSeenNpcs())
            {
                if (player.getLocalEnvironment().getRemovedNpcs().Contains(n))
                {
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 3); //delete npc.
                    continue;
                }
                else
                {
                    if (n.getSprites().getPrimarySprite() == -1)
                    {
                        if (n.getUpdateFlags().isUpdateRequired())
                        {
                            mainPacket.addBits(1, 1);
                            mainPacket.addBits(2, 0);
                        }
                        else
                        {
                            mainPacket.addBits(1, 0);
                        }
                    }
                    else if (n.getSprites().getSecondarySprite() == -1)
                    {
                        mainPacket.addBits(1, 1);
                        mainPacket.addBits(2, 1);
                        mainPacket.addBits(3, XLATE_DIRECTION_TO_CLIENT[n.getSprites().getPrimarySprite()]);
                        mainPacket.addBits(1, n.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                    else
                    {
                        mainPacket.addBits(1, 1);
                        mainPacket.addBits(2, 2);
                        mainPacket.addBits(3, n.getSprites().getPrimarySprite());
                        mainPacket.addBits(3, n.getSprites().getSecondarySprite());
                        mainPacket.addBits(1, n.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                    if (n.getUpdateFlags().isUpdateRequired())
                    {
                        appendUpdateBlock(n, updateBlock);
                    }
                }
            }

            //Send information of all the new npcs in our own location.
            foreach (Npc n in player.getLocalEnvironment().getNewNpcs())
            {
                int yPos = n.getLocation().getY() - player.getLocation().getY();
                int xPos = n.getLocation().getX() - player.getLocation().getX();

                mainPacket.addBits(15, n.getIndex());
                mainPacket.addBits(1, 1);
                mainPacket.addBits(3, n.getFaceDirection());
                mainPacket.addBits(1, n.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                mainPacket.addBits(5, yPos < 0 ? yPos + 32 : yPos);
                mainPacket.addBits(14, n.getId());
                mainPacket.addBits(5, xPos < 0 ? xPos + 32 : xPos);

                if (n.getUpdateFlags().isUpdateRequired())
                {
                    appendUpdateBlock(n, updateBlock);
                }
            }

            if (updateBlock.getLength() >= 3)
            {
                mainPacket.addBits(15, 32767);
            }
            mainPacket.finishBitAccess();
            mainPacket.addBytes(updateBlock.toPacket().getData());
            player.getConnection().SendPacket(mainPacket.toPacket());

            /**
             * Done with with all our updates.. time to refine our environment lists.
             * Remove npcs who either moved away from our location or hidden / dead etc..
             * Mix new npcs with old npcs into one npclist.
             * Clear new npc list, for more new npcs again
             */
            player.getLocalEnvironment().organizeNpcs();
        }
        private static void appendAppearanceUpdate(Player p, PacketBuilder updateBlock)
        {
            PacketBuilder playerProps = new PacketBuilder().setSize(Packet.Size.Bare);

            Appearance app = p.getAppearance();

            playerProps.addByte((byte)(app.getGender() & 0xFF));
            if ((app.getGender() & 0x2) == 2)
            {
                playerProps.addByte((byte)0);
                playerProps.addByte((byte)0);
            }
            playerProps.addByte((byte)p.getPrayers().getPkIcon());
            playerProps.addByte((byte)p.getPrayers().getHeadIcon());
            if (!app.isInvisible())
            {
                if (!app.isNpc())
                {
                    for (int i = 0; i < 4; i++)
                    {
                        if (p.getEquipment().getItemInSlot((ItemData.EQUIP)i) != -1)
                        {
                            playerProps.addUShort(32768 + p.getEquipment().getSlot((ItemData.EQUIP)i).getDefinition().getEquipId());
                        }
                        else
                        {
                            playerProps.addByte((byte)0);
                        }
                    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.CHEST) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.CHEST).getDefinition().getEquipId());
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.AMULET));
                    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.SHIELD) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.SHIELD).getDefinition().getEquipId());
                    }
                    else
                    {
                        playerProps.addByte((byte)0);
                    }
                    Item chest = p.getEquipment().getSlot(ItemData.EQUIP.CHEST);
                    if (chest != null && chest.getDefinition() != null)
                    {
                        if (!ItemData.isFullBody(chest.getDefinition()))
                        {
                            playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.WEAPON));
                        }
                        else
                        {
                            playerProps.addByte((byte)0);
                        }
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.WEAPON));
                    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.LEGS) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.LEGS).getDefinition().getEquipId());
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.SHIELD));
                    }
                    Item hat = p.getEquipment().getSlot(ItemData.EQUIP.HAT);
                    if (hat != null && hat.getDefinition() != null)
                    {
                        if (!ItemData.isFullHat(hat.getDefinition()) && !ItemData.isFullMask(hat.getDefinition()))
                        {
                            playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.HAT));
                        }
                        else
                        {
                            playerProps.addByte((byte)0);
                        }
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.HAT));
                    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.HANDS) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.HANDS).getDefinition().getEquipId());
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.CHEST));
                    }
                    if (p.getEquipment().getItemInSlot(ItemData.EQUIP.FEET) != -1)
                    {
                        playerProps.addUShort(32768 + p.getEquipment().getSlot(ItemData.EQUIP.FEET).getDefinition().getEquipId());
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(6));
                    }
                    if (hat != null && hat.getDefinition() != null)
                    {
                        if (!ItemData.isFullMask(hat.getDefinition()))
                        {
                            playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.CAPE));
                        }
                        else
                        {
                            playerProps.addByte((byte)0);
                        }
                    }
                    else
                    {
                        playerProps.addUShort(0x100 + app.getLook(ItemData.EQUIP.CAPE));
                    }
                }
                else
                {
                    playerProps.addUShort(-1);
                    playerProps.addUShort(app.getNpcId());
                    playerProps.addByte((byte)255);
                }
            }
            else
            {
                for (int i = 0; i < 12; i++)
                {
                    playerProps.addByte((byte)0);
                }
            }
            foreach (int colour in app.getColoursArray())
            {
                playerProps.addByte((byte)colour);
            }
            playerProps.addUShort(p.getEquipment().getStandWalkAnimation());
            playerProps.addLong(p.getLoginDetails().getLongName());
            playerProps.addByte((byte)p.getSkills().getCombatLevel());
            playerProps.addUShort(0);
            playerProps.addByte((byte)0);
            updateBlock.addByteA((byte)(playerProps.getLength() & 0xFF));
            updateBlock.addBytes(playerProps.toPacket().getData(), 0, playerProps.getLength());
        }
        /**
         * Update the specified player.
         * @param p
         */
        public static void update(Player player)
        {
            //Creates a list of new players in area. [This only happens once.. no rebuilding like all runescape 2 servers.]
            player.getLocalEnvironment().updatePlayersInArea();

            //Attempt to skip a pointless update if possible.
            //Any current users on screen got a update for me.
            bool hasAppearanceUpdate = player.getLocalEnvironment().getSeenPlayers().Exists(new Predicate <Player>(delegate(Player p) { return(p.getUpdateFlags().hasAnyUpdate()); }));
            //No new pending players and no players pending to get removed from screen.
            bool hasAddRemoveUpdate = (player.getLocalEnvironment().getNewPlayers().Count > 0 || player.getLocalEnvironment().getRemovedPlayers().Count > 0);

            //no updates.. exit.

            if (!hasAppearanceUpdate && !hasAddRemoveUpdate && !player.getUpdateFlags().hasAnyUpdate() && !player.getUpdateFlags().didMapRegionChange() && player.getConnection().getPingCount() < 7)
            {
                return;
            }

            player.getConnection().resetPingCount();

            if (player.getUpdateFlags().didMapRegionChange())
            {
                player.getPackets().sendMapRegion();
            }

            PacketBuilder mainPacket  = new PacketBuilder().setId(225).setSize(Packet.Size.VariableShort).initBitAccess();
            PacketBuilder updateBlock = new PacketBuilder().setSize(Packet.Size.Bare);

            if (player.getUpdateFlags().isTeleporting())   //teleport
            {
                mainPacket.addBits(1, 1);
                mainPacket.addBits(2, 3);
                mainPacket.addBits(7, player.getLocation().getLocalY(player.getUpdateFlags().getLastRegion())); //currentX
                mainPacket.addBits(1, 1);
                mainPacket.addBits(2, player.getLocation().getZ());                                             //heightLevel
                mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                mainPacket.addBits(7, player.getLocation().getLocalX(player.getUpdateFlags().getLastRegion())); //currentY
            }
            else
            {
                if (player.getSprites().getPrimarySprite() == -1)   //no movement
                {
                    mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    if (player.getUpdateFlags().isUpdateRequired())
                    {
                        mainPacket.addBits(2, 0);
                    }
                }
                else     //movement.
                {
                    mainPacket.addBits(1, 1);
                    if (player.getSprites().getSecondarySprite() == -1)   //not running
                    {
                        mainPacket.addBits(2, 1);
                        mainPacket.addBits(3, player.getSprites().getPrimarySprite()); //walk
                        mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                    else
                    {
                        mainPacket.addBits(2, 2);
                        mainPacket.addBits(1, 1);
                        mainPacket.addBits(3, player.getSprites().getPrimarySprite());   //walk
                        mainPacket.addBits(3, player.getSprites().getSecondarySprite()); //run
                        mainPacket.addBits(1, player.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                    }
                }
            }
            if (player.getUpdateFlags().isUpdateRequired())
            {
                appendUpdateBlock(player, updateBlock, false);                          //update my own updates.
            }
            mainPacket.addBits(8, player.getLocalEnvironment().getSeenPlayers().Count); //All players I've seen already (not new players)

            //Send information of all the players in our own location.
            foreach (Player p in player.getLocalEnvironment().getSeenPlayers())
            {
                if (player.getLocalEnvironment().getRemovedPlayers().Contains(p))
                {
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 3); //delete player.
                    continue;
                }
                else if (p.getSprites().getPrimarySprite() == -1)
                {
                    if (p.getUpdateFlags().isUpdateRequired())
                    {
                        mainPacket.addBits(1, 1);                 //update required.
                        mainPacket.addBits(2, 0);                 //finish
                    }
                    else
                    {
                        mainPacket.addBits(1, 0);                 //no update required, either region changed or no movement change.
                    }
                }
                else if (p.getSprites().getPrimarySprite() != -1 && p.getSprites().getSecondarySprite() == -1)
                {
                    mainPacket.addBits(1, 1); //update required.
                    mainPacket.addBits(2, 1); //update just walk direction sprite
                    mainPacket.addBits(3, p.getSprites().getPrimarySprite());
                    mainPacket.addBits(1, p.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                }
                else if (p.getSprites().getPrimarySprite() != -1 && p.getSprites().getSecondarySprite() != -1) //Bit 2 = 2, updates both sprites.
                {
                    mainPacket.addBits(1, 1);                                                                  //update required.
                    mainPacket.addBits(2, 2);                                                                  //update both walk & run sprites.
                    mainPacket.addBits(1, 1);
                    mainPacket.addBits(3, p.getSprites().getPrimarySprite());
                    mainPacket.addBits(3, p.getSprites().getSecondarySprite());
                    mainPacket.addBits(1, p.getUpdateFlags().isUpdateRequired() ? 1 : 0);
                }
                if (p.getUpdateFlags().isUpdateRequired())
                {
                    appendUpdateBlock(p, updateBlock, false);
                }
            }

            //Send information of all the new players in our own location.
            foreach (Player p in player.getLocalEnvironment().getNewPlayers())
            {
                int yPos = p.getLocation().getY() - player.getLocation().getY();
                int xPos = p.getLocation().getX() - player.getLocation().getX();

                mainPacket.addBits(11, p.getIndex()); //playerId of new player.
                mainPacket.addBits(1, 1);
                mainPacket.addBits(5, xPos < 0 ? xPos + 32 : xPos);
                mainPacket.addBits(3, p.getWalkingQueue().getLastDirection());
                mainPacket.addBits(1, 1);
                mainPacket.addBits(5, yPos < 0 ? yPos + 32 : yPos);
                appendUpdateBlock(p, updateBlock, true); //force appearance update.
            }

            if (updateBlock.getLength() > 0)
            {
                mainPacket.addBits(11, 2047); //2047 max players in server,area.
            }
            mainPacket.finishBitAccess();
            if (updateBlock.getLength() > 0)
            {
                mainPacket.addBytes(updateBlock.toPacket().getData());
            }
            if (player.getConnection() != null)
            {
                player.getConnection().SendPacket(mainPacket.toPacket());
            }

            /**
             * Done with with all our updates.. fine to refine our environment lists.
             * Remove players who either moved away from our location or plain old disconnected.
             * Mix new players with old players into one playerlist.
             * Clear new players list, for more new players again
             */
            player.getLocalEnvironment().organizePlayers();
        }