Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.86 KB | None | 0 0
  1. /**
  2. * The Forgotten Server - a free and open-source MMORPG server emulator
  3. * Copyright (C) 2015 Mark Samman <mark.samman@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. */
  19.  
  20. #include "otpch.h"
  21. #include <boost/range/adaptor/reversed.hpp>
  22. #include "protocolgamebase.h"
  23. #include "game.h"
  24. #include "iologindata.h"
  25. #include "tile.h"
  26. #include "outputmessage.h"
  27.  
  28. extern Game g_game;
  29.  
  30. void ProtocolGameBase::onConnect()
  31. {
  32. auto output = OutputMessagePool::getOutputMessage();
  33. static std::random_device rd;
  34. static std::ranlux24 generator(rd());
  35. static std::uniform_int_distribution<uint16_t> randNumber(0x00, 0xFF);
  36.  
  37. // Skip checksum
  38. output->skipBytes(sizeof(uint32_t));
  39.  
  40. // Packet length & type
  41. output->add<uint16_t>(0x0006);
  42. output->addByte(0x1F);
  43.  
  44. // Add timestamp & random number
  45. challengeTimestamp = static_cast<uint32_t>(time(nullptr));
  46. output->add<uint32_t>(challengeTimestamp);
  47.  
  48. challengeRandom = randNumber(generator);
  49. output->addByte(challengeRandom);
  50.  
  51. // Go back and write checksum
  52. output->skipBytes(-12);
  53. output->add<uint32_t>(adlerChecksum(output->getOutputBuffer() sizeof(uint32_t), 8));
  54.  
  55. send(std::move(output));
  56. }
  57.  
  58. void ProtocolGameBase::AddOutfit(NetworkMessage& msg, const Outfit_t& outfit)
  59. {
  60. msg.add<uint16_t>(outfit.lookType);
  61.  
  62. if (outfit.lookType != 0) {
  63. msg.addByte(outfit.lookHead);
  64. msg.addByte(outfit.lookBody);
  65. msg.addByte(outfit.lookLegs);
  66. msg.addByte(outfit.lookFeet);
  67. msg.addByte(outfit.lookAddons);
  68. } else {
  69. msg.addItemId(outfit.lookTypeEx);
  70. }
  71.  
  72. msg.add<uint16_t>(outfit.lookMount);
  73. }
  74.  
  75. void ProtocolGameBase::checkCreatureAsKnown(uint32_t id, bool& known, uint32_t& removedKnown)
  76. {
  77. auto result = knownCreatureSet.insert(id);
  78. if (!result.second) {
  79. known = true;
  80. return;
  81. }
  82.  
  83. known = false;
  84.  
  85. if (knownCreatureSet.size() > 1300) {
  86. // Look for a creature to remove
  87. for (std::unordered_set<uint32_t>::iterator it = knownCreatureSet.begin(), end = knownCreatureSet.end(); it != end; it) {
  88. Creature* creature = g_game.getCreatureByID(*it);
  89. if (!canSee(creature)) {
  90. removedKnown = *it;
  91. knownCreatureSet.erase(it);
  92. return;
  93. }
  94. }
  95.  
  96. // Bad situation. Let's just remove anyone.
  97. std::unordered_set<uint32_t>::iterator it = knownCreatureSet.begin();
  98. if (*it == id) {
  99. it;
  100. }
  101.  
  102. removedKnown = *it;
  103. knownCreatureSet.erase(it);
  104. } else {
  105. removedKnown = 0;
  106. }
  107. }
  108.  
  109. void ProtocolGameBase::AddCreature(NetworkMessage& msg, const Creature* creature, bool known, uint32_t remove)
  110. {
  111. CreatureType_t creatureType = creature->getType();
  112.  
  113. const Player* otherPlayer = creature->getPlayer();
  114.  
  115. if (known) {
  116. msg.add<uint16_t>(0x62);
  117. msg.add<uint32_t>(creature->getID());
  118. } else {
  119. msg.add<uint16_t>(0x61);
  120. msg.add<uint32_t>(remove);
  121. msg.add<uint32_t>(creature->getID());
  122. msg.addByte(creatureType);
  123. msg.addString(creature->getName());
  124. }
  125.  
  126. if (creature->isHealthHidden()) {
  127. msg.addByte(0x00);
  128. } else {
  129. msg.addByte(std::ceil((static_cast<double>(creature->getHealth()) / std::max<int32_t>(creature->getMaxHealth(), 1)) * 100));
  130. }
  131.  
  132. msg.addByte(creature->getDirection());
  133.  
  134. if (!creature->isInGhostMode() && !creature->isInvisible()) {
  135. AddOutfit(msg, creature->getCurrentOutfit());
  136. } else {
  137. static Outfit_t outfit;
  138. AddOutfit(msg, outfit);
  139. }
  140.  
  141. LightInfo lightInfo;
  142. creature->getCreatureLight(lightInfo);
  143. msg.addByte(player->isAccessPlayer() ? 0xFF : lightInfo.level);
  144. msg.addByte(lightInfo.color);
  145.  
  146. msg.add<uint16_t>(creature->getStepSpeed() / 2);
  147.  
  148. msg.addByte(player->getSkullClient(creature));
  149. msg.addByte(player->getPartyShield(otherPlayer));
  150.  
  151. if (!known) {
  152. msg.addByte(player->getGuildEmblem(otherPlayer));
  153. }
  154.  
  155. if (creatureType == CREATURETYPE_MONSTER) {
  156. const Creature* master = creature->getMaster();
  157. if (master) {
  158. const Player* masterPlayer = master->getPlayer();
  159. if (masterPlayer) {
  160. if (masterPlayer == player) {
  161. creatureType = CREATURETYPE_SUMMON_OWN;
  162. } else {
  163. creatureType = CREATURETYPE_SUMMON_OTHERS;
  164. }
  165. }
  166. }
  167. }
  168.  
  169. msg.addByte(creatureType); // Type (for summons)
  170. msg.addByte(creature->getSpeechBubble());
  171. msg.addByte(0xFF); // MARK_UNMARKED
  172.  
  173. if (otherPlayer) {
  174. msg.add<uint16_t>(otherPlayer->getHelpers());
  175. } else {
  176. msg.add<uint16_t>(0x00);
  177. }
  178.  
  179. msg.addByte(player->canWalkthroughEx(creature) ? 0x00 : 0x01);
  180. }
  181.  
  182. void ProtocolGameBase::AddPlayerStats(NetworkMessage& msg)
  183. {
  184. msg.addByte(0xA0);
  185.  
  186. msg.add<uint16_t>(std::min<int32_t>(player->getHealth(), std::numeric_limits<uint16_t>::max()));
  187. msg.add<uint16_t>(std::min<int32_t>(player->getPlayerInfo(PLAYERINFO_MAXHEALTH), std::numeric_limits<uint16_t>::max()));
  188.  
  189. msg.add<uint32_t>(player->getFreeCapacity());
  190. msg.add<uint32_t>(player->getCapacity());
  191.  
  192. msg.add<uint64_t>(player->getExperience());
  193.  
  194. msg.add<uint16_t>(player->getLevel());
  195. msg.addByte(player->getPlayerInfo(PLAYERINFO_LEVELPERCENT));
  196. msg.addDouble(0, 3); // experience bonus
  197.  
  198. msg.add<uint16_t>(std::min<int32_t>(player->getMana(), std::numeric_limits<uint16_t>::max()));
  199. msg.add<uint16_t>(std::min<int32_t>(player->getPlayerInfo(PLAYERINFO_MAXMANA), std::numeric_limits<uint16_t>::max()));
  200.  
  201. msg.addByte(std::min<uint32_t>(player->getMagicLevel(), std::numeric_limits<uint8_t>::max()));
  202. msg.addByte(std::min<uint32_t>(player->getBaseMagicLevel(), std::numeric_limits<uint8_t>::max()));
  203. msg.addByte(player->getPlayerInfo(PLAYERINFO_MAGICLEVELPERCENT));
  204.  
  205. msg.addByte(player->getSoul());
  206.  
  207. msg.add<uint16_t>(player->getStaminaMinutes());
  208.  
  209. msg.add<uint16_t>(player->getBaseSpeed() / 2);
  210.  
  211. Condition* condition = player->getCondition(CONDITION_REGENERATION);
  212. msg.add<uint16_t>(condition ? condition->getTicks() / 1000 : 0x00);
  213.  
  214. msg.add<uint16_t>(player->getOfflineTrainingTime() / 60 / 1000);
  215. }
  216.  
  217. void ProtocolGameBase::AddPlayerSkills(NetworkMessage& msg)
  218. {
  219. msg.addByte(0xA1);
  220.  
  221. for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; i) {
  222. msg.add<uint16_t>(std::min<int32_t>(player->getSkillLevel(i), std::numeric_limits<uint16_t>::max()));
  223. msg.add<uint16_t>(player->getBaseSkill(i));
  224. msg.addByte(player->getSkillPercent(i));
  225. }
  226. }
  227.  
  228. void ProtocolGameBase::AddWorldLight(NetworkMessage& msg, const LightInfo& lightInfo)
  229. {
  230. msg.addByte(0x82);
  231. msg.addByte((player->isAccessPlayer() ? 0xFF : lightInfo.level));
  232. msg.addByte(lightInfo.color);
  233. }
  234.  
  235. void ProtocolGameBase::AddCreatureLight(NetworkMessage& msg, const Creature* creature)
  236. {
  237. LightInfo lightInfo;
  238. creature->getCreatureLight(lightInfo);
  239.  
  240. msg.addByte(0x8D);
  241. msg.add<uint32_t>(creature->getID());
  242. msg.addByte((player->isAccessPlayer() ? 0xFF : lightInfo.level));
  243. msg.addByte(lightInfo.color);
  244. }
  245.  
  246. bool ProtocolGameBase::canSee(const Creature* c) const
  247. {
  248. if (!c || !player || c->isRemoved()) {
  249. return false;
  250. }
  251.  
  252. if (!player->canSeeCreature(c)) {
  253. return false;
  254. }
  255.  
  256. return canSee(c->getPosition());
  257. }
  258.  
  259. bool ProtocolGameBase::canSee(const Position& pos) const
  260. {
  261. return canSee(pos.x, pos.y, pos.z);
  262. }
  263.  
  264. bool ProtocolGameBase::canSee(int32_t x, int32_t y, int32_t z) const
  265. {
  266. if (!player) {
  267. return false;
  268. }
  269.  
  270. const Position& myPos = player->getPosition();
  271. if (myPos.z <= 7) {
  272. //we are on ground level or above (7 -> 0)
  273. //view is from 7 -> 0
  274. if (z > 7) {
  275. return false;
  276. }
  277. } else if (myPos.z >= 8) {
  278. //we are underground (8 -> 15)
  279. //view is /- 2 from the floor we stand on
  280. if (std::abs(myPos.getZ() - z) > 2) {
  281. return false;
  282. }
  283. }
  284.  
  285. //negative offset means that the action taken place is on a lower floor than ourself
  286. int32_t offsetz = myPos.getZ() - z;
  287. if ((x >= myPos.getX() - 8 offsetz) && (x <= myPos.getX() 9 offsetz) &&
  288. (y >= myPos.getY() - 6 offsetz) && (y <= myPos.getY() 7 offsetz)) {
  289. return true;
  290. }
  291. return false;
  292. }
  293.  
  294. //tile
  295. void ProtocolGameBase::RemoveTileThing(NetworkMessage& msg, const Position& pos, uint32_t stackpos)
  296. {
  297. if (stackpos >= 10) {
  298. return;
  299. }
  300.  
  301. msg.addByte(0x6C);
  302. msg.addPosition(pos);
  303. msg.addByte(stackpos);
  304. }
  305.  
  306. void ProtocolGameBase::sendUpdateTile(const Tile* tile, const Position& pos)
  307. {
  308. if (!canSee(pos)) {
  309. return;
  310. }
  311.  
  312. NetworkMessage msg;
  313. msg.addByte(0x69);
  314. msg.addPosition(pos);
  315.  
  316. if (tile) {
  317. GetTileDescription(tile, msg);
  318. msg.addByte(0x00);
  319. msg.addByte(0xFF);
  320. } else {
  321. msg.addByte(0x01);
  322. msg.addByte(0xFF);
  323. }
  324.  
  325. writeToOutputBuffer(msg);
  326. }
  327.  
  328. void ProtocolGameBase::GetTileDescription(const Tile* tile, NetworkMessage& msg)
  329. {
  330. msg.add<uint16_t>(0x00); //environmental effects
  331.  
  332. int32_t count;
  333. Item* ground = tile->getGround();
  334. if (ground) {
  335. msg.addItem(ground);
  336. count = 1;
  337. } else {
  338. count = 0;
  339. }
  340.  
  341. const TileItemVector* items = tile->getItemList();
  342. if (items) {
  343. for (auto it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; it) {
  344. msg.addItem(*it);
  345.  
  346. if (count == 10) {
  347. return;
  348. }
  349. }
  350. }
  351.  
  352. const CreatureVector* creatures = tile->getCreatures();
  353. if (creatures) {
  354. for (const Creature* creature : boost::adaptors::reverse(*creatures)) {
  355. if (!player->canSeeCreature(creature)) {
  356. continue;
  357. }
  358.  
  359. bool known;
  360. uint32_t removedKnown;
  361. checkCreatureAsKnown(creature->getID(), known, removedKnown);
  362. AddCreature(msg, creature, known, removedKnown);
  363.  
  364. if (count == 10) {
  365. return;
  366. }
  367. }
  368. }
  369.  
  370. if (items) {
  371. for (auto it = items->getBeginDownItem(), end = items->getEndDownItem(); it != end; it) {
  372. msg.addItem(*it);
  373.  
  374. if (count == 10) {
  375. return;
  376. }
  377. }
  378. }
  379. }
  380.  
  381. void ProtocolGameBase::GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, NetworkMessage& msg)
  382. {
  383. int32_t skip = -1;
  384. int32_t startz, endz, zstep;
  385.  
  386. if (z > 7) {
  387. startz = z - 2;
  388. endz = std::min<int32_t>(MAP_MAX_LAYERS - 1, z 2);
  389. zstep = 1;
  390. } else {
  391. startz = 7;
  392. endz = 0;
  393. zstep = -1;
  394. }
  395.  
  396. for (int32_t nz = startz; nz != endz zstep; nz = zstep) {
  397. GetFloorDescription(msg, x, y, nz, width, height, z - nz, skip);
  398. }
  399.  
  400. if (skip >= 0) {
  401. msg.addByte(skip);
  402. msg.addByte(0xFF);
  403. }
  404. }
  405.  
  406. void ProtocolGameBase::GetFloorDescription(NetworkMessage& msg, int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, int32_t offset, int32_t& skip)
  407. {
  408. for (int32_t nx = 0; nx < width; nx) {
  409. for (int32_t ny = 0; ny < height; ny) {
  410. Tile* tile = g_game.map.getTile(x nx offset, y ny offset, z);
  411. if (tile) {
  412. if (skip >= 0) {
  413. msg.addByte(skip);
  414. msg.addByte(0xFF);
  415. }
  416.  
  417. skip = 0;
  418. GetTileDescription(tile, msg);
  419. } else if (skip == 0xFE) {
  420. msg.addByte(0xFF);
  421. msg.addByte(0xFF);
  422. skip = -1;
  423. } else {
  424. skip;
  425. }
  426. }
  427. }
  428. }
  429.  
  430. void ProtocolGameBase::sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex)
  431. {
  432. NetworkMessage msg;
  433. msg.addByte(0x6E);
  434.  
  435. msg.addByte(cid);
  436.  
  437. if (container->getID() == ITEM_BROWSEFIELD) {
  438. msg.addItem(1987, 1);
  439. msg.addString("Browse Field");
  440. } else {
  441. msg.addItem(container);
  442. msg.addString(container->getName());
  443. }
  444.  
  445. msg.addByte(container->capacity());
  446.  
  447. msg.addByte(hasParent ? 0x01 : 0x00);
  448.  
  449. msg.addByte(container->isUnlocked() ? 0x01 : 0x00); // Drag and drop
  450. msg.addByte(container->hasPagination() ? 0x01 : 0x00); // Pagination
  451.  
  452. uint32_t containerSize = container->size();
  453. msg.add<uint16_t>(containerSize);
  454. msg.add<uint16_t>(firstIndex);
  455. if (firstIndex < containerSize) {
  456. uint8_t itemsToSend = std::min<uint32_t>(std::min<uint32_t>(container->capacity(), containerSize - firstIndex), std::numeric_limits<uint8_t>::max());
  457.  
  458. msg.addByte(itemsToSend);
  459. for (ItemDeque::const_iterator it = container->getItemList().begin() firstIndex, end = it itemsToSend; it != end; it) {
  460. msg.addItem(*it);
  461. }
  462. } else {
  463. msg.addByte(0x00);
  464. }
  465. writeToOutputBuffer(msg);
  466. }
  467.  
  468. void ProtocolGameBase::sendChannel(uint16_t channelId, const std::string& channelName, const UsersMap* channelUsers, const InvitedMap* invitedUsers)
  469. {
  470. NetworkMessage msg;
  471. msg.addByte(0xAC);
  472.  
  473. msg.add<uint16_t>(channelId);
  474. msg.addString(channelName);
  475.  
  476. if (channelUsers) {
  477. msg.add<uint16_t>(channelUsers->size());
  478. for (const auto& it : *channelUsers) {
  479. msg.addString(it.second->getName());
  480. }
  481. } else {
  482. msg.add<uint16_t>(0x00);
  483. }
  484.  
  485. if (invitedUsers) {
  486. msg.add<uint16_t>(invitedUsers->size());
  487. for (const auto& it : *invitedUsers) {
  488. msg.addString(it.second->getName());
  489. }
  490. } else {
  491. msg.add<uint16_t>(0x00);
  492. }
  493. writeToOutputBuffer(msg);
  494. }
  495.  
  496. void ProtocolGameBase::sendMagicEffect(const Position& pos, uint8_t type)
  497. {
  498. if (!canSee(pos)) {
  499. return;
  500. }
  501.  
  502. NetworkMessage msg;
  503. msg.addByte(0x83);
  504. msg.addPosition(pos);
  505. msg.addByte(type);
  506. writeToOutputBuffer(msg);
  507. }
  508.  
  509. void ProtocolGameBase::sendAddCreature(const Creature* creature, const Position& pos, int32_t stackpos, bool isLogin)
  510. {
  511. if (!canSee(pos)) {
  512. return;
  513. }
  514.  
  515. if (creature != player) {
  516. if (stackpos != -1) {
  517. NetworkMessage msg;
  518. msg.addByte(0x6A);
  519. msg.addPosition(pos);
  520. msg.addByte(stackpos);
  521.  
  522. bool known;
  523. uint32_t removedKnown;
  524. checkCreatureAsKnown(creature->getID(), known, removedKnown);
  525. AddCreature(msg, creature, known, removedKnown);
  526. writeToOutputBuffer(msg);
  527. }
  528.  
  529. if (isLogin) {
  530. sendMagicEffect(pos, CONST_ME_TELEPORT);
  531. }
  532. return;
  533. }
  534.  
  535. NetworkMessage msg;
  536. msg.addByte(0x17);
  537.  
  538. msg.add<uint32_t>(player->getID());
  539. msg.add<uint16_t>(0x32); // beat duration (50)
  540.  
  541. msg.addDouble(Creature::speedA, 3);
  542. msg.addDouble(Creature::speedB, 3);
  543. msg.addDouble(Creature::speedC, 3);
  544.  
  545. // can report bugs?
  546. if (player->getAccountType() >= ACCOUNT_TYPE_TUTOR) {
  547. msg.addByte(0x01);
  548. } else {
  549. msg.addByte(0x00);
  550. }
  551.  
  552. msg.addByte(0x00); // can change pvp framing option
  553. msg.addByte(0x00); // expert mode button enabled
  554.  
  555. writeToOutputBuffer(msg);
  556.  
  557. sendPendingStateEntered();
  558. sendEnterWorld();
  559. sendMapDescription(pos);
  560.  
  561. if (isLogin) {
  562. sendMagicEffect(pos, CONST_ME_TELEPORT);
  563. }
  564.  
  565. sendInventoryItem(CONST_SLOT_HEAD, player->getInventoryItem(CONST_SLOT_HEAD));
  566. sendInventoryItem(CONST_SLOT_NECKLACE, player->getInventoryItem(CONST_SLOT_NECKLACE));
  567. sendInventoryItem(CONST_SLOT_BACKPACK, player->getInventoryItem(CONST_SLOT_BACKPACK));
  568. sendInventoryItem(CONST_SLOT_ARMOR, player->getInventoryItem(CONST_SLOT_ARMOR));
  569. sendInventoryItem(CONST_SLOT_RIGHT, player->getInventoryItem(CONST_SLOT_RIGHT));
  570. sendInventoryItem(CONST_SLOT_LEFT, player->getInventoryItem(CONST_SLOT_LEFT));
  571. sendInventoryItem(CONST_SLOT_LEGS, player->getInventoryItem(CONST_SLOT_LEGS));
  572. sendInventoryItem(CONST_SLOT_FEET, player->getInventoryItem(CONST_SLOT_FEET));
  573. sendInventoryItem(CONST_SLOT_RING, player->getInventoryItem(CONST_SLOT_RING));
  574. sendInventoryItem(CONST_SLOT_AMMO, player->getInventoryItem(CONST_SLOT_AMMO));
  575.  
  576. sendStats();
  577. sendSkills();
  578.  
  579. //gameworld light-settings
  580. LightInfo lightInfo;
  581. g_game.getWorldLightInfo(lightInfo);
  582. sendWorldLight(lightInfo);
  583.  
  584. //player light level
  585. sendCreatureLight(creature);
  586.  
  587. const std::forward_list<VIPEntry>& vipEntries = IOLoginData::getVIPEntries(player->getAccount());
  588.  
  589. if (player->isAccessPlayer()) {
  590. for (const VIPEntry& entry : vipEntries) {
  591. VipStatus_t vipStatus;
  592.  
  593. Player* vipPlayer = g_game.getPlayerByGUID(entry.guid);
  594. if (!vipPlayer) {
  595. vipStatus = VIPSTATUS_OFFLINE;
  596. } else {
  597. vipStatus = VIPSTATUS_ONLINE;
  598. }
  599.  
  600. sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus);
  601. }
  602. } else {
  603. for (const VIPEntry& entry : vipEntries) {
  604. VipStatus_t vipStatus;
  605.  
  606. Player* vipPlayer = g_game.getPlayerByGUID(entry.guid);
  607. if (!vipPlayer || vipPlayer->isInGhostMode()) {
  608. vipStatus = VIPSTATUS_OFFLINE;
  609. } else {
  610. vipStatus = VIPSTATUS_ONLINE;
  611. }
  612.  
  613. sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus);
  614. }
  615. }
  616.  
  617. sendBasicData();
  618. player->sendIcons();
  619. }
  620.  
  621. void ProtocolGameBase::sendStats()
  622. {
  623. NetworkMessage msg;
  624. AddPlayerStats(msg);
  625. writeToOutputBuffer(msg);
  626. }
  627.  
  628. void ProtocolGameBase::sendBasicData()
  629. {
  630. NetworkMessage msg;
  631. msg.addByte(0x9F);
  632. msg.addByte(player->isPremium() ? 0x01 : 0x00);
  633. msg.add<uint32_t>(std::numeric_limits<uint32_t>::max());
  634. msg.addByte(player->getVocation()->getClientId());
  635. msg.add<uint16_t>(0x00);
  636. writeToOutputBuffer(msg);
  637. }
  638.  
  639. void ProtocolGameBase::sendPendingStateEntered()
  640. {
  641. NetworkMessage msg;
  642. msg.addByte(0x0A);
  643. writeToOutputBuffer(msg);
  644. }
  645.  
  646. void ProtocolGameBase::sendEnterWorld()
  647. {
  648. NetworkMessage msg;
  649. msg.addByte(0x0F);
  650. writeToOutputBuffer(msg);
  651. }
  652.  
  653. void ProtocolGameBase::sendInventoryItem(slots_t slot, const Item* item)
  654. {
  655. NetworkMessage msg;
  656. if (item) {
  657. msg.addByte(0x78);
  658. msg.addByte(slot);
  659. msg.addItem(item);
  660. } else {
  661. msg.addByte(0x79);
  662. msg.addByte(slot);
  663. }
  664. writeToOutputBuffer(msg);
  665. }
  666.  
  667. void ProtocolGameBase::sendSkills()
  668. {
  669. NetworkMessage msg;
  670. AddPlayerSkills(msg);
  671. writeToOutputBuffer(msg);
  672. }
  673.  
  674. void ProtocolGameBase::sendCreatureLight(const Creature* creature)
  675. {
  676. if (!canSee(creature)) {
  677. return;
  678. }
  679.  
  680. NetworkMessage msg;
  681. AddCreatureLight(msg, creature);
  682. writeToOutputBuffer(msg);
  683. }
  684.  
  685. void ProtocolGameBase::sendWorldLight(const LightInfo& lightInfo)
  686. {
  687. NetworkMessage msg;
  688. AddWorldLight(msg, lightInfo);
  689. writeToOutputBuffer(msg);
  690. }
  691.  
  692. void ProtocolGameBase::sendMapDescription(const Position& pos)
  693. {
  694. NetworkMessage msg;
  695. msg.addByte(0x64);
  696. msg.addPosition(player->getPosition());
  697. GetMapDescription(pos.x - 8, pos.y - 6, pos.z, 18, 14, msg);
  698. writeToOutputBuffer(msg);
  699. }
  700.  
  701. void ProtocolGameBase::sendVIP(uint32_t guid, const std::string& name, const std::string& description, uint32_t icon, bool notify, VipStatus_t status)
  702. {
  703. NetworkMessage msg;
  704. msg.addByte(0xD2);
  705. msg.add<uint32_t>(guid);
  706. msg.addString(name);
  707. msg.addString(description);
  708. msg.add<uint32_t>(std::min<uint32_t>(10, icon));
  709. msg.addByte(notify ? 0x01 : 0x00);
  710. msg.addByte(status);
  711. writeToOutputBuffer(msg);
  712. }
  713.  
  714. void ProtocolGameBase::sendCancelWalk()
  715. {
  716. NetworkMessage msg;
  717. msg.addByte(0xB5);
  718. msg.addByte(player->getDirection());
  719. writeToOutputBuffer(msg);
  720. }
  721.  
  722. void ProtocolGameBase::sendPing()
  723. {
  724. NetworkMessage msg;
  725. msg.addByte(0x1D);
  726. writeToOutputBuffer(msg, false);
  727. }
  728.  
  729. void ProtocolGameBase::sendPingBack()
  730. {
  731. NetworkMessage msg;
  732. msg.addByte(0x1E);
  733. writeToOutputBuffer(msg, false);
  734. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement