ServerType0.pm.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:43k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - Network subsystem
  3. #  This module contains functions for sending messages to the server.
  4. #
  5. #  This software is open source, licensed under the GNU General Public
  6. #  License, version 2.
  7. #  Basically, this means that you're allowed to modify and distribute
  8. #  this software. However, if you distribute modified versions, you MUST
  9. #  also distribute the source code.
  10. #  See http://www.gnu.org/licenses/gpl.html for the full license.
  11. #########################################################################
  12. # June 21 2007, this is the server type for:
  13. # pRO (Philippines), except Sakray and Thor
  14. # And many other servers.
  15. # Servertype overview: http://www.openkore.com/wiki/index.php/ServerType
  16. package Network::Send::ServerType0;
  17. use strict;
  18. use Time::HiRes qw(time);
  19. use Digest::MD5;
  20. use Network::Send ();
  21. use base qw(Network::Send);
  22. use Plugins;
  23. use Globals qw($accountID $sessionID $sessionID2 $accountSex $char $charID %config %guild @chars $masterServer $syncSync);
  24. use Log qw(debug);
  25. use Translation qw(T TF);
  26. use I18N qw(stringToBytes);
  27. use Utils;
  28. use Utils::Exceptions;
  29. sub new {
  30. my ($class) = @_;
  31. return $class->SUPER::new(@_);
  32. }
  33. sub sendAddSkillPoint {
  34. my ($self, $skillID) = @_;
  35. my $msg = pack("C*", 0x12, 0x01) . pack("v*", $skillID);
  36. $self->sendToServer($msg);
  37. }
  38. sub sendAddStatusPoint {
  39. my ($self, $statusID) = @_;
  40. my $msg = pack("C*", 0xBB, 0) . pack("v*", $statusID) . pack("C*", 0x01);
  41. $self->sendToServer($msg);
  42. }
  43. sub sendAlignment {
  44. my ($self, $ID, $alignment) = @_;
  45. my $msg = pack("C*", 0x49, 0x01) . $ID . pack("C*", $alignment);
  46. $self->sendToServer($msg);
  47. debug "Sent Alignment: ".getHex($ID).", $alignmentn", "sendPacket", 2;
  48. }
  49. sub sendArrowCraft {
  50. my ($self, $index) = @_;
  51. my $msg = pack("C*", 0xAE, 0x01) . pack("v*", $index);
  52. $self->sendToServer($msg);
  53. debug "Sent Arrowmake: $indexn", "sendPacket", 2;
  54. }
  55. sub sendAttack {
  56. my ($self, $monID, $flag) = @_;
  57. my $msg;
  58. $msg = pack("C*", 0x89, 0x00) .
  59. $monID .
  60. pack("C*", $flag);
  61. $self->sendToServer($msg);
  62. debug "Sent attack: ".getHex($monID)."n", "sendPacket", 2;
  63. }
  64. sub sendAttackStop {
  65. my $self = shift;
  66. #my $msg = pack("C*", 0x18, 0x01);
  67. # Apparently this packet is wrong. The server disconnects us if we do this.
  68. # Sending a move command to the current position seems to be able to emulate
  69. # what this function is supposed to do.
  70. # Don't use this function, use Misc::stopAttack() instead!
  71. #sendMove ($char->{'pos_to'}{'x'}, $char->{'pos_to'}{'y'});
  72. #debug "Sent stop attackn", "sendPacket";
  73. }
  74. sub sendAutoSpell {
  75. my ($self, $ID) = @_;
  76. my $msg = pack("C*", 0xce, 0x01, $ID, 0x00, 0x00, 0x00);
  77. $self->sendToServer($msg);
  78. }
  79. sub sendBanCheck {
  80. my ($self, $ID) = @_;
  81. my $msg = pack("C*", 0x87, 0x01) . $ID;
  82. $self->sendToServer($msg);
  83. debug "Sent Account Ban Check Request : " . getHex($ID) . "n", "sendPacket", 2;
  84. }
  85. sub sendBuy {
  86. my ($self, $ID, $amount) = @_;
  87. my $msg = pack("C*", 0xC8, 0x00, 0x08, 0x00) . pack("v*", $amount, $ID);
  88. $self->sendToServer($msg);
  89. debug "Sent buy: ".getHex($ID)."n", "sendPacket", 2;
  90. }
  91. sub sendBuyVender {
  92. my ($self, $venderID, $ID, $amount) = @_;
  93. my $msg = pack("C*", 0x34, 0x01, 0x0C, 0x00) . $venderID . pack("v*", $amount, $ID);
  94. $self->sendToServer($msg);
  95. debug "Sent Vender Buy: ".getHex($ID)."n", "sendPacket";
  96. }
  97. sub sendCardMerge {
  98. my ($self, $card_index, $item_index) = @_;
  99. my $msg = pack("C*", 0x7C, 0x01) . pack("v*", $card_index, $item_index);
  100. $self->sendToServer($msg);
  101. debug "Sent Card Merge: $card_index, $item_indexn", "sendPacket";
  102. }
  103. sub sendCardMergeRequest {
  104. my ($self, $card_index) = @_;
  105. my $msg = pack("C*", 0x7A, 0x01) . pack("v*", $card_index);
  106. $self->sendToServer($msg);
  107. debug "Sent Card Merge Request: $card_indexn", "sendPacket";
  108. }
  109. sub sendCartAdd {
  110. my ($self, $index, $amount) = @_;
  111. my $msg = pack("C*", 0x26, 0x01) . pack("v*", $index) . pack("V*", $amount);
  112. $self->sendToServer($msg);
  113. debug "Sent Cart Add: $index x $amountn", "sendPacket", 2;
  114. }
  115. sub sendCartGet {
  116. my ($self, $index, $amount) = @_;
  117. my $msg = pack("C*", 0x27, 0x01) . pack("v*", $index) . pack("V*", $amount);
  118. $self->sendToServer($msg);
  119. debug "Sent Cart Get: $index x $amountn", "sendPacket", 2;
  120. }
  121. sub sendCharCreate {
  122. my ($self, $slot, $name,
  123.     $str, $agi, $vit, $int, $dex, $luk,
  124. $hair_style, $hair_color) = @_;
  125. $hair_color ||= 1;
  126. $hair_style ||= 0;
  127. my $msg = pack("C*", 0x67, 0x00) .
  128. pack("a24", stringToBytes($name)) .
  129. pack("C*", $str, $agi, $vit, $int, $dex, $luk, $slot) .
  130. pack("v*", $hair_color, $hair_style);
  131. $self->sendToServer($msg);
  132. }
  133. sub sendCharDelete {
  134. my ($self, $charID, $email) = @_;
  135. my $msg = pack("C*", 0x68, 0x00) .
  136. $charID . pack("a40", stringToBytes($email));
  137. $self->sendToServer($msg);
  138. }
  139. sub sendCharLogin {
  140. my ($self, $char) = @_;
  141. my $msg = pack("C*", 0x66,0) . pack("C*",$char);
  142. $self->sendToServer($msg);
  143. }
  144. sub sendChat {
  145. my ($self, $message) = @_;
  146. $message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");
  147. my ($data, $charName); # Type: Bytes
  148. $message = stringToBytes($message); # Type: Bytes
  149. $charName = stringToBytes($char->{name});
  150. $data = pack("C*", 0x8C, 0x00) .
  151. pack("v*", length($charName) + length($message) + 8) .
  152. $charName . " : " . $message . chr(0);
  153. $self->sendToServer($data);
  154. }
  155. sub sendChatRoomBestow {
  156. my ($self, $name) = @_;
  157. my $binName = stringToBytes($name);
  158. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  159. $binName .= chr(0) x (24 - length($binName));
  160. my $msg = pack("C*", 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00) . $binName;
  161. $self->sendToServer($msg);
  162. debug "Sent Chat Room Bestow: $namen", "sendPacket", 2;
  163. }
  164. sub sendChatRoomChange {
  165. my ($self, $title, $limit, $public, $password) = @_;
  166. my $titleBytes = stringToBytes($title);
  167. my $passwordBytes = stringToBytes($password);
  168. $passwordBytes = substr($passwordBytes, 0, 8) if (length($passwordBytes) > 8);
  169. $passwordBytes = $passwordBytes . chr(0) x (8 - length($passwordBytes));
  170. my $msg = pack("C*", 0xDE, 0x00).pack("v*", length($titleBytes) + 15, $limit).pack("C*",$public).$passwordBytes.$titleBytes;
  171. $self->sendToServer($msg);
  172. debug "Sent Change Chat Room: $title, $limit, $public, $passwordn", "sendPacket", 2;
  173. }
  174. sub sendChatRoomCreate {
  175. my ($self, $title, $limit, $public, $password) = @_;
  176. my $passwordBytes = stringToBytes($password);
  177. $passwordBytes = substr($passwordBytes, 0, 8) if (length($passwordBytes) > 8);
  178. $passwordBytes = $passwordBytes . chr(0) x (8 - length($passwordBytes));
  179. my $binTitle = stringToBytes($title);
  180. my $msg = pack("C*", 0xD5, 0x00) .
  181. pack("v*", length($binTitle) + 15, $limit) .
  182. pack("C*", $public) . $passwordBytes . $binTitle;
  183. $self->sendToServer($msg);
  184. debug "Sent Create Chat Room: $title, $limit, $public, $passwordn", "sendPacket", 2;
  185. }
  186. sub sendChatRoomJoin {
  187. my ($self, $ID, $password) = @_;
  188. my $passwordBytes = stringToBytes($password);
  189. $passwordBytes = substr($passwordBytes, 0, 8) if (length($passwordBytes) > 8);
  190. $passwordBytes = $passwordBytes . chr(0) x (8 - length($passwordBytes));
  191. my $msg = pack("C*", 0xD9, 0x00).$ID.$passwordBytes;
  192. $self->sendToServer($msg);
  193. debug "Sent Join Chat Room: ".getHex($ID)." $passwordn", "sendPacket", 2;
  194. }
  195. sub sendChatRoomKick {
  196. my ($self, $name) = @_;
  197. my $binName = stringToBytes($name);
  198. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  199. $binName .= chr(0) x (24 - length($binName));
  200. my $msg = pack("C*", 0xE2, 0x00) . $binName;
  201. $self->sendToServer($msg);
  202. debug "Sent Chat Room Kick: $namen", "sendPacket", 2;
  203. }
  204. sub sendChatRoomLeave {
  205. my $self = shift;
  206. my $msg = pack("C*", 0xE3, 0x00);
  207. $self->sendToServer($msg);
  208. debug "Sent Leave Chat Roomn", "sendPacket", 2;
  209. }
  210. sub sendCloseShop {
  211. my $self = shift;
  212. my $msg = pack("C*", 0x2E, 0x01);
  213. $self->sendToServer($msg);
  214. debug "Shop Closedn", "sendPacket", 2;
  215. }
  216. sub sendCommandMercenary {
  217. my ($self, $command, $type) = @_;
  218. # $type is ignored, $command can be 0, 1 or 2
  219. my $msg = pack ('v2 C1', 0x022D, $type, $command);
  220. $self->sendToServer ($msg);
  221. debug "Sent MercenaryCommand", "sendPacket", 2;
  222. }
  223. sub sendCompanionRelease {
  224. my $msg = pack("C*", 0x2A, 0x01);
  225. $_[0]->sendToServer($msg);
  226. debug "Sent Companion Release (Cart, Falcon or Pecopeco)n", "sendPacket", 2;
  227. }
  228. sub sendCurrentDealCancel {
  229. my $msg = pack("C*", 0xED, 0x00);
  230. $_[0]->sendToServer($msg);
  231. debug "Sent Cancel Current Dealn", "sendPacket", 2;
  232. }
  233. sub sendDeal {
  234. my ($self, $ID) = @_;
  235. my $msg = pack("C*", 0xE4, 0x00) . $ID;
  236. $_[0]->sendToServer($msg);
  237. debug "Sent Initiate Deal: ".getHex($ID)."n", "sendPacket", 2;
  238. }
  239. sub sendDealAccept {
  240. my $msg = pack("C*", 0xE6, 0x00, 0x03);
  241. $_[0]->sendToServer($msg);
  242. debug "Sent Accept Dealn", "sendPacket", 2;
  243. }
  244. sub sendDealAddItem {
  245. my ($self, $index, $amount) = @_;
  246. my $msg = pack("C*", 0xE8, 0x00) . pack("v*", $index) . pack("V*",$amount);
  247. $_[0]->sendToServer($msg);
  248. debug "Sent Deal Add Item: $index, $amountn", "sendPacket", 2;
  249. }
  250. sub sendDealCancel {
  251. my $msg = pack("C*", 0xE6, 0x00, 0x04);
  252. $_[0]->sendToServer($msg);
  253. debug "Sent Cancel Dealn", "sendPacket", 2;
  254. }
  255. sub sendDealFinalize {
  256. my $msg = pack("C*", 0xEB, 0x00);
  257. $_[0]->sendToServer($msg);
  258. debug "Sent Deal OKn", "sendPacket", 2;
  259. }
  260. sub sendDealOK {
  261. my $msg = pack("C*", 0xEB, 0x00);
  262. $_[0]->sendToServer($msg);
  263. debug "Sent Deal OKn", "sendPacket", 2;
  264. }
  265. sub sendDealTrade {
  266. my $msg = pack("C*", 0xEF, 0x00);
  267. $_[0]->sendToServer($msg);
  268. debug "Sent Deal Traden", "sendPacket", 2;
  269. }
  270. sub sendDrop {
  271. my ($self, $index, $amount) = @_;
  272. my $msg;
  273. $msg = pack("C*", 0xA2, 0x00) . pack("v*", $index, $amount);
  274. $self->sendToServer($msg);
  275. debug "Sent drop: $index x $amountn", "sendPacket", 2;
  276. }
  277. sub sendEmotion {
  278. my ($self, $ID) = @_;
  279. my $msg = pack("C*", 0xBF, 0x00).pack("C1",$ID);
  280. $self->sendToServer($msg);
  281. debug "Sent Emotionn", "sendPacket", 2;
  282. }
  283. sub sendEnteringVender {
  284. my ($self, $ID) = @_;
  285. my $msg = pack("C*", 0x30, 0x01) . $ID;
  286. $self->sendToServer($msg);
  287. debug "Sent Entering Vender: ".getHex($ID)."n", "sendPacket", 2;
  288. }
  289. sub sendEquip {
  290. my ($self, $index, $type) = @_;
  291. my $msg = pack("C*", 0xA9, 0x00) . pack("v*", $index) .  pack("v*", $type);
  292. $self->sendToServer($msg);
  293. debug "Sent Equip: $index Type: $typen" , 2;
  294. }
  295. sub sendFriendAccept {
  296. my ($self, $accountID, $charID) = @_;
  297. my $msg = pack("C*", 0x08, 0x02) . $accountID . $charID . pack("C*", 0x01, 0x00, 0x00, 0x00);
  298. $self->sendToServer($msg);
  299. debug "Sent Accept friend requestn", "sendPacket";
  300. }
  301. sub sendFriendReject {
  302. my ($self, $accountID, $charID) = @_;
  303. my $msg = pack("C*", 0x08, 0x02) . $accountID . $charID . pack("C*", 0x00, 0x00, 0x00, 0x00);
  304. $self->sendToServer($msg);
  305. debug "Sent Reject friend requestn", "sendPacket";
  306. }
  307. sub sendFriendRequest {
  308. my ($self, $name) = @_;
  309. my $binName = stringToBytes($name);
  310. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  311. $binName = $binName . chr(0) x (24 - length($binName));
  312. my $msg = pack("C*", 0x02, 0x02) . $binName;
  313. $self->sendToServer($msg);
  314. debug "Sent Request to be a friend: $namen", "sendPacket";
  315. }
  316. sub sendFriendRemove {
  317. my ($self, $accountID, $charID) = @_;
  318. my $msg = pack("C*", 0x03, 0x02) . $accountID . $charID;
  319. $self->sendToServer($msg);
  320. debug "Sent Remove a friendn", "sendPacket";
  321. }
  322. sub sendForgeItem {
  323. my ($self, $ID,
  324. # nameIDs for added items such as Star Crumb or Flame Heart
  325. $item1, $item2, $item3) = @_;
  326. my $msg = pack("C*", 0x8E, 0x01) . pack("v1 v1 v1 v1", $ID, $item1, $item2, $item3);
  327. $self->sendToServer($msg);
  328. debug "Sent Forge Item: $IDn" , 2;
  329. }
  330. sub sendGameLogin {
  331. my ($self, $accountID, $sessionID, $sessionID2, $sex) = @_;
  332. my $msg = pack("v1", hex($masterServer->{gameLogin_packet}) || 0x65) . $accountID . $sessionID . $sessionID2 . pack("C*", 0, 0, $sex);
  333. if (hex($masterServer->{gameLogin_packet}) == 0x0273 || hex($masterServer->{gameLogin_packet}) == 0x0275) {
  334. my ($serv) = $masterServer->{ip} =~ /d+.d+.d+.(d+)/;
  335. $msg .= pack("x16 C1 x3", $serv);
  336. }
  337. $self->sendToServer($msg);
  338. debug "Sent sendGameLoginn", "sendPacket", 2;
  339. }
  340. sub sendGetCharacterName {
  341. my ($self, $ID) = @_;
  342. my $msg = pack("C*", 0x93, 0x01) . $ID;
  343. $self->sendToServer($msg);
  344. debug "Sent get character name: ID - ".getHex($ID)."n", "sendPacket", 2;
  345. }
  346. sub sendGetPlayerInfo {
  347. my ($self, $ID) = @_;
  348. my $msg;
  349. $msg = pack("C*", 0x94, 0x00) . $ID;
  350. $self->sendToServer($msg);
  351. debug "Sent get player info: ID - ".getHex($ID)."n", "sendPacket", 2;
  352. }
  353. sub sendGetStoreList {
  354. my ($self, $ID) = @_;
  355. my $msg = pack("C*", 0xC5, 0x00) . $ID . pack("C*",0x00);
  356. $self->sendToServer($msg);
  357. debug "Sent get store list: ".getHex($ID)."n", "sendPacket", 2;
  358. }
  359. sub sendGetSellList {
  360. my ($self, $ID) = @_;
  361. my $msg = pack("C*", 0xC5, 0x00) . $ID . pack("C*",0x01);
  362. $self->sendToServer($msg);
  363. debug "Sent sell to NPC: ".getHex($ID)."n", "sendPacket", 2;
  364. }
  365. sub sendGmSummon {
  366. my ($self, $playerName) = @_;
  367. my $packet = pack("C*", 0xBD, 0x01) . pack("a24", stringToBytes($playerName));
  368. $self->sendToServer($packet);
  369. }
  370. sub sendGuildAlly {
  371. my ($self, $ID, $flag) = @_;
  372. my $msg = pack("C*", 0x72, 0x01).$ID.pack("V1", $flag);
  373. $self->sendToServer($msg);
  374. debug "Sent Ally Guild : ".getHex($ID).", $flagn", "sendPacket", 2;
  375. }
  376. sub sendGuildBreak {
  377. my ($self, $guildName) = @_;
  378. my $msg = pack("C C a40", 0x5D, 0x01, stringToBytes($guildName));
  379. $self->sendToServer($msg);
  380. debug "Sent Guild Break: $guildNamen", "sendPacket", 2;
  381. }
  382. sub sendGuildChat {
  383. my ($self, $message) = @_;
  384. my ($charName);
  385. $message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");
  386. $message = stringToBytes($message);
  387. $charName = stringToBytes($char->{name});
  388. my $data = pack("C*",0x7E, 0x01) .
  389. pack("v*", length($charName) + length($message) + 8) .
  390. $charName . " : " . $message . chr(0);
  391. $self->sendToServer($data);
  392. }
  393. sub sendGuildCreate {
  394. my ($self, $name) = @_;
  395. my $msg = pack("C*", 0x65, 0x01, 0x4D, 0x8B, 0x01, 0x00) .
  396. pack("a24", stringToBytes($name));
  397. $self->sendToServer($msg);
  398. debug "Sent Guild Create: $namen", "sendPacket", 2;
  399. }
  400. sub sendGuildInfoRequest {
  401. my $self = shift;
  402. my $msg = pack("C*", 0x4d, 0x01);
  403. $self->sendToServer($msg);
  404. debug "Sent Guild Information Requestn", "sendPacket";
  405. }
  406. sub sendGuildJoin {
  407. my ($self, $ID, $flag) = @_;
  408. my $msg = pack("C*", 0x6B, 0x01).$ID.pack("V1", $flag);
  409. $self->sendToServer($msg);
  410. debug "Sent Join Guild : ".getHex($ID).", $flagn", "sendPacket";
  411. }
  412. sub sendGuildJoinRequest {
  413. my ($self, $ID) = @_;
  414. my $msg = pack("C*", 0x68, 0x01).$ID.$accountID.$charID;
  415. $self->sendToServer($msg);
  416. debug "Sent Request Join Guild: ".getHex($ID)."n", "sendPacket";
  417. }
  418. sub sendGuildLeave {
  419. my ($self, $reason) = @_;
  420. my $mess = pack("Z40", stringToBytes($reason));
  421. my $msg = pack("C*", 0x59, 0x01).$guild{ID}.$accountID.$charID.$mess;
  422. $self->sendToServer($msg);
  423. debug "Sent Guild Leave: $reason (".getHex($msg).")n", "sendPacket";
  424. }
  425. sub sendGuildMemberKick {
  426. my ($self, $guildID, $accountID, $charID, $cause) = @_;
  427. my $msg = pack("C*", 0x5B, 0x01).$guildID.$accountID.$charID.pack("a40", stringToBytes($cause));
  428. $self->sendToServer($msg);
  429. debug "Sent Guild Kick: ".getHex($charID)."n", "sendPacket";
  430. }
  431. sub sendGuildMemberTitleSelect {
  432. # set the title for a member
  433. my ($self, $accountID, $charID, $index) = @_;
  434. my $msg = pack("C*", 0x55, 0x01).pack("v1",16).$accountID.$charID.pack("V1",$index);
  435. $self->sendToServer($msg);
  436. debug "Sent Change Guild title: ".getHex($charID)." $indexn", "sendPacket", 2;
  437. }
  438. sub sendGuildNotice {
  439. # sets the notice/announcement for the guild
  440. my ($self, $guildID, $name, $notice) = @_;
  441. my $msg = pack("C*", 0x6E, 0x01) . $guildID .
  442. pack("a60 a120", stringToBytes($name), stringToBytes($notice));
  443. $self->sendToServer($msg);
  444. debug "Sent Change Guild Notice: $noticen", "sendPacket", 2;
  445. }
  446. sub sendGuildRankChange {
  447. # change the title for a certain index
  448. # i would  guess 0 is the top rank, but i dont know
  449. my ($self, $index, $permissions, $tax, $title) = @_;
  450. my $msg = pack("C*", 0x61, 0x01) .
  451. pack("v1", 44) . # packet length, we can actually send multiple titles in the same packet if we wanted to
  452. pack("V1", $index) . # index of this rank in the list
  453. pack("V1", $permissions) . # this is their abilities, not sure what format
  454. pack("V1", $index) . # isnt even used on emulators, but leave in case Aegis wants this
  455. pack("V1", $tax) . # guild tax amount, not sure what format
  456. pack("a24", $title);
  457. $self->sendToServer($msg);
  458. debug "Sent Set Guild title: $index $titlen", "sendPacket", 2;
  459. }
  460. sub sendGuildRequest {
  461. my ($self, $page) = @_;
  462. my $msg = pack("C*", 0x4f, 0x01).pack("V1", $page);
  463. $self->sendToServer($msg);
  464. debug "Sent Guild Request Page : ".$page."n", "sendPacket";
  465. }
  466. sub sendGuildSetAlly {
  467. # this packet is for guildmaster asking to set alliance with another guildmaster
  468. # the other sub for sendGuildAlly are responses to this sub
  469. # kept the parameters open, but everything except $targetAID could be replaced with Global variables
  470. # unless you plan to mess around with the alliance packet, no exploits though, I tried ;-)
  471. # -zdivpsa
  472. my ($self, $targetAID, $myAID, $charID) = @_; # remote socket, $net
  473. my $msg = pack("C*", 0x70, 0x01) .
  474. $targetAID .
  475. $myAID .
  476. $charID;
  477. $self->sendToServer($msg);
  478. }
  479. sub sendHomunculusFeed {
  480. my $self = shift;
  481. my $msg = pack("C*", 0x2D, 0x02, 0x00, 0x00, 0x01);
  482. $self->sendToServer($msg);
  483. debug "Sent Feed Homunculusn", "sendPacket", 2;
  484. }
  485. sub sendHomunculusGetStats {
  486. my $self = shift;
  487. my $msg = pack("C*", 0x2D, 0x02, 0x00, 0x00, 0x00);
  488. $self->sendToServer($msg);
  489. debug "Sent Get Homunculus Statsn", "sendPacket", 2;
  490. }
  491. sub sendHomunculusMove {
  492. my $self = shift;
  493. my $homunID = shift;
  494. my $x = int scalar shift;
  495. my $y = int scalar shift;
  496. my $msg = pack("C*", 0x32, 0x02) . $homunID . getCoordString($x, $y);
  497. $self->sendToServer($msg);
  498. debug "Sent Homunculus move to: $x, $yn", "sendPacket", 2;
  499. }
  500. sub sendHomunculusAttack {
  501. my $self = shift;
  502. my $homunID = shift;
  503. my $targetID = shift;
  504. my $flag = shift;
  505. my $msg = pack("C*", 0x33, 0x02) . $homunID . $targetID . pack("C1", $flag);
  506. $self->sendToServer($msg);
  507. debug "Sent Homunculus attack: ".getHex($targetID)."n", "sendPacket", 2;
  508. }
  509. sub sendHomunculusStandBy {
  510. my $self = shift;
  511. my $homunID = shift;
  512. my $msg = pack("C*", 0x34, 0x02) . $homunID;
  513. $self->sendToServer($msg);
  514. debug "Sent Homunculus standbyn", "sendPacket", 2;
  515. }
  516. sub sendHomunculusName {
  517. my $self = shift;
  518. my $name = shift;
  519. my $msg = pack("v1 a24", 0x0231, stringToBytes($name));
  520. $self->sendToServer($msg);
  521. debug "Sent Homunculus Rename: $namen", "sendPacket", 2;
  522. }
  523. sub sendIdentify {
  524. my $self = shift;
  525. my $index = shift;
  526. my $msg = pack("C*", 0x78, 0x01) . pack("v*", $index);
  527. $self->sendToServer($msg);
  528. debug "Sent Identify: $indexn", "sendPacket", 2;
  529. }
  530. sub sendIgnore {
  531. my $self = shift;
  532. my $name = shift;
  533. my $flag = shift;
  534. my $binName = stringToBytes($name);
  535. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  536. $binName = $binName . chr(0) x (24 - length($binName));
  537. my $msg = pack("C*", 0xCF, 0x00) . $binName . pack("C*", $flag);
  538. $self->sendToServer($msg);
  539. debug "Sent Ignore: $name, $flagn", "sendPacket", 2;
  540. }
  541. sub sendIgnoreAll {
  542. my $self = shift;
  543. my $flag = shift;
  544. my $msg = pack("C*", 0xD0, 0x00).pack("C*", $flag);
  545. $self->sendToServer($msg);
  546. debug "Sent Ignore All: $flagn", "sendPacket", 2;
  547. }
  548. sub sendIgnoreListGet {
  549. my $self = shift;
  550. my $flag = shift;
  551. my $msg = pack("C*", 0xD3, 0x00);
  552. $self->sendToServer($msg);
  553. debug "Sent get Ignore List: $flagn", "sendPacket", 2;
  554. }
  555. sub sendItemUse {
  556. my ($self, $ID, $targetID) = @_;
  557. my $msg;
  558. $msg = pack("C*", 0xA7, 0x00).pack("v*",$ID) .
  559. $targetID;
  560. $self->sendToServer($msg);
  561. debug "Item Use: $IDn", "sendPacket", 2;
  562. }
  563. sub sendLook {
  564. my ($self, $body, $head) = @_;
  565. my $msg;
  566. $msg = pack("C*", 0x9B, 0x00, $head, 0x00, $body);
  567. $self->sendToServer($msg);
  568. debug "Sent look: $body $headn", "sendPacket", 2;
  569. $char->{look}{head} = $head;
  570. $char->{look}{body} = $body;
  571. }
  572. sub sendMapLoaded {
  573. my $self = shift;
  574. my $msg;
  575. $syncSync = pack("V", getTickCount());
  576. $msg = pack("C*", 0x7D,0x00);
  577. debug "Sending Map Loadedn", "sendPacket";
  578. $self->sendToServer($msg);
  579. Plugins::callHook('packet/sendMapLoaded');
  580. }
  581. sub sendMapLogin {
  582. my ($self, $accountID, $charID, $sessionID, $sex) = @_;
  583. my $msg;
  584. $sex = 0 if ($sex > 1 || $sex < 0); # Sex can only be 0 (female) or 1 (male)
  585. if ($self->{serverType} == 0 || $self->{serverType} == 21 || $self->{serverType} == 22) {
  586. # Server Type 21 is tRO (2008-09-16Ragexe12_Th), 22 is idRO
  587. $msg = pack("C*", 0x72,0) .
  588. $accountID .
  589. $charID .
  590. $sessionID .
  591. pack("V1", getTickCount()) .
  592. pack("C*",$sex);
  593. } else { #oRO and pRO
  594. my $key;
  595. $key = pack("C*", 0xFA, 0x12, 0, 0x50, 0x83);
  596. $msg = pack("C*", 0x72, 0, 0, 0, 0) .
  597. $accountID .
  598. $key .
  599. $charID .
  600. pack("C*", 0xFF, 0xFF) .
  601. $sessionID .
  602. pack("V", getTickCount()) .
  603. pack("C", $sex);
  604. }
  605. $self->sendToServer($msg);
  606. }
  607. sub sendMasterCodeRequest {
  608. my $self = shift;
  609. my $type = shift;
  610. my $code = shift;
  611. my $msg;
  612. if ($type eq 'code') {
  613. $msg = '';
  614. foreach (split(/ /, $code)) {
  615. $msg .= pack("C1",hex($_));
  616. }
  617. } else { # type eq 'type'
  618. if ($code == 1) {
  619. $msg = pack("C*", 0x04, 0x02, 0x7B, 0x8A, 0xA8, 0x90, 0x2F, 0xD8, 0xE8, 0x30, 0xF8, 0xA5, 0x25, 0x7A, 0x0D, 0x3B, 0xCE, 0x52);
  620. } elsif ($code == 2) {
  621. $msg = pack("C*", 0x04, 0x02, 0x27, 0x6A, 0x2C, 0xCE, 0xAF, 0x88, 0x01, 0x87, 0xCB, 0xB1, 0xFC, 0xD5, 0x90, 0xC4, 0xED, 0xD2);
  622. } elsif ($code == 3) {
  623. $msg = pack("C*", 0x04, 0x02, 0x42, 0x00, 0xB0, 0xCA, 0x10, 0x49, 0x3D, 0x89, 0x49, 0x42, 0x82, 0x57, 0xB1, 0x68, 0x5B, 0x85);
  624. } elsif ($code == 4) {
  625. $msg = pack("C*", 0x04, 0x02, 0x22, 0x37, 0xD7, 0xFC, 0x8E, 0x9B, 0x05, 0x79, 0x60, 0xAE, 0x02, 0x33, 0x6D, 0x0D, 0x82, 0xC6);
  626. } elsif ($code == 5) {
  627. $msg = pack("C*", 0x04, 0x02, 0xc7, 0x0A, 0x94, 0xC2, 0x7A, 0xCC, 0x38, 0x9A, 0x47, 0xF5, 0x54, 0x39, 0x7C, 0xA4, 0xD0, 0x39);
  628. }
  629. }
  630. $msg .= pack("C*", 0xDB, 0x01);
  631. $self->sendToServer($msg);
  632. }
  633. sub sendMasterLogin {
  634. my ($self, $username, $password, $master_version, $version) = @_;
  635. my $msg;
  636. if ($self->{serverType} == 4) {
  637. # This is used on the RuRO private server.
  638. # A lot of packets are different so I gave up,
  639. # but I'll keep this code around in case anyone ever needs it.
  640. # I'm not sure if serverType 4 actually needs this whacko login
  641. $username = substr($username, 0, 23) if (length($username) > 23);
  642. $password = substr($password, 0, 23) if (length($password) > 23);
  643. my $tmp = pack("C*", 0x0D, 0xF0, 0xAD, 0xBA) x 6;
  644. substr($tmp, 0, length($username) + 1, $username . chr(0));
  645. $username = $tmp;
  646. $tmp = (pack("C*", 0x0D, 0xF0, 0xAD, 0xBA) x 3) .
  647. pack("C*", 0x00, 0xD0, 0xC2, 0xCF, 0xA2, 0xF9, 0xCA, 0xDF, 0x0E, 0xA6, 0xF1, 0x41);
  648. substr($tmp, 0, length($password) + 1, $password . chr(0));
  649. $password = $tmp;
  650. $msg = pack("v1 V", hex($masterServer->{masterLogin_packet}) || 0x64, $version) .
  651. $username . $password .
  652. pack("C*", $master_version);
  653. } else {
  654. $msg = pack("v1 V", hex($masterServer->{masterLogin_packet}) || 0x64, $version) .
  655. pack("a24", $username) .
  656. pack("a24", $password) .
  657. pack("C*", $master_version);
  658. }
  659. $self->sendToServer($msg);
  660. }
  661. sub sendMasterSecureLogin {
  662. my $self = shift;
  663. my $username = shift;
  664. my $password = shift;
  665. my $salt = shift;
  666. my $version = shift;
  667. my $master_version = shift;
  668. my $type =  shift;
  669. my $account = shift;
  670. my $md5 = Digest::MD5->new;
  671. my ($msg);
  672. $username = stringToBytes($username);
  673. $password = stringToBytes($password);
  674. if ($type % 2 == 1) {
  675. $salt = $salt . $password;
  676. } else {
  677. $salt = $password . $salt;
  678. }
  679. $md5->add($salt);
  680. if ($type < 3 ) {
  681. $msg = pack("C*", 0xDD, 0x01) . pack("V1", $version) . pack("a24", $username) .
  682.  $md5->digest . pack("C*", $master_version);
  683. }else{
  684. $account = ($account>0) ? $account -1 : 0;
  685. $msg = pack("C*", 0xFA, 0x01) . pack("V1", $version) . pack("a24", $username) .
  686.  $md5->digest . pack("C*", $master_version). pack("C1", $account);
  687. }
  688. $self->sendToServer($msg);
  689. }
  690. sub sendMemo {
  691. my $self = shift;
  692. my $msg = pack("C*", 0x1D, 0x01);
  693. $self->sendToServer($msg);
  694. debug "Sent Memon", "sendPacket", 2;
  695. }
  696. sub sendMercenaryCommand {
  697. my ($self, $command) = @_;
  698. # 0x0 => COMMAND_REQ_NONE
  699. # 0x1 => COMMAND_REQ_PROPERTY
  700. # 0x2 => COMMAND_REQ_DELETE
  701. my $msg = pack ('v1 C1', 0x029F, $command);
  702. $self->sendToServer ($msg);
  703. debug "Sent MercenaryCommand", "sendPacket", 2;
  704. }
  705. sub sendMove {
  706. my $self = shift;
  707. my $x = int scalar shift;
  708. my $y = int scalar shift;
  709. my $msg;
  710. $msg = pack("C*", 0x85, 0x00) . getCoordString($x, $y);
  711. $self->sendToServer($msg);
  712. debug "Sent move to: $x, $yn", "sendPacket", 2;
  713. }
  714. sub sendOpenShop {
  715. my ($self, $title, $items) = @_;
  716. my $length = 0x55 + 0x08 * @{$items};
  717. my $msg = pack("C*", 0xB2, 0x01).
  718. pack("v*", $length).
  719. pack("a80", stringToBytes($title)).
  720. pack("C*", 0x01);
  721. foreach my $item (@{$items}) {
  722. $msg .= pack("v1", $item->{index}).
  723. pack("v1", $item->{amount}).
  724. pack("V1", $item->{price});
  725. }
  726. $self->sendToServer($msg);
  727. }
  728. sub sendOpenWarp {
  729. my ($self, $map) = @_;
  730. my $msg = pack("C*", 0x1b, 0x01, 0x1b, 0x00) . $map .
  731. chr(0) x (16 - length($map));
  732. $self->sendToServer($msg);
  733. }
  734. sub sendPartyChat {
  735. my $self = shift;
  736. my $message = shift;
  737. my $charName;
  738. $message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");
  739. $message = stringToBytes($message);
  740. $charName = stringToBytes($char->{name});
  741. my $msg = pack("C*",0x08, 0x01) . pack("v*", length($charName) + length($message) + 8) .
  742. $charName . " : " . $message . chr(0);
  743. $self->sendToServer($msg);
  744. }
  745. sub sendPartyJoin {
  746. my $self = shift;
  747. my $ID = shift;
  748. my $flag = shift;
  749. my $msg = pack("C*", 0xFF, 0x00).$ID.pack("V", $flag);
  750. $self->sendToServer($msg);
  751. debug "Sent Join Party: ".getHex($ID).", $flagn", "sendPacket", 2;
  752. }
  753. sub sendPartyJoinRequest {
  754. my $self = shift;
  755. my $ID = shift;
  756. my $msg = pack("C*", 0xFC, 0x00).$ID;
  757. $self->sendToServer($msg);
  758. debug "Sent Request Join Party: ".getHex($ID)."n", "sendPacket", 2;
  759. }
  760. sub sendPartyKick {
  761. my $self = shift;
  762. my $ID = shift;
  763. my $name = shift;
  764. my $binName = stringToBytes($name);
  765. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  766. $binName .= chr(0) x (24 - length($binName));
  767. my $msg = pack("C*", 0x03, 0x01) . $ID . $binName;
  768. $self->sendToServer($msg);
  769. debug "Sent Kick Party: ".getHex($ID).", $namen", "sendPacket", 2;
  770. }
  771. sub sendPartyLeave {
  772. my $self = shift;
  773. my $msg = pack("C*", 0x00, 0x01);
  774. $self->sendToServer($msg);
  775. debug "Sent Leave Partyn", "sendPacket", 2;
  776. }
  777. sub sendPartyOrganize {
  778. my $self = shift;
  779. my $name = shift;
  780. my $share1 = shift || 1;
  781. my $share2 = shift || 1;
  782. my $binName = stringToBytes($name);
  783. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  784. $binName .= chr(0) x (24 - length($binName));
  785. #my $msg = pack("C*", 0xF9, 0x00) . $binName;
  786. # I think this is obsolete - which serverTypes still support this packet anyway?
  787. # FIXME: what are shared with $share1 and $share2? experience? item? vice-versa?
  788. my $msg = pack("C*", 0xE8, 0x01) . $binName . pack("C*", $share1, $share2);
  789. $self->sendToServer($msg);
  790. debug "Sent Organize Party: $namen", "sendPacket", 2;
  791. }
  792. sub sendPartyShareEXP {
  793. my $self = shift;
  794. my $flag = shift;
  795. my $msg = pack("C*", 0x02, 0x01).pack("V", $flag);
  796. $self->sendToServer($msg);
  797. debug "Sent Party Share: $flagn", "sendPacket", 2;
  798. }
  799. sub sendPetCapture {
  800. my $self = shift;
  801. my $monID = shift;
  802. my $msg = pack("C*", 0x9F, 0x01) . $monID . pack("C*", 0x00, 0x00);
  803. $self->sendToServer($msg);
  804. debug "Sent pet capture: ".getHex($monID)."n", "sendPacket", 2;
  805. }
  806. sub sendPetFeed {
  807. my $self = shift;
  808. my $msg = pack("C*", 0xA1, 0x01, 0x01);
  809. $self->sendToServer($msg);
  810. debug "Sent Pet Feedn", "sendPacket", 2;
  811. }
  812. sub sendPetGetInfo {
  813. my $self = shift;
  814. my $msg = pack("C*", 0xA1, 0x01, 0x00);
  815. $self->sendToServer($msg);
  816. debug "Sent Pet Get Infon", "sendPacket", 2;
  817. }
  818. sub sendPetHatch {
  819. my $self = shift;
  820. my $index = shift;
  821. my $msg = pack("C*", 0xA7, 0x01) . pack("v1", $index);
  822. $self->sendToServer($msg);
  823. debug "Sent Incubator hatch: $indexn", "sendPacket", 2;
  824. }
  825. sub sendPetName {
  826. my $self = shift;
  827. my $name = shift;
  828. my $msg = pack("C1 C1 a24", 0xA5, 0x01, stringToBytes($name));
  829. $self->sendToServer($msg);
  830. debug "Sent Pet Rename: $namen", "sendPacket", 2;
  831. }
  832. sub sendPetPerformance {
  833. my $self = shift;
  834. my $msg = pack("C*", 0xA1, 0x01, 0x02);
  835. $self->sendToServer($msg);
  836. debug "Sent Pet Performancen", "sendPacket", 2;
  837. }
  838. sub sendPetReturnToEgg {
  839. my $self = shift;
  840. my $msg = pack("C*", 0xA1, 0x01, 0x03);
  841. $self->sendToServer($msg);
  842. debug "Sent Pet Return to Eggn", "sendPacket", 2;
  843. }
  844. sub sendPetUnequipItem {
  845. my $self = shift;
  846. my $msg = pack("C*", 0xA1, 0x01, 0x04);
  847. $self->sendToServer($msg);
  848. debug "Sent Pet Unequip Itemn", "sendPacket", 2;
  849. }
  850. sub sendPreLoginCode {
  851. # no server actually needs this, but we might need it in the future?
  852. my $self = shift;
  853. my $type = shift;
  854. my $msg;
  855. if ($type == 1) {
  856. $msg = pack("C*", 0x04, 0x02, 0x82, 0xD1, 0x2C, 0x91, 0x4F, 0x5A, 0xD4, 0x8F, 0xD9, 0x6F, 0xCF, 0x7E, 0xF4, 0xCC, 0x49, 0x2D);
  857. }
  858. $self->sendToServer($msg);
  859. debug "Sent pre-login packet $typen", "sendPacket", 2;
  860. }
  861. sub sendPrivateMsg {
  862. my ($self, $user, $message) = @_;
  863. $message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");
  864. $message = stringToBytes($message);
  865. $user = stringToBytes($user);
  866. my $msg = pack("C*", 0x96, 0x00) . pack("v*", length($message) + 29) . $user .
  867. chr(0) x (24 - length($user)) . $message . chr(0);
  868. $self->sendToServer($msg);
  869. }
  870. sub sendQuit {
  871. my $self = shift;
  872. my $msg = pack("C*", 0x8A, 0x01, 0x00, 0x00);
  873. $self->sendToServer($msg);
  874. debug "Sent Quitn", "sendPacket", 2;
  875. }
  876. sub sendQuitToCharSelect {
  877. my $msg = pack("C*", 0xB2, 0x00, 0x01);
  878. $_[0]->sendToServer($msg);
  879. debug "Sent Quit To Char Selectionn", "sendPacket", 2;
  880. }
  881. sub sendRaw {
  882. my $self = shift;
  883. my $raw = shift;
  884. my @raw;
  885. my $msg;
  886. @raw = split / /, $raw;
  887. foreach (@raw) {
  888. $msg .= pack("C", hex($_));
  889. }
  890. $self->sendToServer($msg);
  891. debug "Sent Raw Packet: @rawn", "sendPacket", 2;
  892. }
  893. sub sendRequestMakingHomunculus {
  894. # WARNING: If you don't really know, what are you doing - don't touch this
  895. my ($self, $make_homun) = @_;
  896. my $skill = new Skill (idn => 241);
  897. if (
  898. Actor::Item::get (997) && Actor::Item::get (998) && Actor::Item::get (999)
  899. && ($char->getSkillLevel ($skill) > 0)
  900. ) {
  901. my $msg = pack ('v1 C1', 0x01CA, $make_homun);
  902. $self->sendToServer($msg);
  903. debug "Sent RequestMakingHomunculusn", "sendPacket", 2;
  904. }
  905. }
  906. sub sendRemoveAttachments {
  907. # remove peco, falcon, cart
  908. my $msg = pack("C*", 0x2A, 0x01);
  909. $_[0]->sendToServer($msg);
  910. debug "Sent remove attachmentsn", "sendPacket", 2;
  911. }
  912. sub sendRepairItem {
  913. my ($self, $args) = @_;
  914. my $msg = pack("C2 v2 V2 C1", 0xFD, 0x01, %{$args}->{index}, %{$args}->{nameID}, %{$args}->{status}, %{$args}->{status2}, %{$args}->{listID});
  915. $self->sendToServer($msg);
  916. debug ("Sent repair item: ".%{$args}->{index}."n", "sendPacket", 2);
  917. }
  918. sub sendRespawn {
  919. my $self = shift;
  920. my $msg = pack("C*", 0xB2, 0x00, 0x00);
  921. $self->sendToServer($msg);
  922. debug "Sent Respawnn", "sendPacket", 2;
  923. }
  924. sub sendSell {
  925. my $self = shift;
  926. my $index = shift;
  927. my $amount = shift;
  928. my $msg = pack("C*", 0xC9, 0x00, 0x08, 0x00) . pack("v*", $index, $amount);
  929. $self->sendToServer($msg);
  930. debug "Sent sell: $index x $amountn", "sendPacket", 2;
  931. }
  932. sub sendSellBulk {
  933. my $self = shift;
  934. my $r_array = shift;
  935. my $sellMsg = "";
  936. for (my $i = 0; $i < @{$r_array}; $i++) {
  937. $sellMsg .= pack("v*", $r_array->[$i]{index}, $r_array->[$i]{amount});
  938. debug "Sent bulk sell: $r_array->[$i]{index} x $r_array->[$i]{amount}n", "d_sendPacket", 2;
  939. }
  940. my $msg = pack("C*", 0xC9, 0x00) . pack("v*", length($sellMsg) + 4) . $sellMsg;
  941. $self->sendToServer($msg);
  942. }
  943. sub sendSit {
  944. my $self = shift;
  945. my $msg;
  946. $msg = pack("C*", 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02);
  947. $self->sendToServer($msg);
  948. debug "Sittingn", "sendPacket", 2;
  949. }
  950. sub sendSkillUse {
  951. my ($self, $ID, $lv, $targetID) = @_;
  952. my $msg;
  953. $msg = pack("C*", 0x13, 0x01).pack("v*",$lv,$ID).$targetID;
  954. $self->sendToServer($msg);
  955. debug "Skill Use: $IDn", "sendPacket", 2;
  956. }
  957. sub sendSkillUseLoc {
  958. my ($self, $ID, $lv, $x, $y) = @_;
  959. my $msg;
  960. $msg = pack("C*", 0x16, 0x01).pack("v*",$lv,$ID,$x,$y);
  961. $self->sendToServer($msg);
  962. debug "Skill Use on Location: $ID, ($x, $y)n", "sendPacket", 2;
  963. }
  964. sub sendStorageAdd {
  965. my ($self, $index, $amount) = @_;
  966. my $msg;
  967. $msg = pack("C*", 0xF3, 0x00) . pack("v*", $index) . pack("V*", $amount);
  968. $self->sendToServer($msg);
  969. debug "Sent Storage Add: $index x $amountn", "sendPacket", 2;
  970. }
  971. sub sendStorageAddFromCart {
  972. my $self = shift;
  973. my $index = shift;
  974. my $amount = shift;
  975. my $msg;
  976. $msg = pack("C*", 0x29, 0x01) . pack("v*", $index) . pack("V*", $amount);
  977. $self->sendToServer($msg);
  978. debug "Sent Storage Add From Cart: $index x $amountn", "sendPacket", 2;
  979. }
  980. sub sendStorageClose {
  981. my ($self) = @_;
  982. my $msg;
  983. if (($self->{serverType} == 3) || ($self->{serverType} == 5) || ($self->{serverType} == 9) || ($self->{serverType} == 15)) {
  984. $msg = pack("C*", 0x93, 0x01);
  985. } elsif ($self->{serverType} == 12) {
  986. $msg = pack("C*", 0x72, 0x00);
  987. } elsif ($self->{serverType} == 14) {
  988. $msg = pack("C*", 0x16, 0x01);
  989. } else {
  990. $msg = pack("C*", 0xF7, 0x00);
  991. }
  992. $self->sendToServer($msg);
  993. debug "Sent Storage Donen", "sendPacket", 2;
  994. }
  995. sub sendStorageGet {
  996. my ($self, $index, $amount) = @_;
  997. my $msg;
  998. $msg = pack("C*", 0xF5, 0x00) . pack("v*", $index) . pack("V*", $amount);
  999. $self->sendToServer($msg);
  1000. debug "Sent Storage Get: $index x $amountn", "sendPacket", 2;
  1001. }
  1002. sub sendStorageGetToCart {
  1003. my $self = shift;
  1004. my $index = shift;
  1005. my $amount = shift;
  1006. my $msg;
  1007. $msg = pack("C*", 0x28, 0x01) . pack("v*", $index) . pack("V*", $amount);
  1008. $self->sendToServer($msg);
  1009. debug "Sent Storage Get From Cart: $index x $amountn", "sendPacket", 2;
  1010. }
  1011. sub sendStoragePassword {
  1012. my $self = shift;
  1013. # 16 byte packed hex data
  1014. my $pass = shift;
  1015. # 2 = set password ?
  1016. # 3 = give password ?
  1017. my $type = shift;
  1018. my $msg;
  1019. if ($type == 3) {
  1020. $msg = pack("C C v", 0x3B, 0x02, $type).$pass.pack("H*", "EC62E539BB6BBC811A60C06FACCB7EC8");
  1021. } elsif ($type == 2) {
  1022. $msg = pack("C C v", 0x3B, 0x02, $type).pack("H*", "EC62E539BB6BBC811A60C06FACCB7EC8").$pass;
  1023. } else {
  1024. ArgumentException->throw("The 'type' argument has invalid value ($type).");
  1025. }
  1026. $self->sendToServer($msg);
  1027. }
  1028. sub sendLoginPinCode {
  1029. my $self = shift;
  1030. # String's with PIN codes
  1031. my $pin1 = shift;
  1032. my $pin2 = shift;
  1033.         # Actually the Key
  1034. my $key_v = shift;
  1035. # 2 = set password
  1036. # 3 = enter password
  1037. my $type = shift;
  1038. my $encryptionKey = shift;
  1039. my $msg;
  1040. if ($pin1 !~ /^d*$/) {
  1041. ArgumentException->throw("PIN code 1 must contain only digits.");
  1042. }
  1043. if ($type == 2 && $pin2 !~ /^d*$/) {
  1044. ArgumentException->throw("PIN code 2 must contain only digits.");
  1045. }
  1046. if (!$encryptionKey) {
  1047. ArgumentException->throw("No encryption key given.");
  1048. }
  1049. my $crypton = new Utils::Crypton(pack("V*", @{$encryptionKey}), 32);
  1050. my $num1 = pin_encode($pin1, $key_v);
  1051. my $num2 = pin_encode($pin2, $key_v);
  1052. if ($type == 2) {
  1053. if ((length($pin1) > 3) && (length($pin1) < 9) && (length($pin2) > 3) && (length($pin2) < 9)) {
  1054. my $ciphertextblock1 = $crypton->encrypt(pack("V*", $num1, 0, 0, 0)); 
  1055. my $ciphertextblock2 = $crypton->encrypt(pack("V*", $num2, 0, 0, 0));
  1056. $msg = pack("C C v", 0x3B, 0x02, $type).$ciphertextblock1.$ciphertextblock2;
  1057. $self->sendToServer($msg);
  1058. } else {
  1059. ArgumentException->throw("Both PIN codes must be more than 3 and less than 9 characters long.");
  1060. }
  1061. } elsif ($type == 3) {
  1062. if ((length($pin1) > 3) && (length($pin1) < 9)) {
  1063. my $ciphertextblock1 = $crypton->encrypt(pack("V*", $num1, 0, 0, 0)); 
  1064. my $ciphertextblock2 = $crypton->encrypt(pack("V*", 0, 0, 0, 0)); 
  1065. $msg = pack("C C v", 0x3B, 0x02, $type).$ciphertextblock1.$ciphertextblock2;
  1066. $self->sendToServer($msg);
  1067. } else {
  1068. ArgumentException->throw("PIN code 1 must be more than 3 and less than 9 characters long.");
  1069. }
  1070. } else {
  1071. ArgumentException->throw("The 'type' argument has invalid value ($type).");
  1072. }
  1073. }
  1074. sub sendStand {
  1075. my $self = shift;
  1076. my $msg;
  1077. $msg = pack("C*", 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03);
  1078. $self->sendToServer($msg);
  1079. debug "Standingn", "sendPacket", 2;
  1080. }
  1081. sub sendSuperNoviceDoriDori {
  1082. my $msg = pack("C*", 0xE7, 0x01);
  1083. $_[0]->sendToServer($msg);
  1084. debug "Sent Super Novice dori dorin", "sendPacket", 2;
  1085. }
  1086. sub sendSuperNoviceExplosion {
  1087. my $msg = pack("C*", 0xED, 0x01);
  1088. $_[0]->sendToServer($msg);
  1089. debug "Sent Super Novice Explosionn", "sendPacket", 2;
  1090. }
  1091. sub sendSync {
  1092. my ($self, $initialSync) = @_;
  1093. my $msg;
  1094. # XKore mode 1 lets the client take care of syncing.
  1095. return if ($self->{net}->version == 1);
  1096. $syncSync = pack("V", getTickCount());
  1097. $msg = pack("C*", 0x7E, 0x00) . $syncSync;
  1098. $self->sendToServer($msg);
  1099. debug "Sent Syncn", "sendPacket", 2;
  1100. }
  1101. sub sendTake {
  1102. my ($self, $itemID) = @_;
  1103. my $msg;
  1104. $msg = pack("C*", 0x9F, 0x00) . $itemID;
  1105. $self->sendToServer($msg);
  1106. debug "Sent taken", "sendPacket", 2;
  1107. }
  1108. sub sendTalk {
  1109. my $self = shift;
  1110. my $ID = shift;
  1111. my $msg = pack("C*", 0x90, 0x00) . $ID . pack("C*",0x01);
  1112. $self->sendToServer($msg);
  1113. debug "Sent talk: ".getHex($ID)."n", "sendPacket", 2;
  1114. }
  1115. sub sendTalkCancel {
  1116. my $self = shift;
  1117. my $ID = shift;
  1118. my $msg = pack("C*", 0x46, 0x01) . $ID;
  1119. $self->sendToServer($msg);
  1120. debug "Sent talk cancel: ".getHex($ID)."n", "sendPacket", 2;
  1121. }
  1122. sub sendTalkContinue {
  1123. my $self = shift;
  1124. my $ID = shift;
  1125. my $msg = pack("C*", 0xB9, 0x00) . $ID;
  1126. $self->sendToServer($msg);
  1127. debug "Sent talk continue: ".getHex($ID)."n", "sendPacket", 2;
  1128. }
  1129. sub sendTalkResponse {
  1130. my $self = shift;
  1131. my $ID = shift;
  1132. my $response = shift;
  1133. my $msg = pack("C*", 0xB8, 0x00) . $ID. pack("C1",$response);
  1134. $self->sendToServer($msg);
  1135. debug "Sent talk respond: ".getHex($ID).", $responsen", "sendPacket", 2;
  1136. }
  1137. sub sendTalkNumber {
  1138. my $self = shift;
  1139. my $ID = shift;
  1140. my $number = shift;
  1141. my $msg = pack("C*", 0x43, 0x01) . $ID .
  1142. pack("V1", $number);
  1143. $self->sendToServer($msg);
  1144. debug "Sent talk number: ".getHex($ID).", $numbern", "sendPacket", 2;
  1145. }
  1146. sub sendTalkText {
  1147. my $self = shift;
  1148. my $ID = shift;
  1149. my $input = stringToBytes(shift);
  1150. my $msg = pack("C*", 0xD5, 0x01) . pack("v*", length($input)+length($ID)+5) . $ID . $input . chr(0);
  1151. $self->sendToServer($msg);
  1152. debug "Sent talk text: ".getHex($ID).", $inputn", "sendPacket", 2;
  1153. }
  1154. sub sendTeleport {
  1155. my $self = shift;
  1156. my $location = shift;
  1157. $location = substr($location, 0, 16) if (length($location) > 16);
  1158. $location .= chr(0) x (16 - length($location));
  1159. my $msg = pack("C*", 0x1B, 0x01, 0x1A, 0x00) . $location;
  1160. $self->sendToServer($msg);
  1161. debug "Sent Teleport: $locationn", "sendPacket", 2;
  1162. }
  1163. sub sendTop10Alchemist {
  1164. my $self = shift;
  1165. my $msg = pack("C*", 0x18, 0x02);
  1166. $self->sendToServer($msg);
  1167. debug "Sent Top 10 Alchemist requestn", "sendPacket", 2;
  1168. }
  1169. sub sendTop10Blacksmith {
  1170. my $self = shift;
  1171. my $msg = pack("C*", 0x17, 0x02);
  1172. $self->sendToServer($msg);
  1173. debug "Sent Top 10 Blacksmith requestn", "sendPacket", 2;
  1174. }
  1175. sub sendTop10PK {
  1176. my $self = shift;
  1177. my $msg = pack("C*", 0x37, 0x02);
  1178. $self->sendToServer($msg);
  1179. debug "Sent Top 10 PK requestn", "sendPacket", 2;
  1180. }
  1181. sub sendTop10Taekwon {
  1182. my $self = shift;
  1183. my $msg = pack("C*", 0x25, 0x02);
  1184. $self->sendToServer($msg);
  1185. debug "Sent Top 10 Taekwon requestn", "sendPacket", 2;
  1186. }
  1187. sub sendUnequip {
  1188. my $self = shift;
  1189. my $index = shift;
  1190. my $msg = pack("C*", 0xAB, 0x00) . pack("v*", $index);
  1191. $self->sendToServer($msg);
  1192. debug "Sent Unequip: $indexn", "sendPacket", 2;
  1193. }
  1194. sub sendWho {
  1195. my $self = shift;
  1196. my $msg = pack("C*", 0xC1, 0x00);
  1197. $self->sendToServer($msg);
  1198. debug "Sent Whon", "sendPacket", 2;
  1199. }
  1200. sub sendMessageIDEncryptionInitialized {
  1201. my $self = shift;
  1202. my $msg = pack("C*", 0xAF, 0x02);
  1203. $self->sendToServer($msg);
  1204. debug "Sent Message ID Encryption Initializedn", "sendPacket", 2;
  1205. }
  1206. sub sendMailboxOpen {
  1207. my $self = $_[0];
  1208. my $msg = pack("C*", 0x3F, 0x02);
  1209. $self->sendToServer($msg);
  1210. debug "Sent mailbox open.n", "sendPacket", 2;
  1211. }
  1212. sub sendMailRead {
  1213. my ($self, $mailID) = @_;
  1214. my $msg = pack("C2 V1", 0x41, 0x02, $mailID);
  1215. $self->sendToServer($msg);
  1216. debug "Sent read mail.n", "sendPacket", 2;
  1217. }
  1218. sub sendMailDelete {
  1219. my ($self, $mailID) = @_;
  1220. my $msg = pack("C2 V1", 0x43, 0x02, $mailID);
  1221. $self->sendToServer($msg);
  1222. debug "Sent delete mail.n", "sendPacket", 2;
  1223. }
  1224. sub sendMailReturn {
  1225. my ($self, $mailID, $sender) = @_;
  1226. my $msg = pack("C2 V1 Z24", 0x73, 0x02, $mailID, stringToBytes($sender));
  1227. $self->sendToServer($msg);
  1228. debug "Sent return mail.n", "sendPacket", 2;
  1229. }
  1230. sub sendMailOperateWindow {
  1231. my ($self, $window) = @_;
  1232. my $msg = pack("C2 C1 x1", 0x46, 0x02, $window);
  1233. $self->sendToServer($msg);
  1234. debug "Sent mail window.n", "sendPacket", 2;
  1235. }
  1236. sub sendMailGetAttach {
  1237. my ($self, $mailID) = @_;
  1238. my $msg = pack("C2 V1", 0x44, 0x02, $mailID);
  1239. $self->sendToServer($msg);
  1240. debug "Sent mail get attachment.n", "sendPacket", 2;
  1241. }
  1242. sub sendMailSetAttach {
  1243. my $self = $_[0];
  1244. my $amount = $_[1];
  1245. my $index = (defined $_[2]) ? $_[2] : 0; # 0 for zeny
  1246. my $msg = pack("C2 v1 V1", 0x47, 0x02, $index, $amount);
  1247. $self->sendToServer($msg);
  1248. debug "Sent mail set attachment.n", "sendPacket", 2;
  1249. }
  1250. sub sendMailSend {
  1251. my ($self, $length, $receiver, $title, $msglength, $mailmsg) = @_;
  1252. my $msg = pack("C2 v1 Z24 a40 C1 Z*", 0x48, 0x02, $length, stringToBytes($receiver), stringToBytes($title), $msglength, stringToBytes($mailmsg));
  1253. $self->sendToServer($msg);
  1254. debug "Sent mail send.n", "sendPacket", 2;
  1255. }
  1256. sub sendAuctionAddItemCancel {
  1257. my ($self) = @_;
  1258. my $msg = pack("C2 v1", 0x4B, 0x02, 1);
  1259. $self->sendToServer($msg);
  1260. debug "Sent Auction Add Item Cancel.n", "sendPacket", 2;
  1261. }
  1262. sub sendAuctionAddItem {
  1263. my ($self, $index, $amount) = @_;
  1264. my $msg = pack("C2 v1 V1", 0x4C, 0x02, $index, $amount);
  1265. $self->sendToServer($msg);
  1266. debug "Sent Auction Add Item.n", "sendPacket", 2;
  1267. }
  1268. sub sendAuctionCreate {
  1269. my ($self, $price, $buynow, $hours) = @_;
  1270. my $msg = pack("C2 V1 V1 v1", 0x4D, 0x02, $price, $buynow, $hours);
  1271. $self->sendToServer($msg);
  1272. debug "Sent Auction Create.n", "sendPacket", 2;
  1273. }
  1274. sub sendAuctionCancel {
  1275. my ($self, $id) = @_;
  1276. my $msg = pack("C2 V1", 0x4E, 0x02, $id);
  1277. $self->sendToServer($msg);
  1278. debug "Sent Auction Cancel.n", "sendPacket", 2;
  1279. }
  1280. sub sendAuctionBuy {
  1281. my ($self, $id, $bid) = @_;
  1282. my $msg = pack("C2 V1 V1", 0x4F, 0x02, $id, $bid);
  1283. $self->sendToServer($msg);
  1284. debug "Sent Auction Buy.n", "sendPacket", 2;
  1285. }
  1286. sub sendAuctionItemSearch {
  1287. my ($self, $type, $price, $text, $page) = @_;
  1288. $page = (defined $page) ? $page : 1;
  1289. my $msg = pack("C2 v1 V1 Z24 v1", 0x51, 0x02, $type, $price, stringToBytes($text), $page);
  1290. $self->sendToServer($msg);
  1291. debug "Sent Auction Item Search.n", "sendPacket", 2;
  1292. }
  1293. sub sendAuctionReqMyInfo {
  1294. my ($self, $type) = @_;
  1295. my $msg = pack("C2 v1", 0x5C, 0x02, $type);
  1296. $self->sendToServer($msg);
  1297. debug "Sent Auction Request My Info.n", "sendPacket", 2;
  1298. }
  1299. sub sendAuctionMySellStop {
  1300. my ($self, $id) = @_;
  1301. my $msg = pack("C2 V1", 0x5D, 0x02, $id);
  1302. $self->sendToServer($msg);
  1303. debug "Sent My Sell Stop.n", "sendPacket", 2;
  1304. }
  1305. 1;