public async Task <bool> TakeTownPortalToArea(Client client, Player player, Area area)
        {
            var portal = client.Game.GetEntityByCode(EntityCode.TownPortal).FirstOrDefault(t => t.TownPortalArea == area && t.TownPortalOwnerId == player.Id);

            if (portal == null)
            {
                return(false);
            }

            var movementMode = GetMovementMode(client.Game);
            var pathToPortal = await _pathingService.GetPathToLocation(client.Game, portal.Location, movementMode);

            if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToPortal, movementMode))
            {
                Log.Information($"Moving to {portal.Location} failed");
                return(false);
            }

            if (!await GeneralHelpers.TryWithTimeout(async(retryCount) =>
            {
                if (retryCount > 0 && retryCount % 5 == 0)
                {
                    client.Game.RequestUpdate(client.Game.Me.Id);
                }

                client.Game.InteractWithEntity(portal);
                return(await GeneralHelpers.TryWithTimeout(async(retryCount) =>
                {
                    await Task.Delay(50);
                    return client.Game.Area == area;
                }, TimeSpan.FromSeconds(0.5)));
            }, TimeSpan.FromSeconds(10)))
            {
                return(false);
            }

            if (!await GeneralHelpers.TryWithTimeout(async(retryCount) =>
            {
                if (retryCount > 0 && retryCount % 5 == 0)
                {
                    client.Game.RequestUpdate(client.Game.Me.Id);
                }

                await Task.Delay(100);

                return(await _pathingService.IsNavigatablePointInArea(client.Game.MapId, Difficulty.Normal, area, client.Game.Me.Location));
            }, TimeSpan.FromSeconds(10)))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        public static async Task <bool> PickupCorpseIfExists(Client client, IPathingService pathingService)
        {
            var corpseId = client.Game.Me.CorpseId;

            if (corpseId != null)
            {
                var pickupSucceeded = false;
                var corpse          = client.Game.Players.FirstOrDefault(p => p.Id == corpseId);
                Log.Information($"Found corpse {corpse.Id} for {client.LoggedInUserName()}, trying to pickup");
                pickupSucceeded = await GeneralHelpers.TryWithTimeout(async (retryCount) =>
                {
                    if (client.Game.Me.Location.Distance(corpse.Location) > 5)
                    {
                        Log.Information($"Getting walking path from {client.Game.Me.Location} to {corpse.Location} with distance {client.Game.Me.Location.Distance(corpse.Location)}");
                        var walkingPath = await pathingService.GetPathToLocation(client.Game, corpse.Location, MovementMode.Walking);
                        await MovementHelpers.TakePathOfLocations(client.Game, walkingPath, MovementMode.Walking);
                        return(false);
                    }

                    return(client.Game.PickupBody(corpse));
                }, TimeSpan.FromSeconds(5));

                var message = pickupSucceeded ? "succeeded" : "failed";
                Log.Information($"Pickup of corpse {message}");
                return(pickupSucceeded);
            }

            return(true);
        }
Ejemplo n.º 3
0
        private async Task <bool> PickupNearbyItems(Game game, double distance)
        {
            var pickupItems = game.Items.Where(i =>
            {
                return(i.Ground && game.Me.Location.Distance(i.Location) < distance && Pickit.Pickit.ShouldPickupItem(game, i));
            }).OrderBy(n => game.Me.Location.Distance(n.Location));

            foreach (var item in pickupItems)
            {
                if (!game.IsInGame())
                {
                    return(false);
                }

                InventoryHelpers.MoveInventoryItemsToCube(game);
                if (game.Inventory.FindFreeSpace(item) == null)
                {
                    continue;
                }

                await GeneralHelpers.TryWithTimeout(async (retryCount) =>
                {
                    if (game.Me.Location.Distance(item.Location) >= 5)
                    {
                        var pathNearest = await _pathingService.GetPathToLocation(game.MapId, Difficulty.Normal, Area.Travincal, game.Me.Location, item.Location, MovementMode.Walking);
                        await MovementHelpers.TakePathOfLocations(game, pathNearest, MovementMode.Walking);
                        return(false);
                    }

                    return(true);
                }, TimeSpan.FromSeconds(3));

                if (game.Me.Location.Distance(item.Location) < 5)
                {
                    game.PickupItem(item);
                }
            }

            InventoryHelpers.MoveInventoryItemsToCube(game);
            return(true);
        }
