コード例 #1
0
ファイル: ZoneCommand.cs プロジェクト: Archomeda/AutoSaliens
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            var split = parameters.Split(' ');

            if (split.Length != 2)
            {
                this.Logger?.LogCommandOutput("{err}Invalid amount of parameters.");
                return;
            }

            var planet = await SaliensApi.GetPlanetAsync(split[0]);

            if (planet == null)
            {
                this.Logger?.LogCommandOutput("{err}Unknown planet id.");
                return;
            }

            if (!int.TryParse(split[1], out int zonePos))
            {
                this.Logger?.LogCommandOutput("{err}Invalid zone position.");
                return;
            }

            if (zonePos >= planet.Zones.Count)
            {
                this.Logger?.LogCommandOutput("{err}Unknown zone position.");
                return;
            }

            this.Logger?.LogCommandOutput(planet.Zones[zonePos].ToConsoleBlock());
        }
コード例 #2
0
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(Program.Settings.Token))
            {
                this.Logger?.LogCommandOutput("{{warn}}No token has been set.");
                return;
            }

            var playerInfo = await SaliensApi.GetPlayerInfoAsync(Program.Settings.Token);

            if (string.IsNullOrWhiteSpace(playerInfo?.ActivePlanet))
            {
                this.Logger?.LogCommandOutput("No planet has been joined.");
                return;
            }
            if (string.IsNullOrWhiteSpace(playerInfo?.ActiveZoneGame))
            {
                this.Logger?.LogCommandOutput("No zone has been joined.");
                return;
            }

            if (!int.TryParse(playerInfo.ActiveZonePosition, out int zonePos))
            {
                this.Logger?.LogCommandOutput("Invalid zone.");
                return;
            }
            var planet = await SaliensApi.GetPlanetAsync(playerInfo.ActivePlanet);

            this.Logger?.LogCommandOutput(planet.Zones[zonePos].ToConsoleBlock());
        }
コード例 #3
0
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(Program.Saliens.Token))
            {
                return("{{warn}}No token has been set.");
            }

            if (Program.Saliens.PlanetDetails == null)
            {
                return("No planet information available yet.");
            }

            var planet = Program.Saliens.JoinedPlanet;

            if (planet == null)
            {
                return("No planet has been joined.");
            }

            if (planet.Zones == null)
            {
                planet = await SaliensApi.GetPlanet(parameters);

                var index = Program.Saliens.PlanetDetails.FindIndex(p => p.Id == parameters);
                Program.Saliens.PlanetDetails[index] = planet;
            }

            return(planet.ToConsoleBlock());
        }
コード例 #4
0
        protected override string FormatState(PlayerInfoResponse playerInfo, DiscordPresence presence)
        {
            bool hasActivePlanet   = !string.IsNullOrWhiteSpace(playerInfo.ActivePlanet);
            bool hasActiveZone     = !string.IsNullOrWhiteSpace(playerInfo.ActiveZonePosition);
            bool hasActiveBossZone = !string.IsNullOrWhiteSpace(playerInfo.ActiveBossGame);

            var state = "Inactive";

            if (hasActivePlanet && (hasActiveZone || hasActiveBossZone))
            {
                state = $"Planet {playerInfo.ActivePlanet} - ";
                if (hasActiveBossZone)
                {
                    state += $"Boss Zone";
                }
                else if (hasActiveZone)
                {
                    state += $"Zone {playerInfo.ActiveZonePosition}";
                }
                var planet = SaliensApi.GetPlanet(playerInfo.ActivePlanet);
                if (hasActiveZone && int.TryParse(playerInfo.ActiveZonePosition, out int zonePos))
                {
                    var zone = planet.Zones[zonePos];
                    if (zone != null)
                    {
                        state += $" ({zone.RealDifficulty.ToString().Substring(0, 1)})";
                    }
                }
            }
            else if (hasActivePlanet && !hasActiveZone)
            {
                state = $"Planet {playerInfo.ActivePlanet}";
            }
            return(state);
        }
コード例 #5
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task UpdatePlayerInfo(TimeSpan?forceCacheExpiryTime = null)
        {
            if (string.IsNullOrEmpty(this.Token))
            {
                return;
            }

            this.PlayerInfo = await SaliensApi.GetPlayerInfoAsync(this.Token, forceCacheExpiryTime);

            this.State = BotState.Idle;

            if (!string.IsNullOrWhiteSpace(this.PlayerInfo.ActivePlanet))
            {
                this.ActivePlanet = await SaliensApi.GetPlanetAsync(this.PlayerInfo.ActivePlanet, forceCacheExpiryTime);

                this.State = BotState.OnPlanet;

                if (int.TryParse(this.PlayerInfo.ActiveZonePosition, out int zonePosition))
                {
                    this.ActiveZone          = this.ActivePlanet.Zones[zonePosition];
                    this.ActiveZoneStartDate = DateTime.Now - this.PlayerInfo.TimeInZone;
                    this.State = BotState.InZone;
                }

                if (!string.IsNullOrWhiteSpace(this.PlayerInfo.ActiveBossGame))
                {
                    this.ActiveZone          = this.ActivePlanet.Zones.FirstOrDefault(z => z.GameId == this.PlayerInfo.ActiveBossGame);
                    this.ActiveZoneStartDate = DateTime.Now - this.PlayerInfo.TimeInZone;
                    this.State = BotState.InBossZone;
                }
            }

            this.PresenceUpdateTrigger.SetSaliensPlayerState(this.PlayerInfo);
        }
