What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

[How it Works] Injection And You

Okay and how has it changed. Dont need big explanation. Just a simple with the new MOP Api you should use X ;)
This is the new method: <code><code>using (StyxWoW.Memory.AcquireFrame()) { ... } </code></code>
 
I'm learning c++ :( although similar the slight differences to C do my head in!!!!
 
Hi,

i want to write a loop with up to 100k lua requests. My loop is inside the StyxWoW.Memory.AcquireFrame block. But while debugging i noticed that he does not force to execute the code within one frame. He enters the loop and starts to execute the loop. Only after the loop reaches 5k-50k he force wow to execute the rest in one frame.

is this a result of:
Yes, we have some failsafe code to ensure you can't lock the game too long.

?
 
Hi,

i want to write a loop with up to 100k lua requests. My loop is inside the StyxWoW.Memory.AcquireFrame block. But while debugging i noticed that he does not force to execute the code within one frame. He enters the loop and starts to execute the loop. Only after the loop reaches 5k-50k he force wow to execute the rest in one frame.

is this a result of:


?

No, HB will only exit the frame lock if you have not issued a new injection for 1 second. The frame lock is also not reentered on next injections in the same frame lock:
Code:
using (StyxWoW.Memory.AcquireFrame(true))
{
  Lua.DoString("print('hello')"); // Runs in 1 frame
  Lua.DoString("print('hello')"); // Runs in the same frame as previous

  Thread.Sleep(1500);
  Lua.DoString("print('hello')"); // Runs in a different frame
  Lua.DoString("print('hello')"); // Runs in another different frame
}

If you replaced Thread.Sleep(1500) with
Code:
for (int i = 0; i < 3; i++)
{
  Thread.Sleep(500);
  Lua.DoString("print('hello')");
}

Then the frame lock is not exited, so all of the injections run in the same frame.

Please note that this is an implementation detail which may change.
 
Hi MaiN,

my plugin does exactly the different.

PHP:
using (StyxWoW.Memory.AcquireFrame(true))
{
    Logging.Write("entered .AcquireFrame()");
    string lua;
    string answer;
    for (uint i = 1; i <= m; i++)
    {
        if((i % 1000) == 0)Logging.Write("still looping... current task index: " + i);
        lua = string.Format(LuaFormatGetAuctionItemInfo, "list", i);
        answer = Lua.GetReturnVal<string>(lua, 0);
        if(answer != "false")
        {
            ahqueryList.Add(new grandmasAuctionItemInfo(answer));
        } 
    }  
}

The "m" value is usually between 70k and 100k. HB still enters my loop but does not execute it in one frame. He needs a lot of time to loop but after a while (usually 1-3 minutes, between 5k-50k loops) he execute the rest of my loop in one frame in just a few seconds.
 
Last edited:
According to what I understood from the conversation, using the framelock would be the safe way to execute multiple LUA asap is that right?

PHP:
using (StyxWoW.Memory.AcquireFrame())
{
    int total = BuyItemCount < item.Quantity ? 1 : BuyItemCount % item.Quantity == 0 ? BuyItemCount / item.Quantity : (int)Math.Round((decimal)(BuyItemCount / item.Quantity));
    for (int i = total; i > 0; i--)
    {
        Lua.DoString(string.Format("RunMacroText(\"/script BuyMerchantItem({0},{1})\")", item.Index, item.Quantity), 0);
    }
}

If that is right, what would be the correct way to run the above? I mean its interacting with a in game merchant window to buy items and I would think that the above way would simple smash the game with consecutive buy requests without respecting the game limits is that right?

Given that I could simple run that without the frame lock and the API would take care of handling it by it self applying the locks where needed? Or do I still need to lock myself and base the amount of buy on frames available + interval between running it etc?

Keep in mind this NPC does not sell the total amount in 1 command you need to keep interacting.

So perhaps:


PHP:
using (StyxWoW.Memory.AcquireFrame())
{
    int total = BuyItemCount < item.Quantity ? 1 : BuyItemCount % item.Quantity == 0 ? BuyItemCount / item.Quantity : (int)Math.Round((decimal)(BuyItemCount / item.Quantity));
    for (int i = total; i > 0; i--)
    {
        Lua.DoString(string.Format("RunMacroText(\"/script BuyMerchantItem({0},{1})\")", item.Index, item.Quantity), 0);
        Thread.Sleep(1000);
    }
}
 
Last edited:
According to what I understood from the conversation, using the framelock would be the safe way to execute multiple LUA asap is that right?

PHP:
using (StyxWoW.Memory.AcquireFrame())
{
    int total = BuyItemCount < item.Quantity ? 1 : BuyItemCount % item.Quantity == 0 ? BuyItemCount / item.Quantity : (int)Math.Round((decimal)(BuyItemCount / item.Quantity));
    for (int i = total; i > 0; i--)
    {
        Lua.DoString(string.Format("RunMacroText(\"/script BuyMerchantItem({0},{1})\")", item.Index, item.Quantity), 0);
    }
}

If that is right, what would be the correct way to run the above? I mean its interacting with a in game merchant window to buy items and I would think that the above way would simple smash the game with consecutive buy requests without respecting the game limits is that right?

Given that I could simple run that without the frame lock and the API would take care of handling it by it self applying the locks where needed? Or do I still need to lock myself and base the amount of buy on frames available + interval between running it etc?