Ejemplo n.º 4
0
        public async Task GameLoop(List <Tuple <AccountCharacter, Client> > clients, int gameCount)
        {
            var leadClient = clients.Single(c => GetIsLeadClient(c));
            var csManager  = new CSManager(new List <Client> {
                leadClient.Item2
            });
            uint currentTeleportId    = 0;
            var  nextGameCancellation = new CancellationTokenSource();
            var  gameTasks            = clients.Select(async(c, i) =>
            {
                bool isLeadClient = leadClient == c;
                if (!isLeadClient)
                {
                    await Task.Delay(TimeSpan.FromSeconds(2 * i));
                    if (!await RealmConnectHelpers.JoinGameWithRetry(gameCount, c.Item2, _config, c.Item1))
                    {
                        return(false);
                    }
                }

                Log.Information("In game");
                var client = c.Item2;
                client.Game.RequestUpdate(client.Game.Me.Id);
                if (!GeneralHelpers.TryWithTimeout(
                        (_) => client.Game.Me.Location.X != 0 && client.Game.Me.Location.Y != 0,
                        TimeSpan.FromSeconds(10)))
                {
                    return(false);
                }

                var townManagementOptions = new TownManagementOptions()
                {
                    Act = Act.Act4
                };

                if (!await _townManagementService.PerformTownTasks(c.Item2, townManagementOptions))
                {
                    return(false);
                }

                Func <uint> getTeleportId = () => currentTeleportId;

                if (c.Item1.Character.Equals(_csconfig.TeleportCharacterName, StringComparison.CurrentCultureIgnoreCase))
                {
                    var result = await TaxiCs(c.Item2, csManager, t => currentTeleportId = t);
                    nextGameCancellation.Cancel();
                    return(result);
                }
                else
                {
                    var movementMode     = client.Game.Me.HasSkill(Skill.Teleport) ? MovementMode.Teleport : MovementMode.Walking;
                    var pathToTpLocation = await _pathingService.GetPathToLocation(client.Game, new Point(5042, 5036), movementMode);
                    if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToTpLocation, movementMode))
                    {
                        Log.Warning($"Client {client.Game.Me.Name} {movementMode} to portal area failed at {client.Game.Me.Location}");
                        return(false);
                    }

                    await BaseCsBot(csManager, getTeleportId, nextGameCancellation, client, GetKillActionForClass(client));
                }

                return(true);
            }
                                                       ).ToList();
            var firstCompletedResult = await Task.WhenAny(gameTasks);

            if (!await firstCompletedResult)
            {
                Log.Warning($"One or more characters failed there town task");
                nextGameCancellation.Cancel();
                await Task.WhenAll(gameTasks);

                return;
            }

            var townResults = await Task.WhenAll(gameTasks);

            if (townResults.Any(r => !r))
            {
                Log.Warning($"One or more characters failed there town task");
                nextGameCancellation.Cancel();
                return;
            }
        }
Ejemplo n.º 5
0
 public static async Task <List <Point> > GetPathToLocation(this IPathingService pathingService, Game game, Point toLocation, MovementMode movementMode)
 {
     return(await pathingService.GetPathToLocation(game.MapId, Difficulty.Normal, game.Area, game.Me.Location, toLocation, movementMode));
 }
Ejemplo n.º 6
0
        protected override async Task <bool> RunSingleGame(Client client)
        {
            Log.Information("In game");
            client.Game.RequestUpdate(client.Game.Me.Id);
            if (!GeneralHelpers.TryWithTimeout(
                    (_) => client.Game.Me.Location.X != 0 && client.Game.Me.Location.Y != 0,
                    TimeSpan.FromSeconds(10)))
            {
                return(false);
            }

            if (client.Game.Me.Class != CharacterClass.Sorceress)
            {
                throw new NotSupportedException("Only sorceress is supported on Mephisto");
            }

            /*
             * while (client.Game.Players.Count < 2)
             * {
             *  Thread.Sleep(TimeSpan.FromMilliseconds(100));
             * }
             */

            var townManagementOptions = new TownManagementOptions()
            {
                Act = Act.Act3
            };

            await _townManagementService.PerformTownTasks(client, townManagementOptions);

            NeedsMule = client.Game.Inventory.Items.Any(i => i.IsIdentified && Pickit.Pickit.ShouldKeepItem(client.Game, i) && Pickit.Pickit.CanTouchInventoryItem(client.Game, i)) ||
                        client.Game.Cube.Items.Any(i => i.IsIdentified && Pickit.Pickit.ShouldKeepItem(client.Game, i));
            if (NeedsMule)
            {
                return(true);
            }

            Log.Information("Taking DuranceOfHateLevel2 Waypoint");
            if (!await _townManagementService.TakeWaypoint(client, Waypoint.DuranceOfHateLevel2))
            {
                Log.Information("Taking DuranceOfHateLevel2 waypoint failed");
                return(false);
            }

            var path2 = await _pathingService.GetPathFromWaypointToArea(client.Game.MapId, Difficulty.Normal, Area.DuranceOfHateLevel2, Waypoint.DuranceOfHateLevel2, Area.DuranceOfHateLevel3, MovementMode.Teleport);

            if (!await MovementHelpers.TakePathOfLocations(client.Game, path2, MovementMode.Teleport))
            {
                Log.Warning($"Teleporting to DuranceOfHateLevel3 warp failed at location {client.Game.Me.Location}");
                return(false);
            }

            var warp = client.Game.GetNearestWarp();

            if (warp == null || warp.Location.Distance(client.Game.Me.Location) > 20)
            {
                Log.Warning($"Warp not close enough at location {warp?.Location} while at location {client.Game.Me.Location}");
                return(false);
            }

            Log.Information($"Taking warp to Durance 3");
            if (!GeneralHelpers.TryWithTimeout((_) => client.Game.TakeWarp(warp) && client.Game.Area == Area.DuranceOfHateLevel3,
                                               TimeSpan.FromSeconds(2)))
            {
                Log.Warning($"Taking warp failed at location {client.Game.Me.Location} to warp at location {warp.Location}");
                return(false);
            }

            if (!await GeneralHelpers.TryWithTimeout(async(retryCount) =>
            {
                client.Game.RequestUpdate(client.Game.Me.Id);
                var isValidPoint = await _pathingService.IsNavigatablePointInArea(client.Game.MapId, Difficulty.Normal, Area.DuranceOfHateLevel3, client.Game.Me.Location);
                return(isValidPoint);
            }, TimeSpan.FromSeconds(3.5)))
            {
                Log.Error("Checking whether moved to area failed");
                return(false);
            }

            Log.Information($"Teleporting to Mephisto");
            var path3 = await _pathingService.GetPathToLocation(client.Game, new Point(17566, 8070), MovementMode.Teleport);

            if (!await MovementHelpers.TakePathOfLocations(client.Game, path3, MovementMode.Teleport))
            {
                Log.Warning($"Teleporting to Mephisto failed at location {client.Game.Me.Location}");
                return(false);
            }

            if (!GeneralHelpers.TryWithTimeout((_) => client.Game.GetNPCsByCode(NPCCode.Mephisto).Count > 0, TimeSpan.FromSeconds(2)))
            {
                Log.Warning($"Finding Mephisto failed while at location {client.Game.Me.Location}");
                return(false);
            }

            var mephisto = client.Game.GetNPCsByCode(NPCCode.Mephisto).Single();

            Log.Information($"Killing Mephisto");
            if (!GeneralHelpers.TryWithTimeout((retryCount) =>
            {
                if (!client.Game.IsInGame())
                {
                    return(true);
                }

                if (mephisto.Location.Distance(client.Game.Me.Location) < 30)
                {
                    client.Game.RepeatRightHandSkillOnLocation(Skill.StaticField, client.Game.Me.Location);
                }

                Thread.Sleep(200);
                if (retryCount % 5 == 0)
                {
                    client.Game.UseRightHandSkillOnEntity(Skill.FrozenOrb, mephisto);
                }

                return(mephisto.LifePercentage < 30);
            },
                                               TimeSpan.FromSeconds(30)))
            {
                Log.Warning($"Killing Mephisto failed at location {client.Game.Me.Location}");
                return(false);
            }

            if (!GeneralHelpers.TryWithTimeout((_) =>
            {
                client.Game.UseRightHandSkillOnEntity(Skill.FrozenOrb, mephisto);

                if (!client.Game.IsInGame())
                {
                    return(true);
                }

                return(GeneralHelpers.TryWithTimeout((_) => mephisto.State == EntityState.Dead,
                                                     TimeSpan.FromSeconds(0.7)));
            }, TimeSpan.FromSeconds(30)))
            {
                Log.Warning($"Killing Mephisto failed at location {client.Game.Me.Location}");
                return(false);
            }

            if (!PickupNearbyItems(client))
            {
                Log.Warning($"Failed to pickup items at location {client.Game.Me.Location}");
                return(false);
            }

            return(true);
        }