price.ash: learn how much an item costs, courtesy items.ofloathing.org

jasonharper

Developer
[quote author=zarqon link=topic=2016.msg9902#msg9902 date=1227476317]A plea to the devs:

Please consider introducing these functions to ASH:

  • [li]int autosell_price( item ) - returns the autosell price of an item. Current methods for accessing this (creating an independent map of data, or loading mafia's entire item database only for one info point) are hugely inefficient.[/li]
    [li]int mall_price( item ) - returns the current lowest price for an item in the mall once per item per day, to prevent mallbots. This would allow item pricing without buying the item, but it would still be just as difficult as now to manipulate mall prices.[/li]
[/quote]
I have added the autosell_price() function in r6524 - it appears non-abusable, and genuinely useful.

I don't feel that I have the authority to overturn existing policy on making mall prices available to scripts.
 

Bale

Minion
[quote author=jasonharper link=topic=2016.msg9932#msg9932 date=1227560646]
I don't feel that I have the authority to overturn existing policy on making mall prices available to scripts.
[/quote]

Of course not, but you could give them a tiny nudge by simply answering this question: If they agreed to once per day pricing, would you do all the work of writing the function so that they only have to make the decision?
 

zarqon

Well-known member
Zecious Babaloni and jasonharper save the day!

This would be a perfect example of a time when it would be awesome if file_to_map() worked with URLs. (Kind of like a public update command.) Centralized data files would be super easy to access in scripts... it would even enable automatic updates for script data files... or perhaps I'm just dreaming. :)

I had a bit of discussion with Zecious and he is working on a script to generate another data file, which will probably be called average.txt, which will contain the average price for each item over the last 7 days. Which will unfortunately negate a lot of your work with parsing export.txt into a big map, dj_d.

In the meantime, I changed just a few lines so now it gets data from today.txt. It still caches this data, so it will only hit the ofloathing server once per day max. I also changed the order of things so that if the ofloathing value checks out, it won't bother with the wiki, which makes it the fastest, most server-friendly version of this script to date. Enjoy this until Zecious gets average.txt up, at which point only a few tiny edits will need to be made to move over.

@asturia: Sorry, I had already changed the name of price() to get_value() in my script before I wrote about your solution. Try it using this one and it should work. ps - it's Zarqon with a Q. :)

@jason: Thanks a bunch! I know I am one of many who appreciates your instant attention to user requests. This will be a genuinely useful feature. Once this appears in the daily builds, I'll be able to save even more server hits with some of my scripts.

I also understand your position on mall_price(). It has been a longstanding policy, as well as a longstanding request by those who didn't yet know the policy. The policy exists for good reason: just because something is created in a certain spirit, it does not follow that everyone will use it in that same spirit. Which is why proper safeguards must be in place. Previously, to my knowledge no one has requested mall price access with a suitable safeguard in mind. But I do think that a per-item time limit on price requests (per day or per session), using the cached value after that, is a suitable safeguard against the kind of abuse that Hola and Veracity want to prevent.

I can only think of two ways to bypass this safeguard, here made public along with ideas on prevention:

  • [li]1) The obvious way would be to reset mafia's external price/date cache (assuming this data is stored in a file), the easiest method of which would be deleting the file. Of course, doing that would require something outside mafia, which is no different from the way things are now. Still, if a user could simply delete a file, run a script, delete the file, run a script, etc. (or make an external script to do that) that's too easy to abuse.
    Solutions:
    • [li]Store the price/date values as part of the application file. Not sure if that is easily doable in Java. I also don't think it's the best solution.[/li]
      [li]Instead of limiting mall requests to one per item per day, limit it to one per item per session. Then the pricing cache could be kept internally. Getting more than one current price a day would require restarting mafia. I think this is an excellent solution.[/li]
      [li]If this external data were added to GLOBAL_prefs.txt or some other file that people need, normal users would be loathe to delete it, and editing it would take more time than just visiting the mall manually. Editing the data could also be made very difficult by encrypting it (probably some kind of hash of price and date together).[/li]
      [li]If you are storing the data externally, I think this is the best solution. The price/date data is stored in a separate file (encrypted to prevent editing). If mafia is run without that data file, the file is created but an internal "pricedisallowed" flag is set for that session and mall_price() will abort with an error explaining the need to restart. If the file is deleted while mafia is running, the flag will also be set. Only after restarting mafia could you then use the function, and if you deleted the file while mafia was running, you'd have to restart twice. This would only affect normal users once, if at all -- they would have to call mall_price() their first time running mafia to encounter the error.[/li]
    [/li]
    [li]2) The other method involves running many separate instances of mafia, since each one gets one price per day. For this to work would require many dummy KoL accounts with mall access, and a complex script running on all machines that communicates pricing info to one master account that serves as the mallbot. Hugely impractical, expecially in light of the fact that if you have enough meat you can already make a mallbot of sorts using the closet trick.
    Solutions: none needed, doing this would be ridiculous. It's about as easy to learn Java and write your own mallbot.[/li]

Intended behavior: mall_price() would check to see if the value is cached (or in memory) and has not expired. If the value is found, it returns that value, otherwise it returns the current minimum mall price (storing it in the cache/memory). This stored value would be used for every future call of mall_search() until 1) the cached value expired (one day), or 2) the value was no longer in memory (next session). This would have the effect of allowing only one server hit per item per day (or session), and would not enable manipulation of mall prices.

Furthermore, the script we have made here already makes once-daily item prices available. Adding this function to ASH would only make those prices more accurate, because the pricing would happen at the exact time of calling the function (the first time, which is all any script should really need).

What do you think, Hola, Ver, jason? Do I make a convincing argument?
 

Attachments

  • value.ash
    2.8 KB · Views: 35

jasonharper

Developer
[quote author=zarqon link=topic=2016.msg9939#msg9939 date=1227581155]Intended behavior: mall_price() would check to see if the value is cached (or in memory) and has not expired. If the value is found, it returns that value, otherwise it returns the current minimum mall price (storing it in the cache/memory). [/quote]
I'm not entirely sure you're asking for the right thing here - the minimum price isn't necessarily meaningful if it's a 1/day limit, or there's simply only one available at that price. Frankly, an anomalously low price seems more useful to a mallbot than a legitimate user.
 

zarqon

Well-known member
We are looking to know what we could expect to pay for an item without needing to pay for it. If the current mall price is anomalously low, that is still the price we would pay for it if we acted quickly. Further, sometimes prices which may appear to a script to be anomalies may really be trends, as is often the case with relatively new items.

If you can think of some other method whereby users looking to budget or appraise items would be better served (perhaps some kind of average of the top X stores, the mode of the top X stores, etc) I'm all for it. Such a method would be even harder to abuse.

An anomalously low daily price would not be terrifically useful to a mallbot. What would it do? Buy some items? How many? It can't know. It could try buying a handful and checking again but it would get the same cached value every time so it wouldn't know if it had succeeded in buying out the lower-priced items until the following day.
 

dj_d

Member
For the record, I love to have my work invalidated by people who redo it better.

@jasonharper: you're absolutely right. I think I suggested this in the other thread as a solution. Show the second-lowest price. Fine for budgetary purposes, nearly useless for mallbots.

@Zarqon: that big ugly hack is basically a way to make file_to_map work with URLs. It caches the context as a text file, then runs file_to_map on it.
Also, I think there's some value to parsing export.txt anyway - some people may want a high estimate of the price, some may want a low estimate, some may want the average. For example, if you're budgeting, you might prefer over-estimating to under-. The current mess seems to work pretty well, though, so I may get back to the original project (to be posted shortly).
 

jasonharper

Developer
If I was only allowed to know one number about a mall item, I think I'd want the price of the 5th or so available item - in other words, it would only be the lowest price if at least 5 were available at that price. That should skip over most price anomalies.

A mallbot could easily buy out a known underpriced item, using techniques that have been previously discussed here. Actually, there's nothing stopping one from trying that on every item that normally sells for more than min price - perhaps that loophole needs to be closed before considering anything that would make such behavior easier.
 

Bale

Minion
[quote author=jasonharper link=topic=2016.msg9949#msg9949 date=1227600276]
If I was only allowed to know one number about a mall item, I think I'd want the price of the 5th or so available item - in other words, it would only be the lowest price if at least 5 were available at that price. That should skip over most price anomalies.
[/quote]
And I'd want to know the price of the first that didn't have a limit per day. It would be pretty hard to satisfy everyone... I guess that's why this idea never goes anywhere. Still, if you were willing to add a function for the 5th item, everyone would be glad to at least get some sort of mallchecking ability for so many reasons. We understand that mallchecking will be hobbled and if this is the flavor of hobbling you prefer, I'd say thank you for offering it.
 

zarqon

Well-known member
@jason: Awesome idea. Knowing the nth item price would be great. N should probably scale depending on the ratio of price increase to n. For example, I'd want to know the 1st or 2nd cheapest Tome of Snowcone Summoning, not the 5th, as the price curve is usually steep on really pricey items -- and for really rare items, the 5th might be priced at 999,999,999. But for something cheap, knowing the 30th item price might be the best. Something like

n = (price of 1st / price of 10th)*30

I arbitrarily chose 30, but you could decide how "safe" to be with a little testing.

Or, something that looks at the difference between the 1st and 20th and what percentage of the 1st that is, if it's over 100% use a lower value for n, if it's under 100% use a higher value.

I might be getting excited about your idea and making up worthless ones of my own that I will fully think through later and reject, but I thought I would share it while the excitement was fresh. :)
 

jasonharper

Developer
[quote author=zarqon link=topic=2016.msg9939#msg9939 date=1227581155]
This would be a perfect example of a time when it would be awesome if file_to_map() worked with URLs.[/quote]
Apparently, it does already... I haven't actually tried this, but there is a special case in the code if the supplied filename starts with "http".
 

zarqon

Well-known member
[quote author=jasonharper link=topic=2016.msg9968#msg9968 date=1227648642]
there is a special case in the code if the supplied filename starts with "http".
[/quote]

That's odd because I actually tried it before writing that and didn't get any results, but testing it now shows that it works. Perhaps something else in the script wasn't working yet at that time.

I've rewritten the script to use file_to_map() with the remote today.txt. Unfortunately that meant adding a setting to your preferences file (filename => timestamp), since the timestamp was no longer stored in the data. Enjoy.
 

Attachments

  • value.ash
    2.4 KB · Views: 64

zarqon

Well-known member
[quote author=jasonharper link=topic=2016.msg9949#msg9949 date=1227600276]
A mallbot could easily buy out a known underpriced item, using techniques that have been previously discussed here. Actually, there's nothing stopping one from trying that on every item that normally sells for more than min price - perhaps that loophole needs to be closed before considering anything that would make such behavior easier.
[/quote]

How would it know it was underpriced? It would need something to compare against. A script could not arrive at a "normally sells for" number if all it had was a daily minimum from a random time. We are asking for one or the other, not both. Min price, or "normally sells for" price. For my purposes, the second one would be better, and even harder to exploit by bots.
 

Bale

Minion
I'd like to thank zarqon and dj_d for having made this script. I've used it many, many times and many scripts of mine would have been impossible without it. Now I'd like to bid it a fond adeiu since jasonharper has just implemented mall_price() in revision 6989.

Code:
item [12] super_drink;
super_drink [ 0 ] = $item[ prussian cathouse ];
super_drink [ 1 ] = $item[ Neuromancer ];
super_drink [ 2 ] = $item[ vodka stratocaster ];
super_drink [ 3 ] = $item[ Mon Tiki];
super_drink [ 4 ] = $item[ teqiwila slammer ];
super_drink [ 5 ] = $item[ Divine ];
super_drink [ 6 ] = $item[ Gordon Bennett ];
super_drink [ 7 ] = $item[ gimlet ];
super_drink [ 8 ] = $item[ yellow brick road ];
super_drink [ 9 ] = $item[ mandarina colada ];
super_drink [ 10 ] = $item[ tangarita ];
super_drink [ 11 ] = $item[ Mae West ];

int [item] price;
for i from 0 upto 11
	price [ super_drink [i] ] = mall_price(super_drink [i] );
sort super_drink by price[value];

for i from 0 upto 11
	print( price [super_drink [i]] + " "+ super_drink [i]);


Tee-hee! I'm now in price sorting heaven!

Farewell value.ash. Thanks to mafia's ongoing development I won't miss you at all, but I will always feel a little nostalgic for the good times we had.

Edit: Or if I want even more brevity, this can be reduced to a single line with cli_execute():

cli_execute ("cheapest prussian cathouse, Neuromancer, vodka stratocaster, Mon Tiki, teqiwila slammer, Divine, Gordon Bennett, gimlet, yellow brick road, mandarina colada, tangarita, Mae West");
 
Last edited:

zarqon

Well-known member
Yes indeed, the new mall_price() is just what this thread ordered. :)

I personally am keeping value.ash around. In certain info-gathering-intensive situations, such as for my clan StashBot, it is far more KoL-server-friendly to continue using this script, which only generates one server hit per day (and not on KoL servers at that). I have found it surprisingly accurate, although a few items are quite underpriced.
 

mredge73

Member
Hey Guys
Do you guys know what it means when it says "do cmds with "it" replaced with best"?
Can any of you guys explain this function for me? Thanks

This is what I am taking about:

cheapest[?] [+]item [,[-]item]... [; cmds] - compare prices, do cmds with "it" replaced with best.
expensive[?] [+]item [,[-]item]... [; cmds] - compare prices, do cmds with "it" replaced with best.
 
By itself, the "cheapest" command will search the prices of the items you specify and print them out in order from cheapest to most expensive. If you follow that with one or more CLI commands, it will instead run those commands, replacing the word "it" with the name of the cheapest item.

For example, "cheapest hi mein; eat 3 it" will search the mall to find out which hi mein is cheapest, and then eat 3 of them.
 

Bale

Minion
Or my personal favorite:
Code:
cheapest +tangarita; buy 4 it; drink 4 it;
The + means it will search the zap group!
 

zarqon

Well-known member
The wiki method was the worst of the three methods for getting pricing information (least consistent, most server-intensive), so I'm no longer using it. I may have deleted that functionality from my server, but I can't remember at the moment (I'm at work). You should be fine with just the ofloathing price and mall_price().
 
Top