Skip to content

Commit

Permalink
add support to cryptkey in xkore 1 and 3 (#1374)
Browse files Browse the repository at this point in the history
* fix xkore 1 and 3

* remove not used variable

* missing import

* remove portal los

in last update i sended the portal_los together in this i'm removing this file

* xkore 1 reset key when chang mapserver
  • Loading branch information
alisonrag committed Nov 17, 2017
1 parent ec4f8fe commit 431221d
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ tables/iRO/Restart/skillnametable-custom.txt
tables/**/portalsLOS.txt
tables/**/npcs.txt
tables/**/monsters.txt
*.xpm
3 changes: 2 additions & 1 deletion plugins/reconnect/reconnect.pl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ sub unload {

sub trying_to_connect {
my ( undef, $params ) = @_;

return if($config{XKore} eq 1 || $config{XKore} eq 3);
# Only trigger if we're connecting to the login server.
next if $masterServers{ $config{master} }->{ip} ne $params->{host};
next if $masterServers{ $config{master} }->{port} ne $params->{port};
Expand All @@ -46,6 +46,7 @@ sub trying_to_connect {
}

sub connected {
return if($config{XKore} eq 1 || $config{XKore} eq 3);
$counter = 0;
$timeout{reconnect} = { timeout => timeout() };
}
Expand Down
8 changes: 8 additions & 0 deletions src/Network/Receive.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1834,6 +1834,12 @@ 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->{flag} ne 0 && ($config{XKore} eq "1" || $config{XKore} eq "3")) {
$timeout{master}{time} = time;
return;
}

# flags:
# 0 - correct
# 1 - requested (already defined)
Expand Down Expand Up @@ -2127,6 +2133,8 @@ sub area_spell_multiple3 {
sub sync_request_ex {
my ($self, $args) = @_;

return if($config{XKore} eq 1 || $config{XKore} eq 3); # let the clien hanle this

# Debug Log
# message "Received Sync Ex : 0x" . $args->{switch} . "\n";

Expand Down
14 changes: 8 additions & 6 deletions src/Network/Receive/ServerType0.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1182,16 +1182,16 @@ sub map_loaded {
Plugins::callHook('in_game');
$timeout{'ai'}{'time'} = time;
our $quest_generation++;

$messageSender->sendRequestCashItemsList() if ($masterServer->{serverType} eq 'bRO'); # tested at bRO 2013.11.30, request for cashitemslist
$messageSender->sendCashShopOpen() if ($config{whenInGame_requestCashPoints});
$messageSender->sendIgnoreAll("all") if ($config{ignoreAll}); # broking xkore 1 and 3 when use cryptkey
}

$char->{pos} = {};
makeCoordsDir($char->{pos}, $args->{coords}, \$char->{look}{body});
$char->{pos_to} = {%{$char->{pos}}};
message(TF("Your Coordinates: %s, %s\n", $char->{pos}{x}, $char->{pos}{y}), undef, 1);

$messageSender->sendIgnoreAll("all") if ($config{ignoreAll});
$messageSender->sendRequestCashItemsList() if ($masterServer->{serverType} eq 'bRO'); # tested at bRO 2013.11.30, request for cashitemslist
$messageSender->sendCashShopOpen() if ($config{whenInGame_requestCashPoints});
}

sub actor_look_at {
Expand Down Expand Up @@ -2801,6 +2801,8 @@ sub private_message_sent {
sub sync_received_characters {
my ($self, $args) = @_;

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

$charSvrSet{sync_Count} = $args->{sync_Count} if (exists $args->{sync_Count});

unless ($net->clientAlive) {
Expand Down Expand Up @@ -2893,10 +2895,10 @@ sub received_characters {
## Note to devs: If other official servers support > 3 characters, then
## you should add these other serverTypes to the list compared here:
if (($args->{switch} eq '099D') &&
(grep { $masterServer->{serverType} eq $_ } qw( twRO iRO idRO ))
(grep { $masterServer->{serverType} eq $_ } qw( twRO iRO idRO bRO ))
) {
$net->setState(1.5);
if ($charSvrSet{sync_CountDown} && $config{'XKore'} ne '1') {
if ($charSvrSet{sync_CountDown} && $config{'XKore'} ne '1' && $config{'XKore'} ne '3') {
$messageSender->sendToServer($messageSender->reconstruct({switch => 'sync_received_characters'}));
$charSvrSet{sync_CountDown}--;
}
Expand Down
83 changes: 81 additions & 2 deletions src/Network/XKore.pm
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ use Exception::Class ('Network::XKore::CannotStart');

use Modules 'register';
use Globals;
use Log qw(message error);
use Log qw(message error debug);
use Utils::Win32;
use Network;
use Network::Send ();
use Utils qw(dataWaiting timeOut);
use Translation;
use Misc qw(chatLog);
use Network::MessageTokenizer;

my $currentClientKey = 0;

##
# Network::XKore->new()
Expand Down Expand Up @@ -59,7 +62,11 @@ sub new {
$masterServer = $masterServers{$config{master}};
$packetParser = Network::Receive->create($self, $masterServer->{serverType});
$messageSender = Network::Send->create($self, $masterServer->{serverType});

$clientPacketHandler = Network::ClientReceive->new;

$self->{tokenizer} = new Network::MessageTokenizer($self->getRecvPackets());
$self->{kore_map_changed_hook} = Plugins::addHook('packet/map_changed', \&kore_map_changed, $self);

Plugins::addHook("Network::Receive/willMangle", \&willMangle);
Plugins::addHook("Network::Receive/mangle", \&mangle);

Expand Down Expand Up @@ -416,9 +423,18 @@ sub recv {
: "";
if ($type eq "R") {
# Client-bound (or "from server") packets
my $switch = uc(unpack("H2", substr($msg, 1, 1))) . uc(unpack("H2", substr($msg, 0, 1)));
if (($switch eq "0071" || $switch eq "0092") && $currentClientKey && $messageSender->{encryption}->{crypt_key}) {
$currentClientKey = $messageSender->{encryption}->{crypt_key_1};
$messageSender->{encryption}->{crypt_key} = $messageSender->{encryption}->{crypt_key_1};
}
$self->{serverPackets} .= $msg;
} elsif ($type eq "S") {
# Server-bound (or "to server") packets
if($self->getState() eq Network::IN_GAME || $self->getState() eq Network::CONNECTED_TO_CHAR_SERVER) {
$self->onClientData($msg);
return undef;
}
$self->{clientPackets} .= $msg;
} elsif ($type eq "K") {
# Keep-alive... useless.
Expand Down Expand Up @@ -579,5 +595,68 @@ sub hackClient {
# $message =~ s/\n/\\n/g;
# main::sendMessage($messageSender, "k", $message);
#}
sub onClientData {
my ($self, $msg) = @_;
my $additional_data;
my $type;

while (my $message = $self->{tokenizer}->readNext(\$type)) {
$msg .= $message;
}
$self->decryptMessageID(\$msg);

$msg = $self->{tokenizer}->slicePacket($msg, \$additional_data); # slice packet if needed

$self->{tokenizer}->add($msg, 1);

$messageSender->sendToServer($_) for $messageSender->process(
$self->{tokenizer}, $clientPacketHandler
);

$self->{tokenizer}->clear();

if($additional_data) {
$self->onClientData($additional_data);
}
}

sub decryptMessageID {
my ($self, $r_message) = @_;

if(!$messageSender->{encryption}->{crypt_key} && $messageSender->{encryption}->{crypt_key_3}) {
$currentClientKey = $messageSender->{encryption}->{crypt_key_1};
} elsif(!$currentClientKey) {
return;
}

my $messageID = unpack("v", $$r_message);

# Saving Last Informations for Debug Log
my $oldMID = $messageID;
my $oldKey = ($currentClientKey >> 16) & 0x7FFF;

# Calculating the Encryption Key
$currentClientKey = ($currentClientKey * $messageSender->{encryption}->{crypt_key_3} + $messageSender->{encryption}->{crypt_key_2}) & 0xFFFFFFFF;

# Xoring the Message ID
$messageID = ($messageID ^ (($currentClientKey >> 16) & 0x7FFF)) & 0xFFFF;
$$r_message = pack("v", $messageID) . substr($$r_message, 2);

# Debug Log
debug (sprintf("Decrypted MID : [%04X]->[%04X] / KEY : [0x%04X]->[0x%04X]\n", $oldMID, $messageID, $oldKey, ($currentClientKey >> 16) & 0x7FFF), "sendPacket", 0) if $config{debugPacket_sent};
}

sub getRecvPackets {
return \%rpackets;
}

sub kore_map_changed {
# Reset CryptKey when mapserver change
if($currentClientKey && $messageSender->{encryption}->{crypt_key}) {
debug (sprintf("Reseting Key in Map-Change: [0x%04X]->[0x%04X]\n", $currentClientKey, $messageSender->{encryption}->{crypt_key_1}));
$currentClientKey = $messageSender->{encryption}->{crypt_key_1};
$messageSender->{encryption}->{crypt_key} = $messageSender->{encryption}->{crypt_key_1};
}
}

return 1;
Loading

0 comments on commit 431221d

Please sign in to comment.