コード例 #6
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task JoinBossZone(int zonePosition)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    this.Logger?.LogMessage($"{{action}}Joining {{zone}}BOSS zone {zonePosition}{{action}}...");
                    await SaliensApi.JoinBossZoneAsync(this.Token, zonePosition);

                    // States
                    this.ActiveZone                    = this.ActivePlanet.Zones[zonePosition];
                    this.ActiveZoneStartDate           = DateTime.Now;
                    this.PlayerInfo.ActiveZoneGame     = null;
                    this.PlayerInfo.ActiveBossGame     = this.ActiveZone.GameId;
                    this.PlayerInfo.ActiveZonePosition = zonePosition.ToString();
                    this.PlayerInfo.TimeInZone         = TimeSpan.FromSeconds(0);
                    this.State = BotState.InBossZone;

                    this.PresenceUpdateTrigger.SetSaliensPlayerState(this.PlayerInfo);

                    return;
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.Fail:
                    case EResult.Busy:
                    case EResult.RateLimitExceeded:
                        this.Logger?.LogMessage($"{{warn}}Failed to join boss zone: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                        await Task.Delay(2000);

                        continue;

                    case EResult.Expired:
                    case EResult.NoMatch:
                    default:
                        this.Logger?.LogMessage($"{{warn}}Failed to join boss zone: {ex.Message}");
                        ResetState();
                        throw;
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogMessage($"{{warn}}Failed to join boss zone: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                    await Task.Delay(2000);

                    continue;
                }
            }

            // States, only set when failed
            ResetState();
            void ResetState()
            {
                this.State = BotState.OnPlanet;
            }
        }
コード例 #7
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task JoinPlanet(string planetId)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    var planet = await SaliensApi.GetPlanetAsync(planetId);

                    this.Logger?.LogMessage($"{{action}}Joining planet {{planet}}{planetId} ({planet.State.Name}){{action}}...");
                    await SaliensApi.JoinPlanetAsync(this.Token, planetId);

                    // States
                    this.ActivePlanet            = planet;
                    this.PlayerInfo.ActivePlanet = planetId;
                    this.State = BotState.OnPlanet;

                    this.PresenceUpdateTrigger.SetSaliensPlayerState(this.PlayerInfo);

                    return;
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.Fail:
                    case EResult.Busy:
                    case EResult.RateLimitExceeded:
                        this.Logger?.LogMessage($"{{warn}}Failed to join planet: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                        await Task.Delay(2000);

                        continue;

                    case EResult.Expired:
                    case EResult.NoMatch:
                    default:
                        this.Logger?.LogMessage($"{{warn}}Failed to join planet: {ex.Message}");
                        ResetState();
                        throw;
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogMessage($"{{warn}}Failed to join planet: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                    await Task.Delay(2000);

                    continue;
                }
            }

            // States, only set when failed
            ResetState();
            void ResetState()
            {
                this.State = BotState.Idle;
            }
        }
コード例 #8
0
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            var planet = await SaliensApi.GetPlanetAsync(parameters);

            if (planet == null)
            {
                this.Logger?.LogCommandOutput("{err}Unknown planet id.");
                return;
            }
            this.Logger?.LogCommandOutput(planet.ToConsoleBlock());
        }
コード例 #9
0
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            if (!string.IsNullOrWhiteSpace(parameters) && parameters != "all" && parameters != "live")
            {
                this.Logger?.LogCommandOutput("{err}Invalid parameter.");
                return;
            }

            var planetDetails = (await SaliensApi.GetPlanetsAsync()).Values.OrderBy(p => p.State.Priority);

            var active = planetDetails.Where(p => p.State.Running);
            var future = planetDetails.Where(p => !p.State.Active && !p.State.Captured);

            if (parameters == "all")
            {
                var captured = planetDetails.Where(p => p.State.Captured);
                this.Logger?.LogCommandOutput("Captured planets:");
                await PrintPlanets(captured);

                this.Logger?.LogCommandOutput("");
                this.Logger?.LogCommandOutput("Upcoming planets:");
                await PrintPlanets(future);

                this.Logger?.LogCommandOutput("");
            }
            this.Logger?.LogCommandOutput("Active planets:");
            await PrintPlanets(active);

            this.Logger?.LogCommandOutput("");
            if (string.IsNullOrWhiteSpace(parameters))
            {
                this.Logger?.LogCommandOutput("Upcoming planets:");
                await PrintPlanets(future.Take(2));

                this.Logger?.LogCommandOutput("");
            }

            this.Logger?.LogCommandOutput($"To get a list of all planets, use the command: {{command}}planets {{param}}all{{reset}}{Environment.NewLine}{Environment.NewLine}" +

                                          $"To see more information about a planet, use the command: {{command}}planet {{param}}<id>{{reset}}{Environment.NewLine}" +
                                          $"where {{param}}<id>{{reset}} is replaced with the planet id.");

            async Task PrintPlanets(IEnumerable <Planet> planets)
            {
                var results = await Task.WhenAll(planets.Select(p => p.Zones == null ? SaliensApi.GetPlanetAsync(p.Id) : Task.FromResult(p)));

                foreach (var planet in results)
                {
                    this.Logger?.LogCommandOutput(planet.ToConsoleLine());
                }
            }
        }
コード例 #10
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task <List <Planet> > GetActivePlanets()
        {
            var planets = (await SaliensApi.GetPlanetsAsync()).Values
                          .OrderBy(p => p.State.Priority);

            var activePlanets = await Task.WhenAll(planets
                                                   .Where(p => p.State.Running)
                                                   .Select(p => SaliensApi.GetPlanetAsync(p.Id)));

            // Get the next 2 future planets, if available
            var lastPlanetIndex = planets.ToList().FindIndex(p => p.Id == activePlanets.Last().Id);
            var lastPlanets     = (await Task.WhenAll(planets.Skip(lastPlanetIndex + 1)
                                                      .Take(2)
                                                      .Select(p => SaliensApi.GetPlanetAsync(p.Id))));

            return(activePlanets.Concat(lastPlanets).ToList());
        }
コード例 #11
0
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            var split = parameters.Split(' ');

            if (split.Length != 2)
            {
                return("{err}Invalid amount of parameters.");
            }

            if (Program.Saliens.PlanetDetails == null)
            {
                return("No planet information available yet.");
            }

            var planet = Program.Saliens.PlanetDetails.FirstOrDefault(p => p.Id == split[0]);

            if (planet == null)
            {
                return("{err}Unknown planet id.");
            }

            if (!int.TryParse(split[1], out int zonePos))
            {
                return("{err}Invalid zone position.");
            }

            if (planet.Zones == null || planet.Zones.Count == 0)
            {
                var index = Program.Saliens.PlanetDetails.FindIndex(p => p.Id == planet.Id);
                planet = await SaliensApi.GetPlanet(planet.Id);

                Program.Saliens.PlanetDetails[index] = planet;
            }

            var zone = planet.Zones.FirstOrDefault(z => z.ZonePosition == zonePos);

            if (zone == null)
            {
                return("{err}Unknown zone position.");
            }

            return(zone.ToConsoleBlock());
        }
コード例 #12
0
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(Program.Saliens.Token))
            {
                return("{warn}No token has been set.");
            }

            var info = await SaliensApi.GetPlayerInfo(Program.Settings.Token);

            Program.Saliens.PlayerInfo = info;

            return($"Level: {{level}}{info.Level}{{reset}}{Environment.NewLine}" +
                   $"XP: {{xp}}{long.Parse(info.Score).ToString("#,##0")}{{reset}} (required for next level: {{reqxp}}{long.Parse(info.NextLevelScore).ToString("#,##0")}{{reset}}){Environment.NewLine}" +
                   $"Clan: {info.ClanInfo.Name}{Environment.NewLine}" +
                   $"Active planet: {{planet}}{info.ActivePlanet} {{reset}}{Environment.NewLine}" +
                   $"Time spent on planet: {info.TimeOnPlanet.ToString()}{Environment.NewLine}" +
                   $"Active zone: {{zone}}{info.ActiveZonePosition} ({info.ActiveZoneGame}){{reset}}{Environment.NewLine}" +
                   $"Time spent in zone: {info.TimeInZone.TotalSeconds} seconds");
        }
コード例 #13
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task <List <Zone> > FindMostWantedZones()
        {
            var activeZones = (await SaliensApi.GetPlanetAsync(this.ActivePlanet.Id)).Zones.Where(z => !z.Captured);

            // Filter out blacklisted games
            var zones = activeZones.OrderBy(p => 0);

            if (this.Strategy.HasFlag(BotStrategy.FocusBosses))
            {
                zones = zones.ThenByDescending(z => z.BossActive ? 1 : 0);
            }
            if (this.Strategy.HasFlag(BotStrategy.MostDifficultZonesFirst))
            {
                zones = zones.ThenByDescending(z => z.RealDifficulty);
            }
            else if (this.Strategy.HasFlag(BotStrategy.LeastDifficultZonesFirst))
            {
                zones = zones.ThenBy(z => z.RealDifficulty);
            }
            if (this.Strategy.HasFlag(BotStrategy.MostCompletedZonesFirst))
            {
                zones = zones.ThenByDescending(z => z.CaptureProgress);
            }
            else if (this.Strategy.HasFlag(BotStrategy.LeastCompletedZonesFirst))
            {
                zones = zones.ThenBy(z => z.CaptureProgress);
            }

            if (this.Strategy.HasFlag(BotStrategy.TopDown))
            {
                zones = zones.ThenBy(z => z.ZonePosition);
            }
            else if (this.Strategy.HasFlag(BotStrategy.BottomUp))
            {
                zones = zones.ThenByDescending(z => z.ZonePosition);
            }

            // Filter out blacklisted games
            return(zones
                   .Where(z => !string.IsNullOrWhiteSpace(z.GameId) && !(this.BlacklistedGames.ContainsKey(z.GameId) && this.BlacklistedGames[z.GameId] > DateTime.Now))
                   .ToList());
        }
コード例 #14
0
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(parameters))
            {
                // Show the current overridden planet id
                if (!string.IsNullOrWhiteSpace(Program.Settings.OverridePlanetId))
                {
                    this.Logger?.LogCommandOutput($"The planet id is currently overridden to: {{value}}{Program.Settings.OverridePlanetId}");
                }
                else
                {
                    this.Logger?.LogCommandOutput("You have currently no planet id override set.");
                }

                this.Logger?.LogCommandOutput("You can override the planet id by appending the planet id to this command: {command}overrideplanetid {param}<id>");
                this.Logger?.LogCommandOutput("where {param}<id> is replaced with the planet id, or {param}remove{reset} if you wish to remove it.");
            }
            else
            {
                // Set the overridden planet id
                if (parameters == "remove")
                {
                    Program.Settings.OverridePlanetId.Value = null;
                    this.Logger?.LogCommandOutput("Your planet id override has been removed.");
                }
                else
                {
                    var planet = await SaliensApi.GetPlanetAsync(parameters);

                    if (planet == null)
                    {
                        this.Logger?.LogCommandOutput("{err}Invalid planet id. Check the planets for ids.");
                    }
                    else
                    {
                        Program.Settings.OverridePlanetId.Value = parameters;
                        this.Logger?.LogCommandOutput("Your planet id override has been saved.");
                    }
                }
            }
        }
