Bug - Fixed  has no matches

GValko

Member
I was just finishing some farming today, when I used the CLI to mallsell. In a slip of forgetfulness I typed "mallsell * game grid", at which point Mafia threw a few debug warnings and a log out. (I was attempting to sell game grid tickets.)

Now I'm pretty sure in the past it would have asked me to disambiguate in a case like this, so I'm not exactly sure why it told me there was an error and left it at that.

Here's the debug log:
Code:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        KoLmafia v14.2 r8632, Windows Vista, Java 1.6.0_21
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Please note: do not post this log in the KoLmafia thread. If you
 would like the dev team to look at it, please write a bug report
 at kolmafia.us. Include specific information about what you were 
 doing when you made this and include the log as an attachment.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Timestamp: Tue Sep 21 22:28:43 EDT 2010
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


Unexpected error, debug log printed.
class java.lang.NumberFormatException: grid
java.lang.NumberFormatException: grid
	at net.sourceforge.kolmafia.utilities.StringUtilities.parseIntInternal1(StringUtilities.java:721)
	at net.sourceforge.kolmafia.utilities.StringUtilities.parseInt(StringUtilities.java:666)
	at net.sourceforge.kolmafia.textui.command.MallSellCommand.run(MallSellCommand.java:94)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeCommand(KoLmafiaCLI.java:527)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:401)
	at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.handleQueue(CommandDisplayFrame.java:194)
	at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.run(CommandDisplayFrame.java:175)


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        KoLmafia v14.2 r8632, Windows Vista, Java 1.6.0_21
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Please note: do not post this log in the KoLmafia thread. If you
 would like the dev team to look at it, please write a bug report
 at kolmafia.us. Include specific information about what you were 
 doing when you made this and include the log as an attachment.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Timestamp: Tue Sep 21 22:28:43 EDT 2010
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


Unexpected error, debug log printed.
class java.lang.NumberFormatException: game
java.lang.NumberFormatException: game
	at net.sourceforge.kolmafia.utilities.StringUtilities.parseIntInternal1(StringUtilities.java:721)
	at net.sourceforge.kolmafia.utilities.StringUtilities.parseInt(StringUtilities.java:666)
	at net.sourceforge.kolmafia.textui.command.MallSellCommand.run(MallSellCommand.java:109)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeCommand(KoLmafiaCLI.java:527)
	at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:401)
	at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.handleQueue(CommandDisplayFrame.java:194)
	at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.run(CommandDisplayFrame.java:175)
 
This was discussed a little here:

http://kolmafia.us/showthread.php?5231-*-has-no-matches

Here's a summery of the thread:

Every once in awhile, the cli doesn't handle commas well. Most of the time, if you put in:

Code:
mallsell * item a, * item b, * etc

Everything will work fine. But every once in awhile it'll give you an error saying, "[*] has no matches"... and the only way to get mafia to handle multiple items is to use semicolons:

Code:
mallsell * item a; mallsell * item b; mallsell * etc

The thing that's going to be hard to solve this is that what works and what doesn't seems to change everyday. A command that doesn't work yesterday may work fine today. It's not a big issue, it's just annoying when it comes up. And since I use the cli fairly often, it comes up at least once a day.
 
"mallsell * <item>" gives unexpected error when you have zero of the item

mallsell said:
> mallsell * little paper umbrella

Unexpected error, debug log printed.
Unexpected error, debug log printed.
[* little] has no matches.

> inv little paper umbrella

> mallsell little paper umbrella

Transferring items to store...
Items offered up for sale.

> mallsell 11 little paper umbrella

Transferring items to store...
Items offered up for sale.

> buy little paper umbrella

Searching for "little paper umbrella"...
Purchasing little paper umbrella (1 @ 700)...
You acquire an item: little paper umbrella
Purchases complete.

> mallsell * little paper umbrella

Transferring items to store...
Items offered up for sale.

mallsell * <item> fails when you have zero of the item (unexpected error)
mallsell N <item> succeeds even if you have zero of the item

This is in contrast to, say, closet:
closet said:
> closet take * little paper umbrella

> closet take 1 little paper umbrella

Removing items from closet...
Transfer failed for little paper umbrella

> closet put * little paper

> closet put 1 little paper

Placing items into closet...
Transfer failed for little paper umbrella
 
There are several other threads about issues with mallsell *. I'm going to merge them all together.
 
Sorry for the dupe.

There is similar behavior with display put, e.g.

display said:
> display put 111 epic beard

Placing items in display case...
Requests complete.

> display epic

Uncle Hobo's epic beard (111)
 
Here is a patch that should allow "mallsell * itemname" to not give an error message when you have 0 of the item while still giving an error message when you type an invalid item name.
 

Attachments

Hm, it looks like KoLmafia trying to guess at what your item name is based on a really old way to use the mallsell command is reporting a pretty cryptic error message that looks like it's truncating the strings within commas when the reality is it's just trying to figure out what the real command was based on some old legacy settings. Since 'help' now shows you the exact format of the command (and the command has been around for at least a few years now), I'll remove that code and see if we can't get a less cryptic error.
 
From MallSellCommand.java

PHP:
			items[ i ] = ItemFinder.getFirstMatchingItem( itemNames[ i ], true );

			if ( items[ i ] == null )
			{
				KoLmafia.updateDisplay( KoLConstants.ERROR_STATE, "[" + itemNames[ i ] + "] has no matches." );
				return;
			}

If ItemFinder.getFirstMatchingItem finds the item but you have none of the item, it returns null anyway. That's the only case the if statement there catches that ItemFinder doesn't catch, since ItemFinder already gives an error message if it doesn't find a matching item (accomplished by changing the last parameter of getFirstMatchingItem to true).
 
Is it possible that what's happening is triggered on an "unrecognized / unspecific item" issue, but reports the "*" instead of the item name? I just thought it was odd, as "game grid" could refer to either the tokens or tickets...
 
No, because I test this with "mallsell * warm subject gift certificate" with none in inventory and get the same results. If getFirstMatchingItem() finds any matching item, and if you have any of that item, it returns the item name with * stripped out. Otherwise, MallSellCommand has to use the string it started with, which includes *.

It's possible that "game grid" doesn't give a match because it's ambiguous, but the name of the function makes it sound like it should pick one somehow.

And I just realized that the if block I posted above needs to be there, because nothing else prevents the function from continuing onward, but updateDisplay() doesn't need to be in it.
 
When you don't have any warm subject gift certificate in your inventory, these:
PHP:
ItemFinder.getFirstMatchingItem( "* warm subject gift certificate", true );
ItemFinder.getFirstMatchingItem( "0 warm subject gift certificate", true );
will return null, but not
PHP:
ItemFinder.getFirstMatchingItem( "1 warm subject gift certificate", true );

I would like to change MallSellCommand to go through all the items listed in the parameters, but only add to the AdventureResult[] items map the items that don't end up being null, and whose count is not 0.

The map is defined with a fixed size though:
PHP:
AdventureResult[] items = new AdventureResult[ itemNames.length ];

I've been looking through Mafia's source, but I can't find any example of what I want to do. The ASH equivalent would be:
PHP:
AdventureResult [ int ] items;
for i from 0 to itemNames.count()-1
{
	items[ i ] = getFirstMatchingItem( itemNames[ i ], true );
}
 
Last edited:
You have three parallel arrays of fixed size. AutoMallRequest requires three arrays.
I see two choices:

1) Mall Sell Command uses three parallel ArrayListsand uses xxx.add() to add to them. It then converts each ArrayList to an array before passing them to AutoMallRequest. Look at AutoMallCommand to see exactly that with the single argument version of AutoMallRequest.
2) Make AutoMallRequest accept arrays, as currently, but, itself, skip null entries.

#1 is probably easier, for now.
 
I was working on doing 1), and I was stuck exactly at converting the ArrayList into arrays. I was trying to figure out why toArray() wasn't working, and your tip came exactly at the right time.
 
Here is what AutoMallRequest expects:
PHP:
AutoMallRequest( final Object[] items, final int[] prices, final int[] limits )
It looks like toArray() works like a charm for my ArrayList itemList, in which I add AdventureResults.

I have a problem with the prices and limits though. I add prices the the ArrayList priceList like this:
PHP:
priceList.add( new Integer( price ) );
But doing
PHP:
int[] prices = new int[ priceList.size() ];
prices = priceList.toArray();
gives me an "incompatible types" error, and
PHP:
int[] prices = new int[ priceList.size() ];
prices = (int[]) priceList.toArray()
gives me an "inconvertible type" error.

It looks likes I can't turn an Object[] into an int[].

I wish I knew Java :)
 
Unfortunately there's no built-in way to cast between those two types. Similarly, you can't cast a string to an int; you have to do something like:

Code:
for ( int i = 0; i < priceList.size(); ++i )
{
		try
		{
			prices[ i ] = Integer.parseInt( priceList[ i ] );
		}
		catch ( NumberFormatException e )
		{
			//handling for when parseInt gets a string that it can't interpret as an int
		}
}

Something like that.
 
I finally got this to work. It was instructive.

I'll post it as a patch here instead of committing, because it really feels like amateur work.
 

Attachments

Suggestion: take a look at utilities.IntegerArray. That is an ArrayList of integers. You can do:

IntegerArray ia = new IntegerArray();
ia.set( 0, 1 );
int ia.get( 0 );
int ia.size();

You could extend this utility class to have two more methods:

ia.add( 1 );
...will add a new integer to the end, just like an ArrayList

int [] ia.toArray();
... will copy the internal ArrayList of Integers into a newly allocated array of ints.

With that, you declare priceList and limitList to be IntegerArrays rather than ArrayLists, do priceList.add( price ) with an int rather than an Integer, and do the final request with

RequestThread.postRequest( new AutoMallRequest( itemList.toArray(), priceList.toArray(), limitList.toArray() ) );

What do you think?
 
Ok, new patch with your suggestions.

I still haven't committed because the command now skips names that don't match an item, or items that you don't have any of, without ending in an error state:
Code:
> inv warm subj

> ash cli_execute( "mallsell 4 warm subj @ 5000 limit 2, 1 dense meat stack @ 10000 limit 10, 1 noitemfound @ 1000, 1 meatloaf helmet @ 15000" );

[COLOR="#ff0000"][noitemfound] has no matches.[/COLOR]
Transferring items to store...
Items offered up for sale.
Returned: true
The user will have an error message for "[noitemfound] has no matches", but "mallsell 4 warm subj" does nothing silently.
 

Attachments

Code-wise, it looks good to me.

I'm not sure if the inconsistency between "mallsell <item>" and "mallsell <item> @ <price> limit <limit>" indicates the 1 argument version is right and the 3 argument version is wrong, or vice versa.
 
Back
Top