Wednesday, December 29, 2010

Modifying Openkore to Enable KS

Today, out of curious, I open inside my openkore openkore/scr folder to see what happen inside.There is a limitation every openkore user known, the bot will not kill steal others.So I try to look inside the scr/AI/Attack.pm to see what I can do to overcome the limitation.

And very lucky, I saw this block

# Check for kill steal and mob-training while moving
if ((AI::is("move", "route") && $args->{attackID} && AI::inQueue("attack")
&& timeOut($args->{movingWhileAttackingTimeout}, 0.2))) {



See the comment, our solution is here !!!!
Scroll down a bit an I found these line


# Check for kill steal while moving
if ($monster && !Misc::checkMonsterCleanness($ID)) {
message T("Dropping target - you will not kill steal others\n");


So the condition check is the Misc::checkMonsterCleanness. I can change to

Misc::checkMonsterCleanness($ID);
if ($monster && 0) {
message T("Dropping target - you will not kill steal others\n");


So it will condition will never met. To prevent error, I will call the function Misc::checkMonsterCleanness before the condition check.

To play safe, I didn't do that, I find the source of Misc::checkMonsterCleanness.
The file is scr/Misc.pm

Then, a simple search of keyword clean and I got here

##
# boolean checkMonsterCleanness(Bytes ID)
# ID: the monster's ID.
# Requires: $ID is a valid monster ID.
#
# Checks whether a monster is "clean" (not being attacked by anyone).
sub checkMonsterCleanness {
return 1 if (!$config{attackAuto});
my $ID = $_[0];
return 1 if ($playersList->getByID($ID));
my $monster = $monstersList->getByID($ID);

# If party attacked monster, or if monster attacked/missed party
if ($monster->{dmgFromParty} > 0 || $monster->{dmgToParty} > 0 || $monster->{missedToParty} > 0) {
return 1;
}

if ($config{aggressiveAntiKS}) {
# Aggressive anti-KS mode, for people who are paranoid about not kill stealing.

# If we attacked the monster first, do not drop it, we are being KSed
return 1 if ($monster->{dmgFromYou} || $monster->{missedFromYou});

# If others attacked the monster then always drop it, wether it attacked us or not!
return 0 if (($monster->{dmgFromPlayer} && %{$monster->{dmgFromPlayer}})
|| ($monster->{missedFromPlayer} && %{$monster->{missedFromPlayer}})
|| (($monster->{castOnByPlayer}) && %{$monster->{castOnByPlayer}})
|| (($monster->{castOnToPlayer}) && %{$monster->{castOnToPlayer}}));
}

# If monster attacked/missed you
return 1 if ($monster->{'dmgToYou'} || $monster->{'missedYou'});

# If we're in follow mode
if (defined(my $followIndex = AI::findAction("follow"))) {
my $following = AI::args($followIndex)->{following};
my $followID = AI::args($followIndex)->{ID};

if ($following) {
# And master attacked monster, or the monster attacked/missed master
if ($monster->{dmgToPlayer}{$followID} > 0
|| $monster->{missedToPlayer}{$followID} > 0
|| $monster->{dmgFromPlayer}{$followID} > 0) {
return 1;
}
}
}

if (objectInsideSpell($monster)) {
# Prohibit attacking this monster in the future
$monster->{dmgFromPlayer}{$char->{ID}} = 1;
return 0;
}

#check party casting on mob
my $allowed = 1;
if (scalar(keys %{$monster->{castOnByPlayer}}) > 0)
{
foreach (keys %{$monster->{castOnByPlayer}})
{
my $ID1=$_;
my $source = Actor::get($_);
unless ( existsInList($config{tankersList}, $source->{name}) ||
($char->{party} && %{$char->{party}} && $char->{party}{users}{$ID1} && %{$char->{party}{users}{$ID1}}))
{
$allowed = 0;
last;
}
}
}

# If monster hasn't been attacked by other players
if (scalar(keys %{$monster->{missedFromPlayer}}) == 0
&& scalar(keys %{$monster->{dmgFromPlayer}}) == 0
#&& scalar(keys %{$monster->{castOnByPlayer}}) == 0 #change to $allowed
&& $allowed

# and it hasn't attacked any other player
&& scalar(keys %{$monster->{missedToPlayer}}) == 0
&& scalar(keys %{$monster->{dmgToPlayer}}) == 0
&& scalar(keys %{$monster->{castOnToPlayer}}) == 0
) {
# The monster might be getting lured by another player.
# So we check whether it's walking towards any other player, but only
# if we haven't already attacked the monster.
if ($monster->{dmgFromYou} || $monster->{missedFromYou}) {
return 1;
} else {
return !objectIsMovingTowardsPlayer($monster);
}
}

# The monster didn't attack you.
# Other players attacked it, or it attacked other players.
if ($monster->{dmgFromYou} || $monster->{missedFromYou}) {
# If you have already attacked the monster before, then consider it clean
return 1;
}
# If you haven't attacked the monster yet, it's unclean.

return 0;
}


Then I make these changes

The comment said if the function return 1 show the the monster is clean and ok for attacking.

##
# boolean checkMonsterCleanness(Bytes ID)
# ID: the monster's ID.
# Requires: $ID is a valid monster ID.
#
# Checks whether a monster is "clean" (not being attacked by anyone).
sub checkMonsterCleanness {
return 1 if (!$config{attackAuto});
my $ID = $_[0];
return 1 if ($playersList->getByID($ID));
my $monster = $monstersList->getByID($ID);

# If party attacked monster, or if monster attacked/missed party
if ($monster->{dmgFromParty} > 0 || $monster->{dmgToParty} > 0 || $monster->{missedToParty} > 0) {
return 1;
}

if ($config{aggressiveAntiKS}) {
# Aggressive anti-KS mode, for people who are paranoid about not kill stealing.

# If we attacked the monster first, do not drop it, we are being KSed
return 1 if ($monster->{dmgFromYou} || $monster->{missedFromYou});

# If others attacked the monster then always drop it, wether it attacked us or not!
return 1 if (($monster->{dmgFromPlayer} && %{$monster->{dmgFromPlayer}})
|| ($monster->{missedFromPlayer} && %{$monster->{missedFromPlayer}})
|| (($monster->{castOnByPlayer}) && %{$monster->{castOnByPlayer}})
|| (($monster->{castOnToPlayer}) && %{$monster->{castOnToPlayer}}));
}

# If monster attacked/missed you
return 1 if ($monster->{'dmgToYou'} || $monster->{'missedYou'});

# If we're in follow mode
if (defined(my $followIndex = AI::findAction("follow"))) {
my $following = AI::args($followIndex)->{following};
my $followID = AI::args($followIndex)->{ID};

if ($following) {
# And master attacked monster, or the monster attacked/missed master
if ($monster->{dmgToPlayer}{$followID} > 0
|| $monster->{missedToPlayer}{$followID} > 0
|| $monster->{dmgFromPlayer}{$followID} > 0) {
return 1;
}
}
}

if (objectInsideSpell($monster)) {
# Prohibit attacking this monster in the future
$monster->{dmgFromPlayer}{$char->{ID}} = 1;
return
1
;
}

#check party casting on mob
my $allowed = 1;
if (scalar(keys %{$monster->{castOnByPlayer}}) > 0)
{
foreach (keys %{$monster->{castOnByPlayer}})
{
my $ID1=$_;
my $source = Actor::get($_);
unless ( existsInList($config{tankersList}, $source->{name}) ||
($char->{party} && %{$char->{party}} && $char->{party}{users}{$ID1} && %{$char->{party}{users}{$ID1}}))
{
$allowed = 0;
last;
}
}
}

# If monster hasn't been attacked by other players
if (scalar(keys %{$monster->{missedFromPlayer}}) == 0
&& scalar(keys %{$monster->{dmgFromPlayer}}) == 0
#&& scalar(keys %{$monster->{castOnByPlayer}}) == 0 #change to $allowed
&& $allowed

# and it hasn't attacked any other player
&& scalar(keys %{$monster->{missedToPlayer}}) == 0
&& scalar(keys %{$monster->{dmgToPlayer}}) == 0
&& scalar(keys %{$monster->{castOnToPlayer}}) == 0
) {
# The monster might be getting lured by another player.
# So we check whether it's walking towards any other player, but only
# if we haven't already attacked the monster.
if ($monster->{dmgFromYou} || $monster->{missedFromYou}) {
return 1;
} else {
objectIsMovingTowardsPlayer($monster);
return 1 ;

}
}

# The monster didn't attack you.
# Other players attacked it, or it attacked other players.
if ($monster->{dmgFromYou} || $monster->{missedFromYou}) {
# If you have already attacked the monster before, then consider it clean
return 1;
}
# If you haven't attacked the monster yet, it's unclean.

return 1;
}


I changed all the return 0 to return 1, so whatever happens, i didn't affect the whole process and always return 1.And the result is good, my bot work nicely and KS-ing people.

The above result is made by tried and error. One of the funny modify I made is the bot will ks and ONLY ks other player, it won't attack a standing monster unless the monster attacked by other player.

An easier solution will be changing

##
# boolean checkMonsterCleanness(Bytes ID)
# ID: the monster's ID.
# Requires: $ID is a valid monster ID.
#
# Checks whether a monster is "clean" (not being attacked by anyone).
sub checkMonsterCleanness {
return 1 if (!$config{attackAuto});

to

##
# boolean checkMonsterCleanness(Bytes ID)
# ID: the monster's ID.
# Requires: $ID is a valid monster ID.
#
# Checks whether a monster is "clean" (not being attacked by anyone).
sub checkMonsterCleanness {
return 1 if ($config{attackAuto});

*I didn't try this, modify at your own risk.*


Warning:
KS bot will piss off hand player, making your character banned from server.

1 comment: