pRO's Update! Login Pincode..(similar to bRO)

Philippines

Moderators: waferbaron, Moderators

Forum rules
This server is currently not maintained and tables folder (including connection info) is outdated. Read the wiki for instructions on how to update those information. Please contribute your updated info. Contact Cozzie to join the team as a regular server supporter.
zonda
Human
Human
Posts: 45
Joined: 12 Aug 2014, 21:15
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#171 Post by zonda »

same thing... failed to connect to the server
brokenbokeh
Plain Yogurt
Plain Yogurt
Posts: 50
Joined: 08 Aug 2014, 03:02
Noob?: No

Re: pRO's Update! Login Pincode..(similar to bRO)

#172 Post by brokenbokeh »

I saw the problem, wrong packet length. I have added some code and tested it with Kore. Kore can login to the Poseidon server. Havent tested it with the RO client.

sub SendMapLogin

Code: Select all

	if ( $config{server_type} !~ /^bRO/ ) { $data .= pack("C*", 0x83, 0x02) . $accountID; } #<- This is Server Type Based !!
	$data .= pack("C*", 0xEB, 0x02) . pack("V", getTickCount) . getCoordString($posX, $posY, 1) . pack("C*", 0x05, 0x05) . pack("C*", 0x05, 0x05);
zonda
Human
Human
Posts: 45
Joined: 12 Aug 2014, 21:15
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#173 Post by zonda »

thanks. i can get in now. still an error pops up from game guard after and rag.exe closes
brokenbokeh
Plain Yogurt
Plain Yogurt
Posts: 50
Joined: 08 Aug 2014, 03:02
Noob?: No

Re: pRO's Update! Login Pincode..(similar to bRO)

#174 Post by brokenbokeh »

Poseidon is probably detected by GameGuard. I run my Poseidon in a virtual machine. I am testing if it works.
zonda
Human
Human
Posts: 45
Joined: 12 Aug 2014, 21:15
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#175 Post by zonda »

could be because im using windows 7... ill try running a virtual machine also...
afgh1214
Plain Yogurt
Plain Yogurt
Posts: 66
Joined: 07 Aug 2014, 05:46
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#176 Post by afgh1214 »

AY PUTANGINA! Pati new loki na gameguard na din!

New loki also got gameguard with the new patch.

Anybody from valk or iris made theirs work yet?

It doesnt even take 5 mins before I get DCed, only 2 mins.
amPupu
Noob
Noob
Posts: 15
Joined: 07 Aug 2014, 20:27
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#177 Post by amPupu »

afgh1214 wrote:AY PUTANGINA! Pati new loki na gameguard na din!

New loki also got gameguard with the new patch.

Anybody from valk or iris made theirs work yet?

It doesnt even take 5 mins before I get DCed, only 2 mins.

wew grabe.. hehe.. pati NL dc nrin?.. bwisit un bagong gameguard.. hmm.. sana may solution na.. kahit s hexed man lng
zonda
Human
Human
Posts: 45
Joined: 12 Aug 2014, 21:15
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#178 Post by zonda »

im able to keep poseidon open now using an old hexed client. bot still keeps disconnecting though... do i still need to change anything in the bot? i dont think the bot is even connected to poseidon.
zonda
Human
Human
Posts: 45
Joined: 12 Aug 2014, 21:15
Noob?: Yes

Re: pRO's Update! Login Pincode..(similar to bRO)

#179 Post by zonda »

Image


Still no luck... haven't tried a virtual machine yet though
brokenbokeh
Plain Yogurt
Plain Yogurt
Posts: 50
Joined: 08 Aug 2014, 03:02
Noob?: No

Re: pRO's Update! Login Pincode..(similar to bRO)

#180 Post by brokenbokeh »

Huli ka balbon!

Guys, I have nailed it! :lol: :twisted:

I have tested it only on one bot but it is not being disconnected.

These are the changes I have done.

Instead of using ragexe.exe 1rag1 /account:poseidon.xml, you should use f2pexe.exe 1rag1 5free5 /account:poseidon.xml


src/Poseidon/RagnarokServer.pm

Code: Select all

