Advertisement
Tyluur

Untitled

Jan 8th, 2012
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.88 KB | None | 0 0
  1. package com.rs2.model.players;
  2.  
  3. import java.util.Iterator;
  4.  
  5. import com.rs2.Constants;
  6. import com.rs2.model.Position;
  7. import com.rs2.model.World;
  8. import com.rs2.model.players.Player.LoginStages;
  9. import com.rs2.net.StreamBuffer;
  10. import com.rs2.util.Misc;
  11. import com.rs2.util.NameUtil;
  12.  
  13. /*
  14. * This file is part of RuneSource.
  15. *
  16. * RuneSource is free software: you can redistribute it and/or modify
  17. * it under the terms of the GNU General Public License as published by
  18. * the Free Software Foundation, either version 3 of the License, or
  19. * (at your option) any later version.
  20. *
  21. * RuneSource is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with RuneSource. If not, see <http://www.gnu.org/licenses/>.
  28. */
  29.  
  30. /**
  31. * Provides static utility methods for updating players.
  32. *
  33. * @author blakeman8192
  34. */
  35. public final class PlayerUpdating {
  36.  
  37. /**
  38. * Updates the player.
  39. *
  40. * @param player
  41. * the player
  42. */
  43. public static void update(Player player) {
  44. // XXX: The buffer sizes may need to be tuned.
  45. StreamBuffer.OutBuffer out = StreamBuffer.newOutBuffer(2048);
  46. StreamBuffer.OutBuffer block = StreamBuffer.newOutBuffer(1024);
  47.  
  48. // Initialize the update packet.
  49. out.writeVariableShortPacketHeader(player.getEncryptor(), 81);
  50. out.setAccessType(StreamBuffer.AccessType.BIT_ACCESS);
  51.  
  52. // Update this player.
  53. PlayerUpdating.updateLocalPlayerMovement(player, out);
  54. if (player.getUpdateFlags().isUpdateRequired()) {
  55. PlayerUpdating.updateState(player, block, false, true);
  56. }
  57.  
  58. // Update other local players.
  59. out.writeBits(8, player.getPlayers().size());
  60. for (Iterator<Player> i = player.getPlayers().iterator(); i.hasNext();) {
  61. Player other = i.next();
  62. if (other.getPosition().isViewableFrom(player.getPosition()) && other.getLoginStage() == LoginStages.LOGGED_IN && !other.needsPlacement()) {
  63. PlayerUpdating.updateOtherPlayerMovement(other, out);
  64. if (other.getUpdateFlags().isUpdateRequired()) {
  65. PlayerUpdating.updateState(other, block, false, false);
  66. }
  67. } else {
  68. out.writeBit(true);
  69. out.writeBits(2, 3);
  70. i.remove();
  71. }
  72. }
  73.  
  74. // Update the local player list.
  75. for (int i = 0; i < World.getPlayers().length; i++) {
  76. if (player.getPlayers().size() >= 255) {
  77. // Player limit has been reached.
  78. break;
  79. }
  80. Player other = World.getPlayers()[i];
  81. if (other == null || other == player || other.getLoginStage() != LoginStages.LOGGED_IN) {
  82. continue;
  83. }
  84. if (!player.getPlayers().contains(other) && other.getPosition().isViewableFrom(player.getPosition())) {
  85. player.getPlayers().add(other);
  86. PlayerUpdating.addPlayer(out, player, other);
  87. PlayerUpdating.updateState(other, block, true, false);
  88. }
  89. }
  90.  
  91. // Append the attributes block to the main packet.
  92. if (block.getBuffer().position() > 0) {
  93. out.writeBits(11, 2047);
  94. out.setAccessType(StreamBuffer.AccessType.BYTE_ACCESS);
  95. out.writeBytes(block.getBuffer());
  96. } else {
  97. out.setAccessType(StreamBuffer.AccessType.BYTE_ACCESS);
  98. }
  99.  
  100. // Finish the packet and send it.
  101. out.finishVariableShortPacketHeader();
  102. player.send(out.getBuffer());
  103. }
  104.  
  105. /**
  106. * Appends the state of a player's chat to a buffer.
  107. *
  108. * @param player
  109. * the player
  110. * @param out
  111. * the buffer
  112. */
  113. public static void appendChat(Player player, StreamBuffer.OutBuffer out) {
  114. out.writeShort(((player.getChatColor() & 0xff) << 8) + (player.getChatEffects() & 0xff), StreamBuffer.ByteOrder.LITTLE);
  115. out.writeByte(player.getStaffRights());
  116. out.writeByte(player.getChatText().length, StreamBuffer.ValueType.C);
  117. out.writeBytesReverse(player.getChatText());
  118. }
  119.  
  120. /**
  121. * Appends the state of a player's appearance to a buffer.
  122. *
  123. * @param player
  124. * the player
  125. * @param out
  126. * the buffer
  127. */
  128. public static void appendAppearance(Player player, StreamBuffer.OutBuffer out) {
  129. StreamBuffer.OutBuffer block = StreamBuffer.newOutBuffer(128);
  130.  
  131. block.writeByte(player.getGender()); // Gender
  132. block.writeByte(player.getPrayerIcon());
  133. //System.out.println("gg"+player.getPrayerIcon());
  134. block.writeByte(-1);
  135. block.writeByte(-1);
  136.  
  137. // Hat.
  138. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_HEAD)) {
  139. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_HEAD).getId());
  140. } else {
  141. block.writeByte(0);
  142. }
  143.  
  144. // Cape.
  145. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_CAPE)) {
  146. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_CAPE).getId());
  147. } else {
  148. block.writeByte(0);
  149. }
  150.  
  151. // Amulet.
  152. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_AMULET)) {
  153. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_AMULET).getId());
  154. } else {
  155. block.writeByte(0);
  156. }
  157.  
  158. // Weapon.
  159. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_WEAPON)) {
  160. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_WEAPON).getId());
  161. } else {
  162. block.writeByte(0);
  163. }
  164.  
  165. // Chest.
  166. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_CHEST)) {
  167. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_CHEST).getId());
  168. } else {
  169. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_CHEST]);
  170. }
  171.  
  172. // Shield.
  173. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_SHIELD)) {
  174. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_SHIELD).getId());
  175. } else {
  176. block.writeByte(0);
  177. }
  178.  
  179. Item chest = player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_CHEST);
  180. if (chest != null) {
  181. if (!Equipment.isPlatebody(chest.getId())) {
  182. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_ARMS]);
  183. } else {
  184. block.writeShort(0x200 + chest.getId());
  185. }
  186. } else {
  187. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_ARMS]);
  188. }
  189.  
  190. // Legs.
  191. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_LEGS)) {
  192. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_LEGS).getId());
  193. } else {
  194. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_LEGS]);
  195. }
  196.  
  197. // Head (with a hat already on).
  198. Item helm = player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_HEAD);
  199. if (helm != null) {
  200. if (!Equipment.isFullMask(helm.getId()) && !Equipment.isFullHelm(helm.getId())) {
  201. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_HEAD]);
  202. } else {
  203. block.writeByte(0);
  204. }
  205. } else {
  206. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_HEAD]);
  207. }
  208.  
  209. // Hands.
  210. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_HANDS)) {
  211. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_HANDS).getId());
  212. } else {
  213. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_HANDS]);
  214. }
  215.  
  216. // Feet.
  217. if (player.getEquipment().getItemContainer().isSlotUsed(Constants.EQUIPMENT_SLOT_FEET)) {
  218. block.writeShort(0x200 + player.getEquipment().getItemContainer().get(Constants.EQUIPMENT_SLOT_FEET).getId());
  219. } else {
  220. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_FEET]);
  221. }
  222.  
  223. // Beard.
  224. if (helm != null) {
  225. if (!Equipment.isFullMask(helm.getId()) && !Equipment.isFullHelm(helm.getId()) &&
  226. player.getGender() == Constants.GENDER_MALE) {
  227. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_BEARD]);
  228. } else {
  229. block.writeByte(0);
  230. }
  231. } else {
  232. block.writeShort(0x100 + player.getAppearance()[Constants.APPEARANCE_SLOT_BEARD]);
  233. }
  234.  
  235. // Player colors
  236. block.writeByte(player.getColors()[0]);
  237. block.writeByte(player.getColors()[1]);
  238. block.writeByte(player.getColors()[2]);
  239. block.writeByte(player.getColors()[3]);
  240. block.writeByte(player.getColors()[4]);
  241. // Movement animations
  242. Item item = player.getEquipment().
  243. getItemContainer().get(Constants.EQUIPMENT_SLOT_WEAPON);
  244. block.writeShort(player.getEquipment().getStandAnim(item)); // stand
  245. block.writeShort(0x337); // stand turn
  246. block.writeShort(player.getEquipment().getWalkAnim(item)); // walk
  247. block.writeShort(0x334); // turn 180
  248. block.writeShort(0x335); // turn 90 cw
  249. block.writeShort(0x336); // turn 90 ccw
  250. block.writeShort(player.getEquipment().getRunAnim(item)); // run
  251.  
  252. block.writeLong(NameUtil.nameToLong(player.getUsername()));
  253. block.writeByte(player.getSkill().getCombatLevel()); // Combat level.
  254. block.writeShort(0);
  255.  
  256. // Append the block length and the block to the packet.
  257. out.writeByte(block.getBuffer().position(), StreamBuffer.ValueType.C);
  258. out.writeBytes(block.getBuffer());
  259. }
  260.  
  261. /**
  262. * Adds a player to the local player list of another player.
  263. *
  264. * @param out
  265. * the packet to write to
  266. * @param player
  267. * the host player
  268. * @param other
  269. * the player being added
  270. */
  271. public static void addPlayer(StreamBuffer.OutBuffer out, Player player, Player other) {
  272. out.writeBits(11, other.getIndex()); // Server slot.
  273. out.writeBit(true); // Yes, an update is required.
  274. out.writeBit(true); // Discard walking queue(?)
  275.  
  276. // Write the relative position.
  277. Position delta = Misc.delta(player.getPosition(), other.getPosition());
  278. out.writeBits(5, delta.getY());
  279. out.writeBits(5, delta.getX());
  280. }
  281.  
  282. /**
  283. * Updates movement for this local player. The difference between this
  284. * method and the other player method is that this will make use of sector
  285. * 2,3 to place the player in a specific position while sector 2,3 is not
  286. * present in updating of other players (it simply flags local list removal
  287. * instead).
  288. *
  289. * @param player
  290. * @param out
  291. */
  292. public static void updateLocalPlayerMovement(Player player, StreamBuffer.OutBuffer out) {
  293. boolean updateRequired = player.getUpdateFlags().isUpdateRequired();
  294. if (player.needsPlacement()) { // Do they need placement?
  295. out.writeBit(true); // Yes, there is an update.
  296. int posX = player.getPosition().getLocalX(player.getCurrentRegion());
  297. int posY = player.getPosition().getLocalY(player.getCurrentRegion());
  298. appendPlacement(out, posX, posY, player.getPosition().getZ(), player.isResetMovementQueue(), updateRequired);
  299. player.setNeedsPlacement(false);
  300. } else { // No placement update, check for movement.
  301. int pDir = player.getPrimaryDirection();
  302. int sDir = player.getSecondaryDirection();
  303. if (pDir != -1) { // If they moved.
  304. out.writeBit(true); // Yes, there is an update.
  305. if (sDir != -1) { // If they ran.
  306. appendRun(out, pDir, sDir, updateRequired);
  307. } else { // Movement but no running - they walked.
  308. appendWalk(out, pDir, updateRequired);
  309. }
  310. } else { // No movement.
  311. if (updateRequired) { // Does the state need to be updated?
  312. out.writeBit(true); // Yes, there is an update.
  313. appendStand(out);
  314. } else { // No update whatsoever.
  315. out.writeBit(false);
  316. }
  317. }
  318. }
  319. }
  320.  
  321. /**
  322. * Updates the movement of a player for another player (does not make use of
  323. * sector 2,3).
  324. *
  325. * @param player
  326. * the player
  327. * @param out
  328. * the packet
  329. */
  330. public static void updateOtherPlayerMovement(Player player, StreamBuffer.OutBuffer out) {
  331. boolean updateRequired = player.getUpdateFlags().isUpdateRequired();
  332. int pDir = player.getPrimaryDirection();
  333. int sDir = player.getSecondaryDirection();
  334. if (pDir != -1) { // If they moved.
  335. out.writeBit(true); // Yes, there is an update.
  336. if (sDir != -1) { // If they ran.
  337. appendRun(out, pDir, sDir, updateRequired);
  338. } else { // Movement but no running - they walked.
  339. appendWalk(out, pDir, updateRequired);
  340. }
  341. } else { // No movement.
  342. if (updateRequired) { // Does the state need to be updated?
  343. out.writeBit(true); // Yes, there is an update.
  344. appendStand(out);
  345. } else { // No update whatsoever.
  346. out.writeBit(false);
  347. }
  348. }
  349. }
  350.  
  351. /**
  352. * Updates the state of a player.
  353. *
  354. * @param player
  355. * the player
  356. * @param block
  357. * the block
  358. */
  359. public static void updateState(Player player, StreamBuffer.OutBuffer block, boolean forceAppearance, boolean noChat) {
  360. int mask = 0x0;
  361. if (player.getUpdateFlags().isGraphicsUpdateRequired()) {
  362. mask |= 0x100;
  363. }
  364. if (player.getUpdateFlags().isAnimationUpdateRequired()) {
  365. mask |= 0x8;
  366. }
  367. if (player.getUpdateFlags().isForceChatUpdate()) {
  368. mask |= 0x4;
  369. }
  370. if (player.getUpdateFlags().isChatUpdateRequired() && !noChat) {
  371. mask |= 0x80;
  372. }
  373. if (player.getUpdateFlags().isEntityFaceUpdate()) {
  374. mask |= 0x1;
  375. }
  376. if (player.isAppearanceUpdateRequired() || forceAppearance) {
  377. mask |= 0x10;
  378. }
  379. if (player.getUpdateFlags().isFaceToDirection()) {
  380. mask |= 0x2;
  381. }
  382. if (player.getUpdateFlags().isHitUpdate()) {
  383. mask |= 0x20;
  384. }
  385. if (player.getUpdateFlags().isHitUpdate2()) {
  386. mask |= 0x200;
  387. }
  388. if (mask >= 0x100) {
  389. mask |= 0x40;
  390. block.writeShort(mask, StreamBuffer.ByteOrder.LITTLE);
  391. } else {
  392. block.writeByte(mask);
  393. }
  394. if (player.getUpdateFlags().isGraphicsUpdateRequired()) {
  395. block.writeShort(player.getUpdateFlags().getGraphicsId(), StreamBuffer.ByteOrder.LITTLE);
  396. block.writeInt(player.getUpdateFlags().getGraphicsDelay());
  397. }
  398. if (player.getUpdateFlags().isAnimationUpdateRequired()) {
  399. block.writeShort(player.getUpdateFlags().getAnimationId(), StreamBuffer.ByteOrder.LITTLE);
  400. block.writeByte(player.getUpdateFlags().getAnimationDelay(), StreamBuffer.ValueType.C);
  401. }
  402. if (player.getUpdateFlags().isForceChatUpdate()) {
  403. block.writeString(player.getUpdateFlags().getForceChatMessage());
  404. }
  405. if (player.getUpdateFlags().isChatUpdateRequired() && !noChat) {
  406. appendChat(player, block);
  407. }
  408. if (player.getUpdateFlags().isEntityFaceUpdate()) {
  409. block.writeShort(player.getUpdateFlags().getEntityFaceIndex(), StreamBuffer.ByteOrder.LITTLE);
  410. }
  411. if (player.isAppearanceUpdateRequired() || forceAppearance) {
  412. appendAppearance(player, block);
  413. }
  414. if (player.getUpdateFlags().isFaceToDirection()) {
  415. block.writeShort(player.getUpdateFlags().getFace().getX() * 2 + 1, StreamBuffer.ValueType.A, StreamBuffer.ByteOrder.LITTLE);
  416. block.writeShort(player.getUpdateFlags().getFace().getY() * 2 + 1, StreamBuffer.ByteOrder.LITTLE);
  417. }
  418. if (player.getUpdateFlags().isHitUpdate()) {
  419. block.writeByte(player.getUpdateFlags().getDamage());
  420. block.writeByte(player.getUpdateFlags().getHitType(), StreamBuffer.ValueType.A);
  421. block.writeByte(player.getSkill().getLevel()[Skill.HITPOINTS], StreamBuffer.ValueType.C);
  422. block.writeByte(player.getSkill().getLevelForXP((int) player.getSkill().getExp()[Skill.HITPOINTS]));
  423. }
  424. if (player.getUpdateFlags().isHitUpdate2()) {
  425. block.writeByte(player.getUpdateFlags().getDamage2());
  426. block.writeByte(player.getUpdateFlags().getHitType2(), StreamBuffer.ValueType.S);
  427. block.writeByte(player.getSkill().getLevel()[Skill.HITPOINTS]);
  428. block.writeByte(player.getSkill().getLevelForXP((int) player.getSkill().getExp()[Skill.HITPOINTS]), StreamBuffer.ValueType.C);
  429. }
  430. }
  431.  
  432. /**
  433. * Appends the stand version of the movement section of the update packet
  434. * (sector 2,0). Appending this (instead of just a zero bit) automatically
  435. * assumes that there is a required attribute update afterwards.
  436. *
  437. * @param out
  438. * the buffer to append to
  439. */
  440. public static void appendStand(StreamBuffer.OutBuffer out) {
  441. out.writeBits(2, 0); // 0 - no movement.
  442. }
  443.  
  444. /**
  445. * Appends the walk version of the movement section of the update packet
  446. * (sector 2,1).
  447. *
  448. * @param out
  449. * the buffer to append to
  450. * @param direction
  451. * the walking direction
  452. * @param attributesUpdate
  453. * whether or not a player attributes update is required
  454. */
  455. public static void appendWalk(StreamBuffer.OutBuffer out, int direction, boolean attributesUpdate) {
  456. out.writeBits(2, 1); // 1 - walking.
  457.  
  458. // Append the actual sector.
  459. out.writeBits(3, direction);
  460. out.writeBit(attributesUpdate);
  461. }
  462.  
  463. /**
  464. * Appends the walk version of the movement section of the update packet
  465. * (sector 2,2).
  466. *
  467. * @param out
  468. * the buffer to append to
  469. * @param direction
  470. * the walking direction
  471. * @param direction2
  472. * the running direction
  473. * @param attributesUpdate
  474. * whether or not a player attributes update is required
  475. */
  476. public static void appendRun(StreamBuffer.OutBuffer out, int direction, int direction2, boolean attributesUpdate) {
  477. out.writeBits(2, 2); // 2 - running.
  478.  
  479. // Append the actual sector.
  480. out.writeBits(3, direction);
  481. out.writeBits(3, direction2);
  482. out.writeBit(attributesUpdate);
  483. }
  484.  
  485. /**
  486. * Appends the player placement version of the movement section of the
  487. * update packet (sector 2,3). Note that by others this was previously
  488. * called the "teleport update".
  489. *
  490. * @param out
  491. * the buffer to append to
  492. * @param localX
  493. * the local X coordinate
  494. * @param localY
  495. * the local Y coordinate
  496. * @param z
  497. * the Z coordinate
  498. * @param discardMovementQueue
  499. * whether or not the client should discard the movement queue
  500. * @param attributesUpdate
  501. * whether or not a plater attributes update is required
  502. */
  503. public static void appendPlacement(StreamBuffer.OutBuffer out, int localX, int localY, int z, boolean discardMovementQueue, boolean attributesUpdate) {
  504. out.writeBits(2, 3); // 3 - placement.
  505.  
  506. // Append the actual sector.
  507. out.writeBits(2, z);
  508. out.writeBit(discardMovementQueue);
  509. out.writeBit(attributesUpdate);
  510. out.writeBits(7, localY);
  511. out.writeBits(7, localX);
  512. }
  513.  
  514. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement