Ejemplo n.º 1
0
        public async Task Run(GameContext context, BaseWorkerWindow vm, Action <string> statusUpdater, CancellationToken cancellationToken)
        {
            await Task.CompletedTask;
            var wall = new WallBattle(context);

            if (!wall.IsScreenActive())
            {
                throw new InvalidOperationException("You're not in the wall combat");
            }
            var lastOneMirror = DateTime.UtcNow;
            var strange       = 0;

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();
                statusUpdater("Waiting for heroes to die...");
                await wall.Deactivation(cancellationToken);

                cancellationToken.ThrowIfCancellationRequested();
                if (!wall.IsFailureDialogActive())
                {
                    if (strange++ > 50)
                    {
                        throw new Exception("Desynchronized from battle");
                    }
                    continue;
                }

                strange = 0;
                if ((DateTime.UtcNow - lastOneMirror).TotalMinutes > ResetInterval)
                {
                    statusUpdater("Respawning...");
                    lastOneMirror = DateTime.UtcNow;
                    await wall.PressUse1Mirror(cancellationToken);
                }
                else
                {
                    statusUpdater("Respawning...");
                    await wall.PressUse2Mirrors(cancellationToken);
                }

                context.MoveCursor(10, 10);
            }
        }
Ejemplo n.º 2
0
        public async Task Run(GameContext context, BaseWorkerWindow vm, Action <string> statusUpdater, CancellationToken cancellationToken)
        {
            await Task.CompletedTask;
            var maps    = new TreasureMaps(context);
            var rewards = new RewardsDialog(context);

            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();
                if (!maps.IsScreenActive())
                {
                    throw new InvalidOperationException("You're not at the treasure maps screen");
                }
                statusUpdater("Looting...");
                await maps.PressLootButton(cancellationToken);

                cancellationToken.ThrowIfCancellationRequested();
                statusUpdater("Getting rewards...");
                await rewards.Activation(cancellationToken);

                await rewards.PressOkButton(cancellationToken);
            }
        }
