Shop Sell packet - Skul - 06-15-2014 11:57 AM
I redid the Shop Sell packet on my server and I'm having a problem that I can't understand. When trying to buy from a provisioner NPC, I get a total packet length of 1002 characters and spheresvr.exe returns a 'Packet Too Big' error. This does not allow anyone to buy from a provisioner. Then on the other hand I can buy from an armorer even though the packet length is over 3000 characters.
Here's the code:
Code:
[function f_packet_0x09e]
if (<uid.<argn2>.ischar>)
if (<uid.<argn2>.npc>==brain_vendor)
ctag.buysell=<argn1>
if (<dargn1>==1)
if (<uid.<argn2>.findlayer.28.rescount>)
forcont <findlayer.21>
if (<uid.<argn2>.findlayer.28.findid.<baseid>>)
if (<tag0.override.value>) || (<value>)
if (<dlocal.x> < <ddef0.vendor_limit_sell>)
local.x += 1
local.uid<dlocal.x>=<uid>
local.uid<dlocal.x>.amount=<amount>
if (<tag0.override.value>)
local.uid<dlocal.x>.value=<tag0.override.value>
else
local.uid<dlocal.x>.value=<value>
endif
endif
endif
endif
endfor
if (<local.x>)
for x 1 <local.x>
if (strmatch(<local.packet>,0))
local.packet=d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
else
local.packet=<local.packet> d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
endif
local.packetlength += <eval <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> +14>
endfor
if (<dlocal.x> > 5)
uid.<argn2>.speak You have many items I am interested in.
else
uid.<argn2>.speak What would you like to sell?
endif
sendpacket 09e w<eval <local.packetlength> +9> d<argn2> w<local.x> <local.packet>
else
uid.<argn2>.speak Sorry you have nothing of interest.
endif
else
uid.<argn2>.speak Sorry I am not buying any items at this time.
endif
else
if (<uid.<argn2>.findlayer.26.rescount>)
forcont <uid.<argn2>.findlayer.26>
if (<tag0.override.value>) || (<value>)
if (<dlocal.x> < <ddef0.vendor_limit_buy>)
local.x += 1
local.uid<dlocal.x>=<uid>
if (<tag0.override.value>)
local.uid<dlocal.x>.value=<tag0.override.value>
else
local.uid<dlocal.x>.value=<value>
endif
endif
endif
endfor
endif
if (<uid.<argn2>.findlayer.27.rescount>)
forcont <uid.<argn2>.findlayer.27>
if (<tag0.override.value>) || (<value>)
if (<dlocal.x> < <ddef0.vendor_limit_buy>)
local.x += 1
local.uid<dlocal.x>=<uid>
if (<tag0.override.value>)
local.uid<dlocal.x>.value=<tag0.override.value>
else
local.uid<dlocal.x>.value=<value>
endif
endif
endif
endfor
endif
if (<local.x>)
for x 1 <local.x>
if (strmatch(<local.packet>,0))
local.packet=d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
else
local.packet=<local.packet> d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
endif
local.packetlength += <eval <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> +14>
endfor
if (<dlocal.x> > 5)
uid.<argn2>.speak I have many goods for sale.
else
uid.<argn2>.speak What would you like to buy?
endif
ctag.buysell=
serv.b <eval strlen(<local.packet>)>
sendpacket 09e w<eval <local.packetlength> +9> d<argn2> w<local.x> <local.packet>
else
uid.<argn2>.speak Sorry I do not have any items in for sale at this time.
endif
endif
endif
endif
return 1
Any feedback? Looks complicated but this line here:
Code:
serv.b <eval strlen(<local.packet>)>
returns the total packet length.
How is it that 1002 characters is 'Too Big' while over 3000 characters is not?
Any feedback is much appreciated, thank you.
RE: Shop Sell packet - Feeh - 06-15-2014 01:34 PM
The only restriction is that packet length must be smaller than script_max_line_length - 4 or 4092
The function is not complete so I can not test it locally, my best till now is:
1- Instead of sending the packet, log it to a file and check the contents
2- Split the packet in two or more
RE: Shop Sell packet - Skul - 06-16-2014 02:19 AM
Here's the whole script, it is very easy to install. The purpose of this script is to allow tag.override.value on items to alter the value of an item without having to change the script file for that item.
Code:
[comment information]
This script allows you to add 'tag.override.value' to any item in-game to modify the value of an item sold on a vendor.
Installation:
Open speakshopkeep.scp and replace the BUY command with NEW_BUY and the SELL command with NEW_SELL.
Enjoy.
[defname defnames_shop_sell]
vendor_limit_sell 32 //amount of items displayed in the sell list
vendor_limit_buy 32 //amount of items displayed in the buy list
vendor_limit_names 8 //limit of characters of item names in vendor list
[function new_buy]
if (<src.ischar>)
if (<src.isplayer>)
if !(<src.tag0.new_buysell>)
src.tag.new_buysell=1
src.timerf 1, tag.new_buysell=
buy
updatex
dorand 4
speak Yes?
speak Hmm?
Speak Hold on.
Speak One moment.
enddo
src.timerf 1, f_packet_0x09e 0, <uid>
endif
endif
endif
[function new_sell]
if (<src.ischar>)
if (<src.isplayer>)
if !(<src.tag0.new_buysell>)
src.tag.new_buysell=1
src.timerf 1, tag.new_buysell=
sell
updatex
dorand 4
speak Yes?
speak Hmm?
Speak Hold on.
Speak One moment.
enddo
src.timerf 1, f_packet_0x09e 1, <uid>
endif
endif
endif
[function f_packet_0x09e]
if (<uid.<argn2>.ischar>)
if (<uid.<argn2>.npc>==brain_vendor)
ctag.buysell=<argn1>
if (<dargn1>==1)
if (<uid.<argn2>.findlayer.28.rescount>)
forcont <findlayer.21>
if (<uid.<argn2>.findlayer.28.findid.<baseid>>)
if (<tag0.override.value>) || (<value>)
if (<dlocal.x> < <ddef0.vendor_limit_sell>)
local.x += 1
local.uid<dlocal.x>=<uid>
local.uid<dlocal.x>.amount=<amount>
if (<tag0.override.value>)
local.uid<dlocal.x>.value=<tag0.override.value>
else
local.uid<dlocal.x>.value=<value>
endif
endif
endif
endif
endfor
if (<local.x>)
for x 1 <local.x>
if (strmatch(<local.packet>,0))
local.packet=d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
else
local.packet=<local.packet> d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
endif
local.packetlength += <eval <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> +14>
endfor
if (<dlocal.x> > 5)
uid.<argn2>.speak You have many items I am interested in.
else
uid.<argn2>.speak What would you like to sell?
endif
sendpacket 09e w<eval <local.packetlength> +9> d<argn2> w<local.x> <local.packet>
else
uid.<argn2>.speak Sorry you have nothing of interest.
endif
else
uid.<argn2>.speak Sorry I am not buying any items at this time.
endif
else
if (<uid.<argn2>.findlayer.26.rescount>)
forcont <uid.<argn2>.findlayer.26>
if (<tag0.override.value>) || (<value>)
if (<dlocal.x> < <ddef0.vendor_limit_buy>)
local.x += 1
local.uid<dlocal.x>=<uid>
if (<tag0.override.value>)
local.uid<dlocal.x>.value=<tag0.override.value>
else
local.uid<dlocal.x>.value=<value>
endif
endif
endif
endfor
endif
if (<uid.<argn2>.findlayer.27.rescount>)
forcont <uid.<argn2>.findlayer.27>
if (<tag0.override.value>) || (<value>)
if (<dlocal.x> < <ddef0.vendor_limit_buy>)
local.x += 1
local.uid<dlocal.x>=<uid>
if (<tag0.override.value>)
local.uid<dlocal.x>.value=<tag0.override.value>
else
local.uid<dlocal.x>.value=<value>
endif
endif
endif
endfor
endif
if (<local.x>)
for x 1 <local.x>
if (strmatch(<local.packet>,0))
local.packet=d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
else
local.packet=<local.packet> d<local.uid<dlocal.x>> w<uid.<local.uid<dlocal.x>>.dispiddec> w<uid.<local.uid<dlocal.x>>.color> w<uid.<local.uid<dlocal.x>>.amount> w<uid.<local.uid<dlocal.x>>.value> w<qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <asc <uid.<local.uid<dlocal.x>>.name>>:<strsub 0 <eval <eval <ddef0.vendor_limit_names> *4> +-1> <asc <uid.<local.uid<dlocal.x>>.name>>>>
endif
local.packetlength += <eval <qval <eval strlen(<uid.<local.uid<dlocal.x>>.name>)> < <ddef0.vendor_limit_names> ? <eval strlen(<uid.<local.uid<dlocal.x>>.name>)>:<ddef0.vendor_limit_names>> +14>
endfor
if (<dlocal.x> > 5)
uid.<argn2>.speak I have many goods for sale.
else
uid.<argn2>.speak What would you like to buy?
endif
ctag.buysell=
//serv.b <eval strlen(<local.packet>)>
sendpacket 09e w<eval <local.packetlength> +9> d<argn2> w<local.x> <local.packet>
else
uid.<argn2>.speak Sorry I do not have any items in for sale at this time.
endif
endif
endif
endif
return 1
[function f_packet_0x9f]
ref1=<local.char>
ref2=((<local.6> | (<local.5> * 256)) | (( <local.4> | (<local.3> * 256)) * 65536))
for x 1 <local.8>
local.item<dlocal.x>=((<local.<eval <local.item> +12>> | (<local.<eval <local.item> +11>> * 256)) | (( <local.<eval <local.item> +10>> | (<local.<eval <local.item> +9>> * 256)) * 65536))
local.item<dlocal.x>.amount=(<local.<eval <local.item> +13>> | <local.<eval <local.item> +14>>)
local.item += 6
endfor
if (<ref1.ctag0.buysell>)
for x 1 <local.x>
if (<ref1.findlayer.21.finduid.<local.item<dlocal.x>>>)
if (<ref1.findlayer.21.finduid.<local.item<dlocal.x>>.amount>==<dlocal.item<dlocal.x>.amount>)
local.value += <eval <ref1.findlayer.21.finduid.<local.item<dlocal.x>>.value> * <dlocal.item<dlocal.x>.amount>>
ref1.findlayer.21.finduid.<local.item<dlocal.x>>.remove
elseif (<ref1.findlayer.21.finduid.<local.item<dlocal.x>>.amount> >= <dlocal.item<dlocal.x>.amount>)
local.value += <eval <ref1.findlayer.21.finduid.<local.item<dlocal.x>>.value> * <dlocal.item<dlocal.x>.amount>>
endif
endif
endfor
if (<local.value>)
if (<ref2.findlayer.29.more1> >= <local.value>)
ref2.timerf 1, speak I have bought your items for <dlocal.value> gold pieces.
if (<dlocal.value>==1)
ref2.sound=53
elseif (<dlocal.value> < 5)
ref2.sound=54
else
ref2.sound=55
endif
ref2.findlayer.29.more1 -= <local.value>
while (<dlocal.value> >= 65535)
serv.newitem=i_gold
new.amount=65535
new.cont=<ref1.findlayer.21>
local.value -= 65535
endwhile
if (<local.value> > 0)
serv.newitem=i_gold
new.amount=<local.value>
new.cont=<ref1.findlayer.21>
endif
ref2.timerf 1, Thank you.
else
ref2.timerf 1, speak I can not afford to purchase that from you.
endif
else
ref2.timerf 1, speak Sorry, your items have no value to me.
endif
else
for x 1 <local.x>
if (<uid.<local.item<dlocal.x>>.tag0.override.value>)
local.cost += <uid.<local.item<dlocal.x>>.tag0.override.value>)
else
local.cost += <uid.<local.item<dlocal.x>>.value>
endif
endfor
if (<eval <ref1.findlayer.21.rescount i_gold> +<ref1.findlayer.29.rescount i_gold>> >= <dlocal.cost>) || (<ref1.isgm>)
for x 1 <local.x>
if (<uid.<local.item<dlocal.x>>.amount>==<dlocal.item<dlocal.x>.amount>)
uid.<local.item<dlocal.x>>.cont=<ref1.findlayer.21>
else
uid.<local.item<dlocal.x>>.amount -= <local.item<dlocal.x>.amount>
serv.newitem=<uid.<local.item<dlocal.x>>.baseid>
new.amount=<local.item<dlocal.x>.amount>
new.cont=<ref1.findlayer.21>
endif
if (strmatch(<local.items>,0))
local.items=<uid.<local.item<dlocal.x>>.name>
else
if !(<local.item<eval <local.x> +1>>)
local.items=<local.items>, and <uid.<local.item<dlocal.x>>.name>
else
local.items=<local.items>, <uid.<local.item<dlocal.x>>.name>
endif
endif
endfor
ref2.timerf 1, speak Here <qval <dlocal.x>==1 ?is:are> your <qval <dlocal.x>==1 ?item:items> <local.items>.
ref2.timerf 1, speak That will be <dlocal.cost> gold.
if (<dlocal.value>==1)
ref2.sound=53
elseif (<dlocal.value> < 5)
ref2.sound=54
else
ref2.sound=55
endif
if !(<ref1.isgm>)
ref2.findlayer.29.more1 += <local.cost>
if (<ref2.findlayer.29.more1> > <ref2.findlayer.29.more2>)
ref2.findlayer.29.more1=<ref2.findlayer.29.more2>
endif
forcont <ref1.findlayer.21>
if (<local.cost>)
if (<type>==t_gold)
if (<amount> > <local.cost>)
amount -= <local.cost>
update
local.cost=
else
local.cost -= <amount>
remove
endif
endif
endif
endfor
if (<local.cost>)
forcont <ref1.findlayer.29>
if (<local.cost>)
if (<type>==t_gold)
if (<amount> > <local.cost>)
amount -= <local.cost>
update
local.cost=
else
local.cost -= <amount>
remove
endif
endif
endif
endfor
endif
endif
ref2.timerf 1, speak Thank you very much!
else
ref2.timerf 1, speak Sorry but you can not afford that.
endif
endif
ref2.updatex
return 1
[eof]
Just to let you know, when I try buying from a provisioner I get:Quote:SENDPACKET too big.
yet buying from an armorer has more items and gives no error.
RE: Shop Sell packet - Feeh - 06-16-2014 02:53 AM
Tested and no major problems found, I just got "Undefined keyword 'speak'" that I can replace with "say"
Both armorer and provisioner are displaying BUY/SELL menu, also tested with other long-vend-list vendors and no problems
If you have a packet logger, try comparing the packet you're about to send with Sphere's version of the packet
Are you using an old Sphere version ?
RE: Shop Sell packet - Skul - 06-16-2014 03:29 AM
Actually I am using an old version of sphere, from 2013. I suppose I should update! lol. Thanks for reading my lengthy post, hah. I'll try out the latest version from the site and give it a try.
Same problem... Here's my log:Quote:13:39:(blizz - Shop Sell.scp,143)vendor id: c_h_tinker packet length: 1616
13:39:ERROR:(blizz - Shop Sell.scp,144)SENDPACKET too big.
13:39:2:'Skul' commands 'tele'=1
13:39:2:'Skul' Says 'buy' mode=0
13:39:WARNING:(blizz - Shop Sell.scp,133)Setting max length of 2048 was exceeded on (VAR,TAG,LOCAL).packet
13:39:(blizz - Shop Sell.scp,143)vendor id: c_h_armorer packet length: 2038
13:39:ERROR:(blizz - Shop Sell.scp,144)SENDPACKET too big.
RE: Shop Sell packet - Feeh - 06-16-2014 04:24 AM
Try with a fresh Server...I still have no idea why this is happening with the smaller packet
Instead of placing the data into locals, send it. Client can read splited packet
RE: Shop Sell packet - Skul - 06-16-2014 04:58 AM
Aha, I found the error, turned out to be a comma in the <value> of the item, bad seperation in the packet.
RE: Shop Sell packet - mrkarlo - 06-19-2014 08:14 AM
hi can you help me please! how can I get target after new_buy command?
2. and how to equip memory on char, who says new_buy?
SRC.Newitem i_memory_xx
SRC.ACT.Equip
return 1
RE: Shop Sell packet - Skul - 06-19-2014 11:11 AM
here's an example:
Code:
[function new_buy]
if (<src.ischar>)
if (<src.isplayer>)
if !(<findlayer.26.rescount>)
restock 1
endif
face=<src.uid>
src.f_packet_0x09e 0, <uid>
buy
src.targetf f_function //target
serv.newitem=i_memory_memory //your memory object
src.equip=<new.uid> //equip memory object
endif
endif
Keep in mind I just updated the Shop Sell script, you might want to update before adding your code.
RE: Shop Sell packet - mrkarlo - 06-19-2014 06:28 PM
thanks Skul for respond, but there is no any Target.
Code:
src.targetf f_new_buy //target
serv.newitem=i_memory_xx //your memory object
src.equip=<new.uid> //equip memory object
Code:
[ITEMDEF i_memory_xx]
ID=i_memory
lalala
ON=@Equip
TARGET Select target
|