shopper plugin
Moderator: Moderators
shopper plugin
A couple of years ago I wrote a shopper plugin as some sort of a mentoring response to edeline, who wrote a similar (but a bit unpolished) plugin. It can be found at the old openkore forum http://bibian.ath.cx/openkore/viewtopic.php?t=19654
I still think it's useful, even if it has limitations
I still think it's useful, even if it has limitations
Got your topic trashed by a mod?
Trashing topics is one click, and moving a topic to its proper forum is a lot harder. You expend the least effort in deciding where to post, mods expend the least effort by trashing.
Have a nice day.
Trashing topics is one click, and moving a topic to its proper forum is a lot harder. You expend the least effort in deciding where to post, mods expend the least effort by trashing.
Have a nice day.
Re: shopper plugin
I was actually just about to start looking for something like this.
thanks
thanks
Re: shopper plugin
If anyone finds this useful, go ahead and use it. I based it on edeline's merchant plugin, but I rewrote alot of the code (all of the code?). You can find a macro file and stuff on bibian's archive forum in the yamd thread, but I included an example below anyway.
I use a combination of wget/curl to upload the file to the site, and I chose it over directly adding to the database because I wrote the site in another language and didn't want to double write hasing functions and similar things. Plus, this is generally run from a different system than the website.
batch file it runs
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>
Oh no.
Re: shopper plugin
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; }
DARKest Ninja
Re: shopper plugin
I am trying to create a site of search of prices in the Brazilian server and vi this topic, I have advanced knowledge of the Kore more I am lay in what it is necessary for creation of the site, assist could me in some ideas? Already I have host that it supports PHP/MySQL (host good). Debtor.
-
- Human
- Posts: 26
- Joined: 29 Oct 2008, 22:18
- Noob?: No
Re: shopper plugin
just asking, the mod by "motivus" prints all in column in a .txt file
what should be modified to print all on line? i mean =x
a normal print by the plugin
what should be modified to print all on line? i mean =x
a normal print by the plugin
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.
Re: shopper plugin
I installed it on my openkore but no results. please tell me the correct format to install.
thanks
thanks
Re: shopper plugin
Change the "\n" to "whateveryouwanttoseperate"cazanova000 wrote: a line print D:
Code: Select all
use constant SEP_DATA => "\n";
Oh no.
shopper plugin
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.
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.
[]s
SophoS
SophoS
-
- Super Moderators
- Posts: 801
- Joined: 06 May 2008, 12:47
- Noob?: No
Re: shopper plugin
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.
In case you are not using latest kore's svn, you should probably then try that.
One ST0 to rule them all? One PE viewer to find them!
One ST_kRO to bring them all and in the darkness bind them...
Mount Doom awaits us, fellowship of OpenKore!
One ST_kRO to bring them all and in the darkness bind them...
Mount Doom awaits us, fellowship of OpenKore!