No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

protocolgamesend.cpp 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. /*
  2. * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. * THE SOFTWARE.
  21. */
  22. #include "protocolgame.h"
  23. #include "game.h"
  24. #include "client.h"
  25. #include <framework/core/application.h>
  26. #include <framework/platform/platform.h>
  27. #include <framework/util/crypt.h>
  28. void ProtocolGame::send(const OutputMessagePtr& outputMessage)
  29. {
  30. // avoid usage of automated sends (bot modules)
  31. if(!g_game.checkBotProtection())
  32. return;
  33. Protocol::send(outputMessage);
  34. }
  35. void ProtocolGame::sendExtendedOpcode(uint8 opcode, const std::string& buffer)
  36. {
  37. if(m_enableSendExtendedOpcode) {
  38. OutputMessagePtr msg(new OutputMessage);
  39. msg->addU8(Proto::ClientExtendedOpcode);
  40. msg->addU8(opcode);
  41. msg->addString(buffer);
  42. send(msg);
  43. } else {
  44. g_logger.error(stdext::format("Unable to send extended opcode %d, extended opcodes are not enabled", opcode));
  45. }
  46. }
  47. void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRandom)
  48. {
  49. OutputMessagePtr msg(new OutputMessage);
  50. msg->addU8(Proto::ClientPendingGame);
  51. msg->addU16(g_game.getOs());
  52. msg->addU16(g_game.getProtocolVersion());
  53. if(g_game.getFeature(Otc::GameClientVersion))
  54. msg->addU32(g_game.getClientVersion());
  55. if(g_game.getFeature(Otc::GameContentRevision))
  56. msg->addU16(g_things.getContentRevision());
  57. if(g_game.getFeature(Otc::GamePreviewState))
  58. msg->addU8(0);
  59. int offset = msg->getMessageSize();
  60. // first RSA byte must be 0
  61. msg->addU8(0);
  62. if(g_game.getFeature(Otc::GameLoginPacketEncryption)) {
  63. // xtea key
  64. generateXteaKey();
  65. msg->addU32(m_xteaKey[0]);
  66. msg->addU32(m_xteaKey[1]);
  67. msg->addU32(m_xteaKey[2]);
  68. msg->addU32(m_xteaKey[3]);
  69. msg->addU8(0); // is gm set?
  70. }
  71. if(g_game.getFeature(Otc::GameSessionKey)) {
  72. msg->addString(m_sessionKey);
  73. msg->addString(m_characterName);
  74. } else {
  75. if(g_game.getFeature(Otc::GameAccountNames))
  76. msg->addString(m_accountName);
  77. else
  78. msg->addU32(stdext::from_string<uint32>(m_accountName));
  79. msg->addString(m_characterName);
  80. msg->addString(m_accountPassword);
  81. if(g_game.getFeature(Otc::GameAuthenticator))
  82. msg->addString(m_authenticatorToken);
  83. }
  84. if(g_game.getFeature(Otc::GameChallengeOnLogin)) {
  85. msg->addU32(challengeTimestamp);
  86. msg->addU8(challengeRandom);
  87. }
  88. std::string extended = callLuaField<std::string>("getLoginExtendedData");
  89. if(!extended.empty())
  90. msg->addString(extended);
  91. // complete the bytes for rsa encryption with zeros
  92. int paddingBytes = g_crypt.rsaGetSize() - (msg->getMessageSize() - offset);
  93. assert(paddingBytes >= 0);
  94. msg->addPaddingBytes(paddingBytes);
  95. // encrypt with RSA
  96. if(g_game.getFeature(Otc::GameLoginPacketEncryption))
  97. msg->encryptRsa();
  98. if(g_game.getFeature(Otc::GameProtocolChecksum))
  99. enableChecksum();
  100. send(msg);
  101. if(g_game.getFeature(Otc::GameLoginPacketEncryption))
  102. enableXteaEncryption();
  103. }
  104. void ProtocolGame::sendEnterGame()
  105. {
  106. OutputMessagePtr msg(new OutputMessage);
  107. msg->addU8(Proto::ClientEnterGame);
  108. send(msg);
  109. }
  110. void ProtocolGame::sendLogout()
  111. {
  112. OutputMessagePtr msg(new OutputMessage);
  113. msg->addU8(Proto::ClientLeaveGame);
  114. send(msg);
  115. }
  116. void ProtocolGame::sendPing()
  117. {
  118. if(g_game.getFeature(Otc::GameExtendedClientPing))
  119. sendExtendedOpcode(2, "");
  120. else {
  121. OutputMessagePtr msg(new OutputMessage);
  122. msg->addU8(Proto::ClientPing);
  123. Protocol::send(msg);
  124. }
  125. }
  126. void ProtocolGame::sendPingBack()
  127. {
  128. OutputMessagePtr msg(new OutputMessage);
  129. msg->addU8(Proto::ClientPingBack);
  130. send(msg);
  131. }
  132. void ProtocolGame::sendAutoWalk(const std::vector<Otc::Direction>& path)
  133. {
  134. OutputMessagePtr msg(new OutputMessage);
  135. msg->addU8(Proto::ClientAutoWalk);
  136. msg->addU8(path.size());
  137. for(Otc::Direction dir : path) {
  138. uint8 byte;
  139. switch(dir) {
  140. case Otc::East:
  141. byte = 1;
  142. break;
  143. case Otc::NorthEast:
  144. byte = 2;
  145. break;
  146. case Otc::North:
  147. byte = 3;
  148. break;
  149. case Otc::NorthWest:
  150. byte = 4;
  151. break;
  152. case Otc::West:
  153. byte = 5;
  154. break;
  155. case Otc::SouthWest:
  156. byte = 6;
  157. break;
  158. case Otc::South:
  159. byte = 7;
  160. break;
  161. case Otc::SouthEast:
  162. byte = 8;
  163. break;
  164. default:
  165. byte = 0;
  166. break;
  167. }
  168. msg->addU8(byte);
  169. }
  170. send(msg);
  171. }
  172. void ProtocolGame::sendWalkNorth()
  173. {
  174. OutputMessagePtr msg(new OutputMessage);
  175. msg->addU8(Proto::ClientWalkNorth);
  176. send(msg);
  177. }
  178. void ProtocolGame::sendWalkEast()
  179. {
  180. OutputMessagePtr msg(new OutputMessage);
  181. msg->addU8(Proto::ClientWalkEast);
  182. send(msg);
  183. }
  184. void ProtocolGame::sendWalkSouth()
  185. {
  186. OutputMessagePtr msg(new OutputMessage);
  187. msg->addU8(Proto::ClientWalkSouth);
  188. send(msg);
  189. }
  190. void ProtocolGame::sendWalkWest()
  191. {
  192. OutputMessagePtr msg(new OutputMessage);
  193. msg->addU8(Proto::ClientWalkWest);
  194. send(msg);
  195. }
  196. void ProtocolGame::sendStop()
  197. {
  198. OutputMessagePtr msg(new OutputMessage);
  199. msg->addU8(Proto::ClientStop);
  200. send(msg);
  201. }
  202. void ProtocolGame::sendWalkNorthEast()
  203. {
  204. OutputMessagePtr msg(new OutputMessage);
  205. msg->addU8(Proto::ClientWalkNorthEast);
  206. send(msg);
  207. }
  208. void ProtocolGame::sendWalkSouthEast()
  209. {
  210. OutputMessagePtr msg(new OutputMessage);
  211. msg->addU8(Proto::ClientWalkSouthEast);
  212. send(msg);
  213. }
  214. void ProtocolGame::sendWalkSouthWest()
  215. {
  216. OutputMessagePtr msg(new OutputMessage);
  217. msg->addU8(Proto::ClientWalkSouthWest);
  218. send(msg);
  219. }
  220. void ProtocolGame::sendWalkNorthWest()
  221. {
  222. OutputMessagePtr msg(new OutputMessage);
  223. msg->addU8(Proto::ClientWalkNorthWest);
  224. send(msg);
  225. }
  226. void ProtocolGame::sendTurnNorth()
  227. {
  228. OutputMessagePtr msg(new OutputMessage);
  229. msg->addU8(Proto::ClientTurnNorth);
  230. send(msg);
  231. }
  232. void ProtocolGame::sendTurnEast()
  233. {
  234. OutputMessagePtr msg(new OutputMessage);
  235. msg->addU8(Proto::ClientTurnEast);
  236. send(msg);
  237. }
  238. void ProtocolGame::sendTurnSouth()
  239. {
  240. OutputMessagePtr msg(new OutputMessage);
  241. msg->addU8(Proto::ClientTurnSouth);
  242. send(msg);
  243. }
  244. void ProtocolGame::sendTurnWest()
  245. {
  246. OutputMessagePtr msg(new OutputMessage);
  247. msg->addU8(Proto::ClientTurnWest);
  248. send(msg);
  249. }
  250. void ProtocolGame::sendEquipItem(int itemId, int countOrSubType)
  251. {
  252. OutputMessagePtr msg(new OutputMessage);
  253. msg->addU8(Proto::ClientEquipItem);
  254. msg->addU16(itemId);
  255. msg->addU8(countOrSubType);
  256. send(msg);
  257. }
  258. void ProtocolGame::sendMove(const Position& fromPos, int thingId, int stackpos, const Position& toPos, int count)
  259. {
  260. OutputMessagePtr msg(new OutputMessage);
  261. msg->addU8(Proto::ClientMove);
  262. addPosition(msg, fromPos);
  263. msg->addU16(thingId);
  264. msg->addU8(stackpos);
  265. addPosition(msg, toPos);
  266. msg->addU8(count);
  267. send(msg);
  268. }
  269. void ProtocolGame::sendInspectNpcTrade(int itemId, int count)
  270. {
  271. OutputMessagePtr msg(new OutputMessage);
  272. msg->addU8(Proto::ClientInspectNpcTrade);
  273. msg->addU16(itemId);
  274. msg->addU8(count);
  275. send(msg);
  276. }
  277. void ProtocolGame::sendBuyItem(int itemId, int subType, int amount, bool ignoreCapacity, bool buyWithBackpack)
  278. {
  279. OutputMessagePtr msg(new OutputMessage);
  280. msg->addU8(Proto::ClientBuyItem);
  281. msg->addU16(itemId);
  282. msg->addU8(subType);
  283. msg->addU8(amount);
  284. msg->addU8(ignoreCapacity ? 0x01 : 0x00);
  285. msg->addU8(buyWithBackpack ? 0x01 : 0x00);
  286. send(msg);
  287. }
  288. void ProtocolGame::sendSellItem(int itemId, int subType, int amount, bool ignoreEquipped)
  289. {
  290. OutputMessagePtr msg(new OutputMessage);
  291. msg->addU8(Proto::ClientSellItem);
  292. msg->addU16(itemId);
  293. msg->addU8(subType);
  294. if(g_game.getFeature(Otc::GameDoubleShopSellAmount))
  295. msg->addU16(amount);
  296. else
  297. msg->addU8(amount);
  298. msg->addU8(ignoreEquipped ? 0x01 : 0x00);
  299. send(msg);
  300. }
  301. void ProtocolGame::sendCloseNpcTrade()
  302. {
  303. OutputMessagePtr msg(new OutputMessage);
  304. msg->addU8(Proto::ClientCloseNpcTrade);
  305. send(msg);
  306. }
  307. void ProtocolGame::sendRequestTrade(const Position& pos, int thingId, int stackpos, uint creatureId)
  308. {
  309. OutputMessagePtr msg(new OutputMessage);
  310. msg->addU8(Proto::ClientRequestTrade);
  311. addPosition(msg, pos);
  312. msg->addU16(thingId);
  313. msg->addU8(stackpos);
  314. msg->addU32(creatureId);
  315. send(msg);
  316. }
  317. void ProtocolGame::sendInspectTrade(bool counterOffer, int index)
  318. {
  319. OutputMessagePtr msg(new OutputMessage);
  320. msg->addU8(Proto::ClientInspectTrade);
  321. msg->addU8(counterOffer ? 0x01 : 0x00);
  322. msg->addU8(index);
  323. send(msg);
  324. }
  325. void ProtocolGame::sendAcceptTrade()
  326. {
  327. OutputMessagePtr msg(new OutputMessage);
  328. msg->addU8(Proto::ClientAcceptTrade);
  329. send(msg);
  330. }
  331. void ProtocolGame::sendRejectTrade()
  332. {
  333. OutputMessagePtr msg(new OutputMessage);
  334. msg->addU8(Proto::ClientRejectTrade);
  335. send(msg);
  336. }
  337. void ProtocolGame::sendUseItem(const Position& position, int itemId, int stackpos, int index)
  338. {
  339. OutputMessagePtr msg(new OutputMessage);
  340. msg->addU8(Proto::ClientUseItem);
  341. addPosition(msg, position);
  342. msg->addU16(itemId);
  343. msg->addU8(stackpos);
  344. msg->addU8(index);
  345. send(msg);
  346. }
  347. void ProtocolGame::sendUseItemWith(const Position& fromPos, int itemId, int fromStackPos, const Position& toPos, int toThingId, int toStackPos)
  348. {
  349. OutputMessagePtr msg(new OutputMessage);
  350. msg->addU8(Proto::ClientUseItemWith);
  351. addPosition(msg, fromPos);
  352. msg->addU16(itemId);
  353. msg->addU8(fromStackPos);
  354. addPosition(msg, toPos);
  355. msg->addU16(toThingId);
  356. msg->addU8(toStackPos);
  357. send(msg);
  358. }
  359. void ProtocolGame::sendUseOnCreature(const Position& pos, int thingId, int stackpos, uint creatureId)
  360. {
  361. OutputMessagePtr msg(new OutputMessage);
  362. msg->addU8(Proto::ClientUseOnCreature);
  363. addPosition(msg, pos);
  364. msg->addU16(thingId);
  365. msg->addU8(stackpos);
  366. msg->addU32(creatureId);
  367. send(msg);
  368. }
  369. void ProtocolGame::sendRotateItem(const Position& pos, int thingId, int stackpos)
  370. {
  371. OutputMessagePtr msg(new OutputMessage);
  372. msg->addU8(Proto::ClientRotateItem);
  373. addPosition(msg, pos);
  374. msg->addU16(thingId);
  375. msg->addU8(stackpos);
  376. send(msg);
  377. }
  378. void ProtocolGame::sendCloseContainer(int containerId)
  379. {
  380. OutputMessagePtr msg(new OutputMessage);
  381. msg->addU8(Proto::ClientCloseContainer);
  382. msg->addU8(containerId);
  383. send(msg);
  384. }
  385. void ProtocolGame::sendUpContainer(int containerId)
  386. {
  387. OutputMessagePtr msg(new OutputMessage);
  388. msg->addU8(Proto::ClientUpContainer);
  389. msg->addU8(containerId);
  390. send(msg);
  391. }
  392. void ProtocolGame::sendEditText(uint id, const std::string& text)
  393. {
  394. OutputMessagePtr msg(new OutputMessage);
  395. msg->addU8(Proto::ClientEditText);
  396. msg->addU32(id);
  397. msg->addString(text);
  398. send(msg);
  399. }
  400. void ProtocolGame::sendEditList(uint id, int doorId, const std::string& text)
  401. {
  402. OutputMessagePtr msg(new OutputMessage);
  403. msg->addU8(Proto::ClientEditList);
  404. msg->addU8(doorId);
  405. msg->addU32(id);
  406. msg->addString(text);
  407. send(msg);
  408. }
  409. void ProtocolGame::sendLook(const Position& position, int thingId, int stackpos)
  410. {
  411. OutputMessagePtr msg(new OutputMessage);
  412. msg->addU8(Proto::ClientLook);
  413. addPosition(msg, position);
  414. msg->addU16(thingId);
  415. msg->addU8(stackpos);
  416. send(msg);
  417. }
  418. void ProtocolGame::sendLookCreature(uint32 creatureId)
  419. {
  420. OutputMessagePtr msg(new OutputMessage);
  421. msg->addU8(Proto::ClientLookCreature);
  422. msg->addU32(creatureId);
  423. send(msg);
  424. }
  425. void ProtocolGame::sendTalk(Otc::MessageMode mode, int channelId, const std::string& receiver, const std::string& message)
  426. {
  427. if(message.empty())
  428. return;
  429. if(message.length() > 255) {
  430. g_logger.traceError("message too large");
  431. return;
  432. }
  433. OutputMessagePtr msg(new OutputMessage);
  434. msg->addU8(Proto::ClientTalk);
  435. msg->addU8(Proto::translateMessageModeToServer(mode));
  436. switch(mode) {
  437. case Otc::MessagePrivateTo:
  438. case Otc::MessageGamemasterPrivateTo:
  439. case Otc::MessageRVRAnswer:
  440. msg->addString(receiver);
  441. break;
  442. case Otc::MessageChannel:
  443. case Otc::MessageChannelHighlight:
  444. case Otc::MessageChannelManagement:
  445. case Otc::MessageGamemasterChannel:
  446. msg->addU16(channelId);
  447. break;
  448. default:
  449. break;
  450. }
  451. msg->addString(message);
  452. send(msg);
  453. }
  454. void ProtocolGame::sendRequestChannels()
  455. {
  456. OutputMessagePtr msg(new OutputMessage);
  457. msg->addU8(Proto::ClientRequestChannels);
  458. send(msg);
  459. }
  460. void ProtocolGame::sendJoinChannel(int channelId)
  461. {
  462. OutputMessagePtr msg(new OutputMessage);
  463. msg->addU8(Proto::ClientJoinChannel);
  464. msg->addU16(channelId);
  465. send(msg);
  466. }
  467. void ProtocolGame::sendLeaveChannel(int channelId)
  468. {
  469. OutputMessagePtr msg(new OutputMessage);
  470. msg->addU8(Proto::ClientLeaveChannel);
  471. msg->addU16(channelId);
  472. send(msg);
  473. }
  474. void ProtocolGame::sendOpenPrivateChannel(const std::string& receiver)
  475. {
  476. OutputMessagePtr msg(new OutputMessage);
  477. msg->addU8(Proto::ClientOpenPrivateChannel);
  478. msg->addString(receiver);
  479. send(msg);
  480. }
  481. void ProtocolGame::sendOpenRuleViolation(const std::string& reporter)
  482. {
  483. OutputMessagePtr msg(new OutputMessage);
  484. msg->addU8(Proto::ClientOpenRuleViolation);
  485. msg->addString(reporter);
  486. send(msg);
  487. }
  488. void ProtocolGame::sendCloseRuleViolation(const std::string& reporter)
  489. {
  490. OutputMessagePtr msg(new OutputMessage);
  491. msg->addU8(Proto::ClientCloseRuleViolation);
  492. msg->addString(reporter);
  493. send(msg);
  494. }
  495. void ProtocolGame::sendCancelRuleViolation()
  496. {
  497. OutputMessagePtr msg(new OutputMessage);
  498. msg->addU8(Proto::ClientCancelRuleViolation);
  499. send(msg);
  500. }
  501. void ProtocolGame::sendCloseNpcChannel()
  502. {
  503. OutputMessagePtr msg(new OutputMessage);
  504. msg->addU8(Proto::ClientCloseNpcChannel);
  505. send(msg);
  506. }
  507. void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight, Otc::PVPModes pvpMode)
  508. {
  509. OutputMessagePtr msg(new OutputMessage);
  510. msg->addU8(Proto::ClientChangeFightModes);
  511. msg->addU8(fightMode);
  512. msg->addU8(chaseMode);
  513. msg->addU8(safeFight ? 0x01: 0x00);
  514. if(g_game.getFeature(Otc::GamePVPMode))
  515. msg->addU8(pvpMode);
  516. send(msg);
  517. }
  518. void ProtocolGame::sendAttack(uint creatureId, uint seq)
  519. {
  520. OutputMessagePtr msg(new OutputMessage);
  521. msg->addU8(Proto::ClientAttack);
  522. msg->addU32(creatureId);
  523. if(g_game.getFeature(Otc::GameAttackSeq))
  524. msg->addU32(seq);
  525. send(msg);
  526. }
  527. void ProtocolGame::sendFollow(uint creatureId, uint seq)
  528. {
  529. OutputMessagePtr msg(new OutputMessage);
  530. msg->addU8(Proto::ClientFollow);
  531. msg->addU32(creatureId);
  532. if(g_game.getFeature(Otc::GameAttackSeq))
  533. msg->addU32(seq);
  534. send(msg);
  535. }
  536. void ProtocolGame::sendInviteToParty(uint creatureId)
  537. {
  538. OutputMessagePtr msg(new OutputMessage);
  539. msg->addU8(Proto::ClientInviteToParty);
  540. msg->addU32(creatureId);
  541. send(msg);
  542. }
  543. void ProtocolGame::sendJoinParty(uint creatureId)
  544. {
  545. OutputMessagePtr msg(new OutputMessage);
  546. msg->addU8(Proto::ClientJoinParty);
  547. msg->addU32(creatureId);
  548. send(msg);
  549. }
  550. void ProtocolGame::sendRevokeInvitation(uint creatureId)
  551. {
  552. OutputMessagePtr msg(new OutputMessage);
  553. msg->addU8(Proto::ClientRevokeInvitation);
  554. msg->addU32(creatureId);
  555. send(msg);
  556. }
  557. void ProtocolGame::sendPassLeadership(uint creatureId)
  558. {
  559. OutputMessagePtr msg(new OutputMessage);
  560. msg->addU8(Proto::ClientPassLeadership);
  561. msg->addU32(creatureId);
  562. send(msg);
  563. }
  564. void ProtocolGame::sendLeaveParty()
  565. {
  566. OutputMessagePtr msg(new OutputMessage);
  567. msg->addU8(Proto::ClientLeaveParty);
  568. send(msg);
  569. }
  570. void ProtocolGame::sendShareExperience(bool active)
  571. {
  572. OutputMessagePtr msg(new OutputMessage);
  573. msg->addU8(Proto::ClientShareExperience);
  574. msg->addU8(active ? 0x01 : 0x00);
  575. if(g_game.getClientVersion() < 910)
  576. msg->addU8(0);
  577. send(msg);
  578. }
  579. void ProtocolGame::sendOpenOwnChannel()
  580. {
  581. OutputMessagePtr msg(new OutputMessage);
  582. msg->addU8(Proto::ClientOpenOwnChannel);
  583. send(msg);
  584. }
  585. void ProtocolGame::sendInviteToOwnChannel(const std::string& name)
  586. {
  587. OutputMessagePtr msg(new OutputMessage);
  588. msg->addU8(Proto::ClientInviteToOwnChannel);
  589. msg->addString(name);
  590. send(msg);
  591. }
  592. void ProtocolGame::sendExcludeFromOwnChannel(const std::string& name)
  593. {
  594. OutputMessagePtr msg(new OutputMessage);
  595. msg->addU8(Proto::ClientExcludeFromOwnChannel);
  596. msg->addString(name);
  597. send(msg);
  598. }
  599. void ProtocolGame::sendCancelAttackAndFollow()
  600. {
  601. OutputMessagePtr msg(new OutputMessage);
  602. msg->addU8(Proto::ClientCancelAttackAndFollow);
  603. send(msg);
  604. }
  605. void ProtocolGame::sendRefreshContainer(int containerId)
  606. {
  607. OutputMessagePtr msg(new OutputMessage);
  608. msg->addU8(Proto::ClientRefreshContainer);
  609. msg->addU8(containerId);
  610. send(msg);
  611. }
  612. void ProtocolGame::sendRequestOutfit()
  613. {
  614. OutputMessagePtr msg(new OutputMessage);
  615. msg->addU8(Proto::ClientRequestOutfit);
  616. send(msg);
  617. }
  618. void ProtocolGame::sendChangeOutfit(const Outfit& outfit)
  619. {
  620. OutputMessagePtr msg(new OutputMessage);
  621. msg->addU8(Proto::ClientChangeOutfit);
  622. if(g_game.getFeature(Otc::GameLooktypeU16))
  623. msg->addU16(outfit.getId());
  624. else
  625. msg->addU8(outfit.getId());
  626. msg->addU8(outfit.getHead());
  627. msg->addU8(outfit.getBody());
  628. msg->addU8(outfit.getLegs());
  629. msg->addU8(outfit.getFeet());
  630. if(g_game.getFeature(Otc::GamePlayerAddons))
  631. msg->addU8(outfit.getAddons());
  632. if(g_game.getFeature(Otc::GamePlayerMounts))
  633. msg->addU16(outfit.getMount());
  634. send(msg);
  635. }
  636. void ProtocolGame::sendMountStatus(bool mount)
  637. {
  638. if(g_game.getFeature(Otc::GamePlayerMounts)) {
  639. OutputMessagePtr msg(new OutputMessage);
  640. msg->addU8(Proto::ClientMount);
  641. msg->addU8(mount);
  642. send(msg);
  643. } else {
  644. g_logger.error("ProtocolGame::sendMountStatus does not support the current protocol.");
  645. }
  646. }
  647. void ProtocolGame::sendAddVip(const std::string& name)
  648. {
  649. OutputMessagePtr msg(new OutputMessage);
  650. msg->addU8(Proto::ClientAddVip);
  651. msg->addString(name);
  652. send(msg);
  653. }
  654. void ProtocolGame::sendRemoveVip(uint playerId)
  655. {
  656. OutputMessagePtr msg(new OutputMessage);
  657. msg->addU8(Proto::ClientRemoveVip);
  658. msg->addU32(playerId);
  659. send(msg);
  660. }
  661. void ProtocolGame::sendEditVip(uint playerId, const std::string& description, int iconId, bool notifyLogin)
  662. {
  663. OutputMessagePtr msg(new OutputMessage);
  664. msg->addU8(Proto::ClientEditVip);
  665. msg->addU32(playerId);
  666. msg->addString(description);
  667. msg->addU32(iconId);
  668. msg->addU8(notifyLogin);
  669. send(msg);
  670. }
  671. void ProtocolGame::sendBugReport(const std::string& comment)
  672. {
  673. OutputMessagePtr msg(new OutputMessage);
  674. msg->addU8(Proto::ClientBugReport);
  675. msg->addString(comment);
  676. send(msg);
  677. }
  678. void ProtocolGame::sendRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment)
  679. {
  680. OutputMessagePtr msg(new OutputMessage);
  681. msg->addU8(Proto::ClientRuleViolation);
  682. msg->addString(target);
  683. msg->addU8(reason);
  684. msg->addU8(action);
  685. msg->addString(comment);
  686. msg->addString(statement);
  687. msg->addU16(statementId);
  688. msg->addU8(ipBanishment);
  689. send(msg);
  690. }
  691. void ProtocolGame::sendDebugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d)
  692. {
  693. OutputMessagePtr msg(new OutputMessage);
  694. msg->addU8(Proto::ClientDebugReport);
  695. msg->addString(a);
  696. msg->addString(b);
  697. msg->addString(c);
  698. msg->addString(d);
  699. send(msg);
  700. }
  701. void ProtocolGame::sendRequestQuestLog()
  702. {
  703. OutputMessagePtr msg(new OutputMessage);
  704. msg->addU8(Proto::ClientRequestQuestLog);
  705. send(msg);
  706. }
  707. void ProtocolGame::sendRequestQuestLine(int questId)
  708. {
  709. OutputMessagePtr msg(new OutputMessage);
  710. msg->addU8(Proto::ClientRequestQuestLine);
  711. msg->addU16(questId);
  712. send(msg);
  713. }
  714. void ProtocolGame::sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation)
  715. {
  716. OutputMessagePtr msg(new OutputMessage);
  717. msg->addU8(Proto::ClientNewRuleViolation);
  718. msg->addU8(reason);
  719. msg->addU8(action);
  720. msg->addString(characterName);
  721. msg->addString(comment);
  722. msg->addString(translation);
  723. send(msg);
  724. }
  725. void ProtocolGame::sendRequestItemInfo(int itemId, int subType, int index)
  726. {
  727. OutputMessagePtr msg(new OutputMessage);
  728. msg->addU8(Proto::ClientRequestItemInfo);
  729. msg->addU8(subType);
  730. msg->addU16(itemId);
  731. msg->addU8(index);
  732. send(msg);
  733. }
  734. void ProtocolGame::sendAnswerModalDialog(uint32 dialog, int button, int choice)
  735. {
  736. OutputMessagePtr msg(new OutputMessage);
  737. msg->addU8(Proto::ClientAnswerModalDialog);
  738. msg->addU32(dialog);
  739. msg->addU8(button);
  740. msg->addU8(choice);
  741. send(msg);
  742. }
  743. void ProtocolGame::sendBrowseField(const Position& position)
  744. {
  745. if(!g_game.getFeature(Otc::GameBrowseField))
  746. return;
  747. OutputMessagePtr msg(new OutputMessage);
  748. msg->addU8(Proto::ClientBrowseField);
  749. addPosition(msg, position);
  750. send(msg);
  751. }
  752. void ProtocolGame::sendSeekInContainer(int cid, int index)
  753. {
  754. if(!g_game.getFeature(Otc::GameContainerPagination))
  755. return;
  756. OutputMessagePtr msg(new OutputMessage);
  757. msg->addU8(Proto::ClientSeekInContainer);
  758. msg->addU8(cid);
  759. msg->addU16(index);
  760. send(msg);
  761. }
  762. void ProtocolGame::sendBuyStoreOffer(int offerId, int productType, const std::string& name)
  763. {
  764. OutputMessagePtr msg(new OutputMessage);
  765. msg->addU8(Proto::ClientBuyStoreOffer);
  766. msg->addU32(offerId);
  767. msg->addU8(productType);
  768. if(productType == Otc::ProductTypeNameChange)
  769. msg->addString(name);
  770. send(msg);
  771. }
  772. void ProtocolGame::sendRequestTransactionHistory(int page, int entriesPerPage)
  773. {
  774. OutputMessagePtr msg(new OutputMessage);
  775. msg->addU8(Proto::ClientRequestTransactionHistory);
  776. if(g_game.getClientVersion() <= 1096) {
  777. msg->addU16(page);
  778. msg->addU32(entriesPerPage);
  779. } else {
  780. msg->addU32(page);
  781. msg->addU8(entriesPerPage);
  782. }
  783. send(msg);
  784. }
  785. void ProtocolGame::sendRequestStoreOffers(const std::string& categoryName, int serviceType)
  786. {
  787. OutputMessagePtr msg(new OutputMessage);
  788. msg->addU8(Proto::ClientRequestStoreOffers);
  789. if(g_game.getFeature(Otc::GameIngameStoreServiceType)) {
  790. msg->addU8(serviceType);
  791. }
  792. msg->addString(categoryName);
  793. send(msg);
  794. }
  795. void ProtocolGame::sendOpenStore(int serviceType, const std::string& category)
  796. {
  797. OutputMessagePtr msg(new OutputMessage);
  798. msg->addU8(Proto::ClientOpenStore);
  799. if(g_game.getFeature(Otc::GameIngameStoreServiceType)) {
  800. msg->addU8(serviceType);
  801. msg->addString(category);
  802. }
  803. send(msg);
  804. }
  805. void ProtocolGame::sendTransferCoins(const std::string& recipient, int amount)
  806. {
  807. OutputMessagePtr msg(new OutputMessage);
  808. msg->addU8(Proto::ClientTransferCoins);
  809. msg->addString(recipient);
  810. msg->addU16(amount);
  811. send(msg);
  812. }
  813. void ProtocolGame::sendOpenTransactionHistory(int entriesPerPage)
  814. {
  815. OutputMessagePtr msg(new OutputMessage);
  816. msg->addU8(Proto::ClientOpenTransactionHistory);
  817. msg->addU8(entriesPerPage);
  818. send(msg);
  819. }
  820. void ProtocolGame::sendChangeMapAwareRange(int xrange, int yrange)
  821. {
  822. if(!g_game.getFeature(Otc::GameChangeMapAwareRange))
  823. return;
  824. OutputMessagePtr msg(new OutputMessage);
  825. msg->addU8(Proto::ClientChangeMapAwareRange);
  826. msg->addU8(xrange);
  827. msg->addU8(yrange);
  828. send(msg);
  829. }
  830. void ProtocolGame::addPosition(const OutputMessagePtr& msg, const Position& position)
  831. {
  832. msg->addU16(position.x);
  833. msg->addU16(position.y);
  834. msg->addU8(position.z);
  835. }