@Override
  public void run(final String cmd, String parameters) {
    AdventureResult crop = CampgroundRequest.getCrop();
    if (crop == null) {
      KoLmafia.updateDisplay("You don't have a garden.");
      return;
    }

    int count = crop.getCount();

    if (parameters.equals("")) {
      String name = count != 1 ? ItemDatabase.getPluralName(crop.getItemId()) : crop.getName();
      KoLmafia.updateDisplay("Your garden has " + count + " " + name + " in it.");
      return;
    }

    if (parameters.equals("pick")) {
      if (count == 0) {
        KoLmafia.updateDisplay("There is nothing ready to pick in your garden.");
        return;
      }

      if (!Limitmode.limitCampground() && !KoLCharacter.isEd() && !KoLCharacter.inNuclearAutumn()) {
        CampgroundRequest.harvestCrop();
      }
    }
  }
  public static boolean isAllowed(String type, final String key) {
    if (KoLCharacter.isTrendy() && !TrendyRequest.isTrendy(type, key)) {
      return false;
    }
    if (!KoLCharacter.getRestricted()) {
      return true;
    }

    if (type.equals("Bookshelf")) {
      type = "Bookshelf Books";
    } else if (type.equals("Clan Item")) {
      type = "Clan Items";
    }

    if (type.equals("Bookshelf Books")) {
      // Work around a KoL bug: most restricted books are
      // listed both under Bookshelf Books and Items, but
      // 3 are listed under only one or the other.
      return StandardRequest.isNotRestricted("Bookshelf Books", key)
          && StandardRequest.isNotRestricted("Items", key);
    }

    List<String> list = StandardRequest.typeToList(type);
    return list != null && StandardRequest.isNotRestricted(list, key);
  }
Exemple #3
0
  public static final String getCounters(String label, int minTurns, int maxTurns) {
    label = label.toLowerCase();
    boolean checkExempt = label.length() == 0;
    minTurns += KoLCharacter.getCurrentRun();
    maxTurns += KoLCharacter.getCurrentRun();
    StringBuilder buf = new StringBuilder();

    synchronized (TurnCounter.relayCounters) {
      for (TurnCounter current : TurnCounter.relayCounters) {
        if (current.value < minTurns || current.value > maxTurns) {
          continue;
        }
        if (checkExempt && current.isExempt("")) {
          continue;
        }
        if (!current.parsedLabel.toLowerCase().contains(label)) {
          continue;
        }
        if (buf.length() != 0) {
          buf.append("\t");
        }
        buf.append(current.parsedLabel);
      }
    }

    return buf.toString();
  }
