Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package org.lazaro.rt5e.network.protocol.world;
- import org.lazaro.rt5e.Constants;
- import org.lazaro.rt5e.Context;
- import org.lazaro.rt5e.logic.Entity;
- import org.lazaro.rt5e.logic.item.Item;
- import org.lazaro.rt5e.logic.map.Directions;
- import org.lazaro.rt5e.logic.mask.ChatMessage;
- import org.lazaro.rt5e.logic.mask.Hit;
- import org.lazaro.rt5e.logic.mask.Mask;
- import org.lazaro.rt5e.logic.npc.NPCDefinition;
- import org.lazaro.rt5e.logic.player.Appearance;
- import org.lazaro.rt5e.logic.player.Player;
- import org.lazaro.rt5e.logic.utility.PlayerUpdater;
- import org.lazaro.rt5e.network.Packet;
- import org.lazaro.rt5e.network.PacketBuilder;
- import org.lazaro.rt5e.utility.TextUtilities;
- /**
- * @author Lazaro
- */
- public class GPP613 implements PlayerUpdater {
- private int[] playerHashLoc = new int[2048];
- private void doAnimation(Player player, PacketBuilder pb) {
- pb.putShortA(player.getMasks().getAnimationId()).putByteS(player.getMasks().getAnimationDelay());
- }
- private void doAppearance(Player player, PacketBuilder pb) {
- Packet appearanceBlock = player.getCachedAppearanceBlock();
- pb.putS((byte) (appearanceBlock.getLength() & 0xFF));
- byte[] payload = appearanceBlock.getBytes();
- pb.putA(payload);
- }
- public Packet doApperanceBlock(Player player) {
- PacketBuilder appearanceBlock = new PacketBuilder();
- Appearance app = player.getAppearance();
- int hash = 0;
- // hash |= 0 << 6; // something to do with the chat bar
- // hash |= 0 << 3; // player size (example: if the player turns into an
- // npc and it is bigger than 1 tile)
- // hash |= 0x2; if the player has a display name
- // hash |= 0x4; //??
- hash |= player.getAppearance().getGender().intValue() & 0x1;
- appearanceBlock.putByte(hash);
- appearanceBlock.putByte(0 /* 1-mob status */).putByte(app.getPKIcon()).putByte(app.getPrayerIcon());
- if (!app.isNPC()) {
- for (int i = 0; i < 4; i++) {
- Item item = player.getEquipment().get(i);
- if (item != null) {
- appearanceBlock.putShort(32768 + item.getDefinition().getEquipmentId());
- } else {
- appearanceBlock.putByte(0);
- }
- }
- Item chestItem = player.getEquipment().get(Constants.Equipment.CHEST_SLOT);
- if (chestItem != null) {
- appearanceBlock.putShort(32768 + chestItem.getDefinition().getEquipmentId());
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(2));
- }
- Item shieldItem = player.getEquipment().get(Constants.Equipment.SHIELD_SLOT);
- if (shieldItem != null) {
- appearanceBlock.putShort(32768 + shieldItem.getDefinition().getEquipmentId());
- } else {
- appearanceBlock.putByte(0);
- }
- if (chestItem != null && chestItem.getDefinition().isFullBody()) {
- appearanceBlock.putByte(0);
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(3));
- }
- Item bottomItem = player.getEquipment().get(Constants.Equipment.BOTTOMS_SLOT);
- if (bottomItem != null) {
- appearanceBlock.putShort(32768 + bottomItem.getDefinition().getEquipmentId());
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(5));
- }
- Item helmItem = player.getEquipment().get(Constants.Equipment.HELM_SLOT);
- if (helmItem != null && (helmItem.getDefinition().isHat() || helmItem.getDefinition().isMask())) {
- appearanceBlock.putByte(0);
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(0));
- }
- Item glovesItem = player.getEquipment().get(Constants.Equipment.GLOVES_SLOT);
- if (glovesItem != null) {
- appearanceBlock.putShort(32768 + glovesItem.getDefinition().getEquipmentId());
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(4));
- }
- Item bootsItem = player.getEquipment().get(Constants.Equipment.BOOTS_SLOT);
- if (bootsItem != null) {
- appearanceBlock.putShort(32768 + bootsItem.getDefinition().getEquipmentId());
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(6));
- }
- if (helmItem != null && helmItem.getDefinition().isMask()) {
- appearanceBlock.putByte(0);
- } else {
- appearanceBlock.putShort(0x100 + app.getLook(1));
- }
- } else {
- appearanceBlock.putShort(-1);
- appearanceBlock.putShort(app.getNPCType());
- appearanceBlock.putByte(0);
- }
- for (int i = 0; i < 5; i++) {
- appearanceBlock.put(app.getColor(i));
- }
- Item weapon = player.getEquipment().get(Constants.Equipment.WEAPON_SLOT);
- appearanceBlock.putShort(!app.isNPC() ? (weapon != null ? weapon.getDefinition().getRenderId() : 1426) : NPCDefinition.forType(app.getNPCType()).getRenderId());
- appearanceBlock.putString(player.getName());
- // extra string if the player has a display name
- appearanceBlock.put((byte) player.getSkills().getCombatLevel()); // combat
- // level
- appearanceBlock.putShort(0);
- appearanceBlock.putByte(0);
- return appearanceBlock.toPacket();
- }
- private void doChat(Player player, PacketBuilder pb) {
- ChatMessage msg = player.getMasks().getChat();
- int effects = msg.getColor() << 8 | msg.getEffect();
- if (false) {
- effects |= 0x8000; // flags something
- }
- byte[] textBuffer = new byte[256];
- textBuffer[0] = (byte) msg.getText().length();
- int length = TextUtilities.huffmanCompress(msg.getText(), textBuffer, 1);
- pb.putShort(effects).putByteS(player.getRights().intValue()).put(textBuffer, 0, length + 1);
- }
- private void doFaceDirection(Player player, PacketBuilder pb) {
- int dX = player.getLocation().getX() - player.getMasks().getFaceDirection().getX();
- int dY = player.getLocation().getY() - player.getMasks().getFaceDirection().getY();
- pb.putLEShort(((int) (Math.atan2(dX, dY) * 2607.5945876176133)) & 0x3fff);
- }
- private void doFaceEntity(Player player, PacketBuilder pb) {
- pb.putShortA(player.getMasks().getFaceEntity().getId());
- }
- private void doForcedMovementMode(Player player, PacketBuilder pb) {
- pb.putByteC(player.getMasks().getForcedMovementMode());
- }
- private void doGraphics(Player player, PacketBuilder pb) {
- pb.putLEShortA(player.getMasks().getGraphicsId()).putInt1(player.getMasks().getGraphicsDelay()).putByteS(player.getMasks().getGraphicsHeight());
- }
- private void doGraphics2(Player player, PacketBuilder pb) {
- pb.putShortA(player.getMasks().getGraphicsId2()).putInt(player.getMasks().getGraphicsDelay2()).putByte(player.getMasks().getGraphicsHeight2());
- }
- private void doHit(Player player, PacketBuilder pb) {
- Hit hit = player.getMasks().getHit();
- int hpRatio = player.getHP() * 255 / player.getMaxHP();
- pb.putSmart(hit.getDamage()).putByte(hit.getType()).putByte(hpRatio);
- }
- private void doHit2(Player player, PacketBuilder pb) {
- Hit hit = player.getMasks().getHit2();
- pb.putSmart(hit.getDamage()).putByteS(hit.getType());
- }
- public Packet doMaskBlock(Entity entity) {
- return doMaskBlock((Player) entity, false);
- }
- private Packet doMaskBlock(Player player, boolean newPlayer) {
- PacketBuilder pb = new PacketBuilder();
- int mask = 0;
- if (player.getMasks().requiresUpdate(Mask.MaskType.HIT2)) {
- mask |= 0x10000;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.ANIMATION)) {
- mask |= 0x80;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.GRAPHICS2)) {
- mask |= 0x1000;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.MOVEMENT_MODE) || newPlayer) {
- mask |= 0x10;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FORCED_CHAT)) {
- mask |= 0x400;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FACE_ENTITY) || (newPlayer && player.getMasks().getFaceEntity() != null)) {
- mask |= 0x2;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.APPEARANCE) || newPlayer) {
- mask |= 0x20;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FORCED_MOVEMENT_MODE)) {
- mask |= 0x2000;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.HIT)) {
- mask |= 0x40;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FACE_DIRECTION) || (newPlayer && player.getMasks().getFaceDirection() != null)) {
- mask |= 0x4;
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.GRAPHICS)) {
- mask |= 0x8;
- }
- if (mask >= 0x100) {
- mask |= 0x1;
- if (mask >= 0x10000) {
- mask |= 0x800;
- pb.putByte(mask & 0xff).putByte(mask >> 8 & 0xffff).putByte(mask >> 16);
- } else {
- pb.putByte(mask & 0xff).putByte(mask >> 8);
- }
- } else {
- pb.putByte(mask & 0xff);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.HIT2)) {
- doHit2(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.ANIMATION)) {
- doAnimation(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.GRAPHICS2)) {
- doGraphics2(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.MOVEMENT_MODE) || newPlayer) {
- doMovementMode(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FORCED_CHAT)) {
- doForcedChat(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FACE_ENTITY) || (newPlayer && player.getMasks().getFaceEntity() != null)) {
- doFaceEntity(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.APPEARANCE) || newPlayer) {
- doAppearance(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FORCED_MOVEMENT_MODE)) {
- doForcedMovementMode(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.HIT)) {
- doHit(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.FACE_DIRECTION) || (newPlayer && player.getMasks().getFaceDirection() != null)) {
- doFaceDirection(player, pb);
- }
- if (player.getMasks().requiresUpdate(Mask.MaskType.GRAPHICS)) {
- doGraphics(player, pb);
- }
- return pb.toPacket();
- }
- private void doForcedChat(Player player, PacketBuilder pb) {
- pb.putString(player.getMasks().getForcedChat().getText());
- }
- private void doMovementMode(Player player, PacketBuilder pb) {
- pb.putByteC(player.getMovementMode());
- }
- public int getPlayerHashLoc(int index) {
- return playerHashLoc[index];
- }
- private void masks(Player player, PacketBuilder pb, boolean newPlayer) {
- if (!newPlayer) {
- pb.put(player.getCachedMaskBlock().getBytes());
- } else {
- pb.put(doMaskBlock(player, newPlayer).getBytes());
- }
- }
- public void setPlayerHashLoc(int index, int value) {
- playerHashLoc[index] = value;
- }
- public void update(Player player) {
- PacketBuilder pb = new PacketBuilder(53, Packet.Type.VAR_SHORT);
- /**
- * NSN0
- */
- pb.recalculateBitPosition();
- int skip = -1;
- for (int i = 1; i < 2048; i++) {
- if (player.isInViewport(i)) {
- if (!player.skippedLastCycle(i)) {
- Player local = Context.getWorld().getGlobalPlayers().get(i);
- if (!updateLocalPlayer(player, local, i, pb, skip)) {
- player.setSkippedThisCycle(local.getIndex(), true);
- skip++;
- } else {
- skip = -1;
- }
- }
- }
- }
- writeSkip(skip, pb);
- /**
- * NSN1
- */
- pb.recalculateBitPosition();
- skip = -1;
- for (int i = 1; i < 2048; i++) {
- if (player.isInViewport(i)) {
- if (player.skippedLastCycle(i)) {
- Player local = Context.getWorld().getGlobalPlayers().get(i);
- if (!updateLocalPlayer(player, local, i, pb, skip)) {
- player.setSkippedThisCycle(local.getIndex(), true);
- skip++;
- } else {
- skip = -1;
- }
- }
- }
- }
- writeSkip(skip, pb);
- int newPlayerCount = 0;
- /**
- * NSN2
- */
- pb.recalculateBitPosition();
- skip = -1;
- for (int i = 1; i < 2048; i++) {
- if (player.skippedLastCycle(i)) {
- Player p2 = Context.getWorld().getGlobalPlayers().get(i);
- if (player.isInViewport(i) || player.justLeftViewport(i)) {
- continue;
- } else if (p2 == null || p2.isOnLogin()) {
- player.setSkippedThisCycle(i, true);
- skip++;
- continue;
- }
- if (player.getLocation().withinRange(p2.getLocation()) && newPlayerCount < 64) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 0, pb, false);
- newPlayerCount++;
- } else if (p2.isTeleporting() || p2.loggedInThisCycle()) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 3, pb, false);
- } else if (p2.getMapRegionDirection() != null) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 2, pb, false);
- } else if (p2.isHeightUpdate()) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 1, pb, false);
- } else {
- player.setSkippedThisCycle(i, true);
- skip++;
- }
- }
- }
- writeSkip(skip, pb);
- /**
- * NSN3
- */
- pb.recalculateBitPosition();
- skip = -1;
- for (int i = 1; i < 2048; i++) {
- if (!player.skippedLastCycle(i)) {
- Player p2 = Context.getWorld().getGlobalPlayers().get(i);
- if (player.isInViewport(i) || player.justLeftViewport(i)) {
- continue;
- } else if (p2 == null || p2.isOnLogin()) {
- player.setSkippedThisCycle(i, true);
- skip++;
- continue;
- }
- if (player.getLocation().withinRange(p2.getLocation()) && newPlayerCount < 64) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 0, pb, false);
- newPlayerCount++;
- } else if (p2.isTeleporting() || p2.loggedInThisCycle()) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 3, pb, false);
- } else if (p2.getMapRegionDirection() != null) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 2, pb, false);
- } else if (p2.isHeightUpdate()) {
- writeSkip(skip, pb);
- skip = -1;
- updateGlobalPlayer(player, p2, 1, pb, false);
- } else {
- player.setSkippedThisCycle(i, true);
- skip++;
- }
- }
- }
- writeSkip(skip, pb);
- /**
- * Masks
- */
- pb.recalculateBitPosition();
- for (int i : player.getUpdateRequiredList()) {
- Player local = Context.getWorld().getGlobalPlayers().get(i);
- boolean justEnteredViewport = player.justEnteredViewport(i);
- if (local.getMasks().requiresUpdate() || justEnteredViewport) {
- masks(local, pb, justEnteredViewport);
- }
- }
- player.getConnection().write(pb.toPacket());
- }
- private void updateGlobalPlayer(Player owner, Player player, int stage, PacketBuilder pb, boolean repeated) {
- if (!repeated) {
- pb.putBits(1, 1);
- }
- pb.putBits(2, stage);
- switch (stage) {
- case 0:
- if (player.isTeleporting() || player.loggedInThisCycle()) {
- pb.putBits(1, 1);
- updateGlobalPlayer(owner, player, 3, pb, true);
- } else if (player.getMapRegionDirection() != null) {
- pb.putBits(1, 1);
- updateGlobalPlayer(owner, player, 2, pb, true);
- } else if (player.isHeightUpdate()) {
- pb.putBits(1, 1);
- updateGlobalPlayer(owner, player, 1, pb, true);
- } else {
- pb.putBits(1, 0);
- }
- int x = player.getLocation().getX() - (player.getLocation().getRegionX() << 6);
- int y = player.getLocation().getY() - (player.getLocation().getRegionY() << 6);
- pb.putBits(6, x);
- pb.putBits(6, y);
- pb.putBits(1, 1); // requires update, TODO: we could disable this
- // and make the client use it's cached
- // appearance block if the player hasn't changed
- // appearance yet
- owner.setInViewport(player.getIndex(), true);
- owner.setJustEnteredViewport(player.getIndex(), true);
- owner.setSkippedThisCycle(player.getIndex(), true);
- owner.getUpdateRequiredList().addLast(player.getIndex());
- break;
- case 1:
- int hashLoc = playerHashLoc[player.getIndex()];
- int z = (hashLoc >> 16) & 0x3;
- z = player.getLocation().getZ() - z & 0x3;
- pb.putBits(2, z);
- break;
- case 2:
- hashLoc = playerHashLoc[player.getIndex()];
- z = (hashLoc >> 16) & 0x3;
- z = player.getLocation().getZ() - z & 0x3;
- pb.putBits(5, z << 3 | (player.getMapRegionDirection().intValue() & 0x7));
- break;
- case 3:
- hashLoc = playerHashLoc[player.getIndex()];
- z = (hashLoc >> 16) & 0x3;
- x = (hashLoc >> 8) & 0xff;
- y = hashLoc & 0xff;
- x = player.getLocation().getRegionX() - x & 0xff;
- y = player.getLocation().getRegionY() - y & 0xff;
- z = player.getLocation().getZ() - z & 0x3;
- pb.putBits(18, z << 16 | x << 8 | y);
- break;
- }
- }
- private void updateLocalPlayer(Player owner, Player player, int index, int stage, boolean remove, PacketBuilder pb) {
- pb.putBits(1, 1);
- pb.putBits(1, remove ? 0 : (player.getMasks().requiresUpdate() ? 1 : 0));
- pb.putBits(2, stage);
- switch (stage) {
- case 0:
- if (remove) {
- if (player != null) {
- if (player.isTeleporting()) {
- pb.putBits(1, 1);
- updateGlobalPlayer(owner, player, 3, pb, true);
- } else if (player.getMapRegionDirection() != null) {
- pb.putBits(1, 1);
- updateGlobalPlayer(owner, player, 2, pb, true);
- } else if (player.isHeightUpdate()) {
- pb.putBits(1, 1);
- updateGlobalPlayer(owner, player, 1, pb, true);
- } else {
- pb.putBits(1, 0);
- }
- } else {
- pb.putBits(1, 0);
- }
- owner.setInViewport(index, false);
- owner.setJustLeftViewport(index, true);
- }
- break;
- case 1:
- pb.putBits(3, player.getDirection().getDirection().intValue());
- break;
- case 2:
- pb.putBits(4, player.getDirection().getDirection().intValue());
- break;
- case 3:
- pb.putBits(1, owner != player ? 0 : 1);
- if (owner != player) {
- int x = player.getLocation().getX() - player.getOldLocation().getX() & 0x1f;
- int y = player.getLocation().getY() - player.getOldLocation().getY() & 0x1f;
- int z = player.getLocation().getZ() - player.getOldLocation().getZ() & 0x3;
- pb.putBits(12, z << 10 | x << 5 | y);
- } else {
- int x = player.getLocation().getX() - player.getOldLocation().getX() & 0x3fff;
- int y = player.getLocation().getY() - player.getOldLocation().getY() & 0x3fff;
- int z = player.getLocation().getZ() - player.getOldLocation().getZ() & 0x3;
- pb.putBits(30, z << 28 | x << 14 | y);
- }
- break;
- }
- }
- /**
- * For updating a local player.
- * <p/>
- * Used int NSN0 and NSN1.
- *
- * @param owner The player we are updating.
- * @param player A local player.
- * @param pb The message factory to write with.
- * @return If the block was written.
- */
- private boolean updateLocalPlayer(Player owner, Player player, int index, PacketBuilder pb, int skip) {
- if (player == null || (owner != player && (!player.isValid() || player.isDestroyed() || (owner.isTeleporting() && player.isTeleporting()) || !owner.getLocation().withinRange(player.getLocation())))) {
- writeSkip(skip, pb);
- updateLocalPlayer(owner, player, index, 0, true, pb);
- } else {
- if (player.isTeleporting() && (!player.isForcedTeleporting() || owner == player)) {
- writeSkip(skip, pb);
- updateLocalPlayer(owner, player, index, 3, false, pb);
- } else if (player.getDirection().getDirection() != null) {
- writeSkip(skip, pb);
- if (player.getDirection().getDirection() instanceof Directions.RunningDirection) {
- updateLocalPlayer(owner, player, index, 2, false, pb);
- } else {
- updateLocalPlayer(owner, player, index, 1, false, pb);
- }
- } else {
- if (player.getMasks().requiresUpdate()) {
- writeSkip(skip, pb);
- updateLocalPlayer(owner, player, index, 0, false, pb);
- } else {
- return false;
- }
- }
- if (player.getMasks().requiresUpdate()) {
- owner.getUpdateRequiredList().addLast(player.getIndex());
- }
- }
- return true;
- }
- /**
- * Writes an amount of loops to skip.
- *
- * @param skip The amount of loops to skip.
- * @param pb The message factory to write with.
- */
- private void writeSkip(int skip, PacketBuilder pb) {
- if (skip > -1) {
- int type = 0;
- if (skip != 0) {
- if (skip < 32) {
- type = 1;
- } else if (skip < 256) {
- type = 2;
- } else if (skip < 2048) {
- type = 3;
- } else {
- throw new IllegalArgumentException("Skip count cannot be over 2047!");
- }
- }
- pb.putBits(1, 0);
- pb.putBits(2, type);
- switch (type) {
- case 1:
- pb.putBits(5, skip);
- break;
- case 2:
- pb.putBits(8, skip);
- break;
- case 3:
- pb.putBits(11, skip);
- break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement