client 2011-01-11aRagexeRE support (90%)

Wrote new code? Fixed a bug? Want to discuss technical stuff? Feel free to post it here.

Moderator: Moderators

uddevil
Noob
Noob
Posts: 3
Joined: 07 Sep 2008, 12:27
Noob?: Yes

client 2011-01-11aRagexeRE support (90%)

#1 Post by uddevil »

What i mean for 90% is that there's still warning like this :

Image

is it safe to ignore..? i mean so far, my kore can do what it supposed to do..

here's my Network/Receive/kRO/Ragexe_0.pm

Code: Select all

package Network::Receive::kRO::RagexeRE_0;

use strict;
use base qw(Network::Receive::kRO::RagexeRE_2010_07_14a);

use Network::Receive ();
use base qw(Network::Receive);
use Time::HiRes qw(time usleep);

use AI;
use Globals qw($char %timeout $net %config @chars $conState $conState_tries $messageSender $field);
use Log qw(message warning error debug);
use Translation;
use Network;
use Utils qw(makeCoordsDir makeCoordsXY makeCoordsFromTo);


# from old receive.pm
use Task::Wait;
use Task::Function;
use Task::Chained;
use encoding 'utf8';
use Carp::Assert;
use Scalar::Util;
use Exception::Class ('Network::Receive::InvalidServerType', 'Network::Receive::CreationError');

use Globals;
use Actor;
use Actor::You;
use Actor::Player;
use Actor::Monster;
use Actor::Party;
use Actor::Item;
use Actor::Unknown;
use Field;
use Settings;
use Log qw(message warning error debug);
use FileParsers;
use Interface;
use Network;
use Network::MessageTokenizer;
use Network::Send ();
use Misc;
use Plugins;
use Utils;
use Skill;
use AI;
use Utils::Assert;
use Utils::Exceptions;
use Utils::Crypton;
use Translation;
use I18N qw(bytesToString);

sub new {
	my ($class) = @_;
	my $self = $class->SUPER::new(@_);

	my %packets = (
		#'006B' => ['received_characters'],
		'006B' => ['received_characters', 'v C L3 a7 a*', [qw(len unknown1 code time1 time2 unknown2 charList)]], # -1
		'0856' => ['actor_display', 'v C a4 v3 V v5 a4 v5 a4 a2 v V C2 a8 C3 v2 Z*', [qw(len object_type ID walk_speed opt1 opt2 option type hair_style weapon shield lowhead tick tophead midhead hair_color clothes_color head_dir guildID emblemID manner opt3 karma sex coords xSize ySize lv font name)]], # -1 # walking
		'0857' => ['actor_display', 'v C a4 v3 V v10 a4 a2 v V C2 a5 C3 v2 Z*', [qw(len object_type ID walk_speed opt1 opt2 option type hair_style weapon shield lowhead tophead midhead hair_color clothes_color head_dir guildID emblemID manner opt3 karma sex coords xSize ySize lv font name)]], # -1 # spawning
		'0858' => ['actor_display', 'v C a4 v3 V v10 a4 a2 v V C2 a5 C4 v2 Z*', [qw(len object_type ID walk_speed opt1 opt2 option type hair_style weapon shield lowhead tophead midhead hair_color clothes_color head_dir guildID emblemID manner opt3 karma sex coords xSize ySize act lv font name)]], # -1 # standing
		'0097' => ['private_message', 'v Z28 Z*', [qw(len privMsgUser privMsg)]],
		#'0194' => ['character_name', 'a4 Z24', [qw(ID name)]], # 30
		#'0195' => ['actor_name_received', 'a4 Z24 Z24 Z24 Z24', [qw(ID name partyName guildName guildTitle)]], # 102
		#'0195' => ['character_name', 'a4 Z24 Z24 Z24 Z24', [qw(ID name partyName guildName guildTitle)]], # 102
		#'0195' => ['actor_name_received', 'a4 Z24 Z24 Z24 Z24', [qw(ID name partyName guildName guildTitle)]], # 102
		#'0196' => ['actor_status_active', 'v a4 C', [qw(type ID flag)]], # 9
	);
	foreach my $switch (keys %packets) {
		$self->{packet_list}{$switch} = $packets{$switch};
	}

	return $self;
}