Exemple #4
0
 public int getTurnsRemaining() {
   int remain = this.value - KoLCharacter.getCurrentRun();
   if (remain < 0 && this.wander) {
     this.value = KoLCharacter.getCurrentRun();
     remain = 0;
   }
   return remain;
 }
  public static void logout() {
    if (LogoutManager.isRunning) {
      return;
    }

    LogoutManager.isRunning = true;

    // If there's no user to worry about, we're done now.

    String userName = KoLCharacter.getUserName();

    if (userName == null || userName.equals("")) {
      return;
    }

    if (!KoLmafia.isSessionEnding()) {
      LogoutManager.prepare();
    }

    KoLmafia.updateDisplay("Preparing for logout...");

    // Shut down chat-related activity

    BuffBotHome.setBuffBotActive(false);
    ChatManager.dispose();

    // Run on-logout scripts

    String scriptSetting = Preferences.getString("logoutScript");
    if (!scriptSetting.equals("")) {
      KoLmafia.updateDisplay("Executing logout script...");
      KoLmafiaCLI.DEFAULT_SHELL.executeLine(scriptSetting);
    }

    if (Preferences.getBoolean("sharePriceData")) {
      KoLmafia.updateDisplay("Sharing mall price data with other users...");
      KoLmafiaCLI.DEFAULT_SHELL.executeLine(
          "spade prices http://kolmafia.us/scripts/updateprices.php");
    }

    // Clear out user data

    RequestLogger.closeSessionLog();
    RequestLogger.closeMirror();

    GenericRequest.reset();
    KoLCharacter.reset("");

    // Execute the logout request

    RequestThread.postRequest(new LogoutRequest());
    KoLmafia.updateDisplay("Logout completed.");

    RequestLogger.closeDebugLog();

    LogoutManager.isRunning = false;
  }
  private static void doLogin(String name) {
    LoginRequest.isLoggingIn(true);

    try {
      ConcoctionDatabase.deferRefresh(true);
      LoginManager.initialize(name);
    } finally {
      ConcoctionDatabase.deferRefresh(false);
      LoginRequest.isLoggingIn(false);
    }

    // Abort further processing in Valhalla.
    if (CharPaneRequest.inValhalla()) {
      return;
    }

    // Abort further processing if we logged in to a fight or choice
    if (KoLmafia.isRefreshing()) {
      return;
    }

    if (Preferences.getBoolean(name, "getBreakfast")) {
      int today = HolidayDatabase.getPhaseStep();
      BreakfastManager.getBreakfast(Preferences.getInteger("lastBreakfast") != today);
      Preferences.setInteger("lastBreakfast", today);
    }

    if (Preferences.getBoolean("sharePriceData")) {
      KoLmafiaCLI.DEFAULT_SHELL.executeLine(
          "update prices http://kolmafia.us/scripts/updateprices.php?action=getmap");
    }

    // Also, do mushrooms, if a mushroom script has already
    // been setup by the user.

    if (Preferences.getBoolean(
        "autoPlant" + (KoLCharacter.canInteract() ? "Softcore" : "Hardcore"))) {
      String currentLayout = Preferences.getString("plantingScript");
      if (!currentLayout.equals("")
          && KoLCharacter.knollAvailable()
          && MushroomManager.ownsPlot()) {
        KoLmafiaCLI.DEFAULT_SHELL.executeLine(
            "call " + KoLConstants.PLOTS_DIRECTORY + currentLayout + ".ash");
      }
    }

    String scriptSetting = Preferences.getString("loginScript");
    if (!scriptSetting.equals("")) {
      KoLmafiaCLI.DEFAULT_SHELL.executeLine(scriptSetting);
    }

    if (EventManager.hasEvents()) {
      KoLmafiaCLI.DEFAULT_SHELL.executeLine("events");
    }
  }
Exemple #7
0
  public static final boolean isCounting(final String label, final int start, final int stop) {
    int begin = KoLCharacter.getCurrentRun() + start;
    int end = KoLCharacter.getCurrentRun() + stop;

    synchronized (TurnCounter.relayCounters) {
      for (TurnCounter current : TurnCounter.relayCounters) {
        if (current.parsedLabel.equals(label) && current.value >= begin && current.value <= end) {
          return true;
        }
      }
    }

    return false;
  }
Exemple #8
0
  public static final String getUnexpiredCounters() {
    int currentTurns = KoLCharacter.getCurrentRun();
    StringBuilder counters = new StringBuilder();

    synchronized (TurnCounter.relayCounters) {
      for (TurnCounter current : TurnCounter.relayCounters) {
        if (current.value < currentTurns) {
          // Can't remove the counter - a counterScript
          // may still be waiting for it to be delivered.
          continue;
        }

        if (counters.length() > 0) {
          counters.append(KoLConstants.LINE_BREAK);
        }

        counters.append(current.parsedLabel);
        counters.append(" (");
        counters.append(current.value - currentTurns);
        counters.append(")");
      }
    }

    return counters.toString();
  }
  public static void prepare() {
    // If there's no user to worry about, we're done now.

    String userName = KoLCharacter.getUserName();

    if (userName == null || userName.equals("")) {
      return;
    }

    // If you need to allow for another login, create a login frame
    // to ensure that there is an active frame to display messages.

    if (StaticEntity.getClient() instanceof KoLmafiaGUI) {
      KoLmafiaGUI.constructFrame(LoginFrame.class);
    }

    // Shut down main frame

    if (KoLDesktop.instanceExists()) {
      KoLDesktop.getInstance().dispose();
    }

    // Close down any other active frames.	Since
    // there is at least one active, logout will
    // not be called again.

    Frame[] frames = Frame.getFrames();

    for (int i = 0; i < frames.length; ++i) {
      if (frames[i].getClass() != LoginFrame.class) {
        frames[i].dispose();
      }
    }
  }
