Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions src/Base/Ragnarok/AccountServer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -167,6 +171,7 @@ sub token_login {
switch => 'login_error',
type => Network::Receive::ServerType0::ACCEPT_ID_PASSWD,
}));
sleep 1;
$client->close();
}
};
Expand All @@ -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
};
}

Expand All @@ -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';
}

Expand Down
83 changes: 52 additions & 31 deletions src/Base/Ragnarok/CharServer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -98,42 +98,51 @@ sub game_login {
$client->send($args->{accountID});

my $output;
# 099D
my @char_list = $self->getCharacters($session);
if ($self->{recvPacketParser}{packet_lut}{received_characters} eq '099D') {
$output = $self->{recvPacketParser}->reconstruct({
switch => 'received_characters_info',
normal_slot => $charSvrSet{normal_slot},
premium_slot => $charSvrSet{premium_slot},
billing_slot => $charSvrSet{billing_slot},
producible_slot => $charSvrSet{producible_slot},
valid_slot => $charSvrSet{valid_slot},
chars => \@char_list,
});

if ($charSvrSet{sync_Count} > 0) {
$output .= $self->{recvPacketParser}->reconstruct({
switch => 'sync_received_characters',
sync_Count => $charSvrSet{sync_Count},
my $replay_character_flow = @{$charSvrSet{xkore2_character_bootstrap_raw} || []};
if ($replay_character_flow) {
$output = join('', @{$charSvrSet{xkore2_character_bootstrap_raw}});
$client->{xkore2_character_pages_raw} = [@{$charSvrSet{xkore2_character_pages_raw} || []}];
} else {
# Fall back to reconstruction for older servers that do not use the
# modern multi-packet character-selection flow.
my @char_list = $self->getCharacters($session);
if ($self->{recvPacketParser}{packet_lut}{received_characters} eq '099D') {
$output = $self->{recvPacketParser}->reconstruct({
switch => 'received_characters_info',
normal_slot => $charSvrSet{normal_slot},
premium_slot => $charSvrSet{premium_slot},
billing_slot => $charSvrSet{billing_slot},
producible_slot => $charSvrSet{producible_slot},
valid_slot => $charSvrSet{valid_slot},
chars => \@char_list,
});

if ($charSvrSet{sync_Count} > 0) {
$output .= $self->{recvPacketParser}->reconstruct({
switch => 'sync_received_characters',
sync_Count => $charSvrSet{sync_Count},
});
}
} else { # 006B
$output = $self->{recvPacketParser}->reconstruct({
switch => 'received_characters_info',
total_slot => $charSvrSet{total_slot},
premium_start_slot => $charSvrSet{premium_start_slot},
premium_end_slot => $charSvrSet{premium_end_slot},
chars => \@char_list,
});
}
} else { # 006B
$output = $self->{recvPacketParser}->reconstruct({
switch => 'received_characters_info',
total_slot => $charSvrSet{total_slot},
premium_start_slot => $charSvrSet{premium_start_slot},
premium_end_slot => $charSvrSet{premium_end_slot},
chars => \@char_list,
});
}
$client->send($output);

# Show list of characters.
&sendCharInfo;
&sendCharInfo unless $replay_character_flow;

# TODO: Check if we need send accountID
my $data .= pack('C2 x4 a4 v', 0xB9, 0x08, $args->{accountID}, 0);
$client->send($data);
unless ($replay_character_flow) {
my $data .= pack('C2 x4 a4 v', 0xB9, 0x08, $args->{accountID}, 0);
$client->send($data);
}
}
}

Expand Down Expand Up @@ -165,8 +174,13 @@ sub char_login {
# We can't get the character information for some reason.
$client->send(pack('C*', 0x6C, 0x00, 0));
} else {
my $host = inet_aton($self->{mapServer}->getHost);
$host = inet_aton($client->{BSC_sock}->sockhost) if $host eq "\000\000\000\000";
my $mapHost = $self->{mapServer}->getHost;
my $host = inet_aton($mapHost);
if ($host eq "\000\000\000\000") {
$mapHost = $client->{BSC_sock}->sockhost;
$host = inet_aton($mapHost);
}
my $mapPort = $self->{mapServer}->getPort;

$session->{charID} = $char->{charID};
$session->{state} = 'About to load map';
Expand All @@ -175,16 +189,23 @@ sub char_login {
charID => $char->{charID},
mapName => $charInfo->{map},
mapIP => $host,
mapPort => $self->{mapServer}->getPort,
mapPort => $mapPort,
mapUrl => $mapHost . ':' . $mapPort,
}));
}
}
}
sleep 1;
$client->close();
}

