Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.rs.game.player;
- import com.rs.game.Animation;
- import com.rs.game.EntityList;
- import com.rs.game.ForceMovement;
- import com.rs.game.ForceTalk;
- import com.rs.game.Graphics;
- import com.rs.game.Hit;
- import com.rs.game.World;
- import com.rs.game.WorldTile;
- import com.rs.io.OutputStream;
- import com.rs.utils.Utils;
- import java.util.ArrayList;
- import java.util.Iterator;
- public final class LocalPlayerUpdate
- {
- private Player player;
- private byte[] slotFlags;
- private Player[] localPlayers;
- private int[] localPlayersIndexes;
- private int localPlayersIndexesCount;
- private int[] outPlayersIndexes;
- private int outPlayersIndexesCount;
- private int[] regionHashes;
- private byte[][] cachedAppearencesHashes;
- private int totalRenderDataSentLength;
- public Player[] getLocalPlayers()
- {
- return this.localPlayers;
- }
- public boolean needAppearenceUpdate(int index, byte[] hash)
- {
- return true;
- }
- public LocalPlayerUpdate(Player player)
- {
- this.player = player;
- this.slotFlags = new byte[2048];
- this.localPlayers = new Player[2048];
- this.localPlayersIndexes = new int[2000];
- this.outPlayersIndexes = new int[2048];
- this.regionHashes = new int[2048];
- this.cachedAppearencesHashes = new byte[2000][];
- }
- public void init(OutputStream stream)
- {
- stream.initBitAccess();
- stream.writeBits(30, this.player.get30BitsLocationHash());
- this.localPlayers[this.player.getIndex()] = this.player;
- this.localPlayersIndexes[(this.localPlayersIndexesCount++)] = this.player.getIndex();
- for (int playerIndex = 1; playerIndex < 2048; playerIndex++) {
- if (playerIndex == this.player.getIndex())
- continue;
- Player player = (Player)World.getPlayers().get(playerIndex);
- stream.writeBits(18, this.regionHashes[playerIndex] = player != null ? player.get18BitsLocationHash() : 0);
- this.outPlayersIndexes[(this.outPlayersIndexesCount++)] = playerIndex;
- }
- stream.finishBitAccess();
- }
- private boolean needsRemove(Player p)
- {
- return (p.hasFinished()) || (!this.player.withinDistance(p));
- }
- private boolean needsAdd(Player p)
- {
- return (p != null) && (!p.hasFinished()) && (this.player.withinDistance(p));
- }
- private void updateRegionHash(OutputStream stream, int oldHash, int newHash)
- {
- int oldX = (oldHash & 0xFF72) >> 8;
- int oldY = 0xFF & oldHash;
- int oldPlane = oldHash >> 16;
- int newX = (newHash & 0xFF72) >> 8;
- int newY = 0xFF & newHash;
- int newPlane = newHash >> 16;
- int planeOffset = newPlane - oldPlane;
- if ((oldX == newX) && (oldY == newY))
- {
- stream.writeBits(2, 1);
- stream.writeBits(2, planeOffset);
- }
- else if ((Math.abs(newX - oldX) <= 1) && (Math.abs(newY - oldY) <= 1))
- {
- int dx = newX - oldX;
- int dy = newY - oldY;
- int opcode;
- if ((dx == -1) && (dy == -1)) {
- opcode = 0;
- }
- else
- {
- if ((dx == 1) && (dy == -1)) {
- opcode = 2;
- }
- else
- {
- if ((dx == -1) && (dy == 1)) {
- opcode = 5;
- }
- else
- {
- if ((dx == 1) && (dy == 1)) {
- opcode = 7;
- }
- else
- {
- if (dy == -1) {
- opcode = 1;
- }
- else
- {
- if (dx == -1) {
- opcode = 3;
- }
- else
- {
- if (dx == 1)
- opcode = 4;
- else
- opcode = 6;
- }
- }
- }
- }
- }
- }
- stream.writeBits(2, 2);
- stream.writeBits(5, (planeOffset << 3) + (opcode & 0x7));
- }
- else {
- int xOffset = newX - oldX;
- int yOffset = newY - oldY;
- stream.writeBits(2, 3);
- stream.writeBits(18, (yOffset & 0xFF) + ((xOffset & 0xFF) << 8) + (planeOffset << 16));
- }
- }
- private void processOutsidePlayers(OutputStream stream, OutputStream updateBlockData, boolean nsn2)
- {
- stream.initBitAccess();
- int skip = 0;
- for (int i = 0; i < this.outPlayersIndexesCount; i++)
- {
- int playerIndex = this.outPlayersIndexes[i];
- if (nsn2 ? (0x1 & this.slotFlags[playerIndex]) != 0 : (0x1 & this.slotFlags[playerIndex]) == 0) {
- if (skip > 0)
- {
- this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
- skip--;
- }
- else {
- Player p = (Player)World.getPlayers().get(playerIndex);
- if (needsAdd(p))
- {
- stream.writeBits(1, 1);
- stream.writeBits(2, 0);
- int hash = p.get18BitsLocationHash();
- if (hash == this.regionHashes[playerIndex])
- {
- stream.writeBits(1, 0);
- }
- else {
- stream.writeBits(1, 1);
- updateRegionHash(stream, this.regionHashes[playerIndex], hash);
- this.regionHashes[playerIndex] = hash;
- }
- stream.writeBits(6, p.getXInRegion());
- stream.writeBits(6, p.getYInRegion());
- boolean needAppearenceUpdate = needAppearenceUpdate(p.getIndex(), p.getAppearence().getMD5AppeareanceDataHash());
- appendUpdateBlock(p, updateBlockData, needAppearenceUpdate, true);
- stream.writeBits(1, 1);
- this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
- this.localPlayers[p.getIndex()] = p;
- }
- else {
- int hash = p != null ? p.get18BitsLocationHash() : this.regionHashes[playerIndex];
- if ((p != null) && (hash != this.regionHashes[playerIndex]))
- {
- stream.writeBits(1, 1);
- updateRegionHash(stream, this.regionHashes[playerIndex], hash);
- this.regionHashes[playerIndex] = hash;
- }
- else {
- stream.writeBits(1, 0);
- for (int i2 = i + 1; i2 < this.outPlayersIndexesCount; i2++)
- {
- int p2Index = this.outPlayersIndexes[i2];
- if (nsn2 ? (0x1 & this.slotFlags[p2Index]) == 0 : (0x1 & this.slotFlags[p2Index]) != 0)
- continue;
- Player p2 = (Player)World.getPlayers().get(p2Index);
- if ((needsAdd(p2)) || ((p2 != null) && (p2.get18BitsLocationHash() != this.regionHashes[p2Index])))
- break;
- skip++;
- }
- skipPlayers(stream, skip);
- this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
- }
- }
- }
- }
- }
- stream.finishBitAccess();
- }
- private void processLocalPlayers(OutputStream stream, OutputStream updateBlockData, boolean nsn0)
- {
- stream.initBitAccess();
- int skip = 0;
- for (int i = 0; i < this.localPlayersIndexesCount; i++)
- {
- int playerIndex = this.localPlayersIndexes[i];
- if (nsn0 ? (0x1 & this.slotFlags[playerIndex]) == 0 : (0x1 & this.slotFlags[playerIndex]) != 0) {
- if (skip > 0)
- {
- this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
- skip--;
- }
- else {
- Player p = this.localPlayers[playerIndex];
- if (needsRemove(p))
- {
- stream.writeBits(1, 1);
- stream.writeBits(1, 0);
- stream.writeBits(2, 0);
- this.regionHashes[playerIndex] = (p.getLastWorldTile() != null ? p.getLastWorldTile().get18BitsLocationHash() : p.get18BitsLocationHash());
- int hash = p.get18BitsLocationHash();
- if (hash == this.regionHashes[playerIndex])
- {
- stream.writeBits(1, 0);
- }
- else {
- stream.writeBits(1, 1);
- updateRegionHash(stream, this.regionHashes[playerIndex], hash);
- this.regionHashes[playerIndex] = hash;
- }
- this.localPlayers[playerIndex] = null;
- }
- else {
- boolean needAppearenceUpdate = needAppearenceUpdate(p.getIndex(), p.getAppearence().getMD5AppeareanceDataHash());
- boolean needUpdate = (p.needMasksUpdate()) || (needAppearenceUpdate);
- if (needUpdate)
- appendUpdateBlock(p, updateBlockData, needAppearenceUpdate, false);
- if (p.hasTeleported())
- {
- stream.writeBits(1, 1);
- stream.writeBits(1, needUpdate ? 1 : 0);
- stream.writeBits(2, 3);
- int xOffset = p.getX() - p.getLastWorldTile().getX();
- int yOffset = p.getY() - p.getLastWorldTile().getY();
- int planeOffset = p.getPlane() - p.getLastWorldTile().getPlane();
- if ((Math.abs(p.getX() - p.getLastWorldTile().getX()) <= 14) && (Math.abs(p.getY() - p.getLastWorldTile().getY()) <= 14))
- {
- stream.writeBits(1, 0);
- if (xOffset < 0)
- xOffset += 32;
- if (yOffset < 0)
- yOffset += 32;
- stream.writeBits(12, yOffset + (xOffset << 5) + (planeOffset << 10));
- }
- else {
- stream.writeBits(1, 1);
- stream.writeBits(30, (yOffset & 0x3FFF) + ((xOffset & 0x3FFF) << 14) + ((planeOffset & 0x3) << 28));
- }
- }
- else if ((p.getNextRunDirection() != -1) || (p.getNextWalkDirection() != -1))
- {
- int dx = p.getNextWalkDirection() != -1 ? Utils.DIRECTION_DELTA_X[p.getNextWalkDirection()] : 0;
- int dy = p.getNextWalkDirection() != -1 ? Utils.DIRECTION_DELTA_Y[p.getNextWalkDirection()] : 0;
- boolean running;
- int opcode;
- if (p.getNextRunDirection() != -1)
- {
- dx += Utils.DIRECTION_DELTA_X[p.getNextRunDirection()];
- dy += Utils.DIRECTION_DELTA_Y[p.getNextRunDirection()];
- opcode = Utils.getPlayerRunningDirection(dx, dy);
- if (opcode == -1)
- {
- running = false;
- opcode = Utils.getPlayerWalkingDirection(dx, dy);
- }
- else {
- running = true;
- }
- }
- else {
- running = false;
- opcode = Utils.getPlayerWalkingDirection(dx, dy);
- }
- stream.writeBits(1, 1);
- if ((dx == 0) && (dy == 0))
- {
- stream.writeBits(1, 1);
- stream.writeBits(2, 0);
- if (!needUpdate)
- appendUpdateBlock(p, updateBlockData, needAppearenceUpdate, false);
- }
- else {
- stream.writeBits(1, needUpdate ? 1 : 0);
- stream.writeBits(2, running ? 2 : 1);
- stream.writeBits(running ? 4 : 3, opcode);
- }
- }
- else if (needUpdate)
- {
- stream.writeBits(1, 1);
- stream.writeBits(1, 1);
- stream.writeBits(2, 0);
- }
- else {
- stream.writeBits(1, 0);
- for (int i2 = i + 1; i2 < this.localPlayersIndexesCount; i2++)
- {
- int p2Index = this.localPlayersIndexes[i2];
- if (nsn0 ? (0x1 & this.slotFlags[p2Index]) != 0 : (0x1 & this.slotFlags[p2Index]) == 0)
- continue;
- Player p2 = this.localPlayers[p2Index];
- if ((needsRemove(p2)) || (p2.hasTeleported()) || (p2.getNextWalkDirection() != -1) || (p2.needMasksUpdate()) || (needAppearenceUpdate(p2.getIndex(), p2.getAppearence().getMD5AppeareanceDataHash())))
- break;
- skip++;
- }
- skipPlayers(stream, skip);
- this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
- }
- }
- }
- }
- }
- stream.finishBitAccess();
- }
- private void skipPlayers(OutputStream stream, int amount)
- {
- stream.writeBits(2, amount != 0 ? 3 : amount <= 255 ? 2 : amount <= 31 ? 1 : 0);
- if (amount > 0)
- stream.writeBits(amount <= 255 ? 8 : amount <= 31 ? 5 : 11, amount);
- }
- private void appendUpdateBlock(Player p, OutputStream data, boolean needAppearenceUpdate, boolean added)
- {
- int maskData = 0;
- if (p.getNextAnimation() != null)
- maskData |= 64;
- if (p.getNextGraphics3() != null)
- maskData |= 262144;
- if (p.getTemporaryMoveType() != 0)
- maskData |= 512;
- if (p.getNextGraphics4() != null)
- maskData |= 524288;
- if (!p.getNextHits().isEmpty())
- maskData |= 4;
- if (needAppearenceUpdate)
- maskData |= 8;
- if (p.getNextForceTalk() != null)
- maskData |= 16384;
- if ((added) || (p.isUpdateMovementType()))
- maskData |= 1;
- if ((p.getNextFaceEntity() != -2) || ((added) && (p.getLastFaceEntity() != -1)))
- maskData |= 16;
- if (p.getNextForceMovement() != null)
- maskData |= 4096;
- if ((added) || ((p.getNextFaceWorldTile() != null) && (p.getNextRunDirection() == -1) && (p.getNextWalkDirection() == -1)))
- maskData |= 32;
- if (p.getNextGraphics1() != null)
- maskData |= 2;
- if (p.getNextGraphics2() != null)
- maskData |= 256;
- if (maskData >= 256)
- maskData |= 128;
- if (maskData >= 65536)
- maskData |= 2048;
- data.writeByte(maskData);
- if (maskData >= 256)
- data.writeByte(maskData >> 8);
- if (maskData >= 65536)
- data.writeByte(maskData >> 16);
- if (p.getNextAnimation() != null)
- applyAnimationMask(p, data);
- if (p.getNextGraphics3() != null)
- applyGraphicsMask3(p, data);
- if (p.getTemporaryMoveType() != 0)
- applyTemporaryMoveTypeMask(p, data);
- if (p.getNextGraphics4() != null)
- applyGraphicsMask4(p, data);
- if (!p.getNextHits().isEmpty())
- applyHitsMask(p, data);
- if (needAppearenceUpdate)
- applyAppearanceMask(p, data);
- if (p.getNextForceTalk() != null)
- applyForceTalkMask(p, data);
- if ((added) || (p.isUpdateMovementType()))
- applyMoveTypeMask(p, data);
- if ((p.getNextFaceEntity() != -2) || ((added) && (p.getLastFaceEntity() != -1)))
- applyFaceEntityMask(p, data);
- if (p.getNextForceMovement() != null)
- applyForceMovementMask(p, data);
- if ((added) || ((p.getNextFaceWorldTile() != null) && (p.getNextRunDirection() == -1) && (p.getNextWalkDirection() == -1)))
- applyFaceDirectionMask(p, data);
- if (p.getNextGraphics1() != null)
- applyGraphicsMask1(p, data);
- if (p.getNextGraphics2() != null)
- applyGraphicsMask2(p, data);
- }
- private void applyForceTalkMask(Player p, OutputStream data)
- {
- data.writeString(p.getNextForceTalk().getText());
- }
- private void applyHitsMask(Player p, OutputStream data)
- {
- int count = p.getNextHits().size();
- data.writeByte(count);
- if (count > 0)
- {
- int hp = p.getHitpoints();
- int maxHp = p.getMaxHitpoints();
- if (hp > maxHp)
- hp = maxHp;
- int hpBarPercentage = (hp != 0) && (maxHp != 0) ? hp * 255 / maxHp : 0;
- for (Iterator iterator = p.getNextHits().iterator(); iterator.hasNext(); data.writeByteC(hpBarPercentage))
- {
- Hit hit = (Hit)iterator.next();
- boolean interactingWith = hit.interactingWith(this.player, p);
- if ((hit.missed()) && (!interactingWith)) {
- data.writeSmart(32766);
- }
- else if (hit.getSoaking() != null)
- {
- data.writeSmart(32767);
- data.writeSmart(hit.getMark(this.player, p));
- data.writeSmart(hit.getDamage());
- data.writeSmart(hit.getSoaking().getMark(this.player, p));
- data.writeSmart(hit.getSoaking().getDamage());
- }
- else {
- data.writeSmart(hit.getMark(this.player, p));
- data.writeSmart(hit.getDamage());
- }
- data.writeSmart(hit.getDelay());
- }
- }
- }
- private void applyFaceEntityMask(Player p, OutputStream data)
- {
- data.writeShort128(p.getNextFaceEntity() != -2 ? p.getNextFaceEntity() : p.getLastFaceEntity());
- }
- private void applyFaceDirectionMask(Player p, OutputStream data)
- {
- data.writeShort(p.getDirection());
- }
- private void applyMoveTypeMask(Player p, OutputStream data)
- {
- data.write128Byte(p.getRun() ? 2 : 1);
- }
- private void applyTemporaryMoveTypeMask(Player p, OutputStream data)
- {
- data.writeByteC(p.getTemporaryMoveType());
- }
- private void applyGraphicsMask1(Player p, OutputStream data)
- {
- data.writeShort(p.getNextGraphics1().getId());
- data.writeIntLE(p.getNextGraphics1().getSettingsHash());
- data.writeByte128(p.getNextGraphics1().getSettings2Hash());
- }
- private void applyGraphicsMask2(Player p, OutputStream data)
- {
- data.writeShortLE128(p.getNextGraphics2().getId());
- data.writeIntV2(p.getNextGraphics2().getSettingsHash());
- data.writeByteC(p.getNextGraphics2().getSettings2Hash());
- }
- private void applyGraphicsMask3(Player p, OutputStream data)
- {
- data.writeShortLE128(p.getNextGraphics3().getId());
- data.writeIntV2(p.getNextGraphics3().getSettingsHash());
- data.writeByteC(p.getNextGraphics3().getSettings2Hash());
- }
- private void applyGraphicsMask4(Player p, OutputStream data)
- {
- data.writeShortLE(p.getNextGraphics4().getId());
- data.writeIntV2(p.getNextGraphics4().getSettingsHash());
- data.writeByteC(p.getNextGraphics4().getSettings2Hash());
- }
- private void applyAnimationMask(Player p, OutputStream data)
- {
- int[] ai;
- int j = (ai = p.getNextAnimation().getIds()).length;
- for (int i = 0; i < j; i++)
- {
- int id = ai[i];
- data.writeShortLE(id);
- }
- data.writeByte128(p.getNextAnimation().getSpeed());
- }
- private void applyAppearanceMask(Player p, OutputStream data) {
- byte[] renderData = p.getAppearence().getAppeareanceData();
- this.totalRenderDataSentLength += renderData.length;
- this.cachedAppearencesHashes[p.getIndex()] = p.getAppearence()
- .getMD5AppeareanceDataHash();
- data.write128Byte(renderData.length);
- data.writeBytes(renderData);
- }
- private void applyForceMovementMask(Player p, OutputStream data)
- {
- data.write128Byte(p.getNextForceMovement().getToFirstTile().getX() - p.getX());
- data.writeByte(p.getNextForceMovement().getToFirstTile().getY() - p.getY());
- data.writeByte128(p.getNextForceMovement().getToSecondTile() != null ? p.getNextForceMovement().getToSecondTile().getX() - p.getX() : 0);
- data.writeByte128(p.getNextForceMovement().getToSecondTile() != null ? p.getNextForceMovement().getToSecondTile().getY() - p.getY() : 0);
- data.writeShortLE(p.getNextForceMovement().getFirstTileTicketDelay() * 30);
- data.writeShortLE128(p.getNextForceMovement().getToSecondTile() != null ? p.getNextForceMovement().getSecondTileTicketDelay() * 30 : 0);
- data.writeByte128(p.getNextForceMovement().getDirection());
- }
- public OutputStream createPacketAndProcess() {
- OutputStream stream = new OutputStream();
- OutputStream updateBlockData = new OutputStream();
- stream.writePacketVarShort(69);
- processLocalPlayers(stream, updateBlockData, true);
- processLocalPlayers(stream, updateBlockData, false);
- processOutsidePlayers(stream, updateBlockData, true);
- processOutsidePlayers(stream, updateBlockData, false);
- stream.writeBytes(updateBlockData.getBuffer(), 0, updateBlockData.getOffset());
- stream.endPacketVarShort();
- this.totalRenderDataSentLength = 0;
- this.localPlayersIndexesCount = 0;
- this.outPlayersIndexesCount = 0;
- for (int playerIndex = 1; playerIndex < 2048; playerIndex++)
- {
- int tmp92_91 = playerIndex;
- byte[] tmp92_88 = this.slotFlags; tmp92_88[tmp92_91] = (byte)(tmp92_88[tmp92_91] >> 1);
- Player player = this.localPlayers[playerIndex];
- if (player == null)
- this.outPlayersIndexes[(this.outPlayersIndexesCount++)] = playerIndex;
- else
- this.localPlayersIndexes[(this.localPlayersIndexesCount++)] = playerIndex;
- }
- return stream;
- }
- }
Add Comment
Please, Sign In to add comment