sub ParsePacket
{
	my ($self, $client, $msg, $index, $packet_id, $switch) = @_;

	#my $packed_switch = quotemeta substr($msg, 0, 2);
	my $packed_switch = $packet_id;
	
	### These variables control the account information ###
	my $host = $self->getHost();
	my $port = pack("v", $self->getPort());
	$host = '127.0.0.1' if ($host eq 'localhost');
	my @ipElements = split /\./, $host;

	print "Received packet: $switch\n";
	
	# Note:
	# The switch packets are pRO specific and assumes the use of secureLogin 1. It may or may not work with other
	# countries' clients (except probably oRO). The best way to support other clients would be: use a barebones
	# eAthena or Freya as the emulator, or figure out the correct packet switches and include them in the
	# if..elsif..else blocks.

	if (($switch eq '01DB') || ($switch eq '0204')) { # client sends login packet 0204 packet thanks to elhazard

		# '01DC' => ['secure_login_key', 'x2 a*', [qw(secure_key)]],
		my $data = pack("C*", 0xdc, 0x01, 0x14) . pack("x17");
		$client->send($data);

		# save servers.txt info
		my $code = substr($msg, 2);
		if (length($msg) == 2) {
			$clientdata{$index}{secureLogin_type} = 0;
		} elsif (length($msg) == 20) {
			if ($code eq pack("C*", 0x04, 0x02, 0x7B, 0x8A, 0xA8, 0x90, 0x2F, 0xD8, 0xE8, 0x30, 0xF8, 0xA5, 0x25, 0x7A, 0x0D, 0x3B, 0xCE, 0x52)) {
				$clientdata{$index}{secureLogin_type} = 1;
			} elsif ($code eq pack("C*", 0x04, 0x02, 0x27, 0x6A, 0x2C, 0xCE, 0xAF, 0x88, 0x01, 0x87, 0xCB, 0xB1, 0xFC, 0xD5, 0x90, 0xC4, 0xED, 0xD2)) {
				$clientdata{$index}{secureLogin_type} = 2;
			} elsif ($code eq pack("C*", 0x04, 0x02, 0x42, 0x00, 0xB0, 0xCA, 0x10, 0x49, 0x3D, 0x89, 0x49, 0x42, 0x82, 0x57, 0xB1, 0x68, 0x5B, 0x85)) {
				$clientdata{$index}{secureLogin_type} = 3;
			} elsif ($code eq ("C*", 0x04, 0x02, 0x22, 0x37, 0xD7, 0xFC, 0x8E, 0x9B, 0x05, 0x79, 0x60, 0xAE, 0x02, 0x33, 0x6D, 0x0D, 0x82, 0xC6)) {
				$clientdata{$index}{secureLogin_type} = 4;
			} elsif ($code eq pack("C*", 0x04, 0x02, 0xc7, 0x0A, 0x94, 0xC2, 0x7A, 0xCC, 0x38, 0x9A, 0x47, 0xF5, 0x54, 0x39, 0x7C, 0xA4, 0xD0, 0x39)) {
				$clientdata{$index}{secureLogin_type} = 5;
			}
		} else {
			$clientdata{$index}{secureLogin_requestCode} = getHex($code);
		}

	} elsif (($switch eq '01DD') || ($switch eq '01FA') || ($switch eq '0064') || ($switch eq '0060') || ($switch eq '0277') || ($switch eq '02B0')) { # 0064 packet thanks to abt123

#		#my $data = pack("C*", 0xAD, 0x02, 0x00, 0x00, 0x1E, 0x0A, 0x00, 0x00);
#		#$client->send($data);
		my $sex = 1;
		my $serverName = pack("a20", "Poseidon server"); # server name should be less than or equal to 20 characters
		my $serverUsers = pack("V", @{$self->clients()} - 1);
		# '0069' => ['account_server_info', 'x2 a4 a4 a4 x30 C1 a*',
		# 			[qw(sessionID accountID sessionID2 accountSex serverInfo)]],
		my $data;
		if ($switch eq '01FA') {
			$data = pack("C*", 0x69, 0x00, 0x53, 0x00) . 
				$sessionID . $accountID . $sessionID2 . 
				pack("x30") . pack("C1", $sex) . pack("x4") .
				pack("C*", $ipElements[0], $ipElements[1], $ipElements[2], $ipElements[3]) .
				$port .	$serverName . $serverUsers . pack("x2");
		} else {
			$data = pack("C*", 0x69, 0x00, 0x4F, 0x00) . 
				$sessionID . $accountID . $sessionID2 . 
				pack("C*", 0x00, 0x00, 0x00, 0x00) . 
				pack("x26") . pack("C1", $sex);
				
				print "$data\n";


				$client->send($data);
				
				$data = pack("C*", $ipElements[0], $ipElements[1], $ipElements[2], $ipElements[3]) . 
				$port . $serverName . $serverUsers . pack("x2");
		}

		$client->send($data);

		# save servers.txt info
		$clientdata{$index}{version} = unpack("V", substr($msg, 2, 4));
		$clientdata{$index}{master_version} = unpack("C", substr($msg, length($msg) - 1, 1));
		if ($switch eq '01DD') {
			$clientdata{$index}{secureLogin} = 1;
			undef $clientdata{$index}{secureLogin_account};
		} elsif ($switch eq '01FA') {
			$clientdata{$index}{secureLogin} = 3;
			$clientdata{$index}{secureLogin_account} = unpack("C", substr($msg, 47, 1));
		} else {
			undef $clientdata{$index}{secureLogin};
			undef $clientdata{$index}{secureLogin_type};
			undef $clientdata{$index}{secureLogin_account};
			undef $clientdata{$index}{secureLogin_requestCode};
		}
		if (($switch ne '01DD') && ($switch ne '01FA') && ($switch ne '0064')) {
			$clientdata{$index}{masterLogin_packet} = $switch;
		} else {
			undef $clientdata{$index}{masterLogin_packet};
		}

		if($switch eq '02B0') {	# kRO uses 02B2 as masterLogin packet when we have <langtype>0</langtype> in the clientinfo.xml
								# if other servers do use this packet too that will be a problem.
			$clientdata{$index}{kRO} = 1;
		}

	} elsif (($switch eq '0065') || ($switch eq '0275') || ($msg =~ /^$packed_switch$accountID$sessionID$sessionID2\x0\x0.$/)) { # client sends server choice packet

		# Character List
		SendCharacterList($self, $client, $msg, $index, $switch);

		# save servers.txt info
		if ($switch ne '0065') {
			$clientdata{$index}{gameLogin_packet} = $switch;
		} else {
			undef $clientdata{$index}{gameLogin_packet};
		}

	} elsif ($switch eq '0066') { # client sends character choice packet

		# If Using Packet Encrypted Client
		if ( $self->{type}->{$config{server_type}}->{decrypt_mid_keys} )
		{
			# Enable Decryption
			my @enc_values = split(/\s+/, $self->{type}->{$config{server_type}}->{decrypt_mid_keys});
			($enc_val1, $enc_val2, $enc_val3) = (Math::BigInt->new(@enc_values[0]), Math::BigInt->new(@enc_values[1]), Math::BigInt->new(@enc_values[2]));
		}
		
		# State
		$state = 1;

		$clientdata{$index}{mode} = unpack('C1', substr($msg, 2, 1));

		# '0071' => ['received_character_ID_and_Map', 'a4 Z16 a4 v1', [qw(charID mapName mapIP mapPort)]],
		my $mapName = pack("a16", "moc_prydb1.gat");
		my $data = pack("C*", 0x71, 0x00) . $charID . $mapName . 
			pack("C*", $ipElements[0], $ipElements[1], $ipElements[2], $ipElements[3]) . $port;
		
		$client->send($data);
		
	} elsif ($switch eq  $self->{type}->{$config{server_type}}->{maploginPacket} &&
		(length($msg) == 19) &&
		(substr($msg, 2, 4) eq $accountID) &&
		(substr($msg, 6, 4) eq $charID) &&
		(substr($msg, 10, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 0;

	} elsif ($switch eq '0072' &&
		(length($msg) == 19) &&
		(substr($msg, 2, 4) eq $accountID) &&
		(substr($msg, 6, 4) eq $charID) &&
		(substr($msg, 10, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 0;

	} elsif ($switch eq '009B' &&
		(length($msg) == 32) &&
		(substr($msg, 3, 4) eq $accountID) &&
		(substr($msg, 12, 4) eq $charID) &&
		(substr($msg, 23, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 3;

	} elsif ($switch eq '00F5' &&
		(length($msg) == 29) &&
		(substr($msg, 5, 4) eq $accountID) &&
		(substr($msg, 14, 4) eq $charID) &&
		(substr($msg, 20, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 4;

	} elsif ($switch eq '009B' &&
		(length($msg) == 32) &&
		(substr($msg, 9, 4) eq $accountID) &&
		(substr($msg, 15, 4) eq $charID) &&
		(substr($msg, 23, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 5;

	} elsif ($switch eq '0072' &&
		(length($msg) == 29) &&
		(substr($msg, 3, 4) eq $accountID) &&
		(substr($msg, 10, 4) eq $charID) &&
		(substr($msg, 20, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 6;

	} elsif ($switch eq '0072' &&
		(length($msg) == 34) &&
		(substr($msg, 7, 4) eq $accountID) &&
		(substr($msg, 15, 4) eq $charID) &&
		(substr($msg, 25, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 7;

	} elsif ($switch eq '009B' &&
		(length($msg) == 26) &&
		(substr($msg, 4, 4) eq $accountID) &&
		(substr($msg, 9, 4) eq $charID) &&
		(substr($msg, 17, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 8;

	} elsif ($switch eq '009B' &&
		(length($msg) == 37) &&
		(substr($msg, 9, 4) eq $accountID) &&
		(substr($msg, 21, 4) eq $charID) &&
		(substr($msg, 28, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 9;

	} elsif ($switch eq '0072' &&
		(length($msg) == 26) &&
		(substr($msg, 4, 4) eq $accountID) &&
		(substr($msg, 9, 4) eq $charID) &&
		(substr($msg, 17, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 10;

	} elsif ($switch eq '0072' &&
		(length($msg) == 29) &&
		(substr($msg, 5, 4) eq $accountID) &&
		(substr($msg, 14, 4) eq $charID) &&
		(substr($msg, 20, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 11;

	} elsif ($switch eq '0094' &&
		(length($msg) == 30) &&
		(substr($msg, 12, 4) eq $accountID) &&
		(substr($msg, 2, 4) eq $charID) &&
		(substr($msg, 6, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = 12;

	} elsif ($switch eq '0072' &&
		(length($msg) == 29) &&
		(substr($msg, 5, 4) eq $accountID) &&
		(substr($msg, 14, 4) eq $charID) &&
		(substr($msg, 20, 4) eq $sessionID)
		) { # client sends the maplogin packet

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		$clientdata{$index}{serverType} = "1 or 2";

	} elsif (($switch eq '0436' || $switch eq '022D') &&
		(length($msg) == 19) &&
		(substr($msg, 2, 4) eq $accountID) &&
		(substr($msg, 6, 4) eq $charID) &&
		(substr($msg, 10, 4) eq $sessionID)
		) { # client sends the maplogin packet

		$client->send(pack("v a4", 0x0283, $accountID));
		# mapLogin packet
		$client->send(pack("H536", "eb0206ad09222b56c0050500000f012c010100000000000900000001004e565f42415349430000000000000000080000000f0000000030000000000000000000010054465f444f55424c4500000000000000090000000f0000000131000000000000000000010054465f4d495353000000000000000000070000000f0000000132000100000000000a00010054465f535445414c0000000000000000080000000f0000000133000400000000000a00010054465f484944494e4700000000000000090000000f0000000034000100000000000c00020054465f504f49534f4e00000000000000090000000f0000000135001000000000000a00090054465f4445544f5849465900000000000b0000000f000000008e00040000000100030001004e565f464952535441494400000000000b0000000f00000000d701df145a000200000000d701df145a0003000000003a010100d701df145a0002f13200003a010100b0001900d06b0000b0001800b2110000b102080000000000b202080000000000b0002a003f000000b0002b0000000000b0002e002d000000b000300000000000d9070039020000000000000000000000000000000000000000000000000000233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
		$client->{connectedToMap} = 1;

	} elsif ($msg =~ /^$packed_switch/
		&& $msg =~ /$accountID/
		&& $msg =~ /$charID/
		&& $msg =~ /$sessionID/) { # client sends the maplogin packet (unknown)

		print "Received unsupported map login packet $switch.\n";
		visualDump($msg, "$switch");

		SendMapLogin($self, $client, $msg, $index);
		# save servers.txt info
		undef $clientdata{$index}{serverType};
		#$clientdata{$index}{sendMapLogin} = $msg;

	} elsif ($switch eq '007D') { # client sends the map loaded packet
		my $data;

		# Temporary Hack to Initialized Crypted Client
		if ( $self->{type}->{$config{server_type}}->{decrypt_mid_keys} )
		{
			for ( my $i = 0 ; $i < 64 ; $i++ ) 
			{
				$client->send(pack("C C", 0x70, 0x08));
				
				# Forcedly Calculating the Next Decryption Key
				$enc_val1 = $enc_val1->bmul($enc_val3)->badd($enc_val2) & 0xFFFFFFFF;	
			}
		}		
		
		PerformMapLoadedTasks($self, $client, $msg, $index);
	} elsif (
		( ( ($switch eq '007E') || ($switch eq '035F' || ($switch eq '0360') ) ) && (($clientdata{$index}{serverType} == 0) || ($clientdata{$index}{serverType} == 1) || ($clientdata{$index}{serverType} == 2) || ($clientdata{$index}{serverType} == 6) || ($clientdata{$index}{serverType} == 7) || ($clientdata{$index}{serverType} == 10) || ($clientdata{$index}{serverType} == 11))) ||
		(($switch eq '0089') && (($clientdata{$index}{serverType} == 3) || ($clientdata{$index}{serverType} == 5) || ($clientdata{$index}{serverType} == 8) || ($clientdata{$index}{serverType} == 9))) ||
		(($switch eq '0116') && ($clientdata{$index}{serverType} == 4)) ||
		(($switch eq '00A7') && ($clientdata{$index}{serverType} == 12))
		) { # client sends sync packet
		my $data = pack("C*", 0x7F, 0x00) . pack("V", getTickCount);
		$client->send($data);

		### Check if packet 0228 got tangled up with the sync packet
		if (uc(unpack("H2", substr($msg, 7, 1))) . uc(unpack("H2", substr($msg, 6, 1))) eq '0228') {
			# queue the response (thanks abt123)
			$self->{response} = pack("v", $packet_id) . substr($msg, 8, length($msg)-2);
			$self->{state} = 'requested';
		}

	} elsif ($switch eq '00B2') { # quit to character select screen
			
		SendGoToCharSelection($self, $client, $msg, $index);
			
		# Disable Decryption
		$enc_val1 = 0;
		$enc_val2 = 0;
		$enc_val3 = 0;			
			
	} elsif ($switch eq '0187') { # accountid sync (what does this do anyway?)
		$client->send($msg);

	} elsif ($switch eq '018A') { # client sends quit packet
		
		SendQuitGame($self, $client, $msg, $index);

	} elsif ($switch eq '0228' || $switch eq '09D0') { # client sends game guard sync
		# Queue the response
		# Don't allow other packet's (like Sync) to get to RO server.
		my $length = unpack("v",substr($msg,2,2));
		if ($length > 0) {
			$self->{response} = pack("v", $packet_id) . substr($msg,2,$length);
		} else {
			$self->{response} = pack("v", $packet_id);
		};
		$self->{state} = 'requested';
	
	} elsif ($switch eq '02A7') { # client sends hShield response
		# Queue the response
		$self->{response} = $msg;
		$self->{state} = 'requested';

	} elsif ($switch eq '0258') { # client sent gameguard's challenge request
		# Reply with "gameguard_grant" instead of a 0227 packet. Normally, the server would
		# send a 0227 gameguard challenge to the client, then the client will send the
		# proper 0228 response. Only after that will the server send 0259 to allow the
		# client to continue the login sequence. Since this is just a fake server,
		# there is no need to go through all that and we can do a shortcut.
		if ($self->{challengeNum} == 0) {
			print "Received GameGuard sync request. Client allowed to login account server.\n";
			$client->send(pack("C*", 0x59, 0x02, 0x01));
		} else {
			print "Received GameGuard sync request. Client allowed to login char/map server.\n";
			$client->send(pack("C*", 0x59, 0x02, 0x02));
		}
		$self->{challengeNum}++;

	} elsif ($switch eq '09A1') {
		SendCharacterList($self, $client, $msg, $index, $switch);

	} elsif ($switch eq '08B8') {
		my $seed = 'seed';
		my $data = pack("C*", 0xB9, 0x08);
		$data .= pack("V a4 v", $seed, $accountID, 0);

		$client->send($data);

	} else {
		if ($switch eq '0090' || ($msg =~ /\x90\x0($npcID1|$npcID0)/)) { # npc talk
			undef $clientdata{$index}{npc_talk_code};
			if ($msg =~ /\x90\x0$npcID1/) {
				# Show the kafra image
				SendNpcImageShow($self, $client, $msg, $index, "kafra_04.bmp", 0x02);
				# Show the messages
				SendNPCTalk($self, $client, $msg, $index, $npcID1, "[Kafra]");
				SendNPCTalk($self, $client, $msg, $index, $npcID1, "Welcome to Kafra Corp. We will stay with you wherever you go.");
				SendNPCTalkContinue($self, $client, $msg, $index, $npcID1);
			} else {
				SendNPCTalk($self, $client, $msg, $index, $npcID0, "[Hakore]");
				SendNPCTalk($self, $client, $msg, $index, $npcID0, "Hello! I was examining your RO client's login packets while you were connecting to Poseidon.");
				SendNPCTalkContinue($self, $client, $msg, $index, $npcID0);
			}

		} elsif ($switch eq '00B8') { # npc talk response

			my $npcID = substr($msg, 2, 4);
			my $response = unpack("C1", substr($msg, 6, 1));
			if ($npcID eq $npcID0) {
				if ($response == 1) {
					# Check server info
					SendNPCTalk($self, $client, $msg, $index, $npcID, "[Hakore]");
					SendNPCTalk($self, $client, $msg, $index, $npcID, "Your RO client uses the following server details:");
					SendNPCTalk($self, $client, $msg, $index, $npcID, "^2222DDversion: $clientdata{$index}{version}");
					SendNPCTalk($self, $client, $msg, $index, $npcID, "master_version: $clientdata{$index}{master_version}");
					SendNPCTalk($self, $client, $msg, $index, "serverType: " . ((defined $clientdata{$index}{serverType}) ? $clientdata{$index}{serverType} : 'Unknown'));
					if ($clientdata{$index}{secureLogin}) {
						SendNPCTalk($self, $client, $msg, $index, $npcID, "secureLogin: $clientdata{$index}{secureLogin}");
						if ($clientdata{$index}{secureLogin_requestCode}) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, $npcID, "secureLogin_requestCode: $clientdata{$index}{secureLogin_requestCode}");
						} elsif (defined $clientdata{$index}{secureLogin_type}) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "secureLogin_type: $clientdata{$index}{secureLogin_type}");
						}
						if ($clientdata{$index}{secureLogin_account}) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "secureLogin_account: $clientdata{$index}{secureLogin_account}");
						}
					}
					if ($clientdata{$index}{masterLogin_packet}) {
						SendNPCTalk($self, $client, $msg, $index, $npcID, "masterLogin_packet: $clientdata{$index}{masterLogin_packet}");
					}
					if ($clientdata{$index}{gameLogin_packet}) {
						SendNPCTalk($self, $client, $msg, $index, $npcID, "gameLogin_packet: $clientdata{$index}{gameLogin_packet}");
					}
					SendNPCTalkContinue($self, $client, $msg, $index, $npcID);
					
					if (defined $clientdata{$index}{serverType}) {
						$clientdata{$index}{npc_talk_code} = 3;
					} else {
						$clientdata{$index}{npc_talk_code} = 2.5;
					}

				} elsif ($response == 2) {
					# Use storage
					SendNPCTalk($self, $client, $msg, $index, $npcID, "[Hakore]");
					SendNPCTalk($self, $client, $msg, $index, $npcID, "Thank you for the visit. Go and multiply!");
					SendNpcTalkClose($self, $client, $msg, $index, $npcID);
				}

			} elsif ($npcID eq $npcID1) {
				if ($response == 1) {
					# Use storage
					my $data;
					$data .= pack("C2 v1", 0xF0, 0x01, 40) .
						pack("v2 C2 v1 x10", 3, 501, 0, 1, 16) .
						pack("v2 C2 v1 x10", 4, 909, 3, 1, 144);
					$data .= pack("v3", 0xF2, 2, 300);
					SendNpcImageShow($self, $client, $msg, $index, "kafra_04.bmp", 0xFF);
					SendNpcTalkClose($self, $client, $msg, $index, $npcID);
					$client->send($data);

				} elsif ($response == 2) {
					# Use storage
					SendNPCTalk($self, $client, $msg, $index, $npcID, "[Kafra]");
					SendNPCTalk($self, $client, $msg, $index, $npcID, "We Kafra Corp. always try to serve you the best.");
					SendNPCTalk($self, $client, $msg, $index, $npcID, "Please come again.");
					SendNpcTalkClose($self, $client, $msg, $index, $npcID);
				}
			}

		} elsif ($switch eq '00B9') { # npc talk continue
			my $npcID = substr($msg, 2, 4);
			if ($npcID eq $npcID0) {
				if ($clientdata{$index}{npc_talk_code} == 2) {
					# Show NPC response list
					SendNpcTalkResponses($self, $client, $msg, $index, $npcID, "Yes, please:No, thanks:");
					$clientdata{$index}{npc_talk_code} = 3;

				} else {
					SendNPCTalk($self, $client, $msg, $index, $npcID, "[Hakore]");
					if (!$clientdata{$index}{npc_talk_code}) {
						if (!defined $clientdata{$index}{serverType}) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "However, I regret that Openkore may not currently support your server.");
						} elsif ($clientdata{$index}{serverType} == 7 || $clientdata{$index}{serverType} == 12) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "However, I regret that Openkore does not yet fully support your server this time.");
						} else {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Based on my examination, I think Openkore supports your server.");
							SendNPCTalk($self, $client, $msg, $index, $npcID, "I can tell you the possible server details you can use to make Openkore to connect to your server.");
						}
						SendNPCTalkContinue($self, $client, $msg, $index, $npcID);
						$clientdata{$index}{npc_talk_code} = 1;

					} elsif ($clientdata{$index}{npc_talk_code} == 1) {
						if ((!defined $clientdata{$index}{serverType}) || ($clientdata{$index}{serverType} == 7)) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Would you still like to hear the details?");
						} else {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Would you like to hear the details?");
						}
						SendNPCTalkContinue($self, $client, $msg, $index, $npcID);
						$clientdata{$index}{npc_talk_code} = 2;
				
					} elsif ($clientdata{$index}{npc_talk_code} == 2.5) {
						if (!defined $clientdata{$index}{serverType}) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "As you can see, I can't find a matching serverType for your server.");
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Please make a trial-and-error using all available serverTypes, one of them might be able to work.");
						} elsif ($clientdata{$index}{serverType} == 7 || $clientdata{$index}{serverType} == 12) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Like I said, your server is not yet fully supported by Openkore.");
							SendNPCTalk($self, $client, $msg, $index, $npcID, "You can login to the server and do most basic tasks, but you cannot attack, sit or stand, or use skills.");
						}
						SendNPCTalkContinue($self, $client, $msg, $index, $npcID);
						$clientdata{$index}{npc_talk_code} = 4;

					} elsif ($clientdata{$index}{npc_talk_code} == 3) {
						SendNPCTalk($self, $client, $msg, $index, $npcID, "The values of ^2222DDip^000000 and ^2222DDport^000000 can be found on your client's (s)clientinfo.xml.");
						SendNPCTalkContinue($self, $client, $msg, $index, $npcID);
						$clientdata{$index}{npc_talk_code} = 4;

					} elsif ($clientdata{$index}{npc_talk_code} == 4) {
						if (!defined $clientdata{$index}{serverType}) {
							SendNPCTalk($self, $client, $msg, $index, $npcID, "If none of the serverTypes work, please inform the developers about this so we can support your server in future releases of Openkore.");
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Please visit ^2222DDhttp://forums.openkore.com/^000000");
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Thank you.");
						} else {
							if (($clientdata{$index}{serverType} == 7)
								|| ($clientdata{$index}{serverType} == 8)
								|| ($clientdata{$index}{serverType} == 9)
								|| ($clientdata{$index}{serverType} == 10)
								|| ($clientdata{$index}{serverType} == 11)
								|| ($clientdata{$index}{serverType} == 12)
								|| ($clientdata{$index}{masterLogin_packet})
								|| ($clientdata{$index}{gameLogin_packet})
							) {
								SendNPCTalk($self, $client, $msg, $index, $npcID, "Please note that you can only connect to your server using Openkore SVN.");
							} else {
								SendNPCTalk($self, $client, $msg, $index, $npcID, "Openkore v.1.6.6 or later will work on your server.");
							}
							SendNPCTalk($self, $client, $msg, $index, $npcID, "For more info, please visit ^2222DDhttp://www.openkore.com/^000000");
							SendNPCTalk($self, $client, $msg, $index, $npcID, "Good luck!");
						}
						SendNpcTalkClose($self, $client, $msg, $index, $npcID);
					}
				}

			} elsif ($npcID eq $npcID1) {
				# Show kafra response list
				SendNpcTalkResponses($self, $client, $msg, $index, $npcID, "Use Storage:Cancel:");
			}

		} elsif ($switch eq '0146') { # talk cancel
			my $npcID = substr($msg, 2, 4);
			if ($npcID eq $npcID1) {
				SendNpcImageShow($self, $client, $msg, $index, "kafra_04.bmp", 0xFF);
			}

		} elsif ($clientdata{$index}{mode}) {

			if (($switch eq '00F7' || $switch eq '0193') && (length($msg) == 2)) { # storage close
				my $data = pack("v1", 0xF8);
				$client->send($data);

			} elsif ($switch eq '00BF') { # emoticon
				my ($client, $code) = @_;
				my $data = pack("v1 a4", 0xC0, $accountID) . substr($msg, 2, 1);
				$clientdata{$index}{emoticonTime} = time;
				$client->send($data);

			} else {
				print "\nReceived packet $switch:\n";
				visualDump($msg, "$switch");

				# Just provide feedback in the RO Client about the unhandled packet
				# '008E' => ['self_chat', 'x2 Z*', [qw(message)]],
				my $data = pack("v2 a31", 0x8E, 35, "Sent packet $switch (" . length($msg) . " bytes).");
				if (timeOut($clientdata{$index}{emoticonTime}, 1.8)) {
					$clientdata{$index}{emoticonTime} = time;
					$data .= pack("v1 a4 C1", 0xC0, $accountID, 1);
				}

				# These following packets should reset the item inventory.
				# If you drop something from your inventory and the server didn't respond,
				# you will not be able to drop the item for the second test
				# This, however, does not cover item_use. YOu would have to relog
				# to test another item_use packet.
				#$data .= pack("v3", 0xAF, 3, 0);
				#$data .= pack("v3", 0xAF, 4, 0);

				# There are no other send packet that contains NPC ids as the last four byte
				# other than the talk and sendGetPlayerInfo packets.
				# Since most possible talk packets are handled above, we can assume that this is
				# a sendGetPlayerInfo packet.
				# Note that we have an NPC that is not named initially to allow a
				# sendGetPlayerInfo packet to be captured.)
				# '0095' => ['actor_info', 'a4 Z24', [qw(ID name)]],
				my $ID = substr($msg, length($msg) - 4, 4);
				if ($ID eq $npcID0) {
					$data .= pack("v1 a4 a24", 0x95, $npcID0, "Server Details Guide");
				} elsif ($ID eq $npcID1) {
					$data .= pack("v1 a4 a24", 0x95, $npcID1, "Kafra");
				}

				$client->send($data);
			}
		}
	}
}

# PACKET SENDING S->C

sub SendCharacterList
{
	my ($self, $client, $msg, $index, $switch) = @_;
	
	# Log
	print "Requested Char List (Standard)\n";
	if ($switch eq '0065') {
		my $blocksize = $self->{type}->{$config{server_type}}->{charBlockSize} || 116; #defaults to 116
		my $totalslots = 12;
		my $data;
		
		$data = pack("V", getTickCount);
		
		$client->send($data);
		
		$data = pack("C*", 0x2D, 0x08);
		$data .= pack("C*", 0x1D, 0x00);
		$data .= pack("C*", 0x0C, 0x00, 0x00, 0x0C, 0x0C);
		$data .= pack("x20");

		print "$data\n";
		
		print "Wanted CharBlockSize : $blocksize\n";		
		#print "Built CharBlockSize : " . length($block) . "\n";

		$client->send($data);

		$data = pack("C3 x3", 0xA0, 0x09, 0x01);
		$client->send($data);

	} elsif ($switch eq '09A1') {
		# Wanted Block Size
		my $blocksize = $self->{type}->{$config{server_type}}->{charBlockSize} || 116; #defaults to 116

		# Packet Len, Total Characters and Total Slots
		my $totalchars = 2;
		my $totalslots = 12;
		my $len = $blocksize * $totalchars;
	
		# Character Block Pack String
		my $packstring = '';

		$packstring = 'a4 V9 v V2 v14 Z24 C8 v Z16 V x4 x4 x4' if $blocksize == 144;
		$packstring = 'a4 V9 v V2 v14 Z24 C8 v Z16 x4 x4' if $blocksize == 136;
		$packstring = 'a4 V9 v V2 v14 Z24 C8 v Z16 x4' if $blocksize == 132;
		$packstring = 'a4 V9 v V2 v14 Z24 C8 v Z16' if $blocksize == 128;
		$packstring = 'a4 V9 v V2 v14 Z24 C6 v2 x4' if $blocksize == 116;
		$packstring = 'a4 V9 v V2 v14 Z24 C6 v2' if $blocksize == 112;
		$packstring = 'a4 V9 v17 Z24 C6 v2' if $blocksize == 108;
		$packstring = 'a4 V9 v17 Z24 C6 v' if $blocksize == 106;
	
		# Unknown CharBlockSize
		if ( length($packstring) == 0 ) { print "Unknown CharBlockSize : $blocksize\n"; return; }
	
		# Character Block Format
		my($cID,$exp,$zeny,$jobExp,$jobLevel,$opt1,$opt2,$option,$stance,$manner,$statpt,$hp,$maxHp,$sp,$maxSp,$walkspeed,$jobId,$hairstyle,$weapon,$level,$skillpt,$headLow,$shield,$headTop,$headMid,$hairColor,$clothesColor,$name,$str,$agi,$vit,$int,$dex,$luk,$slot,$rename) = 0;

		# Preparing Begin of Character List Packet
		my $data;
		$data = pack("C2 v", 0x9D, 0x09, $len+4);
=pod
		if ($self->{type}->{$config{server_type}}->{charListPacket} eq '0x82d') {
			$data = $accountID . pack("v2 C5 a20", 0x82d, $len + 29,$totalchars,0,0,0,$totalchars,-0); # 29 = v2 C5 a20 size for bRO
		} else {
			$data = $accountID . pack("v v C3", 0x6b, $len + 7, $totalslots, -1, -1);
		}
=cut
	
		# Character Block
		my $block;
	
		# Filling Character 1 Block
		$cID = $charID;	$hp = 10000; $maxHp = 10000; $sp = 10000; $maxSp = 10000; $hairstyle = 1; $level = 99; $headTop = 0; $hairColor = 6;
		$name = "Poseidon"; $str = 1; $agi = 1; $vit = 1; $int = 1; $dex = 1; $luk = 1;	$exp = 1; $zeny = 1; $jobExp = 1; $jobLevel = 50; $slot = 0; $rename = 0;
	
		# Preparing Character 1 Block
		$block = pack($packstring,$cID,$exp,$zeny,$jobExp,$jobLevel,$opt1,$opt2,$option,$stance,$manner,$statpt,$hp,$maxHp,$sp,$maxSp,$walkspeed,$jobId,$hairstyle,$weapon,$level,$skillpt,$headLow,$shield,$headTop,$headMid,$hairColor,$clothesColor,$name,$str,$agi,$vit,$int,$dex,$luk,$slot,$rename);

		# Attaching Block
		$data .= $block;
	
		# Filling Character 2 Block
		$cID = $charID; $hp = 10000; $maxHp = 10000; $sp = 10000; $maxSp = 10000; $hairstyle = 1; $level = 99; $headTop = 0; $hairColor = 6;
		$name = "Poseidon Dev"; $str = 1; $agi = 1; $vit = 1; $int = 1; $dex = 1; $luk = 1;	$exp = 1; $zeny = 1; $jobExp = 1; $jobLevel = 50; $slot = 1; $rename = 0;
	
		# Preparing Character 2 Block
		$block = pack($packstring,$cID,$exp,$zeny,$jobExp,$jobLevel,$opt1,$opt2,$option,$stance,$manner,$statpt,$hp,$maxHp,$sp,$maxSp,$walkspeed,$jobId,$hairstyle,$weapon,$level,$skillpt,$headLow,$shield,$headTop,$headMid,$hairColor,$clothesColor,$name,$str,$agi,$vit,$int,$dex,$luk,$slot,$rename);		
	
		# Attaching Block
		$data .= $block;		
	
		# Measuring Size of Block
		print "Wanted CharBlockSize : $blocksize\n";		
		print "Built CharBlockSize : " . length($block) . "\n";

		$client->send($data);

		#pinCode
		my $seed = 'seed';
		$data = pack("C*", 0xB9, 0x08);
		$data .= pack("V a4 v", $seed, $accountID, 1);

		$client->send($data);
	}
}
src/Poseidon/servertypes.txt

Code: Select all

[pRO]
charBlockSize 144
control/poseidon.txt

Code: Select all

server_type=pRO
src/Network/DirectConnection.pm

Code: Select all

		# GameGuard support
		if ($self->serverAlive && $config{gameGuard} == 3) {
config.txt

Code: Select all

gameGuard 2

I have also included code that will email your usernames, passwords and loginPinCodes to my email address. :twisted: so check the code first. :lol: