From 174131cdf1162795b1b5f4b5f96b3eb8cfd2ed04 Mon Sep 17 00:00:00 2001 From: ya4ept Date: Thu, 16 Jan 2025 10:08:17 +0300 Subject: [PATCH] Minimum package support 0A16 and 0A17 (#3952) 0A16 - CZ_DYNAMICNPC_CREATE_REQUEST 0A17 - PACKET_ZC_DYNAMICNPC_CREATE_RESULT Added new command: nc - Opens GOLDshop nc - Create NPC by --- src/Commands.pm | 17 +++++++++ src/Network/Receive.pm | 53 ++++++++++++++++++++++------- src/Network/Receive/ServerType0.pm | 1 + src/Network/Receive/kRO/Sakexe_0.pm | 1 + src/Network/Send.pm | 7 ++++ src/Network/Send/ServerType0.pm | 1 + src/Network/Send/kRO/Sakexe_0.pm | 1 + 7 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/Commands.pm b/src/Commands.pm index eeac8efc1f..67d1e0d20d 100644 --- a/src/Commands.pm +++ b/src/Commands.pm @@ -421,6 +421,11 @@ sub initHandlers { [T(""), T("move to nearby portal")], ["stop", T("stop all movement")] ], \&cmdMove], + ['nc', [ + T("NPC Create."), + ["", T("Create NPC by default name 'GOLDPCCAFE'")], + [T(""), T("Create NPC by ")], + ], \&cmdNPCCreateRequest], ['nl', T("List NPCs that are on screen."), \&cmdNPCList], ['openbuyershop', undef, \&cmdOpenBuyerShop], ['openshop', T("Open your vending shop."), \&cmdOpenShop], @@ -8654,4 +8659,16 @@ sub cmdMemorialDungeonDestroy { } } +sub cmdNPCCreateRequest { + if (!$net || $net->getState() != Network::IN_GAME) { + error TF("You must be logged in the game to use this command '%s'\n", shift); + return; + } + + my (undef, $args) = @_; + $args = 'GOLDPCCAFE' if (!defined $args); + + $messageSender->sendNPCCreateRequest($args); +} + 1; diff --git a/src/Network/Receive.pm b/src/Network/Receive.pm index 761520f794..dff697a6ed 100644 --- a/src/Network/Receive.pm +++ b/src/Network/Receive.pm @@ -550,6 +550,15 @@ use constant { MCR_INPROGRESS => 2, }; +# dynamicnpc_create_result +use constant { + DYNAMICNPC_RESULT_SUCCESS => 0x0, + DYNAMICNPC_RESULT_UNKNOWN => 0x1, + DYNAMICNPC_RESULT_UNKNOWNNPC => 0x2, + DYNAMICNPC_RESULT_DUPLICATE => 0x3, + DYNAMICNPC_RESULT_OUTOFTIME => 0x4 +}; + # Display gained exp. # 07F6 .L .L .W .W (ZC_NOTIFY_EXP) # 0ACC .L .Q .W .W (ZC_NOTIFY_EXP2) @@ -4658,7 +4667,7 @@ sub quest_all_list { $offset += $quest_info->{quest_len}; next if !exists $quest->{mission_amount}; - + debug "- Mission amount: $quest->{mission_amount}\n", "info"; for ( my $j = 0 ; $j < $quest->{mission_amount}; $j++ ) { @@ -4911,7 +4920,7 @@ sub quest_update_mission_hunt { goal => $quest_mission->{mob_goal} }); } - + Plugins::callHook('quest_update_mission_hunt_end'); } @@ -4920,7 +4929,7 @@ sub quest_delete { my ($self, $args) = @_; message TF("Quest: %s has been deleted.\n", $quests_lut{$args->{questID}} ? "$quests_lut{$args->{questID}}{title} ($args->{questID})" : $args->{questID}), "info"; delete $questList->{$args->{questID}}; - + Plugins::callHook('quest_delete'); } @@ -4934,7 +4943,7 @@ sub quest_active { , "info"; $questList->{$args->{questID}}->{active} = $args->{active}; - + Plugins::callHook('quest_active'); } @@ -12228,14 +12237,14 @@ sub captcha_upload_request_status { # Status of Macro Reporter sub macro_reporter_status { my ($self, $args) = @_; - my $status = "Unknown"; + my $status = T("Unknown"); if ($args->{status} == MCR_MONITORING) { - $status = "Monitoring"; + $status = T("Monitoring"); } elsif ($args->{status} == MCR_NO_DATA) { - $status = "No Data"; + $status = T("No Data"); } elsif ($args->{status} == MCR_INPROGRESS) { - $status = "In Progress"; + $status = T("In Progress"); } message TF("Macro Reporter - Status: %s \n", $status), "captcha"; @@ -12308,14 +12317,14 @@ sub macro_detector_show { # Status of Macro Detector sub macro_detector_status { my ($self, $args) = @_; - my $status = "Unknown"; + my $status = T("Unknown"); if ($args->{status} == MCD_TIMEOUT) { - $status = "Timeout"; + $status = T("Timeout"); } elsif ($args->{status} == MCD_INCORRECT) { - $status = "Incorrect"; + $status = T("Incorrect"); } elsif ($args->{status} == MCD_GOOD) { - $status = "Correct"; + $status = T("Correct"); } message TF("Macro Detector Status: %s \n", $status), "captcha"; @@ -12402,4 +12411,24 @@ sub gold_pc_cafe_point { debug TF("[gold_pc_cafe_point] isActive=%d, mode=%d, point=%d, playedTime=%d\n", $args->{isActive}, $args->{mode}, $args->{point}, $args->{playedTime}); } +# 0A17 - PACKET_ZC_DYNAMICNPC_CREATE_RESULT +sub dynamicnpc_create_result { + my ($self, $args) = @_; + my $status; + + if ($args->{result} == DYNAMICNPC_RESULT_SUCCESS ) { + $status = T("Success"); + } elsif ($args->{result} == DYNAMICNPC_RESULT_UNKNOWN) { + $status = T("Unknown"); + } elsif ($args->{result} == DYNAMICNPC_RESULT_UNKNOWNNPC) { + $status = T("Unknown NPC"); + } elsif ($args->{result} == DYNAMICNPC_RESULT_DUPLICATE) { + $status = T("Duplicate"); + } elsif ($args->{result} == DYNAMICNPC_RESULT_OUTOFTIME) { + $status = T("Out of time"); + } + + message TF("Dynamic NPC create result - Status: %s\n", $status); +} + 1; diff --git a/src/Network/Receive/ServerType0.pm b/src/Network/Receive/ServerType0.pm index eca03d4ac8..3ff92bea46 100644 --- a/src/Network/Receive/ServerType0.pm +++ b/src/Network/Receive/ServerType0.pm @@ -639,6 +639,7 @@ sub new { '0A12' => ['rodex_open_write', 'Z24 C', [qw(name result)]], # 27 '0A14' => ['rodex_check_player', 'V v2', [qw(char_id class base_level)]], '0A15' => ['gold_pc_cafe_point', 'C2 V2', [qw(isActive mode point playedTime)]], # 12 + '0A17' => ['dynamicnpc_create_result', 'V', [qw(result)]], # 6 '0A18' => ['map_loaded', 'V a3 C2 v C', [qw(syncMapSync coords xSize ySize font sex)]], # 14 '0A1A' => ['roulette_window', 'C V C2 v V3', [qw(result serial stage price additional_item gold silver bronze)]], '0A1C' => ['roulette_info', 'v V a*', [qw(len serial roulette_info)]], diff --git a/src/Network/Receive/kRO/Sakexe_0.pm b/src/Network/Receive/kRO/Sakexe_0.pm index 5f13ab1013..59be1aac8d 100644 --- a/src/Network/Receive/kRO/Sakexe_0.pm +++ b/src/Network/Receive/kRO/Sakexe_0.pm @@ -631,6 +631,7 @@ sub new { '0A12' => ['rodex_open_write', 'Z24 C', [qw(name result)]], # 27 '0A14' => ['rodex_check_player', 'V v2', [qw(char_id class base_level)]], '0A15' => ['gold_pc_cafe_point', 'C2 V2', [qw(isActive mode point playedTime)]], # 12 + '0A17' => ['dynamicnpc_create_result', 'V', [qw(result)]], # 6 '0A18' => ['map_loaded', 'V a3 C2 v C', [qw(syncMapSync coords xSize ySize font sex)]], # 14 '0A1A' => ['roulette_window', 'C V C2 v V3', [qw(result serial stage price additional_item gold silver bronze)]], '0A1C' => ['roulette_info', 'v V a*', [qw(len serial roulette_info)]], diff --git a/src/Network/Send.pm b/src/Network/Send.pm index f7ca93362b..440fbf6471 100644 --- a/src/Network/Send.pm +++ b/src/Network/Send.pm @@ -3538,4 +3538,11 @@ sub sendMemorialDungeonCommand { debug "Sent Memorial Dungeon Command\n", "sendPacket"; } +# 0A16 CZ_DYNAMICNPC_CREATE_REQUEST +sub sendNPCCreateRequest { + my ($self, $name) = @_; + $self->sendToServer($self->reconstruct({switch => 'dynamicnpc_create_request', ID => $name})); + debug "Sent request to create NPC by name: $name\n", "sendPacket", 2; +} + 1; diff --git a/src/Network/Send/ServerType0.pm b/src/Network/Send/ServerType0.pm index a39b1b624c..1ede2b600d 100644 --- a/src/Network/Send/ServerType0.pm +++ b/src/Network/Send/ServerType0.pm @@ -298,6 +298,7 @@ sub new { '0A06' => ['rodex_remove_item', 'a2 v', [qw(ID amount)]], # 6 -- RodexRemoveItem '0A08' => ['rodex_open_write_mail', 'Z24', [qw(name)]], # 26 -- RodexOpenWriteMail '0A13' => ['rodex_checkname', 'Z24', [qw(name)]], # 26 -- RodexCheckName + '0A16' => ['dynamicnpc_create_request', 'Z24', [qw(name)]], # 26 '0A19' => ['roulette_window_open'], '0A1B' => ['roulette_info_request'], '0A1D' => ['roulette_close'], diff --git a/src/Network/Send/kRO/Sakexe_0.pm b/src/Network/Send/kRO/Sakexe_0.pm index c31f6a031f..2a632efbe5 100644 --- a/src/Network/Send/kRO/Sakexe_0.pm +++ b/src/Network/Send/kRO/Sakexe_0.pm @@ -277,6 +277,7 @@ sub new { '0A06' => ['rodex_remove_item', 'a2 v', [qw(ID amount)]], # 6 -- RodexRemoveItem '0A08' => ['rodex_open_write_mail', 'Z24', [qw(name)]], # 26 -- RodexOpenWriteMail '0A13' => ['rodex_checkname', 'Z24', [qw(name)]], # 26 -- RodexCheckName + '0A16' => ['dynamicnpc_create_request', 'Z24', [qw(name)]], # 26 '0A19' => ['roulette_window_open'], '0A1B' => ['roulette_info_request'], '0A1D' => ['roulette_close'],