PDA

View Full Version : Bazaar bots


provocating
01-02-2011, 11:22 AM
Has anyone ever done an auction bot ? I was just asking because i also run a Trinity Core server and there is an AHBOT that someone created. Pretty damn cool since it buys and sells items. I got very positive reviews when I added the code to my server. I was thinking this should not be too hard to implement in the EqEmulator server. There again I would not want to recreate the wheel if someone has already done it, or may even be able to build off of existing code. The most I have come up with is someone has created merchants that sell gear in the bazaar.

Secrets
01-02-2011, 12:27 PM
Has anyone ever done an auction bot ? I was just asking because i also run a Trinity Core server and there is an AHBOT that someone created. Pretty damn cool since it buys and sells items. I got very positive reviews when I added the code to my server. I was thinking this should not be too hard to implement in the EqEmulator server. There again I would not want to recreate the wheel if someone has already done it, or may even be able to build off of existing code. The most I have come up with is someone has created merchants that sell gear in the bazaar.

I've been thinking about implementing something like this in perl for a while now.

Wouldn't be *that* hard with perl's DBI module.

Just gotta make a table to store items you hand to an NPC, and then have someone who can buy the items search like they do normally in the bazaar, just with mysql queries in perl instead of C++. Table doesn't have to be complex either; just id, itemid, sellername, price, sold (this will be one or zero.)

Hopefully that lets you brainstorm a bit,

provocating
01-02-2011, 02:05 PM
I am going to get started on this. I have taken PERL classes years ago and have about 20 PERL books around work and my house. It will just take me a while to get back into the groove of things. In fact since I have learned other languages since playing with PERL, it should make more sense to me now.

What they do in Trinity Core is have the BOT buy items in intervals until he reaches his MAX, then he quits. Same with buying, in intervals he will buy auction items for a random price with a min, and max amount. One thing that does pose a question, do all items in PEQ have a buy / sell price and are they realistic ? If not that is going to be the hardest work for me.

provocating
01-03-2011, 02:47 PM
The more I think about it, I am not sure this can be done in Perl alone, maybe someone can tell me if it can be done in Perl.

I do not want your standard NPC merchants that I have seen implemented in the past. I want these to have trader satchels with items and the NPC's actually put the items up for sale. This way the player could actually use the Bazaar window to find items, like in live. The NPC's would give random calls pulled out of a table, maybe pull the item names from the table and the asking price, this would be done with variables. The call would be at random times, with the text also being random and pulled from a large pool of possibilities. The merchants would also need to buy the players items if he auctions them, at random times. This would force the player to actually use the auction system and the NPC auctioneer would buy the players items at a lower cost than what he would sell it back for. This sounds like it would be hard to do, but very possible. I am just not sure if I will have to edit the zone file or I could do it all in Perl.

Huppy
01-07-2011, 04:23 PM
I would love to see something like that implemented on the server/db.
On live right now, they have a couple of npc's in the pok selling defiant
gear for various levels, which is something I thought about doing for my
server, but it would be kewl to have some bots in Baz, with items that
are searchable with the /baz window.

provocating
01-10-2011, 09:32 AM
So my first step is going to be to have them equip the trader satchels, is this possible ? I am going through each and every Perl object under quest, and also some of the other objects but not seeing it yet. I plan on doing a more exhaustive search at lunch today.

provocating
01-10-2011, 11:10 AM
I am thinking that the whole idea of an NPC holding a traders satchel, and moving items in an out of a database may not work. I guess the whole bazaar trader deal is client side correct ? So even if I could get an NPC to equip a satchel, and put things in it I still could not get them to actually turn on the trader function ?

If all else fails I could rather easily just do this. Set up a spawn point, make that spawn point randomly spawn maybe 10 vendors, each with a 10 percent chance of being spawned. Each vendor has different items. The vendors have player names instead of npc names, makes it more real. Have them do random calls, at random times. This would give an element of randomness. That vendor stays there for an amount of time then despawns at a random time, then it repeats. Do this for maybe 50-100 spawn points would be a start. It is not what I want though. What I actually want are the items randomly generated. As far as getting the items in the database and random items that seems easy with MySQL DBI statements in the vendor Perl file. It is getting that NPC to do the trader things I am getting stuck at.

Akkadius
01-10-2011, 12:54 PM
The more I think about it, I am not sure this can be done in Perl alone, maybe someone can tell me if it can be done in Perl.

I do not want your standard NPC merchants that I have seen implemented in the past. I want these to have trader satchels with items and the NPC's actually put the items up for sale. This way the player could actually use the Bazaar window to find items, like in live. The NPC's would give random calls pulled out of a table, maybe pull the item names from the table and the asking price, this would be done with variables. The call would be at random times, with the text also being random and pulled from a large pool of possibilities. The merchants would also need to buy the players items if he auctions them, at random times. This would force the player to actually use the auction system and the NPC auctioneer would buy the players items at a lower cost than what he would sell it back for. This sounds like it would be hard to do, but very possible. I am just not sure if I will have to edit the zone file or I could do it all in Perl.

Yes, it could be done in Perl. Infact I was just thinking about this once again because I wanted to get to this months ago, but wasn't something I wanted to attack right now. I could have something functional in a short while.

provocating
01-10-2011, 01:09 PM
Just the code to make an npc hold the satchel and equip it, then turn on trading would be enough. I am just stuck at this part. Maybe there is some undocumented functions I am not aware of.

Derision
01-10-2011, 02:37 PM
Just the code to make an npc hold the satchel and equip it, then turn on trading would be enough. I am just stuck at this part. Maybe there is some undocumented functions I am not aware of.

All the bazaar code assume that the Trader is a client (e.g. when you buy something off a Trader, the server sends packets to it to remove the item from it's inventory, add the purchase price, etc.).

As it stands right now, you can't make an NPC a Bazaar trader ... you'd have to cook something up using NPC merchants as you suggest.

provocating
01-10-2011, 02:46 PM
That is what I needed, a definitive answer is cannot be done. I will just code up boatload of bots with different gear as merchants, but have them doing random stuff. Random is good.

provocating
01-11-2011, 01:59 PM
I am sure this will take a while for me to complete. I was going to go for 5 different NPC's for each spawn point but that really seems counterproductive. Instead I am going to start with 100 npc's with 50 spawn points, 50 percent chance per point. After I look at the Bazaar I may bump it up to more spawns if it looks empty. This is going to take me quite a while to complete. Even after the spawns are complete I will need to script each and every NPC with some type of shouts in the bazaar, random ones. I am thinking a small amount of the bots have a proximity say going, or maybe emotes.

I have a question for everyone though, where does the PEQ database get it's pricing for items from ? I have never paid any attention to the prices of items till now but looking at something as simple as Centi items, I notice two items can have a drastic difference in price.

Chanus
01-11-2011, 02:19 PM
I believe pricing is attached to the item itself, and then the variance on vendors is a field on the merchant itself... and then there's things like CHA modifying prices, but that shouldn't come into to play in the Bazaar.

provocating
01-11-2011, 02:31 PM
Well I know that :)

I need to know where the data was gathered from ?

Chanus
01-11-2011, 02:37 PM
Oh, you mean like what determines the price of anything?

I would guess it was just mined off Lucy ( lucy.allakhazam.com )

provocating
01-11-2011, 02:50 PM
Okay I will start to reference Lucy's to see what is off. Wonder if it was done with a PERL CGI script and if someone still has it ?

Derision
01-11-2011, 03:01 PM
I think Cavedude just periodically downloads the items database from 13th floor and imports it into PEQ.

http://eqitems.13th-floor.org/

The item DB (as a delimited text file) is under the downloads link.

provocating
01-11-2011, 03:04 PM
I have been visiting their site, but did not notice they had downloads.....cool stuff.

Caryatis
01-11-2011, 07:10 PM
If all else fails I could rather easily just do this. Set up a spawn point, make that spawn point randomly spawn maybe 10 vendors, each with a 10 percent chance of being spawned. Each vendor has different items. The vendors have player names instead of npc names, makes it more real. Have them do random calls, at random times. This would give an element of randomness. That vendor stays there for an amount of time then despawns at a random time, then it repeats. Do this for maybe 50-100 spawn points would be a start. It is not what I want though. What I actually want are the items randomly generated. As far as getting the items in the database and random items that seems easy with MySQL DBI statements in the vendor Perl file. It is getting that NPC to do the trader things I am getting stuck at.

The idea of an auction bot is attractive to most players, your version of it though I'm not sure(not sure how random items play into an auction bot). While this may be possible using only Perl, I think the more elegant solution is going to involve more C++ than Perl.

Derision only said that currently its not possible for the bazaar code to handle NPCs, without ever having looked at the code I wonder if making it recognize NPCs is not the best way to go in this situation. In this case I think the NPC is little more than visual placeholder, would have to track the items for sale more reliably than in a bag on an NPC.

I envison it more like walking up to a generic NPC and purchasing a place in the bazaar, this would copy the look and name of your character onto that NPC and load any previous items you had for sale into his inventory. Then by giving him items, he writes those to the db and updates his list. Clients can then use the bazaar window to search for items as they would if the player was in zone as well. If it got paired up with the barter window as well, might be able to do the reverse and have roving NPC buyers who buy things for their clients as they are put up for sale.

Without using any c++ I think the best you could do is have the NPCs /auc items, then when players hail the NPC they are given a list of saylinks of the items for sale with prices. If they have enough plat when they click the desired link, it removes the plat from their char, deletes the item from the sellers db and then summons one to their cursor.

provocating
01-11-2011, 07:17 PM
Well the best I can do is Perl coding at the moment. I can read some C++ but it is still out of my league. In my case I just want something a little different. Crazy thing I always feel like I am slightly cheating when I use BOTS, I know it is crazy but when I can not even have to cast or send a pet out I feel like I am cheating. Hell I can just make a hotkey with a group of BOTS and the mob is dead. I am not quite sure what I want but I think trying to recreate the bazaar like live is a first step for me.

Akkadius
01-11-2011, 07:35 PM
While this is something I have been wanting to get done, it hasn't been at the top of my list like I was saying. Also, it would need player-base time-tweaking over an extended period of time. The reason why I say it would take an extended period of time is because you would want it flexible enough to not only store player trades, but you would also want to be able to classify the items that are being put for auction in a menu so that when you have 20,000 items on an auction/trade system, you will be able to navigate it all without it being utter chaos.

Just to shoot some examples would be to sort by latest posting, the most popularly bought items that are up for post again.

-Maintaining a system of average prices and color coating the messages based on auctions being a good deal or costing more than the average cost of the item.
-You could limit each account or player to a certain amount of items to put up for auction.
-After so long of an item sitting on auction, it either A) Get's returned back to the players inventory B) Threatens to get deleted or C) Goes to a collections bin after so long
-Being able to set rules on your item max/min and your rate for decreasing each day.

And I'm sure there are other features I am missing right now because you have the player base to tell you what should be added to it over time.

I will definitely implement this on my own server, but it may not be as soon as you'd like it.

BrandeX
08-21-2011, 11:25 PM
I've been thinking about implementing something like this in perl for a while now.

Wouldn't be *that* hard with perl's DBI module.

Just gotta make a table to store items you hand to an NPC, and then have someone who can buy the items search like they do normally in the bazaar, just with mysql queries in perl instead of C++. Table doesn't have to be complex either; just id, itemid, sellername, price, sold (this will be one or zero.)

Hopefully that lets you brainstorm a bit,

They have seller "bots" on EQTitan server. You hand them items and set a price via # commands. The bots sell them while you are elsewhere or offline, and you collect the cash when you zone in to baz.

provocating
11-28-2011, 10:57 AM
Well after months of letting it sit I finally got back on this during the Thanksgiving Holidays.

What I ended up doing is starting with just one NPC. The NPC randomly pulls a small list of items from the item table, based on certain criteria. The items are then loading into him like a vendor would. He randomly yells in the zone with random text and links to what is for sale. I know it is a lot of randomness but I did not want anything to be static. I am thinking having him randomly spawn / despawn and during the respawn the items clear out.

It sounds easy to do all of this, but it has not been super easy for me to do with my lack of coding experience, but it is now done. I had to modify the server code a bit because clearing out the vendors items did not seem to have a built in routine. Also the pricing in the database was an issue as some items had a zero value. I found someone had a post on modifying server pricing and used it. I need to go back through that and critique the pricing.