コード例 #15
0
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(parameters))
            {
                // Show the current token
                if (!string.IsNullOrWhiteSpace(Program.Settings.Token))
                {
                    this.Logger?.LogCommandOutput($"Your token is currently set to: {{value}}{Program.Settings.Token}{{reset}}.");
                }
                else
                {
                    this.Logger?.LogCommandOutput("You have currently no token set.");
                }

                this.Logger?.LogCommandOutput("You can change the token by appending the token to this command: {command}token {param}<your_token>");
                this.Logger?.LogCommandOutput("where {param}<your_token>{reset} is replaced with your token.");
            }
            else
            {
                // Set the token
                try
                {
                    var playerInfo = await SaliensApi.GetPlayerInfoAsync(parameters);

                    if (playerInfo != null)
                    {
                        Program.Settings.Token.Value = parameters;
                        this.Logger?.LogCommandOutput("Your token has been saved.");
                    }
                    else
                    {
                        this.Logger?.LogCommandOutput("{{err}}Invalid token.");
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogCommandOutput($"{{err}}Invalid response. {ex.Message}");
                }
            }
        }
コード例 #16
0
ファイル: ZonesCommand.cs プロジェクト: samdsk/AutoSaliens
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            if (Program.Saliens.PlanetDetails == null)
            {
                return("No planet information available yet.");
            }

            var planet = Program.Saliens.PlanetDetails.FirstOrDefault(p => p.Id == parameters);

            if (planet == null)
            {
                return("{err}Unknown planet id.");
            }

            if (planet.Zones == null || planet.Zones.Count == 0)
            {
                // Zones not available yet, request them manually
                var index = Program.Saliens.PlanetDetails.FindIndex(p => p.Id == planet.Id);
                planet = await SaliensApi.GetPlanet(planet.Id);

                Program.Saliens.PlanetDetails[index] = planet;
            }

            var active   = planet.Zones.Where(z => !z.Captured);
            var captured = planet.Zones.Where(z => z.Captured);

            return($"Zones on {{planet}}planet {planet.Id} ({planet.State.Name}){{reset}}{Environment.NewLine}" +
                   $"Captured zones:{Environment.NewLine}" +
                   $"{string.Join(Environment.NewLine, captured.Select(z => z.ToConsoleLine()))}{Environment.NewLine}{Environment.NewLine}" +

                   $"Active zones:{Environment.NewLine}" +
                   $"{string.Join(Environment.NewLine, active.Select(z => z.ToConsoleLine()))}{Environment.NewLine}{Environment.NewLine}" +

                   $"To see more information about a zone, use the command: {{command}}zone {{param}}<planet_id> <zone_pos>{{reset}}{Environment.NewLine}" +
                   $"where {{param}}<planet_id>{{reset}} is replaced with the planet id,{Environment.NewLine}" +
                   $"and {{param}}<zone_pos>{{reset}} is replaced with the zone position");
        }
コード例 #17
0
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            if (Program.Saliens.PlanetDetails == null)
            {
                return("No planet information available yet.");
            }

            var planet = Program.Saliens.PlanetDetails.FirstOrDefault(p => p.Id == parameters);

            if (planet == null)
            {
                return("{err}Unknown planet id.");
            }

            if (planet.Zones == null)
            {
                planet = await SaliensApi.GetPlanet(parameters);

                var index = Program.Saliens.PlanetDetails.FindIndex(p => p.Id == parameters);
                Program.Saliens.PlanetDetails[index] = planet;
            }

            return(planet.ToConsoleBlock());
        }
コード例 #18
0
        private void PresenceLoopThread()
        {
            while (!this.cancelSource.Token.IsCancellationRequested)
            {
                if (string.IsNullOrWhiteSpace(this.ApiToken))
                {
                    return;
                }

                TimeSpan timeToWait = TimeSpan.FromSeconds(fallbackRefreshRate);
                try
                {
                    var playerInfo = SaliensApi.GetPlayerInfo(this.ApiToken);
                    this.presence.Logger?.LogMessage($"Updating Discord presence with {playerInfo.Score} XP");
                    this.presence.SetSaliensPlayerState(playerInfo);
                    if (!string.IsNullOrWhiteSpace(playerInfo.ActiveZonePosition))
                    {
                        if (playerInfo.TimeInZone < TimeSpan.FromSeconds(110))
                        {
                            timeToWait = TimeSpan.FromSeconds(110) - playerInfo.TimeInZone;
                        }
                        else if (playerInfo.TimeInZone < TimeSpan.FromSeconds(120))
                        {
                            timeToWait = TimeSpan.FromSeconds(120) - playerInfo.TimeInZone;
                        }
                        timeToWait += TimeSpan.FromSeconds(5);
                    }
                }
                catch (Exception ex)
                {
                    this.presence.Logger?.LogException(ex);
                }

                this.cancelSource.Token.WaitHandle.WaitOne(timeToWait);
            }
        }
コード例 #19
0
ファイル: ZonesCommand.cs プロジェクト: Archomeda/AutoSaliens
        public override async Task RunAsync(string parameters, CancellationToken cancellationToken)
        {
            var planet = await SaliensApi.GetPlanetAsync(parameters);

            if (planet == null)
            {
                this.Logger?.LogCommandOutput("{err}Unknown planet id.");
                return;
            }

            var active   = planet.Zones.Where(z => !z.Captured);
            var captured = planet.Zones.Where(z => z.Captured);

            this.Logger?.LogCommandOutput($"Zones on {{planet}}planet {planet.Id} ({planet.State.Name}){{reset}}{Environment.NewLine}" +
                                          $"Captured zones:{Environment.NewLine}" +
                                          $"{string.Join(Environment.NewLine, captured.Select(z => z.ToConsoleLine()))}{Environment.NewLine}{Environment.NewLine}" +

                                          $"Active zones:{Environment.NewLine}" +
                                          $"{string.Join(Environment.NewLine, active.Select(z => z.ToConsoleLine()))}{Environment.NewLine}{Environment.NewLine}" +

                                          $"To see more information about a zone, use the command: {{command}}zone {{param}}<planet_id> <zone_pos>{{reset}}{Environment.NewLine}" +
                                          $"where {{param}}<planet_id>{{reset}} is replaced with the planet id,{Environment.NewLine}" +
                                          $"and {{param}}<zone_pos>{{reset}} is replaced with the zone position");
        }
コード例 #20
0
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(parameters))
            {
                // Show the current token
                if (!string.IsNullOrWhiteSpace(Program.Saliens.Token))
                {
                    this.WriteConsole($"Your token is currently set to: {{value}}{Program.Saliens.Token}{{reset}}.");
                }
                else
                {
                    this.WriteConsole("You have currently no token set.");
                }

                this.WriteConsole("You can change the token by appending the token to this command: {command}token {param}<your_token>");
                this.WriteConsole("where {param}<your_token>{reset} is replaced with your token.");

                return("");
            }
            else
            {
                // Set the token
                try
                {
                    Program.Saliens.PlayerInfo = await SaliensApi.GetPlayerInfo(parameters);

                    Program.Settings.Token = parameters;
                    Program.Settings.Save();
                    return("Your token has been saved.");
                }
                catch (WebException ex)
                {
                    return($"{{err}}Invalid response. {ex.Message}");
                }
            }
        }
コード例 #21
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        public async Task <BossLevelState> ReportBossDamage(int startLevel, long startXp, bool useHealAbility, int damageToBoss, int damageTaken)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    var message = $"{{action}}Reporting boss damage {{value}}+{damageToBoss.ToString("#,##0")}";
                    if (damageTaken > 0)
                    {
                        message += $"{{action}}, {{negvalue}}-{damageTaken.ToString("#,##0")}";
                    }
                    if (useHealAbility)
                    {
                        message += $"{{action}}, {{value}}+Heal";
                    }
                    message += $"{{action}}...";
                    this.Logger?.LogMessage(message);

                    var response = await SaliensApi.ReportBossDamageAsync(this.Token, useHealAbility, damageToBoss, damageTaken);

                    if (response.BossStatus == null)
                    {
                        return(BossLevelState.WaitingForPlayers);
                    }

                    BossPlayer currentPlayer = null;
                    var        bossHpColor   = MathUtils.ScaleColor(response.BossStatus.BossMaxHp - response.BossStatus.BossHp, response.BossStatus.BossMaxHp, new[] { "{svlow}", "{slow}", "{smed}", "{shigh}", "{svhigh}" });
                    this.Logger?.LogMessage($"{bossHpColor}Boss HP: {response.BossStatus.BossHp.ToString("#,##0")}/{response.BossStatus.BossMaxHp.ToString("#,##0")}{{reset}} - {{lasers}}{response.NumLaserUses} lasers{{reset}} - {{heals}}{response.NumTeamHeals} heals");
                    foreach (var player in response.BossStatus.BossPlayers.OrderBy(p => p.Name))
                    {
                        var playerStartLevel = player.LevelOnJoin;
                        long.TryParse(player.ScoreOnJoin, out long playerStartXp);

                        var isCurrentPlayer = playerStartLevel == startLevel && playerStartXp == startXp;
                        if (isCurrentPlayer)
                        {
                            currentPlayer = player;
                        }
                        var playerColor = isCurrentPlayer ? "{player}" : "{reset}";
                        var hpColor     = MathUtils.ScaleColor(player.MaxHp - player.Hp, player.MaxHp, new[] { "{svlow}", "{slow}", "{smed}", "{shigh}", "{svhigh}" });
                        this.Logger?.LogMessage($"{playerColor}{(player.Name.Length > 16 ? player.Name.Substring(0, 16) : player.Name).PadLeft(16)}: " +
                                                $"{hpColor}HP {player.Hp.ToString("#,##0").PadLeft(7)}/{player.MaxHp.ToString("#,##0").PadLeft(7)}{playerColor} - " +
                                                $"XP {player.XpEarned.ToString("#,##0").PadLeft(9)}/{(playerStartXp + player.XpEarned).ToString("#,##0").PadLeft(12)}");
                    }

                    if (response.GameOver && currentPlayer != null && long.TryParse(this.PlayerInfo.Score, out long oldScore))
                    {
                        // States
                        this.PlayerInfo.Score          = (oldScore + currentPlayer.XpEarned).ToString();
                        this.PlayerInfo.Level          = currentPlayer.NewLevel;
                        this.PlayerInfo.NextLevelScore = currentPlayer.NextLevelScore;
                    }
                    return(response.GameOver ? BossLevelState.GameOver : BossLevelState.Active);
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.Fail:
                    case EResult.Busy:
                    case EResult.RateLimitExceeded:
                        this.Logger?.LogMessage($"{{warn}}Failed to report boss damage: {ex.Message} - Giving it a second ({i + 1}/5)...");
                        await Task.Delay(1000);

                        continue;

                    case EResult.Expired:
                    case EResult.NoMatch:
                    default:
                        this.Logger?.LogMessage($"{{warn}}Failed to report boss damage: {ex.Message}");
                        ResetState();
                        throw;
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogMessage($"{{warn}}Failed to report boss damage: {ex.Message} - Giving it a second ({i + 1}/5)...");
                    await Task.Delay(1000);

                    continue;
                }
            }

            // States, only set when failed
            ResetState();
            void ResetState()
            {
                this.ActiveZone = null;
                this.PlayerInfo.ActiveBossGame     = null;
                this.PlayerInfo.ActiveZonePosition = null;
                this.State = BotState.ForcedZoneLeave;
            }

            return(BossLevelState.Error);
        }