Ejemplo n.º 3
0
        public async Task Run(GameContext context, BaseWorkerWindow vm, Action <string> statusUpdater, CancellationToken cancellationToken)
        {
            using (NDC.Push("Arena Worker")) {
                await Task.CompletedTask;
                var      lobby           = new ArenaLobby(context);
                var      matcher         = new ArenaMatcher(context);
                var      prepareBattle   = new PrepareBattle(context);
                var      lastScore       = 0L;
                var      lastCombatScore = 0L;
                Opponent lastOpponent    = null;
                var      combatResults   = new List <CombatLogItem>();
                var      strategies      = new List <IArenaStrategy>();
                if (!string.IsNullOrEmpty(WorstEnemy))
                {
                    strategies.Add(new WorstEnemyArenaStrategy(WorstEnemy, WorstEnemyOnly, WorstEnemyMaxDist));
                }
                if (UseHistory)
                {
                    strategies.Add(new HistoryArenaStrategy());
                }
                if (UseScore)
                {
                    strategies.Add(new PowerArenaStrategy());
                    strategies.Add(new ScoreFallbackArenaStrategy());
                }

                if (strategies.Any())
                {
                    strategies.Add(new PowerArenaStrategy());
                }
                var clog = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "logs", "combat.jlog");
                if (!Directory.Exists(Path.GetDirectoryName(clog)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(clog));
                }
                if (File.Exists(clog))
                {
                    try {
                        combatResults.AddRange(JsonConvert.DeserializeObject <CombatLogItem[]>(File.ReadAllText(clog)));
                    } catch {
                    }
                }

                Logger.Info("Created screens, entering main loop.");
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (!lobby.IsScreenActive())
                    {
                        Logger.Fatal("Lobby screen not detected! Bailing out.");
                        throw new InvalidOperationException("Not on the arena lobby screen");
                    }

                    if (lobby.CurrentScore > MaxScore)
                    {
                        Logger.InfoFormat("Score limit reached (current {0} > max {1}). Bailing out.", lobby.CurrentScore, MaxScore);
                        return;
                    }

                    lastCombatScore = lobby.CurrentScore - lastScore;
                    if (lastScore != 0 && lobby.CurrentScore != 0 && lastOpponent != null)
                    {
                        combatResults.Add(
                            new CombatLogItem {
                            Date        = DateTime.UtcNow,
                            Name        = lastOpponent.Name,
                            Power       = lastOpponent.Power,
                            ScoreChange = lastCombatScore
                        }
                            );
                        File.WriteAllText(clog, JsonConvert.SerializeObject(combatResults, Formatting.Indented));
                    }

                    var combatLookup = combatResults.ToLookup(x => x.Name);

                    lastScore = lobby.CurrentScore;
                    cancellationToken.ThrowIfCancellationRequested();
                    Logger.Info("Switching to matcher screen.");
                    while (true)
                    {
                        do
                        {
                            await lobby.PressBattleButton(cancellationToken);
                        } while (lobby.IsScreenActive());

                        var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
                        try {
                            await matcher.Activation(CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken).Token);

                            break;
                        } catch (TaskCanceledException) {
                            if (lobby.IsScreenActive())
                            {
                                continue;
                            }
                            throw;
                        }
                    }

                    if (matcher.TicketsLeft == 0)
                    {
                        await Task.Delay(500, cancellationToken);

                        Logger.Info("Recapture matcher screen due to possible erratic tickets reading.");
                        matcher.IsScreenActive();
                    }

                    if (matcher.TicketsLeft <= MinTickets)
                    {
                        Logger.InfoFormat("Tickets limit reached (current {0} < min {1}). Bailing out.", matcher.TicketsLeft, MinTickets);
                        return;
                    }

                    Logger.Info("Enabling fast battle.");

                    statusUpdater($"My power {matcher.MyPower.Pretty()}, score {lobby.CurrentScore}. {matcher.TicketsLeft} tickets left.");
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        Logger.InfoFormat("Matcher screen found opponents {0}; {1}; {2}.", matcher.Opponents[0], matcher.Opponents[1], matcher.Opponents[2]);

                        var opponentsWithHistory = matcher.Opponents.Select(
                            x => {
                            var logs = combatLookup[x.Name].Where(l => Math.Abs(1.0 - (double)l.Power / x.Power) < .1).ToArray();
                            return(new OpponentWithHistory(x, logs.Length > 0 ? logs.Average(l => l.ScoreChange) : 0));
                        }
                            ).ToArray();
                        var engaged = false;
                        foreach (var strategy in strategies)
                        {
                            var result = strategy.SelectOpponent(opponentsWithHistory, matcher.MyPower, lobby.CurrentScore);
                            if (result.Item1 != null)
                            {
                                lastOpponent = result.Item1;
                                matcher.Refresh();
                                await matcher.ToggleFastBattle(true, cancellationToken);

                                await matcher.EngageOpponent(result.Item1, cancellationToken);

                                engaged = true;
                                break;
                            }

                            if (!result.Item2)
                            {
                                break;
                            }
                        }

                        if (engaged)
                        {
                            break;
                        }

                        Logger.Info("Refreshing matcher as no valid opponents found.");
                        cancellationToken.ThrowIfCancellationRequested();
                        await matcher.GetNewOpponents(cancellationToken);

                        //await Task.Delay(100, cancellationToken);
                        if (!matcher.IsScreenActive())
                        {
                            Logger.Fatal("Matcher screen not detected after refresh! Bailing out.");
                            throw new InvalidOperationException("Not on the arena matcher screen");
                        }
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                    if (!prepareBattle.IsScreenActive())
                    {
                        Logger.Fatal("Prepare for battle screen not detected! Bailing out.");
                        throw new InvalidOperationException("Not on the prepare battle screen");
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                    Logger.Info("Into the battle!");
                    await prepareBattle.Engage(cancellationToken);

                    cancellationToken.ThrowIfCancellationRequested();
                    var ts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
                    try {
                        await matcher.Activation(CancellationTokenSource.CreateLinkedTokenSource(ts.Token, cancellationToken).Token);
                    } catch (TaskCanceledException) {
                        if (lobby.IsScreenActive())
                        {
                            continue;
                        }
                    }

                    Logger.Info("Trying to close matcher.");
                    while (true)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        if (matcher.IsScreenActive())
                        {
                            await matcher.Close(cancellationToken);

                            if (lobby.IsScreenActive())
                            {
                                Logger.Info("Ok, we're back to lobby.");
                                break;
                            }

                            await Task.Delay(200, cancellationToken);
                        }
                        else if (lobby.IsScreenActive())
                        {
                            continue;
                        }
                        else
                        {
                            Logger.Fatal("Matcher screen not detected while trying to close it! Bailing out.");
                            throw new InvalidOperationException("Not on the arena matcher screen");
                        }
                    }

                    await Task.Delay(300, cancellationToken);
                }
            }
        }