Now all I have left to do is come up with shouts for zone, then make 30+ of these guys with different names, looks, shouts and behaviors.....tada.....East Commons tunnel is now alive.

provocating
11-28-2011, 05:47 PM
So far so good, I am sure it needs tons of tweeking, but he is working.

http://reefcrazed.dyndns.org:82/screenshots/EQ000066.jpg

Furinex
04-15-2012, 10:17 AM
You should share this... Im looking for something for solo servers that allows the acquisition of items unattainable solo. This looks like the solution.

provocating
04-15-2012, 10:28 AM
Well I have started and stopped multiple times. I did code out some that just sat in East Commons, announced items. Basically they pulled random items out of the database based on type and price. I will definitely share it but keep in mind, I wrote it months ago and never went back and tweaked it out.

It was not so much a "bazaar bot" but East Commons NPC's that pull random items from the items table, set prices and announced. It may not even be what a server admin would want. Some of the things that bothered me was it used Perl DBI and also the fact the config sat in the Perl file. It was not the elegant solution I really wanted so I ditched the idea.

chrsschb
04-15-2012, 12:00 PM
By sharing it you allow more experienced coders to fine tune it.

provocating
04-15-2012, 12:08 PM
This was one of them in East Commons.


#Battlestaff Fuzzietoe 22210
INSERT INTO `npc_types` (id, name, lastname, level, race, class, bodytype, hp, mana, gender, texture, helmtexture, size, hp_regen_rate, mana_regen_rate, loottable_id, merchant_id, alt_currency_id, npc_spells_id, npc_faction_id, adventure_template_id, trap_template, mindmg, maxdmg, attack_count, npcspecialattks, aggroradius, face, luclin_hairstyle, luclin_haircolor, luclin_eyecolor, luclin_eyecolor2, luclin_beardcolor, luclin_beard, drakkin_heritage, drakkin_tattoo, drakkin_details, armortint_id, armortint_red, armortint_green, armortint_blue, d_meele_texture1, d_meele_texture2, prim_melee_type, sec_melee_type, runspeed, MR, CR, DR, FR, PR, Corrup, see_invis, see_invis_undead, qglobal, AC, npc_aggro, spawn_limit, attack_speed, findable, STR, STA, DEX, AGI, _INT, WIS, CHA, see_hide, see_improved_hide, trackable, isbot, exclude, ATK, Accuracy, slow_mitigation, version, maxlevel, scalerate, private_corpse, unique_spawn_by_name, underwater) VALUES ('22210', 'Battlestaff_Fuzzietoe', '', '65', '11', '41', '1', '4476', '0', '0', '2', '0', '5', '0', '0', '0', '346724', '0', '0', '0', '0', '0', '54', '110', '-1', '', '70', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '28', '28', '1.25', '9', '9', '9', '9', '9', '9', '0', '0', '0', '614', '0', '0', '-7.37742', '0', '137', '137', '137', '137', '137', '137', '137', '0', '0', '1', '0', '1', '0', '0', '0', '0', '0', '100', '0', '0', '0');
INSERT INTO `spawngroup` (`id`, `name`, `spawn_limit`, `dist`, `max_x`, `min_x`, `max_y`, `min_y`, `delay`) VALUES (200005, 'ecommons_200005', 0, 0, 0, 0, 0, 0, 0);
INSERT INTO `spawn2` (`id`, `spawngroupID`, `zone`, `version`, `x`, `y`, `z`, `heading`, `respawntime`, `variance`, `pathgrid`, `_condition`, `cond_value`, `enabled`, `animation`) VALUES (300005, 200005, 'ecommons', 0, 888.600000, -1056.700000, -3.2, 233.8, 1200, 0, 0, 0, 1, 1, 0);
INSERT INTO `spawnentry` (`spawngroupID`, `npcID`, `chance`) VALUES (200005, 22210, 100);
INSERT INTO `merchantlist` (`merchantid`, `slot`, `item`, `faction_required`, `level_required`, `alt_currency_cost`) VALUES (346724, 1, 13006, -100, 0, 0);


Battlestaff_Fuzzietoe.pl

#!/usr/bin/perl -w
use DBI;