コード例 #22
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        public async Task ReportScore(int score)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    this.Logger?.LogMessage($"{{action}}Reporting score {{xp}}{score.ToString("#,##0")}{{action}}...");
                    var stopwatch = new Stopwatch();
                    stopwatch.Start();
                    var response = await SaliensApi.ReportScoreAsync(this.Token, score);

                    stopwatch.Stop();

                    // Only change the network delay if the last delay was lower
                    // Don't want to be too eager for an occasional spike
                    if (this.reportScoreNetworkDelay.TotalMilliseconds == 0 || stopwatch.Elapsed < this.reportScoreNetworkDelay)
                    {
                        this.reportScoreNetworkDelay = stopwatch.Elapsed;
                    }

                    if (!string.IsNullOrWhiteSpace(response.NewScore))
                    {
                        if (!string.IsNullOrWhiteSpace(response.NextLevelScore))
                        {
                            this.Logger?.LogMessage($"XP: {{oldxp}}{long.Parse(response.OldScore).ToString("#,##0")}{{reset}} -> {{xp}}{long.Parse(response.NewScore).ToString("#,##0")}{{reset}} (next level at {{reqxp}}{long.Parse(response.NextLevelScore).ToString("#,##0")}{{reset}})");
                        }
                        else
                        {
                            this.Logger?.LogMessage($"XP: {{oldxp}}{long.Parse(response.OldScore).ToString("#,##0")}{{reset}} -> {{xp}}{long.Parse(response.NewScore).ToString("#,##0")}");
                        }
                    }
                    if (response.NewLevel != response.OldLevel)
                    {
                        this.Logger?.LogMessage($"New level: {{oldlevel}}{response.OldLevel}{{reset}} -> {{level}}{response.NewLevel}{{reset}}");
                    }

                    // States
                    this.PlayerInfo.Score          = response.NewScore;
                    this.PlayerInfo.Level          = response.NewLevel;
                    this.PlayerInfo.NextLevelScore = response.NextLevelScore;
                    this.ActiveZone = null;
                    this.PlayerInfo.ActiveZoneGame     = null;
                    this.PlayerInfo.ActiveZonePosition = null;
                    this.PlayerInfo.TimeInZone         = TimeSpan.FromSeconds(0);
                    this.State = BotState.OnPlanet;

                    return;
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.Fail:
                    case EResult.Busy:
                    case EResult.RateLimitExceeded:
                    case EResult.TimeIsOutOfSync:
                        if (ex.EResult == EResult.TimeIsOutOfSync)
                        {
                            // Decrease the delay with a small amount
                            this.reportScoreNetworkDelay -= TimeSpan.FromMilliseconds(25);
                        }
                        this.Logger?.LogMessage($"{{warn}}Failed to submit score: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                        await Task.Delay(2000);

                        continue;

                    case EResult.Expired:
                    case EResult.NoMatch:
                    default:
                        this.Logger?.LogMessage($"{{warn}}Failed to submit score: {ex.Message}");
                        ResetState();
                        throw;
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogMessage($"{{warn}}Failed to submit score: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                    await Task.Delay(2000);

                    continue;
                }
            }

            // States, only set when failed
            ResetState();
            void ResetState()
            {
                this.ActiveZone = null;
                this.PlayerInfo.ActiveZoneGame     = null;
                this.PlayerInfo.ActiveZonePosition = null;
                this.State = BotState.ForcedZoneLeave;
            }
        }
コード例 #23
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task JoinZone(int zonePosition)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    this.Logger?.LogMessage($"{{action}}Joining {{zone}}zone {zonePosition}{{action}}...");
                    var stopwatch = new Stopwatch();
                    stopwatch.Start();
                    await SaliensApi.JoinZoneAsync(this.Token, zonePosition);

                    stopwatch.Stop();

                    var startDate = DateTime.Now;

                    // If the request took too long, resynchronize the start date
                    if (stopwatch.Elapsed > TimeSpan.FromSeconds(1))
                    {
                        var playerInfo = await SaliensApi.GetPlayerInfoAsync(this.Token, TimeSpan.FromSeconds(0));

                        var diff = (startDate - (DateTime.Now - playerInfo.TimeInZone));
                        if (diff > TimeSpan.FromSeconds(0))
                        {
                            this.Logger?.LogMessage($"{{action}}Recalibrated zone join time with {{value}}{diff.Negate().TotalSeconds.ToString("0.###")} seconds");
                            startDate = DateTime.Now - playerInfo.TimeInZone;
                        }
                    }

                    // States
                    this.ActiveZone                    = this.ActivePlanet.Zones[zonePosition];
                    this.ActiveZoneStartDate           = startDate;
                    this.PlayerInfo.ActiveZoneGame     = this.ActiveZone.GameId;
                    this.PlayerInfo.ActiveZonePosition = zonePosition.ToString();
                    this.PlayerInfo.TimeInZone         = TimeSpan.FromSeconds(0);
                    this.State = BotState.InZone;

                    this.PresenceUpdateTrigger.SetSaliensPlayerState(this.PlayerInfo);

                    return;
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.Fail:
                    case EResult.Busy:
                    case EResult.RateLimitExceeded:
                        this.Logger?.LogMessage($"{{warn}}Failed to join zone: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                        await Task.Delay(2000);

                        continue;

                    case EResult.Expired:
                    case EResult.NoMatch:
                    default:
                        this.Logger?.LogMessage($"{{warn}}Failed to join zone: {ex.Message}");
                        ResetState();
                        throw;
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogMessage($"{{warn}}Failed to join zone: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                    await Task.Delay(2000);

                    continue;
                }
            }

            // States, only set when failed
            ResetState();
            void ResetState()
            {
                this.State = BotState.OnPlanet;
            }
        }
コード例 #24
0
ファイル: PlanetsCommand.cs プロジェクト: samdsk/AutoSaliens
        public override async Task <string> Run(string parameters, CancellationToken cancellationToken)
        {
            if (!string.IsNullOrWhiteSpace(parameters) && parameters != "all" && parameters != "live")
            {
                return("{err}Invalid parameter.");
            }

            if (Program.Saliens.PlanetDetails == null)
            {
                return("No planet information available yet.");
            }

            var planetDetails = Program.Saliens.PlanetDetails.OrderBy(p => p.State.Priority);

            var active = planetDetails.Where(p => p.State.Running);
            var future = planetDetails.Where(p => !p.State.Active && !p.State.Captured);

            if (parameters == "all" || parameters == "live")
            {
                var captured = planetDetails.Where(p => p.State.Captured);
                this.WriteConsole("Captured planets:");
                await PrintPlanets(captured);

                this.WriteConsole("");
                this.WriteConsole("Upcoming planets:");
                await PrintPlanets(future);

                this.WriteConsole("");
            }
            this.WriteConsole("Active planets:");
            await PrintPlanets(active);

            this.WriteConsole("");
            if (string.IsNullOrWhiteSpace(parameters))
            {
                this.WriteConsole("Upcoming planets:");
                await PrintPlanets(future.Take(1));

                this.WriteConsole("");
            }

            return($"To get a list of all planets, use the command: {{command}}planets {{param}}all{{reset}}{Environment.NewLine}" +
                   $"To fully refresh the list of planets, use the command: {{command}}planets {{param}}live{{reset}}{Environment.NewLine}{Environment.NewLine}" +

                   $"To see more information about a planet, use the command: {{command}}planet {{param}}<id>{{reset}}{Environment.NewLine}" +
                   $"where {{param}}<id>{{reset}} is replaced with the planet id.");

            async Task PrintPlanets(IEnumerable <Planet> planets)
            {
                var tasks = planets.Select(p => parameters == "live" || p.Zones == null ? SaliensApi.GetPlanet(p.Id) : Task.FromResult(p));

                foreach (var task in tasks)
                {
                    var planet = await task;
                    var i      = Program.Saliens.PlanetDetails.FindIndex(p => p.Id == planet.Id);
                    Program.Saliens.PlanetDetails[i] = planet;
                    this.WriteConsole(planet.ToConsoleLine());
                }
            }
        }
コード例 #25
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task LeaveGame(string gameId)
        {
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    await SaliensApi.LeaveGameAsync(this.Token, gameId);

                    if (this.HasActivePlanet && this.ActivePlanet.Id == gameId)
                    {
                        this.Logger?.LogMessage($"{{action}}Leaving planet {{planet}}{gameId} ({this.ActivePlanet.State.Name}){{action}}...");

                        // States
                        this.ActivePlanet            = null;
                        this.PlayerInfo.ActivePlanet = null;
                        this.PlayerInfo.TimeOnPlanet = TimeSpan.FromSeconds(0);
                        this.State = BotState.Idle;
                    }
                    else if (this.HasActiveZone && this.ActiveZone.GameId == gameId)
                    {
                        this.Logger?.LogMessage($"{{action}}Leaving zone {{zone}}{this.ActiveZone.ZonePosition} ({gameId}){{action}}...");

                        // States
                        this.ActiveZone = null;
                        this.PlayerInfo.ActiveBossGame     = null;
                        this.PlayerInfo.ActiveZoneGame     = null;
                        this.PlayerInfo.ActiveZonePosition = null;
                        this.PlayerInfo.TimeInZone         = TimeSpan.FromSeconds(0);
                        this.State = BotState.OnPlanet;
                    }

                    this.PresenceUpdateTrigger.SetSaliensPlayerState(this.PlayerInfo);

                    return;
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.Fail:
                    case EResult.Busy:
                    case EResult.RateLimitExceeded:
                        this.Logger?.LogMessage($"{{warn}}Failed to leave game: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                        await Task.Delay(2000);

                        continue;

                    case EResult.Expired:
                    case EResult.NoMatch:
                    default:
                        this.Logger?.LogMessage($"{{warn}}Failed to leave game: {ex.Message}");
                        ResetState();
                        throw;
                    }
                }
                catch (WebException ex)
                {
                    this.Logger?.LogMessage($"{{warn}}Failed to leave game: {ex.Message} - Giving it a few seconds ({i + 1}/5)...");
                    await Task.Delay(2000);

                    continue;
                }
            }

            // States, only set when failed
            ResetState();
            void ResetState()
            {
                this.State = BotState.Invalid; // Just reset
            }
        }
コード例 #26
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task <List <Planet> > FindMostWantedPlanets()
        {
            var mostWantedPlanets = new List <Planet>();
            var activePlanets     = (await SaliensApi.GetPlanetsWithZonesAsync(true)).Values;

            // Overridden planet
            if (!string.IsNullOrWhiteSpace(this.OverridePlanetId))
            {
                try
                {
                    var planet = await SaliensApi.GetPlanetAsync(this.OverridePlanetId);

                    if (planet.State.Running)
                    {
                        mostWantedPlanets.Add(planet);
                    }
                }
                catch (SaliensApiException ex)
                {
                    switch (ex.EResult)
                    {
                    case EResult.InvalidParam:
                    case EResult.Expired:
                    case EResult.NoMatch:
                    case EResult.ValueOutOfRange:
                        Program.Settings.OverridePlanetId.Value = null;
                        break;

                    default:
                        throw;
                    }
                }
            }

            // Force current joined planet if FocusCurrentPlanet is selected
            if (this.Strategy.HasFlag(BotStrategy.FocusCurrentPlanet) && this.HasActivePlanet)
            {
                var planet = await SaliensApi.GetPlanetAsync(this.ActivePlanet.Id);

                if (planet.State.Running)
                {
                    mostWantedPlanets.Add(planet);
                }
            }

            if (this.Strategy.HasFlag(BotStrategy.FocusRandomPlanet))
            {
                mostWantedPlanets.AddRange(activePlanets
                                           .Where(p => !mostWantedPlanets.Any(mp => mp.Id == p.Id))
                                           .ToList()
                                           .Shuffle());
            }
            else
            {
                // As of 26th June, the planet difficulty is always low, so let's skip it for now
                var planets = activePlanets.OrderBy(p => 0);

                if (this.Strategy.HasFlag(BotStrategy.FocusBosses))
                {
                    planets = planets.ThenByDescending(p => p.Zones.Any(z => z.BossActive) ? 1 : 0);
                }
                if (this.Strategy.HasFlag(BotStrategy.MostDifficultPlanetsFirst))
                {
                    planets = planets
                              //.ThenByDescending(p => (int)p.State.Difficulty)
                              .ThenByDescending(p => p.MaxFreeZonesDifficulty)
                              .ThenByDescending(p => p.WeightedAverageFreeZonesDifficulty);
                }
                else if (this.Strategy.HasFlag(BotStrategy.LeastDifficultPlanetsFirst))
                {
                    planets = planets
                              //.ThenBy(p => (int)p.State.Difficulty)
                              .ThenBy(p => p.MaxFreeZonesDifficulty)
                              .ThenBy(p => p.WeightedAverageFreeZonesDifficulty);
                }
                if (this.Strategy.HasFlag(BotStrategy.MostCompletedPlanetsFirst))
                {
                    planets = planets.ThenByDescending(p => p.State.CaptureProgress);
                }
                else if (this.Strategy.HasFlag(BotStrategy.LeastCompletedPlanetsFirst))
                {
                    planets = planets.ThenBy(p => p.State.CaptureProgress);
                }

                if (this.Strategy.HasFlag(BotStrategy.TopDown))
                {
                    planets = planets.ThenBy(p => p.Id);
                }
                else if (this.Strategy.HasFlag(BotStrategy.BottomUp))
                {
                    planets = planets.ThenByDescending(p => p.Id);
                }

                mostWantedPlanets.AddRange(planets);
            }

            // Filter out blacklisted games
            return(mostWantedPlanets
                   .Where(p => !(this.BlacklistedGames.ContainsKey(p.Id) && this.BlacklistedGames[p.Id] > DateTime.Now))
                   .ToList());
        }
