A user asked about how to get the contents of stash and save info to a file based on the new code posted. Here's an example that does Skill Gems and Currency.
You can modify the actual text output in the format you need. If anyone has any questions about this example or why a certain thing is done, feel free to ask. If you'd like an example of doing something different in this category, just shoot me a PM, and an example can be made (or put on the todo list, as not all the new code is done yet).
Updated for Beta #796+
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using Buddy.Coroutines;
using log4net;
using Loki.Bot.v2;
using Loki.Game;
using Loki.Game.GameData;
using Loki.TreeSharp;
using Loki.Utilities;
using Action = Loki.TreeSharp.Action;
namespace Loki.Bot.Logic.Bots.ApiTest
{
/// <summary></summary>
public class InventoryStashBot
: IBot
{
/// <summary></summary>
private static readonly ILog Log = Logger.GetLoggerInstanceForType();
/// <summary>The main coroutine.</summary>
private Coroutine _coroutine;
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. </summary>
public void Dispose()
{
}
/// <summary>Whether or not this bot requires game input to happen. </summary>
public bool RequiresGameInput
{
get { return true; }
}
/// <summary> Gets the name of this bot. </summary>
public string Name
{
get { return "InventoryStashBot"; }
}
/// <summary> Gets the description of this bot. </summary>
public string Description
{
get { return "Coroutine testing code."; }
}
/// <summary> Gets the configuration window for this bot. </summary>
public Window ConfigWindow
{
get { return null; }
}
/// <summary> Gets the logic for this bot. </summary>
public Composite Logic { get; private set; }
/// <summary>Which items to pulse when this bot runs.</summary>
public PulseFlags PulseFlags
{
get { return PulseFlags.All; }
}
/// <summary> Starts this bot. Do any initialization here. </summary>
public void Start()
{
Logic = new Action(ret => RunStatus.Success);
_coroutine = new Coroutine(Main());
}
/// <summary> Stops this bot. Do any pre-dispose cleanup here. </summary>
public void Stop()
{
if (_coroutine != null)
{
_coroutine.Dispose();
_coroutine = null;
}
_needsStashContents = true;
}
/// <summary> Pulses the bot. Do any update logic here. </summary>
public void Pulse()
{
// Check to see if the coroutine is finished. If it is, stop the bot.
if (_coroutine.Status == CoroutineStatus.RanToCompletion || _coroutine.Status == CoroutineStatus.Faulted)
{
var msg = string.Format("The bot coroutine has finished {0}",
_coroutine.Status == CoroutineStatus.RanToCompletion ? "successfully." : "due to an error.");
Log.DebugFormat(msg);
BotMain.Stop(msg);
return;
}
// Otherwise, resume it.
if (_coroutine.Status == CoroutineStatus.Runnable)
{
object value;
while (_coroutine.Resume(out value) && value != LokiCoroutine.EndTick)
{
}
}
}
private bool _needsStashContents = true;
private IEnumerator Main()
{
while (true)
{
yield return LokiCoroutine.EndTick;
// Don't do anything if we are not in town.
if (!LokiPoe.ObjectManager.Me.IsInTown)
continue;
// If Stash is not open yet, go to it and open it.
if (!LokiPoe.Gui.IsStashWindowOpen)
{
Log.DebugFormat("[Main] The Stash window is not open. Now moving to Stash to open it.");
yield return Coroutines.OpenStashCoroutine();
var res = (bool)Coroutine.Current.LastResult;
if (!res)
{
Log.ErrorFormat("[Main] OpenStashCoroutine failed. Stopping the bot.");
BotMain.Stop("An unrecoverable error was encountered.");
break;
}
continue;
}
// If we haven't requested the stash contents, request them. If we don't actually need to, then the coroutine will finish
// quickly, as it doesn't have to request the contents again.
if (_needsStashContents)
{
Log.DebugFormat("[Main] We need to request the contents of Stash.");
yield return Coroutines.RequestStashContentsCoroutine();
var rsccerr = (Coroutines.RequestStashContentsCoroutineError)Coroutine.Current.LastResult;
if (rsccerr != Coroutines.RequestStashContentsCoroutineError.None)
{
Log.ErrorFormat("[Main] RequestStashContentsCoroutine returned {0}. Stopping the bot.", rsccerr);
BotMain.Stop("An unrecoverable error was encountered.");
break;
}
_needsStashContents = false;
}
// The stash tab system in PoE is made up of the actual stash tab containers, which has info such as the name,
// if it's premium, and stuff like that. Then, there's the actual item container tab that contains the item
// objects. That is why there are two sets of functions for working with stash tabs.
// This example shows how to write items to file as you encounter them.
using (
var fs = new FileStream(string.Format("skillgems_{0}.txt", Environment.TickCount), FileMode.Create,
FileAccess.Write))
{
using (TextWriter tw = new StreamWriter(fs))
{
foreach (var tab in LokiPoe.PlayerInventory.GetAllStashTabs())
{
foreach (var inventoryItem in tab.Items)
{
var item = inventoryItem.Item;
if (item.Rarity == Rarity.Gem)
{
tw.WriteLine("[Tab:{0}] [Col {3}, Row {4}] {1}{2}", tab.DisplayName, inventoryItem.FullName, item.Quality != 0 ? string.Format(" {0}%", item.Quality) : "", inventoryItem.Location.X, inventoryItem.Location.Y);
}
}
}
}
}
// This example shows how to accumulate totals for an item, and then write it out at the end.
using (
var fs = new FileStream(string.Format("currency_{0}.txt", Environment.TickCount), FileMode.Create,
FileAccess.Write))
{
using (TextWriter tw = new StreamWriter(fs))
{
var counts = new Dictionary<string, int>();
foreach (var tab in LokiPoe.PlayerInventory.GetAllStashTabs())
{
foreach (var inventoryItem in tab.Items)
{
var item = inventoryItem.Item;
if (item.Rarity == Rarity.Currency)
{
var name = inventoryItem.FullName;
if (!counts.ContainsKey(name))
{
counts.Add(name, 0);
}
// The item we get is actually the "stack" of currency. We have a wrapper to access that
// info through InventoryItem, as item represents one of those items, not the stack itself.
counts[name] += inventoryItem.Currency.StackCount;
}
}
}
foreach (var kvp in counts)
{
tw.WriteLine("{0} x {1}", kvp.Value, kvp.Key);
}
}
}
break;
}
// ReSharper disable once FunctionNeverReturns
}
}
}
You can modify the actual text output in the format you need. If anyone has any questions about this example or why a certain thing is done, feel free to ask. If you'd like an example of doing something different in this category, just shoot me a PM, and an example can be made (or put on the todo list, as not all the new code is done yet).
Updated for Beta #796+
Last edited: