Code:
package org.niobe.world.util;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.niobe.model.Appearance.Gender;
import org.niobe.model.Attributes.Attribute;
import org.niobe.model.UpdateFlag.Flag;
import org.niobe.model.container.ItemContainer;
import org.niobe.model.container.impl.Equipment;
import org.niobe.model.definitions.ItemDefinition;
import org.niobe.model.Appearance;
import org.niobe.model.MovementQueue;
import org.niobe.net.packet.Packet.Type;
import org.niobe.net.packet.Packet;
import org.niobe.net.packet.PacketBuilder;
import org.niobe.util.NameUtils;
import org.niobe.world.Player;
import org.niobe.world.World;
public class PlayerUpdating {
private List<Player> localPlayers = new LinkedList<Player>();
public PlayerUpdating update() {
if (player.getAttributes().containsKey(Attribute.CHANGING_REGION)) {
player.getPacketSender().sendMapRegion();
}
PacketBuilder update = new PacketBuilder();
PacketBuilder packet = new PacketBuilder(81, Type.SHORT);
packet.initializeBitAccess();
updateMovement(packet).appendUpdates(update, player, false, true);
packet.writeBits(8, localPlayers.size());
System.out.println("Current local players: ");
for (Player player : localPlayers) {
System.out.println("Player: " + player.getUsername());
}
for (Iterator<Player> playerIterator = localPlayers.iterator(); playerIterator.hasNext();) {
Player otherPlayer = (Player) playerIterator.next();
if (player.getRegion().getArea().getPlayers().contains(otherPlayer) && !otherPlayer.getAttributes().containsKey(Attribute.TELEPORTING)) {
updateOtherPlayerMovement(packet, otherPlayer);
if (otherPlayer.getUpdateFlag().isUpdateRequired()) {
appendUpdates(update, otherPlayer, false, false);
}
} else {
localPlayers.remove(otherPlayer);
playerIterator.remove();
packet.writeBits(1, 1).writeBits(2, 3);
}
}
for (Iterator<Player> playerIterator = player.getRegion().getArea().getPlayers().iterator(); playerIterator.hasNext();) {
Player otherPlayer = (Player) playerIterator.next();
if (localPlayers.size() >= 255)
break;
if (otherPlayer == player || localPlayers.contains(otherPlayer))
continue;
localPlayers.add(otherPlayer);
addPlayer(otherPlayer, packet);
appendUpdates(update, otherPlayer, false, false);
}
if (!update.isEmpty()) {
packet.writeBits(11, 2047);
packet.finalizeBitAccess();
packet.writeBuffer(update.toPacket().getBuffer());
System.out.println("builder is not empty.");
} else {
packet.finalizeBitAccess();
System.out.println("builder is empty");
}
System.out.println("writing update.toPacket()");
player.write(packet.toPacket());
return this;
}
public PlayerUpdating addPlayer(Player otherPlayer, PacketBuilder builder) {
builder.writeBits(11, otherPlayer.getIndex());
builder.writeBits(1, 1);
builder.writeBits(1, 1);
builder.writeBits(5, otherPlayer.getPosition().getY() - otherPlayer.getPosition().getY());
builder.writeBits(5, otherPlayer.getPosition().getX() - otherPlayer.getPosition().getX());
appendUpdates(builder, otherPlayer, true, false);
return this;
}
private PlayerUpdating appendUpdates(PacketBuilder builder, Player player, boolean updateAppearance, boolean noChat) {
if (!player.getUpdateFlag().isUpdateRequired() && !updateAppearance)
return this;
PacketBuilder block = new PacketBuilder();
int mask = 0;
if (player.getUpdateFlag().flagged(Flag.APPEARANCE) || updateAppearance) {
mask |= 0x10;
}
if (player.getUpdateFlag().flagged(Flag.CHAT) && !noChat) {
mask |= 0x80;
}
if (mask >= 0x100) {
mask |= 0x40;
block.writeByte((byte) (mask & 0xFF));
block.writeByte((byte) (mask >> 8));
} else {
block.writeByte((byte) mask);
}
if (player.getUpdateFlag().flagged(Flag.APPEARANCE)) {
updateAppearance(block, player);
}
if (player.getUpdateFlag().flagged(Flag.CHAT) && !noChat) {
updateChat(block, player);
}
return this;
}
private PlayerUpdating updateMovement(PacketBuilder builder) {
if (player.getAttributes().containsKey(Attribute.TELEPORTING) || player.getAttributes().containsKey(Attribute.CHANGING_REGION)) {
builder.writeBits(1, 1);
builder.writeBits(2, 3);
builder.writeBits(2, player.getPosition().getZ());
builder.writeBits(1, player.getTeleportTarget() != null ? 1 : 0);
builder.writeBits(1, player.getUpdateFlag().isUpdateRequired() ? 1 : 0);
builder.writeBits(7, player.getPosition().getLocalY());
builder.writeBits(7, player.getPosition().getLocalX());
} else {
if (!player.getMovementQueue().updateRequired()) {
if (player.getUpdateFlag().isUpdateRequired()) {
builder.writeBits(1, 1);
builder.writeBits(2, 0);
} else {
builder.writeBits(1, 0);
}
} else {
if (player.getMovementQueue().getDirections()[MovementQueue.RUNNING_DIRECTION] == -1) {
builder.writeBits(1, 1);
builder.writeBits(2, 1);
builder.writeBits(3, player.getMovementQueue().getDirections()[MovementQueue.WALKING_DIRECTION]);
builder.writeBits(1, player.getUpdateFlag().isUpdateRequired() ? 1 : 0);
} else {
builder.writeBits(1, 1);
builder.writeBits(2, 2);
builder.writeBits(3, player.getMovementQueue().getDirections()[MovementQueue.WALKING_DIRECTION]);
builder.writeBits(3, player.getMovementQueue().getDirections()[MovementQueue.RUNNING_DIRECTION]);
builder.writeBits(1, player.getUpdateFlag().isUpdateRequired() ? 1 : 0);
}
}
}
return this;
}
private PlayerUpdating updateChat(PacketBuilder builder, Player otherPlayer) {
int effects = ((otherPlayer.getPlayerUpdating().chatColor & 0xff) << 8) + (otherPlayer.getPlayerUpdating().chatEffect & 0xff);
builder.writeLEShort(effects);
builder.writeByte(/*player.getRights().ordinal()*/0);
builder.writeByteC((byte) otherPlayer.getPlayerUpdating().chat.length);
builder.writeBytes(otherPlayer.getPlayerUpdating().chat);
return this;
}
private PlayerUpdating updateAppearance(PacketBuilder builder, Player otherPlayer) {
Appearance appearance = otherPlayer.getAppearance();
ItemContainer equipment = otherPlayer.getEquipment();
PacketBuilder properties = new PacketBuilder();
properties.writeByte((byte) appearance.getGender().getId());
properties.writeByte((byte) appearance.getHeadIcon().getId());
properties.writeByte((byte) appearance.getSkullHint().getId());
int[] equip = new int[equipment.getCapacity()];
for (int i = 0; i < equipment.getCapacity(); i++) {
equip[i] = equipment.getItems()[i].getId();
}
if (equip[Equipment.HAT_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.HAT_SLOT]);
} else {
properties.writeByte(0);
}
if (equip[Equipment.CAPE_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.CAPE_SLOT]);
} else {
properties.writeByte(0);
}
if (equip[Equipment.AMULET_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.AMULET_SLOT]);
} else {
properties.writeByte(0);
}
if (equip[Equipment.WEAPON_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.WEAPON_SLOT]);
} else {
properties.writeByte(0);
}
if (equip[Equipment.BODY_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.BODY_SLOT]);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.CHEST]);
}
if (equip[Equipment.SHIELD_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.SHIELD_SLOT]);
} else {
properties.writeByte(0);
}
if (ItemDefinition.forId(equip[Equipment.BODY_SLOT]).isFullBody()) {
properties.writeByte(0);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.ARMS]);
}
if (equip[Equipment.LEGS_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.LEGS_SLOT]);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.LEGS]);
}
if (ItemDefinition.forId(equip[Equipment.HAT_SLOT]).isFullHelm()) {
properties.writeByte(0);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.HEAD]);
}
if (equip[Equipment.HANDS_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.HANDS_SLOT]);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.HANDS]);
}
if (equip[Equipment.FEET_SLOT] > -1) {
properties.writeShort(0x200 + equip[Equipment.FEET_SLOT]);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.FEET]);
}
if (appearance.getLook()[Appearance.BEARD] <= 0 || appearance.getGender().equals(Gender.FEMALE)) {
properties.writeByte(0);
} else {
properties.writeShort(0x100 + appearance.getLook()[Appearance.BEARD]);
}
properties.writeByte(appearance.getLook()[Appearance.HAIR_COLOUR]);
properties.writeByte(appearance.getLook()[Appearance.TORSO_COLOUR]);
properties.writeByte(appearance.getLook()[Appearance.LEG_COLOUR]);
properties.writeByte(appearance.getLook()[Appearance.FEET_COLOUR]);
properties.writeByte(appearance.getLook()[Appearance.SKIN_COLOUR]);
properties.writeShort(0x328); // TODO: standAnimIndex
properties.writeShort(0x337); // TODO: standTurnAnimIndex
properties.writeShort(0x333); // TODO: walkAnimIndex
properties.writeShort(0x334); // TODO: turn180AnimIndex
properties.writeShort(0x335); // TODO: turn90CWAnimIndex
properties.writeShort(0x336); // TODO: turn90CCWAnimIndex
properties.writeShort(0x338); // TODO: runAnimIndex
properties.writeLong(NameUtils.nameToLong(player.getUsername()));
properties.writeByte(otherPlayer.getSkills().getCombatLevel());
properties.writeShort(otherPlayer.getSkills().getTotalLevel());
Packet packet = properties.toPacket();
builder.writeByteC((byte) packet.getLength());
builder.writeBuffer(packet.getBuffer());
return this;
}
private PlayerUpdating updateOtherPlayerMovement(PacketBuilder packetBuilder, Player otherPlayer) {
if (!otherPlayer.getMovementQueue().updateRequired()) {
if (otherPlayer.getUpdateFlag().isUpdateRequired()) {
packetBuilder.writeBits(1, 1);
packetBuilder.writeBits(2, 0);
} else {
packetBuilder.writeBits(1, 0);
}
} else if (otherPlayer.getMovementQueue().getDirections()[MovementQueue.RUNNING_DIRECTION] == -1) {
packetBuilder.writeBits(1, 1);
packetBuilder.writeBits(2, 1);
packetBuilder.writeBits(3, otherPlayer.getMovementQueue().getDirections()[MovementQueue.WALKING_DIRECTION]);
packetBuilder.writeBits(1, otherPlayer.getUpdateFlag().isUpdateRequired() ? 1 : 0);
} else {
packetBuilder.writeBits(1, 1);
packetBuilder.writeBits(2, 2);
packetBuilder.writeBits(3, otherPlayer.getMovementQueue().getDirections()[MovementQueue.WALKING_DIRECTION]); // Walking
packetBuilder.writeBits(3, otherPlayer.getMovementQueue().getDirections()[MovementQueue.RUNNING_DIRECTION]); // Running
packetBuilder.writeBits(1, otherPlayer.getUpdateFlag().isUpdateRequired() ? 1 : 0);
}
return this;
}
public PlayerUpdating resetFlags() {
chat = new byte[256];
chatColor = chatEffect = 0;
player.getUpdateFlag().set(Flag.NONE);
player.getMovementQueue().setDirections(-1, -1);
return this;
}
public PlayerUpdating(Player player) {
this.player = player;
}
private Player player;
private byte[] chat = new byte[256];
private int chatColor = 0, chatEffect = 0;
}