コード例 #27
0
ファイル: SaliensBot.cs プロジェクト: Archomeda/AutoSaliens
        private async Task Loop()
        {
            this.BotActivated?.Invoke(this, null);
            while (!this.cancelSource.Token.IsCancellationRequested)
            {
                try
                {
                    this.Logger?.LogMessage($"{{verb}}State: {this.State}");
                    switch (this.State)
                    {
                    case BotState.Idle:
                        await this.DoIdle();

                        break;

                    case BotState.Resume:
                        await this.DoResume();

                        break;

                    case BotState.OnPlanet:
                        await this.DoOnPlanet();

                        break;

                    case BotState.InZone:
                        await this.DoInZone();

                        break;

                    case BotState.InZoneEnd:
                        await this.DoInZoneEnd();

                        break;

                    case BotState.InBossZone:
                        await this.DoInBossZone();

                        break;

                    case BotState.ForcedZoneLeave:
                        await this.DoForcedZoneLeave();

                        break;

                    case BotState.Invalid:
                    default:
                        await this.DoInvalid();

                        break;
                    }
                }
                catch (OperationCanceledException) { }
                catch (SaliensApiException ex)
                {
                    // Update states
                    this.Logger?.LogMessage($"{{action}}Updating states...");
                    await this.UpdatePlayerInfo(TimeSpan.FromSeconds(5));

                    await SaliensApi.GetPlanetsWithZonesAsync(true, TimeSpan.FromSeconds(5));

                    switch (ex.EResult)
                    {
                    case EResult.Expired:
                    case EResult.NoMatch:
                        if (this.State == BotState.InZone || this.State == BotState.InZoneEnd)
                        {
                            this.State = BotState.ForcedZoneLeave;
                        }
                        break;

                    case EResult.InvalidState:
                    default:
                        this.State = BotState.Invalid;
                        break;
                    }
                }
                catch (Exception ex)
                {
                    this.Logger?.LogException(ex);
                    this.State = BotState.Invalid;
                }
            }
            this.BotDeactivated?.Invoke(this, null);
        }