defmodule Odinsea.Net.Opcodes do @moduledoc """ Packet opcodes for MapleStory GMS v342. Directly ported from Java recvops.properties and sendops.properties. All opcode values MUST match exactly for compatibility with the v342 client. Naming conventions: - Client → Server (recv): cp_* (Client Packet) - Server → Client (send): lp_* (LoopBack Packet) """ # ================================================================================================== # Client → Server (Recv Opcodes) - From recvops.properties # ================================================================================================== # Connection/Security def cp_alive_ack(), do: 0x16 # Login/Account def cp_client_hello(), do: 0x01 def cp_login_password(), do: 0x02 def cp_serverlist_request(), do: 0x04 def cp_charlist_request(), do: 0x05 def cp_serverstatus_request(), do: 0x06 def cp_check_char_name(), do: 0x0E def cp_create_char(), do: 0x12 def cp_create_ultimate(), do: 0x14 def cp_delete_char(), do: 0x15 def cp_exception_log(), do: 0x17 def cp_security_packet(), do: 0x18 def cp_hardware_info(), do: 0x70 def cp_window_focus(), do: 0x71 def cp_char_select(), do: 0x19 def cp_auth_second_password(), do: 0x1A def cp_rsa_key(), do: 0x20 def cp_client_dump_log(), do: 0x1D def cp_create_security_handle(), do: 0x1E def cp_select_world(), do: 0x03 def cp_check_user_limit(), do: 0x06 # Migration/Channel def cp_player_loggedin(), do: 0x0D def cp_change_map(), do: 0x23 def cp_change_channel(), do: 0x24 def cp_enter_cash_shop(), do: 0x25 def cp_enter_pvp(), do: 0x26 def cp_enter_pvp_party(), do: 0x27 def cp_leave_pvp(), do: 0x29 def cp_migrate_in(), do: 0x0D def cp_enter_mts(), do: 0xB4 # Player Movement/Actions def cp_move_player(), do: 0x2A def cp_cancel_chair(), do: 0x2C def cp_use_chair(), do: 0x2D def cp_close_range_attack(), do: 0x2F def cp_ranged_attack(), do: 0x30 def cp_magic_attack(), do: 0x31 def cp_passive_energy(), do: 0x32 def cp_take_damage(), do: 0x34 def cp_pvp_attack(), do: 0x35 def cp_general_chat(), do: 0x36 def cp_close_chalkboard(), do: 0x37 def cp_face_expression(), do: 0x38 def cp_face_android(), do: 0x39 def cp_use_itemeffect(), do: 0x3A def cp_wheel_of_fortune(), do: 0x3B def cp_char_info_request(), do: 0x75 def cp_spawn_pet(), do: 0x76 def cp_cancel_debuff(), do: 0x78 def cp_change_map_special(), do: 0x79 def cp_use_inner_portal(), do: 0x7B def cp_trock_add_map(), do: 0x7C # NPC Interaction def cp_npc_talk(), do: 0x40 def cp_npc_move(), do: 0x41 # NPC animation/movement (added for compatibility) def cp_npc_talk_more(), do: 0x42 def cp_npc_shop(), do: 0x43 def cp_storage(), do: 0x44 def cp_use_hired_merchant(), do: 0x45 def cp_merch_item_store(), do: 0x47 def cp_duey_action(), do: 0x48 def cp_mech_cancel(), do: 0x49 def cp_owl(), do: 0x4A def cp_owl_warp(), do: 0x4B # Inventory/Items def cp_item_sort(), do: 0x4D def cp_item_gather(), do: 0x4E def cp_item_move(), do: 0x4F def cp_move_bag(), do: 0x50 def cp_switch_bag(), do: 0x51 def cp_use_item(), do: 0x53 def cp_cancel_item_effect(), do: 0x54 def cp_use_summon_bag(), do: 0x56 def cp_pet_food(), do: 0x57 def cp_use_mount_food(), do: 0x58 def cp_use_scripted_npc_item(), do: 0x59 def cp_use_recipe(), do: 0x5A def cp_use_cash_item(), do: 0x5B def cp_use_catch_item(), do: 0x5D def cp_use_skill_book(), do: 0x5E def cp_use_owl_minerva(), do: 0x60 def cp_use_tele_rock(), do: 0x61 def cp_use_return_scroll(), do: 0x62 def cp_use_upgrade_scroll(), do: 0x63 def cp_use_flag_scroll(), do: 0x64 def cp_use_equip_scroll(), do: 0x65 def cp_use_potential_scroll(), do: 0x66 def cp_use_bag(), do: 0x68 def cp_use_magnify_glass(), do: 0x69 def cp_item_pickup(), do: 0x10C # Stats/Skills def cp_distribute_ap(), do: 0x6A def cp_auto_assign_ap(), do: 0x6B def cp_heal_over_time(), do: 0x6C def cp_distribute_sp(), do: 0x6E def cp_special_move(), do: 0x6F def cp_cancel_buff(), do: 0x70 def cp_skill_effect(), do: 0x71 def cp_meso_drop(), do: 0x72 def cp_give_fame(), do: 0x73 def cp_skill_macro(), do: 0x84 def cp_change_keymap(), do: 0xB2 # Anti-Cheat def cp_user_anti_macro_item_use_request(), do: 0x7D def cp_user_anti_macro_skill_use_request(), do: 0x7E def cp_user_anti_macro_question_result(), do: 0x7F # Quests def cp_quest_action(), do: 0x81 def cp_reward_item(), do: 0x86 def cp_update_quest(), do: 0x142 def cp_quest_item(), do: 0x143 def cp_use_item_quest(), do: 0x144 # Crafting def cp_item_maker(), do: 0x87 def cp_repair_all(), do: 0x88 def cp_repair(), do: 0x89 def cp_solomon(), do: 0x8C def cp_gach_exp(), do: 0x8D def cp_craft_done(), do: 0xC8 def cp_craft_effect(), do: 0xC9 def cp_craft_make(), do: 0xCA # Profession/Harvesting def cp_profession_info(), do: 0x97 def cp_use_pot(), do: 0x98 def cp_clear_pot(), do: 0x99 def cp_feed_pot(), do: 0x9A def cp_cure_pot(), do: 0x9B def cp_reward_pot(), do: 0x9C def cp_use_treasuer_chest(), do: 0x95 def cp_start_harvest(), do: 0x12E def cp_stop_harvest(), do: 0x12F def cp_make_extractor(), do: 0x114 # Social def cp_partychat(), do: 0xA0 def cp_party_chat(), do: cp_partychat() # Alias for readability def cp_whisper(), do: 0xA1 def cp_messenger(), do: 0xA2 def cp_player_interaction(), do: 0xA3 def cp_party_operation(), do: 0xA4 def cp_deny_party_request(), do: 0xA5 def cp_expedition_operation(), do: 0xA6 def cp_expedition_listing(), do: 0xA7 def cp_guild_operation(), do: 0xA8 def cp_deny_guild_request(), do: 0xA9 def cp_admin_command(), do: 0xAA def cp_admin_log(), do: 0xAB def cp_buddylist_modify(), do: 0xAC def cp_note_action(), do: 0xAD def cp_alliance_operation(), do: 0xBA def cp_deny_alliance_request(), do: 0xBB # Family def cp_request_family(), do: 0xBC def cp_open_family(), do: 0xBD def cp_family_operation(), do: 0xBE def cp_delete_junior(), do: 0xBF def cp_delete_senior(), do: 0xC0 def cp_accept_family(), do: 0xC1 def cp_use_family(), do: 0xC2 def cp_family_precept(), do: 0xC3 def cp_family_summon(), do: 0xC4 def cp_cygnus_summon(), do: 0xC5 def cp_aran_combo(), do: 0xC6 # Misc def cp_follow_request(), do: 0x8E def cp_follow_reply(), do: 0x91 def cp_auto_follow_reply(), do: 0x92 def cp_report(), do: 0x94 def cp_pvp_respawn(), do: 0x9D def cp_use_door(), do: 0xAF def cp_use_mech_door(), do: 0xB0 def cp_rps_game(), do: 0xB3 def cp_ring_action(), do: 0xB5 def cp_bbs_operation(), do: 0xCD def cp_transform_player(), do: 0xD2 def cp_xmas_surprise(), do: 0xD3 def cp_game_poll(), do: 0xD4 # Pets def cp_move_pet(), do: 0xD7 def cp_pet_chat(), do: 0xD8 def cp_pet_command(), do: 0xD9 def cp_pet_loot(), do: 0xDA def cp_pet_auto_pot(), do: 0xDB # Summons def cp_move_summon(), do: 0xDF def cp_summon_attack(), do: 0xE0 def cp_damage_summon(), do: 0xE1 def cp_sub_summon(), do: 0xE2 def cp_remove_summon(), do: 0xE3 def cp_pvp_summon(), do: 0xE4 # Dragon/Android def cp_move_dragon(), do: 0xE7 def cp_move_android(), do: 0xEA def cp_quick_slot(), do: 0xED def cp_pam_song(), do: 0xF0 # Mobs/Life def cp_move_life(), do: 0xF7 def cp_auto_aggro(), do: 0xF8 def cp_friendly_damage(), do: 0xFB def cp_monster_bomb(), do: 0xFC def cp_hypnotize_dmg(), do: 0xFD def cp_mob_skill_delay_end(), do: 0xFE def cp_mob_bomb(), do: 0xFF def cp_mob_node(), do: 0x100 def cp_display_node(), do: 0x101 def cp_npc_action(), do: 0x106 # Reactors def cp_damage_reactor(), do: 0x10F def cp_touch_reactor(), do: 0x110 # Events/Games def cp_snowball(), do: 0x119 def cp_left_knock_back(), do: 0x11A def cp_coconut(), do: 0x11B def cp_monster_carnival(), do: 0x125 def cp_ship_object(), do: 0x127 def cp_party_search_start(), do: 0x129 def cp_party_search_stop(), do: 0x12A # Cash Shop def cp_cs_update(), do: 0x135 def cp_buy_cs_item(), do: 0x136 def cp_coupon_code(), do: 0x137 # MTS def cp_mapletv(), do: 0x140 def cp_touching_mts(), do: 0x159 def cp_mts_tab(), do: 0x15A # Custom (server-specific) def cp_inject_packet(), do: 0x5002 def cp_set_code_page(), do: 0x5003 # Special (negative offsets from other opcodes) def cp_change_set(), do: 0x7FFE def cp_get_book_info(), do: 0x7FFA def cp_reissue_medal(), do: 0x7FFB def cp_click_reactor(), do: 0x7FFC # ================================================================================================== # Server → Client (Send Opcodes) - From sendops.properties # ================================================================================================== # General def lp_alive_req(), do: 0x0D # Login def lp_login_status(), do: 0x01 def lp_serverstatus(), do: 0x03 def lp_serverlist(), do: 0x06 def lp_charlist(), do: 0x07 def lp_server_ip(), do: 0x08 def lp_char_name_response(), do: 0x09 def lp_add_new_char_entry(), do: 0x0A def lp_delete_char_response(), do: 0x0B def lp_change_channel(), do: 0x0C def lp_cs_use(), do: 0x0E def lp_channel_selected(), do: 0x10 def lp_relog_response(), do: 0x12 def lp_rsa_key(), do: 0x13 def lp_enable_recommended(), do: 0x15 def lp_send_recommended(), do: 0x16 def lp_login_auth(), do: 0x17 def lp_secondpw_error(), do: 0x18 # Inventory/Stats def lp_modify_inventory_item(), do: 0x19 def lp_update_inventory_slot(), do: 0x1A def lp_update_stats(), do: 0x1B def lp_give_buff(), do: 0x1C def lp_cancel_buff(), do: 0x1D def lp_temp_stats(), do: 0x1E def lp_temp_stats_reset(), do: 0x1F def lp_update_skills(), do: 0x20 def lp_fame_response(), do: 0x22 def lp_show_status_info(), do: 0x23 def lp_show_notes(), do: 0x24 def lp_trock_locations(), do: 0x25 def lp_anti_macro_result(), do: 0x26 def lp_update_mount(), do: 0x2B def lp_show_quest_completion(), do: 0x2C def lp_send_title_box(), do: 0x2D def lp_fishing_store(), do: 0x2E def lp_use_skill_book(), do: 0x2F def lp_sp_reset(), do: 0x30 def lp_report(), do: 0x31 def lp_finish_sort(), do: 0x33 def lp_finish_gather(), do: 0x34 def lp_char_info(), do: 0x37 # Social/Party/Guild def lp_party_operation(), do: 0x38 def lp_expedition_operation(), do: 0x3A def lp_buddylist(), do: 0x3B def lp_guild_operation(), do: 0x3D def lp_alliance_operation(), do: 0x3E # Map Effects/Environment def lp_spawn_portal(), do: 0x3F def lp_mech_portal(), do: 0x40 def lp_servermessage(), do: 0x41 def lp_pigmi_reward(), do: 0x42 def lp_owl_of_minerva(), do: 0x43 def lp_engage_request(), do: 0x45 def lp_engage_result(), do: 0x46 def lp_yellow_chat(), do: 0x4A def lp_shop_discount(), do: 0x4B def lp_catch_mob(), do: 0x4C def lp_fishing_board_update(), do: 0x55 def lp_bbs_operation(), do: 0x56 def lp_avatar_mega(), do: 0x58 def lp_player_npc(), do: 0x5D # Special Systems def lp_energy(), do: 0x69 def lp_ghost_point(), do: 0x6A def lp_ghost_status(), do: 0x6B def lp_fairy_pend_msg(), do: 0x6C # Family def lp_send_pedigree(), do: 0x6D def lp_open_family(), do: 0x6E def lp_family_message(), do: 0x6F def lp_family_invite(), do: 0x70 def lp_family_junior(), do: 0x71 def lp_senior_message(), do: 0x72 def lp_family(), do: 0x73 def lp_rep_increase(), do: 0x74 def lp_family_loggedin(), do: 0x75 def lp_family_buff(), do: 0x76 def lp_family_use_request(), do: 0x77 def lp_level_update(), do: 0x78 def lp_marriage_update(), do: 0x79 def lp_job_update(), do: 0x7A def lp_pendant_slot(), do: 0x7B # Misc UI/Messages def lp_follow_request(), do: 0x7C def lp_top_msg(), do: 0x7E def lp_mid_msg(), do: 0x7F def lp_clear_mid_msg(), do: 0x80 def lp_update_jaguar(), do: 0x82 def lp_ultimate_explorer(), do: 0x84 def lp_gm_police(), do: 0x88 def lp_pam_song(), do: 0x89 def lp_profession_info(), do: 0x8B def lp_item_pot(), do: 0x8D def lp_skill_macro(), do: 0x8F # Warps/Shops def lp_warp_to_map(), do: 0x90 def lp_mts_open(), do: 0x91 def lp_cs_open(), do: 0x92 def lp_login_welcome(), do: 0x94 def lp_server_blocked(), do: 0x97 def lp_pvp_blocked(), do: 0x98 # Effects def lp_show_equip_effect(), do: 0x99 def lp_multichat(), do: 0x9A def lp_whisper(), do: 0x9B def lp_boss_env(), do: 0x9D def lp_move_env(), do: 0x9E def lp_update_env(), do: 0x9F def lp_map_effect(), do: 0xA1 def lp_cash_song(), do: 0xA2 def lp_gm_effect(), do: 0xA3 def lp_ox_quiz(), do: 0xA4 def lp_gmevent_instructions(), do: 0xA5 def lp_clock(), do: 0xA6 def lp_boat_eff(), do: 0xA7 def lp_boat_effect(), do: 0xA8 def lp_stop_clock(), do: 0xAC # Mini-games def lp_pyramid_update(), do: 0xAF def lp_pyramid_result(), do: 0xB0 def lp_quick_slot(), do: 0xB1 def lp_move_platform(), do: 0xB2 # PVP def lp_pvp_info(), do: 0xB6 def lp_public_npc(), do: 0xB7 # Players def lp_spawn_player(), do: 0xB8 def lp_remove_player_from_map(), do: 0xB9 def lp_chattext(), do: 0xBA def lp_chalkboard(), do: 0xBC def lp_update_char_box(), do: 0xBD def lp_show_scroll_effect(), do: 0xBF def lp_show_potential_effect(), do: 0xC1 def lp_show_potential_reset(), do: 0xC2 def lp_player_damaged(), do: 0xC3 def lp_pvp_attack(), do: 0xC4 def lp_pvp_mist(), do: 0xC5 def lp_pvp_cool(), do: 0xC6 def lp_tesla_triangle(), do: 0xC7 def lp_fishing_caught(), do: 0xC8 def lp_pams_song(), do: 0xC9 def lp_follow_effect(), do: 0xCA def lp_craft_effect(), do: 0xCC def lp_craft_complete(), do: 0xCD def lp_harvested(), do: 0xCE # Pets def lp_spawn_pet(), do: 0xD1 def lp_move_pet(), do: 0xD4 def lp_pet_chat(), do: 0xD5 def lp_pet_namechange(), do: 0xD6 def lp_pet_update(), do: 0xD7 def lp_pet_command(), do: 0xD8 # Dragon/Android def lp_dragon_spawn(), do: 0xD9 def lp_dragon_move(), do: 0xDA def lp_dragon_remove(), do: 0xDB def lp_android_spawn(), do: 0xDC def lp_android_move(), do: 0xDD def lp_android_emotion(), do: 0xDE def lp_android_remove(), do: 0xDF def lp_android_deactivated(), do: 0xE0 # Player Actions def lp_move_player(), do: 0xE2 def lp_close_range_attack(), do: 0xE4 def lp_ranged_attack(), do: 0xE5 def lp_magic_attack(), do: 0xE6 def lp_energy_attack(), do: 0xE7 def lp_skill_effect(), do: 0xE8 def lp_cancel_skill_effect(), do: 0xEA def lp_damage_player(), do: 0xEB def lp_facial_expression(), do: 0xEC def lp_show_item_effect(), do: 0xED def lp_show_chair(), do: 0xF0 def lp_update_char_look(), do: 0xF1 def lp_show_foreign_effect(), do: 0xF2 def lp_give_foreign_buff(), do: 0xF3 def lp_cancel_foreign_buff(), do: 0xF4 def lp_update_partymember_hp(), do: 0xF5 def lp_load_guild_name(), do: 0xF6 def lp_load_guild_icon(), do: 0xF7 def lp_load_team(), do: 0xF8 def lp_show_harvest(), do: 0xF9 def lp_pvp_hp(), do: 0xFA def lp_cancel_chair(), do: 0xFC def lp_show_item_gain_inchat(), do: 0xFF def lp_current_map_warp(), do: 0x100 def lp_mesobag_success(), do: 0x101 def lp_mesobag_failure(), do: 0x102 def lp_update_quest_info(), do: 0x104 def lp_buff_bar(), do: 0x108 def lp_pet_flag_change(), do: 0x10A # Repair def lp_repair_window(), do: 0x115 def lp_cygnus_intro_lock(), do: 0x116 def lp_cygnus_intro_disable_ui(), do: 0x117 def lp_summon_hint(), do: 0x118 def lp_summon_hint_msg(), do: 0x119 def lp_aran_combo(), do: 0x11A def lp_aran_combo_recharge(), do: 0x11B def lp_game_poll_reply(), do: 0x11E def lp_spouse_message(), do: 0x11F def lp_follow_move(), do: 0x124 def lp_follow_msg(), do: 0x125 def lp_game_poll_question(), do: 0x127 def lp_create_ultimate(), do: 0x128 def lp_harvest_message(), do: 0x129 def lp_open_bag(), do: 0x12B def lp_dragon_blink(), do: 0x12D def lp_pvp_icegage(), do: 0x12E def lp_cooldown(), do: 0x12F # Summons def lp_spawn_summon(), do: 0x131 def lp_remove_summon(), do: 0x132 def lp_move_summon(), do: 0x133 def lp_summon_attack(), do: 0x134 def lp_pvp_summon(), do: 0x135 def lp_summon_skill(), do: 0x136 def lp_damage_summon(), do: 0x137 # Monsters def lp_spawn_monster(), do: 0x13A def lp_kill_monster(), do: 0x13B def lp_spawn_monster_control(), do: 0x13C def lp_move_monster(), do: 0x13D def lp_move_monster_response(), do: 0x13E def lp_apply_monster_status(), do: 0x140 def lp_cancel_monster_status(), do: 0x141 def lp_mob_to_mob_damage(), do: 0x142 def lp_damage_monster(), do: 0x144 def lp_show_monster_hp(), do: 0x148 def lp_show_magnet(), do: 0x149 def lp_catch_monster(), do: 0x14A def lp_monster_properties(), do: 0x14D def lp_remove_talk_monster(), do: 0x14E def lp_talk_monster(), do: 0x14F # NPCs def lp_spawn_npc(), do: 0x156 def lp_remove_npc(), do: 0x157 def lp_spawn_npc_request_controller(), do: 0x158 def lp_npc_action(), do: 0x159 def lp_npc_set_script(), do: 0x15F # Merchants def lp_spawn_hired_merchant(), do: 0x161 def lp_destroy_hired_merchant(), do: 0x162 def lp_update_hired_merchant(), do: 0x163 # Map Objects def lp_drop_item_from_mapobject(), do: 0x165 def lp_remove_item_from_map(), do: 0x167 def lp_spawn_mist(), do: 0x16B def lp_remove_mist(), do: 0x16C def lp_spawn_door(), do: 0x16D def lp_remove_door(), do: 0x16E def lp_mech_door_spawn(), do: 0x16F def lp_mech_door_remove(), do: 0x170 # Reactors def lp_reactor_hit(), do: 0x171 def lp_reactor_spawn(), do: 0x173 def lp_reactor_destroy(), do: 0x174 def lp_spawn_extractor(), do: 0x176 def lp_remove_extractor(), do: 0x177 # Mini-games/Events def lp_roll_snowball(), do: 0x178 def lp_hit_snowball(), do: 0x179 def lp_snowball_message(), do: 0x17A def lp_left_knock_back(), do: 0x17B def lp_hit_coconut(), do: 0x17C def lp_coconut_score(), do: 0x17D def lp_monster_carnival_start(), do: 0x180 def lp_monster_carnival_obtained_cp(), do: 0x181 def lp_monster_carnival_party_cp(), do: 0x182 def lp_monster_carnival_summon(), do: 0x183 def lp_monster_carnival_died(), do: 0x186 def lp_chaos_horntail_shrine(), do: 0x18E def lp_chaos_zakum_shrine(), do: 0x18F def lp_horntail_shrine(), do: 0x190 def lp_english_quiz(), do: 0x191 # PVP (continued) def lp_pvp_type(), do: 0x192 def lp_pvp_transform(), do: 0x193 def lp_pvp_enabled(), do: 0x195 def lp_pvp_score(), do: 0x196 def lp_pvp_result(), do: 0x197 def lp_pvp_team(), do: 0x198 def lp_pvp_scoreboard(), do: 0x199 def lp_pvp_points(), do: 0x19B def lp_pvp_killed(), do: 0x19C def lp_pvp_mode(), do: 0x19D def lp_pvp_iceknight(), do: 0x19E def lp_capture_flags(), do: 0x19F def lp_capture_position(), do: 0x1A0 def lp_capture_reset(), do: 0x1A1 # NPC/Shop Interactions def lp_npc_talk(), do: 0x1A3 def lp_open_npc_shop(), do: 0x1A5 def lp_confirm_shop_transaction(), do: 0x1A6 def lp_open_storage(), do: 0x1A9 def lp_merch_item_msg(), do: 0x1AA def lp_merch_item_store(), do: 0x1AB def lp_rps_game(), do: 0x1AC def lp_messenger(), do: 0x1AD def lp_player_interaction(), do: 0x1AE def lp_duey(), do: 0x1B6 # Cash Shop def lp_cs_update(), do: 0x1B8 def lp_cs_operation(), do: 0x1B9 def lp_xmas_surprise(), do: 0x1BD # Input def lp_keymap(), do: 0x1C5 def lp_pet_auto_hp(), do: 0x1C6 def lp_pet_auto_mp(), do: 0x1C7 # TV/MTS def lp_start_tv(), do: 0x1CD def lp_remove_tv(), do: 0x1CE def lp_enable_tv(), do: 0x1CF def lp_vicious_hammer(), do: 0x1D3 def lp_get_mts_tokens(), do: 0x1D7 def lp_mts_operation(), do: 0x1D8 # Custom (server-specific) def lp_damage_skin(), do: 0x5000 def lp_open_website(), do: 0x5001 def lp_perfect_pitch(), do: 0x5002 def lp_get_code_page(), do: 0x5003 # Special (calculated/custom offsets) def lp_block_portal(), do: 0x7FFA def lp_ariant_scoreboard(), do: 0x7FFB def lp_player_hint(), do: 0x7FFC def lp_ariant_thing(), do: 0x7FFD def lp_ariant_pq_start(), do: 0x7FAE def lp_npc_confirm(), do: 0x7FBE def lp_pin_assigned(), do: 0x7FCE def lp_all_charlist(), do: 0x7FDE def lp_get_card(), do: 0x7FEE def lp_card_set(), do: 0x7FEE def lp_book_stats(), do: 0x7FEA def lp_book_info(), do: 0x7FEB def lp_party_search(), do: 0x7FEC def lp_member_search(), do: 0x7FED # ================================================================================================== # Helper Functions # ================================================================================================== @doc """ Returns a human-readable name for a given opcode value. Useful for debugging and logging. """ def name_for(opcode) when is_integer(opcode) do case opcode do # Client opcodes (common ones for debugging) 0x01 -> "CP_CLIENT_HELLO" 0x02 -> "CP_LOGIN_PASSWORD" 0x0D -> "CP_PLAYER_LOGGEDIN" 0x19 -> "CP_CHAR_SELECT" 0x23 -> "CP_CHANGE_MAP" 0x24 -> "CP_CHANGE_CHANNEL" 0x2A -> "CP_MOVE_PLAYER" 0x36 -> "CP_GENERAL_CHAT" 0x40 -> "CP_NPC_TALK" 0xA0 -> "CP_PARTYCHAT" 0xA1 -> "CP_WHISPER" # Server opcodes (common ones for debugging) 0x01 -> "LP_LOGIN_STATUS" 0x06 -> "LP_SERVERLIST" 0x07 -> "LP_CHARLIST" 0x0D -> "LP_ALIVE_REQ" 0xB8 -> "LP_SPAWN_PLAYER" 0xB9 -> "LP_REMOVE_PLAYER_FROM_MAP" 0xBA -> "LP_CHATTEXT" 0xE2 -> "LP_MOVE_PLAYER" 0x9A -> "LP_MULTICHAT" 0x9B -> "LP_WHISPER" 0x1A3 -> "LP_NPC_TALK" _ -> "UNKNOWN_0x#{Integer.to_string(opcode, 16) |> String.upcase()}" end end @doc """ Validates if an opcode is a known client packet. """ def valid_client_opcode?(opcode) when is_integer(opcode) do opcode in [ # Add all valid client opcodes here for validation 0x01, 0x02, 0x04, 0x05, 0x06, 0x0D, 0x0E, 0x12, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1D, 0x1E, 0x20, 0x23, 0x24, 0x25, 0x26, 0x27, 0x29, 0x2A, 0x2C, 0x2D, 0x2F, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x40, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5D, 0x5E, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x75, 0x76, 0x78, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x81, 0x84, 0x86, 0x87, 0x88, 0x89, 0x8C, 0x8D, 0x8E, 0x91, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAF, 0xB0, 0xB2, 0xB3, 0xB4, 0xB5, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC8, 0xC9, 0xCA, 0xCD, 0xD2, 0xD3, 0xD4, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE7, 0xEA, 0xED, 0xF0, 0xF7, 0xF8, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 0x106, 0x10C, 0x10F, 0x110, 0x114, 0x119, 0x11A, 0x11B, 0x125, 0x127, 0x129, 0x12A, 0x12E, 0x12F, 0x135, 0x136, 0x137, 0x140, 0x142, 0x143, 0x144, 0x159, 0x15A ] end def valid_client_opcode?(_), do: false end