diff --git a/src/Base/Ragnarok/AccountServer.pm b/src/Base/Ragnarok/AccountServer.pm index 725e4ca8d1..c973c73c35 100644 --- a/src/Base/Ragnarok/AccountServer.pm +++ b/src/Base/Ragnarok/AccountServer.pm @@ -104,50 +104,54 @@ sub master_login { ip => $ip, port => $charServer->getPort, name => $charServer->getName, + state => 0, users => $charServer->getPlayersCount, - display => 5, # don't show number of players + display => 0, # don't show number of players + property => 0, ip_port => $ip . ':' . $charServer->getPort, + unknown => 0, }; } - + $client->send($self->{recvPacketParser}->reconstruct({ switch => 'account_server_info', # maybe sessionstore should store sessionID as bytes? sessionID => pack('V', $session{sessionID}), accountID => $session{accountID}, sessionID2 => pack('V', $session{sessionID2}), + lastLoginIP => 0, + lastLoginTime => time, accountSex => $session{sex}, + iAccountSID => 0, servers => \@servers, })); - $client->close(); } elsif ($result == ACCOUNT_NOT_FOUND) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::REFUSE_INVALID_ID, })); - $client->close(); } elsif ($result == PASSWORD_INCORRECT) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::REFUSE_INVALID_PASSWD, })); - $client->close(); } elsif ($result == ACCOUNT_BANNED) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::REFUSE_NOT_CONFIRMED, })); - $client->close(); } elsif ($result == SERVER_REFUSED) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::ACCEPT_ID_PASSWD, })); - $client->close(); } else { die "Unexpected result $result."; } + + sleep 1; + $client->close(); } sub token_login { @@ -167,6 +171,7 @@ sub token_login { switch => 'login_error', type => Network::Receive::ServerType0::ACCEPT_ID_PASSWD, })); + sleep 1; $client->close(); } }; @@ -187,11 +192,12 @@ sub token_login { ip => $ip, port => $charServer->getPort, name => $charServer->getName, - users => $charServer->getPlayersCount, state => 0, + users => $charServer->getPlayersCount, property => 0, + display => 0, # don't show number of players + ip_port => $ip . ':' . $charServer->getPort, unknown => 0, - display => 5, # don't show number of players }; } @@ -204,37 +210,36 @@ sub token_login { lastLoginIP => 0, lastLoginTime => time, accountSex => $session{sex}, + iAccountSID => 0, servers => \@servers, })); - $client->close(); } elsif ($result == ACCOUNT_NOT_FOUND) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::REFUSE_INVALID_ID, })); - $client->close(); } elsif ($result == PASSWORD_INCORRECT) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::REFUSE_INVALID_PASSWD, })); - $client->close(); } elsif ($result == ACCOUNT_BANNED) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::REFUSE_NOT_CONFIRMED, })); - $client->close(); } elsif ($result == SERVER_REFUSED) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'login_error', type => Network::Receive::ServerType0::ACCEPT_ID_PASSWD, })); - $client->close(); } else { die "Unexpected result $result."; } + sleep 1; + $client->close(); + $session{state} = 'About to select character'; } diff --git a/src/Base/Ragnarok/CharServer.pm b/src/Base/Ragnarok/CharServer.pm index aa8b2251e6..d1136cc676 100644 --- a/src/Base/Ragnarok/CharServer.pm +++ b/src/Base/Ragnarok/CharServer.pm @@ -176,10 +176,12 @@ sub char_login { mapName => $charInfo->{map}, mapIP => $host, mapPort => $self->{mapServer}->getPort, + mapUrl => $host . ':' . $self->{mapServer}->getPort })); } } } + sleep 1; $client->close(); } diff --git a/src/Network/Receive/kRO/RagexeRE_2014_10_22b.pm b/src/Network/Receive/kRO/RagexeRE_2014_10_22b.pm index aaf5a86bf1..d2dab0f548 100644 --- a/src/Network/Receive/kRO/RagexeRE_2014_10_22b.pm +++ b/src/Network/Receive/kRO/RagexeRE_2014_10_22b.pm @@ -18,8 +18,16 @@ use strict; use base qw(Network::Receive::kRO::RagexeRE_2014_09_17c); sub new { - my ($class) = @_; - return $class->SUPER::new(@_); + my ($class) = @_; + my $self = $class->SUPER::new(@_); + + my %handlers = qw( + map_loaded 0A18 + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + + return $self; } 1; diff --git a/src/Network/Receive/kRO/RagexeRE_2016_04_14b.pm b/src/Network/Receive/kRO/RagexeRE_2016_04_14b.pm index efa293aae6..fb4e073720 100644 --- a/src/Network/Receive/kRO/RagexeRE_2016_04_14b.pm +++ b/src/Network/Receive/kRO/RagexeRE_2016_04_14b.pm @@ -18,7 +18,15 @@ use base qw(Network::Receive::kRO::RagexeRE_2016_03_02b); sub new { my ($class) = @_; - return $class->SUPER::new(@_); + my $self = $class->SUPER::new(@_); + + my %handlers = qw( + map_loaded 02EB + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + + return $self; } 1; diff --git a/src/Network/Receive/kRO/RagexeRE_2017_04_12a.pm b/src/Network/Receive/kRO/RagexeRE_2017_04_12a.pm index 2cd31cc27a..72df25824b 100644 --- a/src/Network/Receive/kRO/RagexeRE_2017_04_12a.pm +++ b/src/Network/Receive/kRO/RagexeRE_2017_04_12a.pm @@ -18,7 +18,16 @@ use base qw(Network::Receive::kRO::RagexeRE_2017_02_08b); sub new { my ($class) = @_; - return $class->SUPER::new(@_); + my $self = $class->SUPER::new(@_); + + my %handlers = qw( + account_server_info 0AC4 + received_character_ID_and_Map 0AC5 + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + + return $self; } 1; diff --git a/src/Network/Receive/kRO/RagexeRE_2018_11_21.pm b/src/Network/Receive/kRO/RagexeRE_2018_11_21.pm index 13d982fd90..821c744aba 100644 --- a/src/Network/Receive/kRO/RagexeRE_2018_11_21.pm +++ b/src/Network/Receive/kRO/RagexeRE_2018_11_21.pm @@ -28,6 +28,12 @@ sub new { $self->{packet_list}{$_} = $packets{$_} for keys %packets; + my %handlers = qw( + inventory_expansion_result 0B18 + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + return $self; } diff --git a/src/Network/Receive/kRO/RagexeRE_2021_11_03.pm b/src/Network/Receive/kRO/RagexeRE_2021_11_03.pm index a3b784dbe5..79468037e4 100644 --- a/src/Network/Receive/kRO/RagexeRE_2021_11_03.pm +++ b/src/Network/Receive/kRO/RagexeRE_2021_11_03.pm @@ -19,6 +19,12 @@ sub new { my ($class) = @_; my $self = $class->SUPER::new(@_); + my %handlers = qw( + received_characters 0B72 + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + return $self; } diff --git a/src/Network/Receive/kRO/Sakexe_2007_10_02a.pm b/src/Network/Receive/kRO/Sakexe_2007_10_02a.pm index f8f1a9b1b5..42f7512754 100644 --- a/src/Network/Receive/kRO/Sakexe_2007_10_02a.pm +++ b/src/Network/Receive/kRO/Sakexe_2007_10_02a.pm @@ -22,7 +22,15 @@ use base qw(Network::Receive::kRO::Sakexe_2007_05_07a); sub new { my ($class) = @_; - return $class->SUPER::new(@_); + my $self = $class->SUPER::new(@_); + + my %handlers = qw( + account_id 0283 + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + + return $self; } 1; \ No newline at end of file diff --git a/src/Network/Receive/kRO/Sakexe_2008_01_02a.pm b/src/Network/Receive/kRO/Sakexe_2008_01_02a.pm index c0ec0a3835..bac1a19ea5 100644 --- a/src/Network/Receive/kRO/Sakexe_2008_01_02a.pm +++ b/src/Network/Receive/kRO/Sakexe_2008_01_02a.pm @@ -22,7 +22,15 @@ use base qw(Network::Receive::kRO::Sakexe_2007_11_27a); sub new { my ($class) = @_; - return $class->SUPER::new(@_); + my $self = $class->SUPER::new(@_); + + my %handlers = qw( + map_loaded 02EB + ); + + $self->{packet_lut}{$_} = $handlers{$_} for keys %handlers; + + return $self; } 1; \ No newline at end of file diff --git a/src/Network/XKore2/MapServer.pm b/src/Network/XKore2/MapServer.pm index f93d8a0729..df499b628c 100644 --- a/src/Network/XKore2/MapServer.pm +++ b/src/Network/XKore2/MapServer.pm @@ -184,7 +184,6 @@ sub map_loaded { $self->send_inventory($client, $char); $self->send_ground_items($client); $self->send_portals($client); - $self->send_npcs($client); $self->send_monsters($client); $self->send_npcs($client); $self->send_pets($client); @@ -454,7 +453,47 @@ sub send_player_info { my ($self, $client, $char) = @_; my $data = undef; + # Send skill information + if($self->{packet_lut}{skills_list} eq "0B32") { + foreach my $ID (@skillsID) { + $data .= pack('v V v3 C v', + $char->{skills}{$ID}{ID}, $char->{skills}{$ID}{targetType}, + $char->{skills}{$ID}{lv}, $char->{skills}{$ID}{sp}, + $char->{skills}{$ID}{range}, $char->{skills}{$ID}{up}, + $char->{skills}{$ID}{lv2}); + } + $data = pack('C2 v', 0x32, 0x0B, length($data) + 4) . $data; + } else { + foreach my $ID (@skillsID) { + $data .= pack('v2 x2 v3 a24 C', + $char->{skills}{$ID}{ID}, $char->{skills}{$ID}{targetType}, + $char->{skills}{$ID}{lv}, $char->{skills}{$ID}{sp}, + $char->{skills}{$ID}{range}, $ID, $char->{skills}{$ID}{up}); + } + $data = pack('C2 v', 0x0F, 0x01, length($data) + 4) . $data; + } + $client->send($data); + + # Send weapon/shield appearance + $data .= pack('C2 a4 C v2', 0xD7, 0x01, $char->{ID}, 2, $char->{weapon}, $char->{shield}); + + # Send attack range + $data = pack('C2 v', 0x3A, 0x01, $char->{attack_range}); + + # More stats + $data = pack('C2 v V', 0xB0, 0x00, 0, $char->{walk_speed} * 1000); # Walk speed + $data .= pack('C2 v V', 0xB0, 0x00, 5, $char->{hp}); # Current HP + $data .= pack('C2 v V', 0xB0, 0x00, 6, $char->{hp_max}); # Max HP + $data .= pack('C2 v V', 0xB0, 0x00, 7, $char->{sp}); # Current SP + $data .= pack('C2 v V', 0xB0, 0x00, 8, $char->{sp_max}); # Max SP + $data .= pack('C2 v V', 0xB0, 0x00, 12, $char->{points_skill}); # Skill points left + $data .= pack('C2 v V', 0xB0, 0x00, 24, $char->{weight} * 10); # Current weight + $data .= pack('C2 v V', 0xB0, 0x00, 25, $char->{weight_max} * 10); # Max weight + $data .= pack('C2 v V', 0xB0, 0x00, 53, $char->{attack_delay}); # Attack speed + $client->send($data); + # Player stats. + $data = undef; $data = pack('C2 v1 C12 v12 x4', 0xBD, 0x00, $char->{points_free}, @@ -473,18 +512,6 @@ sub send_player_info { ); $client->send($data); - # More stats - $data = pack('C2 v V', 0xB0, 0x00, 0, $char->{walk_speed} * 1000); # Walk speed - $data .= pack('C2 v V', 0xB0, 0x00, 5, $char->{hp}); # Current HP - $data .= pack('C2 v V', 0xB0, 0x00, 6, $char->{hp_max}); # Max HP - $data .= pack('C2 v V', 0xB0, 0x00, 7, $char->{sp}); # Current SP - $data .= pack('C2 v V', 0xB0, 0x00, 8, $char->{sp_max}); # Max SP - $data .= pack('C2 v V', 0xB0, 0x00, 12, $char->{points_skill}); # Skill points left - $data .= pack('C2 v V', 0xB0, 0x00, 24, $char->{weight} * 10); # Current weight - $data .= pack('C2 v V', 0xB0, 0x00, 25, $char->{weight_max} * 10); # Max weight - $data .= pack('C2 v V', 0xB0, 0x00, 53, $char->{attack_delay}); # Attack speed - $client->send($data); - # Base stat info (str, agi, vit, int, dex, luk) this time with bonus $data = pack('C2 V3', 0x41, 0x01, 13, $char->{str}, $char->{str_bonus}); $data .= pack('C2 V3', 0x41, 0x01, 14, $char->{agi}, $char->{agi_bonus}); @@ -499,10 +526,6 @@ sub send_player_info { $char->{ID}, $char->{look}{head}, $char->{look}{body}) ); - # Send attack range - $data = pack('C2 v', 0x3A, 0x01, $char->{attack_range}); - # Send weapon/shield appearance - $data .= pack('C2 a4 C v2', 0xD7, 0x01, $char->{ID}, 2, $char->{weapon}, $char->{shield}); # Send status info $data .= pack('v a4 v3 x', 0x119, $char->{ID}, $char->{opt1}, $char->{opt2}, $char->{option}); $client->send($data); @@ -526,7 +549,7 @@ sub send_player_info { } } } - + $client->send($data) if (length($data) > 0); # Send spirit sphere information @@ -536,17 +559,6 @@ sub send_player_info { $data .= pack('C2 v V', 0xB1, 0x00, 23, $char->{exp_job_max}); $client->send($data); - # Send skill information - $data = undef; - foreach my $ID (@skillsID) { - $data .= pack('v2 x2 v3 a24 C', - $char->{skills}{$ID}{ID}, $char->{skills}{$ID}{targetType}, - $char->{skills}{$ID}{lv}, $char->{skills}{$ID}{sp}, - $char->{skills}{$ID}{range}, $ID, $char->{skills}{$ID}{up}); - } - $data = pack('C2 v', 0x0F, 0x01, length($data) + 4) . $data; - $client->send($data); - # Send Hotkeys if ($hotkeyList) { $data = undef; @@ -717,9 +729,7 @@ sub send_npc_info { sub send_avoid_sprite_error_hack { my ($self, $client, $char) = @_; - my $data = pack('C15', 0x29, 0x02, 0xA7, 0x94, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40); - $client->send($data); - $data = $self->{recvPacketParser}->reconstruct({ + my $data = $self->{recvPacketParser}->reconstruct({ switch => '0229', ID => $char->{ID}, opt1 => $char->{opt1}, @@ -756,6 +766,13 @@ sub map_login { })); } + if (exists $self->{recvPacketParser}{packet_lut}{inventory_expansion_result}) { + $client->send($self->{recvPacketParser}->reconstruct({ + switch => 'inventory_expansion_result', + result => 0, + })); + } + if (exists $self->{recvPacketParser}{packet_lut}{account_id}) { $client->send($self->{recvPacketParser}->reconstruct({ switch => 'account_id',