Sell items to player buyer shop

For everything NOT server specific support. Do NOT ask for connectivity help here!.

Moderator: Moderators

Message
Author
o12116
Noob
Noob
Posts: 8
Joined: 18 Nov 2019, 17:52
Noob?: No

Re: Sell items to player buyer shop

#11 Post by o12116 »

fadreus wrote:It's not that people rarely vending it. It just sold out the moment it appear in ragial usually.
Things that don't have high demand never ever people put up Buying Store.
Thanks for the pro tip! It makes a lot of sense.

I just tested Mortimal's plugin by going to a position where bot can see the buyer (who buys Poison Spore), and then execute below command in the console.

Code: Select all

macro sell_to_player
Image

So nothing happened and there's no error message. I guess the plugin's just not triggered?

It sure is loaded at the beginning
Image

In my macros.txt
Image

In my config.txt
Image

Should I add some logging in sellToPlayer.pl for further testings?
(I'm not familiar with perl syntax tho...

Mortimal
Developers
Developers
Posts: 389
Joined: 01 Nov 2008, 15:31
Noob?: No

Re: Sell items to player buyer shop

#12 Post by Mortimal »

Use this to debug give new logs... put pause 2 in macro after $buyerIdx++
Attachments

[The extension pl has been deactivated and can no longer be displayed.]

Please use pin function for uploading your file contents!

o12116
Noob
Noob
Posts: 8
Joined: 18 Nov 2019, 17:52
Noob?: No

Re: Sell items to player buyer shop

#13 Post by o12116 »

Mortimal wrote:Use this to debug give new logs... put pause 2 in macro after $buyerIdx++
Here goes
Image

Image

I think it's not receiving @itemList (and also $buyerZenyLimit)
After adding this into plugin
Image

The log becomes
Image

Mortimal
Developers
Developers
Posts: 389
Joined: 01 Nov 2008, 15:31
Noob?: No

Re: Sell items to player buyer shop

#14 Post by Mortimal »

Omg sorry. sellToPlayer.pl line 26.

Code: Select all

sub sellspecified {
	my (undef, $args) = @_;
	my ($buyerID, $buyingStoreID, $buyerZenyLimit, @itemList) = ($args->{buyerID} , $args->{buyingStoreID}, $args->{zeny} , @{$args->{itemList}});
	message "SellToPlayer activated with Buyer ID - $buyerID;
										 Buying store ID - $buyingStoreID;
										 Buyer zeny limit - $buyerZenyLimit.\n", 'info';
	my $prefix;
Please use pin function for uploading your file contents!

o12116
Noob
Noob
Posts: 8
Joined: 18 Nov 2019, 17:52
Noob?: No

Re: Sell items to player buyer shop

#15 Post by o12116 »

After modification it got into the foreach loop. However an error occurred.

Image

I did some digging and got 2 findings:
1. The error is caused by $item->{ID}
2. I'm using

Code: Select all

sellToPlayer Poison Spore {
	disabled 0
	minPrice 1900
}
in my config.txt so we should use $char->inventory->getByName instead.

Thus I changed the code to
Image

Now the plugin ran through, but still not selling anything
Image

I think there really is something wrong with $itemGotByName->{ID}.
It returned a single quote ' and ignored the linebreak "\n" at the end of Line# 51, producing an ugly log

Code: Select all

Check selling item inventory index: '================
instead of

Code: Select all

Check selling item inventory index: ##
================
Btw here's the modified plugin

[The extension pl has been deactivated and can no longer be displayed.]


Mortimal
Developers
Developers
Posts: 389
Joined: 01 Nov 2008, 15:31
Noob?: No

Re: Sell items to player buyer shop

#16 Post by Mortimal »

Show logs from this sellToPlayer.pl:

Code: Select all

package selltoplayer;

use strict;
use Plugins;
use Globals qw(%config $char $messageSender);
use Log qw(message);
use Misc qw(itemNameToID);

Plugins::register('selltoplayer', 'sells items to player buyer shop', \&Unload, \&Reload);

my $packetHook = Plugins::addHooks (
	['packet_buying_store2', \&sellspecified, undef],
);

sub Reload {
	message "selltoplayer plugin reloading, ", 'system';
	Plugins::delHooks($packetHook);
}

sub Unload {
	message "selltoplayer plugin unloading, ", 'system';
	Plugins::delHooks($packetHook);
}

sub sellspecified {
	my (undef, $args) = @_;
	my ($buyerID, $buyingStoreID, $buyerZenyLimit, @itemList) = ($args->{buyerID}, $args->{buyingStoreID}, $args->{buyerZenyLimit}, @{$args->{itemList}});
	message "SellToPlayer activated with:"."\nBuyer ID - ".        $buyerID.";".
										  ."\nBuying store ID - ". $buyingStoreID.";".
										  ."\nBuyer zeny limit - ".$buyerZenyLimit.".\n", 'info';
	my $prefix;
	for (my $i = 0; exists $config{$prefix = "sellToPlayer_$i"}; $i++) {
		next unless my $item = $char->inventory->get($config{"${prefix}"})
					&& !$config{"${prefix}_disabled"};
		message "SellToPlayer cycling items.\n", 'info';

		foreach my $itemInList (@itemList){
			message "Buyer is buying: \nItem name - ".$itemInList->{name}.";
									  \nItem ID - ".itemNameToID($itemInList->{name}).";
									  \nAmount - ".$itemInList->{amount}.";
									  \nPrice - ". $itemInList->{price}.".\n", 'info';

			my $itemGotByName = $char->inventory->getByName($config{"${prefix}"});
			
			message "================\n", 'info';
			message "Check selling item name: ".           $itemGotByName->{name} = $itemGotByName =~ /(.*)\s\(\d+\)/."\n", 'info';
			message "Check selling item ID: ".             $itemGotByName->{nameID}."\n", 'info';
			message "Check selling item amount: ".         $itemGotByName->{amount}."\n", 'info';
			message "Check selling item inventory index: ".$itemGotByName->{ID} = $itemGotByName =~ /.*\s\((\d+)\)/."\n", 'info';
			message "================\n\n", 'info';

			next unless itemNameToID($itemInList->{name}) == $itemGotByName->{nameID};
			next unless (!$config{"${prefix}_minPrice"} || $itemInList->{price} >= $config{"${prefix}_minPrice"});

			my $maxSellAmount = $itemInList->{amount}>=$itemGotByName->{amount}?$itemGotByName->{amount}:$itemInList->{amount};
			my $sellAmount = $maxSellAmount*$itemInList->{price} <= $buyerZenyLimit?$maxSellAmount:int($buyerZenyLimit/$itemInList->{price});
			next if $sellAmount <= 0;
			message "SellToPlayer sending sellpacket activated with:".
										 ."\nID - ".$itemGotByName->{ID}.";".
										 ."\nItem ID - ".$itemGotByName->{nameID}.";".
										 ."\nAmount - ".$sellAmount."\n", 'info';
			$messageSender->sendBuyBulkBuyer($buyerID, [{ID => $itemGotByName->{ID}, itemID => $itemGotByName->{nameID}, amount => $sellAmount}], $buyingStoreID);
		}
	}
}
Please use pin function for uploading your file contents!

o12116
Noob
Noob
Posts: 8
Joined: 18 Nov 2019, 17:52
Noob?: No

Re: Sell items to player buyer shop

#17 Post by o12116 »

Thanks for waiting lol
There are some syntax error in the new plugin but I get the idea
Brilliant that you thought of regex matching
I attach the modified version at the end

Now we have no problem getting our inventory index
But $buyerID & $buyingStoreID seem a little messy, causing the bot to disconnect when executing sendBuyBulkBuyer
(It gets the right $buyerZenyLimit every time tho)

Image

Image

Note that the messy $buyerID & $buyingStoreID some time ""eat away" logging so you can't even see SellToPlayer activated with in the first screenshot
Anyway I think we're getting close!

Plugin:

Code: Select all

package selltoplayer;

use strict;
use Plugins;
use Globals qw(%config $char $messageSender);
use Log qw(message);
use Misc qw(itemNameToID);

Plugins::register('selltoplayer', 'sells items to player buyer shop', \&Unload, \&Reload);

my $packetHook = Plugins::addHooks (
   ['packet_buying_store2', \&sellspecified, undef],
);

sub Reload {
   message "selltoplayer plugin reloading, ", 'system';
   Plugins::delHooks($packetHook);
}

sub Unload {
   message "selltoplayer plugin unloading, ", 'system';
   Plugins::delHooks($packetHook);
}

sub sellspecified {
   my (undef, $args) = @_;
   my ($buyerID, $buyingStoreID, $buyerZenyLimit, @itemList) = ($args->{buyerID}, $args->{buyingStoreID}, $args->{buyerZenyLimit}, @{$args->{itemList}});

   message "BuyerID: ", 'info';
   message "$buyerID", 'info';
   message "\n", 'info';
   message "BuyerZenyLimit: ", 'info';
   message "$buyerZenyLimit", 'info';
   message "\n", 'info';
   message "BuyingStoreID: ", 'info';
   message "$buyingStoreID", 'info';
   message "\n\n", 'info';

   message "SellToPlayer activated with: "."
                                Buyer ID - ".$buyerID.";
                                Buying store ID - ".$buyingStoreID.";
                                Buyer zeny limit - ".$buyerZenyLimit.".\n", 'info';

   my $prefix;
   for (my $i = 0; exists $config{$prefix = "sellToPlayer_$i"}; $i++) {
      next unless my $item = $char->inventory->get($config{"${prefix}"})
               && !$config{"${prefix}_disabled"};
      message "\nSellToPlayer cycling items.\n", 'info';

      foreach my $itemInList (@itemList){
         message "Buyer is buying: "."
                             Item name - ".$itemInList->{name}.";
                             Item ID - ".itemNameToID($itemInList->{name}).";
                             Amount - ".$itemInList->{amount}.";
                             Price - ". $itemInList->{price}.".\n", 'info';

         my $itemGotByName = $char->inventory->getByName($config{"${prefix}"});

         if ($itemGotByName =~ m/(.*)\s\(\d+\)/) {
          $itemGotByName->{name} = $1
         }
         if ($itemGotByName =~ m/.*\s\((\d+)\)/) {
            $itemGotByName->{ID} = $1
         }
         message "================\n", 'info';
         message "Check selling item name: ".           $itemGotByName->{name}."\n", 'info';
         message "Check selling item inventory index: ".$itemGotByName->{ID}."\n", 'info';
         message "Check selling item ID: ".             $itemGotByName->{nameID}."\n", 'info';
         message "Check selling item amount: ".         $itemGotByName->{amount}."\n", 'info';
         message "================\n\n", 'info';

         next unless itemNameToID($itemInList->{name}) == $itemGotByName->{nameID};
         next unless (!$config{"${prefix}_minPrice"} || $itemInList->{price} >= $config{"${prefix}_minPrice"});

         my $maxSellAmount = $itemInList->{amount}>=$itemGotByName->{amount}?$itemGotByName->{amount}:$itemInList->{amount};
         my $sellAmount = $maxSellAmount*$itemInList->{price} <= $buyerZenyLimit?$maxSellAmount:int($buyerZenyLimit/$itemInList->{price});
         next if $sellAmount <= 0;
         message "SellToPlayer sending sellpacket activated with:\n", 'info';
         message "Item inventory index - ".$itemGotByName->{ID}."\n", 'info';
         message "ID - ".$itemGotByName->{nameID}."\n", 'info';
         message "Amount - ".$sellAmount."\n", 'info';
         message "BuyerID - ", 'info';
         message "$buyerID", 'info';
         message "\nBuyingStoreID - ", 'info';
         message "$buyingStoreID\n", 'info';
         $messageSender->sendBuyBulkBuyer($buyerID, [{ID => $itemGotByName->{ID}, itemID => $itemGotByName->{nameID}, amount => $sellAmount}], $buyingStoreID);
      }
   }
}

Mortimal
Developers
Developers
Posts: 389
Joined: 01 Nov 2008, 15:31
Noob?: No

Re: Sell items to player buyer shop

#18 Post by Mortimal »

Тут мои полномочия всё.
And here goes the problem... because i totally don't give a f*ck how packets in Ragnarok works. A bug is here:

\src\Network\Receive\ServerType0.pm line 500

Code: Select all

'0818' => ['buying_store_items_list', 'v a4 a4 V', [qw(len buyerID buyingStoreID zeny)]],
the packet is encoded not correctly. Zeny is messy to.

upd. u need to catch some of this packets to encode them
Please use pin function for uploading your file contents!

o12116
Noob
Noob
Posts: 8
Joined: 18 Nov 2019, 17:52
Noob?: No

Re: Sell items to player buyer shop

#19 Post by o12116 »

Got it. So no further progress can be made for now.

Actually my original code can get working with an additional pause
It's just so stupid and I feel ashamed to even post it out lol

Anyway if anyone's interested, here's the complete macro

Code: Select all

macro sell_to_player {
	$itemIdx = @inventory (Stem)
	$sellQty = @invamount (Stem)
	$buyerIdx = 0
	while ($buyerIdx <= 10) as dumbSell
		do buyer $buyerIdx
		do buyer $buyerIdx $itemIdx $sellQty
		log buyer $buyerIdx $itemIdx $sellQty
		pause 12
		$buyerIdx++
   end dumbSell
}

Mortimal
Developers
Developers
Posts: 389
Joined: 01 Nov 2008, 15:31
Noob?: No

Re: Sell items to player buyer shop

#20 Post by Mortimal »

Code: Select all

package selltoplayer;

use strict;
use Plugins;
use Globals qw(%config $char $messageSender $buyerID $buyingStoreID);
use Log qw(message);
use Misc qw(itemNameToID);

Plugins::register('selltoplayer', 'sells items to player buyer shop', \&Unload, \&Reload);

my $packetHook = Plugins::addHooks (
	['packet_buying_store2', \&sellspecified, undef],
);

sub Reload {
	message "selltoplayer plugin reloading, ", 'system';
	Plugins::delHooks($packetHook);
}

sub Unload {
	message "selltoplayer plugin unloading, ", 'system';
	Plugins::delHooks($packetHook);
}

sub sellspecified {
	my (undef, $args) = @_;
	my (undef, undef, undef, @itemList) = ($args->{buyerID}, $args->{buyingStoreID}, $args->{buyerZenyLimit}, @{$args->{itemList}});
	my $buyerZenyLimit = 100000;
	message "SellToPlayer activated with:\nBuyer ID - ".        $buyerID.";".
										  "\nBuying store ID - ". $buyingStoreID.";".
										  "\nBuyer zeny limit - ".$buyerZenyLimit.".\n", 'info';
	
	my $prefix;
	for (my $i = 0; exists $config{$prefix = "sellToPlayer_$i"}; $i++) {
		next unless my $item = $char->inventory->get($config{"${prefix}"})
					&& !$config{"${prefix}_disabled"};
		message "SellToPlayer cycling items.\n", 'info';

		foreach my $itemInList (@itemList){
			message "Buyer is buying: \nItem name - ".$itemInList->{name}.";
									  \nItem ID - ".itemNameToID($itemInList->{name}).";
									  \nAmount - ".$itemInList->{amount}.";
									  \nPrice - ". $itemInList->{price}.".\n", 'info';

			my $itemGotByName = $char->inventory->getByName($config{"${prefix}"});
			$itemGotByName->{name} = $itemGotByName =~ /(.*)\s\(\d+\)/;
			$itemGotByName->{ID} = $itemGotByName =~ /.*\s\((\d+)\)/;
			message "================\n", 'info';
			message "Check selling item name: ".           $itemGotByName->{name}, 'info';
			message "\nCheck selling item ID: ".           $itemGotByName->{nameID}."\n", 'info';
			message "Check selling item amount: ".         $itemGotByName->{amount}."\n", 'info';
			message "Check selling item inventory index: ".$itemGotByName->{ID}."\n", 'info';
			message "================\n\n", 'info';

			next unless itemNameToID($itemInList->{name}) == $itemGotByName->{nameID};
			next unless (!$config{"${prefix}_minPrice"} || $itemInList->{price} >= $config{"${prefix}_minPrice"});

			my $maxSellAmount = $itemInList->{amount}>=$itemGotByName->{amount}?$itemGotByName->{amount}:$itemInList->{amount};
			my $sellAmount = $maxSellAmount*$itemInList->{price} <= $buyerZenyLimit?$maxSellAmount:int($buyerZenyLimit/$itemInList->{price});
			next if $sellAmount <= 0;
			message "SellToPlayer sending sellpacket activated with".
										 "\nID - ".$itemGotByName->{ID}.";".
										 "\nItem ID - ".$itemGotByName->{nameID}.";".
										 "\nAmount - ".$sellAmount."\n", 'info';
			$messageSender->sendBuyBulkBuyer($buyerID, [{ID => $itemGotByName->{ID}, itemID => $itemGotByName->{nameID}, amount => $sellAmount}], $buyingStoreID);
		}
	}
}
Ok! We can use globals here so we will... Use this
Please use pin function for uploading your file contents!

Post Reply