I still think it's useful, even if it has limitations

Moderator: Moderators
Code: Select all
package YAMDB;
#YAMD by edeline
# YAMDB fork by Motivus aka Dishonru aka Belial
#Config Start
#use constant LOG_PATH => "marketlog.txt";
use constant BASE_DELAY => 0.1;
use constant RAND_DELAY => 0.1;
use constant SEP_DATA => "\n";
use constant SEP_OBJECTS => "\n";
use constant SEP_SHOPS => "\n";
use constant SEP_NEWCRAWL => "CLEAR\n";
use constant SEP_CARDS => " ";
use constant MAX_TRIES => 100;
#Config End
#If you want to use a database scroll down to "Logging functions" and go to town
use strict;
use Globals;
use Log qw(message debug error warning);
use Network::Send;
use Settings;
use Plugins;
use Skill;
use Utils;
use Misc;
use AI;
use Actor;
Plugins::register('YAMDB', 'Requests and parses vender information', \&unload);
my $hooks = Plugins::addHooks(
['AI_pre', \&visitShop, undef],
['packet_vender', \& venderFound, undef],
['packet_vender_store2', \&dumpShop, undef],
);
my $commandsID = Commands::register(
["yamdb_info", "displays number of shops visited so far", \&countVisited],
["yamdb_flush", "empties the market log information & issues CLEAR command", \&emptyBuffer],
);
sub unload {
Plugins::delHooks($hooks);
Commands::unregister($commandsID);
writeCon("Plugin unloaded.");
}
my %venderVisited;
my $timeLastVisit = time();
my @shopList;
my $iterate;
###
# Hooks
###
sub dumpShop {
my $hookName = shift;
my $args=shift;
my $vender = Actor::get($args->{'venderID'});
my @venderItemList = @{$args->{'itemList'}};
my ($playerName, $vendName, $vendPos);
$playerName = $vender->name;
if (defined $venderLists{$args->{'venderID'}}{'title'}) {
$vendName = $venderLists{$args->{'venderID'}}{'title'};
}
else {
writeCon("Shop from $playerName has no name. It's possible we walked off screen.");
return;
}
if (!(defined $venderVisited{$args->{'venderID'}}) || $venderVisited{$args->{'venderID'}} ne $vendName) {
if (defined $vender->{pos_to}{x} && defined $vender->{pos_to}{y}) {
$vendPos = "$vender->{pos_to}{x},$vender->{pos_to}{y}";
}
else {
writeCon("Shop from player ".$playerName." (".$args->{'venderID'}.") has no position. It's possible we walked off screen.");
return;
}
#Register vender information
my ($playerFace, $playerCart, $playerStrID);
$playerFace = sprintf("%02d%02d", $vender->{hair_style}, $vender->{hair_color});
$playerCart = getCartType($vender->{param3});
$playerStrID = formatID($args->{'venderID'});
registerVend($playerStrID, $playerName, $vendName, $field{name}, $vendPos, $playerFace,
$vender->{type}, $playerCart, $vender->{headgear}{top}, $vender->{headgear}{mid}, $vender->{headgear}{low},
$vender->{lv}, $vender->{sex}, $vender->{sitting} |0);
#Register items in vend
for (my $itemID = 0; $itemID < @venderItemList; $itemID++) {
if (defined $venderItemList[$itemID]) {
my ($itemName, $itemPrice, $itemAmount, $itemTypeID, $itemUpgrade, $itemSlots, $itemSlotData, $itemType);
$itemTypeID = $venderItemList[$itemID]->{nameID};
$itemName = $venderItemList[$itemID]->{name};
$itemPrice = $venderItemList[$itemID]->{price};
$itemAmount = $venderItemList[$itemID]->{amount};
$itemUpgrade = $venderItemList[$itemID]->{upgrade};
$itemSlots = countCards($itemTypeID);
$itemSlotData = formatCards($venderItemList[$itemID]->{cards});
registerItem($playerStrID, $itemTypeID, $itemName, $itemPrice, $itemAmount, $itemUpgrade, $itemSlots, $itemSlotData);
}
}
#Mark vender as visited, end current vend
$venderVisited{$args->{'venderID'}} = $vendName;
endVend();
#Show shops visited
countVisited();
}
}
sub venderFound {
my ($packet, $args) = @_;
my $ID = $args->{ID};
if ($ID && !defined($venderVisited{$ID})) {
$messageSender->sendGetPlayerInfo($ID);
pushShop({vendorID => $ID, try => 0});
if (!AI::is('checkShop')) {
AI::queue('checkShop', {shopsToVisit => 1});
}
else {
my $shopsToVisit = @shopList;
AI::dequeue;
AI::queue('checkShop', {shopsToVisit => $shopsToVisit});
}
}
}
sub visitShop {
if (AI::is('checkShop') && timeOut($timeLastVisit, getDelay())) {
my $shop = shift @shopList;
my $venderID = $shop->{vendorID};
my $try = $shop->{try};
my $vender = Actor::get($venderID);
my $venderName = $vender->name;
if (!(defined $venderVisited{$venderID}) || $venderLists{$venderID}{'title'} ne $venderVisited{$venderID}) {
if (rindex($venderName, "Unknown #") == -1 || $config{'shopfast'} || $try > MAX_TRIES) {
sendEnteringVender(\$remote_socket, $venderID);
}
elsif ($vender->distance() <= 20) { #If vendor is in range re-queue it until we get its name
$try++;
pushShop({vendorID => $venderID, try => $try});
return;
}
}
#If we visited the vend or the vender is >20 tiles away we need to queue a new list
if (@shopList == 0) { #No more venders, allow normal AI to resume
AI::dequeue;
#countVisited();
}
else {
my $shopsToVisit = @shopList;
AI::dequeue;
AI::queue('checkShop', {shopsToVisit => $shopsToVisit});
}
$timeLastVisit = time;
}
}
###
# Commands
###
sub emptyBuffer {
writeCon("Resetting marketlog.txt and visited vend list");
%venderVisited = ();
resetLog(1, time()."\n");
}
sub countVisited {
writeCon("Shops Visited: ".scalar(keys(%venderVisited)));
}
###
# Logging Functions
###
sub registerVend {
my $playerID = shift;
my $playerName = shift;
my $vendTitle = shift;
my $vendMap = shift;
my $vendPos = shift;
my $playerFace = shift;
my $playerClass = shift;
my $playerCart = shift;
my $playerHeadTop = shift;
my $playerHeadMid = shift;
my $playerHeadBot = shift;
my $playerLevel = shift;
my $playerGender = shift;
my $playerSitting = shift;
addLog($playerID.SEP_DATA
.$playerName.SEP_DATA
.$vendTitle.SEP_DATA
.$vendMap.SEP_DATA
.$vendPos.SEP_DATA
.$playerFace.SEP_DATA
.$playerClass.SEP_DATA
.$playerCart.SEP_DATA
.$playerHeadTop.SEP_DATA
.$playerHeadMid.SEP_DATA
.$playerHeadBot.SEP_DATA
.$playerLevel.SEP_DATA
.$playerGender.SEP_DATA
.$playerSitting.SEP_OBJECTS);
}
sub registerItem {
my $parentID = shift;
my $itemID = shift;
my $itemName = shift;
my $itemPrice = shift;
my $itemAmount = shift;
my $itemUpgrade = shift;
my $itemSlots = shift;
my $itemSlotData = shift;
addLog($itemID.SEP_DATA
.$itemName.SEP_DATA
.$itemPrice.SEP_DATA
.$itemAmount.SEP_DATA
.$itemUpgrade.SEP_DATA
.$itemSlots.SEP_DATA
.$itemSlotData.SEP_OBJECTS);
}
sub endVend {
addLog(SEP_SHOPS);
}
###
# Text file logging functions
###
sub addLog {
my $logText = shift;
my $logPath = "marketlog_".$config{'server'}.".txt";
open(F, ">>".$logPath);
print F $logText;
close(F);
}
sub resetLog {
my $clear = shift;
my $logBuffer = shift;
my $logPath = "marketlog_".$config{'server'}.".txt";
open(F, ">".$logPath);
if ($clear) {
$iterate = 0;
print F SEP_NEWCRAWL;
}
print F $logBuffer;
close(F);
}
###
# Information Format Functions
###
sub getCartType {
my $effects = shift;
if ($effects &8) {
return 1;
}
elsif ($effects &128) {
return 2;
}
elsif ($effects &256) {
return 3;
}
elsif ($effects &512) {
return 4;
}
elsif ($effects &1024) {
return 5;
}
return 0;
}
sub formatID {
my $DWORD = shift;
$DWORD = unpack("l", $DWORD);
$DWORD = sprintf("%010d", $DWORD);
return $DWORD;
}
sub formatCards {
my $cardMess = shift;
my @cards;
for (my $i = 0; $i < 4; $i++) {
my $card = unpack("v1", substr($cardMess, $i*2, 2));
last unless $card;
push(@cards, $card);
}
my $cardStr;
$cardStr = sprintf("%05d%s%05d%s%05d%s%05d", $cards[0], SEP_CARDS, $cards[1], SEP_CARDS, $cards[2], SEP_CARDS, $cards[3]);
return $cardStr;
}
sub countCards {
my $itemID = shift;
my $count;
$count = $itemSlotCount_lut{$itemID};
if (!$count)
{
$count = "0";
}
return $count;
}
sub itemHash {
#Put your function to generate unique item hashes based on id/cards/upgrade here (I removed mine)
}
###
# Utility Functions
###
sub writeCon() {
my $msg = shift;
message "[YAMDB] ".$msg."\n";
}
sub pushShop {
my $args = shift;
push @shopList, ((defined $args) ? $args : {});
}
sub getDelay {
my $delay = BASE_DELAY + rand(RAND_DELAY);
return $delay;
}
1;
Code: Select all
automacro crawlChaos {
map prontera
run-once 1
call marketwatch
}
macro marketwatch {
do yamdb_flush
call move
do relog 1100
do eval system "parse"
release crawlChaos
}
macro move {
do move 115 118
do move 121 104
do move 121 90
do move 130 94
do move 130 111
do move 133 120
do move 145 119
do move 143 91
do move 152 115
do move 153 107
do move 153 99
do move 150 89
do move 151 80
do move 155 66
do move 155 48
do move 156 33
do move 156 137
do move 155 156
do move 155 173
do move 156 189
do move 171 191
do move 136 214
do move 138 201
do move 115 118
}
Code: Select all
del <filename from site>
curl -T marketlog_2.txt <site> --user username:password
wget <site>
Motivus wrote:Code: Select all
automacro crawlChaos { map prontera run-once 1 call marketwatch } macro marketwatch { do yamdb_flush call move do relog 1100 do eval system "parse" release crawlChaos } macro move { do move 115 118 do move 121 104 do move 121 90 do move 130 94 do move 130 111 do move 133 120 do move 145 119 do move 143 91 do move 152 115 do move 153 107 do move 153 99 do move 150 89 do move 151 80 do move 155 66 do move 155 48 do move 156 33 do move 156 137 do move 155 156 do move 155 173 do move 156 189 do move 171 191 do move 136 214 do move 138 201 do move 115 118 }
Code: Select all
sub crawlChaos { return if ($field{name} ne "prontera"); emptyBuffer(); my $i = 0 while ($i < 23) { if (!AI::inQueue("route")) { do { my $mx = int(rand(57)+115); my $my = int(rand(182)+33); } while (!$field->isWalkable($mx, $my); main::ai_route($field{name}, $mx, $my, attackOnRoute => 1, noSitAuto => 1, notifyUponArrival => 1); $i++; } } Commands::run("relog 1100"); Commands::run("eval system \"parse\""); return; }
a line print D:ID
Nick of Merchant
Name of Shop
City
Coord
ID
ItemID
ItemName
Price
Etc.
ID
Nick of Merchant,Name of Shop,City,Coord,ID,ItemID,ItemName,Price,Etc.
Change the "\n" to "whateveryouwanttoseperate"cazanova000 wrote: a line print D:
Code: Select all
use constant SEP_DATA => "\n";
I've seen a similar problem as yours before on bRO, which i then solved by adding a new packet into kore.Sophos wrote:Had already tested this plugin and it worked. It happens that today it no longer works, I believe that because of some update BRO.
The bot walks into a store and when he comes close is the checkshop.
Do not list any item on the console (as It did), so I think it is not working.
Can anyone help me (I don´t know nothing about plugin) ?
I do not know anything about plugin.