sub sync_received_characters {
my ($self, $args, $client) = @_;
if (exists $client->{xkore2_character_pages_raw}) {
my $page = shift @{$client->{xkore2_character_pages_raw}};
$client->send($page) if defined $page;
return;
}
if ($nChar == 0) {
&sendCharInfo;
$nChar = 1;
Expand Down
36 changes: 36 additions & 0 deletions src/Network/Receive.pm
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,11 @@ sub received_characters_slots_info {
# CHARACTER_INFO_NEO_UNION3 is based in charblocksize, check sub received_characters_unpackString
sub received_characters {
my ($self, $args) = @_;
$charSvrSet{received_characters_switch} = $args->{switch} if $args->{switch};
if ($args->{switch} && $args->{switch} eq $self->{packet_lut}{received_characters} && $args->{RAW_MSG}) {
push @{$charSvrSet{xkore2_character_pages_raw}},
substr($args->{RAW_MSG}, 0, $args->{RAW_MSG_SIZE});
}
my $blockSize = $self->received_characters_blockSize();
my $char_info = $self->received_characters_unpackString;

Expand Down Expand Up @@ -929,6 +934,11 @@ sub received_characters {
# total count: Server send from total pages until 1 page
sub sync_received_characters {
my ($self, $args) = @_;
$charSvrSet{sync_received_characters_switch} = $args->{switch} if $args->{switch};
if ($args->{RAW_MSG}) {
push @{$charSvrSet{xkore2_character_bootstrap_raw}},
substr($args->{RAW_MSG}, 0, $args->{RAW_MSG_SIZE});
}

return unless (UNIVERSAL::isa($net, 'Network::DirectConnection'));

Expand Down Expand Up @@ -1036,6 +1046,13 @@ sub character_creation_failed {
# CHARACTER_INFO_NEO_UNION3 and CHARACTER_INFO_NEO_UNION2 are based in charblocksize, check sub received_characters_unpackString
sub received_characters_info {
my ($self, $args) = @_;
$charSvrSet{received_characters_info_switch} = $args->{switch} if $args->{switch};
$charSvrSet{xkore2_character_bootstrap_raw} = [];
$charSvrSet{xkore2_character_pages_raw} = [];
if ($args->{RAW_MSG}) {
push @{$charSvrSet{xkore2_character_bootstrap_raw}},
substr($args->{RAW_MSG}, 0, $args->{RAW_MSG_SIZE});
}
Scalar::Util::weaken(my $weak = $self);
my $timeout = {timeout => 6, time => time};

Expand Down Expand Up @@ -4167,6 +4184,10 @@ sub marriage_partner_name {
sub login_pin_code_request {
# This is ten second-level password login for 2013/3/29 upgrading of twRO
my ($self, $args) = @_;
if ($args->{RAW_MSG} && ref($charSvrSet{xkore2_character_bootstrap_raw}) eq 'ARRAY') {
push @{$charSvrSet{xkore2_character_bootstrap_raw}},
substr($args->{RAW_MSG}, 0, $args->{RAW_MSG_SIZE});
}

if ($args->{flag} ne 0 && ($config{XKore} eq "1" || $config{XKore} eq "3")) {
$timeout{master}{time} = time;
Expand Down Expand Up @@ -5450,6 +5471,7 @@ sub cart_add_failed {
sub inventory_items_stackable {
my ($self, $args) = @_;
return unless changeToInGameState();
$char->{xkore2_inventory_stackable_packet} = $args->{RAW_MSG};

$self->_items_list({
class => 'Actor::Item',
Expand All @@ -5472,6 +5494,10 @@ sub inventory_items_stackable {
sub item_list_start {
my ($self, $args) = @_;
$current_item_list = $args->{type};
if ($args->{type} == INVTYPE_INVENTORY) {
$char->{xkore2_inventory_packets} = [$args->{RAW_MSG}];
$char->{xkore2_inventory_complete} = 0;
}

debug "Starting Item List. ID: $args->{type}". ($args->{name} ? " ($args->{name})\n" : "\n"), "info";

Expand All @@ -5489,6 +5515,9 @@ sub item_list_start {
sub item_list_stackable {
my ($self, $args) = @_;
return unless changeToInGameState();
if ($args->{type} == INVTYPE_INVENTORY && ref $char->{xkore2_inventory_packets} eq 'ARRAY') {
push @{$char->{xkore2_inventory_packets}}, $args->{RAW_MSG};
}

my $arguments = {
class => 'Actor::Item',
Expand Down Expand Up @@ -5531,6 +5560,9 @@ sub item_list_stackable {
sub item_list_nonstackable {
my ($self, $args) = @_;
return unless changeToInGameState();
if ($args->{type} == INVTYPE_INVENTORY && ref $char->{xkore2_inventory_packets} eq 'ARRAY') {
push @{$char->{xkore2_inventory_packets}}, $args->{RAW_MSG};
}

my $arguments = {
class => 'Actor::Item',
Expand Down Expand Up @@ -5580,6 +5612,10 @@ sub item_list_nonstackable {

sub item_list_end {
my ($self, $args) = @_;
if ($args->{type} == INVTYPE_INVENTORY && ref $char->{xkore2_inventory_packets} eq 'ARRAY') {
push @{$char->{xkore2_inventory_packets}}, $args->{RAW_MSG};
$char->{xkore2_inventory_complete} = 1;
}
debug TF("Ending Item List. ID: %s\n", $args->{type}), "info";
if ( $args->{type} == INVTYPE_INVENTORY ) {
$char->inventory->onitemListEnd();
Expand Down
12 changes: 10 additions & 2 deletions src/Network/Receive/kRO/RagexeRE_2014_10_22b.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
10 changes: 9 additions & 1 deletion src/Network/Receive/kRO/RagexeRE_2016_04_14b.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Loading