$db_login='eqemu';
$db_password='pass';
$db_host='127.0.0.1';
$db_database='peq';

# 1 warrior, 2 cleric, 4 paladin, 8 ranger, 16 sk, 32, druid, 64 monk, 128 bard, 256, rogue,
# 512 shaman, 1024 necro, 2048 wiz, 4096 mage, 8192 enchant, 16384 beast, 32768 beserk
$target_class=0;

$min_vendor_count=20;
$max_vendor_count=100;

@random_result_set=();

$size=0;
$announce_time=600; #Random announce time offset.
$reload_items_time=14400; #Random reload time offset. (3600=one hour, 14400=four hours, 86400=one day)
$initial_stock_delay=12; #NPC is not always up on slow loading zones.

$dbh=DBI->connect('DBI:mysql:' . $db_database . ';host=' . $db_host, $db_login, $db_password
) || die "Could not connect to database: $DBI::errstr";

$sth = $dbh->prepare('SELECT id FROM items WHERE nodrop=1 and norent=1 and questitemflag=0 and stacksize=1 AND price>0 AND classes > ' . $target_class );
$sth->execute();
while (@row=$sth->fetchrow_array){
push (@random_result_set, $row[0]);
}
$size=@random_result_set;
$vendor_item_count=$min_vendor_count+int(rand($max _vendor_count-$min_vendor_count));

sub EVENT_SPAWN
{
quest::settimer("initial_stock", $initial_stock_delay);
quest::settimer("reload_items", int(rand($reload_items_time)+3600)); #Timer for item inventory reload.
quest::settimer("announce", int(rand($announce_time)+240)); #Random announcements.
}

sub EVENT_TIMER
{
if($timer eq "initial_stock")
{
LOAD_VENDOR();
quest::stoptimer("initial_stock");
}

if($timer eq "reload_items")
{
LOAD_VENDOR();
}

if($timer eq "announce")
{
if(@random_result_set>0)
{
$rand=int(rand(6));
if ($rand==0) {quest::shout(sprintf("%s%s%s%s%s%s%s","New vendor up in the east commons tunnel check these items for sale (" . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
elsif ($rand==1) {quest::shout(sprintf("%s%s%s%s%s%s%s","Check out my wares just inside the east commons tunnel (" . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
elsif ($rand==2) {quest::shout(sprintf("%s%s%s%s%s%s%s","Lowest prices in Norath !!! Check out my " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1)) . ", " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
elsif ($rand==3) {quest::shout(sprintf("%s%s%s%s%s%s%s","WTS " . ANNOUNCE(int(rand($vendor_item_count)+1)) . " and " . ANNOUNCE(int(rand($vendor_item_count)+1)) . " and " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
elsif ($rand==4) {quest::shout(sprintf("%s%s","Selling " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
elsif ($rand==5) {quest::shout(sprintf("%s%s","Come visit Battlestaff Fuzzietoe at the entrance to the East Commons tunnel, great prices on items like this " . ANNOUNCE(int(rand($vendor_item_count)+1))));}
}
$npc->SetAppearance(int(rand(2)));
}

if($timer eq "initial_load_vendor")
{
#quest::shout('end load');
LOAD_VENDOR();
#quest::shout('end load2');
quest::stoptimer("initial_load_vendor");
}
}

sub ANNOUNCE
{
sprintf("%c%06X%s%s%c",0x12,$random_result_set[$_[0]],"00000000000000000000000000000000000000000000",quest::itemname($random_result_set[$_[0]]),0x12);
}

sub LOAD_VENDOR
{
quest::merchantclear($npc->GetNPCTypeID());

fisher_yates_shuffle( \@random_result_set);

#Iterate through current items, add them.
for ($i=0; $i<=$vendor_item_count; $i++)
{
#quest::emote("Adding item " . $random_result_set[$i]);
quest::MerchantSetItem($npc->GetNPCTypeID(), $random_result_set[$i], 1);
}
}

sub fisher_yates_shuffle
{
my $array=shift;
my $i=@$array;
while ( --$i )
{
my $j = int rand( $i+1 );
@$array[$i,$j]=@$array[$j,$i];
}
}

$dbh ->disconnect();