Keep in mind this NPC does not sell the total amount in 1 command you need to keep interacting.

So perhaps:


PHP:
using (StyxWoW.Memory.AcquireFrame())
{
    int total = BuyItemCount < item.Quantity ? 1 : BuyItemCount % item.Quantity == 0 ? BuyItemCount / item.Quantity : (int)Math.Round((decimal)(BuyItemCount / item.Quantity));
    for (int i = total; i > 0; i--)
    {
        Lua.DoString(string.Format("RunMacroText(\"/script BuyMerchantItem({0},{1})\")", item.Index, item.Quantity), 0);
        Thread.Sleep(1000);
    }
}

Thread.Sleep should never be used. The correct way to do it is to run a coroutine with human-like delays between each buy request. Using Coroutine.Wait you can also sanity check that your buy requests are going through (for example by checking that you lose gold or that an item appears in the inventory).
 
Thread.Sleep should never be used. The correct way to do it is to run a coroutine with human-like delays between each buy request. Using Coroutine.Wait you can also sanity check that your buy requests are going through (for example by checking that you lose gold or that an item appears in the inventory).

I see, but on the first example there is no thread.sleep, in that scenario would you very likely hammer the merchant trying to instantly buy all the items or does HB handle that by itself respecting how it will interact or something?

Either way that specific case I have it would regardless need more than 1 frame to run right? As in every NPC interacting would be a new frame, would the AcquireFrame accommodate that itself or should I just rearrange the code to use the Coroutine.Wait without acquiring the frame?

And again for further reference with Coroutine.Wait it would look like this?:

PHP:
using (StyxWoW.Memory.AcquireFrame())
{
    int total = BuyItemCount < item.Quantity ? 1 : BuyItemCount % item.Quantity == 0 ? BuyItemCount / item.Quantity : (int)Math.Round((decimal)(BuyItemCount / item.Quantity));
    for (int i = total; i > 0; i--)
    {
        await Coroutine.Wait(1000, () => LuaDoStringBoolean(item.Index, item.Quantity));
    }
}

Because Lua.DoString does not return a bool so we use some other option to return true or false?
PHP:
bool LuaDoStringBoolean(int index, int quantity)
{
    Lua.DoString(string.Format("RunMacroText(\"/script BuyMerchantItem({0},{1})\")", index, quantity), 0);
    // see if our currency or gold or whatever change and return true or false based on that.
}
 
Last edited:
I see, but on the first example there is no thread.sleep, in that scenario would you very likely hammer the merchant trying to instantly buy all the items or does HB handle that by itself respecting how it will interact or something?

Either way that specific case I have it would regardless need more than 1 frame to run right? As in every NPC interacting would be a new frame, would the AcquireFrame accommodate that itself or should I just rearrange the code to use the Coroutine.Wait without acquiring the frame?

And again for further reference with Coroutine.Wait it would look like this?:

PHP:
using (StyxWoW.Memory.AcquireFrame())
{
    int total = BuyItemCount < item.Quantity ? 1 : BuyItemCount % item.Quantity == 0 ? BuyItemCount / item.Quantity : (int)Math.Round((decimal)(BuyItemCount / item.Quantity));
    for (int i = total; i > 0; i--)
    {
        await Coroutine.Wait(1000, () => LuaDoStringBoolean(item.Index, item.Quantity));
    }
}

Because Lua.DoString does not return a bool so we make our own fake escape goat?
PHP:
bool LuaDoStringBoolean(int index, int quantity)
{
    Lua.DoString(string.Format("RunMacroText(\"/script BuyMerchantItem({0},{1})\")", index, quantity), 0);
    return true;
}

You do not need to acquire a frame by yourself. HB already runs in a frame lock by default, and the option not to run in a frame lock will be removed soon.
Your usage of Coroutine.Wait is incorrect - it waits until the condition becomes true, which it does instantly for your condition. The correct way would be (in some form of pseudocode):

Code:
Lua.DoString("buy merchant item code");
// Store count of items in bags here, or amount of gold, something else
if (!await Coroutine.Wait(3000, () => Check that determines if we lost gold or if an item appeared in our bags))
{
  // Something went wrong since we did not lose gold or have an item appear in our bags.
  // Handle this, for example by logging something to the user
  break;
}

// Gold disappeared/item appeared in our bags
// Simulate that we are human..
await CommonCoroutines.SleepForRandomUiInteractionTime();
// Buy next item after this
 
You do not need to acquire a frame by yourself. HB already runs in a frame lock by default, and the option not to run in a frame lock will be removed soon.
That's nice to know, less complication to use the API. So what would we do when we want to compute something with a single frame, will there be an alternative way or it will evaluate and see what should or could run within a frame and do it by it self?

Code:
Lua.DoString("buy merchant item code");
// Store count of items in bags here, or amount of gold, something else
if (!await Coroutine.Wait(3000, () => Check that determines if we lost gold or if an item appeared in our bags))
{
  // Something went wrong since we did not lose gold or have an item appear in our bags.
  // Handle this, for example by logging something to the user
  break;
}

// Gold disappeared/item appeared in our bags
// Simulate that we are human..
await CommonCoroutines.SleepForRandomUiInteractionTime();
// Buy next item after this

Thanks a lot for the insight, nice to know we have other sort of built-in sleep's for specific things like frame, item usage, etc.
 
Back
Top