public static MoveItemResult StashItemsToKeep(Game game, IExternalMessagingClient externalMessagingClient)
        {
            if (!HasAnyItemsToStash(game))
            {
                return(MoveItemResult.Succes);
            }

            var itemsToKeep = game.Inventory.Items.Where(i => i.IsIdentified && Pickit.Pickit.ShouldKeepItem(game, i) && Pickit.Pickit.CanTouchInventoryItem(game, i)).ToList();

            itemsToKeep.AddRange(game.Cube.Items.Where(i => i.IsIdentified && Pickit.Pickit.ShouldKeepItem(game, i)));
            var goldOnPerson = game.Me.Attributes.GetValueOrDefault(Attribute.GoldOnPerson, 0);

            foreach (var item in itemsToKeep)
            {
                Log.Information($"{game.Me.Name}: Want to keep {item.GetFullDescription()}");
                if (!(item.Name == ItemName.Ring && item.Quality == QualityType.Unique) && item.Classification != ClassificationType.Gem)
                {
                    externalMessagingClient.SendMessage($"{game.Me.Name}: Want to keep {item.GetFullDescription()}");
                }
            }

            return(StashItemsAndGold(game, itemsToKeep, goldOnPerson));
        }
예제 #2
0
        private async Task <MoveItemResult> MoveAllInventoryItemsToTradeScreenThatFit(Client client, Container muleInventory, List <Item> tradeableItems)
        {
            var temporaryInventory = new Inventory();

            foreach (var item in muleInventory.Items)
            {
                temporaryInventory.Add(item);
            }

            bool atLeastOneTraded = false;

            var tradeScreenClient = new Container(10, 4);

            foreach (var item in tradeableItems)
            {
                var space = tradeScreenClient.FindFreeSpace(item);
                if (space == null)
                {
                    continue;
                }

                var freeSpaceInventory = temporaryInventory.FindFreeSpace(item);
                if (freeSpaceInventory == null)
                {
                    if (atLeastOneTraded)
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }

                client.Game.RemoveItemFromContainer(item);

                bool resultToBuffer = GeneralHelpers.TryWithTimeout((retryCount) => client.Game.CursorItem?.Id == item.Id, TimeSpan.FromSeconds(5));
                if (!resultToBuffer)
                {
                    Log.Error($"Moving item {item.Id} - {item.Name} to buffer failed");
                    await _externalMessagingClient.SendMessage($"Moving item {item.Id} - {item.Name} to buffer failed");

                    return(MoveItemResult.Failed);
                }

                await Task.Delay(100);

                client.Game.InsertItemIntoContainer(item, space, ItemContainer.Trade);

                var moveResult = GeneralHelpers.TryWithTimeout(
                    (retryCount) => client.Game.CursorItem == null && client.Game.Items.FirstOrDefault(i => i.Id == item.Id)?.Container == ContainerType.ForTrade,
                    TimeSpan.FromSeconds(5));
                if (!moveResult)
                {
                    Log.Error($"Moving item {item.Id} - {item.Name} to trade failed");
                    await _externalMessagingClient.SendMessage($"Moving item {item.Id} - {item.Name} to trade failed ");

                    return(MoveItemResult.Failed);
                }

                await Task.Delay(100);

                var newItem = client.Game.Items.First(i => i.Id == item.Id);
                temporaryInventory.Block(freeSpaceInventory, newItem.Width, newItem.Height);
                tradeScreenClient.Add(newItem);
                atLeastOneTraded = true;
            }

            return(atLeastOneTraded ? MoveItemResult.Succes : MoveItemResult.NoSpace);
        }
        protected async Task CreateGameLoop(Client client)
        {
            _accountCharacter.Validate();
            try
            {
                if (!RealmConnectHelpers.ConnectToRealm(client, _config, _accountCharacter))
                {
                    throw new Exception("Could not connect to realm");
                }

                int totalCount           = 0;
                int gameCount            = 0;
                int successiveFailures   = 0;
                int gameDescriptionIndex = 0;
                while (true)
                {
                    if (successiveFailures > 0 && successiveFailures % 10 == 0)
                    {
                        gameDescriptionIndex++;
                        if (gameDescriptionIndex == _config.GameDescriptions?.Count)
                        {
                            gameDescriptionIndex = 0;
                        }
                        var reconnectMessage = $"Many successive failures, swithing GS to {_config.GameDescriptions?.ElementAtOrDefault(gameDescriptionIndex)}";
                        Log.Warning(reconnectMessage);
                        bool reconnectResult = await RealmConnectHelpers.ConnectToRealmWithRetry(client, _config, _accountCharacter, 10);

                        if (!reconnectResult)
                        {
                            await _externalMessagingClient.SendMessage($"Reconnect tries of 10 reached, restarting bot");

                            return;
                        }
                    }

                    if (gameCount >= 100)
                    {
                        gameCount = 1;
                    }

                    if (NeedsMule)
                    {
                        await _externalMessagingClient.SendMessage($"{client.LoggedInUserName()}: needs mule, starting mule");

                        if (await _muleService.MuleItemsForClient(client))
                        {
                            NeedsMule = false;
                            await _externalMessagingClient.SendMessage($"{client.LoggedInUserName()}: finished mule");
                        }
                        else
                        {
                            await Task.Delay(Math.Pow(successiveFailures, 1.3) *TimeSpan.FromSeconds(5));

                            await _externalMessagingClient.SendMessage($"{client.LoggedInUserName()}: failed to mule all items, trying again");

                            if (!await RealmConnectHelpers.ConnectToRealmWithRetry(client, _config, _accountCharacter, 10))
                            {
                                throw new Exception("Could not connect to realm");
                            }
                            successiveFailures++;
                            continue;
                        }
                    }

                    try
                    {
                        gameCount++;
                        totalCount++;
                        if (client.CreateGame(_config.Difficulty, $"{_config.GameNamePrefix}{gameCount}", _config.GamePassword, _config.GameDescriptions?.ElementAtOrDefault(gameDescriptionIndex)))
                        {
                            if (!await RunSingleGame(client))
                            {
                                successiveFailures += 1;
                            }
                            else
                            {
                                successiveFailures = 0;
                            }
                        }
                        else
                        {
                            successiveFailures += 1;
                            await Task.Delay(Math.Pow(successiveFailures, 1.3) *TimeSpan.FromSeconds(5));
                        }

                        if (client.Game.IsInGame())
                        {
                            client.Game.LeaveGame();
                            await Task.Delay(TimeSpan.FromSeconds(3));
                        }

                        if (!client.RejoinMCP())
                        {
                            var reconnectMessage = $"Reconnecting to MCP failed, reconnecting to realm instead";
                            Log.Warning(reconnectMessage);
                            if (!await RealmConnectHelpers.ConnectToRealmWithRetry(client, _config, _accountCharacter, 10))
                            {
                                throw new Exception("Could not connect to realm");
                            }
                        }
                    }
                    catch (HttpRequestException)
                    {
                        await _externalMessagingClient.SendMessage($"{client.LoggedInUserName() } Received http exception, map server is probably down, restarting bot");

                        return;
                    }
                    catch (Exception e)
                    {
                        gameDescriptionIndex++;
                        if (gameDescriptionIndex == _config.GameDescriptions?.Count)
                        {
                            gameDescriptionIndex = 0;
                        }

                        successiveFailures += 1;
                        Log.Warning($"Disconnecting client due to exception {e}, reconnecting to realm, game description is now: {_config.GameDescriptions?.ElementAtOrDefault(gameDescriptionIndex)}");
                        bool reconnectResult = await RealmConnectHelpers.ConnectToRealmWithRetry(client, _config, _accountCharacter, 10);

                        if (!reconnectResult)
                        {
                            await _externalMessagingClient.SendMessage($"Reconnect tries of 10 reached, restarting bot");

                            return;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e, $"Unhandled Exception: {e}");
                await _externalMessagingClient.SendMessage($"bot crashed with exception: {e}");

                throw e;
            }
            finally
            {
                if (client.Game.IsInGame())
                {
                    client.Game.LeaveGame();
                }

                client.Disconnect();
            }
        }