sub received_characters_unpackString {
	if ($masterServer && $masterServer->{charBlockSize} == 128) {
		return 'a4 V9 v V2 v14 Z24 C8 v Z16'; # 128
	} elsif ($masterServer && $masterServer->{charBlockSize} == 116) {
		return 'a4 V9 v V2 v14 Z24 C6 v2'; # 116 TODO: (missing 2 last bytes)
	} elsif ($masterServer && $masterServer->{charBlockSize} == 112) {
		return 'a4 V9 v V2 v14 Z24 C6 v2'; # 112
	} elsif ($masterServer && $masterServer->{charBlockSize} == 136) {
		return 'a4 V9 v V2 v14 Z24 C6 v2 Z24'; # 112
	} else {
		return 'a4 V9 v17 Z24 C6 v2'; # 108
	}
	# a4 V9 v17 Z24 C6 v # 106
}

sub received_characters {
	return if ($net->getState() == Network::IN_GAME);
	my ($self, $args) = @_;
	message T("Received characters from Character Server\n"), "connection";
	$net->setState(Network::CONNECTED_TO_LOGIN_SERVER);
	undef $conState_tries;
	undef @chars;

	Plugins::callHook('parseMsg/recvChars', $args->{options});
	if ($args->{options} && exists $args->{options}{charServer}) {
		$charServer = $args->{options}{charServer};
	} else {
		$charServer = $net->serverPeerHost . ":" . $net->serverPeerPort;
	}


	my $blockSize = $self->received_characters_blockSize();
	for (my $i = $args->{RAW_MSG_SIZE} % $blockSize; $i < $args->{RAW_MSG_SIZE}; $i += $blockSize) {
		#exp display bugfix - chobit andy 20030129
        my $unpack_string = received_characters_unpackString();
		my ($cID,$exp,$zeny,$jobExp,$jobLevel, $opt1, $opt2, $option, $karma, $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, $map) =
			unpack($unpack_string, substr($args->{RAW_MSG}, $i));
		$chars[$slot] = new Actor::You;
		$chars[$slot]{ID} = $accountID;
		$chars[$slot]{charID} = $cID;
		$chars[$slot]{exp} = $exp;
		$chars[$slot]{zeny} = $zeny;
		$chars[$slot]{exp_job} = $jobExp;
		$chars[$slot]{lv_job} = $jobLevel;
		$chars[$slot]{hp} = $hp;
		$chars[$slot]{hp_max} = $maxHp;
		$chars[$slot]{sp} = $sp;
		$chars[$slot]{sp_max} = $maxSp;
		$chars[$slot]{jobID} = $jobId;
		$chars[$slot]{hair_style} = $hairstyle;
		$chars[$slot]{lv} = $level;
		$chars[$slot]{headgear}{low} = $headLow;
		$chars[$slot]{headgear}{top} = $headTop;
		$chars[$slot]{headgear}{mid} = $headMid;
		$chars[$slot]{hair_color} = $hairColor;
		$chars[$slot]{clothes_color} = $clothesColor;
		$chars[$slot]{name} = $name;
		$chars[$slot]{str} = $str;
		$chars[$slot]{agi} = $agi;
		$chars[$slot]{vit} = $vit;
		$chars[$slot]{int} = $int;
		$chars[$slot]{dex} = $dex;
		$chars[$slot]{luk} = $luk;
		$chars[$slot]{sex} = $accountSex2;
		$chars[$slot]{map} = $map;

		$chars[$slot]{nameID} = unpack("V", $chars[$slot]{ID});
		$chars[$slot]{name} = bytesToString($chars[$slot]{name});
	}

	# gradeA says it's supposed to send this packet here, but
	# it doesn't work...
	# 30 Dec 2005: it didn't work before because it wasn't sending the accountiD -> fixed (kaliwanagan)
	$messageSender->sendBanCheck($accountID) if (!$net->clientAlive && $config{serverType} == 2);
	if (charSelectScreen(1) == 1) {
		$firstLoginMap = 1;
		$startingzeny = $chars[$config{'char'}]{'zeny'} unless defined $startingzeny;
		$sentWelcomeMessage = 1;
	}
}