Exemple #10
0
  public TurnCounter(final int value, final String label, final String image) {
    this.value = KoLCharacter.getCurrentRun() + value;
    this.label = label.replaceAll(":", "");
    this.image = image.replaceAll(":", "");
    this.lastWarned = -1;
    this.parsedLabel = this.label;
    int pos = this.parsedLabel.lastIndexOf(" ");
    while (pos != -1) {
      String word = this.parsedLabel.substring(pos + 1).trim();
      if (word.equals("loc=*")) {
        this.exemptions = TurnCounter.ALL_LOCATIONS;
      } else if (word.startsWith("loc=")) {
        if (this.exemptions == null) {
          this.exemptions = new HashSet<String>();
        }
        this.exemptions.add(word.substring(4));
      } else if (word.startsWith("type=")) {
        if (word.substring(5).equals("wander")) {
          this.wander = true;
        }
      } else if (word.contains(".php")) {
        this.URL = word;
      } else break;

      this.parsedLabel = this.parsedLabel.substring(0, pos).trim();
      pos = this.parsedLabel.lastIndexOf(" ");
    }
    if (this.parsedLabel.length() == 0) {
      this.parsedLabel = "Manual";
    }
  }
 public static boolean isNotRestricted(final String type, final String key) {
   if (!KoLCharacter.getRestricted()) {
     return true;
   }
   List<String> list = StandardRequest.typeToList(type);
   return list != null && StandardRequest.isNotRestricted(list, key);
 }
Exemple #12
0
  public static final TurnCounter getExpiredCounter(GenericRequest request, boolean informational) {
    String URL = request.getURLString();
    KoLAdventure adventure = AdventureDatabase.getAdventureByURL(URL);

    String adventureId;
    int turnsUsed;

    if (adventure != null) {
      adventureId = adventure.getAdventureId();
      turnsUsed = adventure.getRequest().getAdventuresUsed();
    } else if (AdventureDatabase.getUnknownName(URL) != null) {
      adventureId = "";
      turnsUsed = 1;
    } else {
      adventureId = "";
      turnsUsed = TurnCounter.getTurnsUsed(request);
    }

    if (turnsUsed == 0) {
      return null;
    }

    int thisTurn = KoLCharacter.getCurrentRun();
    int currentTurns = thisTurn + turnsUsed - 1;

    synchronized (TurnCounter.relayCounters) {
      Iterator<TurnCounter> it = TurnCounter.relayCounters.iterator();

      while (it.hasNext()) {
        TurnCounter current = it.next();

        if (current.value > currentTurns
            || current.lastWarned == thisTurn
            || current.isExempt(adventureId) != informational) {
          continue;
        }

        if (informational
            && current.value > thisTurn) { // Defer until later, there's no point in reporting an
          // informational counter prior to actual expiration.
          continue;
        }

        if (current.value < thisTurn) {
          if (current.wander) {
            // This might not actually be necessary
            continue;
          }
          it.remove();
        }

        current.lastWarned = thisTurn;
        return current;
      }
    }

    return null;
  }
Exemple #13
0
  public static final boolean isCounting(final String label) {
    synchronized (TurnCounter.relayCounters) {
      for (TurnCounter current : TurnCounter.relayCounters) {
        if (current.parsedLabel.equals(label) && current.value >= KoLCharacter.getCurrentRun()) {
          return true;
        }
      }
    }

    return false;
  }
