Advertisement
Guest User

Untitled

a guest
Jun 28th, 2013
451
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 41.86 KB | None | 0 0
  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://wiki.openkore.com/index.php/ServerType
  16. package Network::Send::ServerType0;
  17.  
  18. use strict;
  19. use Time::HiRes qw(time);
  20.  
  21. use Misc qw(stripLanguageCode);
  22. use Network::Send ();
  23. use base qw(Network::Send);
  24. use Plugins;
  25. use Globals qw($accountID $sessionID $sessionID2 $accountSex $char $charID %config %guild @chars $masterServer $syncSync);
  26. use Log qw(debug);
  27. use Translation qw(T TF);
  28. use I18N qw(bytesToString stringToBytes);
  29. use Utils;
  30. use Utils::Exceptions;
  31. use Utils::Rijndael;
  32.  
  33. # to test zealotus bug
  34. #use Data::Dumper;
  35.  
  36.  
  37. sub new {
  38. my ($class) = @_;
  39. my $self = $class->SUPER::new(@_);
  40.  
  41. my %packets = (
  42. '0064' => ['master_login', 'V Z24 Z24 C', [qw(version username password master_version)]],
  43. '0065' => ['game_login', 'a4 a4 a4 v C', [qw(accountID sessionID sessionID2 userLevel accountSex)]],
  44. '0066' => ['char_login', 'C', [qw(slot)]],
  45. '0067' => ['char_create'], # TODO
  46. '0068' => ['char_delete'], # TODO
  47. '0072' => ['map_login', 'a4 a4 a4 V C', [qw(accountID charID sessionID tick sex)]],
  48. '007D' => ['map_loaded'], # len 2
  49. # '007E' => ['sync', 'V', [qw(time)]],
  50. # '0085' => ['character_move', 'a3', [qw(coords)]],
  51. '0089' => ['actor_action', 'a4 C', [qw(targetID type)]],
  52. '008C' => ['public_chat', 'x2 Z*', [qw(message)]],
  53. # '0094' => ['actor_info_request', 'a4', [qw(ID)]],
  54. '0096' => ['private_message', 'x2 Z24 Z*', [qw(privMsgUser privMsg)]],
  55. # '009B' => ['actor_look_at', 'v C', [qw(head body)]],
  56. # '009F' => ['item_take', 'a4', [qw(ID)]],
  57. # '00A2' => ['item_drop', 'v2', [qw(index amount)]],
  58. '00B2' => ['restart', 'C', [qw(type)]],
  59. #'00F3' => ['map_login', '', [qw()]],
  60. # '00F3' => ['storage_item_add', 'v V', [qw(index amount)]],
  61. # '00F5' => ['storage_item_remove', 'v V', [qw(index amount)]],
  62. # '0102' => ['party_setting', 'V', [qw(exp)]],
  63. '0108' => ['party_chat', 'x2 Z*', [qw(message)]],
  64. '0113' => ['skill_use', 'v2 a4', [qw(lv skillID targetID)]],
  65. # '0116' => ['skill_use_location', 'v4', [qw(lv skillID x y)]],
  66. '0134' => ['buy_bulk_vender', 'x2 a4 a*', [qw(venderID itemInfo)]],
  67. '0149' => ['alignment', 'a4 C v', [qw(targetID type point)]],
  68. '014D' => ['guild_check'], # len 2
  69. '014F' => ['guild_info_request', 'V', [qw(type)]],
  70. '0151' => ['guild_emblem_request', 'a4', [qw(guildID)]],
  71. '017E' => ['guild_chat', 'x2 Z*', [qw(message)]],
  72. '0187' => ['ban_check', 'a4', [qw(accountID)]],
  73. '018A' => ['quit_request', 'v', [qw(type)]],
  74. '0193' => ['actor_name_request', 'a4', [qw(ID)]],
  75. '01B2' => ['shop_open'], # TODO
  76. '012E' => ['shop_close'], # len 2
  77. '01DB' => ['secure_login_key_request'], # len 2
  78. '01DD' => ['master_login', 'V Z24 a16 C', [qw(version username password_salted_md5 master_version)]],
  79. '01FA' => ['master_login', 'V Z24 a16 C C', [qw(version username password_salted_md5 master_version clientInfo)]],
  80. '0204' => ['client_hash', 'a16', [qw(hash)]],
  81. '0208' => ['friend_response', 'a4 a4 V', [qw(friendAccountID friendCharID type)]],
  82. '021D' => ['less_effect'], # TODO
  83. '0232' => ['actor_move', 'a4 a3', [qw(ID coords)]],
  84. '0275' => ['game_login', 'a4 a4 a4 v C x16 v', [qw(accountID sessionID sessionID2 userLevel accountSex iAccountSID)]],
  85. '02B0' => ['master_login', 'V Z24 a24 C Z16 Z14 C', [qw(version username password_rijndael master_version ip mac isGravityID)]],
  86. '035F' => ['character_move', 'a3', [qw(coords)]],
  87. '0360' => ['sync', 'V', [qw(time)]],
  88. '0361' => ['actor_look_at', 'v C', [qw(head body)]],
  89. '0362' => ['item_take', 'a4', [qw(ID)]],
  90. '0363' => ['item_drop', 'v2', [qw(index amount)]],
  91. '0364' => ['storage_item_add', 'v V', [qw(index amount)]],
  92. '0365' => ['storage_item_remove', 'v V', [qw(index amount)]],
  93. '0366' => ['skill_use_location', 'v4', [qw(lv skillID x y)]],
  94. '0368' => ['actor_info_request', 'a4', [qw(ID)]],
  95. '0369' => ['actor_name_request', 'a4', [qw(ID)]],
  96. '0436' => ['map_login', 'a4 a4 a4 V C', [qw(accountID charID sessionID tick sex)]],
  97. '0437' => ['character_move','a3', [qw(coords)]],
  98. '0443' => ['skill_select', 'V v', [qw(why skillID)]],
  99. '07D7' => ['party_setting', 'V C2', [qw(exp itemPickup itemDivision)]],
  100. '0801' => ['buy_bulk_vender', 'x2 a4 a4 a*', [qw(venderID venderCID itemInfo)]], #Selling store
  101. '0802' => ['booking_register', 'v8', [qw(level MapID job0 job1 job2 job3 job4 job5)]],
  102. '0804' => ['booking_search', 'v3 V s', [qw(level MapID job LastIndex ResultCount)]],
  103. '0806' => ['booking_delete'],
  104. '0808' => ['booking_update', 'v6', [qw(job0 job1 job2 job3 job4 job5)]],
  105. '0811' => ['buy_bulk_openShop', 'a4 c a*', [qw(limitZeny result itemInfo)]], #Selling store
  106. '0815' => ['buy_bulk_closeShop'],
  107. '0819' => ['buy_bulk_buyer', 'a4 a4 a*', [qw(buyerID buyingStoreID itemInfo)]], #Buying store
  108. '0827' => ['char_delete2', 'a4', [qw(charID)]], # 6
  109. '082B' => ['char_delete2_cancel', 'a4', [qw(charID)]], # 6
  110. '08B8' => ['send_pin_password','a4 Z*', [qw(accountID pin)]],
  111. '08BA' => ['new_pin_password','a4 Z*', [qw(accountID pin)]],
  112. '0987' => ['master_login', 'V Z24 a32 C', [qw(version username password_md5_hex master_version)]],
  113. '09A1' => ['sync_received_characters'],
  114. #'08BE' => ['change_pin_password','a*', [qw(accountID oldPin newPin)]], # TODO: PIN change system/command?
  115. );
  116. $self->{packet_list}{$_} = $packets{$_} for keys %packets;
  117.  
  118. # # it would automatically use the first available if not set
  119. # my %handlers = qw(
  120. # master_login 0064
  121. # game_login 0065
  122. # map_login 0072
  123. # character_move 0085
  124. # buy_bulk_vender 0134
  125. # );
  126. # $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers;
  127.  
  128. return $self;
  129. }
  130.  
  131. sub version {
  132. return $masterServer->{version} || 1;
  133. }
  134.  
  135. sub sendAddSkillPoint {
  136. my ($self, $skillID) = @_;
  137. my $msg = pack("C*", 0x12, 0x01) . pack("v*", $skillID);
  138. $self->sendToServer($msg);
  139. }
  140.  
  141. sub sendAddStatusPoint {
  142. my ($self, $statusID) = @_;
  143. my $msg = pack("C*", 0xBB, 0) . pack("v*", $statusID) . pack("C*", 0x01);
  144. $self->sendToServer($msg);
  145. }
  146.  
  147. sub sendAlignment {
  148. my ($self, $ID, $alignment) = @_;
  149. $self->sendToServer($self->reconstruct({
  150. switch => 'alignment',
  151. targetID => $ID,
  152. type => $alignment,
  153. }));
  154. debug "Sent Alignment: ".getHex($ID).", $alignment\n", "sendPacket", 2;
  155. }
  156.  
  157. sub sendArrowCraft {
  158. my ($self, $index) = @_;
  159. my $msg = pack("C*", 0xAE, 0x01) . pack("v*", $index);
  160. $self->sendToServer($msg);
  161. debug "Sent Arrowmake: $index\n", "sendPacket", 2;
  162. }
  163.  
  164. # 0x0089,7,actionrequest,2:6
  165.  
  166. sub sendAttackStop {
  167. my $self = shift;
  168. #my $msg = pack("C*", 0x18, 0x01);
  169. # Apparently this packet is wrong. The server disconnects us if we do this.
  170. # Sending a move command to the current position seems to be able to emulate
  171. # what this function is supposed to do.
  172.  
  173. # Don't use this function, use Misc::stopAttack() instead!
  174. #sendMove ($char->{'pos_to'}{'x'}, $char->{'pos_to'}{'y'});
  175. #debug "Sent stop attack\n", "sendPacket";
  176. }
  177.  
  178. sub sendAutoSpell {
  179. my ($self, $ID) = @_;
  180. my $msg = pack("C*", 0xce, 0x01, $ID, 0x00, 0x00, 0x00);
  181. $self->sendToServer($msg);
  182. }
  183.  
  184. sub sendBanCheck {
  185. my ($self, $ID) = @_;
  186. $self->sendToServer($self->reconstruct({
  187. switch => 'ban_check',
  188. accountID => $ID,
  189. }));
  190. debug "Sent Account Ban Check Request : " . getHex($ID) . "\n", "sendPacket", 2;
  191. }
  192.  
  193. =pod
  194. sub sendBuy {
  195. my ($self, $ID, $amount) = @_;
  196. my $msg = pack("C*", 0xC8, 0x00, 0x08, 0x00) . pack("v*", $amount, $ID);
  197. $self->sendToServer($msg);
  198. debug "Sent buy: ".getHex($ID)."\n", "sendPacket", 2;
  199. }
  200. =cut
  201. # 0x00c8,-1,npcbuylistsend,2:4
  202. sub sendBuyBulk {
  203. my ($self, $r_array) = @_;
  204. my $msg = pack('v2', 0x00C8, 4+4*@{$r_array});
  205. for (my $i = 0; $i < @{$r_array}; $i++) {
  206. $msg .= pack('v2', $r_array->[$i]{amount}, $r_array->[$i]{itemID});
  207. debug "Sent bulk buy: $r_array->[$i]{itemID} x $r_array->[$i]{amount}\n", "d_sendPacket", 2;
  208. }
  209. $self->sendToServer($msg);
  210. }
  211.  
  212. sub sendCardMerge {
  213. my ($self, $card_index, $item_index) = @_;
  214. my $msg = pack("C*", 0x7C, 0x01) . pack("v*", $card_index, $item_index);
  215. $self->sendToServer($msg);
  216. debug "Sent Card Merge: $card_index, $item_index\n", "sendPacket";
  217. }
  218.  
  219. sub sendCardMergeRequest {
  220. my ($self, $card_index) = @_;
  221. my $msg = pack("C*", 0x7A, 0x01) . pack("v*", $card_index);
  222. $self->sendToServer($msg);
  223. debug "Sent Card Merge Request: $card_index\n", "sendPacket";
  224. }
  225.  
  226. sub sendCartAdd {
  227. my ($self, $index, $amount) = @_;
  228. my $msg = pack("C*", 0x26, 0x01) . pack("v*", $index) . pack("V*", $amount);
  229. $self->sendToServer($msg);
  230. debug "Sent Cart Add: $index x $amount\n", "sendPacket", 2;
  231. }
  232.  
  233. sub sendCartGet {
  234. my ($self, $index, $amount) = @_;
  235. my $msg = pack("C*", 0x27, 0x01) . pack("v*", $index) . pack("V*", $amount);
  236. $self->sendToServer($msg);
  237. debug "Sent Cart Get: $index x $amount\n", "sendPacket", 2;
  238. }
  239.  
  240. sub sendCharCreate {
  241. my ($self, $slot, $name,
  242. $str, $agi, $vit, $int, $dex, $luk,
  243. $hair_style, $hair_color) = @_;
  244. $hair_color ||= 1;
  245. $hair_style ||= 0;
  246.  
  247. my $msg = pack("C*", 0x67, 0x00) .
  248. pack("a24", stringToBytes($name)) .
  249. pack("C*", $str, $agi, $vit, $int, $dex, $luk, $slot) .
  250. pack("v*", $hair_color, $hair_style);
  251. $self->sendToServer($msg);
  252. }
  253.  
  254. sub sendCharDelete {
  255. my ($self, $charID, $email) = @_;
  256. my $msg = pack("C*", 0x68, 0x00) .
  257. $charID . pack("a40", stringToBytes($email));
  258. $self->sendToServer($msg);
  259. }
  260.  
  261. sub sendChatRoomBestow {
  262. my ($self, $name) = @_;
  263.  
  264. my $binName = stringToBytes($name);
  265. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  266. $binName .= chr(0) x (24 - length($binName));
  267.  
  268. my $msg = pack("C*", 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00) . $binName;
  269. $self->sendToServer($msg);
  270. debug "Sent Chat Room Bestow: $name\n", "sendPacket", 2;
  271. }
  272.  
  273. sub sendChatRoomChange {
  274. my ($self, $title, $limit, $public, $password) = @_;
  275.  
  276. my $titleBytes = stringToBytes($title);
  277. my $passwordBytes = stringToBytes($password);
  278. $passwordBytes = substr($passwordBytes, 0, 8) if (length($passwordBytes) > 8);
  279. $passwordBytes = $passwordBytes . chr(0) x (8 - length($passwordBytes));
  280.  
  281. my $msg = pack("C*", 0xDE, 0x00).pack("v*", length($titleBytes) + 15, $limit).pack("C*",$public).$passwordBytes.$titleBytes;
  282. $self->sendToServer($msg);
  283. debug "Sent Change Chat Room: $title, $limit, $public, $password\n", "sendPacket", 2;
  284. }
  285.  
  286. sub sendChatRoomCreate {
  287. my ($self, $title, $limit, $public, $password) = @_;
  288.  
  289. my $passwordBytes = stringToBytes($password);
  290. $passwordBytes = substr($passwordBytes, 0, 8) if (length($passwordBytes) > 8);
  291. $passwordBytes = $passwordBytes . chr(0) x (8 - length($passwordBytes));
  292. my $binTitle = stringToBytes($title);
  293.  
  294. my $msg = pack("C*", 0xD5, 0x00) .
  295. pack("v*", length($binTitle) + 15, $limit) .
  296. pack("C*", $public) . $passwordBytes . $binTitle;
  297. $self->sendToServer($msg);
  298. debug "Sent Create Chat Room: $title, $limit, $public, $password\n", "sendPacket", 2;
  299. }
  300.  
  301. sub sendChatRoomJoin {
  302. my ($self, $ID, $password) = @_;
  303.  
  304. my $passwordBytes = stringToBytes($password);
  305. $passwordBytes = substr($passwordBytes, 0, 8) if (length($passwordBytes) > 8);
  306. $passwordBytes = $passwordBytes . chr(0) x (8 - length($passwordBytes));
  307. my $msg = pack("C*", 0xD9, 0x00).$ID.$passwordBytes;
  308. $self->sendToServer($msg);
  309. debug "Sent Join Chat Room: ".getHex($ID)." $password\n", "sendPacket", 2;
  310. }
  311.  
  312. sub sendChatRoomKick {
  313. my ($self, $name) = @_;
  314.  
  315. my $binName = stringToBytes($name);
  316. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  317. $binName .= chr(0) x (24 - length($binName));
  318. my $msg = pack("C*", 0xE2, 0x00) . $binName;
  319. $self->sendToServer($msg);
  320. debug "Sent Chat Room Kick: $name\n", "sendPacket", 2;
  321. }
  322.  
  323. sub sendChatRoomLeave {
  324. my $self = shift;
  325. my $msg = pack("C*", 0xE3, 0x00);
  326. $self->sendToServer($msg);
  327. debug "Sent Leave Chat Room\n", "sendPacket", 2;
  328. }
  329.  
  330. # 0x022d,5,hommenu,4
  331. sub sendHomunculusCommand {
  332. my ($self, $command, $type) = @_; # $type is ignored, $command can be 0:get stats, 1:feed or 2:fire
  333. my $msg = pack ('v2 C', 0x022D, $type, $command);
  334. $self->sendToServer($msg);
  335. debug "Sent Homunculus Command $command", "sendPacket", 2;
  336. }
  337.  
  338. sub sendCompanionRelease {
  339. my $msg = pack("C*", 0x2A, 0x01);
  340. $_[0]->sendToServer($msg);
  341. debug "Sent Companion Release (Cart, Falcon or Pecopeco)\n", "sendPacket", 2;
  342. }
  343.  
  344. sub sendCurrentDealCancel {
  345. my $msg = pack("C*", 0xED, 0x00);
  346. $_[0]->sendToServer($msg);
  347. debug "Sent Cancel Current Deal\n", "sendPacket", 2;
  348. }
  349.  
  350. sub sendDeal {
  351. my ($self, $ID) = @_;
  352. my $msg = pack("C*", 0xE4, 0x00) . $ID;
  353. $_[0]->sendToServer($msg);
  354. debug "Sent Initiate Deal: ".getHex($ID)."\n", "sendPacket", 2;
  355. }
  356.  
  357. sub sendDealReply {
  358. #Reply to a trade-request.
  359. # Type values:
  360. # 0: Char is too far
  361. # 1: Character does not exist
  362. # 2: Trade failed
  363. # 3: Accept
  364. # 4: Cancel
  365. # Weird enough, the client should only send 3/4
  366. # and the server is the one that can reply 0~2
  367. my ($self, $action) = @_;
  368. my $msg = pack('v C', 0x00E6, $action);
  369. $_[0]->sendToServer($msg);
  370. debug "Sent " . ($action == 3 ? "Accept": ($action == 4 ? "Cancel" : "action: " . $action)) . " Deal\n", "sendPacket", 2;
  371. }
  372.  
  373. # TODO: legacy plugin support, remove later
  374. sub sendDealAccept {
  375. $_[0]->sendDealReply(3);
  376. debug "Sent Cancel Deal\n", "sendPacket", 2;
  377. }
  378.  
  379. # TODO: legacy plugin support, remove later
  380. sub sendDealCancel {
  381. $_[0]->sendDealReply(4);
  382. debug "Sent Cancel Deal\n", "sendPacket", 2;
  383. }
  384.  
  385. sub sendDealAddItem {
  386. my ($self, $index, $amount) = @_;
  387. my $msg = pack("C*", 0xE8, 0x00) . pack("v*", $index) . pack("V*",$amount);
  388. $_[0]->sendToServer($msg);
  389. debug "Sent Deal Add Item: $index, $amount\n", "sendPacket", 2;
  390. }
  391.  
  392. sub sendDealFinalize {
  393. my $msg = pack("C*", 0xEB, 0x00);
  394. $_[0]->sendToServer($msg);
  395. debug "Sent Deal OK\n", "sendPacket", 2;
  396. }
  397.  
  398. sub sendDealOK {
  399. my $msg = pack("C*", 0xEB, 0x00);
  400. $_[0]->sendToServer($msg);
  401. debug "Sent Deal OK\n", "sendPacket", 2;
  402. }
  403.  
  404. sub sendDealTrade {
  405. my $msg = pack("C*", 0xEF, 0x00);
  406. $_[0]->sendToServer($msg);
  407. debug "Sent Deal Trade\n", "sendPacket", 2;
  408. }
  409.  
  410. sub sendEmotion {
  411. my ($self, $ID) = @_;
  412. my $msg = pack("C*", 0xBF, 0x00).pack("C1",$ID);
  413. $self->sendToServer($msg);
  414. debug "Sent Emotion\n", "sendPacket", 2;
  415. }
  416.  
  417. sub sendEnteringVender {
  418. my ($self, $ID) = @_;
  419. my $msg = pack("C*", 0x30, 0x01) . $ID;
  420. $self->sendToServer($msg);
  421. debug "Sent Entering Vender: ".getHex($ID)."\n", "sendPacket", 2;
  422. }
  423.  
  424. sub sendEquip {
  425. my ($self, $index, $type) = @_;
  426. my $msg = pack("C*", 0xA9, 0x00) . pack("v*", $index) . pack("v*", $type);
  427. $self->sendToServer($msg);
  428. debug "Sent Equip: $index Type: $type\n" , 2;
  429. }
  430.  
  431. # 0x0208,11,friendslistreply,2:6:10
  432. # Reject:0/Accept:1
  433.  
  434. sub sendFriendRequest {
  435. my ($self, $name) = @_;
  436.  
  437. my $binName = stringToBytes($name);
  438. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  439. $binName = $binName . chr(0) x (24 - length($binName));
  440. my $msg = pack("C*", 0x02, 0x02) . $binName;
  441.  
  442. $self->sendToServer($msg);
  443. debug "Sent Request to be a friend: $name\n", "sendPacket";
  444. }
  445.  
  446. sub sendFriendRemove {
  447. my ($self, $accountID, $charID) = @_;
  448. my $msg = pack("C*", 0x03, 0x02) . $accountID . $charID;
  449. $self->sendToServer($msg);
  450. debug "Sent Remove a friend\n", "sendPacket";
  451. }
  452.  
  453. sub sendProduceMix {
  454. my ($self, $ID,
  455. # nameIDs for added items such as Star Crumb or Flame Heart
  456. $item1, $item2, $item3) = @_;
  457.  
  458. my $msg = pack("v5", 0x018E, $ID, $item1, $item2, $item3);
  459. $self->sendToServer($msg);
  460. debug "Sent Forge, Produce Item: $ID\n" , 2;
  461. }
  462.  
  463. =pod
  464. sub sendGetCharacterName {
  465. my ($self, $ID) = @_;
  466. my $msg = pack("C*", 0x69, 0x03) . $ID;
  467. $self->sendToServer($msg);
  468. debug "Sent get character name: ID - ".getHex($ID)."\n", "sendPacket", 2;
  469. }
  470. =cut
  471.  
  472. sub sendNPCBuySellList { # type:0 get store list, type:1 get sell list
  473. my ($self, $ID, $type) = @_;
  474. my $msg = pack('v a4 C', 0x00C5, $ID , $type);
  475. $self->sendToServer($msg);
  476. debug "Sent get ".($type ? "buy" : "sell")." list to NPC: ".getHex($ID)."\n", "sendPacket", 2;
  477. }
  478.  
  479. =pod
  480. sub sendGetStoreList {
  481. my ($self, $ID, $type) = @_;
  482. my $msg = pack("C*", 0xC5, 0x00) . $ID . pack("C*",0x00);
  483. $self->sendToServer($msg);
  484. debug "Sent get store list: ".getHex($ID)."\n", "sendPacket", 2;
  485. }
  486.  
  487. sub sendGetSellList {
  488. my ($self, $ID) = @_;
  489. my $msg = pack("C*", 0xC5, 0x00) . $ID . pack("C*",0x01);
  490. $self->sendToServer($msg);
  491. debug "Sent sell to NPC: ".getHex($ID)."\n", "sendPacket", 2;
  492. }
  493. =cut
  494.  
  495. sub sendGMSummon {
  496. my ($self, $playerName) = @_;
  497. my $packet = pack("C*", 0xBD, 0x01) . pack("a24", stringToBytes($playerName));
  498. $self->sendToServer($packet);
  499. }
  500.  
  501. sub sendGuildAlly {
  502. my ($self, $ID, $flag) = @_;
  503. my $msg = pack("C*", 0x72, 0x01).$ID.pack("V1", $flag);
  504. $self->sendToServer($msg);
  505. debug "Sent Ally Guild : ".getHex($ID).", $flag\n", "sendPacket", 2;
  506. }
  507.  
  508. sub sendGuildBreak {
  509. my ($self, $guildName) = @_;
  510. my $msg = pack("C C a40", 0x5D, 0x01, stringToBytes($guildName));
  511. $self->sendToServer($msg);
  512. debug "Sent Guild Break: $guildName\n", "sendPacket", 2;
  513. }
  514.  
  515. sub sendGuildCreate {
  516. my ($self, $name) = @_;
  517. # By Default, the second param is our CharID. which indicate the Guild Master Char ID
  518. my $msg = pack('v a4 a24', 0x0165, $charID, stringToBytes($name));
  519. $self->sendToServer($msg);
  520. debug "Sent Guild Create: $name\n", "sendPacket", 2;
  521. }
  522.  
  523. sub sendGuildJoin {
  524. my ($self, $ID, $flag) = @_;
  525. my $msg = pack("C*", 0x6B, 0x01).$ID.pack("V1", $flag);
  526. $self->sendToServer($msg);
  527. debug "Sent Join Guild : ".getHex($ID).", $flag\n", "sendPacket";
  528. }
  529.  
  530. sub sendGuildJoinRequest {
  531. my ($self, $ID) = @_;
  532. my $msg = pack("C*", 0x68, 0x01).$ID.$accountID.$charID;
  533. $self->sendToServer($msg);
  534. debug "Sent Request Join Guild: ".getHex($ID)."\n", "sendPacket";
  535. }
  536.  
  537. sub sendGuildLeave {
  538. my ($self, $reason) = @_;
  539. my $mess = pack("Z40", stringToBytes($reason));
  540. my $msg = pack("C*", 0x59, 0x01).$guild{ID}.$accountID.$charID.$mess;
  541. $self->sendToServer($msg);
  542. debug "Sent Guild Leave: $reason (".getHex($msg).")\n", "sendPacket";
  543. }
  544.  
  545. sub sendGuildMemberKick {
  546. my ($self, $guildID, $accountID, $charID, $cause) = @_;
  547. my $msg = pack("C*", 0x5B, 0x01).$guildID.$accountID.$charID.pack("a40", stringToBytes($cause));
  548. $self->sendToServer($msg);
  549. debug "Sent Guild Kick: ".getHex($charID)."\n", "sendPacket";
  550. }
  551.  
  552. =pod
  553. sub sendGuildMemberTitleSelect {
  554. # set the title for a member
  555. my ($self, $accountID, $charID, $index) = @_;
  556.  
  557. my $msg = pack("C*", 0x55, 0x01).pack("v1",16).$accountID.$charID.pack("V1",$index);
  558. $self->sendToServer($msg);
  559. debug "Sent Change Guild title: ".getHex($charID)." $index\n", "sendPacket", 2;
  560. }
  561. =cut
  562. # 0x0155,-1,guildchangememberposition,2
  563. sub sendGuildMemberPositions {
  564. my ($self, $r_array) = @_;
  565. my $msg = pack('v2', 0x0155, 4+12*@{$r_array});
  566. for (my $i = 0; $i < @{$r_array}; $i++) {
  567. $msg .= pack('a4 a4 V', $r_array->[$i]{accountID}, $r_array->[$i]{charID}, $r_array->[$i]{index});
  568. debug "Sent GuildChangeMemberPositions: $r_array->[$i]{accountID} $r_array->[$i]{charID} $r_array->[$i]{index}\n", "d_sendPacket", 2;
  569. }
  570. $self->sendToServer($msg);
  571. }
  572.  
  573. sub sendGuildNotice {
  574. # sets the notice/announcement for the guild
  575. my ($self, $guildID, $name, $notice) = @_;
  576. my $msg = pack("C*", 0x6E, 0x01) . $guildID .
  577. pack("a60 a120", stringToBytes($name), stringToBytes($notice));
  578. $self->sendToServer($msg);
  579. debug "Sent Change Guild Notice: $notice\n", "sendPacket", 2;
  580. }
  581.  
  582. =pod
  583. sub sendGuildRankChange {
  584. # change the title for a certain index
  585. # i would guess 0 is the top rank, but i dont know
  586. my ($self, $index, $permissions, $tax, $title) = @_;
  587.  
  588. my $msg = pack("C*", 0x61, 0x01) .
  589. pack("v1", 44) . # packet length, we can actually send multiple titles in the same packet if we wanted to
  590. pack("V1", $index) . # index of this rank in the list
  591. pack("V1", $permissions) . # this is their abilities, not sure what format
  592. pack("V1", $index) . # isnt even used on emulators, but leave in case Aegis wants this
  593. pack("V1", $tax) . # guild tax amount, not sure what format
  594. pack("a24", $title);
  595. $self->sendToServer($msg);
  596. debug "Sent Set Guild title: $index $title\n", "sendPacket", 2;
  597. }
  598. =cut
  599. # 0x0161,-1,guildchangepositioninfo,2
  600. sub sendGuildPositionInfo {
  601. my ($self, $r_array) = @_;
  602. my $msg = pack('v2', 0x0161, 4+44*@{$r_array});
  603. for (my $i = 0; $i < @{$r_array}; $i++) {
  604. $msg .= pack('v2 V4 a24', $r_array->[$i]{index}, $r_array->[$i]{permissions}, $r_array->[$i]{index}, $r_array->[$i]{tax}, stringToBytes($r_array->[$i]{title}));
  605. debug "Sent GuildPositionInfo: $r_array->[$i]{index}, $r_array->[$i]{permissions}, $r_array->[$i]{index}, $r_array->[$i]{tax}, ".stringToBytes($r_array->[$i]{title})."\n", "d_sendPacket", 2;
  606. }
  607. $self->sendToServer($msg);
  608. }
  609.  
  610. sub sendGuildRequestEmblem {
  611. my ($self, $guildID) = @_;
  612. my $msg = pack("v V", 0x0151, $guildID);
  613. $self->sendToServer($msg);
  614. debug "Sent Guild Request Emblem.\n", "sendPacket";
  615. }
  616.  
  617. sub sendGuildSetAlly {
  618. # this packet is for guildmaster asking to set alliance with another guildmaster
  619. # the other sub for sendGuildAlly are responses to this sub
  620. # kept the parameters open, but everything except $targetAID could be replaced with Global variables
  621. # unless you plan to mess around with the alliance packet, no exploits though, I tried ;-)
  622. # -zdivpsa
  623. my ($self, $targetAID, $myAID, $charID) = @_; # remote socket, $net
  624. my $msg = pack("C*", 0x70, 0x01) .
  625. $targetAID .
  626. $myAID .
  627. $charID;
  628. $self->sendToServer($msg);
  629.  
  630. }
  631.  
  632. sub sendHomunculusAttack {
  633. my $self = shift;
  634. my $homunID = shift;
  635. my $targetID = shift;
  636. my $flag = shift;
  637. my $msg = pack("C*", 0x33, 0x02) . $homunID . $targetID . pack("C1", $flag);
  638. $self->sendToServer($msg);
  639. debug "Sent Homunculus attack: ".getHex($targetID)."\n", "sendPacket", 2;
  640. }
  641.  
  642. sub sendHomunculusStandBy {
  643. my $self = shift;
  644. my $homunID = shift;
  645. my $msg = pack("C*", 0x34, 0x02) . $homunID;
  646. $self->sendToServer($msg);
  647. debug "Sent Homunculus standby\n", "sendPacket", 2;
  648. }
  649.  
  650. sub sendHomunculusName {
  651. my $self = shift;
  652. my $name = shift;
  653. my $msg = pack("v1 a24", 0x0231, stringToBytes($name));
  654. $self->sendToServer($msg);
  655. debug "Sent Homunculus Rename: $name\n", "sendPacket", 2;
  656. }
  657.  
  658. sub sendIdentify {
  659. my $self = shift;
  660. my $index = shift;
  661. my $msg = pack("C*", 0x78, 0x01) . pack("v*", $index);
  662. $self->sendToServer($msg);
  663. debug "Sent Identify: $index\n", "sendPacket", 2;
  664. }
  665.  
  666. sub sendIgnore {
  667. my $self = shift;
  668. my $name = shift;
  669. my $flag = shift;
  670.  
  671. my $binName = stringToBytes($name);
  672. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  673. $binName = $binName . chr(0) x (24 - length($binName));
  674. my $msg = pack("C*", 0xCF, 0x00) . $binName . pack("C*", $flag);
  675.  
  676. $self->sendToServer($msg);
  677. debug "Sent Ignore: $name, $flag\n", "sendPacket", 2;
  678. }
  679.  
  680. sub sendIgnoreAll {
  681. my $self = shift;
  682. my $flag = shift;
  683. my $msg = pack("C*", 0xD0, 0x00).pack("C*", $flag);
  684. $self->sendToServer($msg);
  685. debug "Sent Ignore All: $flag\n", "sendPacket", 2;
  686. }
  687.  
  688. sub sendIgnoreListGet {
  689. my $self = shift;
  690. my $flag = shift;
  691. my $msg = pack("C*", 0xD3, 0x00);
  692. $self->sendToServer($msg);
  693. debug "Sent get Ignore List: $flag\n", "sendPacket", 2;
  694. }
  695.  
  696. sub sendItemUse {
  697. my ($self, $ID, $targetID) = @_;
  698. my $msg;
  699.  
  700. $msg = pack("C*", 0xA7, 0x00).pack("v*",$ID) .
  701. $targetID;
  702.  
  703. $self->sendToServer($msg);
  704. debug "Item Use: $ID\n", "sendPacket", 2;
  705. }
  706.  
  707. sub sendMemo {
  708. my $self = shift;
  709. my $msg = pack("C*", 0x1D, 0x01);
  710. $self->sendToServer($msg);
  711. debug "Sent Memo\n", "sendPacket", 2;
  712. }
  713.  
  714. sub sendOpenShop {
  715. my ($self, $title, $items) = @_;
  716.  
  717. my $length = 0x55 + 0x08 * @{$items};
  718. my $msg = pack("C*", 0xB2, 0x01).
  719. pack("v*", $length).
  720. pack("a80", stringToBytes($title)).
  721. pack("C*", 0x01);
  722.  
  723. foreach my $item (@{$items}) {
  724. $msg .= pack("v1", $item->{index}).
  725. pack("v1", $item->{amount}).
  726. pack("V1", $item->{price});
  727. }
  728.  
  729. $self->sendToServer($msg);
  730. }
  731.  
  732. sub sendPartyJoin {
  733. my $self = shift;
  734. my $ID = shift;
  735. my $flag = shift;
  736. my $msg = pack("C*", 0xFF, 0x00).$ID.pack("V", $flag);
  737. $self->sendToServer($msg);
  738. debug "Sent Join Party: ".getHex($ID).", $flag\n", "sendPacket", 2;
  739. }
  740.  
  741. sub sendPartyJoinRequest {
  742. my $self = shift;
  743. my $ID = shift;
  744. my $msg = pack("C*", 0xFC, 0x00).$ID;
  745. $self->sendToServer($msg);
  746. debug "Sent Request Join Party: ".getHex($ID)."\n", "sendPacket", 2;
  747. }
  748.  
  749. sub _binName {
  750. my $name = shift;
  751.  
  752. $name = stringToBytes ($name);
  753. $name = substr ($name, 0, 24) if 24 < length $name;
  754. $name .= "\x00" x (24 - length $name);
  755. return $name;
  756. }
  757.  
  758. sub sendPartyJoinRequestByName {
  759. my $self = shift;
  760. my $name = shift;
  761. my $msg = pack ('C*', 0xc4, 0x02) . _binName ($name);
  762. $self->sendToServer($msg);
  763. debug "Sent Request Join Party (by name): $name\n", "sendPacket", 2;
  764. }
  765.  
  766. sub sendPartyJoinRequestByNameReply {
  767. my ($self, $accountID, $flag) = @_;
  768. my $msg = pack('v a4 C', 0x02C7, $accountID, $flag);
  769. $self->sendToServer($msg);
  770. debug "Sent reply Party Invite.\n", "sendPacket", 2;
  771. }
  772.  
  773. sub sendPartyKick {
  774. my $self = shift;
  775. my $ID = shift;
  776. my $name = shift;
  777. my $msg = pack("C*", 0x03, 0x01) . $ID . _binName ($name);
  778. $self->sendToServer($msg);
  779. debug "Sent Kick Party: ".getHex($ID).", $name\n", "sendPacket", 2;
  780. }
  781.  
  782. sub sendPartyLeave {
  783. my $self = shift;
  784. my $msg = pack("C*", 0x00, 0x01);
  785. $self->sendToServer($msg);
  786. debug "Sent Leave Party\n", "sendPacket", 2;
  787. }
  788.  
  789. sub sendPartyOrganize {
  790. my $self = shift;
  791. my $name = shift;
  792. my $share1 = shift || 1;
  793. my $share2 = shift || 1;
  794.  
  795. my $binName = stringToBytes($name);
  796. $binName = substr($binName, 0, 24) if (length($binName) > 24);
  797. $binName .= chr(0) x (24 - length($binName));
  798. #my $msg = pack("C*", 0xF9, 0x00) . $binName;
  799. # I think this is obsolete - which serverTypes still support this packet anyway?
  800. # FIXME: what are shared with $share1 and $share2? experience? item? vice-versa?
  801.  
  802. my $msg = pack("C*", 0xE8, 0x01) . $binName . pack("C*", $share1, $share2);
  803.  
  804. $self->sendToServer($msg);
  805. debug "Sent Organize Party: $name\n", "sendPacket", 2;
  806. }
  807.  
  808. # legacy plugin support, remove later
  809. sub sendPartyShareEXP {
  810. my ($self, $exp) = @_;
  811. $self->sendPartyOption($exp, 0);
  812. }
  813.  
  814. # 0x0102,6,partychangeoption,2:4
  815. # note: item share changing seems disabled in newest clients
  816. sub sendPartyOption {
  817. my ($self, $exp, $itemPickup, $itemDivision) = @_;
  818.  
  819. $self->sendToServer($self->reconstruct({
  820. switch => 'party_setting',
  821. exp => $exp,
  822. itemPickup => $itemPickup,
  823. itemDivision => $itemDivision,
  824. }));
  825. debug "Sent Party Option\n", "sendPacket", 2;
  826. }
  827.  
  828. sub sendPetCapture {
  829. my ($self, $monID) = @_;
  830. my $msg = pack('v a4', 0x019F, $monID);
  831. $self->sendToServer($msg);
  832. debug "Sent pet capture: ".getHex($monID)."\n", "sendPacket", 2;
  833. }
  834.  
  835. # 0x01a1,3,petmenu,2
  836. sub sendPetMenu {
  837. my ($self, $type) = @_; # 0:info, 1:feed, 2:performance, 3:to egg, 4:uneq item
  838. my $msg = pack('v C', 0x01A1, $type);
  839. $self->sendToServer($msg);
  840. debug "Sent Pet Menu\n", "sendPacket", 2;
  841. }
  842.  
  843. sub sendPetHatch {
  844. my ($self, $index) = @_;
  845. my $msg = pack('v2', 0x01A7, $index);
  846. $self->sendToServer($msg);
  847. debug "Sent Incubator hatch: $index\n", "sendPacket", 2;
  848. }
  849.  
  850. sub sendPetName {
  851. my ($self, $name) = @_;
  852. my $msg = pack('v a24', 0x01A5, stringToBytes($name));
  853. $self->sendToServer($msg);
  854. debug "Sent Pet Rename: $name\n", "sendPacket", 2;
  855. }
  856.  
  857. # 0x01af,4,changecart,2
  858. sub sendChangeCart { # lvl: 1, 2, 3, 4, 5
  859. my ($self, $lvl) = @_;
  860. my $msg = pack('v2', 0x01AF, $lvl);
  861. $self->sendToServer($msg);
  862. debug "Sent Cart Change to : $lvl\n", "sendPacket", 2;
  863. }
  864.  
  865. sub sendPreLoginCode {
  866. # no server actually needs this, but we might need it in the future?
  867. my $self = shift;
  868. my $type = shift;
  869. my $msg;
  870. if ($type == 1) {
  871. $msg = pack("C*", 0x04, 0x02, 0x82, 0xD1, 0x2C, 0x91, 0x4F, 0x5A, 0xD4, 0x8F, 0xD9, 0x6F, 0xCF, 0x7E, 0xF4, 0xCC, 0x49, 0x2D);
  872. }
  873. $self->sendToServer($msg);
  874. debug "Sent pre-login packet $type\n", "sendPacket", 2;
  875. }
  876.  
  877. sub sendRaw {
  878. my $self = shift;
  879. my $raw = shift;
  880. my @raw;
  881. my $msg;
  882. @raw = split / /, $raw;
  883. foreach (@raw) {
  884. $msg .= pack("C", hex($_));
  885. }
  886. $self->sendToServer($msg);
  887. debug "Sent Raw Packet: @raw\n", "sendPacket", 2;
  888. }
  889.  
  890. sub sendRequestMakingHomunculus {
  891. # WARNING: If you don't really know, what are you doing - don't touch this
  892. my ($self, $make_homun) = @_;
  893.  
  894. my $skill = new Skill (idn => 241);
  895.  
  896. if (
  897. Actor::Item::get (997) && Actor::Item::get (998) && Actor::Item::get (999)
  898. && ($char->getSkillLevel ($skill) > 0)
  899. ) {
  900. my $msg = pack ('v C', 0x01CA, $make_homun);
  901. $self->sendToServer($msg);
  902. debug "Sent RequestMakingHomunculus\n", "sendPacket", 2;
  903. }
  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 attachments\n", "sendPacket", 2;
  911. }
  912.  
  913. sub sendRepairItem {
  914. my ($self, $args) = @_;
  915. my $msg = pack("C2 v2 V2 C1", 0xFD, 0x01, $args->{index}, $args->{nameID}, $args->{status}, $args->{status2}, $args->{listID});
  916. $self->sendToServer($msg);
  917. debug ("Sent repair item: ".$args->{index}."\n", "sendPacket", 2);
  918. }
  919.  
  920. sub sendSell {
  921. my $self = shift;
  922. my $index = shift;
  923. my $amount = shift;
  924. my $msg = pack("C*", 0xC9, 0x00, 0x08, 0x00) . pack("v*", $index, $amount);
  925. $self->sendToServer($msg);
  926. debug "Sent sell: $index x $amount\n", "sendPacket", 2;
  927. }
  928.  
  929. sub sendSellBulk {
  930. my $self = shift;
  931. my $r_array = shift;
  932. my $sellMsg = "";
  933.  
  934. for (my $i = 0; $i < @{$r_array}; $i++) {
  935. $sellMsg .= pack("v*", $r_array->[$i]{index}, $r_array->[$i]{amount});
  936. debug "Sent bulk sell: $r_array->[$i]{index} x $r_array->[$i]{amount}\n", "d_sendPacket", 2;
  937. }
  938.  
  939. my $msg = pack("C*", 0xC9, 0x00) . pack("v*", length($sellMsg) + 4) . $sellMsg;
  940. $self->sendToServer($msg);
  941. }
  942.  
  943. sub sendStorageAddFromCart {
  944. my $self = shift;
  945. my $index = shift;
  946. my $amount = shift;
  947. my $msg;
  948. $msg = pack("C*", 0x29, 0x01) . pack("v*", $index) . pack("V*", $amount);
  949. $self->sendToServer($msg);
  950. debug "Sent Storage Add From Cart: $index x $amount\n", "sendPacket", 2;
  951. }
  952.  
  953. sub sendStorageClose {
  954. my ($self) = @_;
  955. my $msg;
  956. if (($self->{serverType} == 3) || ($self->{serverType} == 5) || ($self->{serverType} == 9) || ($self->{serverType} == 15)) {
  957. $msg = pack("C*", 0x69, 0x03);
  958. } elsif ($self->{serverType} == 12) {
  959. $msg = pack("C*", 0x72, 0x00);
  960. } elsif ($self->{serverType} == 14) {
  961. $msg = pack("C*", 0x16, 0x01);
  962. } else {
  963. $msg = pack("C*", 0xF7, 0x00);
  964. }
  965.  
  966. $self->sendToServer($msg);
  967. debug "Sent Storage Done\n", "sendPacket", 2;
  968. }
  969.  
  970. sub sendStorageGetToCart {
  971. my $self = shift;
  972. my $index = shift;
  973. my $amount = shift;
  974. my $msg;
  975. $msg = pack("C*", 0x28, 0x01) . pack("v*", $index) . pack("V*", $amount);
  976. $self->sendToServer($msg);
  977. debug "Sent Storage Get From Cart: $index x $amount\n", "sendPacket", 2;
  978. }
  979.  
  980. sub sendStoragePassword {
  981. my $self = shift;
  982. # 16 byte packed hex data
  983. my $pass = shift;
  984. # 2 = set password ?
  985. # 3 = give password ?
  986. my $type = shift;
  987. my $msg;
  988. if ($type == 3) {
  989. $msg = pack("C C v", 0x3B, 0x02, $type).$pass.pack("H*", "EC62E539BB6BBC811A60C06FACCB7EC8");
  990. } elsif ($type == 2) {
  991. $msg = pack("C C v", 0x3B, 0x02, $type).pack("H*", "EC62E539BB6BBC811A60C06FACCB7EC8").$pass;
  992. } else {
  993. ArgumentException->throw("The 'type' argument has invalid value ($type).");
  994. }
  995. $self->sendToServer($msg);
  996. }
  997.  
  998. sub sendSuperNoviceDoriDori {
  999. my $msg = pack("C*", 0xE7, 0x01);
  1000. $_[0]->sendToServer($msg);
  1001. debug "Sent Super Novice dori dori\n", "sendPacket", 2;
  1002. }
  1003.  
  1004. # TODO: is this the sn mental ingame triggered trough the poem?
  1005. sub sendSuperNoviceExplosion {
  1006. my $msg = pack("C*", 0xED, 0x01);
  1007. $_[0]->sendToServer($msg);
  1008. debug "Sent Super Novice Explosion\n", "sendPacket", 2;
  1009. }
  1010.  
  1011. sub sendTalk {
  1012. my $self = shift;
  1013. my $ID = shift;
  1014. my $msg = pack("C*", 0x90, 0x00) . $ID . pack("C*",0x01);
  1015. $self->sendToServer($msg);
  1016. debug "Sent talk: ".getHex($ID)."\n", "sendPacket", 2;
  1017. }
  1018.  
  1019. sub sendTalkCancel {
  1020. my $self = shift;
  1021. my $ID = shift;
  1022. my $msg = pack("C*", 0x46, 0x01) . $ID;
  1023. $self->sendToServer($msg);
  1024. debug "Sent talk cancel: ".getHex($ID)."\n", "sendPacket", 2;
  1025. }
  1026.  
  1027. sub sendTalkContinue {
  1028. my $self = shift;
  1029. my $ID = shift;
  1030. my $msg = pack("C*", 0xB9, 0x00) . $ID;
  1031. $self->sendToServer($msg);
  1032. debug "Sent talk continue: ".getHex($ID)."\n", "sendPacket", 2;
  1033. }
  1034.  
  1035. sub sendTalkResponse {
  1036. my $self = shift;
  1037. my $ID = shift;
  1038. my $response = shift;
  1039. my $msg = pack("C*", 0xB8, 0x00) . $ID. pack("C1",$response);
  1040. $self->sendToServer($msg);
  1041. debug "Sent talk respond: ".getHex($ID).", $response\n", "sendPacket", 2;
  1042. }
  1043.  
  1044. sub sendTalkNumber {
  1045. my $self = shift;
  1046. my $ID = shift;
  1047. my $number = shift;
  1048. my $msg = pack("C*", 0x43, 0x01) . $ID .
  1049. pack("V1", $number);
  1050. $self->sendToServer($msg);
  1051. debug "Sent talk number: ".getHex($ID).", $number\n", "sendPacket", 2;
  1052. }
  1053.  
  1054. sub sendTalkText {
  1055. my $self = shift;
  1056. my $ID = shift;
  1057. my $input = stringToBytes(shift);
  1058. my $msg = pack("C*", 0xD5, 0x01) . pack("v*", length($input)+length($ID)+5) . $ID . $input . chr(0);
  1059. $self->sendToServer($msg);
  1060. debug "Sent talk text: ".getHex($ID).", $input\n", "sendPacket", 2;
  1061. }
  1062.  
  1063. # 0x011b,20,useskillmap,2:4
  1064. sub sendWarpTele { # type: 26=tele, 27=warp
  1065. my ($self, $skillID, $map) = @_;
  1066. my $msg = pack('v2 Z16', 0x011B, $skillID, stringToBytes($map));
  1067. $self->sendToServer($msg);
  1068. debug "Sent ". ($skillID == 26 ? "Teleport" : "Open Warp") . "\n", "sendPacket", 2
  1069. }
  1070. =pod
  1071. sub sendTeleport {
  1072. my $self = shift;
  1073. my $location = shift;
  1074. $location = substr($location, 0, 16) if (length($location) > 16);
  1075. $location .= chr(0) x (16 - length($location));
  1076. my $msg = pack("C*", 0x1B, 0x01, 0x1A, 0x00) . $location;
  1077. $self->sendToServer($msg);
  1078. debug "Sent Teleport: $location\n", "sendPacket", 2;
  1079. }
  1080.  
  1081. sub sendOpenWarp {
  1082. my ($self, $map) = @_;
  1083. my $msg = pack("C*", 0x1b, 0x01, 0x1b, 0x00) . $map .
  1084. chr(0) x (16 - length($map));
  1085. $self->sendToServer($msg);
  1086. }
  1087. =cut
  1088.  
  1089. sub sendTop10Alchemist {
  1090. my $self = shift;
  1091. my $msg = pack("v", 0x0218);
  1092. $self->sendToServer($msg);
  1093. debug "Sent Top 10 Alchemist request\n", "sendPacket", 2;
  1094. }
  1095.  
  1096. sub sendTop10Blacksmith {
  1097. my $self = shift;
  1098. my $msg = pack("v", 0x0217);
  1099. $self->sendToServer($msg);
  1100. debug "Sent Top 10 Blacksmith request\n", "sendPacket", 2;
  1101. }
  1102.  
  1103. sub sendTop10PK {
  1104. my $self = shift;
  1105. my $msg = pack("v", 0x0237);
  1106. $self->sendToServer($msg);
  1107. debug "Sent Top 10 PK request\n", "sendPacket", 2;
  1108. }
  1109.  
  1110. sub sendTop10Taekwon {
  1111. my $self = shift;
  1112. my $msg = pack("v", 0x0225);
  1113. $self->sendToServer($msg);
  1114. debug "Sent Top 10 Taekwon request\n", "sendPacket", 2;
  1115. }
  1116.  
  1117. sub sendUnequip {
  1118. my $self = shift;
  1119. my $index = shift;
  1120. my $msg = pack("v", 0x00AB) . pack("v*", $index);
  1121. $self->sendToServer($msg);
  1122. debug "Sent Unequip: $index\n", "sendPacket", 2;
  1123. }
  1124.  
  1125. sub sendWho {
  1126. my $self = shift;
  1127. my $msg = pack("v", 0x00C1);
  1128. $self->sendToServer($msg);
  1129. debug "Sent Who\n", "sendPacket", 2;
  1130. }
  1131.  
  1132. sub SendAdoptReply {
  1133. my ($self, $parentID1, $parentID2, $result) = @_;
  1134. my $msg = pack("v V3", 0x01F7, $parentID1, $parentID2, $result);
  1135. $self->sendToServer($msg);
  1136. debug "Sent Adoption Reply.\n", "sendPacket", 2;
  1137. }
  1138.  
  1139. sub SendAdoptRequest {
  1140. my ($self, $ID) = @_;
  1141. my $msg = pack("v V", 0x01F9, $ID);
  1142. $self->sendToServer($msg);
  1143. debug "Sent Adoption Request.\n", "sendPacket", 2;
  1144. }
  1145.  
  1146. # 0x0213 has no info on eA
  1147.  
  1148. sub sendMailboxOpen {
  1149. my $self = $_[0];
  1150. my $msg = pack("v", 0x023F);
  1151. $self->sendToServer($msg);
  1152. debug "Sent mailbox open.\n", "sendPacket", 2;
  1153. }
  1154.  
  1155. sub sendMailRead {
  1156. my ($self, $mailID) = @_;
  1157. my $msg = pack("v V", 0x0241, $mailID);
  1158. $self->sendToServer($msg);
  1159. debug "Sent read mail.\n", "sendPacket", 2;
  1160. }
  1161.  
  1162. sub sendMailDelete {
  1163. my ($self, $mailID) = @_;
  1164. my $msg = pack("v V", 0x0243, $mailID);
  1165. $self->sendToServer($msg);
  1166. debug "Sent delete mail.\n", "sendPacket", 2;
  1167. }
  1168.  
  1169. sub sendMailGetAttach {
  1170. my ($self, $mailID) = @_;
  1171. my $msg = pack("v V", 0x0244, $mailID);
  1172. $self->sendToServer($msg);
  1173. debug "Sent mail get attachment.\n", "sendPacket", 2;
  1174. }
  1175.  
  1176. sub sendMailOperateWindow {
  1177. my ($self, $window) = @_;
  1178. my $msg = pack("v C x", 0x0246, $window);
  1179. $self->sendToServer($msg);
  1180. debug "Sent mail window.\n", "sendPacket", 2;
  1181. }
  1182.  
  1183. sub sendMailSetAttach {
  1184. my $self = $_[0];
  1185. my $amount = $_[1];
  1186. my $index = (defined $_[2]) ? $_[2] : 0; # 0 for zeny
  1187. my $msg = pack("v2 V", 0x0247, $index, $amount);
  1188.  
  1189. #We must do it or we will lost attachment what was not send.
  1190. if ($index) {
  1191. $self->sendMailOperateWindow(1);
  1192. } else {
  1193. $self->sendMailOperateWindow(2);
  1194. }
  1195. $AI::temp::mailAttachAmount = $amount;
  1196. $self->sendToServer($msg);
  1197. debug "Sent mail set attachment.\n", "sendPacket", 2;
  1198. }
  1199.  
  1200. sub sendMailSend {
  1201. my ($self, $receiver, $title, $message) = @_;
  1202. my $msg = pack("v2 Z24 a40 C Z*", 0x0248, length($message)+70 , stringToBytes($receiver), stringToBytes($title), length($message), stringToBytes($message));
  1203. $self->sendToServer($msg);
  1204. debug "Sent mail send.\n", "sendPacket", 2;
  1205. }
  1206.  
  1207. sub sendAuctionAddItemCancel {
  1208. my ($self) = @_;
  1209. my $msg = pack("v2", 0x024B, 1);
  1210. $self->sendToServer($msg);
  1211. debug "Sent Auction Add Item Cancel.\n", "sendPacket", 2;
  1212. }
  1213.  
  1214. sub sendAuctionAddItem {
  1215. my ($self, $index, $amount) = @_;
  1216. my $msg = pack("v2 V", 0x024C, $index, $amount);
  1217. $self->sendToServer($msg);
  1218. debug "Sent Auction Add Item.\n", "sendPacket", 2;
  1219. }
  1220.  
  1221. sub sendAuctionCreate {
  1222. my ($self, $price, $buynow, $hours) = @_;
  1223. my $msg = pack("v V2 v", 0x024D, $price, $buynow, $hours);
  1224. $self->sendToServer($msg);
  1225. debug "Sent Auction Create.\n", "sendPacket", 2;
  1226. }
  1227.  
  1228. sub sendAuctionCancel {
  1229. my ($self, $id) = @_;
  1230. my $msg = pack("v V", 0x024E, $id);
  1231. $self->sendToServer($msg);
  1232. debug "Sent Auction Cancel.\n", "sendPacket", 2;
  1233. }
  1234.  
  1235. sub sendAuctionBuy {
  1236. my ($self, $id, $bid) = @_;
  1237. my $msg = pack("v V2", 0x024F, $id, $bid);
  1238. $self->sendToServer($msg);
  1239. debug "Sent Auction Buy.\n", "sendPacket", 2;
  1240. }
  1241.  
  1242. sub sendAuctionItemSearch {
  1243. my ($self, $type, $price, $text, $page) = @_;
  1244. $page = (defined $page) ? $page : 1;
  1245. my $msg = pack("v2 V Z24 v", 0x0251, $type, $price, stringToBytes($text), $page);
  1246. $self->sendToServer($msg);
  1247. debug "Sent Auction Item Search.\n", "sendPacket", 2;
  1248. }
  1249.  
  1250. sub sendAuctionReqMyInfo {
  1251. my ($self, $type) = @_;
  1252. my $msg = pack("v2", 0x025C, $type);
  1253. $self->sendToServer($msg);
  1254. debug "Sent Auction Request My Info.\n", "sendPacket", 2;
  1255. }
  1256.  
  1257. sub sendAuctionMySellStop {
  1258. my ($self, $id) = @_;
  1259. my $msg = pack("v V", 0x025D, $id);
  1260. $self->sendToServer($msg);
  1261. debug "Sent My Sell Stop.\n", "sendPacket", 2;
  1262. }
  1263.  
  1264. sub sendMailReturn {
  1265. my ($self, $mailID, $sender) = @_;
  1266. my $msg = pack("v V Z24", 0x0273, $mailID, stringToBytes($sender));
  1267. $self->sendToServer($msg);
  1268. debug "Sent return mail.\n", "sendPacket", 2;
  1269. }
  1270.  
  1271. sub sendCashShopBuy {
  1272. my ($self, $ID, $amount, $points) = @_;
  1273. my $msg = pack("v v2 V", 0x0288, $ID, $amount, $points);
  1274. $self->sendToServer($msg);
  1275. debug "Sent My Sell Stop.\n", "sendPacket", 2;
  1276. }
  1277.  
  1278. sub sendAutoRevive {
  1279. my ($self, $ID, $amount, $points) = @_;
  1280. my $msg = pack("v", 0x0292);
  1281. $self->sendToServer($msg);
  1282. debug "Sent Auto Revive.\n", "sendPacket", 2;
  1283. }
  1284.  
  1285. sub sendMercenaryCommand {
  1286. my ($self, $command) = @_;
  1287.  
  1288. # 0x0 => COMMAND_REQ_NONE
  1289. # 0x1 => COMMAND_REQ_PROPERTY
  1290. # 0x2 => COMMAND_REQ_DELETE
  1291.  
  1292. my $msg = pack ('v C', 0x029F, $command);
  1293. $self->sendToServer($msg);
  1294. debug "Sent Mercenary Command $command", "sendPacket", 2;
  1295. }
  1296.  
  1297. sub sendMessageIDEncryptionInitialized {
  1298. my $self = shift;
  1299. my $msg = pack("v", 0x02AF);
  1300. $self->sendToServer($msg);
  1301. debug "Sent Message ID Encryption Initialized\n", "sendPacket", 2;
  1302. }
  1303.  
  1304. # has the same effects as rightclicking in quest window
  1305. sub sendQuestState {
  1306. my ($self, $questID, $state) = @_;
  1307. my $msg = pack("v V C", 0x02B6, $questID, $state);
  1308. $self->sendToServer($msg);
  1309. debug "Sent Quest State.\n", "sendPacket", 2;
  1310. }
  1311.  
  1312. sub sendShowEquipPlayer {
  1313. my ($self, $ID) = @_;
  1314. my $msg = pack("v a4", 0x02D6, $ID);
  1315. $self->sendToServer($msg);
  1316. debug "Sent Show Equip Player.\n", "sendPacket", 2;
  1317. }
  1318.  
  1319. sub sendShowEquipTickbox {
  1320. my ($self, $flag) = @_;
  1321. my $msg = pack("v V2", 0x02D8, 0, $flag);
  1322. $self->sendToServer($msg);
  1323. debug "Sent Show Equip Tickbox: flag.\n", "sendPacket", 2;
  1324. }
  1325.  
  1326. sub sendBattlegroundChat {
  1327. my ($self, $message) = @_;
  1328. $message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");
  1329. my $msg = pack("v2 Z*", 0x02DB, length($message)+4, stringToBytes($message));
  1330. $self->sendToServer($msg);
  1331. debug "Sent Battleground chat.\n", "sendPacket", 2;
  1332. }
  1333.  
  1334. sub sendCooking {
  1335. my ($self, $type, $nameID) = @_;
  1336. my $msg = pack("v3", 0x025B, $type, $nameID);
  1337. $self->sendToServer($msg);
  1338. debug "Sent Cooking.\n", "sendPacket", 2;
  1339. }
  1340.  
  1341. sub sendWeaponRefine {
  1342. my ($self, $index) = @_;
  1343. my $msg = pack("v V", 0x0222, $index);
  1344. $self->sendToServer($msg);
  1345. debug "Sent Weapon Refine.\n", "sendPacket", 2;
  1346. }
  1347.  
  1348. # this is different from kRO
  1349. sub sendCaptchaInitiate {
  1350. my ($self) = @_;
  1351. my $msg = pack('v2', 0x07E5, 0x0);
  1352. $self->sendToServer($msg);
  1353. debug "Sending Captcha Initiate\n";
  1354. }
  1355.  
  1356. # captcha packet from kRO::RagexeRE_2009_09_22a
  1357. #0x07e7,32
  1358. # TODO: what is 0x20?
  1359. sub sendCaptchaAnswer {
  1360. my ($self, $answer) = @_;
  1361. my $msg = pack('v2 a4 a24', 0x07E7, 0x20, $accountID, $answer);
  1362. $self->sendToServer($msg);
  1363. }
  1364.  
  1365. sub sendEnteringBuyer {
  1366. my ($self, $ID) = @_;
  1367. my $msg = pack("C*", 0x17, 0x08) . $ID;
  1368. $self->sendToServer($msg);
  1369. debug "Sent Entering Buyer: ".getHex($ID)."\n", "sendPacket", 2;
  1370. }
  1371.  
  1372. sub sendProgress {
  1373. my ($self) = @_;
  1374. my $msg = pack("C*", 0xf1, 0x02);
  1375. $self->sendToServer($msg);
  1376. debug "Sent Progress Bar Finish\n", "sendPacket", 2;
  1377. }
  1378.  
  1379. # 0x0204,18
  1380.  
  1381. 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement