/** * Copyright (c) 2005-2017, KoLmafia development team * http://kolmafia.sourceforge.net/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * [1] Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * [2] Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * [3] Neither the name "KoLmafia" nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package net.sourceforge.kolmafia.session; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.kolmafia.KoLmafia; import net.sourceforge.kolmafia.KoLConstants.MafiaState; import net.sourceforge.kolmafia.RequestEditorKit; import net.sourceforge.kolmafia.RequestLogger; import net.sourceforge.kolmafia.request.GenericRequest; import net.sourceforge.kolmafia.request.RelayRequest; import net.sourceforge.kolmafia.utilities.StringUtilities; public abstract class DvorakManager { private static char [][] tiles = new char[7][9]; private static int currentRow = 0; private final static String solution = "BANANAS"; private static String currentSolution = ""; // <td class='cell greyed'><img // src="http://images.kingdomofloathing.com/itemimages/tilek.gif" // width=30 height=30 border=0 alt='Tile labeled "K"'></td> // // <td class='cell'><a class=nounder // href='tiles.php?action=jump&whichtile=8'><img // src="http://images.kingdomofloathing.com/itemimages/tilep.gif" // width=30 height=30 border=0 alt='Tile labeled "P"'></a></td> private static final Pattern TILE_PATTERN = Pattern.compile( "<td class='(cell|cell greyed)'.*?'Tile labeled \"(.)\"'>(</a>)?</td>" ); private static int parseTiles( final String responseText ) { Matcher matcher = DvorakManager.TILE_PATTERN.matcher( responseText ); int count = 0; while ( matcher.find() ) { int row = count / 9; int column = count % 9; if ( row > 7 ) { KoLmafia.updateDisplay( "Too many rows!" ); return -1; } if ( matcher.group(1).equals( "cell" ) ) { DvorakManager.currentRow = row; } char tile = matcher.group(2).charAt( 0 ); DvorakManager.tiles[ row ][ column ] = tile; count++; } if ( count != (7 * 9 ) ) { KoLmafia.updateDisplay( "Wrong number of cells!" ); return -1; } // If we have made it to a row, we must have successfully // jumped that far. DvorakManager.currentSolution = DvorakManager.solution.substring( 0, 6 - DvorakManager.currentRow ); return DvorakManager.currentRow; } public static void printTiles() { StringBuilder buffer = new StringBuilder(); for ( int row = 0; row < 7; ++row ) { buffer.setLength( 0 ); buffer.append( "Row " ); buffer.append( String.valueOf( row + 1 ) ); buffer.append( ": " ); for ( int col = 0; col < 9; ++col ) { buffer.append( DvorakManager.tiles[ row ][ col ] ); buffer.append( " " ); } if ( row == DvorakManager.currentRow ) { buffer.append( " ---you are here" ); } RequestLogger.printLine( buffer.toString() ); } RequestLogger.printLine(); RequestLogger.printLine( "Current solution = \"" + DvorakManager.currentSolution + "\"" ); } public static final void parseResponse( final String urlString, final String responseText ) { if ( !urlString.startsWith( "tiles.php" ) ) { return; } // We can get the puzzle from whatever row we are on. Unless we screwed up. // // As you step to that tile, something tells you that you've // made an incorrect choice. That something is a large stone // pillar pistoning down from the ceiling and mashing you to a // pulp. Squish! if ( responseText.contains( "Squish!" ) ) { String message = "Oops."; RequestLogger.printLine( message ); RequestLogger.updateSessionLog( message ); DvorakManager.currentRow = -1; } else { DvorakManager.parseTiles( responseText ); } } public static final void lastTile( final String responseText ) { // Called when we arrive at choice 125 // // You jump to the last letter, and put your pom-poms down with // a sigh of relief -- thank goodness that's // over. Worst. Spelling bee. Ever. if ( responseText.contains( "You jump to the last letter" ) ) { StringBuilder buffer = new StringBuilder(); buffer.append( "What's that spell? " ); buffer.append( DvorakManager.currentSolution ); buffer.append( "!" ); String message = buffer.toString(); RequestLogger.printLine( message ); RequestLogger.updateSessionLog( message ); } } private static final Pattern WHICHTILE_PATTERN = Pattern.compile( "whichtile=(\\d)" ); private static final String AN_LETTERS = "AEFILMNORSX"; public static final boolean registerRequest( final String urlString ) { if ( !urlString.startsWith( "tiles.php" ) ) { return false; } Matcher matcher = DvorakManager.WHICHTILE_PATTERN.matcher( urlString ); if ( !matcher.find() ) { RequestLogger.registerLocation( "The Hidden Temple" ); return true; } int col = StringUtilities.parseInt( matcher.group( 1 ) ); // We saved the array and currentRow when we last visited the puzzle. if ( DvorakManager.currentRow < 0 || DvorakManager.currentRow > 6 || col < 0 || col > 8 ) { // Shouldn't happen, but log the URL, at least return false; } int row = DvorakManager.currentRow; char letter = DvorakManager.tiles[ row ][ col ]; DvorakManager.currentSolution += letter; StringBuilder buffer = new StringBuilder(); buffer.append( "Give me " ); buffer.append( DvorakManager.AN_LETTERS.indexOf( letter ) != -1 ? "an" : "a" ); buffer.append( " " ); buffer.append( letter ); buffer.append( "!" ); String message = buffer.toString(); RequestLogger.printLine( message ); RequestLogger.updateSessionLog( message ); return true; } public static final void decorate( final StringBuffer buffer ) { String search = "</div></center></td></tr>"; int index = buffer.indexOf( search ); if ( index == -1 ) { return; } index += 6; // Build a "Solve!" button StringBuffer button = new StringBuffer(); button.append( "<form name=solveform action='" ); button.append( "/KoLmafia/specialCommand?cmd=dvorak&pwd=" ); button.append( GenericRequest.passwordHash ); button.append( "' method=post>" ); button.append( "<input class=button type=submit value=\"Solve!\">" ); button.append( "</form>" ); // Insert it into the page buffer.insert( index, button ); } private static String lastResponse = ""; public static final void saveResponse( final String responseText ) { DvorakManager.lastResponse = responseText; } public static final void solve() { if ( DvorakManager.lastResponse == null ) { KoLmafia.updateDisplay( MafiaState.ERROR, "You don't appear to be at the tiles puzzle" ); return; } // When we visited this url, we parsed the responseText and // saved the tiles and currentRow if ( DvorakManager.currentRow < 0 ) { KoLmafia.updateDisplay( MafiaState.ERROR, "We can't tell what row you are on" ); return; } // Execute requests to hop from tile to tile to the end. GenericRequest request = new GenericRequest( "" ); for ( int row = DvorakManager.currentRow; row >= 0; --row ) { char match = solution.charAt( 6 - row ); int found = -1; for ( int col = 0; col < 9; ++col ) { char tile = tiles[ row ][ col ]; if ( match == tile ) { found = col; break; } } if ( found == -1 ) { KoLmafia.updateDisplay( "Could not find '" + match + "' in row " + ( row + 1 ) ); return; } String url = "tiles.php?action=jump&whichtile=" + found; request.constructURLString( url ); request.run(); } StringBuffer buffer = new StringBuffer( request.responseText ); RequestEditorKit.getFeatureRichHTML( request.getURLString(), buffer ); RelayRequest.specialCommandResponse = buffer.toString(); RelayRequest.specialCommandIsAdventure = true; DvorakManager.lastResponse = null; } }