diff --git a/POGOLib/Configuration.cs b/POGOLib/Configuration.cs deleted file mode 100644 index f926d2b..0000000 --- a/POGOLib/Configuration.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace POGOLib -{ - public static class Configuration - { - /// - /// Gets or sets the in milliseconds for when StatusCode 52 is received from PokémonGo. - /// - public static int RateLimitTimeout { get; set; } = 30000; - } -} \ No newline at end of file diff --git a/POGOLib/Constants.cs b/POGOLib/Constants.cs deleted file mode 100644 index dca164b..0000000 --- a/POGOLib/Constants.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace POGOLib -{ - internal static class Constants - { - public const string ApiUrl = "https://pgorelease.nianticlabs.com/plfe/rpc"; - public const string ApiUserAgent = "Dalvik/2.1.0 (Linux; U; Android 5.0; Nexus 5 Build/LPX13D)"; - - public const string LoginUrl = - "https://sso.pokemon.com/sso/login?service=https%3A%2F%2Fsso.pokemon.com%2Fsso%2Foauth2.0%2FcallbackAuthorize"; - - public const string LoginUserAgent = "Niantic App"; - public const string LoginOauthUrl = "https://sso.pokemon.com/sso/oauth2.0/accessToken"; - - public const string GoogleAuthService = - "audience:server:client_id:848232511240-7so421jotr2609rmqakceuu1luuq0ptb.apps.googleusercontent.com"; - - public const string GoogleAuthApp = "com.nianticlabs.pokemongo"; - public const string GoogleAuthClientSig = "321187995bc7cdc2b5fc91b11a96e2baa8602c62"; - } -} \ No newline at end of file diff --git a/POGOLib/GlobalSuppressions.cs b/POGOLib/GlobalSuppressions.cs deleted file mode 100644 index 8359220..0000000 Binary files a/POGOLib/GlobalSuppressions.cs and /dev/null differ diff --git a/POGOLib/Net/Authentication/Data/AccessToken.cs b/POGOLib/Net/Authentication/Data/AccessToken.cs deleted file mode 100644 index 0210e33..0000000 --- a/POGOLib/Net/Authentication/Data/AccessToken.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Newtonsoft.Json; -using POGOLib.Pokemon.Data; -using POGOProtos.Networking.Envelopes; - -namespace POGOLib.Net.Authentication.Data -{ - public class AccessToken - { - [JsonIgnore] - public string Uid => $"{Username}-{LoginProvider}"; - - [JsonProperty("username", Required = Required.Always)] - public string Username { get; internal set; } - - [JsonProperty("token", Required = Required.Always)] - public string Token { get; internal set; } - - [JsonProperty("expiry", Required = Required.Always)] - public DateTime Expiry { get; internal set; } - - [JsonProperty("login_provider", Required = Required.Always)] - public LoginProvider LoginProvider { get; internal set; } - - [JsonIgnore] - public bool IsExpired => DateTime.UtcNow > Expiry; - - [JsonIgnore] - public AuthTicket AuthTicket { get; internal set; } - - public void Expire() - { - Expiry = DateTime.UtcNow; - AuthTicket = null; - } - } -} \ No newline at end of file diff --git a/POGOLib/Net/Authentication/Data/LoginData.cs b/POGOLib/Net/Authentication/Data/LoginData.cs deleted file mode 100644 index 84730d6..0000000 --- a/POGOLib/Net/Authentication/Data/LoginData.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace POGOLib.Net.Authentication.Data -{ - internal struct LoginData - { - [JsonProperty("lt", Required = Required.Always)] - public string Lt { get; set; } - - [JsonProperty("execution", Required = Required.Always)] - public string Execution { get; set; } - } -} \ No newline at end of file diff --git a/POGOLib/Net/Authentication/Login.cs b/POGOLib/Net/Authentication/Login.cs deleted file mode 100644 index 6e9abfb..0000000 --- a/POGOLib/Net/Authentication/Login.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Text.RegularExpressions; -using DankMemes.GPSOAuthSharp; -using GeoCoordinatePortable; -using log4net; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using POGOLib.Net.Authentication.Data; -using POGOLib.Pokemon.Data; -using POGOLib.Util; - -namespace POGOLib.Net.Authentication -{ - /// - /// Responsible for Authenticating and Re-authenticating the user. - /// - public static class Login - { - private static readonly ILog Log = LogManager.GetLogger(typeof (Login)); - - /// - /// Login with a stored . - /// - /// - /// The password is needed for reauthentication. - /// The initial latitude you will spawn at after logging into PokémonGo. - /// The initial longitude you will spawn at after logging into PokémonGo. - /// - public static Session GetSession(AccessToken accessToken, string password, double initialLatitude, - double initialLongitude) - { - if (accessToken.IsExpired) - { - throw new Exception("AccessToken is expired."); - } - Log.Debug("Authenticated from cache."); - return new Session(accessToken, password, new GeoCoordinate(initialLatitude, initialLongitude)); - } - - /// - /// Login through OAuth with PTC / Google. - /// - /// Your username. - /// Your password. - /// The OAuth provider you use to authenticate. - /// The initial latitude you will spawn at after logging into PokémonGo. - /// The initial longitude you will spawn at after logging into PokémonGo. - /// - public static Session GetSession(string username, string password, LoginProvider loginProvider, - double initialLatitude, double initialLongitude) - { - AccessToken accessToken; - - switch (loginProvider) - { - case LoginProvider.GoogleAuth: - accessToken = WithGoogle(username, password); - break; - case LoginProvider.PokemonTrainerClub: - accessToken = WithPokemonTrainerClub(username, password); - break; - default: - throw new ArgumentOutOfRangeException(nameof(loginProvider), loginProvider, null); - } - - return new Session(accessToken, password, new GeoCoordinate(initialLatitude, initialLongitude)); - } - - /// Authenticate the user through Google. - internal static AccessToken WithGoogle(string email, string password) - { - var googleClient = new GPSOAuthClient(email, password); - var masterLoginResponse = googleClient.PerformMasterLogin(); - - if (masterLoginResponse.ContainsKey("Error")) - { - throw new Exception($"Google returned an error message: '{masterLoginResponse["Error"]}'"); - } - if (!masterLoginResponse.ContainsKey("Token")) - { - throw new Exception("Token was missing from master login response."); - } - var oauthResponse = googleClient.PerformOAuth(masterLoginResponse["Token"], Constants.GoogleAuthService, - Constants.GoogleAuthApp, Constants.GoogleAuthClientSig); - if (!oauthResponse.ContainsKey("Auth")) - { - throw new Exception("Auth token was missing from oauth login response."); - } - Log.Debug("Authenticated through Google."); - return new AccessToken - { - Username = email, - Token = oauthResponse["Auth"], - Expiry = TimeUtil.GetDateTimeFromSeconds(int.Parse(oauthResponse["Expiry"])), - LoginProvider = LoginProvider.GoogleAuth - }; - } - - /// Authenticate the user through PTC. - internal static AccessToken WithPokemonTrainerClub(string username, string password) - { - using (var httpClientHandler = new HttpClientHandler()) - { - httpClientHandler.AllowAutoRedirect = false; - using (var httpClient = new HttpClient(httpClientHandler)) - { - httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(Constants.LoginUserAgent); - var loginData = GetLoginData(httpClient); - var ticket = PostLogin(httpClient, username, password, loginData); - var accessToken = PostLoginOauth(httpClient, ticket); - accessToken.Username = username; - Log.Debug("Authenticated through PTC."); - return accessToken; - } - } - } - - /// - /// Responsible for retrieving login parameters for . - /// - /// An initialized - /// for . - private static LoginData GetLoginData(HttpClient httpClient) - { - var loginDataResponse = httpClient.GetAsync(Constants.LoginUrl).Result; - var loginData = - JsonConvert.DeserializeObject(loginDataResponse.Content.ReadAsStringAsync().Result); - return loginData; - } - - /// - /// Responsible for submitting the login request. - /// - /// - /// The user's PTC username. - /// The user's PTC password. - /// taken from PTC website using . - /// - private static string PostLogin(HttpClient httpClient, string username, string password, LoginData loginData) - { - var loginResponse = - httpClient.PostAsync(Constants.LoginUrl, new FormUrlEncodedContent(new Dictionary - { - {"lt", loginData.Lt}, - {"execution", loginData.Execution}, - {"_eventId", "submit"}, - {"username", username}, - {"password", password} - })).Result; - - var loginResponseDataRaw = loginResponse.Content.ReadAsStringAsync().Result; - if (!loginResponseDataRaw.Contains("{")) - { - var locationQuery = loginResponse.Headers.Location.Query; - var ticketStartPosition = locationQuery.IndexOf("=", StringComparison.Ordinal) + 1; - return locationQuery.Substring(ticketStartPosition, locationQuery.Length - ticketStartPosition); - } - - var loginResponseData = JObject.Parse(loginResponseDataRaw); - var loginResponseErrors = (JArray) loginResponseData["errors"]; - - throw new Exception($"Pokemon Trainer Club gave error(s): '{string.Join(",", loginResponseErrors)}'"); - } - - /// - /// Responsible for finishing the oauth login request. - /// - /// - /// - /// - private static AccessToken PostLoginOauth(HttpClient httpClient, string ticket) - { - var loginResponse = - httpClient.PostAsync(Constants.LoginOauthUrl, new FormUrlEncodedContent(new Dictionary - { - {"client_id", "mobile-app_pokemon-go"}, - {"redirect_uri", "https://www.nianticlabs.com/pokemongo/error"}, - {"client_secret", "w8ScCUXJQc6kXKw8FiOhd8Fixzht18Dq3PEVkUCP5ZPxtgyWsbTvWHFLm2wNY0JR"}, - {"grant_type", "refresh_token"}, - {"code", ticket} - })).Result; - - var loginResponseDataRaw = loginResponse.Content.ReadAsStringAsync().Result; - - var oAuthData = Regex.Match(loginResponseDataRaw, - "access_token=(?.*?)&expires=(?\\d+)"); - if (!oAuthData.Success) - { - throw new Exception($"Couldn't verify the OAuth login response data '{loginResponseDataRaw}'."); - } - return new AccessToken - { - Token = oAuthData.Groups["accessToken"].Value, - Expiry = DateTime.UtcNow.AddSeconds(int.Parse(oAuthData.Groups["expires"].Value)), - LoginProvider = LoginProvider.PokemonTrainerClub - }; - } - } -} \ No newline at end of file diff --git a/POGOLib/Net/RpcClient.cs b/POGOLib/Net/RpcClient.cs deleted file mode 100644 index 174dc7c..0000000 --- a/POGOLib/Net/RpcClient.cs +++ /dev/null @@ -1,545 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text.RegularExpressions; -using System.Threading; -using GeoCoordinatePortable; -using Google.Protobuf; -using Google.Protobuf.Collections; -using log4net; -using POGOLib.Pokemon; -using POGOLib.Pokemon.Data; -using POGOLib.Util; -using POGOProtos.Enums; -using POGOProtos.Map; -using POGOProtos.Networking.Envelopes; -using POGOProtos.Networking.Requests; -using POGOProtos.Networking.Requests.Messages; -using POGOProtos.Networking.Responses; - -namespace POGOLib.Net -{ - public class RpcClient : IDisposable - { - private static readonly ILog Log = LogManager.GetLogger(typeof (RpcClient)); - - /// - /// The used for communication with PokémonGo. - /// - private readonly HttpClient _httpClient; - - /// - /// The authenticated . - /// - private readonly Session _session; - - /// - /// The current 'unique' request id we are at. - /// - private ulong _requestId; - - /// - /// The rpc url we have to call. - /// - private string _requestUrl; - - internal RpcClient(Session session) - { - _session = session; - - var httpClientHandler = new HttpClientHandler - { - AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate - }; - - _httpClient = new HttpClient(httpClientHandler); - _httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(Constants.ApiUserAgent); - _httpClient.DefaultRequestHeaders.ExpectContinue = false; - _requestId = (ulong) new Random().Next(100000000, 999999999); - } - - internal DateTime LastRpcRequest { get; private set; } - - internal DateTime LastRpcMapObjectsRequest { get; private set; } - - internal GeoCoordinate LastGeoCoordinateMapObjectsRequest { get; private set; } = new GeoCoordinate(); - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Sends all requests which the (android-)client sends on startup - /// - internal bool Startup() - { - try - { - // Send GetPlayer to check if we're connected and authenticated - GetPlayerResponse playerResponse; - do - { - var response = SendRemoteProcedureCall(new Request - { - RequestType = RequestType.GetPlayer - }); - playerResponse = GetPlayerResponse.Parser.ParseFrom(response); - if (!playerResponse.Success) - { - Thread.Sleep(1000); - } - } while (!playerResponse.Success); - - _session.Player.Data = playerResponse.PlayerData; - - // Get DownloadRemoteConfig - var remoteConfigResponse = SendRemoteProcedureCall(new Request - { - RequestType = RequestType.DownloadRemoteConfigVersion, - RequestMessage = new DownloadRemoteConfigVersionMessage - { - Platform = Platform.Android, - AppVersion = 2903 - }.ToByteString() - }); - var remoteConfigParsed = DownloadRemoteConfigVersionResponse.Parser.ParseFrom(remoteConfigResponse); - - var timestamp = (ulong) TimeUtil.GetCurrentTimestampInMilliseconds(); - if (_session.Templates.AssetDigests == null || remoteConfigParsed.AssetDigestTimestampMs > timestamp) - { - // GetAssetDigest - var assetDigestResponse = SendRemoteProcedureCall(new Request - { - RequestType = RequestType.GetAssetDigest, - RequestMessage = new GetAssetDigestMessage - { - Platform = Platform.Android, - AppVersion = 2903 - }.ToByteString() - }); - _session.Templates.SetAssetDigests(GetAssetDigestResponse.Parser.ParseFrom(assetDigestResponse)); - } - - if (_session.Templates.ItemTemplates == null || remoteConfigParsed.ItemTemplatesTimestampMs > timestamp) - { - // DownloadItemTemplates - var itemTemplateResponse = SendRemoteProcedureCall(new Request - { - RequestType = RequestType.DownloadItemTemplates - }); - _session.Templates.SetItemTemplates( - DownloadItemTemplatesResponse.Parser.ParseFrom(itemTemplateResponse)); - } - } - catch (Exception) - { - return false; - } - - return true; - } - - /// - /// It is not recommended to call this. Map objects will update automatically and fire the - /// event. - /// - public void RefreshMapObjects() - { - var cellIds = MapUtil.GetCellIdsForLatLong(_session.Player.Coordinate.Latitude, - _session.Player.Coordinate.Longitude); - var sinceTimeMs = new List(cellIds.Length); - - for (var i = 0; i < cellIds.Length; i++) - { - sinceTimeMs.Add(0); - } - - var response = SendRemoteProcedureCall(new Request - { - RequestType = RequestType.GetMapObjects, - RequestMessage = new GetMapObjectsMessage - { - CellId = - { - cellIds - }, - SinceTimestampMs = - { - sinceTimeMs.ToArray() - }, - Latitude = _session.Player.Coordinate.Latitude, - Longitude = _session.Player.Coordinate.Longitude - }.ToByteString() - }); - - var mapObjects = GetMapObjectsResponse.Parser.ParseFrom(response); - - if (mapObjects.Status == MapObjectsStatus.Success) - { - Log.Debug($"Received '{mapObjects.MapCells.Count}' map cells."); - if (mapObjects.MapCells.Count == 0) - { - Log.Error("We received 0 map cells, are your GPS coordinates correct?"); - return; - } - _session.Map.Cells = mapObjects.MapCells; - } - else - { - Log.Error($"GetMapObjects status is: '{mapObjects.Status}'."); - } - } - - /// - /// Gets the next for the . - /// - /// - private ulong GetNextRequestId() - { - return _requestId++; - } - - /// - /// Gets a collection of requests that should be sent in every request to PokémonGo along with your own - /// . - /// - /// - private IEnumerable GetDefaultRequests() - { - var request = new List - { - new Request - { - RequestType = RequestType.GetHatchedEggs - }, - new Request - { - RequestType = RequestType.GetInventory, - RequestMessage = new GetInventoryMessage - { - LastTimestampMs = _session.Player.Inventory.LastInventoryTimestampMs - }.ToByteString() - }, - new Request - { - RequestType = RequestType.CheckAwardedBadges - } - }; - - if (string.IsNullOrEmpty(_session.GlobalSettingsHash)) - { - request.Add(new Request - { - RequestType = RequestType.DownloadSettings - }); - } - else - { - request.Add(new Request - { - RequestType = RequestType.DownloadSettings, - RequestMessage = new DownloadSettingsMessage - { - Hash = _session.GlobalSettingsHash - }.ToByteString() - }); - } - - - //If Incense is active we add this: - //request.Add(new Request - //{ - // RequestType = RequestType.GetIncensePokemon, - // RequestMessage = new GetIncensePokemonMessage - // { - // PlayerLatitude = _session.Player.Coordinate.Latitude, - // PlayerLongitude = _session.Player.Coordinate.Longitude - // }.ToByteString() - //}); - - return request; - } - - /// - /// Gets a with the default requests and authentication data. - /// - /// - /// - private RequestEnvelope GetRequestEnvelope(Request request) - { - var requestEnvelope = new RequestEnvelope - { - StatusCode = 2, - RequestId = GetNextRequestId(), - Latitude = _session.Player.Coordinate.Latitude, - Longitude = _session.Player.Coordinate.Longitude, - Altitude = _session.Player.Coordinate.Altitude, - Unknown12 = 123, // TODO: Figure this out. - Requests = {GetDefaultRequests()} - }; - - if (_session.AccessToken.AuthTicket == null || _session.AccessToken.IsExpired) - { - if (_session.AccessToken.IsExpired) - { - _session.Reauthenticate(); - } - requestEnvelope.AuthInfo = new RequestEnvelope.Types.AuthInfo - { - Provider = _session.AccessToken.LoginProvider == LoginProvider.PokemonTrainerClub ? "ptc" : "google", - Token = new RequestEnvelope.Types.AuthInfo.Types.JWT - { - Contents = _session.AccessToken.Token, - Unknown2 = 59 - } - }; - } - else - { - requestEnvelope.AuthTicket = _session.AccessToken.AuthTicket; - } - - requestEnvelope.Requests.Insert(0, request); - - return requestEnvelope; - } - - /// - /// Prepares the to be sent with . - /// - /// The that will be send. - /// to be sent with . - private ByteArrayContent PrepareRequestEnvelope(RequestEnvelope requestEnvelope) - { - var messageBytes = requestEnvelope.ToByteArray(); - - // TODO: Compression? - - return new ByteArrayContent(messageBytes); - } - - public ByteString SendRemoteProcedureCall(RequestType requestType) - { - return SendRemoteProcedureCall(new Request - { - RequestType = requestType - }); - } - - public ByteString SendRemoteProcedureCall(Request request) - { - var requestEnvelope = GetRequestEnvelope(request); - - using (var requestData = PrepareRequestEnvelope(requestEnvelope)) - { - using (var response = _httpClient.PostAsync(_requestUrl ?? Constants.ApiUrl, requestData).Result) - { - if (!response.IsSuccessStatusCode) - { - Log.Debug(response.Content.ReadAsStringAsync().Result); - throw new Exception( - "Received a non-success HTTP status code from the RPC server, see the console for the response."); - } - - var responseBytes = response.Content.ReadAsByteArrayAsync().Result; - var responseEnvelope = ResponseEnvelope.Parser.ParseFrom(responseBytes); - - switch (responseEnvelope.StatusCode) - { - case 52: // Rate limit? - Log.Info( - $"We are sending requests too fast, sleeping for {Configuration.RateLimitTimeout} milliseconds."); - Thread.Sleep(Configuration.RateLimitTimeout); - return SendRemoteProcedureCall(request); - - case 53: // New RPC url - if (Regex.IsMatch(responseEnvelope.ApiUrl, "pgorelease\\.nianticlabs\\.com\\/plfe\\/\\d+")) - { - _requestUrl = $"https://{responseEnvelope.ApiUrl}/rpc"; - return SendRemoteProcedureCall(request); - } - throw new Exception( - $"Received an incorrect API url: '{responseEnvelope.ApiUrl}', status code was: '{responseEnvelope.StatusCode}'."); - - case 102: // Invalid auth - Log.Debug("Received StatusCode 102, reauthenticating."); - _session.AccessToken.Expire(); - _session.Reauthenticate(); - return SendRemoteProcedureCall(request); - - default: - Log.Info($"Unknown status code: {responseEnvelope.StatusCode}"); - break; - } - - LastRpcRequest = DateTime.UtcNow; - Log.Debug($"Sent RPC Request: '{request.RequestType}'"); - if (request.RequestType == RequestType.GetMapObjects) - { - LastRpcMapObjectsRequest = LastRpcRequest; - LastGeoCoordinateMapObjectsRequest = _session.Player.Coordinate; - } - if (responseEnvelope.AuthTicket != null) - { - _session.AccessToken.AuthTicket = responseEnvelope.AuthTicket; - Log.Debug("Received a new AuthTicket from Pokémon!"); - } - return HandleResponseEnvelope(request, responseEnvelope); - } - } - } - - /// - /// Responsible for handling the received . - /// - /// - /// - /// The received from - /// . - /// - /// Returns the response of the . - private ByteString HandleResponseEnvelope(Request request, ResponseEnvelope responseEnvelope) - { - if (responseEnvelope.Returns.Count != 5) - { - throw new Exception($"There were only {responseEnvelope.Returns.Count} responses, we expected 5."); - } - - // Take requested response and remove from returns. - var requestResponse = responseEnvelope.Returns[0]; - responseEnvelope.Returns.RemoveAt(0); - - // Handle the default responses. - HandleDefaultResponses(responseEnvelope.Returns); - - // Handle responses which affect the inventory - HandleInventoryResponses(request, requestResponse); - - return requestResponse; - } - - private void HandleInventoryResponses(Request request, ByteString requestResponse) - { - ulong pokemonId = 0; - switch (request.RequestType) - { - case RequestType.ReleasePokemon: - var releaseResponse = ReleasePokemonResponse.Parser.ParseFrom(requestResponse); - if (releaseResponse.Result == ReleasePokemonResponse.Types.Result.Success || - releaseResponse.Result == ReleasePokemonResponse.Types.Result.Failed) - { - var releaseMessage = ReleasePokemonMessage.Parser.ParseFrom(request.RequestMessage); - pokemonId = releaseMessage.PokemonId; - } - break; - - case RequestType.EvolvePokemon: - var evolveResponse = EvolvePokemonResponse.Parser.ParseFrom(requestResponse); - if (evolveResponse.Result == EvolvePokemonResponse.Types.Result.Success || - evolveResponse.Result == EvolvePokemonResponse.Types.Result.FailedPokemonMissing) - { - var releaseMessage = ReleasePokemonMessage.Parser.ParseFrom(request.RequestMessage); - pokemonId = releaseMessage.PokemonId; - } - break; - } - if (pokemonId > 0) - { - var pokemons = _session.Player.Inventory.InventoryItems.Where( - i => - i?.InventoryItemData?.PokemonData != null && - i.InventoryItemData.PokemonData.Id.Equals(pokemonId)); - _session.Player.Inventory.RemoveInventoryItems(pokemons); - } - } - - /// - /// Handles the default heartbeat responses. - /// - /// The payload of the . - private void HandleDefaultResponses(RepeatedField returns) - { - var responseCount = 0; - foreach (var bytes in returns) - { - switch (responseCount) - { - case 0: // Get_Hatched_Eggs - var hatchedEggs = GetHatchedEggsResponse.Parser.ParseFrom(bytes); - if (hatchedEggs.Success) - { - // TODO: Throw event, wrap in an object. - } - break; - - case 1: // Get_Inventory - var inventory = GetInventoryResponse.Parser.ParseFrom(bytes); - if (inventory.Success) - { - if (inventory.InventoryDelta.NewTimestampMs >= - _session.Player.Inventory.LastInventoryTimestampMs) - { - _session.Player.Inventory.LastInventoryTimestampMs = - inventory.InventoryDelta.NewTimestampMs; - if (inventory.InventoryDelta != null && - inventory.InventoryDelta.InventoryItems.Count > 0) - { - _session.Player.Inventory.UpdateInventoryItems(inventory.InventoryDelta); - } - } - } - break; - - case 2: // Check_Awarded_Badges - var awardedBadges = CheckAwardedBadgesResponse.Parser.ParseFrom(bytes); - if (awardedBadges.Success) - { - // TODO: Throw event, wrap in an object. - } - break; - - case 3: // Download_Settings - var downloadSettings = DownloadSettingsResponse.Parser.ParseFrom(bytes); - if (string.IsNullOrEmpty(downloadSettings.Error)) - { - if (downloadSettings.Settings == null) - { - continue; - } - if (_session.GlobalSettings == null || _session.GlobalSettingsHash != downloadSettings.Hash) - { - _session.GlobalSettingsHash = downloadSettings.Hash; - _session.GlobalSettings = downloadSettings.Settings; - } - else - { - _session.GlobalSettings = downloadSettings.Settings; - } - } - else - { - Log.Debug($"DownloadSettingsResponse.Error: '{downloadSettings.Error}'"); - } - break; - - default: - throw new Exception($"Unknown response appeared..? {responseCount}"); - } - - responseCount++; - } - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _httpClient?.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/POGOLib/Net/Session.cs b/POGOLib/Net/Session.cs deleted file mode 100644 index b18532d..0000000 --- a/POGOLib/Net/Session.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Threading; -using GeoCoordinatePortable; -using log4net; -using POGOLib.Net.Authentication; -using POGOLib.Net.Authentication.Data; -using POGOLib.Pokemon; -using POGOLib.Pokemon.Data; -using POGOProtos.Settings; - -namespace POGOLib.Net -{ - /// - /// This is an authenticated with PokémonGo that handles everything between the developer and - /// PokémonGo. - /// - public class Session : IDisposable - { - private static readonly ILog Log = LogManager.GetLogger(typeof (Session)); - - /// - /// This is the which is responsible for retrieving events and updating gps - /// location. - /// - private readonly HeartbeatDispatcher _heartbeat; - - /// - /// This is the which is responsible for all communication between us and PokémonGo. - /// Only use this if you know what you are doing. - /// - public readonly RpcClient RpcClient; - - internal Session(AccessToken accessToken, string password, GeoCoordinate geoCoordinate) - { - AccessToken = accessToken; - Password = password; - Player = new Player(geoCoordinate); - Map = new Map(); - Templates = new Templates(); - RpcClient = new RpcClient(this); - _heartbeat = new HeartbeatDispatcher(this); - } - - public Templates Templates { get; } - - /// - /// Gets the of the . - /// - public AccessToken AccessToken { get; private set; } - - /// - /// Gets the of the . - /// - internal string Password { get; } - - /// - /// Gets the of the . - /// - public Player Player { get; private set; } - - /// - /// Gets the of the . - /// - public Map Map { get; } - - /// - /// Gets the of the . - /// - public GlobalSettings GlobalSettings { get; internal set; } - - /// - /// Gets the hash of the . - /// - internal string GlobalSettingsHash { get; set; } = string.Empty; - - private Mutex ReauthenticateMutex { get; } = new Mutex(); - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public bool Startup() - { - if (!RpcClient.Startup()) - { - return false; - } - _heartbeat.StartDispatcher(); - return true; - } - - public void Shutdown() - { - _heartbeat.StopDispatcher(); - } - - /// - /// Ensures the gets reauthenticated, no matter how long it takes. - /// - internal void Reauthenticate() - { - ReauthenticateMutex.WaitOne(); - if (AccessToken.IsExpired) - { - AccessToken accessToken = null; - var tries = 0; - while (accessToken == null) - { - try - { - switch (AccessToken.LoginProvider) - { - case LoginProvider.PokemonTrainerClub: - accessToken = Login.WithPokemonTrainerClub(AccessToken.Username, Password); - break; - case LoginProvider.GoogleAuth: - accessToken = Login.WithGoogle(AccessToken.Username, Password); - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - catch (Exception exception) - { - Log.Error("Reauthenticate exception was catched: ", exception); - } - finally - { - if (accessToken == null) - { - var sleepSeconds = Math.Min(60, ++tries*5); - Log.Error($"Reauthentication failed, trying again in {sleepSeconds} seconds."); - Thread.Sleep(sleepSeconds*1000); - } - } - } - AccessToken = accessToken; - OnAccessTokenUpdated(); - } - ReauthenticateMutex.ReleaseMutex(); - } - - private void OnAccessTokenUpdated() - { - AccessTokenUpdated?.Invoke(this, EventArgs.Empty); - } - - public event EventHandler AccessTokenUpdated; - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - ReauthenticateMutex?.Dispose(); - RpcClient?.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/POGOLib/POGOLib.csproj b/POGOLib/POGOLib.csproj deleted file mode 100644 index fa04ab3..0000000 --- a/POGOLib/POGOLib.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - Debug - AnyCPU - {3BA89DFB-A162-420A-9DED-DAA211E52AD2} - Library - Properties - POGOLib - POGOLib - v4.5 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\GeoCoordinate.1.1.0\lib\portable-net45+wp80+win+wpa81\GeoCoordinatePortable.dll - True - - - ..\packages\Google.Protobuf.3.0.0-beta4\lib\net45\Google.Protobuf.dll - True - - - ..\packages\GPSOAuthSharp.0.0.5\lib\GPSOAuthSharp.dll - True - - - ..\packages\log4net.2.0.5\lib\net45-full\log4net.dll - True - - - ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - True - - - ..\packages\POGOProtos.1.4.0\lib\net45\POGOProtos.dll - True - - - ..\packages\S2Geometry.1.0.3\lib\portable-net45+wp8+win8\S2Geometry.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - - - - \ No newline at end of file diff --git a/POGOLib/Pokemon/Data/LoginProvider.cs b/POGOLib/Pokemon/Data/LoginProvider.cs deleted file mode 100644 index 5b7bc88..0000000 --- a/POGOLib/Pokemon/Data/LoginProvider.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace POGOLib.Pokemon.Data -{ - public enum LoginProvider - { - PokemonTrainerClub, - GoogleAuth - } -} \ No newline at end of file diff --git a/POGOLib/Pokemon/HeartbeatDispatcher.cs b/POGOLib/Pokemon/HeartbeatDispatcher.cs deleted file mode 100644 index e6fc71c..0000000 --- a/POGOLib/Pokemon/HeartbeatDispatcher.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Threading; -using log4net; -using POGOLib.Net; - -namespace POGOLib.Pokemon -{ - internal class HeartbeatDispatcher - { - private static readonly ILog Log = LogManager.GetLogger(typeof (HeartbeatDispatcher)); - - /// - /// The authenticated . - /// - private readonly Session _session; - - /// - /// Determines whether we can keep heartbeating. - /// - private bool _keepHeartbeating = true; - - internal HeartbeatDispatcher(Session session) - { - _session = session; - } - - /// - /// Checks every second if we need to update. - /// - private void CheckDispatch() - { - while (_keepHeartbeating) - { - var canRefresh = false; - if (_session.GlobalSettings != null) - { - var minSeconds = _session.GlobalSettings.MapSettings.GetMapObjectsMinRefreshSeconds; - var maxSeconds = _session.GlobalSettings.MapSettings.GetMapObjectsMaxRefreshSeconds; - var minDistance = _session.GlobalSettings.MapSettings.GetMapObjectsMinDistanceMeters; - var lastGeoCoordinate = _session.RpcClient.LastGeoCoordinateMapObjectsRequest; - var secondsSinceLast = DateTime.UtcNow.Subtract(_session.RpcClient.LastRpcRequest).Seconds; - - if (lastGeoCoordinate.IsUnknown) - { - Log.Debug("Refreshing MapObjects, reason: 'lastGeoCoordinate.IsUnknown'."); - canRefresh = true; - } - else if (secondsSinceLast >= minSeconds) - { - var metersMoved = _session.Player.Coordinate.GetDistanceTo(lastGeoCoordinate); - if (secondsSinceLast >= maxSeconds) - { - Log.Debug("Refreshing MapObjects, reason: 'secondsSinceLast >= maxSeconds'."); - canRefresh = true; - } - else if (metersMoved >= minDistance) - { - Log.Debug("Refreshing MapObjects, reason: 'metersMoved >= minDistance'."); - canRefresh = true; - } - } - } - else - { - canRefresh = true; - } - if (canRefresh) - { - Dispatch(); - } - Thread.Sleep(1000); - } - } - - internal void StartDispatcher() - { - _keepHeartbeating = true; - new Thread(CheckDispatch) - { - IsBackground = true - }.Start(); - } - - internal void StopDispatcher() - { - _keepHeartbeating = false; - } - - private void Dispatch() - { - _session.RpcClient.RefreshMapObjects(); - } - } -} \ No newline at end of file diff --git a/POGOLib/Pokemon/Inventory.cs b/POGOLib/Pokemon/Inventory.cs deleted file mode 100644 index 3f820f8..0000000 --- a/POGOLib/Pokemon/Inventory.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Google.Protobuf.Collections; -using POGOProtos.Inventory; - -namespace POGOLib.Pokemon -{ - /// - /// A wrapper class for . - /// - public class Inventory - { - internal long LastInventoryTimestampMs; - - /// - /// Gets the last received from PokémonGo.
- /// Only use this if you know what you are doing. - ///
- public RepeatedField InventoryItems { get; } = new RepeatedField(); - - internal void RemoveInventoryItems(IEnumerable items) - { - foreach (var item in items) - { - InventoryItems.Remove(item); - } - Update?.Invoke(this, EventArgs.Empty); - } - - internal void UpdateInventoryItems(InventoryDelta delta) - { - if (delta?.InventoryItems == null || delta.InventoryItems.All(i => i == null)) - { - return; - } - InventoryItems.AddRange(delta.InventoryItems.Where(i => i != null)); - // Only keep the newest ones - foreach (var deltaItem in delta.InventoryItems.Where(d => d?.InventoryItemData != null)) - { - var oldItems = new List(); - if (deltaItem.InventoryItemData.PlayerStats != null) - { - oldItems.AddRange( - InventoryItems.Where(i => i.InventoryItemData?.PlayerStats != null) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.PlayerCurrency != null) - { - oldItems.AddRange( - InventoryItems.Where(i => i.InventoryItemData?.PlayerCurrency != null) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.PlayerCamera != null) - { - oldItems.AddRange( - InventoryItems.Where(i => i.InventoryItemData?.PlayerCamera != null) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.InventoryUpgrades != null) - { - oldItems.AddRange( - InventoryItems.Where(i => i.InventoryItemData?.InventoryUpgrades != null) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.PokedexEntry != null) - { - oldItems.AddRange( - InventoryItems.Where( - i => - i.InventoryItemData?.PokedexEntry != null && - i.InventoryItemData.PokedexEntry.PokemonId == - deltaItem.InventoryItemData.PokedexEntry.PokemonId) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.Candy != null) - { - oldItems.AddRange( - InventoryItems.Where( - i => - i.InventoryItemData?.Candy != null && - i.InventoryItemData.Candy.FamilyId == - deltaItem.InventoryItemData.Candy.FamilyId) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.Item != null) - { - oldItems.AddRange( - InventoryItems.Where( - i => - i.InventoryItemData?.Item != null && - i.InventoryItemData.Item.ItemId == deltaItem.InventoryItemData.Item.ItemId) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.PokemonData != null) - { - oldItems.AddRange( - InventoryItems.Where( - i => - i.InventoryItemData?.PokemonData != null && - i.InventoryItemData.PokemonData.Id == deltaItem.InventoryItemData.PokemonData.Id) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.AppliedItems != null) - { - oldItems.AddRange( - InventoryItems.Where(i => i.InventoryItemData?.AppliedItems != null) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - if (deltaItem.InventoryItemData.EggIncubators != null) - { - oldItems.AddRange( - InventoryItems.Where(i => i.InventoryItemData?.EggIncubators != null) - .OrderByDescending(i => i.ModifiedTimestampMs) - .Skip(1)); - } - foreach (var oldItem in oldItems) - { - InventoryItems.Remove(oldItem); - } - } - Update?.Invoke(this, EventArgs.Empty); - } - - public event EventHandler Update; - } -} \ No newline at end of file diff --git a/POGOLib/Pokemon/Map.cs b/POGOLib/Pokemon/Map.cs deleted file mode 100644 index 739e573..0000000 --- a/POGOLib/Pokemon/Map.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using Google.Protobuf.Collections; -using POGOProtos.Map; - -namespace POGOLib.Pokemon -{ - /// - /// A wrapper class for . - /// - public class Map - { - // The last received map cells. - private RepeatedField _cells; - - internal Map() - { - } - - /// - /// Gets the last received from PokémonGo.
- /// Only use this if you know what you are doing. - ///
- public RepeatedField Cells - { - get { return _cells; } - internal set - { - _cells = value; - Update?.Invoke(this, EventArgs.Empty); - } - } - - public event EventHandler Update; - } -} \ No newline at end of file diff --git a/POGOLib/Pokemon/Player.cs b/POGOLib/Pokemon/Player.cs deleted file mode 100644 index 86a3f91..0000000 --- a/POGOLib/Pokemon/Player.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Linq; -using GeoCoordinatePortable; -using POGOProtos.Data; -using POGOProtos.Data.Player; - -namespace POGOLib.Pokemon -{ - public class Player - { - internal Player(GeoCoordinate coordinate) - { - Coordinate = coordinate; - Inventory = new Inventory(); - Inventory.Update += InventoryOnUpdate; - } - - /// - /// Gets the of the . - /// Used for internal calculations. - /// - internal GeoCoordinate Coordinate { get; private set; } - - /// - /// Gets the his current latitude. - /// - public double Latitude => Coordinate.Latitude; - - /// - /// Gets the his current longitude. - /// - public double Longitude => Coordinate.Longitude; - - /// - /// Gets the of the - /// - public Inventory Inventory { get; } - - /// - /// Gets the of the beautiful object by PokémonGo. - /// - public PlayerStats Stats { get; private set; } - - public PlayerData Data { get; set; } - - /// - /// Sets the of the . - /// - /// The latitude of your location. - /// The longitude of your location. - /// The altitude of your location. - public void SetCoordinates(double latitude, double longitude, double altitude = 100) - { - Coordinate = new GeoCoordinate(latitude, longitude, altitude); - } - - /// - /// Calculates the distance between the his current and the given - /// coordinate. - /// - /// The latitude. - /// The longitude. - /// Returns distance in meters. - public double DistanceTo(double latitude, double longitude) - { - return Coordinate.GetDistanceTo(new GeoCoordinate(latitude, longitude)); - } - - private void InventoryOnUpdate(object sender, EventArgs eventArgs) - { - var stats = - Inventory.InventoryItems.FirstOrDefault(i => i?.InventoryItemData?.PlayerStats != null)? - .InventoryItemData?.PlayerStats; - if (stats != null) - { - Stats = stats; - } - } - } -} \ No newline at end of file diff --git a/POGOLib/Pokemon/Templates.cs b/POGOLib/Pokemon/Templates.cs deleted file mode 100644 index f926e92..0000000 --- a/POGOLib/Pokemon/Templates.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Configuration; -using System.IO; -using System.Linq; -using Google.Protobuf; -using Google.Protobuf.Collections; -using POGOProtos.Data; -using POGOProtos.Networking.Responses; - -namespace POGOLib.Pokemon -{ - public class Templates - { - private GetAssetDigestResponse _assetDigestResponse; - private DownloadItemTemplatesResponse _itemTemplatesResponse; - - public Templates() - { - _assetDigestResponse = LoadAssetDigest(); - _itemTemplatesResponse = LoadItemTemplates(); - } - - public RepeatedField AssetDigests => _assetDigestResponse?.Digest; - - public RepeatedField ItemTemplates - => _itemTemplatesResponse?.ItemTemplates; - - public string AssetDigestFile - => - Path.Combine(Environment.CurrentDirectory, - ConfigurationManager.AppSettings["POGOLib.Templates.Directory"] ?? string.Empty, - "templates.asset-digests.dat"); - - public string ItemTemplatesFile - => - Path.Combine(Environment.CurrentDirectory, - ConfigurationManager.AppSettings["POGOLib.Templates.Directory"] ?? string.Empty, - "templates.items.dat"); - - public void SetAssetDigests(GetAssetDigestResponse assetDigestResponse) - { - if (_assetDigestResponse == null || assetDigestResponse.TimestampMs > _assetDigestResponse.TimestampMs) - { - _assetDigestResponse = assetDigestResponse; - SaveTemplate(AssetDigestFile, _assetDigestResponse.ToByteString().ToByteArray()); - } - } - - public void SetItemTemplates(DownloadItemTemplatesResponse itemTemplatesResponse) - { - if (_itemTemplatesResponse == null || itemTemplatesResponse.TimestampMs > _itemTemplatesResponse.TimestampMs) - { - _itemTemplatesResponse = itemTemplatesResponse; - SaveTemplate(ItemTemplatesFile, _itemTemplatesResponse.ToByteString().ToByteArray()); - } - } - - private GetAssetDigestResponse LoadAssetDigest() - { - if (File.Exists(AssetDigestFile)) - { - var bytes = File.ReadAllBytes(AssetDigestFile); - if (bytes.Any()) - { - return GetAssetDigestResponse.Parser.ParseFrom(bytes); - } - } - return null; - } - - private DownloadItemTemplatesResponse LoadItemTemplates() - { - if (File.Exists(ItemTemplatesFile)) - { - var bytes = File.ReadAllBytes(ItemTemplatesFile); - if (bytes.Any()) - { - return DownloadItemTemplatesResponse.Parser.ParseFrom(bytes); - } - } - return null; - } - - private void SaveTemplate(string file, byte[] data) - { - var directory = Path.GetDirectoryName(file); - if (!string.IsNullOrEmpty(directory)) - { - if (!Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } - } - File.WriteAllBytes(file, data); - } - } -} \ No newline at end of file diff --git a/POGOLib/Properties/AssemblyInfo.cs b/POGOLib/Properties/AssemblyInfo.cs deleted file mode 100644 index f33c1f0..0000000 --- a/POGOLib/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("POGOLib")] -[assembly: AssemblyDescription("A community driven PokémonGo API Library written in C#.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("AeonLucid")] -[assembly: AssemblyProduct("POGOLib")] -[assembly: AssemblyCopyright("Copyright © AeonLucid 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("3ba89dfb-a162-420a-9ded-daa211e52ad2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/POGOLib/Util/MapUtil.cs b/POGOLib/Util/MapUtil.cs deleted file mode 100644 index 309ffc1..0000000 --- a/POGOLib/Util/MapUtil.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; -using Google.Common.Geometry; - -namespace POGOLib.Util -{ - internal static class MapUtil - { - public static ulong[] GetCellIdsForLatLong(double latitude, double longitude) - { - var latLong = S2LatLng.FromDegrees(latitude, longitude); - var cell = S2CellId.FromLatLng(latLong); - var cellId = cell.ParentForLevel(15); - var cells = cellId.GetEdgeNeighbors(); - var cellIds = new List - { - cellId.Id - }; - - foreach (var cellEdge1 in cells) - { - if (!cellIds.Contains(cellEdge1.Id)) cellIds.Add(cellEdge1.Id); - - foreach (var cellEdge2 in cellEdge1.GetEdgeNeighbors()) - { - if (!cellIds.Contains(cellEdge2.Id)) cellIds.Add(cellEdge2.Id); - } - } - - return cellIds.ToArray(); - } - } -} \ No newline at end of file diff --git a/POGOLib/Util/TimeUtil.cs b/POGOLib/Util/TimeUtil.cs deleted file mode 100644 index 2effd98..0000000 --- a/POGOLib/Util/TimeUtil.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -namespace POGOLib.Util -{ - public static class TimeUtil - { - private static DateTime _posixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - - /// - /// Returns the current unix timestamp in milliseconds (UTC). - /// - /// - public static long GetCurrentTimestampInMilliseconds() - { - return (long) (DateTime.UtcNow - _posixTime).TotalMilliseconds; - } - - /// - /// Returns the current unix timestamp in seconds (UTC). - /// - /// - public static long GetCurrentTimestampInSeconds() - { - return (long) (DateTime.UtcNow - _posixTime).TotalSeconds; - } - - public static DateTime GetDateTimeFromMilliseconds(long timestampMilliseconds) - { - return _posixTime.AddMilliseconds(timestampMilliseconds); - } - - public static DateTime GetDateTimeFromSeconds(int timestampSeconds) - { - return _posixTime.AddSeconds(timestampSeconds); - } - } -} \ No newline at end of file diff --git a/POGOLib/packages.config b/POGOLib/packages.config deleted file mode 100644 index ad1c3cd..0000000 --- a/POGOLib/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/PoGoBot.Console/BotEventListener.cs b/PoGoBot.Console/BotEventListener.cs index 605faf1..bdd7476 100644 --- a/PoGoBot.Console/BotEventListener.cs +++ b/PoGoBot.Console/BotEventListener.cs @@ -133,14 +133,59 @@ private void HandleEvent(ReleaseEventArgs args) return; } EnqueueMessage("Task_Pokemon_Release_Identifier", "Task_Pokemon_Release_Message", Color.PaleVioletRed, - args.Pokemon.PokemonId.ToString(), args.Pokemon.Cp); + args.Pokemon.PokemonId.ToString(), args.Pokemon.Cp, args.Pokemon.Stamina, + args.Pokemon.IndividualAttack, args.Pokemon.IndividualDefense, args.Pokemon.IndividualStamina); } private void HandleEvent(CatchEventArgs args) { EnqueueMessage("Task_Pokemon_Catch_Identifier", "Task_Pokemon_Catch_Message", Color.ForestGreen, - args.Response.Status, args.Pokemon.PokemonId.ToString(), args.Pokemon.Cp, + args.Response.Status, args.Pokemon.PokemonId.ToString(), args.Pokemon.Cp, args.Pokemon.StaminaMax, + args.Pokemon.IndividualAttack, args.Pokemon.IndividualDefense, args.Pokemon.IndividualStamina, args.CaptureProbability.ToString("0")); } + + private void HandleEvent(LevelUpRewardsEventArgs args) + { + var items = string.Empty; + if (args.Response.ItemsAwarded.Any()) + { + var dictionary = args.Response.ItemsAwarded.GroupBy(i => i.ItemId) + .ToDictionary(k => k.Key, v => v.Sum(x => x.ItemCount)); + items = string.Join(", ", dictionary.Select(kv => kv.Value + " x " + kv.Key).ToArray()); + } + EnqueueMessage("Task_Player_LevelUpRewards_Identifier", "Task_Player_LevelUpRewards_Message_Detected", Color.White, + args.Level, items); + } + + private void HandleEvent(PlayerUpdateEventArgs args) + { + EnqueueMessage("Task_Player_Update_Identifier", "Task_Player_Update_Message", Color.White, + args.Latitude, args.Longitude); + } + + private void HandleEvent(RouteNextPointEventArgs args) + { + EnqueueMessage("Task_Route_Next_Point_Identifier", "Task_Route_Next_Point_Message", Color.Red, + args.NextPoint, args.Latitude, args.Longitude); + } + + private void HandleEvent(UseItemEggIncubatorArgs args) + { + EnqueueMessage("Task_Use_Item_Egg_Incubator_Identifier", "Task_Use_Item_Egg_Incubator_Message", Color.Red, + args.Response.Result, args.ItemId, args.PokemonId); + } + + private void HandleEvent(UseLuckyEggEventArgs args) + { + EnqueueMessage("Task_Use_Lucky_Egg_Identifier", "Task_Use_Lucky_Egg_Message", Color.Red, + args.Response.Result); + } + + private void HandleEvent(EncounterEventArgs args) + { + EnqueueMessage("Task_Encounter_Identifier", "Task_Encounter_Message", Color.Red, + args.Result, args.Pokemon.PokemonId, args.Latitude, args.Longitude); + } } } \ No newline at end of file diff --git a/PoGoBot.Console/PoGoBot.Console.csproj b/PoGoBot.Console/PoGoBot.Console.csproj index ae800c4..6226b23 100644 --- a/PoGoBot.Console/PoGoBot.Console.csproj +++ b/PoGoBot.Console/PoGoBot.Console.csproj @@ -34,6 +34,10 @@ 4 + + ..\packages\C5.2.4.5947.17249\lib\net45\C5.dll + True + ..\packages\Colorful.Console.1.0.5\lib\net461\Colorful.Console.dll True @@ -42,15 +46,37 @@ ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll True - + + ..\packages\GeoCoordinate.1.1.0\lib\portable-net45+wp80+win+wpa81\GeoCoordinatePortable.dll + True + + ..\packages\Google.Protobuf.3.0.0-beta4\lib\net45\Google.Protobuf.dll + True + + + ..\packages\GPSOAuthSharp.0.0.5\lib\GPSOAuthSharp.dll + True ..\packages\log4net.2.0.5\lib\net45-full\log4net.dll - - ..\packages\POGOProtos.1.4.0\lib\net45\POGOProtos.dll + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + + + ..\packages\POGOLib.Official.0.3.0-alpha\lib\net45\POGOLib.dll + True + + + ..\packages\POGOLib.Official.0.3.0-alpha\lib\net45\POGOProtos.dll + True + + + ..\packages\S2Geometry.1.0.3\lib\portable-net45+wp8+win8\S2Geometry.dll + True @@ -96,10 +122,6 @@ {B9464831-D620-45B1-9BD5-6A58887F8FFC} PoGoBot.Logic - - {3BA89DFB-A162-420A-9DED-DAA211E52AD2} - POGOLib - diff --git a/PoGoBot.Console/Resources/Languages/Logic/messages.Designer.cs b/PoGoBot.Console/Resources/Languages/Logic/messages.Designer.cs index b6fee44..bab285c 100644 --- a/PoGoBot.Console/Resources/Languages/Logic/messages.Designer.cs +++ b/PoGoBot.Console/Resources/Languages/Logic/messages.Designer.cs @@ -60,6 +60,24 @@ internal messages() { } } + /// + /// Looks up a localized string similar to Encounter. + /// + internal static string Task_Encounter_Identifier { + get { + return ResourceManager.GetString("Task_Encounter_Identifier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} | {1} | {2} | {3}. + /// + internal static string Task_Encounter_Message { + get { + return ResourceManager.GetString("Task_Encounter_Message", resourceCulture); + } + } + /// /// Looks up a localized string similar to PokeStop. /// @@ -114,6 +132,24 @@ internal static string Task_Item_Use_Message { } } + /// + /// Looks up a localized string similar to LevelUp Rewards. + /// + internal static string Task_Player_LevelUpRewards_Identifier { + get { + return ResourceManager.GetString("Task_Player_LevelUpRewards_Identifier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Level {0} | {1}. + /// + internal static string Task_Player_LevelUpRewards_Message_Detected { + get { + return ResourceManager.GetString("Task_Player_LevelUpRewards_Message_Detected", resourceCulture); + } + } + /// /// Looks up a localized string similar to Softban. /// @@ -141,6 +177,24 @@ internal static string Task_Player_Softban_Message_Lifted { } } + /// + /// Looks up a localized string similar to Player Update. + /// + internal static string Task_Player_Update_Identifier { + get { + return ResourceManager.GetString("Task_Player_Update_Identifier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} {1}. + /// + internal static string Task_Player_Update_Message { + get { + return ResourceManager.GetString("Task_Player_Update_Message", resourceCulture); + } + } + /// /// Looks up a localized string similar to Pokemon. /// @@ -151,7 +205,7 @@ internal static string Task_Pokemon_Catch_Identifier { } /// - /// Looks up a localized string similar to {0} | {1} | CP {2} | Chance: {3}%. + /// Looks up a localized string similar to {0} | {1} | CP {2} | XP {3} | IA {4} | ID {5} | IS {6} | Chance: {7}%. /// internal static string Task_Pokemon_Catch_Message { get { @@ -187,12 +241,66 @@ internal static string Task_Pokemon_Release_Identifier { } /// - /// Looks up a localized string similar to {0} (CP {1}). + /// Looks up a localized string similar to {0} | CP {1} | XP {2} | IA {3} | ID {4} | IS {5}. /// internal static string Task_Pokemon_Release_Message { get { return ResourceManager.GetString("Task_Pokemon_Release_Message", resourceCulture); } } + + /// + /// Looks up a localized string similar to Route Next Point. + /// + internal static string Task_Route_Next_Point_Identifier { + get { + return ResourceManager.GetString("Task_Route_Next_Point_Identifier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ({0}) {1} {2}. + /// + internal static string Task_Route_Next_Point_Message { + get { + return ResourceManager.GetString("Task_Route_Next_Point_Message", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use Egg Incubator. + /// + internal static string Task_Use_Item_Egg_Incubator_Identifier { + get { + return ResourceManager.GetString("Task_Use_Item_Egg_Incubator_Identifier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ({0}) {1} {2}. + /// + internal static string Task_Use_Item_Egg_Incubator_Message { + get { + return ResourceManager.GetString("Task_Use_Item_Egg_Incubator_Message", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use Lucky Egg. + /// + internal static string Task_Use_Lucky_Egg_Identifier { + get { + return ResourceManager.GetString("Task_Use_Lucky_Egg_Identifier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}. + /// + internal static string Task_Use_Lucky_Egg_Message { + get { + return ResourceManager.GetString("Task_Use_Lucky_Egg_Message", resourceCulture); + } + } } } diff --git a/PoGoBot.Console/Resources/Languages/Logic/messages.resx b/PoGoBot.Console/Resources/Languages/Logic/messages.resx index b321c02..8b74f49 100644 --- a/PoGoBot.Console/Resources/Languages/Logic/messages.resx +++ b/PoGoBot.Console/Resources/Languages/Logic/messages.resx @@ -154,12 +154,48 @@ Transfer - {0} (CP {1}) + {0} | CP {1} | XP {2} | IA {3} | ID {4} | IS {5} Pokemon - {0} | {1} | CP {2} | Chance: {3}% + {0} | {1} | CP {2} | XP {3} | IA {4} | ID {5} | IS {6} | Chance: {7}% + + + LevelUp Rewards + + + Level {0} | {1} + + + Player Update + + + {0} {1} + + + Route Next Point + + + ({0}) {1} {2} + + + Use Egg Incubator + + + ({0}) {1} {2} + + + Use Lucky Egg + + + {0} + + + Encounter + + + {0} | {1} | {2} | {3} \ No newline at end of file diff --git a/PoGoBot.Console/Statistic.cs b/PoGoBot.Console/Statistic.cs index f6227cb..1948975 100644 --- a/PoGoBot.Console/Statistic.cs +++ b/PoGoBot.Console/Statistic.cs @@ -83,7 +83,7 @@ public override string ToString() var sdh = (int) (Stardust/runtime.TotalHours); var ph = (int) (Pokemons/runtime.TotalHours); var ih = (int) (Items/runtime.TotalHours); - _lastToString = $"EXP/H: {exph} | SD/H: {sdh} | P/H: {ph} | I/H: {ih}"; + _lastToString = $"EXP: {_bot.Session.Player.Stats.Experience} | LVL: {_bot.Session.Player.Stats.Level} | KM: {_bot.Session.Player.Stats.KmWalked} | PM: {_bot.Session.Player.Stats.PokemonsCaptured} | PS: {_bot.Session.Player.Stats.PokeStopVisits} | EXP/H: {exph} | SD/H: {sdh} | P/H: {ph} | I/H: {ih}"; } return _lastToString; } diff --git a/PoGoBot.Console/packages.config b/PoGoBot.Console/packages.config index 3488e7f..683f425 100644 --- a/PoGoBot.Console/packages.config +++ b/PoGoBot.Console/packages.config @@ -1,8 +1,14 @@  - + + + + + + + \ No newline at end of file diff --git a/PoGoBot.Logic/Api/Categories/Item.cs b/PoGoBot.Logic/Api/Categories/Item.cs index 47d3f9b..0686e89 100644 --- a/PoGoBot.Logic/Api/Categories/Item.cs +++ b/PoGoBot.Logic/Api/Categories/Item.cs @@ -55,5 +55,24 @@ public RecycleInventoryItemResponse Recycle(ItemId itemId, int amount) } return parsed; } + + public UseItemEggIncubatorResponse UseEggIncubator(string itemId, ulong pokemonId) + { + var response = Session.RpcClient.SendRemoteProcedureCall(new Request + { + RequestType = RequestType.UseItemEggIncubator, + RequestMessage = new UseItemEggIncubatorMessage + { + ItemId = itemId, + PokemonId = pokemonId + }.ToByteString() + }); + var parsed = UseItemEggIncubatorResponse.Parser.ParseFrom(response); + if (parsed.Result != UseItemEggIncubatorResponse.Types.Result.Success) + { + Log.Error($"UseItemEggIncubator Result: {parsed.Result}"); + } + return parsed; + } } } \ No newline at end of file diff --git a/PoGoBot.Logic/Api/Categories/Player.cs b/PoGoBot.Logic/Api/Categories/Player.cs index 6bb198d..30583ea 100644 --- a/PoGoBot.Logic/Api/Categories/Player.cs +++ b/PoGoBot.Logic/Api/Categories/Player.cs @@ -1,5 +1,6 @@ using Google.Protobuf; using POGOLib.Net; +using POGOProtos.Inventory.Item; using POGOProtos.Networking.Requests; using POGOProtos.Networking.Requests.Messages; using POGOProtos.Networking.Responses; @@ -45,5 +46,41 @@ public PlayerUpdateResponse Update() }); return PlayerUpdateResponse.Parser.ParseFrom(response); } + + public LevelUpRewardsResponse LevelUpRewards(int level) + { + var response = Session.RpcClient.SendRemoteProcedureCall(new Request + { + RequestType = RequestType.LevelUpRewards, + RequestMessage = new LevelUpRewardsMessage + { + Level = level + }.ToByteString() + }); + var parsed = LevelUpRewardsResponse.Parser.ParseFrom(response); + if (parsed.Result != LevelUpRewardsResponse.Types.Result.Success) + { + Log.Error($"LevelUpRewards Success: {parsed.Result}"); + } + return parsed; + } + + public UseItemXpBoostResponse UseLuckyEgg() + { + var response = Session.RpcClient.SendRemoteProcedureCall(new Request + { + RequestType = RequestType.UseItemXpBoost, + RequestMessage = new UseItemXpBoostMessage + { + ItemId = ItemId.ItemLuckyEgg + }.ToByteString() + }); + var parsed = UseItemXpBoostResponse.Parser.ParseFrom(response); + if (parsed.Result != UseItemXpBoostResponse.Types.Result.Success) + { + Log.Error($"UseItemXpBoost Success: {parsed.Result}"); + } + return parsed; + } } } \ No newline at end of file diff --git a/PoGoBot.Logic/Api/Categories/Pokemon.cs b/PoGoBot.Logic/Api/Categories/Pokemon.cs index f60f0c9..71bfda5 100644 --- a/PoGoBot.Logic/Api/Categories/Pokemon.cs +++ b/PoGoBot.Logic/Api/Categories/Pokemon.cs @@ -66,7 +66,7 @@ public ReleasePokemonResponse Release(ulong pokemonId) return parsed; } - public IncenseEncounterResponse EncounterIncense(long encounterId, string encounterLocation) + public IncenseEncounterResponse EncounterIncense(ulong encounterId, string encounterLocation) { var response = Session.RpcClient.SendRemoteProcedureCall(new Request { diff --git a/PoGoBot.Logic/Automation/BaseBot.cs b/PoGoBot.Logic/Automation/BaseBot.cs index dd37801..b2e6d3a 100644 --- a/PoGoBot.Logic/Automation/BaseBot.cs +++ b/PoGoBot.Logic/Automation/BaseBot.cs @@ -6,6 +6,7 @@ using POGOLib.Net.Authentication; using POGOLib.Net.Authentication.Data; using POGOLib.Pokemon.Data; +using PoGoBot.Logic.Helpers; namespace PoGoBot.Logic.Automation { @@ -43,8 +44,8 @@ protected void Authenticate() Account.Username, Account.Password, Account.Provider, - Account.Position.Latitude, - Account.Position.Longitude + Utils.RandomizeCoordinate(Account.Position.Latitude), + Utils.RandomizeCoordinate(Account.Position.Longitude) ); Session.AccessTokenUpdated += OnSessionAccessTokenUpdated; Authenticated?.Invoke(this, EventArgs.Empty); diff --git a/PoGoBot.Logic/Automation/Events/Tasks/Item/UseItemEggIncubatorArgs.cs b/PoGoBot.Logic/Automation/Events/Tasks/Item/UseItemEggIncubatorArgs.cs new file mode 100644 index 0000000..98879a8 --- /dev/null +++ b/PoGoBot.Logic/Automation/Events/Tasks/Item/UseItemEggIncubatorArgs.cs @@ -0,0 +1,27 @@ +using POGOProtos.Inventory.Item; +using POGOProtos.Networking.Responses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Events.Tasks.Item +{ + public class UseItemEggIncubatorArgs : EventArgs + { + public UseItemEggIncubatorArgs(UseItemEggIncubatorResponse response, string itemId, ulong pokemonId) + { + Response = response; + PokemonId = pokemonId; + ItemId = itemId; + + + + } + + public UseItemEggIncubatorResponse Response { get; } + public ulong PokemonId { get; } + public string ItemId { get; } + } +} diff --git a/PoGoBot.Logic/Automation/Events/Tasks/Player/LevelUpRewardsEventArgs.cs b/PoGoBot.Logic/Automation/Events/Tasks/Player/LevelUpRewardsEventArgs.cs new file mode 100644 index 0000000..0fd7bbc --- /dev/null +++ b/PoGoBot.Logic/Automation/Events/Tasks/Player/LevelUpRewardsEventArgs.cs @@ -0,0 +1,21 @@ +using POGOProtos.Networking.Responses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Events.Tasks.Player +{ + public class LevelUpRewardsEventArgs : EventArgs + { + public LevelUpRewardsEventArgs(LevelUpRewardsResponse response, int level) + { + Response = response; + Level = level; + } + + public LevelUpRewardsResponse Response { get; } + public int Level { get; } + } +} diff --git a/PoGoBot.Logic/Automation/Events/Tasks/Player/PlayerUpdateEventArgs.cs b/PoGoBot.Logic/Automation/Events/Tasks/Player/PlayerUpdateEventArgs.cs new file mode 100644 index 0000000..4446e15 --- /dev/null +++ b/PoGoBot.Logic/Automation/Events/Tasks/Player/PlayerUpdateEventArgs.cs @@ -0,0 +1,23 @@ +using POGOProtos.Networking.Responses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Events.Tasks.Player +{ + public class PlayerUpdateEventArgs : EventArgs + { + public PlayerUpdateEventArgs(PlayerUpdateResponse response, double latitude, double longitude) + { + Response = response; + Latitude = latitude; + Longitude = longitude; + } + + public PlayerUpdateResponse Response { get; } + public double Latitude { get; } + public double Longitude { get; } + } +} diff --git a/PoGoBot.Logic/Automation/Events/Tasks/Player/RouteNextPointEventArgs.cs b/PoGoBot.Logic/Automation/Events/Tasks/Player/RouteNextPointEventArgs.cs new file mode 100644 index 0000000..5db5dd9 --- /dev/null +++ b/PoGoBot.Logic/Automation/Events/Tasks/Player/RouteNextPointEventArgs.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Events.Tasks.Player +{ + public class RouteNextPointEventArgs : EventArgs + { + public RouteNextPointEventArgs(int nextPoint, double latitude, double longitude) + { + NextPoint = nextPoint; + Latitude = latitude; + Longitude = longitude; + } + + public int NextPoint { get; } + public double Latitude { get; } + public double Longitude { get; } + } +} diff --git a/PoGoBot.Logic/Automation/Events/Tasks/Player/UseLuckyEggEventArgs.cs b/PoGoBot.Logic/Automation/Events/Tasks/Player/UseLuckyEggEventArgs.cs new file mode 100644 index 0000000..37ce5c2 --- /dev/null +++ b/PoGoBot.Logic/Automation/Events/Tasks/Player/UseLuckyEggEventArgs.cs @@ -0,0 +1,19 @@ +using POGOProtos.Networking.Responses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Events.Tasks.Player +{ + public class UseLuckyEggEventArgs : EventArgs + { + public UseLuckyEggEventArgs(UseItemXpBoostResponse response) + { + Response = response; + } + + public UseItemXpBoostResponse Response { get; } + } +} diff --git a/PoGoBot.Logic/Automation/Events/Tasks/Pokemon/EncounterEventArgs.cs b/PoGoBot.Logic/Automation/Events/Tasks/Pokemon/EncounterEventArgs.cs index 746e0cc..f88aefe 100644 --- a/PoGoBot.Logic/Automation/Events/Tasks/Pokemon/EncounterEventArgs.cs +++ b/PoGoBot.Logic/Automation/Events/Tasks/Pokemon/EncounterEventArgs.cs @@ -7,7 +7,7 @@ namespace PoGoBot.Logic.Automation.Events.Tasks.Pokemon public class EncounterEventArgs : EventArgs { public EncounterEventArgs(EEncounterResult result, EEncounterType type, PokemonData pokemon, - double captureProbability, ulong encounterId, string spawnPointId) + double captureProbability, ulong encounterId, string spawnPointId, double latitude, double longitude) { Result = result; Type = type; @@ -15,6 +15,8 @@ public EncounterEventArgs(EEncounterResult result, EEncounterType type, PokemonD CaptureProbability = captureProbability; EncounterId = encounterId; SpawnPointId = spawnPointId; + Latitude = latitude; + Longitude = longitude; } public EEncounterResult Result { get; } @@ -23,5 +25,7 @@ public EncounterEventArgs(EEncounterResult result, EEncounterType type, PokemonD public double CaptureProbability { get; } public ulong EncounterId { get; } public string SpawnPointId { get; } + public double Latitude { get; } + public double Longitude { get; } } } \ No newline at end of file diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/EvolveLuckyEggActiveFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/EvolveLuckyEggActiveFilter.cs new file mode 100644 index 0000000..d44282f --- /dev/null +++ b/PoGoBot.Logic/Automation/Filters/Pokemon/EvolveLuckyEggActiveFilter.cs @@ -0,0 +1,26 @@ +using POGOLib.Net; +using POGOProtos.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PoGoBot.Logic.Extensions; +using POGOProtos.Inventory.Item; + +namespace PoGoBot.Logic.Automation.Filters.Pokemon +{ + public class EvolveLuckyEggActiveFilter : BaseFilter> + { + public EvolveLuckyEggActiveFilter(Settings settings, Session session, Func enabledFunction) : base(settings, session, enabledFunction) + { + } + + public override IEnumerable Process(IEnumerable input) + { + var items = Session.Player.Inventory.GetAppliedItems(); + return input.Where(p => (Session.Player.Inventory.GetAmountOfItem(ItemId.ItemLuckyEgg) == 0) || + Session.Player.Inventory.IsItemActive(ItemType.XpBoost)).ToList(); + } + } +} diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/EvolvePriorityTypeFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/EvolvePriorityTypeFilter.cs new file mode 100644 index 0000000..6e36111 --- /dev/null +++ b/PoGoBot.Logic/Automation/Filters/Pokemon/EvolvePriorityTypeFilter.cs @@ -0,0 +1,31 @@ +using PoGoBot.Logic.Enumerations; +using POGOLib.Net; +using POGOProtos.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Filters.Pokemon +{ + class EvolvePriorityTypeFilter : BaseFilter> + { + public EvolvePriorityTypeFilter(Settings settings, Session session) : base(settings, session) + { + } + + public override IEnumerable Process(IEnumerable input) + { + switch (Settings.Bot.Pokemon.Evolve.PriorityType) + { + case EPriorityType.LowCombatPower: + return input.OrderByDescending(p => p.Cp).ThenByDescending(n => n.StaminaMax); + case EPriorityType.LowIndividualValues: + return input.OrderByDescending(p => p.IndividualAttack + p.IndividualDefense + p.IndividualStamina).ThenByDescending(n => n.StaminaMax); + default: + return input.OrderByDescending(p => p.Cp).ThenByDescending(n => n.StaminaMax); + } + } + } +} diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseCombatPowerFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseCombatPowerFilter.cs deleted file mode 100644 index 03831f2..0000000 --- a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseCombatPowerFilter.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using POGOLib.Net; -using POGOProtos.Data; - -namespace PoGoBot.Logic.Automation.Filters.Pokemon -{ - public class ReleaseCombatPowerFilter : BaseFilter> - { - public ReleaseCombatPowerFilter(Settings settings, Session session) : base(settings, session) - { - } - - public override IEnumerable Process(IEnumerable input) - { - return - Settings.Bot.Pokemon.Release.PrioritizeLowCombatPower - ? input.OrderBy(p => p.Cp).ThenBy(n => n.StaminaMax) - : input.OrderByDescending(p => p.Cp).ThenByDescending(n => n.StaminaMax); - } - } -} \ No newline at end of file diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseEvolveAwareFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseEvolveAwareFilter.cs index 5c9c079..b6c29c4 100644 --- a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseEvolveAwareFilter.cs +++ b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseEvolveAwareFilter.cs @@ -35,8 +35,12 @@ public override IEnumerable Process(IEnumerable input) { var pokemonTemplate = _pokemonTemplates.Single(p => p.PokemonId == pokemonId.Key); var familyCandy = candies.Single(p => pokemonTemplate.FamilyId == p.FamilyId); - var amountToSkip = (familyCandy.Candy_ + pokemonTemplate.CandyToEvolve - 1)/ - pokemonTemplate.CandyToEvolve; + int amountToSkip = 0; + if ((pokemonTemplate.CandyToEvolve > 0) && (pokemonTemplate.ParentPokemonId == PokemonId.Missingno)) + { + amountToSkip = Math.Max(0, (familyCandy.Candy_ + pokemonTemplate.CandyToEvolve - 1) / + pokemonTemplate.CandyToEvolve - Settings.Bot.Pokemon.Release.KeepUniqueAmount); + } releasePokemons.AddRange(pokemons.Where(p => p.PokemonId == pokemonId.Key).Skip(amountToSkip).ToList()); } return releasePokemons; diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseMaxIndividualValuesFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseMaxIndividualValuesFilter.cs new file mode 100644 index 0000000..98ba708 --- /dev/null +++ b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseMaxIndividualValuesFilter.cs @@ -0,0 +1,22 @@ +using POGOLib.Net; +using POGOProtos.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Filters.Pokemon +{ + public class ReleaseMaxIndividualValuesFilter : BaseFilter> + { + public ReleaseMaxIndividualValuesFilter(Settings settings, Session session, Func enabledFunction) : base(settings, session, enabledFunction) + { + } + + public override IEnumerable Process(IEnumerable input) + { + return input.Where(p => p.IndividualAttack + p.IndividualDefense + p.IndividualStamina < Settings.Bot.Pokemon.Release.MaximumIndividualValues).ToList(); + } + } +} diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleasePriorityTypeFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleasePriorityTypeFilter.cs new file mode 100644 index 0000000..f78daee --- /dev/null +++ b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleasePriorityTypeFilter.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Linq; +using POGOLib.Net; +using POGOProtos.Data; +using PoGoBot.Logic.Enumerations; + +namespace PoGoBot.Logic.Automation.Filters.Pokemon +{ + public class ReleasePriorityTypeFilter : BaseFilter> + { + public ReleasePriorityTypeFilter(Settings settings, Session session) : base(settings, session) + { + } + + public override IEnumerable Process(IEnumerable input) + { + switch (Settings.Bot.Pokemon.Release.PriorityType) + { + case EPriorityType.LowCombatPower: + return input.OrderByDescending(p => p.Cp).ThenByDescending(n => n.StaminaMax); + case EPriorityType.LowIndividualValues: + return input.OrderByDescending(p => p.IndividualAttack + p.IndividualDefense + p.IndividualStamina).ThenByDescending(n => n.StaminaMax); + default: + return input.OrderByDescending(p => p.Cp).ThenByDescending(n => n.StaminaMax); + } + } + } +} \ No newline at end of file diff --git a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseUniqueFilter.cs b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseUniqueFilter.cs index 5ed2e89..e161f2a 100644 --- a/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseUniqueFilter.cs +++ b/PoGoBot.Logic/Automation/Filters/Pokemon/ReleaseUniqueFilter.cs @@ -20,8 +20,7 @@ public override IEnumerable Process(IEnumerable input) return input; } var pokemons = new List(); - var groups = input.OrderBy(p => p.Cp).ThenBy(n => n.StaminaMax).GroupBy(p => p.PokemonId); - foreach (var group in groups) + foreach (var group in input.GroupBy(p => p.PokemonId)) { pokemons.AddRange(group.Skip(Math.Max(0, Settings.Bot.Pokemon.Release.KeepUniqueAmount))); } diff --git a/PoGoBot.Logic/Automation/Tasks/Item/EggIncubatorTask.cs b/PoGoBot.Logic/Automation/Tasks/Item/EggIncubatorTask.cs new file mode 100644 index 0000000..0891ba0 --- /dev/null +++ b/PoGoBot.Logic/Automation/Tasks/Item/EggIncubatorTask.cs @@ -0,0 +1,47 @@ +using PoGoBot.Logic.Automation.Events.Tasks.Item; +using PoGoBot.Logic.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Tasks.Item +{ + public class EggIncubatorTask : BaseTask + { + + public EggIncubatorTask(Context context) : base(context) + { + } + + public override bool Enabled => Context.Settings.Bot.EggIncubator.Enabled; + + public override void OnExecute() + { + var eggIncubatorsGlobal = Context.Session.Player.Inventory.GetEggIncubators(); + foreach (var eggIncubators in eggIncubatorsGlobal) + { + foreach (var eggIncubator in eggIncubators.EggIncubator.Where(e => e.PokemonId == 0)) + { + var egg = Context.Session.Player.Inventory.GetEggs().Where(e => e.EggIncubatorId.Length == 0).First(); + + var useItemEggIncubatorResponse = Context.RpcRequest.Item.UseEggIncubator(eggIncubator.Id, egg.Id); + Context.Events.DispatchEvent(this, new UseItemEggIncubatorArgs(useItemEggIncubatorResponse, eggIncubator.Id, egg.Id)); + } + + } + } + + public override void OnStart() + { + + } + + public override void OnTerminate() + { + + } + + } +} diff --git a/PoGoBot.Logic/Automation/Tasks/Player/FollowRouteTask.cs b/PoGoBot.Logic/Automation/Tasks/Player/FollowRouteTask.cs new file mode 100644 index 0000000..3a7a289 --- /dev/null +++ b/PoGoBot.Logic/Automation/Tasks/Player/FollowRouteTask.cs @@ -0,0 +1,92 @@ +using GeoCoordinatePortable; +using PoGoBot.Logic.Automation.Events.Tasks.Player; +using PoGoBot.Logic.Helpers; +using POGOLib.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Tasks.Player +{ + public class FollowRouteTask : BaseTask + { + private int _previousPoint; + private int _nextPoint; + private long _time; + + public FollowRouteTask(Context context) : base(context) + { + } + + public override bool Enabled => Context.Settings.Bot.FollowRoute.Enabled; + + public override void OnExecute() + { + var time = TimeUtil.GetCurrentTimestampInMilliseconds(); + if (_time + Context.Settings.Bot.FollowRoute.Speed * 1000 < time) + { + var nextStep = GetNextStep(); + var playerUpdateResponse = Context.RpcRequest.Player.Update(nextStep.Latitude, nextStep.Longitude); + Context.Events.DispatchEvent(this, new PlayerUpdateEventArgs(playerUpdateResponse, nextStep.Latitude, nextStep.Longitude)); + _time = time; + } + } + + public override void OnStart() + { + _previousPoint = 0; + _nextPoint = 0; + FindNextPoint(); + } + + public override void OnTerminate() + { + + } + + private void FindNextPoint() + { + var nextPoints = Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].RouteLinks.Where(c => c != _previousPoint).ToList(); + if (nextPoints.Count() == 0) + { + int tmpPoint = _previousPoint; + _previousPoint = _nextPoint; + _nextPoint = tmpPoint; + } + else + { + _previousPoint = _nextPoint; + if (nextPoints.Count() == 1) + { + _nextPoint = nextPoints.ElementAt(0); + } + else + { + Random rnd = new Random(); + _nextPoint = nextPoints.ElementAt(rnd.Next(nextPoints.Count())); + } + } + Context.Events.DispatchEvent(this, new RouteNextPointEventArgs(_nextPoint, + Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].Position.Latitude, + Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].Position.Longitude)); + } + + private GeoCoordinate GetNextStep() + { + var distance = Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].Position.GetDistanceTo(new GeoCoordinate(Context.Session.Player.Latitude, Context.Session.Player.Longitude)); + if (distance < Context.Settings.Bot.FollowRoute.StepSize) + { + var nextStep = Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].Position; + FindNextPoint(); + return nextStep; + } + var latitude = Context.Session.Player.Latitude + Math.Round((Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].Position.Latitude - Context.Session.Player.Latitude) * + Context.Settings.Bot.FollowRoute.StepSize / distance, 6); + var longitude = Context.Session.Player.Longitude + Math.Round((Context.Settings.Bot.FollowRoute.RoutePoints[_nextPoint].Position.Longitude - Context.Session.Player.Longitude) * + Context.Settings.Bot.FollowRoute.StepSize / distance, 6); + return new GeoCoordinate(Utils.RandomizeCoordinate(latitude), Utils.RandomizeCoordinate(longitude)); + } + } +} diff --git a/PoGoBot.Logic/Automation/Tasks/Player/LevelUpRewardsTask.cs b/PoGoBot.Logic/Automation/Tasks/Player/LevelUpRewardsTask.cs new file mode 100644 index 0000000..7866d54 --- /dev/null +++ b/PoGoBot.Logic/Automation/Tasks/Player/LevelUpRewardsTask.cs @@ -0,0 +1,43 @@ +using PoGoBot.Logic.Automation.Events.Tasks.Player; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Tasks.Player +{ + public class LevelUpRewardsTask : BaseTask + { + + private int CurrentLevel; + + public LevelUpRewardsTask(Context context) : base(context) + { + } + + public override bool Enabled => Context.Settings.Bot.LevelUpRewards.Enabled; + + public override void OnExecute() + { + while (CurrentLevel < Context.Session.Player.Stats.Level) + { + CurrentLevel ++; + + var levelUpRewardsResponse = Context.RpcRequest.Player.LevelUpRewards(CurrentLevel); + Context.Events.DispatchEvent(this, new LevelUpRewardsEventArgs(levelUpRewardsResponse, CurrentLevel)); + } + } + + public override void OnStart() + { + CurrentLevel = Context.Session.Player.Stats.Level; + } + + public override void OnTerminate() + { + + } + + } +} diff --git a/PoGoBot.Logic/Automation/Tasks/Player/UseLuckyEggTask.cs b/PoGoBot.Logic/Automation/Tasks/Player/UseLuckyEggTask.cs new file mode 100644 index 0000000..4c0918e --- /dev/null +++ b/PoGoBot.Logic/Automation/Tasks/Player/UseLuckyEggTask.cs @@ -0,0 +1,45 @@ +using PoGoBot.Logic.Automation.Events.Tasks.Player; +using PoGoBot.Logic.Extensions; +using POGOProtos.Inventory.Item; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Automation.Tasks.Player +{ + class UseLuckyEggTask : BaseTask + { + + public UseLuckyEggTask(Context context) : base(context) + { + } + + public override bool Enabled => Context.Settings.Bot.UseLuckyEgg.Enabled; + + public override void OnExecute() + { + if(! Context.Session.Player.Inventory.IsItemActive(ItemType.XpBoost) && + Context.Session.Player.Inventory.GetAmountOfItem(ItemId.ItemLuckyEgg) > 0) + { + if ((Context.Session.Player.Inventory.GetPokemons().Count + Context.Session.Player.Inventory.GetEggs().Count) * Context.Settings.Bot.UseLuckyEgg.PercentStorageFull >= 100 * Context.Session.Player.Data?.MaxPokemonStorage ) + { + var useLuckyEggResponse = Context.RpcRequest.Player.UseLuckyEgg(); + Context.Events.DispatchEvent(this, new UseLuckyEggEventArgs(useLuckyEggResponse)); + } + } + } + + public override void OnStart() + { + + } + + public override void OnTerminate() + { + + } + + } +} diff --git a/PoGoBot.Logic/Automation/Tasks/Pokemon/BaseEncounterTask.cs b/PoGoBot.Logic/Automation/Tasks/Pokemon/BaseEncounterTask.cs index cc6d4ab..18d64cb 100644 --- a/PoGoBot.Logic/Automation/Tasks/Pokemon/BaseEncounterTask.cs +++ b/PoGoBot.Logic/Automation/Tasks/Pokemon/BaseEncounterTask.cs @@ -13,19 +13,17 @@ protected BaseEncounterTask(Context context) : base(context) } protected List BlacklistedPokemons { get; } = new List(); - protected int MaxPokemonStorage { get; private set; } public override bool Enabled => Context.Settings.Bot.Pokemon.Catch.Enabled; public override bool ShouldExecute => - base.ShouldExecute && Context.Session.Player.Inventory.GetPokemons().Count < MaxPokemonStorage && + base.ShouldExecute && (Context.Session.Player.Inventory.GetPokemons().Count + Context.Session.Player.Inventory.GetEggs().Count) < Context.Session.Player.Data?.MaxPokemonStorage && Context.Session.Player.Inventory.GetAmountOfItems( Context.Settings.Bot.Pokemon.Catch.Balls.Select(b => b.ItemId)) >= Context.Settings.Bot.Pokemon.Catch.MinimumBalls; public override void OnStart() { - MaxPokemonStorage = (Context.Session.Player.Data?.MaxPokemonStorage ?? 250) - 10; Context.Session.Map.Update += OnMapUpdate; Context.Events.EventReceived += OnEventReceived; } diff --git a/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/IncenseTask.cs b/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/IncenseTask.cs index 7f861a7..444d537 100644 --- a/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/IncenseTask.cs +++ b/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/IncenseTask.cs @@ -31,14 +31,14 @@ public override void OnExecute() { return; } - var encounterResponse = Context.RpcRequest.Pokemon.EncounterIncense((long) incenseResponse.EncounterId, + var encounterResponse = Context.RpcRequest.Pokemon.EncounterIncense(incenseResponse.EncounterId, incenseResponse.EncounterLocation); var captureProbability = (encounterResponse.CaptureProbability?.CaptureProbability_?.FirstOrDefault() ?? 0.3)* 100; var result = GetEncounterResult(encounterResponse.Result); Context.Events.DispatchEventAsync(this, new EncounterEventArgs(result, EEncounterType.Incense, encounterResponse.PokemonData, captureProbability, - incenseResponse.EncounterId, incenseResponse.EncounterLocation)); + incenseResponse.EncounterId, incenseResponse.EncounterLocation, incenseResponse.Latitude, incenseResponse.Longitude)); BlacklistedPokemons.Add(incenseResponse.EncounterId); } diff --git a/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/LureTask.cs b/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/LureTask.cs index 80988a2..6e4271e 100644 --- a/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/LureTask.cs +++ b/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/LureTask.cs @@ -40,7 +40,7 @@ public override void OnExecute() var result = GetEncounterResult(encounterResponse.Result); Context.Events.DispatchEventAsync(this, new EncounterEventArgs(result, EEncounterType.Lure, encounterResponse.PokemonData, captureProbability, - fort.LureInfo.EncounterId, fort.LureInfo.FortId)); + fort.LureInfo.EncounterId, fort.LureInfo.FortId, fort.Latitude, fort.Longitude)); BlacklistedPokemons.Add(fort.LureInfo.EncounterId); } diff --git a/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/MapTask.cs b/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/MapTask.cs index dcc08d3..e604bff 100644 --- a/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/MapTask.cs +++ b/PoGoBot.Logic/Automation/Tasks/Pokemon/Encounter/MapTask.cs @@ -40,7 +40,7 @@ public override void OnExecute() var result = GetEncounterResult(encounterResponse.Status); Context.Events.DispatchEventAsync(this, new EncounterEventArgs(result, EEncounterType.Map, encounterResponse.WildPokemon?.PokemonData, - captureProbability, pokemon.EncounterId, pokemon.SpawnPointId)); + captureProbability, pokemon.EncounterId, pokemon.SpawnPointId, pokemon.Latitude, pokemon.Longitude)); BlacklistedPokemons.Add(pokemon.EncounterId); } diff --git a/PoGoBot.Logic/Automation/Tasks/Pokemon/EvolveTask.cs b/PoGoBot.Logic/Automation/Tasks/Pokemon/EvolveTask.cs index adfc407..59e42dd 100644 --- a/PoGoBot.Logic/Automation/Tasks/Pokemon/EvolveTask.cs +++ b/PoGoBot.Logic/Automation/Tasks/Pokemon/EvolveTask.cs @@ -23,7 +23,10 @@ public EvolveTask(Context context) : base(context) new FavoriteFilter(Context.Settings, Context.Session, () => Context.Settings.Bot.Pokemon.Evolve.IgnoreFavorites), new EvolveCombatPowerFilter(Context.Settings, Context.Session), - new EvolveCandyFilter(Context.Settings, Context.Session) + new EvolvePriorityTypeFilter(Context.Settings, Context.Session), + new EvolveCandyFilter(Context.Settings, Context.Session), + new EvolveLuckyEggActiveFilter(Context.Settings, Context.Session, + () => Context.Settings.Bot.Pokemon.Evolve.LuckyEggActive) }); } diff --git a/PoGoBot.Logic/Automation/Tasks/Pokemon/ReleaseTask.cs b/PoGoBot.Logic/Automation/Tasks/Pokemon/ReleaseTask.cs index 45834a3..b4ce07c 100644 --- a/PoGoBot.Logic/Automation/Tasks/Pokemon/ReleaseTask.cs +++ b/PoGoBot.Logic/Automation/Tasks/Pokemon/ReleaseTask.cs @@ -19,14 +19,16 @@ public ReleaseTask(Context context) : base(context) _pipeline = new Pipeline>(); _pipeline.Register(new List>> { - new ReleaseUniqueFilter(Context.Settings, Context.Session, - () => Context.Settings.Bot.Pokemon.Release.KeepUniqueAmount > 0), - new ReleaseCombatPowerFilter(Context.Settings, Context.Session), new DeployedFilter(Context.Settings, Context.Session), new FavoriteFilter(Context.Settings, Context.Session, () => Context.Settings.Bot.Pokemon.Release.IgnoreFavorites), + new ReleasePriorityTypeFilter(Context.Settings, Context.Session), + new ReleaseUniqueFilter(Context.Settings, Context.Session, + () => Context.Settings.Bot.Pokemon.Release.KeepUniqueAmount > 0), new ReleaseEvolveAwareFilter(Context.Settings, Context.Session, - () => Context.Settings.Bot.Pokemon.Release.IsEvolveAware) + () => Context.Settings.Bot.Pokemon.Release.IsEvolveAware), + new ReleaseMaxIndividualValuesFilter(Context.Settings, Context.Session, + () => Context.Settings.Bot.Pokemon.Release.MaximumIndividualValues > 0) }); } diff --git a/PoGoBot.Logic/Enumerations/EPriorityType.cs b/PoGoBot.Logic/Enumerations/EPriorityType.cs new file mode 100644 index 0000000..1aee144 --- /dev/null +++ b/PoGoBot.Logic/Enumerations/EPriorityType.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoGoBot.Logic.Enumerations +{ + public enum EPriorityType + { + LowCombatPower, + LowIndividualValues, + None + } +} diff --git a/PoGoBot.Logic/Extensions/InventoryExtensions.cs b/PoGoBot.Logic/Extensions/InventoryExtensions.cs index 22ae74c..6b10a70 100644 --- a/PoGoBot.Logic/Extensions/InventoryExtensions.cs +++ b/PoGoBot.Logic/Extensions/InventoryExtensions.cs @@ -38,6 +38,14 @@ public static List GetPokemons(this Inventory inventory) .ToList() ?? new List(); } + public static List GetEggs(this Inventory inventory) + { + return + inventory?.InventoryItems?.Select(it => it?.InventoryItemData?.PokemonData) + .Where(p => p != null && p.Id > 0 && p.IsEgg) + .ToList() ?? new List(); + } + public static List GetCandies(this Inventory inventory) { return diff --git a/PoGoBot.Logic/Helpers/Utils.cs b/PoGoBot.Logic/Helpers/Utils.cs index a61dceb..bc4e574 100644 --- a/PoGoBot.Logic/Helpers/Utils.cs +++ b/PoGoBot.Logic/Helpers/Utils.cs @@ -82,5 +82,11 @@ public static T GenerateResource(out bool newFile) where T : class } return data; } + + public static double RandomizeCoordinate(double coordinate) + { + Random rnd = new Random(); + return coordinate + (rnd.Next(40) - 20.0) / 1000000; + } } } \ No newline at end of file diff --git a/PoGoBot.Logic/PoGoBot.Logic.csproj b/PoGoBot.Logic/PoGoBot.Logic.csproj index 5eba721..63054d1 100644 --- a/PoGoBot.Logic/PoGoBot.Logic.csproj +++ b/PoGoBot.Logic/PoGoBot.Logic.csproj @@ -31,6 +31,10 @@ 4 + + ..\packages\C5.2.4.5947.17249\lib\net45\C5.dll + True + ..\packages\GeoCoordinate.1.1.0\lib\portable-net45+wp80+win+wpa81\GeoCoordinatePortable.dll True @@ -39,6 +43,10 @@ ..\packages\Google.Protobuf.3.0.0-beta4\lib\net45\Google.Protobuf.dll True + + ..\packages\GPSOAuthSharp.0.0.5\lib\GPSOAuthSharp.dll + True + ..\packages\log4net.2.0.5\lib\net45-full\log4net.dll True @@ -47,8 +55,16 @@ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True - - ..\packages\POGOProtos.1.4.0\lib\net45\POGOProtos.dll + + ..\packages\POGOLib.Official.0.3.0-alpha\lib\net45\POGOLib.dll + True + + + ..\packages\POGOLib.Official.0.3.0-alpha\lib\net45\POGOProtos.dll + True + + + ..\packages\S2Geometry.1.0.3\lib\portable-net45+wp8+win8\S2Geometry.dll True @@ -63,11 +79,16 @@ + + + + + @@ -86,15 +107,22 @@ + + - + + + + + + @@ -104,6 +132,7 @@ + @@ -129,12 +158,6 @@ - - - {3BA89DFB-A162-420A-9DED-DAA211E52AD2} - POGOLib - -