Ejemplo n.º 4
0
        public async Task Run(GameContext context, BaseWorkerWindow vm, Action <string> statusUpdater, CancellationToken cancellationToken)
        {
            using (NDC.Push("Mapper Worker")) {
                await Task.Delay(1);

                var map    = new WorldMap(context);
                var stride = (int)Math.Ceiling(484D / SubScanBounds.Width);
                var scans  = (int)Math.Ceiling(484D / SubScanBounds.Height);
                var linear = Phase;
                ProcessedTiles = RecognizedTiles = FailedTiles = 0;
                TotalTiles     = 484 * 484 / Period;

                TileInfo[][] mapData = null;
                var          clog    = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "logs", "map.json");
                var          ilog    = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "logs", "tiles");
                var          jss     = new JsonSerializerSettings {
                    TypeNameHandling = TypeNameHandling.All
                };
                if (!Directory.Exists(Path.GetDirectoryName(clog)))
                {
                    Directory.CreateDirectory(clog);
                }
                if (!Directory.Exists(ilog))
                {
                    Directory.CreateDirectory(ilog);
                }
                if (File.Exists(clog))
                {
                    try {
                        mapData = JsonConvert.DeserializeObject <TileInfo[][]>(File.ReadAllText(clog), jss);
                    } catch {
                    }
                }

                if (mapData == null || mapData.Length != 492)
                {
                    mapData = new TileInfo[492][];
                }
                for (var i = 0; i < mapData.Length; i++)
                {
                    if (mapData[i] == null || mapData[i].Length != 492)
                    {
                        mapData[i] = new TileInfo[492];
                    }
                }

                while (!cancellationToken.IsCancellationRequested)
                {
                    if (linear > stride * scans)
                    {
                        break;
                    }
                    var cx = 8 + (linear % stride) * SubScanBounds.Width - SubScanBounds.X;
                    var cy = 8 + (linear / stride) * SubScanBounds.Height - SubScanBounds.Y;
                    statusUpdater($"Mapping at {cx},{cy} ({linear})");

                    if (!map.IsScreenActive())
                    {
                        await Task.Delay(500, cancellationToken);

                        if (!map.IsScreenActive())
                        {
                            Logger.Fatal("World map screen not detected! Bailing out.");
                            throw new InvalidOperationException("Not on the world map screen");
                        }
                    }

                    var needTiles = 0;
                    for (var xx = SubScanBounds.Left; xx < SubScanBounds.Right; xx++)
                    {
                        for (var yy = SubScanBounds.Top; yy < SubScanBounds.Bottom; yy++)
                        {
                            if (xx + cx < 8 || xx + cx > 492 || yy + cy < 8 || yy + cy > 492)
                            {
                                continue;
                            }
                            ProcessedTiles++;
                            if (mapData[cx + xx][cy + yy] == null)
                            {
                                needTiles++;
                            }
                        }
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                    if (needTiles > 0)
                    {
                        statusUpdater($"Mapping {needTiles} tiles at {cx},{cy} ({linear})");
                        await map.GoTo(cx, cy, cancellationToken);

                        for (var xx = SubScanBounds.Left; xx < SubScanBounds.Right; xx++)
                        {
                            for (var yy = SubScanBounds.Top; yy < SubScanBounds.Bottom; yy++)
                            {
                                if (xx + cx < 8 || xx + cx > 492 || yy + cy < 8 || yy + cy > 492)
                                {
                                    continue;
                                }
                                mapData[cx + xx][cy + yy] = await map.SelectTile(xx, yy, Path.Combine(ilog, $"tile{cx + xx},{cy + yy}"), cancellationToken);

                                if (mapData[cx + xx][cy + yy] != null)
                                {
                                    mapData[cx + xx][cy + yy].CenterPoint = new Point(cx + xx, cy + yy);
                                    RecognizedTiles++;
                                }
                                else
                                {
                                    FailedTiles++;
                                }
                            }
                        }

                        File.WriteAllText(clog, JsonConvert.SerializeObject(mapData, jss));
                    }

                    linear += Period;
                }
            }
        }
Ejemplo n.º 5
0
        public async Task Run(GameContext context, BaseWorkerWindow vm, Action <string> statusUpdater, CancellationToken cancellationToken)
        {
            await Task.CompletedTask;
            var tavern = new Tavern(context);
            //var rewards = new RewardsDialog(context);
            var claimed = false;

            do
            {
                claimed = false;
                cancellationToken.ThrowIfCancellationRequested();
                if (!tavern.IsScreenActive())
                {
                    throw new InvalidOperationException("You're not at the tavern screen");
                }
                statusUpdater($"{tavern.StandardCards} standard cards, {tavern.HeroicCards} heroic cards, {tavern.EventPoints} event points.");

                if (tavern.StandardCards > 0 && ClaimStandard)
                {
                    if (tavern.StandardCards >= 10)
                    {
                        await tavern.PressClaimStandard10Button(cancellationToken);
                    }
                    else
                    {
                        await tavern.PressClaimStandard1Button(cancellationToken);
                    }
                    while (!tavern.IsScreenActive())
                    {
                        await tavern.PressCloseButton(cancellationToken);
                    }
                    claimed = true;
                }

                if (tavern.HeroicCards > 0 && ClaimHeroic)
                {
                    if (tavern.HeroicCards >= 10)
                    {
                        await tavern.PressClaimHeroic10Button(cancellationToken);
                    }
                    else
                    {
                        await tavern.PressClaimHeroic1Button(cancellationToken);
                    }
                    while (!tavern.IsScreenActive())
                    {
                        await tavern.PressCloseButton(cancellationToken);
                    }
                    claimed = true;
                }

                if (tavern.EventPoints > 10 && ClaimEvent)
                {
                    if (tavern.EventPoints >= 100)
                    {
                        await tavern.PressClaimEvent10Button(cancellationToken);
                    }
                    else
                    {
                        await tavern.PressClaimEvent1Button(cancellationToken);
                    }
                    while (!tavern.IsScreenActive())
                    {
                        await tavern.PressCloseButton(cancellationToken);
                    }
                    claimed = true;
                }
            } while (claimed);
        }