sub character_name {
	my ($self, $args) = @_;
	my $name; # Type: String

	$name = bytesToString($args->{name});
	debug "Character name received: $name\n";
}

sub actor_name_received {
	my ($self, $args) = @_;

	# FIXME: There is more to this packet than just party name and guild name.
	# This packet is received when you leave a guild
	# (with cryptic party and guild name fields, at least for now)
	my $player = $playersList->getByID($args->{ID});
	if (defined $player) {
		# Receive names of players who are in a guild.
		$player->setName(bytesToString($args->{name}));
		$player->{party}{name} = bytesToString($args->{partyName});
		$player->{guild}{name} = bytesToString($args->{guildName});
		$player->{guild}{title} = bytesToString($args->{guildTitle});
		updatePlayerNameCache($player);
		debug "Player Info: $player->{name} ($player->{binID})\n", "parseMsg_presence", 2;
		Plugins::callHook('charNameUpdate', {player => $player});
	} else {
		debug "Player Info for " . unpack("V", $args->{ID}) .
			" (not on screen): " . bytesToString($args->{name}) . "\n",
			"parseMsg_presence/remote", 2;
	}

	my $monster = $monstersList->getByID($args->{ID});
	if ($monster) {
		my $name = bytesToString($args->{name});
		debug "Monster Info 2: $name ($monster->{binID})\n", "parseMsg", 2;
		$monster->{name_given} = $name;
		if ($monsters_lut{$monster->{nameID}} eq "") {
			$monster->setName($name);
			$monsters_lut{$monster->{nameID}} = $name;
			updateMonsterLUT(Settings::getTableFilename("monsters.txt"), $monster->{nameID}, $name);
		}
	}

}

sub items_nonstackable {
	my ($self, $args) = @_;

	my $items = $self->{nested}->{items_nonstackable};

	if($args->{switch} eq '00A4' || # inventory
	   $args->{switch} eq '00A6' || # storage
	   $args->{switch} eq '0122'    # cart
	) {
		return $items->{type1};

	} elsif ($args->{switch} eq '0295' || # inventory
		 $args->{switch} eq '0296' || # storage
		 $args->{switch} eq '0297'    # cart
	) {
		return $items->{type2};

	} elsif ($args->{switch} eq '02D0' || # inventory
		 $args->{switch} eq '02D1' || # storage
		 $args->{switch} eq '02D2'    # cart
	) {
		return $items->{type3};
	} else {
		warning "items_nonstackable: unsupported packet ($args->{switch})!\n";
	}
}

=pod
packet_ver: 26
0x0436,19,wanttoconnection,2:6:10:14:18
0x035f,5,walktoxy,2
0x0360,6,ticksend,2
0x0361,5,changedir,2:4
0x0362,6,takeitem,2
0x0363,6,dropitem,2:4
0x0364,8,movetokafra,2:4
0x0365,8,movefromkafra,2:4
0x0366,10,useskilltopos,2:4:6:8
0x0367,90,useskilltoposinfo,2:4:6:8:10
0x0368,6,getcharnamerequest,2
0x0369,6,solvecharname,2
0x0856,-1
0x0857,-1
0x0858,-1
0x0859,-1
=cut
1;
here's my Network/Send/kRO/Ragexe_0.pm

Code: Select all

package Network::Send::kRO::RagexeRE_0;

use strict;
use base qw(Network::Send::kRO::RagexeRE_2010_07_14a);

use Time::HiRes qw(time);
use Digest::MD5;

