Как я могу заставить бота ждать определенного события и одновременно продолжать опрашивать события?

Я использую приложение SteamBot.

У меня есть команда, которая должна действовать, когда происходит определенное событие. В этом конкретном случае я, как администратор, даю команду, а бот ждет торгового запроса, а затем продолжает свою логику. Чего я не могу понять, так это того, как заставить его ждать, пока не появится торговый запрос, а затем продолжить.

Предположим, что я ввел команду и теперь нахожусь в функции, которая обрабатывает поведение этой команды. Это очень простой пример того, что я пытаюсь сделать.

private void giveItemsToUser()
{
    Bot.GetInventory();

    // Wait here

    var items = Trade.CurrentSchema.GetItemsByCraftingMaterial('hat');
    foreach (var item in items)
    {
        added += Trade.AddAllItemsByDefindex(item.Defindex, amount);
    }

    Trade.SetReady(true);
    Trade.AcceptTrade();
}

В разделе // Wait here я хочу, чтобы бот останавливался до тех пор, пока не начнется торговля. Затем, как только он начался, он может продолжить и добавить элементы, как ожидалось.

Я попытался добавить переменную inTrade (инициализированную в false), для которой установлено значение true в функции OnTradeInit, и перевести бота в спящий режим, пока это не станет правдой.

while (!inTrade)
{
    Console.WriteLine("Not in trade. Sleeping for 10 seconds.");
    Thread.Sleep(10000);
}

Это, однако, блокирует основную нить и затягивает ее в тугую петлю. Когда он просыпается, он сразу же проверяет, равна ли переменная true, и, если нет, снова переводит его в спящий режим. У функции HandleSteamMessage в Bot.cs нет времени что-либо обрабатывать, даже если бот получил событие во время сна.

Я пытался использовать EventWaitHandle, но он никогда не срабатывает.

EventWaitHandle waitForInTrade = new EventWaitHandle(false, EventResetMode.AutoReset, "OnTradeRequest");
waitForInTrade.WaitOne(30000);
Console.WriteLine("In trade? " + inTrade.ToString());  

Это приостанавливает основной поток на 30 секунд (из-за тайм-аута, переданного в WaitOne), а затем продолжает, как и ожидалось. Однако inTrade по-прежнему ложно, даже если был получен торговый запрос. Так как я не торгую в этот момент, и последующий код будет недействительным.

Итак, каков правильный способ справиться с этим типом взаимодействия?

Я также опубликовал это в субреддите /r/steambot. Я надеюсь, что это не проблема, тем более, что в некоторых комментариях на Github упоминается публикация здесь для лучшей помощи.


person SteambotNewbie    schedule 16.01.2014    source источник
comment
Боковое примечание: по соглашению в C# все методы начинаются с заглавной буквы. Если вы начнете со строчных букв, ваш код будет выглядеть крайне любительским.   -  person BlueRaja - Danny Pflughoeft    schedule 17.01.2014


Ответы (1)


Ваш подход в корне неверен. Steambot основан на событиях, поэтому ваша логика должна основываться на реагировании на события в обработчиках событий, а не на ожидании возникновения событий.

Другими словами, когда администратор выдает команду Give Items, вы не можете просто вызвать метод GiveItemsToUser(). Вместо этого вам понадобится что-то вроде QueueItemsToBeGivenToUser(), которое создает список элементов для передачи пользователю и сохраняет его в приватной переменной. Затем, когда вызывается OnTradeInit(), вы можете проверить, есть ли у этого пользователя какие-либо предметы в очереди, и, если они есть, добавить эти предметы в сделку.

person BlueRaja - Danny Pflughoeft    schedule 16.01.2014