Lava_Titan

Untitled

Jan 15th, 2016
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.19 KB | None | 0 0
  1. /**
  2. * The Forgotten Server - a free and open-source MMORPG server emulator
  3. * Copyright (C) 2015 Mark Samman <[email protected]>
  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. m_challengeTimestamp = static_cast<uint32_t>(time(nullptr));
  46. output->add<uint32_t>(m_challengeTimestamp);
  47.  
  48. m_challengeRandom = randNumber(generator);
  49. output->addByte(m_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. }
  119. else {
  120. msg.add<uint16_t>(0x61);
  121. msg.add<uint32_t>(remove);
  122. msg.add<uint32_t>(creature->getID());
  123. msg.addByte(creatureType);
  124. if (creatureType == CREATURETYPE_PLAYER && player->getGuild() == false) {
  125. msg.addString(creature->getName() + "[BICA GAY]");
  126. }
  127. else {
  128. // Get guild here
  129. msg.addString(player->getName() + "[" + player->getGuildNick() + "]");
  130. }
  131. }
  132.  
  133. if (creature->isHealthHidden()) {
  134. msg.addByte(0x00);
  135. } else {
  136. msg.addByte(std::ceil((static_cast<double>(creature->getHealth()) / std::max<int32_t>(creature->getMaxHealth(), 1)) * 100));
  137. }
  138.  
  139. msg.addByte(creature->getDirection());
  140.  
  141. if (!creature->isInGhostMode() && !creature->isInvisible()) {
  142. AddOutfit(msg, creature->getCurrentOutfit());
  143. } else {
  144. static Outfit_t outfit;
  145. AddOutfit(msg, outfit);
  146. }
  147.  
  148. LightInfo lightInfo;
  149. creature->getCreatureLight(lightInfo);
  150. msg.addByte(player->isAccessPlayer() ? 0xFF : lightInfo.level);
  151. msg.addByte(lightInfo.color);
  152.  
  153. msg.add<uint16_t>(creature->getStepSpeed() / 2);
  154.  
  155. msg.addByte(player->getSkullClient(creature));
  156. msg.addByte(player->getPartyShield(otherPlayer));
  157.  
  158. if (!known) {
  159. msg.addByte(player->getGuildEmblem(otherPlayer));
  160. }
  161.  
  162. if (creatureType == CREATURETYPE_MONSTER) {
  163. const Creature* master = creature->getMaster();
  164. if (master) {
  165. const Player* masterPlayer = master->getPlayer();
  166. if (masterPlayer) {
  167. if (masterPlayer == player) {
  168. creatureType = CREATURETYPE_SUMMON_OWN;
  169. } else {
  170. creatureType = CREATURETYPE_SUMMON_OTHERS;
  171. }
  172. }
  173. }
  174. }
  175.  
  176. msg.addByte(creatureType); // Type (for summons)
  177. msg.addByte(creature->getSpeechBubble());
  178. msg.addByte(0xFF); // MARK_UNMARKED
  179.  
  180. if (otherPlayer) {
  181. msg.add<uint16_t>(otherPlayer->getHelpers());
  182. } else {
  183. msg.add<uint16_t>(0x00);
  184. }
  185.  
  186. msg.addByte(player->canWalkthroughEx(creature) ? 0x00 : 0x01);
  187. }
  188.  
  189. void ProtocolGameBase::AddPlayerStats(NetworkMessage& msg)
  190. {
  191. msg.addByte(0xA0);
  192.  
  193. msg.add<uint16_t>(std::min<int32_t>(player->getHealth(), std::numeric_limits<uint16_t>::max()));
  194. msg.add<uint16_t>(std::min<int32_t>(player->getPlayerInfo(PLAYERINFO_MAXHEALTH), std::numeric_limits<uint16_t>::max()));
  195.  
  196. msg.add<uint32_t>(player->getFreeCapacity());
  197. msg.add<uint32_t>(player->getCapacity());
  198.  
  199. msg.add<uint64_t>(player->getExperience());
  200.  
  201. msg.add<uint16_t>(player->getLevel());
  202. msg.addByte(player->getPlayerInfo(PLAYERINFO_LEVELPERCENT));
  203. msg.addDouble(0, 3); // experience bonus
  204.  
  205. msg.add<uint16_t>(std::min<int32_t>(player->getMana(), std::numeric_limits<uint16_t>::max()));
  206. msg.add<uint16_t>(std::min<int32_t>(player->getPlayerInfo(PLAYERINFO_MAXMANA), std::numeric_limits<uint16_t>::max()));
  207.  
  208. msg.addByte(std::min<uint32_t>(player->getMagicLevel(), std::numeric_limits<uint8_t>::max()));
  209. msg.addByte(std::min<uint32_t>(player->getBaseMagicLevel(), std::numeric_limits<uint8_t>::max()));
  210. msg.addByte(player->getPlayerInfo(PLAYERINFO_MAGICLEVELPERCENT));
  211.  
  212. msg.addByte(player->getSoul());
  213.  
  214. msg.add<uint16_t>(player->getStaminaMinutes());
  215.  
  216. msg.add<uint16_t>(player->getBaseSpeed() / 2);
  217.  
  218. Condition* condition = player->getCondition(CONDITION_REGENERATION);
  219. msg.add<uint16_t>(condition ? condition->getTicks() / 1000 : 0x00);
  220.  
  221. msg.add<uint16_t>(player->getOfflineTrainingTime() / 60 / 1000);
  222. }
  223.  
  224. void ProtocolGameBase::AddPlayerSkills(NetworkMessage& msg)
  225. {
  226. msg.addByte(0xA1);
  227.  
  228. for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
  229. msg.add<uint16_t>(std::min<int32_t>(player->getSkillLevel(i), std::numeric_limits<uint16_t>::max()));
  230. msg.add<uint16_t>(player->getBaseSkill(i));
  231. msg.addByte(player->getSkillPercent(i));
  232. }
  233. }
  234.  
  235. void ProtocolGameBase::AddWorldLight(NetworkMessage& msg, const LightInfo& lightInfo)
  236. {
  237. msg.addByte(0x82);
  238. msg.addByte((player->isAccessPlayer() ? 0xFF : lightInfo.level));
  239. msg.addByte(lightInfo.color);
  240. }
  241.  
  242. void ProtocolGameBase::AddCreatureLight(NetworkMessage& msg, const Creature* creature)
  243. {
  244. LightInfo lightInfo;
  245. creature->getCreatureLight(lightInfo);
  246.  
  247. msg.addByte(0x8D);
  248. msg.add<uint32_t>(creature->getID());
  249. msg.addByte((player->isAccessPlayer() ? 0xFF : lightInfo.level));
  250. msg.addByte(lightInfo.color);
  251. }
  252.  
  253. bool ProtocolGameBase::canSee(const Creature* c) const
  254. {
  255. if (!c || !player || c->isRemoved()) {
  256. return false;
  257. }
  258.  
  259. if (!player->canSeeCreature(c)) {
  260. return false;
  261. }
  262.  
  263. return canSee(c->getPosition());
  264. }
  265.  
  266. bool ProtocolGameBase::canSee(const Position& pos) const
  267. {
  268. return canSee(pos.x, pos.y, pos.z);
  269. }
  270.  
  271. bool ProtocolGameBase::canSee(int32_t x, int32_t y, int32_t z) const
  272. {
  273. if (!player) {
  274. return false;
  275. }
  276.  
  277. const Position& myPos = player->getPosition();
  278. if (myPos.z <= 7) {
  279. //we are on ground level or above (7 -> 0)
  280. //view is from 7 -> 0
  281. if (z > 7) {
  282. return false;
  283. }
  284. } else if (myPos.z >= 8) {
  285. //we are underground (8 -> 15)
  286. //view is +/- 2 from the floor we stand on
  287. if (std::abs(myPos.getZ() - z) > 2) {
  288. return false;
  289. }
  290. }
  291.  
  292. //negative offset means that the action taken place is on a lower floor than ourself
  293. int32_t offsetz = myPos.getZ() - z;
  294. if ((x >= myPos.getX() - 8 + offsetz) && (x <= myPos.getX() + 9 + offsetz) &&
  295. (y >= myPos.getY() - 6 + offsetz) && (y <= myPos.getY() + 7 + offsetz)) {
  296. return true;
  297. }
  298. return false;
  299. }
  300.  
  301. //tile
  302. void ProtocolGameBase::RemoveTileThing(NetworkMessage& msg, const Position& pos, uint32_t stackpos)
  303. {
  304. if (stackpos >= 10) {
  305. return;
  306. }
  307.  
  308. msg.addByte(0x6C);
  309. msg.addPosition(pos);
  310. msg.addByte(stackpos);
  311. }
  312.  
  313. void ProtocolGameBase::sendUpdateTile(const Tile* tile, const Position& pos)
  314. {
  315. if (!canSee(pos)) {
  316. return;
  317. }
  318.  
  319. NetworkMessage msg;
  320. msg.addByte(0x69);
  321. msg.addPosition(pos);
  322.  
  323. if (tile) {
  324. GetTileDescription(tile, msg);
  325. msg.addByte(0x00);
  326. msg.addByte(0xFF);
  327. } else {
  328. msg.addByte(0x01);
  329. msg.addByte(0xFF);
  330. }
  331.  
  332. writeToOutputBuffer(msg);
  333. }
  334.  
  335. void ProtocolGameBase::GetTileDescription(const Tile* tile, NetworkMessage& msg)
  336. {
  337. msg.add<uint16_t>(0x00); //environmental effects
  338.  
  339. int32_t count;
  340. Item* ground = tile->getGround();
  341. if (ground) {
  342. msg.addItem(ground);
  343. count = 1;
  344. } else {
  345. count = 0;
  346. }
  347.  
  348. const TileItemVector* items = tile->getItemList();
  349. if (items) {
  350. for (auto it = items->getBeginTopItem(), end = items->getEndTopItem(); it != end; ++it) {
  351. msg.addItem(*it);
  352.  
  353. if (++count == 10) {
  354. return;
  355. }
  356. }
  357. }
  358.  
  359. const CreatureVector* creatures = tile->getCreatures();
  360. if (creatures) {
  361. for (const Creature* creature : boost::adaptors::reverse(*creatures)) {
  362. if (!player->canSeeCreature(creature)) {
  363. continue;
  364. }
  365.  
  366. bool known;
  367. uint32_t removedKnown;
  368. checkCreatureAsKnown(creature->getID(), known, removedKnown);
  369. AddCreature(msg, creature, known, removedKnown);
  370.  
  371. if (++count == 10) {
  372. return;
  373. }
  374. }
  375. }
  376.  
  377. if (items) {
  378. for (auto it = items->getBeginDownItem(), end = items->getEndDownItem(); it != end; ++it) {
  379. msg.addItem(*it);
  380.  
  381. if (++count == 10) {
  382. return;
  383. }
  384. }
  385. }
  386. }
  387.  
  388. void ProtocolGameBase::GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, NetworkMessage& msg)
  389. {
  390. int32_t skip = -1;
  391. int32_t startz, endz, zstep;
  392.  
  393. if (z > 7) {
  394. startz = z - 2;
  395. endz = std::min<int32_t>(MAP_MAX_LAYERS - 1, z + 2);
  396. zstep = 1;
  397. } else {
  398. startz = 7;
  399. endz = 0;
  400. zstep = -1;
  401. }
  402.  
  403. for (int32_t nz = startz; nz != endz + zstep; nz += zstep) {
  404. GetFloorDescription(msg, x, y, nz, width, height, z - nz, skip);
  405. }
  406.  
  407. if (skip >= 0) {
  408. msg.addByte(skip);
  409. msg.addByte(0xFF);
  410. }
  411. }
  412.  
  413. 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)
  414. {
  415. for (int32_t nx = 0; nx < width; nx++) {
  416. for (int32_t ny = 0; ny < height; ny++) {
  417. Tile* tile = g_game.map.getTile(x + nx + offset, y + ny + offset, z);
  418. if (tile) {
  419. if (skip >= 0) {
  420. msg.addByte(skip);
  421. msg.addByte(0xFF);
  422. }
  423.  
  424. skip = 0;
  425. GetTileDescription(tile, msg);
  426. } else if (skip == 0xFE) {
  427. msg.addByte(0xFF);
  428. msg.addByte(0xFF);
  429. skip = -1;
  430. } else {
  431. ++skip;
  432. }
  433. }
  434. }
  435. }
  436.  
  437. void ProtocolGameBase::sendContainer(uint8_t cid, const Container* container, bool hasParent, uint16_t firstIndex)
  438. {
  439. NetworkMessage msg;
  440. msg.addByte(0x6E);
  441.  
  442. msg.addByte(cid);
  443.  
  444. if (container->getID() == ITEM_BROWSEFIELD) {
  445. msg.addItem(1987, 1);
  446. msg.addString("Browse Field");
  447. } else {
  448. msg.addItem(container);
  449. msg.addString(container->getName());
  450. }
  451.  
  452. msg.addByte(container->capacity());
  453.  
  454. msg.addByte(hasParent ? 0x01 : 0x00);
  455.  
  456. msg.addByte(container->isUnlocked() ? 0x01 : 0x00); // Drag and drop
  457. msg.addByte(container->hasPagination() ? 0x01 : 0x00); // Pagination
  458.  
  459. uint32_t containerSize = container->size();
  460. msg.add<uint16_t>(containerSize);
  461. msg.add<uint16_t>(firstIndex);
  462. if (firstIndex < containerSize) {
  463. uint8_t itemsToSend = std::min<uint32_t>(std::min<uint32_t>(container->capacity(), containerSize - firstIndex), std::numeric_limits<uint8_t>::max());
  464.  
  465. msg.addByte(itemsToSend);
  466. for (ItemDeque::const_iterator it = container->getItemList().begin() + firstIndex, end = it + itemsToSend; it != end; ++it) {
  467. msg.addItem(*it);
  468. }
  469. } else {
  470. msg.addByte(0x00);
  471. }
  472. writeToOutputBuffer(msg);
  473. }
  474.  
  475. void ProtocolGameBase::sendChannel(uint16_t channelId, const std::string& channelName, const UsersMap* channelUsers, const InvitedMap* invitedUsers)
  476. {
  477. NetworkMessage msg;
  478. msg.addByte(0xAC);
  479.  
  480. msg.add<uint16_t>(channelId);
  481. msg.addString(channelName);
  482.  
  483. if (channelUsers) {
  484. msg.add<uint16_t>(channelUsers->size());
  485. for (const auto& it : *channelUsers) {
  486. msg.addString(it.second->getName());
  487. }
  488. } else {
  489. msg.add<uint16_t>(0x00);
  490. }
  491.  
  492. if (invitedUsers) {
  493. msg.add<uint16_t>(invitedUsers->size());
  494. for (const auto& it : *invitedUsers) {
  495. msg.addString(it.second->getName());
  496. }
  497. } else {
  498. msg.add<uint16_t>(0x00);
  499. }
  500. writeToOutputBuffer(msg);
  501. }
  502.  
  503. void ProtocolGameBase::sendMagicEffect(const Position& pos, uint8_t type)
  504. {
  505. if (!canSee(pos)) {
  506. return;
  507. }
  508.  
  509. NetworkMessage msg;
  510. msg.addByte(0x83);
  511. msg.addPosition(pos);
  512. msg.addByte(type);
  513. writeToOutputBuffer(msg);
  514. }
  515.  
  516. void ProtocolGameBase::sendAddCreature(const Creature* creature, const Position& pos, int32_t stackpos, bool isLogin)
  517. {
  518. if (!canSee(pos)) {
  519. return;
  520. }
  521.  
  522. if (creature != player) {
  523. if (stackpos != -1) {
  524. NetworkMessage msg;
  525. msg.addByte(0x6A);
  526. msg.addPosition(pos);
  527. msg.addByte(stackpos);
  528.  
  529. bool known;
  530. uint32_t removedKnown;
  531. checkCreatureAsKnown(creature->getID(), known, removedKnown);
  532. AddCreature(msg, creature, known, removedKnown);
  533. writeToOutputBuffer(msg);
  534. }
  535.  
  536. if (isLogin) {
  537. sendMagicEffect(pos, CONST_ME_TELEPORT);
  538. }
  539. return;
  540. }
  541.  
  542. NetworkMessage msg;
  543. msg.addByte(0x17);
  544.  
  545. msg.add<uint32_t>(player->getID());
  546. msg.add<uint16_t>(0x32); // beat duration (50)
  547.  
  548. msg.addDouble(Creature::speedA, 3);
  549. msg.addDouble(Creature::speedB, 3);
  550. msg.addDouble(Creature::speedC, 3);
  551.  
  552. // can report bugs?
  553. if (player->getAccountType() >= ACCOUNT_TYPE_TUTOR) {
  554. msg.addByte(0x01);
  555. } else {
  556. msg.addByte(0x00);
  557. }
  558.  
  559. msg.addByte(0x00); // can change pvp framing option
  560. msg.addByte(0x00); // expert mode button enabled
  561. msg.addString("http://static.tibia.com/images/store/");
  562. msg.addByte(3);
  563.  
  564. writeToOutputBuffer(msg);
  565.  
  566. sendPendingStateEntered();
  567. sendEnterWorld();
  568. sendMapDescription(pos);
  569.  
  570. if (isLogin) {
  571. sendMagicEffect(pos, CONST_ME_TELEPORT);
  572. }
  573.  
  574. sendInventoryItem(CONST_SLOT_HEAD, player->getInventoryItem(CONST_SLOT_HEAD));
  575. sendInventoryItem(CONST_SLOT_NECKLACE, player->getInventoryItem(CONST_SLOT_NECKLACE));
  576. sendInventoryItem(CONST_SLOT_BACKPACK, player->getInventoryItem(CONST_SLOT_BACKPACK));
  577. sendInventoryItem(CONST_SLOT_ARMOR, player->getInventoryItem(CONST_SLOT_ARMOR));
  578. sendInventoryItem(CONST_SLOT_RIGHT, player->getInventoryItem(CONST_SLOT_RIGHT));
  579. sendInventoryItem(CONST_SLOT_LEFT, player->getInventoryItem(CONST_SLOT_LEFT));
  580. sendInventoryItem(CONST_SLOT_LEGS, player->getInventoryItem(CONST_SLOT_LEGS));
  581. sendInventoryItem(CONST_SLOT_FEET, player->getInventoryItem(CONST_SLOT_FEET));
  582. sendInventoryItem(CONST_SLOT_RING, player->getInventoryItem(CONST_SLOT_RING));
  583. sendInventoryItem(CONST_SLOT_AMMO, player->getInventoryItem(CONST_SLOT_AMMO));
  584.  
  585. sendStats();
  586. sendSkills();
  587.  
  588. //gameworld light-settings
  589. LightInfo lightInfo;
  590. g_game.getWorldLightInfo(lightInfo);
  591. sendWorldLight(lightInfo);
  592.  
  593. //player light level
  594. sendCreatureLight(creature);
  595.  
  596. const std::forward_list<VIPEntry>& vipEntries = IOLoginData::getVIPEntries(player->getAccount());
  597.  
  598. if (player->isAccessPlayer()) {
  599. for (const VIPEntry& entry : vipEntries) {
  600. VipStatus_t vipStatus;
  601.  
  602. Player* vipPlayer = g_game.getPlayerByGUID(entry.guid);
  603. if (!vipPlayer) {
  604. vipStatus = VIPSTATUS_OFFLINE;
  605. } else {
  606. vipStatus = VIPSTATUS_ONLINE;
  607. }
  608.  
  609. sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus);
  610. }
  611. } else {
  612. for (const VIPEntry& entry : vipEntries) {
  613. VipStatus_t vipStatus;
  614.  
  615. Player* vipPlayer = g_game.getPlayerByGUID(entry.guid);
  616. if (!vipPlayer || vipPlayer->isInGhostMode()) {
  617. vipStatus = VIPSTATUS_OFFLINE;
  618. } else {
  619. vipStatus = VIPSTATUS_ONLINE;
  620. }
  621.  
  622. sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus);
  623. }
  624. }
  625.  
  626. sendBasicData();
  627. player->sendIcons();
  628. }
  629.  
  630. void ProtocolGameBase::sendStats()
  631. {
  632. NetworkMessage msg;
  633. AddPlayerStats(msg);
  634. writeToOutputBuffer(msg);
  635. }
  636.  
  637. void ProtocolGameBase::sendBasicData()
  638. {
  639. NetworkMessage msg;
  640. msg.addByte(0x9F);
  641. msg.addByte(player->isPremium() ? 0x01 : 0x00);
  642. msg.add<uint32_t>(std::numeric_limits<uint32_t>::max());
  643. msg.addByte(player->getVocation()->getClientId());
  644. msg.add<uint16_t>(0x00);
  645. writeToOutputBuffer(msg);
  646. }
  647.  
  648. void ProtocolGameBase::sendPendingStateEntered()
  649. {
  650. NetworkMessage msg;
  651. msg.addByte(0x0A);
  652. writeToOutputBuffer(msg);
  653. }
  654.  
  655. void ProtocolGameBase::sendEnterWorld()
  656. {
  657. NetworkMessage msg;
  658. msg.addByte(0x0F);
  659. writeToOutputBuffer(msg);
  660. }
  661.  
  662. void ProtocolGameBase::sendInventoryItem(slots_t slot, const Item* item)
  663. {
  664. NetworkMessage msg;
  665. if (item) {
  666. msg.addByte(0x78);
  667. msg.addByte(slot);
  668. msg.addItem(item);
  669. } else {
  670. msg.addByte(0x79);
  671. msg.addByte(slot);
  672. }
  673. writeToOutputBuffer(msg);
  674. }
  675.  
  676. void ProtocolGameBase::sendSkills()
  677. {
  678. NetworkMessage msg;
  679. AddPlayerSkills(msg);
  680. writeToOutputBuffer(msg);
  681. }
  682.  
  683. void ProtocolGameBase::sendCreatureLight(const Creature* creature)
  684. {
  685. if (!canSee(creature)) {
  686. return;
  687. }
  688.  
  689. NetworkMessage msg;
  690. AddCreatureLight(msg, creature);
  691. writeToOutputBuffer(msg);
  692. }
  693.  
  694. void ProtocolGameBase::sendWorldLight(const LightInfo& lightInfo)
  695. {
  696. NetworkMessage msg;
  697. AddWorldLight(msg, lightInfo);
  698. writeToOutputBuffer(msg);
  699. }
  700.  
  701. void ProtocolGameBase::sendMapDescription(const Position& pos)
  702. {
  703. NetworkMessage msg;
  704. msg.addByte(0x64);
  705. msg.addPosition(player->getPosition());
  706. GetMapDescription(pos.x - 8, pos.y - 6, pos.z, 18, 14, msg);
  707. writeToOutputBuffer(msg);
  708. }
  709.  
  710. void ProtocolGameBase::sendVIP(uint32_t guid, const std::string& name, const std::string& description, uint32_t icon, bool notify, VipStatus_t status)
  711. {
  712. NetworkMessage msg;
  713. msg.addByte(0xD2);
  714. msg.add<uint32_t>(guid);
  715. msg.addString(name);
  716. msg.addString(description);
  717. msg.add<uint32_t>(std::min<uint32_t>(10, icon));
  718. msg.addByte(notify ? 0x01 : 0x00);
  719. msg.addByte(status);
  720. writeToOutputBuffer(msg);
  721. }
  722.  
  723. void ProtocolGameBase::sendCancelWalk()
  724. {
  725. NetworkMessage msg;
  726. msg.addByte(0xB5);
  727. msg.addByte(player->getDirection());
  728. writeToOutputBuffer(msg);
  729. }
  730.  
  731. void ProtocolGameBase::sendPing()
  732. {
  733. NetworkMessage msg;
  734. msg.addByte(0x1D);
  735. writeToOutputBuffer(msg, false);
  736. }
  737.  
  738. void ProtocolGameBase::sendPingBack()
  739. {
  740. NetworkMessage msg;
  741. msg.addByte(0x1E);
  742. writeToOutputBuffer(msg, false);
  743. }
Add Comment
Please, Sign In to add comment