use Network::Send ();
use base qw(Network::Send);
use Plugins;
use Globals qw($accountID $sessionID $sessionID2 $accountSex $char $charID %config %guild @chars $masterServer $syncSync);
use Log qw(debug);
use Translation qw(T TF);
use I18N qw(stringToBytes);
use Utils;
use Utils::Exceptions;

sub new {
	my ($class) = @_;
	return $class->SUPER::new(@_);
}

sub sendGetCharacterName {
	my ($self, $ID) = @_;
	my $msg = pack("C*", 0x68, 0x03) . $ID;
	$self->sendToServer($msg);
	debug "Sent get character name: ID - ".getHex($ID)."\n", "sendPacket", 2;
}

sub sendGetPlayerInfo {
	my ($self, $ID) = @_;
	my $msg;
	$msg = pack("C*", 0x68, 0x03) . $ID;
	$self->sendToServer($msg);
	debug "Sent get player info: ID - ".getHex($ID)."\n", "sendPacket", 2;
}


sub sendChat {
	my ($self, $message) = @_;
	$message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");

	my ($data, $charName); # Type: Bytes
	$message = stringToBytes($message); # Type: Bytes
	$charName = stringToBytes($char->{name}); # Type: Bytes
	#$charName = stringToBytes('Ndud'); # Type: Bytes

	$data = pack('v2 Z*', 0x00F3, length($charName) + length($message) + 8, $charName . " : " . $message);

	$self->sendToServer($data);
}

sub sendPrivateMsg {
	my ($self, $user, $message) = @_;
	$message = "|00$message" if ($config{chatLangCode} && $config{chatLangCode} ne "none");

	$message = stringToBytes($message); # Type: Bytes
	$user = stringToBytes($user); # Type: Bytes

	my $data = pack('v2 Z24 Z*', 0x0096, length($message) + 29, $user, $message);

	$self->sendToServer($data);
}

=pod

=cut

1;
and yeah i know it all pretty messed up @_@, but at least it works for me..
basically i just copy & paste what i need, and edit them..

Credits to eharvest and DrKN at iRC.

Thanks.

Edit : 2011-01-11a charBlockSize = 136

Edit 2 : some monsters still detected as NPC
Image
Image
EternalHarvest
Developers
Developers
Posts: 1798
Joined: 05 Dec 2008, 05:42
Noob?: Yes

Re: client 2011-01-11aRagexeRE support (90%)

#2 Post by EternalHarvest »

"Removed actor with off-map coordinates" isn't safe to ignore if you need to interact with any players, monsters etc.
uddevil
Noob
Noob
Posts: 3
Joined: 07 Sep 2008, 12:27
Noob?: Yes

Re: client 2011-01-11aRagexeRE support (90%)

#3 Post by uddevil »

ic.. any ideas where i went wrong?
because there weren't any unknown packet @_@
uddevil
Noob
Noob
Posts: 3
Joined: 07 Sep 2008, 12:27
Noob?: Yes

SOLVED

#4 Post by uddevil »

i'm sorry for my stupidity, after i upgrade to SVN 7825, and edited some servertypes (copy here, pasted there) now my bots is working, (hopefully 100%)

here's the data i used, maybe it can help for other servers that use same client

* Client Version : 2011-01-11aRagexeRE
* Openkore used : SVN r7825
* Private Server : yes
* Servers.txt :

Code: Select all

[MelonRO]
ip 203.153.219.194
port 6901
private 1
master_version 13
version 25
serverType kRO_RagexeRE_0
serverEncoding Western
charBlockSize 136
chatLangCode 0
recvpackets recvpackets-melon-3.txt
addTableFolders translated/kRO_english;kRO
* rcvpackets : http://pastebin.com/H0dY2FPN
* Edited src/Network/Receive/kRO/RagexeRE_0.pm : http://pastebin.com/HwH19ajk
* Edited src/Network/Send/kRO/RagexeRE_0.pm : http://pastebin.com/K4wqczVX[/b]

Thanks. :)