Openkore.com

OpenKore Forums
It is currently 22 Jan 2018, 06:01

All times are UTC - 5 hours [ DST ]





Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 27 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 14 Jun 2011, 18:37 
Offline
Developers
Developers

Joined: 05 Dec 2008, 05:42
Posts: 1811
Well, it's not really good, but such a transition would allow to eliminate the need in almost all sendSomething functions (excluding compatibility reasons), as well as would be helpful for XKore and Poseidon.


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 14 Jun 2011, 19:30 
Offline
Administrator
Administrator
User avatar

Joined: 24 Apr 2008, 12:02
Posts: 1299
EternalHarvest wrote:
Well, it's not really good, but such a transition would allow to eliminate the need in almost all sendSomething functions (excluding compatibility reasons), as well as would be helpful for XKore and Poseidon.

Yeah. The same system could be used to Construct and Reconstruct any packet, even depending on ServerType.

_________________
Join our Team. Click here.
Image


Image


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 16 Jun 2011, 22:19 
Offline
Developers
Developers

Joined: 05 Dec 2008, 05:42
Posts: 1811
Code:
# This is an old method used back in the iRO beta 2 days when iRO had encrypted packets.
# At the moment (December 20 2006) there are no servers that still use encrypted packets.

Was that particular decrypt/encrypt stuff used for anything since then? Is it in actually working state now? (How to test it?)


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 16 Jun 2011, 22:26 
Offline
Administrator
Administrator
User avatar

Joined: 24 Apr 2008, 12:02
Posts: 1299
EternalHarvest wrote:
Code:
# This is an old method used back in the iRO beta 2 days when iRO had encrypted packets.
# At the moment (December 20 2006) there are no servers that still use encrypted packets.

Was that particular decrypt/encrypt stuff used for anything since then? Is it in actually working state now? (How to test it?)

Well the old part. Not. I did not seen any trace of it anywhere.
They only thing was the Packet Prefix Encryption... but it was too simple one.
Anyway. Encrypt/Decrypt is needed, at least as hooks or some calls to embedded functions. so they could be used to defeat such protections as SHANDA PROTECT (cRO), Delphine, etc.

_________________
Join our Team. Click here.
Image


Image


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 16 Jun 2011, 22:36 
Offline
Developers
Developers

Joined: 05 Dec 2008, 05:42
Posts: 1811
Code:
# $conState contains the connection state:
# 2.5 (set by parseMsg()): Just passed character selection; next 4 bytes will be
#      the account ID

Only set in gameguard_grant actually (because account ID messages are handled... differently now?). Now what's this, right in one of most important subs, parseIncomingMessage?
Code:
   # The user is running in X-Kore mode and wants to switch character or gameGuard type 2 after 0259 tag 02.
   # We're now expecting an accountID, unless the server has replicated packet 0259 (server-side bug).
   if ($net->getState() == 2.5 && (!$config{gameGuard} || ($switch ne '0259' && $config{gameGuard} eq "2"))) {
      if (length($msg) >= 4) {
         $net->setState(Network::CONNECTED_TO_MASTER_SERVER);
         $accountID = substr($msg, 0, 4);
         debug "Selecting character, new accountID: ".unpack("V", $accountID)."\n", "connection";
         $net->clientSend($accountID);
         return substr($msg, 4);
      } else {
         return $msg;
      }
   }

Also return value is never used.


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 16 Jun 2011, 22:41 
Offline
Administrator
Administrator
User avatar

Joined: 24 Apr 2008, 12:02
Posts: 1299
EternalHarvest wrote:
Code:
# $conState contains the connection state:
# 2.5 (set by parseMsg()): Just passed character selection; next 4 bytes will be
#      the account ID

Only set in gameguard_grant actually (because account ID messages are handled... differently now?). Now what's this, right in one of most important subs, parseIncomingMessage?
Code:
   # The user is running in X-Kore mode and wants to switch character or gameGuard type 2 after 0259 tag 02.
   # We're now expecting an accountID, unless the server has replicated packet 0259 (server-side bug).
   if ($net->getState() == 2.5 && (!$config{gameGuard} || ($switch ne '0259' && $config{gameGuard} eq "2"))) {
      if (length($msg) >= 4) {
         $net->setState(Network::CONNECTED_TO_MASTER_SERVER);
         $accountID = substr($msg, 0, 4);
         debug "Selecting character, new accountID: ".unpack("V", $accountID)."\n", "connection";
         $net->clientSend($accountID);
         return substr($msg, 4);
      } else {
         return $msg;
      }
   }

Also return value is never used.

Yeah. Because it was Designed to Check whatever AccountID was received or not. But never completed.

_________________
Join our Team. Click here.
Image


Image


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 16 Jun 2011, 22:51 
Offline
Developers
Developers

Joined: 05 Dec 2008, 05:42
Posts: 1811
kLabMouse wrote:
Anyway. Encrypt/Decrypt is needed, at least as hooks or some calls to embedded functions. so they could be used to defeat such protections as SHANDA PROTECT (cRO), Delphine, etc.

Less offtopic, please, as you know very well that delphine and other protections work via different methods.

Can we remove/disregard that old decrypt/encrypt?

kLabMouse wrote:
Yeah. Because it was Designed to Check whatever AccountID was received or not. But never completed.

So, what to do with it? Looks like it would work only as mentioned server-side bug workaround anyway, as 2.5 isn't used for "wants to switch character".

I'm creating new method in MessageTokenizer which will read, parse and handle all the messages it can (merge of Base::RagnarokServer::onClientData and a part of mainLoop_initialized, including parseIncomingMessage and parseOutgoingClientMessage), so I need to understand what to do with all the weird stuff there.


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 16 Jun 2011, 23:03 
Offline
Administrator
Administrator
User avatar

Joined: 24 Apr 2008, 12:02
Posts: 1299
EternalHarvest wrote:
kLabMouse wrote:
Anyway. Encrypt/Decrypt is needed, at least as hooks or some calls to embedded functions. so they could be used to defeat such protections as SHANDA PROTECT (cRO), Delphine, etc.

Less offtopic, please, as you know very well that delphine and other protections work via different methods.

Can we remove/disregard that old decrypt/encrypt?

kLabMouse wrote:
Yeah. Because it was Designed to Check whatever AccountID was received or not. But never completed.

So, what to do with it? Looks like it would work only as mentioned server-side bug workaround anyway, as 2.5 isn't used for "wants to switch character".

I'm creating new method in MessageTokenizer which will read, parse and handle all the messages it can (merge of Base::RagnarokServer::onClientData and a part of mainLoop_initialized, including parseIncomingMessage and parseOutgoingClientMessage), so I need to understand what to do with all the weird stuff there.

Trow it out. Only left the ability to encrypt/decrypt packet itself. And may-be some place to filter out random receive of AccountID.

P.S. There is such a mess there... I failed last time when I tried to port some parts to AI 2008.

_________________
Join our Team. Click here.
Image


Image


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 20 Jun 2011, 21:06 
Offline
Developers
Developers

Joined: 05 Dec 2008, 05:42
Posts: 1811
Code:
sub gameguard_grant {
   my ($self, $args) = @_;

   if ($args->{server} == 0) {
      error T("The server Denied the login because GameGuard packets where not replied " .
         "correctly or too many time has been spent to send the response.\n" .
         "Please verify the version of your poseidon server and try again\n"), "poseidon";
      return;
   } elsif ($args->{server} == 1) {
      message T("Server granted login request to account server\n"), "poseidon";
   } else {
      message T("Server granted login request to char/map server\n"), "poseidon";
      change_to_constate25 if ($config{'gameGuard'} eq "2");
   }
   $net->setState(1.3) if ($net->getState() == 1.2);
}

Kore requests for this packet when logging into account server, that's right. But how/when the second type (char/map server) is requested or received? I've tried it with XKore 2 using kore with "gameGuard 2" as a client, and after adding support for gameguard_grant in account server only it connects just fine.

Let's ignore that "replicated packet 0259 (server-side bug)" while network state is 2.5 for now.


Top
 Profile  
 
 Post subject: Re: Merge Receive and Send base modules
PostPosted: 21 Jun 2011, 01:13 
Offline
Developers
Developers

Joined: 05 Dec 2008, 05:42
Posts: 1811
No more parseIncomingMessage:
Code:
Index: src/functions.pl
===================================================================
--- src/functions.pl   (revision 7788)
+++ src/functions.pl   (working copy)
@@ -694,26 +694,8 @@
   if (defined($data) && length($data) > 0) {
      Benchmark::begin("parseMsg") if DEBUG;

-      my $type;
      $incomingMessages->add($data);
-      while ($data = $incomingMessages->readNext(\$type)) {
-         if ($type == Network::MessageTokenizer::KNOWN_MESSAGE) {
-            parseIncomingMessage($data);
-         } else {
-            if ($type == Network::MessageTokenizer::UNKNOWN_MESSAGE) {
-               # Unknown message - ignore it
-               my $messageID = Network::MessageTokenizer::getMessageID($data);
-               if (!existsInList($config{debugPacket_exclude}, $messageID)) {
-                  warning TF("Packet Tokenizer: Unknown switch: %s\n", $messageID), "connection";
-                  visualDump($data, "<< Received unknown packet") if ($config{debugPacket_unparsed});
-               }
-            } elsif ($config{debugPacket_received}) {
-               debug "Received account ID\n", "parseMsg", 0 ;
-            }
-            # Pass it along to the client, whatever it is
-            $net->clientSend($data);
-         }
-      }
+      $net->clientSend($packetParser->processTokenizer($incomingMessages));
      $net->clientFlush() if (UNIVERSAL::isa($net, 'Network::XKoreProxy'));
      Benchmark::end("parseMsg") if DEBUG;
   }
@@ -723,6 +705,7 @@
   if (defined($data) && length($data) > 0) {
      my $type;
      $outgoingClientMessages->add($data);
+      # $net->serverSend($messageSender->processTokenizer($outgoingClientMessages, <callback object ?>));
      while ($data = $outgoingClientMessages->readNext(\$type)) {
         parseOutgoingClientMessage($data);
      }
@@ -1004,7 +987,7 @@
   }
   my $switch = Network::MessageTokenizer::getMessageID($msg);
   
-   parseMessage_pre('ro_sent', $switch, $msg, $sendMsg);
+   parseMessage_pre('Network::Send', $switch, $msg, $sendMsg);

   my $serverType = $masterServer->{serverType};

@@ -1315,8 +1298,8 @@
sub parseMessage_pre {
   my ($mode, $switch, $msg, $realMsg) = @_;
   my ($title, $config_suffix, $desc_key, $dumpMethod5_word, $hook) = @{{
-      'received' => ['<< Received packet:', 'received', 'Recv', 'recv', 'parseMsg/pre'],
-      'ro_sent' => ['<< Sent by RO client:', 'ro_sent', 'Send', 'send', 'RO_sendMsg_pre'],
+      'Network::Receive' => ['<< Received packet:', 'received', 'Recv', 'recv', 'parseMsg/pre'],
+      'Network::Send' => ['<< Sent by RO client:', 'ro_sent', 'Send', 'send', 'RO_sendMsg_pre'],
   }->{$mode}};
   
   if ($config{'debugPacket_'.$config_suffix} && !existsInList($config{'debugPacket_exclude'}, $switch) ||
Index: src/Network/PacketParser.pm
===================================================================
--- src/Network/PacketParser.pm   (revision 7791)
+++ src/Network/PacketParser.pm   (working copy)
@@ -310,4 +310,69 @@
   return $hook_args{return};
}

+sub processTokenizer {
+   my ($self, $tokenizer) = @_;
+   
+   my $result = '';
+   my $type;
+   while (my $message = $tokenizer->readNext(\$type)) {
+      if ($type == Network::MessageTokenizer::KNOWN_MESSAGE) {
+         my $switch = Network::MessageTokenizer::getMessageID($message);
+         
+         main::parseMessage_pre($self->{hook_prefix}, $switch, $message, $message);
+         
+         my $willMangle = $self->willMangle($switch);
+         # If we're running in X-Kore mode, pass the message back to the RO client.
+         $result .= $message unless $willMangle;
+         
+         $self->{lastPacketTime} = time;
+         if (my $args = $self->parse($message)) {
+            # Use the new object-oriented packet parser
+            if ($config{debugPacket_received} == 3 &&
+                  existsInList($config{'debugPacket_include'}, $switch)) {
+               my $switch = $args->{switch};
+               my $packet = $packetParser->{packet_list}{$switch};
+               my ($name, $packString, $varNames) = @{$packet};
+               
+               my @vars = ();
+               for my $varName (@{$varNames}) {
+                  message "$varName = $args->{$varName}\n";
+               }
+            }
+            
+            if ($willMangle) {
+               my $ret = $self->mangle($args);
+               if (!$ret) {
+                  # Packet was not mangled
+                  $result .= $args->{RAW_MSG};
+               } elsif ($ret == 1) {
+                  # Packet was mangled
+                  $result .= $packetParser->reconstruct($args);
+               } else {
+                  # Packet was suppressed
+               }
+            }
+         }
+         
+      } elsif ($type == Network::MessageTokenizer::ACCOUNT_ID) {
+         $result .= $message;
+         
+      } elsif ($type == Network::MessageTokenizer::UNKNOWN_MESSAGE) {
+         # Unknown message - ignore it
+         my $switch = Network::MessageTokenizer::getMessageID($message);
+         if (!existsInList($config{debugPacket_exclude}, $switch)) {
+            warning TF("Packet Tokenizer: Unknown switch: %s\n", $switch), "connection";
+            visualDump($message, "<< Received unknown packet") if ($config{debugPacket_unparsed});
+         }
+         # Pass it along to the client, whatever it is
+         $result .= $message;
+         
+      } else {
+         die "Packet Tokenizer: Unknown type: $type";
+      }
+   }
+   
+   return $result;
+}
+
1;

Now, parse() and processTokenizer() need to be able to use object argument to look handlers in (currently it uses $self), and additional arguments to pass to handlers ($client in case of Base::RagnarokServer). Something like $PacketParser->parse($bytes, $object, $arg1, $arg2...). Also, maybe $args hashref for packet handlers should always be the first argument, so handlers would be called as $object->$handler($args, $arg1, $arg2...)? Currently, $client is positioned before $bytes in Base::RagnarokServer.

Object classes with handlers would include currently existing ServerType stuff (handlers should be moved away to separate module later but will work as is), {Base::Ragnarok,Network::XKore2}::{Account,Char,Map}Server, and new modules to replace parseOutgoingClientMessage and such.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 27 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 5 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group