Exemple #14
0
  public static int turnsRemaining(final String label) {
    synchronized (TurnCounter.relayCounters) {
      for (TurnCounter current : TurnCounter.relayCounters) {
        if (current.parsedLabel.equals(label)) {
          return current.value - KoLCharacter.getCurrentRun();
        }
      }
    }

    return -1;
  }
    @Override
    public boolean isVisible(final Object element) {
      AdventureResult item = (AdventureResult) element;
      int itemId = item.getItemId();

      if (RestoresDatabase.isRestore(itemId)) {
        String itemName = item.getName();
        if (KoLCharacter.inBeecore() && KoLCharacter.hasBeeosity(itemName)) {
          return false;
        }
        if (RestoresDatabase.getUsesLeft(itemName) == 0) {
          return false;
        }
        if (RestoresDatabase.getHPRange(itemName).length() == 0
            && RestoresDatabase.getMPRange(itemName).length() == 0) {
          return false;
        }
        return super.isVisible(element);
      }
      return false;
    }
Exemple #16
0
  public static final void loadCounters() {
    synchronized (TurnCounter.relayCounters) {
      TurnCounter.relayCounters.clear();

      String counters = Preferences.getString("relayCounters");
      if (counters.length() == 0) {
        return;
      }

      StringTokenizer tokens = new StringTokenizer(counters, ":");
      while (tokens.hasMoreTokens()) {
        int turns = StringUtilities.parseInt(tokens.nextToken()) - KoLCharacter.getCurrentRun();
        if (!tokens.hasMoreTokens()) break;
        String name = tokens.nextToken();
        if (!tokens.hasMoreTokens()) break;
        String image = tokens.nextToken();
        startCountingInternal(turns, name, image);
      }
    }
  }
    private void buff(boolean maxBuff) {
      UseSkillRequest request = (UseSkillRequest) SkillBuffFrame.this.skillSelect.getSelectedItem();
      if (request == null) {
        return;
      }

      String buffName = request.getSkillName();
      if (buffName == null) {
        return;
      }

      String[] targets =
          StaticEntity.getClient()
              .extractTargets((String) SkillBuffFrame.this.targetSelect.getSelectedItem());

      int buffCount =
          !maxBuff
              ? InputFieldUtilities.getValue(SkillBuffFrame.this.amountField, 1)
              : Integer.MAX_VALUE;
      if (buffCount == 0) {
        return;
      }

      SpecialOutfit.createImplicitCheckpoint();

      if (targets.length == 0) {
        RequestThread.postRequest(
            UseSkillRequest.getInstance(buffName, KoLCharacter.getUserName(), buffCount));
      } else {
        for (int i = 0; i < targets.length && KoLmafia.permitsContinue(); ++i) {
          if (targets[i] != null) {
            RequestThread.postRequest(UseSkillRequest.getInstance(buffName, targets[i], buffCount));
          }
        }
      }

      SpecialOutfit.restoreImplicitCheckpoint();
    }
  public static void cleanup() {
    int itemCount;
    AdventureResult currentItem;

    Object[] items = KoLConstants.junkList.toArray();

    // Before doing anything else, go through the list of items
    // which are traditionally used and use them. Also, if the item
    // can be untinkered, it's usually more beneficial to untinker
    // first.

    boolean madeUntinkerRequest = false;
    boolean canUntinker = UntinkerRequest.canUntinker();

    ArrayList closetList = new ArrayList();

    for (int i = 0; i < items.length; ++i) {
      if (!KoLConstants.singletonList.contains(items[i])
          || KoLConstants.closet.contains(items[i])) {
        continue;
      }

      if (KoLConstants.inventory.contains(items[i])) {
        closetList.add(((AdventureResult) items[i]).getInstance(1));
      }
    }

    if (closetList.size() > 0) {
      RequestThread.postRequest(
          new ClosetRequest(ClosetRequest.INVENTORY_TO_CLOSET, closetList.toArray()));
    }

    do {
      madeUntinkerRequest = false;

      for (int i = 0; i < items.length; ++i) {
        currentItem = (AdventureResult) items[i];
        itemCount = currentItem.getCount(KoLConstants.inventory);

        if (itemCount == 0) {
          continue;
        }

        if (canUntinker
            && (ConcoctionDatabase.getMixingMethod(currentItem) & KoLConstants.CT_MASK)
                == KoLConstants.COMBINE) {
          RequestThread.postRequest(new UntinkerRequest(currentItem.getItemId()));
          madeUntinkerRequest = true;
          continue;
        }

        switch (currentItem.getItemId()) {
          case 184: // briefcase
          case 533: // Gnollish toolbox
          case 553: // 31337 scroll
          case 604: // Penultimate fantasy chest
          case 621: // Warm Subject gift certificate
          case 831: // small box
          case 832: // large box
          case 1768: // Gnomish toolbox
          case 1917: // old leather wallet
          case 1918: // old coin purse
          case 2057: // black pension check
          case 2058: // black picnic basket
          case 2511: // Frat Army FGF
          case 2512: // Hippy Army MPE
          case 2536: // canopic jar
          case 2612: // ancient vinyl coin purse
            RequestThread.postRequest(
                UseItemRequest.getInstance(currentItem.getInstance(itemCount)));
            break;
        }
      }
    } while (madeUntinkerRequest);

    // Now you've got all the items used up, go ahead and prepare to
    // pulverize strong equipment.

    int itemPower;

    if (KoLCharacter.hasSkill("Pulverize")) {
      boolean hasMalusAccess = KoLCharacter.isMuscleClass() && !KoLCharacter.isAvatarOfBoris();

      for (int i = 0; i < items.length; ++i) {
        currentItem = (AdventureResult) items[i];

        if (KoLConstants.mementoList.contains(currentItem)) {
          continue;
        }

        if (currentItem.getName().startsWith("antique")) {
          continue;
        }

        itemCount = currentItem.getCount(KoLConstants.inventory);
        itemPower = EquipmentDatabase.getPower(currentItem.getItemId());

        if (itemCount > 0 && !NPCStoreDatabase.contains(currentItem.getName(), false)) {
          switch (ItemDatabase.getConsumptionType(currentItem.getItemId())) {
            case KoLConstants.EQUIP_HAT:
            case KoLConstants.EQUIP_PANTS:
            case KoLConstants.EQUIP_SHIRT:
            case KoLConstants.EQUIP_WEAPON:
            case KoLConstants.EQUIP_OFFHAND:
              if (InventoryManager.hasItem(ItemPool.TENDER_HAMMER) && itemPower >= 100
                  || hasMalusAccess && itemPower > 10) {
                RequestThread.postRequest(new PulverizeRequest(currentItem.getInstance(itemCount)));
              }

              break;

            case KoLConstants.EQUIP_FAMILIAR:
            case KoLConstants.EQUIP_ACCESSORY:
              if (InventoryManager.hasItem(ItemPool.TENDER_HAMMER)) {
                RequestThread.postRequest(new PulverizeRequest(currentItem.getInstance(itemCount)));
              }

              break;

            default:
              if (currentItem.getName().endsWith("powder")
                  || currentItem.getName().endsWith("nuggets")) {
                RequestThread.postRequest(new PulverizeRequest(currentItem.getInstance(itemCount)));
              }

              break;
          }
        }
      }
    }

    // Now you've got all the items used up, go ahead and prepare to
    // sell anything that's left.

    ArrayList sellList = new ArrayList();

    for (int i = 0; i < items.length; ++i) {
      currentItem = (AdventureResult) items[i];

      if (KoLConstants.mementoList.contains(currentItem)) {
        continue;
      }

      if (currentItem.getItemId() == ItemPool.MEAT_PASTE) {
        continue;
      }

      itemCount = currentItem.getCount(KoLConstants.inventory);
      if (itemCount > 0) {
        sellList.add(currentItem.getInstance(itemCount));
      }
    }

    if (!sellList.isEmpty()) {
      RequestThread.postRequest(new AutoSellRequest(sellList.toArray()));
      sellList.clear();
    }

    if (!KoLCharacter.canInteract()) {
      for (int i = 0; i < items.length; ++i) {
        currentItem = (AdventureResult) items[i];

        if (KoLConstants.mementoList.contains(currentItem)) {
          continue;
        }

        if (currentItem.getItemId() == ItemPool.MEAT_PASTE) {
          continue;
        }

        itemCount = currentItem.getCount(KoLConstants.inventory) - 1;
        if (itemCount > 0) {
          sellList.add(currentItem.getInstance(itemCount));
        }
      }

      if (!sellList.isEmpty()) {
        RequestThread.postRequest(new AutoSellRequest(sellList.toArray()));
      }
    }
  }
  public static void use(final String command, String parameters) {
    if (parameters.equals("")) {
      return;
    }

    boolean either = parameters.startsWith("either ");
    if (either) {
      parameters = parameters.substring(7).trim();
    }

    if (command.equals("eat") || command.equals("eatsilent")) {
      if (KoLCharacter.inBadMoon() && KitchenCommand.visit(parameters)) {
        return;
      }
      if (KoLCharacter.canadiaAvailable() && RestaurantCommand.makeChezSnooteeRequest(parameters)) {
        return;
      }
    }

    if (command.equals("drink") || command.equals("overdrink")) {
      if (KoLCharacter.inBadMoon() && KitchenCommand.visit(parameters)) {
        return;
      }
      if (KoLCharacter.gnomadsAvailable()
          && RestaurantCommand.makeMicroBreweryRequest(parameters)) {
        return;
      }
    }

    // Now, handle the instance where the first item is actually
    // the quantity desired, and the next is the amount to use

    if (command.equals("eat") || command.equals("eatsilent") || command.equals("ghost")) {
      ItemFinder.setMatchType(ItemFinder.FOOD_MATCH);
    } else if (command.equals("drink") || command.equals("overdrink") || command.equals("hobo")) {
      ItemFinder.setMatchType(ItemFinder.BOOZE_MATCH);
    } else if (command.equals("slimeling")) {
      ItemFinder.setMatchType(ItemFinder.EQUIP_MATCH);
    } else {
      ItemFinder.setMatchType(ItemFinder.USE_MATCH);
    }

    Object[] itemList = ItemFinder.getMatchingItemList(KoLConstants.inventory, parameters);

    ItemFinder.setMatchType(ItemFinder.ANY_MATCH);

    for (int level = either ? 0 : 2;
        level <= 2;
        ++level) { // level=0: use only items in inventory, exit on first success
      // level=1: buy/make as needed, exit on first success
      // level=2: use all items in list, buy/make as needed
      for (int i = 0; i < itemList.length; ++i) {
        AdventureResult currentMatch = (AdventureResult) itemList[i];
        int consumpt = ItemDatabase.getConsumptionType(currentMatch.getItemId());

        if (command.equals("eat") && consumpt == KoLConstants.CONSUME_FOOD_HELPER) { // allowed
        } else if (command.equals("eat") || command.equals("ghost")) {
          if (consumpt != KoLConstants.CONSUME_EAT) {
            KoLmafia.updateDisplay(
                MafiaState.ERROR, currentMatch.getName() + " cannot be consumed.");
            return;
          }
        }

        if (command.equals("drink") && consumpt == KoLConstants.CONSUME_DRINK_HELPER) { // allowed
        } else if (command.equals("drink") || command.equals("hobo")) {
          if (consumpt != KoLConstants.CONSUME_DRINK) {
            KoLmafia.updateDisplay(
                MafiaState.ERROR, currentMatch.getName() + " is not an alcoholic beverage.");
            return;
          }
        }

        if (command.equals("use")) {
          switch (consumpt) {
            case KoLConstants.CONSUME_EAT:
            case KoLConstants.CONSUME_FOOD_HELPER:
              KoLmafia.updateDisplay(MafiaState.ERROR, currentMatch.getName() + " must be eaten.");
              return;
            case KoLConstants.CONSUME_DRINK:
            case KoLConstants.CONSUME_DRINK_HELPER:
              KoLmafia.updateDisplay(
                  MafiaState.ERROR, currentMatch.getName() + " is an alcoholic beverage.");
              return;
          }
        }

        int have = currentMatch.getCount(KoLConstants.inventory);
        if (level > 0 || have > 0) {
          if (level == 0 && have < currentMatch.getCount()) {
            currentMatch = currentMatch.getInstance(have);
          }
          if (KoLmafiaCLI.isExecutingCheckOnlyCommand) {
            RequestLogger.printLine(currentMatch.toString());
          } else {
            UseItemRequest request =
                command.equals("hobo")
                    ? UseItemRequest.getInstance(KoLConstants.CONSUME_HOBO, currentMatch)
                    : command.equals("ghost")
                        ? UseItemRequest.getInstance(KoLConstants.CONSUME_GHOST, currentMatch)
                        : command.equals("slimeling")
                            ? UseItemRequest.getInstance(KoLConstants.CONSUME_SLIME, currentMatch)
                            : UseItemRequest.getInstance(currentMatch);
            RequestThread.postRequest(request);
          }

          if (level < 2) {
            return;
          }
        }
      }
    }
  }
 public static void initialize() {
   if (!StandardRequest.initialized && KoLCharacter.getLimitmode() == null) {
     RequestThread.postRequest(StandardRequest.INSTANCE);
   }
 }
  /**
   * Initializes the <code>KoLmafia</code> session. Called after the login has been confirmed to
   * notify that the login was successful, the user-specific settings should be loaded, and the user
   * can begin adventuring.
   */
  public static void initialize(final String username) {
    // Load the JSON string first, so we can use it, if necessary.
    ActionBarManager.loadJSONString();

    // Initialize the variables to their initial states to avoid
    // null pointers getting thrown all over the place

    // Do this first to reset per-player item aliases
    ItemDatabase.reset();

    KoLCharacter.reset(username);

    // Get rid of cached password hashes in KoLAdventures
    AdventureDatabase.refreshAdventureList();

    // Reset all per-player information

    ChatManager.reset();
    MailManager.clearMailboxes();
    StoreManager.clearCache();
    DisplayCaseManager.clearCache();
    ClanManager.clearCache();

    CampgroundRequest.reset();
    MushroomManager.reset();
    HermitRequest.initialize();
    SpecialOutfit.forgetCheckpoints();

    KoLmafia.updateDisplay("Initializing session for " + username + "...");
    Preferences.setString("lastUsername", username);

    // Perform requests to read current character's data

    StaticEntity.getClient().refreshSession();

    // Reset the session tally and encounter list

    StaticEntity.getClient().resetSession();

    // Open the session log and indicate that we've logged in.

    RequestLogger.openSessionLog();

    if (Preferences.getBoolean("logStatusOnLogin")) {
      KoLmafiaCLI.DEFAULT_SHELL.executeCommand("log", "snapshot");
    }

    // If the password hash is non-null, then that means you
    // might be mid-transition.

    if (GenericRequest.passwordHash.equals("")) {
      PasswordHashRequest request = new PasswordHashRequest("lchat.php");
      RequestThread.postRequest(request);
    }

    ContactManager.registerPlayerId(username, String.valueOf(KoLCharacter.getUserId()));

    if (Preferences.getString("spadingData").length() > 10) {
      KoLmafia.updateDisplay(
          "Some data has been collected that may be of interest "
              + "to others.  Please type `spade' to examine and submit or delete this data.");
    }

    // Rebuild Scripts menu if needed
    GenericFrame.compileScripts();

    if (StaticEntity.getClient() instanceof KoLmafiaGUI) {
      KoLmafiaGUI.intializeMainInterfaces();
    } else if (Preferences.getString("initialFrames").indexOf("LocalRelayServer") != -1) {
      KoLmafiaGUI.constructFrame("LocalRelayServer");
    }

    String updateText;

    String holiday = HolidayDatabase.getHoliday(true);
    String moonEffect = HolidayDatabase.getMoonEffect();

    if (holiday.equals("")) {
      updateText = moonEffect;
    } else {
      updateText = holiday + ", " + moonEffect;
    }

    KoLmafia.updateDisplay(updateText);

    if (MailManager.hasNewMessages()) {
      KoLmafia.updateDisplay("You have new mail.");
    }
  }
  @Override
  public void run(final String cmd, final String parameters) {
    int splitIndex = parameters.indexOf("=");
    if (splitIndex == -1) {
      // Allow reading of system properties

      if (parameters.startsWith("System.")) {
        RequestLogger.printLine(System.getProperty(parameters.substring(7)));
      } else if (Preferences.isUserEditable(parameters)) {
        RequestLogger.printLine(Preferences.getString(parameters));
      }

      return;
    }

    String name = parameters.substring(0, splitIndex).trim();
    if (!Preferences.isUserEditable(name)) {
      return;
    }

    String value = parameters.substring(splitIndex + 1).trim();
    if (value.startsWith("\"")) {
      value = value.substring(1, value.endsWith("\"") ? value.length() - 1 : value.length());
    }

    while (value.endsWith(";")) {
      value = value.substring(0, value.length() - 1).trim();
    }

    if (name.equals("battleAction")) {
      if (value.contains(";") || value.startsWith("consult")) {
        CombatActionManager.setDefaultAction(value);
        value = "custom combat script";
      } else {
        value = CombatActionManager.getLongCombatOptionName(value);
      }

      // Special handling of the battle action property,
      // such that auto-recovery gets reset as needed.

      if (name.equals("battleAction") && value != null) {
        LockableListFactory.setSelectedItem(KoLCharacter.getBattleSkillNames(), value);
      }
    }

    if (name.equals("customCombatScript")) {
      ChangeCombatScriptCommand.update(value);
      return;
    }

    if (name.startsWith("combatHotkey")) {
      String desiredValue = CombatActionManager.getLongCombatOptionName(value);

      if (!desiredValue.startsWith("attack") || value.startsWith("attack")) {
        value = desiredValue;
      }
    }

    if (name.equals("_userMods")) {
      Modifiers.overrideModifier("Generated:_userMods", value);
      KoLCharacter.recalculateAdjustments();
      KoLCharacter.updateStatus();
    }

    if (Preferences.getString(name).equals(value)) {
      return;
    }

    // suppress CLI output iff it is a pref that starts with _ AND is defined in defaults.txt
    if (!name.startsWith("_") || Preferences.containsDefault(name))
      RequestLogger.printLine(name + " => " + value);
    Preferences.setString(name, value);

    if (name.startsWith("combatHotkey")) {
      StationaryButtonDecorator.reloadCombatHotkeyMap();
    }
  }
  public static boolean makeChezSnooteeRequest(final String parameters) {
    if (!KoLCharacter.canadiaAvailable()) {
      KoLmafia.updateDisplay(
          "Since you have no access to Little Canadia, you may not visit the restaurant.");
      return false;
    }

    if (KoLConstants.restaurantItems.isEmpty()) {
      ChezSnooteeRequest.getMenu();
    }

    if (parameters.equals("")) {
      RequestLogger.printLine("Today's Special: " + ChezSnooteeRequest.getDailySpecial());
      return false;
    }

    String[] splitParameters = AbstractCommand.splitCountAndName(parameters);
    String countString = splitParameters[0];
    String nameString = splitParameters[1];

    if (nameString.equalsIgnoreCase("daily special")) {
      nameString = ChezSnooteeRequest.getDailySpecial().getName();
    } else if (nameString.startsWith("\u00B6")) {
      String name = ItemDatabase.getItemName(StringUtilities.parseInt(nameString.substring(1)));
      if (name != null) {
        nameString = name;
      }
    }

    nameString = nameString.toLowerCase();

    for (int i = 0; i < KoLConstants.restaurantItems.size(); ++i) {
      String name = (String) KoLConstants.restaurantItems.get(i);

      if (!StringUtilities.substringMatches(name.toLowerCase(), nameString, false)) {
        continue;
      }

      if (KoLmafiaCLI.isExecutingCheckOnlyCommand) {
        RequestLogger.printLine(name);
        return true;
      }

      int count =
          countString == null || countString.length() == 0
              ? 1
              : StringUtilities.parseInt(countString);

      if (count == 0) {
        int fullness = ItemDatabase.getFullness(name);
        if (fullness > 0) {
          count = (KoLCharacter.getFullnessLimit() - KoLCharacter.getFullness()) / fullness;
        }
      }

      for (int j = 0; j < count; ++j) {
        RequestThread.postRequest(new ChezSnooteeRequest(name));
      }

      return true;
    }

    return false;
  }