Guest User

Untitled

a guest
May 20th, 2018
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.31 KB | None | 0 0
  1. package com.rs.game.player;
  2.  
  3. import com.rs.game.Animation;
  4. import com.rs.game.EntityList;
  5. import com.rs.game.ForceMovement;
  6. import com.rs.game.ForceTalk;
  7. import com.rs.game.Graphics;
  8. import com.rs.game.Hit;
  9. import com.rs.game.World;
  10. import com.rs.game.WorldTile;
  11. import com.rs.io.OutputStream;
  12. import com.rs.utils.Utils;
  13. import java.util.ArrayList;
  14. import java.util.Iterator;
  15.  
  16. public final class LocalPlayerUpdate
  17. {
  18. private Player player;
  19. private byte[] slotFlags;
  20. private Player[] localPlayers;
  21. private int[] localPlayersIndexes;
  22. private int localPlayersIndexesCount;
  23. private int[] outPlayersIndexes;
  24. private int outPlayersIndexesCount;
  25. private int[] regionHashes;
  26. private byte[][] cachedAppearencesHashes;
  27. private int totalRenderDataSentLength;
  28.  
  29. public Player[] getLocalPlayers()
  30. {
  31. return this.localPlayers;
  32. }
  33.  
  34. public boolean needAppearenceUpdate(int index, byte[] hash)
  35. {
  36. return true;
  37. }
  38.  
  39. public LocalPlayerUpdate(Player player)
  40. {
  41. this.player = player;
  42. this.slotFlags = new byte[2048];
  43. this.localPlayers = new Player[2048];
  44. this.localPlayersIndexes = new int[2000];
  45. this.outPlayersIndexes = new int[2048];
  46. this.regionHashes = new int[2048];
  47. this.cachedAppearencesHashes = new byte[2000][];
  48. }
  49.  
  50. public void init(OutputStream stream)
  51. {
  52. stream.initBitAccess();
  53. stream.writeBits(30, this.player.get30BitsLocationHash());
  54. this.localPlayers[this.player.getIndex()] = this.player;
  55. this.localPlayersIndexes[(this.localPlayersIndexesCount++)] = this.player.getIndex();
  56. for (int playerIndex = 1; playerIndex < 2048; playerIndex++) {
  57. if (playerIndex == this.player.getIndex())
  58. continue;
  59. Player player = (Player)World.getPlayers().get(playerIndex);
  60. stream.writeBits(18, this.regionHashes[playerIndex] = player != null ? player.get18BitsLocationHash() : 0);
  61. this.outPlayersIndexes[(this.outPlayersIndexesCount++)] = playerIndex;
  62. }
  63.  
  64. stream.finishBitAccess();
  65. }
  66.  
  67. private boolean needsRemove(Player p)
  68. {
  69. return (p.hasFinished()) || (!this.player.withinDistance(p));
  70. }
  71.  
  72. private boolean needsAdd(Player p)
  73. {
  74. return (p != null) && (!p.hasFinished()) && (this.player.withinDistance(p));
  75. }
  76.  
  77. private void updateRegionHash(OutputStream stream, int oldHash, int newHash)
  78. {
  79. int oldX = (oldHash & 0xFF72) >> 8;
  80. int oldY = 0xFF & oldHash;
  81. int oldPlane = oldHash >> 16;
  82. int newX = (newHash & 0xFF72) >> 8;
  83. int newY = 0xFF & newHash;
  84. int newPlane = newHash >> 16;
  85. int planeOffset = newPlane - oldPlane;
  86. if ((oldX == newX) && (oldY == newY))
  87. {
  88. stream.writeBits(2, 1);
  89. stream.writeBits(2, planeOffset);
  90. }
  91. else if ((Math.abs(newX - oldX) <= 1) && (Math.abs(newY - oldY) <= 1))
  92. {
  93. int dx = newX - oldX;
  94. int dy = newY - oldY;
  95. int opcode;
  96. if ((dx == -1) && (dy == -1)) {
  97. opcode = 0;
  98. }
  99. else
  100. {
  101. if ((dx == 1) && (dy == -1)) {
  102. opcode = 2;
  103. }
  104. else
  105. {
  106. if ((dx == -1) && (dy == 1)) {
  107. opcode = 5;
  108. }
  109. else
  110. {
  111. if ((dx == 1) && (dy == 1)) {
  112. opcode = 7;
  113. }
  114. else
  115. {
  116. if (dy == -1) {
  117. opcode = 1;
  118. }
  119. else
  120. {
  121. if (dx == -1) {
  122. opcode = 3;
  123. }
  124. else
  125. {
  126. if (dx == 1)
  127. opcode = 4;
  128. else
  129. opcode = 6;
  130. }
  131. }
  132. }
  133. }
  134. }
  135. }
  136. stream.writeBits(2, 2);
  137. stream.writeBits(5, (planeOffset << 3) + (opcode & 0x7));
  138. }
  139. else {
  140. int xOffset = newX - oldX;
  141. int yOffset = newY - oldY;
  142. stream.writeBits(2, 3);
  143. stream.writeBits(18, (yOffset & 0xFF) + ((xOffset & 0xFF) << 8) + (planeOffset << 16));
  144. }
  145. }
  146.  
  147. private void processOutsidePlayers(OutputStream stream, OutputStream updateBlockData, boolean nsn2)
  148. {
  149. stream.initBitAccess();
  150. int skip = 0;
  151. for (int i = 0; i < this.outPlayersIndexesCount; i++)
  152. {
  153. int playerIndex = this.outPlayersIndexes[i];
  154. if (nsn2 ? (0x1 & this.slotFlags[playerIndex]) != 0 : (0x1 & this.slotFlags[playerIndex]) == 0) {
  155. if (skip > 0)
  156. {
  157. this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
  158. skip--;
  159. }
  160. else {
  161. Player p = (Player)World.getPlayers().get(playerIndex);
  162. if (needsAdd(p))
  163. {
  164. stream.writeBits(1, 1);
  165. stream.writeBits(2, 0);
  166. int hash = p.get18BitsLocationHash();
  167. if (hash == this.regionHashes[playerIndex])
  168. {
  169. stream.writeBits(1, 0);
  170. }
  171. else {
  172. stream.writeBits(1, 1);
  173. updateRegionHash(stream, this.regionHashes[playerIndex], hash);
  174. this.regionHashes[playerIndex] = hash;
  175. }
  176. stream.writeBits(6, p.getXInRegion());
  177. stream.writeBits(6, p.getYInRegion());
  178. boolean needAppearenceUpdate = needAppearenceUpdate(p.getIndex(), p.getAppearence().getMD5AppeareanceDataHash());
  179. appendUpdateBlock(p, updateBlockData, needAppearenceUpdate, true);
  180. stream.writeBits(1, 1);
  181. this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
  182. this.localPlayers[p.getIndex()] = p;
  183. }
  184. else {
  185. int hash = p != null ? p.get18BitsLocationHash() : this.regionHashes[playerIndex];
  186. if ((p != null) && (hash != this.regionHashes[playerIndex]))
  187. {
  188. stream.writeBits(1, 1);
  189. updateRegionHash(stream, this.regionHashes[playerIndex], hash);
  190. this.regionHashes[playerIndex] = hash;
  191. }
  192. else {
  193. stream.writeBits(1, 0);
  194. for (int i2 = i + 1; i2 < this.outPlayersIndexesCount; i2++)
  195. {
  196. int p2Index = this.outPlayersIndexes[i2];
  197. if (nsn2 ? (0x1 & this.slotFlags[p2Index]) == 0 : (0x1 & this.slotFlags[p2Index]) != 0)
  198. continue;
  199. Player p2 = (Player)World.getPlayers().get(p2Index);
  200. if ((needsAdd(p2)) || ((p2 != null) && (p2.get18BitsLocationHash() != this.regionHashes[p2Index])))
  201. break;
  202. skip++;
  203. }
  204.  
  205. skipPlayers(stream, skip);
  206. this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
  207. }
  208. }
  209. }
  210. }
  211. }
  212. stream.finishBitAccess();
  213. }
  214.  
  215. private void processLocalPlayers(OutputStream stream, OutputStream updateBlockData, boolean nsn0)
  216. {
  217. stream.initBitAccess();
  218. int skip = 0;
  219. for (int i = 0; i < this.localPlayersIndexesCount; i++)
  220. {
  221. int playerIndex = this.localPlayersIndexes[i];
  222. if (nsn0 ? (0x1 & this.slotFlags[playerIndex]) == 0 : (0x1 & this.slotFlags[playerIndex]) != 0) {
  223. if (skip > 0)
  224. {
  225. this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
  226. skip--;
  227. }
  228. else {
  229. Player p = this.localPlayers[playerIndex];
  230. if (needsRemove(p))
  231. {
  232. stream.writeBits(1, 1);
  233. stream.writeBits(1, 0);
  234. stream.writeBits(2, 0);
  235. this.regionHashes[playerIndex] = (p.getLastWorldTile() != null ? p.getLastWorldTile().get18BitsLocationHash() : p.get18BitsLocationHash());
  236. int hash = p.get18BitsLocationHash();
  237. if (hash == this.regionHashes[playerIndex])
  238. {
  239. stream.writeBits(1, 0);
  240. }
  241. else {
  242. stream.writeBits(1, 1);
  243. updateRegionHash(stream, this.regionHashes[playerIndex], hash);
  244. this.regionHashes[playerIndex] = hash;
  245. }
  246. this.localPlayers[playerIndex] = null;
  247. }
  248. else {
  249. boolean needAppearenceUpdate = needAppearenceUpdate(p.getIndex(), p.getAppearence().getMD5AppeareanceDataHash());
  250. boolean needUpdate = (p.needMasksUpdate()) || (needAppearenceUpdate);
  251. if (needUpdate)
  252. appendUpdateBlock(p, updateBlockData, needAppearenceUpdate, false);
  253. if (p.hasTeleported())
  254. {
  255. stream.writeBits(1, 1);
  256. stream.writeBits(1, needUpdate ? 1 : 0);
  257. stream.writeBits(2, 3);
  258. int xOffset = p.getX() - p.getLastWorldTile().getX();
  259. int yOffset = p.getY() - p.getLastWorldTile().getY();
  260. int planeOffset = p.getPlane() - p.getLastWorldTile().getPlane();
  261. if ((Math.abs(p.getX() - p.getLastWorldTile().getX()) <= 14) && (Math.abs(p.getY() - p.getLastWorldTile().getY()) <= 14))
  262. {
  263. stream.writeBits(1, 0);
  264. if (xOffset < 0)
  265. xOffset += 32;
  266. if (yOffset < 0)
  267. yOffset += 32;
  268. stream.writeBits(12, yOffset + (xOffset << 5) + (planeOffset << 10));
  269. }
  270. else {
  271. stream.writeBits(1, 1);
  272. stream.writeBits(30, (yOffset & 0x3FFF) + ((xOffset & 0x3FFF) << 14) + ((planeOffset & 0x3) << 28));
  273. }
  274. }
  275. else if ((p.getNextRunDirection() != -1) || (p.getNextWalkDirection() != -1))
  276. {
  277. int dx = p.getNextWalkDirection() != -1 ? Utils.DIRECTION_DELTA_X[p.getNextWalkDirection()] : 0;
  278. int dy = p.getNextWalkDirection() != -1 ? Utils.DIRECTION_DELTA_Y[p.getNextWalkDirection()] : 0;
  279. boolean running;
  280. int opcode;
  281. if (p.getNextRunDirection() != -1)
  282. {
  283. dx += Utils.DIRECTION_DELTA_X[p.getNextRunDirection()];
  284. dy += Utils.DIRECTION_DELTA_Y[p.getNextRunDirection()];
  285. opcode = Utils.getPlayerRunningDirection(dx, dy);
  286. if (opcode == -1)
  287. {
  288. running = false;
  289. opcode = Utils.getPlayerWalkingDirection(dx, dy);
  290. }
  291. else {
  292. running = true;
  293. }
  294. }
  295. else {
  296. running = false;
  297. opcode = Utils.getPlayerWalkingDirection(dx, dy);
  298. }
  299. stream.writeBits(1, 1);
  300. if ((dx == 0) && (dy == 0))
  301. {
  302. stream.writeBits(1, 1);
  303. stream.writeBits(2, 0);
  304. if (!needUpdate)
  305. appendUpdateBlock(p, updateBlockData, needAppearenceUpdate, false);
  306. }
  307. else {
  308. stream.writeBits(1, needUpdate ? 1 : 0);
  309. stream.writeBits(2, running ? 2 : 1);
  310. stream.writeBits(running ? 4 : 3, opcode);
  311. }
  312. }
  313. else if (needUpdate)
  314. {
  315. stream.writeBits(1, 1);
  316. stream.writeBits(1, 1);
  317. stream.writeBits(2, 0);
  318. }
  319. else {
  320. stream.writeBits(1, 0);
  321. for (int i2 = i + 1; i2 < this.localPlayersIndexesCount; i2++)
  322. {
  323. int p2Index = this.localPlayersIndexes[i2];
  324. if (nsn0 ? (0x1 & this.slotFlags[p2Index]) != 0 : (0x1 & this.slotFlags[p2Index]) == 0)
  325. continue;
  326. Player p2 = this.localPlayers[p2Index];
  327. if ((needsRemove(p2)) || (p2.hasTeleported()) || (p2.getNextWalkDirection() != -1) || (p2.needMasksUpdate()) || (needAppearenceUpdate(p2.getIndex(), p2.getAppearence().getMD5AppeareanceDataHash())))
  328. break;
  329. skip++;
  330. }
  331.  
  332. skipPlayers(stream, skip);
  333. this.slotFlags[playerIndex] = (byte)(this.slotFlags[playerIndex] | 0x2);
  334. }
  335. }
  336. }
  337. }
  338. }
  339. stream.finishBitAccess();
  340. }
  341.  
  342. private void skipPlayers(OutputStream stream, int amount)
  343. {
  344. stream.writeBits(2, amount != 0 ? 3 : amount <= 255 ? 2 : amount <= 31 ? 1 : 0);
  345. if (amount > 0)
  346. stream.writeBits(amount <= 255 ? 8 : amount <= 31 ? 5 : 11, amount);
  347. }
  348.  
  349. private void appendUpdateBlock(Player p, OutputStream data, boolean needAppearenceUpdate, boolean added)
  350. {
  351. int maskData = 0;
  352. if (p.getNextAnimation() != null)
  353. maskData |= 64;
  354. if (p.getNextGraphics3() != null)
  355. maskData |= 262144;
  356. if (p.getTemporaryMoveType() != 0)
  357. maskData |= 512;
  358. if (p.getNextGraphics4() != null)
  359. maskData |= 524288;
  360. if (!p.getNextHits().isEmpty())
  361. maskData |= 4;
  362. if (needAppearenceUpdate)
  363. maskData |= 8;
  364. if (p.getNextForceTalk() != null)
  365. maskData |= 16384;
  366. if ((added) || (p.isUpdateMovementType()))
  367. maskData |= 1;
  368. if ((p.getNextFaceEntity() != -2) || ((added) && (p.getLastFaceEntity() != -1)))
  369. maskData |= 16;
  370. if (p.getNextForceMovement() != null)
  371. maskData |= 4096;
  372. if ((added) || ((p.getNextFaceWorldTile() != null) && (p.getNextRunDirection() == -1) && (p.getNextWalkDirection() == -1)))
  373. maskData |= 32;
  374. if (p.getNextGraphics1() != null)
  375. maskData |= 2;
  376. if (p.getNextGraphics2() != null)
  377. maskData |= 256;
  378. if (maskData >= 256)
  379. maskData |= 128;
  380. if (maskData >= 65536)
  381. maskData |= 2048;
  382. data.writeByte(maskData);
  383. if (maskData >= 256)
  384. data.writeByte(maskData >> 8);
  385. if (maskData >= 65536)
  386. data.writeByte(maskData >> 16);
  387. if (p.getNextAnimation() != null)
  388. applyAnimationMask(p, data);
  389. if (p.getNextGraphics3() != null)
  390. applyGraphicsMask3(p, data);
  391. if (p.getTemporaryMoveType() != 0)
  392. applyTemporaryMoveTypeMask(p, data);
  393. if (p.getNextGraphics4() != null)
  394. applyGraphicsMask4(p, data);
  395. if (!p.getNextHits().isEmpty())
  396. applyHitsMask(p, data);
  397. if (needAppearenceUpdate)
  398. applyAppearanceMask(p, data);
  399. if (p.getNextForceTalk() != null)
  400. applyForceTalkMask(p, data);
  401. if ((added) || (p.isUpdateMovementType()))
  402. applyMoveTypeMask(p, data);
  403. if ((p.getNextFaceEntity() != -2) || ((added) && (p.getLastFaceEntity() != -1)))
  404. applyFaceEntityMask(p, data);
  405. if (p.getNextForceMovement() != null)
  406. applyForceMovementMask(p, data);
  407. if ((added) || ((p.getNextFaceWorldTile() != null) && (p.getNextRunDirection() == -1) && (p.getNextWalkDirection() == -1)))
  408. applyFaceDirectionMask(p, data);
  409. if (p.getNextGraphics1() != null)
  410. applyGraphicsMask1(p, data);
  411. if (p.getNextGraphics2() != null)
  412. applyGraphicsMask2(p, data);
  413. }
  414.  
  415. private void applyForceTalkMask(Player p, OutputStream data)
  416. {
  417. data.writeString(p.getNextForceTalk().getText());
  418. }
  419.  
  420. private void applyHitsMask(Player p, OutputStream data)
  421. {
  422. int count = p.getNextHits().size();
  423. data.writeByte(count);
  424. if (count > 0)
  425. {
  426. int hp = p.getHitpoints();
  427. int maxHp = p.getMaxHitpoints();
  428. if (hp > maxHp)
  429. hp = maxHp;
  430. int hpBarPercentage = (hp != 0) && (maxHp != 0) ? hp * 255 / maxHp : 0;
  431. for (Iterator iterator = p.getNextHits().iterator(); iterator.hasNext(); data.writeByteC(hpBarPercentage))
  432. {
  433. Hit hit = (Hit)iterator.next();
  434. boolean interactingWith = hit.interactingWith(this.player, p);
  435. if ((hit.missed()) && (!interactingWith)) {
  436. data.writeSmart(32766);
  437. }
  438. else if (hit.getSoaking() != null)
  439. {
  440. data.writeSmart(32767);
  441. data.writeSmart(hit.getMark(this.player, p));
  442. data.writeSmart(hit.getDamage());
  443. data.writeSmart(hit.getSoaking().getMark(this.player, p));
  444. data.writeSmart(hit.getSoaking().getDamage());
  445. }
  446. else {
  447. data.writeSmart(hit.getMark(this.player, p));
  448. data.writeSmart(hit.getDamage());
  449. }
  450. data.writeSmart(hit.getDelay());
  451. }
  452. }
  453. }
  454.  
  455. private void applyFaceEntityMask(Player p, OutputStream data)
  456. {
  457. data.writeShort128(p.getNextFaceEntity() != -2 ? p.getNextFaceEntity() : p.getLastFaceEntity());
  458. }
  459.  
  460. private void applyFaceDirectionMask(Player p, OutputStream data)
  461. {
  462. data.writeShort(p.getDirection());
  463. }
  464.  
  465. private void applyMoveTypeMask(Player p, OutputStream data)
  466. {
  467. data.write128Byte(p.getRun() ? 2 : 1);
  468. }
  469.  
  470. private void applyTemporaryMoveTypeMask(Player p, OutputStream data)
  471. {
  472. data.writeByteC(p.getTemporaryMoveType());
  473. }
  474.  
  475. private void applyGraphicsMask1(Player p, OutputStream data)
  476. {
  477. data.writeShort(p.getNextGraphics1().getId());
  478. data.writeIntLE(p.getNextGraphics1().getSettingsHash());
  479. data.writeByte128(p.getNextGraphics1().getSettings2Hash());
  480. }
  481.  
  482. private void applyGraphicsMask2(Player p, OutputStream data)
  483. {
  484. data.writeShortLE128(p.getNextGraphics2().getId());
  485. data.writeIntV2(p.getNextGraphics2().getSettingsHash());
  486. data.writeByteC(p.getNextGraphics2().getSettings2Hash());
  487. }
  488.  
  489. private void applyGraphicsMask3(Player p, OutputStream data)
  490. {
  491. data.writeShortLE128(p.getNextGraphics3().getId());
  492. data.writeIntV2(p.getNextGraphics3().getSettingsHash());
  493. data.writeByteC(p.getNextGraphics3().getSettings2Hash());
  494. }
  495.  
  496. private void applyGraphicsMask4(Player p, OutputStream data)
  497. {
  498. data.writeShortLE(p.getNextGraphics4().getId());
  499. data.writeIntV2(p.getNextGraphics4().getSettingsHash());
  500. data.writeByteC(p.getNextGraphics4().getSettings2Hash());
  501. }
  502.  
  503. private void applyAnimationMask(Player p, OutputStream data)
  504. {
  505. int[] ai;
  506. int j = (ai = p.getNextAnimation().getIds()).length;
  507. for (int i = 0; i < j; i++)
  508. {
  509. int id = ai[i];
  510. data.writeShortLE(id);
  511. }
  512.  
  513. data.writeByte128(p.getNextAnimation().getSpeed());
  514. }
  515.  
  516. private void applyAppearanceMask(Player p, OutputStream data) {
  517. byte[] renderData = p.getAppearence().getAppeareanceData();
  518. this.totalRenderDataSentLength += renderData.length;
  519. this.cachedAppearencesHashes[p.getIndex()] = p.getAppearence()
  520. .getMD5AppeareanceDataHash();
  521. data.write128Byte(renderData.length);
  522. data.writeBytes(renderData);
  523. }
  524.  
  525. private void applyForceMovementMask(Player p, OutputStream data)
  526. {
  527. data.write128Byte(p.getNextForceMovement().getToFirstTile().getX() - p.getX());
  528. data.writeByte(p.getNextForceMovement().getToFirstTile().getY() - p.getY());
  529. data.writeByte128(p.getNextForceMovement().getToSecondTile() != null ? p.getNextForceMovement().getToSecondTile().getX() - p.getX() : 0);
  530. data.writeByte128(p.getNextForceMovement().getToSecondTile() != null ? p.getNextForceMovement().getToSecondTile().getY() - p.getY() : 0);
  531. data.writeShortLE(p.getNextForceMovement().getFirstTileTicketDelay() * 30);
  532. data.writeShortLE128(p.getNextForceMovement().getToSecondTile() != null ? p.getNextForceMovement().getSecondTileTicketDelay() * 30 : 0);
  533. data.writeByte128(p.getNextForceMovement().getDirection());
  534. }
  535.  
  536. public OutputStream createPacketAndProcess() {
  537. OutputStream stream = new OutputStream();
  538. OutputStream updateBlockData = new OutputStream();
  539. stream.writePacketVarShort(69);
  540. processLocalPlayers(stream, updateBlockData, true);
  541. processLocalPlayers(stream, updateBlockData, false);
  542. processOutsidePlayers(stream, updateBlockData, true);
  543. processOutsidePlayers(stream, updateBlockData, false);
  544. stream.writeBytes(updateBlockData.getBuffer(), 0, updateBlockData.getOffset());
  545. stream.endPacketVarShort();
  546. this.totalRenderDataSentLength = 0;
  547. this.localPlayersIndexesCount = 0;
  548. this.outPlayersIndexesCount = 0;
  549. for (int playerIndex = 1; playerIndex < 2048; playerIndex++)
  550. {
  551. int tmp92_91 = playerIndex;
  552. byte[] tmp92_88 = this.slotFlags; tmp92_88[tmp92_91] = (byte)(tmp92_88[tmp92_91] >> 1);
  553. Player player = this.localPlayers[playerIndex];
  554. if (player == null)
  555. this.outPlayersIndexes[(this.outPlayersIndexesCount++)] = playerIndex;
  556. else
  557. this.localPlayersIndexes[(this.localPlayersIndexesCount++)] = playerIndex;
  558. }
  559. return stream;
  560. }
  561. }
Add Comment
Please, Sign In to add comment