diff --git a/Common/UITranslation.cs b/Common/UITranslation.cs
index 7ceaf9f..deca880 100644
--- a/Common/UITranslation.cs
+++ b/Common/UITranslation.cs
@@ -52,8 +52,11 @@ public class UITranslation
[Description("Theme")]
public string Theme { get; set; }
-
- [Description("Enter your command")]
+
+ [Description("Scheme")]
+ public string Scheme { get; set; }
+
+ [Description("Enter your Command")]
public string InputCommand { get; set; }
#endregion
@@ -61,11 +64,11 @@ public class UITranslation
[Description("Zoom In")]
public string ZoomIn { get; set; }
-
- [Description("ZoomOut")]
+
+ [Description("Zoom Out")]
public string ZoomOut { get; set; }
- [Description("Clear map")]
+ [Description("Clear Map")]
public string ClearMap { get; set; }
[Description("Walk Here")]
@@ -77,7 +80,7 @@ public class UITranslation
[Description("100% IV")]
public string TabSnipeIV100 { get; set; }
- [Description("Rare pokemon")]
+ [Description("Rare Pokemon")]
public string TabSnipeRarePokemon { get; set; }
[Description("Others")]
@@ -142,12 +145,12 @@ public class UITranslation
[Description("Snipe Upgrade Setting")]
public string MenuUpgradeFilterText { get; set; }
-
[Description("This pokemon can be evolve to below pokemon , please select the branch you want to evolve to")]
public string EvolveConfirm { get; set; }
[Description("Evolve Pokemon")]
public string EvolvePopupCaption { get; set; }
+
[Description("Search & Filters")]
public string FilterAndSearch { get; set; }
@@ -238,22 +241,19 @@ public class UITranslation
[Description("Longitude")]
public string Longitude { get; set; }
-
[Description("Distance")]
public string Distance { get; set; }
-
[Description("Close")]
public string Close { get; set; }
-
- [Description("WalkHere")]
+ [Description("Walk Here")]
public string WalkToHere { get; set; }
[Description("CP")]
public string GymDefenderCP { get; set; }
- [Description("Gym Point")]
+ [Description("Gym Points")]
public string GymPoints { get; set; }
[Description("Pokestops: {0}")]
@@ -267,10 +267,13 @@ public class UITranslation
[Description("Transfered: {0}")]
public string PokemonTransfered { get; set; }
+
[Description("HIDE")]
public string Hide { get; set; }
+
[Description("SHOW")]
public string Show { get; set; }
+
[Description("Transfer filter - {0}")]
public string TransferFilterFormTitle { get; set; }
#endregion
diff --git a/Config/log4net.config b/Config/log4net.config
new file mode 100644
index 0000000..c1ebe95
--- /dev/null
+++ b/Config/log4net.config
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Config/log4net.unix.config b/Config/log4net.unix.config
new file mode 100644
index 0000000..3b07772
--- /dev/null
+++ b/Config/log4net.unix.config
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PoGo.NecroBot.Logic.csproj b/PoGo.NecroBot.Logic.csproj
index 09b3387..aeba393 100644
--- a/PoGo.NecroBot.Logic.csproj
+++ b/PoGo.NecroBot.Logic.csproj
@@ -1,4 +1,4 @@
-
+
@@ -119,6 +119,9 @@
$(SolutionDir)\packages\LiteDB.3.1.0\lib\net35\LiteDB.dll
True
+
+ $(SolutionDir)\packages\log4net.2.0.3\lib\net40-full\log4net.dll
+
$(SolutionDir)\packages\Microsoft.AspNet.SignalR.Client.2.2.1\lib\net45\Microsoft.AspNet.SignalR.Client.dll
True
@@ -140,6 +143,24 @@
$(SolutionDir)\packages\SocketIoClientDotNet.0.9.13\lib\net45\SocketIoClientDotNet.dll
True
+
+ $(SolutionDir)\packages\SuperSocket.1.6.6.1\lib\net45\SuperSocket.Common.dll
+
+
+ $(SolutionDir)\packages\SuperSocket.1.6.6.1\lib\net45\SuperSocket.Facility.dll
+
+
+ $(SolutionDir)\packages\SuperSocket.1.6.6.1\lib\net45\SuperSocket.SocketBase.dll
+
+
+ $(SolutionDir)\packages\SuperSocket.Engine.1.6.6.1\lib\net45\SuperSocket.SocketEngine.dll
+
+
+ $(SolutionDir)\packages\SuperSocket.Engine.1.6.6.1\lib\net45\SuperSocket.SocketService.exe
+
+
+ $(SolutionDir)\packages\SuperSocket.WebSocket.1.6.6.1\lib\net45\SuperSocket.WebSocket.dll
+
True
@@ -148,6 +169,7 @@
+
$(SolutionDir)\packages\System.Console.4.3.0\lib\net46\System.Console.dll
@@ -218,6 +240,9 @@
$(SolutionDir)\packages\Selenium.Support.3.3.0\lib\net40\WebDriver.Support.dll
+
+ $(SolutionDir)\packages\WebSocketSharp.1.0.3-rc11\lib\websocket-sharp.dll
+
$(SolutionDir)\packages\WebSocket4Net.0.14.1\lib\net45\WebSocket4Net.dll
True
@@ -427,6 +452,7 @@
True
Resources.resx
+
@@ -456,6 +482,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -582,6 +650,8 @@
Resources.Designer.cs
+
+
@@ -614,4 +684,4 @@
-->
-
+
\ No newline at end of file
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
index 89b8026..13735ee 100644
--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -40,6 +40,6 @@
// [assembly: AssemblyVersion1("1.0.0.134")]
-[assembly: AssemblyVersion("1.0.0.157")]
+[assembly: AssemblyVersion("1.0.0.158")]
[assembly: AssemblyFileVersion("1.0.0.0")]
-[assembly: AssemblyInformationalVersion("v1.0.0.157")]
\ No newline at end of file
+[assembly: AssemblyInformationalVersion("v1.0.0.158")]
\ No newline at end of file
diff --git a/Service/BotDataSocketClient.cs b/Service/BotDataSocketClient.cs
new file mode 100644
index 0000000..7c534bc
--- /dev/null
+++ b/Service/BotDataSocketClient.cs
@@ -0,0 +1,524 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PoGo.NecroBot.Logic.Event;
+using PoGo.NecroBot.Logic.Event.Snipe;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using POGOProtos.Enums;
+using WebSocketSharp;
+using Logger = PoGo.NecroBot.Logic.Logging.Logger;
+using System.Runtime.Caching;
+using System.Reflection;
+using TinyIoC;
+
+namespace PoGo.NecroBot.Logic.Service
+{
+ public class BotDataSocketClient
+ {
+ public class SocketMessage
+ {
+ public string Header { get; set; }
+ public string Body { get; set; }
+ public long TimeTimestamp { get; set; }
+ public string Hash { get; set; }
+ }
+ public class SocketClientUpdate
+ {
+ public List Pokemons { get; set; }
+
+ public List SnipeFailedPokemons { get; set; }
+ public List ExpiredPokemons { get; set; }
+ public string ClientVersion { get; set; }
+ public List ManualSnipes { get; set; }
+ public string Identitier { get; set; }
+
+ public SocketClientUpdate()
+ {
+ Identitier = TinyIoCContainer.Current.Resolve().LogicSettings.DataSharingConfig.DataServiceIdentification;
+ ManualSnipes = new List();
+ Pokemons = new List();
+ SnipeFailedPokemons = new List();
+ ExpiredPokemons = new List();
+ ClientVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+
+ }
+
+ public bool HasData()
+ {
+ return Pokemons.Count > 0 || SnipeFailedPokemons.Count > 0 || ExpiredPokemons.Count > 0;
+ }
+ }
+ private static SocketClientUpdate clientData = new SocketClientUpdate();
+
+ private const int POLLING_INTERVAL = 5000;
+
+ public static void HandleEvent(AllBotSnipeEvent e, ISession session)
+ {
+ lock(clientData)
+ {
+ if(!string.IsNullOrEmpty(clientData.Identitier))
+ {
+ clientData.ManualSnipes.Add(e.EncounterId);
+ }
+ }
+ }
+ public static void HandleEvent(IEvent evt, ISession session)
+ {
+ }
+ public static void HandleEvent(SnipeFailedEvent e, ISession sesion)
+ {
+ lock (clientData)
+ {
+ clientData.SnipeFailedPokemons.Add(e);
+ }
+ }
+
+ public static void Listen(IEvent evt, ISession session)
+ {
+ dynamic eve = evt;
+
+ try
+ {
+ HandleEvent(eve, session);
+ }
+ catch
+ {
+ }
+ }
+
+ private static void HandleEvent(EncounteredEvent eve, ISession session)
+ {
+ lock (clientData)
+ {
+ if (eve.IsRecievedFromSocket || cache.Get(eve.EncounterId) != null) return;
+ clientData.Pokemons.Add(eve);
+ }
+ }
+ //private static SnipePokemonUpdateEvent lastEncouteredEvent;
+ private static void HandleEvent(SnipePokemonUpdateEvent eve, ISession session)
+ {
+ lock(clientData)
+ {
+ clientData.ExpiredPokemons.Add(eve.EncounterId);
+ }
+ }
+ private static string Serialize(dynamic evt)
+ {
+ var jsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
+
+ // Add custom seriaizer to convert uong to string (ulong shoud not appear to json according to json specs)
+ jsonSerializerSettings.Converters.Add(new IdToStringConverter());
+
+ string json = JsonConvert.SerializeObject(evt, Formatting.None, jsonSerializerSettings);
+ //json = Regex.Replace(json, @"\\\\|\\(""|')|(""|')", match => {
+ // if (match.Groups[1].Value == "\"") return "\""; // Unescape \"
+ // if (match.Groups[2].Value == "\"") return "'"; // Replace " with '
+ // if (match.Groups[2].Value == "'") return "\\'"; // Escape '
+ // return match.Value; // Leave \\ and \' unchanged
+ //});
+ return json;
+ }
+
+ static List processing = new List();
+
+ public static String SHA256Hash(String value)
+ {
+ StringBuilder Sb = new StringBuilder();
+ using (SHA256 hash = SHA256.Create())
+ {
+ Encoding enc = Encoding.UTF8;
+ Byte[] result = hash.ComputeHash(enc.GetBytes(value));
+
+ foreach (Byte b in result)
+ Sb.Append(b.ToString("x2"));
+ }
+
+ return Sb.ToString();
+ }
+
+ public static async Task Start(Session session, string encryptKey, CancellationToken cancellationToken)
+ {
+
+ //Disable autosniper service until finger out how to make it work with API change
+
+ await Task.Delay(30000, cancellationToken); //delay running 30s
+
+ ServicePointManager.Expect100Continue = false;
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ while (true && !termintated)
+ {
+ var socketURL = servers.Dequeue();
+ Logger.Write($"Connecting to {socketURL} ....");
+ await ConnectToServer(session, socketURL, encryptKey);
+ servers.Enqueue(socketURL);
+ }
+
+ }
+ public static async Task ConnectToServer(ISession session, string socketURL, string encryptKey)
+ {
+ if (!string.IsNullOrEmpty(session.LogicSettings.DataSharingConfig.SnipeDataAccessKey))
+ {
+ socketURL += "&access_key=" + session.LogicSettings.DataSharingConfig.SnipeDataAccessKey;
+ }
+
+ int retries = 0;
+ using (var ws = new WebSocket(socketURL))
+ {
+ ws.Log.Level = LogLevel.Fatal; ;
+ ws.Log.Output = (logData, message) =>
+ {
+ //silenly, no log exception message to screen that scare people :)
+ };
+
+ ws.OnMessage += (sender, e) => { OnSocketMessageRecieved(session, sender, e); };
+
+ ws.Connect();
+ while (true && !termintated)
+ {
+ try
+ {
+ if (retries == 3)
+ {
+ //failed to make connection to server times contiuing, temporary stop for 10 mins.
+ session.EventDispatcher.Send(new WarnEvent()
+ {
+ Message = $"Couldn't establish the connection to necrobot socket server : {socketURL}"
+ });
+ if (session.LogicSettings.DataSharingConfig.EnableFailoverDataServers && servers.Count > 1)
+ {
+ break;
+ }
+ await Task.Delay(1 * 60 * 1000);
+ retries = 0;
+ }
+
+ if (ws.ReadyState != WebSocketState.Open)
+ {
+ retries++;
+ ws.Connect();
+ }
+
+ while (ws.ReadyState == WebSocketState.Open && !termintated)
+ {
+ //Logger.Write("Connected to necrobot data service.");
+ retries = 0;
+
+ if (ws.IsAlive && clientData.HasData())
+ {
+ var data = JsonConvert.SerializeObject(clientData);// Serialize(processing);
+ clientData = new SocketClientUpdate();
+
+ var message = Encrypt(data, encryptKey);
+ var actualMessage = JsonConvert.SerializeObject(message);
+ ws.Send($"42[\"client-update\",{actualMessage}]");
+ }
+
+ await Task.Delay(POLLING_INTERVAL);
+ ws.Ping();
+ }
+ }
+ catch (IOException)
+ {
+ session.EventDispatcher.Send(new WarnEvent
+ {
+ Message = "Disconnected from necrobot socket. New connection will be established when service becomes available..."
+ });
+
+ }
+ catch (Exception)
+ {
+ }
+ finally
+ {
+ //everytime disconnected with server bot wil reconnect after 15 sec
+ await Task.Delay(POLLING_INTERVAL);
+ }
+ }
+ }
+ }
+
+ private static void OnSocketMessageRecieved(ISession session, object sender, MessageEventArgs e)
+ {
+ try
+ {
+ OnPokemonRemoved(session, e.Data);
+ OnPokemonUpdateData(session, e.Data);
+ OnPokemonData(session, e.Data);
+ OnSnipePokemon(session, e.Data);
+ OnServerMessage(session, e.Data);
+ }
+ catch (Exception ex)
+ {
+ Logger.Debug("ERROR TO ADD SNIPE< DEBUG ONLY " + ex.Message + "\r\n " + ex.StackTrace);
+ }
+ }
+
+ private static DateTime lastWarningMessage = DateTime.MinValue;
+ private static bool termintated = false;
+ private static void OnServerMessage(ISession session, string message)
+ {
+ var match = Regex.Match(message, "42\\[\"server-message\",(.*)]");
+ if (match != null && !string.IsNullOrEmpty(match.Groups[1].Value))
+ {
+ if (message.Contains("The connection has been denied")) {
+ termintated = true;
+ }
+ var messag = match.Groups[1].Value;
+ if (message.Contains("The connection has been denied") && lastWarningMessage > DateTime.Now.AddMinutes(-5)) return;
+ lastWarningMessage = DateTime.Now;
+ session.EventDispatcher.Send(new NoticeEvent()
+ {
+ Message = "(SNIPE SERVER) " + match.Groups[1].Value
+ });
+ }
+ }
+
+ private static void ONFPMBridgeData(ISession session, string message)
+ {
+ var match = Regex.Match(message, "42\\[\"fpm\",(.*)]");
+ if (match != null && !string.IsNullOrEmpty(match.Groups[1].Value))
+ {
+ //var data = JsonConvert.DeserializeObject>(match.Groups[1].Value);
+
+ // jjskuld - Ignore CS4014 warning for now.
+#pragma warning disable 4014
+ HumanWalkSnipeTask.AddFastPokemapItem(match.Groups[1].Value);
+#pragma warning restore 4014
+ }
+ }
+
+ public static bool CheckIfPokemonBeenCaught(double lat, double lng, PokemonId id, ulong encounterId,
+ ISession session)
+ {
+ string uniqueCacheKey =
+ $"{session.Settings.Username}{Math.Round(lat, 6)}{id}{Math.Round(lng, 6)}";
+ if (session.Cache.Get(uniqueCacheKey) != null) return true;
+ if (encounterId > 0 && session.Cache[encounterId.ToString()] != null) return true;
+
+ return false;
+ }
+
+ private static void OnPokemonUpdateData(ISession session, string message)
+ {
+ var match = Regex.Match(message, "42\\[\"pokemon-update\",(.*)]");
+ if (match != null && !string.IsNullOrEmpty(match.Groups[1].Value))
+ {
+ var data = JsonConvert.DeserializeObject(match.Groups[1].Value);
+ MSniperServiceTask.RemoveExpiredSnipeData(session, data.EncounterId);
+ }
+ }
+
+ private static void OnPokemonRemoved(ISession session, string message)
+ {
+ var match = Regex.Match(message, "42\\[\"pokemon-remove\",(.*)]");
+ if (match != null && !string.IsNullOrEmpty(match.Groups[1].Value))
+ {
+ var data = JsonConvert.DeserializeObject(match.Groups[1].Value);
+ MSniperServiceTask.RemoveExpiredSnipeData(session, data.EncounterId);
+ }
+ }
+
+ private static MemoryCache cache = new MemoryCache("dump");
+
+ //static int count = 0;
+ private static void OnPokemonData(ISession session, string message)
+ {
+ var match = Regex.Match(message, "42\\[\"pokemon\",(.*)]");
+ if (match != null && !string.IsNullOrEmpty(match.Groups[1].Value))
+ {
+ var data = JsonConvert.DeserializeObject(match.Groups[1].Value);
+ data.IsRecievedFromSocket = true;
+ if (Math.Abs(data.Latitude) > 90 || Math.Abs(data.Longitude) > 180)
+ {
+ return;
+ };
+
+ ulong.TryParse(data.EncounterId, out ulong encounterid);
+ if (encounterid > 0 && cache.Get(encounterid.ToString()) == null)
+ {
+ cache.Add(encounterid.ToString(), DateTime.Now, DateTime.Now.AddMinutes(15));
+ }
+
+ session.EventDispatcher.Send(data);
+ if (session.LogicSettings.DataSharingConfig.AutoSnipe)
+ {
+ var move1 = PokemonMove.MoveUnset;
+ var move2 = PokemonMove.MoveUnset;
+ Enum.TryParse(data.Move1, true, out move1);
+ Enum.TryParse(data.Move2, true, out move2);
+
+ bool caught = CheckIfPokemonBeenCaught(data.Latitude, data.Longitude,
+ data.PokemonId, encounterid, session);
+ if (!caught)
+ {
+ var added = MSniperServiceTask.AddSnipeItem(session, new MSniperServiceTask.MSniperInfo2()
+ {
+ UniqueIdentifier = data.EncounterId,
+ Latitude = data.Latitude,
+ Longitude = data.Longitude,
+ EncounterId = encounterid,
+ SpawnPointId = data.SpawnPointId,
+ PokemonId = (short)data.PokemonId,
+ Level = data.Level,
+ Iv = data.IV,
+ Move1 = move1,
+ Move2 = move2,
+ ExpiredTime = data.ExpireTimestamp
+ }).Result;
+ if (added)
+ {
+ session.EventDispatcher.Send(new AutoSnipePokemonAddedEvent(data));
+ }
+ }
+ }
+ }
+ }
+
+ private static void OnSnipePokemon(ISession session, string message)
+ {
+ var match = Regex.Match(message, "42\\[\"snipe-pokemon\",(.*)]");
+ if (match != null && !string.IsNullOrEmpty(match.Value) && !string.IsNullOrEmpty(match.Groups[1].Value))
+ {
+ var data = JsonConvert.DeserializeObject(match.Groups[1].Value);
+
+ //not your snipe item, return need more encrypt here and configuration to allow catch others item
+ if (string.IsNullOrEmpty(session.LogicSettings.DataSharingConfig.DataServiceIdentification) ||
+ string.IsNullOrEmpty(data.RecieverId) ||
+ data.RecieverId.ToLower() != session.LogicSettings.DataSharingConfig.DataServiceIdentification.ToLower()) return;
+
+ var move1 = PokemonMove.Absorb;
+ var move2 = PokemonMove.Absorb;
+ Enum.TryParse(data.Move1, true, out move1);
+ Enum.TryParse(data.Move1, true, out move2);
+ ulong.TryParse(data.EncounterId, out ulong encounterid);
+
+ bool caught = CheckIfPokemonBeenCaught(data.Latitude, data.Longitude, data.PokemonId, encounterid,
+ session);
+ if (caught)
+ {
+ Logger.Write("[SNIPE IGNORED] - Your snipe pokemon has already been cautgh by bot",
+ Logic.Logging.LogLevel.Sniper);
+ return;
+ }
+
+ MSniperServiceTask.AddSnipeItem(session, new MSniperServiceTask.MSniperInfo2()
+ {
+ UniqueIdentifier = data.EncounterId,
+ Latitude = data.Latitude,
+ Longitude = data.Longitude,
+ EncounterId = encounterid,
+ SpawnPointId = data.SpawnPointId,
+ Level = data.Level,
+ PokemonId = (short)data.PokemonId,
+ Iv = data.IV,
+ Move1 = move1,
+ ExpiredTime = data.ExpireTimestamp,
+ Move2 = move2
+ }, true).Wait();
+ }
+ }
+ private static Queue servers = new Queue();
+ public static Task StartAsync(Session session, string encryptKey,
+ CancellationToken cancellationToken = default(CancellationToken))
+ {
+ var config = session.LogicSettings.DataSharingConfig;
+
+ if (config.EnableSyncData)
+ {
+ servers.Enqueue(config.DataRecieverURL);
+
+ if (config.EnableFailoverDataServers)
+ {
+ foreach (var item in config.FailoverDataServers.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
+ {
+ servers.Enqueue(item);
+ }
+ }
+ }
+
+ return Task.Run(() => Start(session, encryptKey, cancellationToken), cancellationToken);
+ }
+
+ public static SocketMessage Encrypt(string message, string encryptKey)
+ {
+ var encryptedtulp = Encrypt(message, encryptKey, false);
+
+ var socketMessage = new SocketMessage()
+ {
+ TimeTimestamp = (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds,
+ Header = encryptedtulp.Item1,
+ Body = encryptedtulp.Item2
+ };
+ socketMessage.Hash = CalculateMD5Hash($"{socketMessage.TimeTimestamp}{socketMessage.Body}{socketMessage.Header}");
+
+ return socketMessage;
+ }
+ public static string CalculateMD5Hash(string input)
+ {
+ // step 1, calculate MD5 hash from input
+
+ MD5 md5 = MD5.Create();
+
+ byte[] inputBytes = Encoding.ASCII.GetBytes(input);
+
+ byte[] hash = md5.ComputeHash(inputBytes);
+
+ // step 2, convert byte array to hex string
+
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < hash.Length; i++)
+
+ {
+
+ sb.Append(hash[i].ToString("X2"));
+
+ }
+
+ return sb.ToString();
+
+ }
+
+
+ public static Tuple Encrypt(string toEncrypt, string key, bool useHashing)
+ {
+ byte[] keyArray;
+ byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);
+
+ if (useHashing)
+ {
+ MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
+ keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));
+ }
+ else
+ keyArray = Encoding.UTF8.GetBytes(key);
+
+ var tdes = new TripleDESCryptoServiceProvider()
+ {
+ Key = keyArray
+ };
+ // tdes.Mode = CipherMode.CBC; // which is default
+ // tdes.Padding = PaddingMode.PKCS7; // which is default
+
+ //Console.WriteLine("iv: {0}", Convert.ToBase64String(tdes.IV));
+
+ ICryptoTransform cTransform = tdes.CreateEncryptor();
+ byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0,
+ toEncryptArray.Length);
+ string iv = Convert.ToBase64String(tdes.IV);
+ string message = Convert.ToBase64String(resultArray, 0, resultArray.Length);
+ return new Tuple(iv, message);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/DropItemHandler.cs b/Service/WebSocketHandler/ActionCommands/DropItemHandler.cs
new file mode 100644
index 0000000..74ae6b7
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/DropItemHandler.cs
@@ -0,0 +1,27 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using POGOProtos.Inventory.Item;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class DropItemHandler : IWebSocketRequestHandler
+ {
+ public DropItemHandler()
+ {
+ Command = "DropItem";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await RecycleItemsTask.DropItem(session, (ItemId) message.ItemId, (int) message.Count);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/EvolvePokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/EvolvePokemonHandler.cs
new file mode 100644
index 0000000..6120a4a
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/EvolvePokemonHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class EvolvePokemonHandler : IWebSocketRequestHandler
+ {
+ public EvolvePokemonHandler()
+ {
+ Command = "EvolvePokemon";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await EvolveSpecificPokemonTask.Execute(session, (ulong) message.PokemonId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/FastpokemapHandler.cs b/Service/WebSocketHandler/ActionCommands/FastpokemapHandler.cs
new file mode 100644
index 0000000..ccb5ebc
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/FastpokemapHandler.cs
@@ -0,0 +1,29 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class FastpokemapHandler : IWebSocketRequestHandler
+ {
+ public FastpokemapHandler()
+ {
+ Command = "Fastpokemap";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ CatchState.AddFastPokemapItem(message.Data);
+
+ await HumanWalkSnipeTask.AddFastPokemapItem(message.Data);
+ //Console.WriteLine(JsonConvert.DeserializeObject(message.Data));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/FavoritePokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/FavoritePokemonHandler.cs
new file mode 100644
index 0000000..02c0fd0
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/FavoritePokemonHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class FavoritePokemonHandler : IWebSocketRequestHandler
+ {
+ public FavoritePokemonHandler()
+ {
+ Command = "FavoritePokemon";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await FavoritePokemonTask.Execute(session, (ulong) message.PokemonId, (bool) message.Favorite);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/HumanSnipePriorityPokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/HumanSnipePriorityPokemonHandler.cs
new file mode 100644
index 0000000..0a5da9f
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/HumanSnipePriorityPokemonHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class HumanSnipePriorityPokemonHandler : IWebSocketRequestHandler
+ {
+ public HumanSnipePriorityPokemonHandler()
+ {
+ Command = "SnipePokemon";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await HumanWalkSnipeTask.TargetPokemonSnip(session, (string) message.Id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/HumanSnipeRemovePokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/HumanSnipeRemovePokemonHandler.cs
new file mode 100644
index 0000000..a2e386c
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/HumanSnipeRemovePokemonHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class HumanSnipeRemovePokemonHandler : IWebSocketRequestHandler
+ {
+ public HumanSnipeRemovePokemonHandler()
+ {
+ Command = "RemovePokemon";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await HumanWalkSnipeTask.RemovePokemonFromQueue(session, (string) message.Id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/LevelUpPokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/LevelUpPokemonHandler.cs
new file mode 100644
index 0000000..d40274d
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/LevelUpPokemonHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class LevelUpPokemonHandler : IWebSocketRequestHandler
+ {
+ public string Command { get; private set; }
+
+ public LevelUpPokemonHandler()
+ {
+ Command = "LevelUpPokemon";
+ }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await LevelUpSpecificPokemonTask.Execute(session, (ulong) message.PokemonId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/SetConfigHandler.cs b/Service/WebSocketHandler/ActionCommands/SetConfigHandler.cs
new file mode 100644
index 0000000..21037b8
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/SetConfigHandler.cs
@@ -0,0 +1,69 @@
+#region using directives
+
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class SetConfigHandler : IWebSocketRequestHandler
+ {
+ public SetConfigHandler()
+ {
+ Command = "SetConfig";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ var profilePath = Path.Combine(Directory.GetCurrentDirectory(), "");
+ var profileConfigPath = Path.Combine(profilePath, "config");
+ var authFile = Path.Combine(profileConfigPath, "auth.json");
+ var configFile = Path.Combine(profileConfigPath, "config.json");
+
+ var jsonSerializeSettings = new JsonSerializerSettings
+ {
+ DefaultValueHandling = DefaultValueHandling.Include,
+ Formatting = Formatting.Indented,
+ Converters = new JsonConverter[] {new StringEnumConverter {CamelCaseText = true}}
+ };
+
+ await Task.Run(() =>
+ {
+ try
+ {
+ var authJson = JsonConvert.SerializeObject((JObject) message.AuthJson, jsonSerializeSettings);
+ if (!string.IsNullOrEmpty(authJson) && authJson != "null")
+ File.WriteAllText(authFile, authJson, Encoding.UTF8);
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ });
+
+ await Task.Run(() =>
+ {
+ try
+ {
+ var configJson = JsonConvert.SerializeObject((JObject) message.ConfigJson, jsonSerializeSettings);
+ if (!string.IsNullOrEmpty(configJson) && configJson != "null")
+ File.WriteAllText(configFile, configJson, Encoding.UTF8);
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/SetMoveToTargetHandler.cs b/Service/WebSocketHandler/ActionCommands/SetMoveToTargetHandler.cs
new file mode 100644
index 0000000..4aaba5e
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/SetMoveToTargetHandler.cs
@@ -0,0 +1,22 @@
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class SetMoveToTargetHandler : IWebSocketRequestHandler
+ {
+ public string Command { get; private set; }
+
+ public SetMoveToTargetHandler()
+ {
+ Command = "SetMoveToTarget";
+ }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await SetMoveToTargetTask.Execute((double) message.Latitude, (double) message.Longitude, (string) message.FortId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/SetTrainerNicknameHandler.cs b/Service/WebSocketHandler/ActionCommands/SetTrainerNicknameHandler.cs
new file mode 100644
index 0000000..3645bc8
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/SetTrainerNicknameHandler.cs
@@ -0,0 +1,61 @@
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Event;
+using PoGo.NecroBot.Logic.Model;
+using PoGo.NecroBot.Logic.State;
+using POGOProtos.Networking.Responses;
+using SuperSocket.WebSocket;
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class SetTrainerNicknameHandler : IWebSocketRequestHandler
+ {
+ public string Command { get; private set; }
+
+ public SetTrainerNicknameHandler()
+ {
+ Command = "SetNickname";
+ }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ string nickname = message.Data;
+
+ if (nickname.Length > 15)
+ {
+ session.EventDispatcher.Send(new NoticeEvent()
+ {
+ Message = "You selected too long Desired name, max length: 15!"
+ });
+ return;
+ }
+ if (nickname == session.Profile.PlayerData.Username) return;
+
+
+ using (var blocker = new BlockableScope(session, BotActions.UpdateProfile))
+ {
+ if (!await blocker.WaitToRun()) return;
+
+ var res = await session.Client.Misc.ClaimCodename(nickname);
+ if (res.Status == ClaimCodenameResponse.Types.Status.Success)
+ {
+ session.EventDispatcher.Send(new NoticeEvent()
+ {
+ Message = $"Your name is now: {res.Codename}"
+ });
+
+ session.EventDispatcher.Send(new NicknameUpdateEvent()
+ {
+ Nickname = res.Codename
+ });
+ }
+ else
+ {
+ session.EventDispatcher.Send(new NoticeEvent()
+ {
+ Message = $"Couldn't change your nickname"
+ });
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs
new file mode 100644
index 0000000..8ac5671
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs
@@ -0,0 +1,34 @@
+#region using directives
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class TransferPokemonHandler : IWebSocketRequestHandler
+ {
+ public TransferPokemonHandler()
+ {
+ Command = "TransferPokemon";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await TransferPokemonTask.Execute(
+ session,
+ session.CancellationTokenSource.Token,
+ new List
+ {
+ (ulong) message.PokemonId
+ }
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/ActionCommands/UpgradePokemonHandler.cs b/Service/WebSocketHandler/ActionCommands/UpgradePokemonHandler.cs
new file mode 100644
index 0000000..efd1cd5
--- /dev/null
+++ b/Service/WebSocketHandler/ActionCommands/UpgradePokemonHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.ActionCommands
+{
+ public class UpgradePokemonHandler : IWebSocketRequestHandler
+ {
+ public UpgradePokemonHandler()
+ {
+ Command = "UpgradePokemon";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await UpgradeSinglePokemonTask.Execute(session, (ulong) message.PokemonId, (bool) message.Max);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/EncodingHelper.cs b/Service/WebSocketHandler/EncodingHelper.cs
new file mode 100644
index 0000000..5a00807
--- /dev/null
+++ b/Service/WebSocketHandler/EncodingHelper.cs
@@ -0,0 +1,43 @@
+#region using directives
+
+using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler
+{
+ internal class EncodingHelper
+ {
+ public static string Serialize(dynamic evt)
+ {
+ var jsonSerializerSettings = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All};
+
+ // Add custom seriaizer to convert uong to string (ulong shoud not appear to json according to json specs)
+ jsonSerializerSettings.Converters.Add(new IdToStringConverter());
+
+ return JsonConvert.SerializeObject(evt, Formatting.None, jsonSerializerSettings);
+ }
+
+ public class IdToStringConverter : JsonConverter
+ {
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
+ JsonSerializer serializer)
+ {
+ var jt = JToken.ReadFrom(reader);
+ return jt.Value();
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return typeof(long) == objectType || typeof(ulong) == objectType;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ serializer.Serialize(writer, value.ToString());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/ConfigResponce.cs b/Service/WebSocketHandler/GetCommands/Events/ConfigResponce.cs
new file mode 100644
index 0000000..893efcb
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/ConfigResponce.cs
@@ -0,0 +1,16 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ public class ConfigResponce : IWebSocketResponce
+ {
+ public ConfigResponce(dynamic data, string requestID)
+ {
+ Command = "ConfigWeb";
+ Data = data;
+ RequestID = requestID;
+ }
+
+ public string RequestID { get; }
+ public string Command { get; }
+ public dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/EggListResponce.cs b/Service/WebSocketHandler/GetCommands/Events/EggListResponce.cs
new file mode 100644
index 0000000..f3d3c6f
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/EggListResponce.cs
@@ -0,0 +1,16 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ public class EggListResponce : IWebSocketResponce
+ {
+ public EggListResponce(dynamic data, string requestID)
+ {
+ Command = "EggListWeb";
+ Data = data;
+ RequestID = requestID;
+ }
+
+ public string RequestID { get; }
+ public string Command { get; }
+ public dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/ItemListResponce.cs b/Service/WebSocketHandler/GetCommands/Events/ItemListResponce.cs
new file mode 100644
index 0000000..2c6f036
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/ItemListResponce.cs
@@ -0,0 +1,16 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ internal class ItemListResponce : IWebSocketResponce
+ {
+ public ItemListResponce(dynamic data, string requestID)
+ {
+ Command = "ItemListWeb";
+ Data = data;
+ RequestID = requestID;
+ }
+
+ public string RequestID { get; }
+ public string Command { get; }
+ public dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/PokemonListResponce.cs b/Service/WebSocketHandler/GetCommands/Events/PokemonListResponce.cs
new file mode 100644
index 0000000..ecd9bf5
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/PokemonListResponce.cs
@@ -0,0 +1,22 @@
+#region using directives
+
+using PoGo.NecroBot.Logic.Event;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ public class PokemonListResponce : IWebSocketResponce, IEvent
+ {
+ public PokemonListResponce(dynamic data, string requestID)
+ {
+ Command = "PokemonListWeb";
+ Data = data;
+ RequestID = requestID;
+ }
+
+ public string RequestID { get; }
+ public string Command { get; }
+ public dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/SnipeListResponce.cs b/Service/WebSocketHandler/GetCommands/Events/SnipeListResponce.cs
new file mode 100644
index 0000000..a37b9a5
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/SnipeListResponce.cs
@@ -0,0 +1,16 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ internal class SnipeListResponce : IWebSocketResponce
+ {
+ public SnipeListResponce(dynamic data, string requestID)
+ {
+ Command = "HumanWalkSnipEvent";
+ Data = data;
+ RequestID = requestID;
+ }
+
+ public string RequestID { get; }
+ public string Command { get; }
+ public dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/TrainerProfileResponce.cs b/Service/WebSocketHandler/GetCommands/Events/TrainerProfileResponce.cs
new file mode 100644
index 0000000..c0fc68f
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/TrainerProfileResponce.cs
@@ -0,0 +1,16 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ internal class TrainerProfileResponce : IWebSocketResponce
+ {
+ public TrainerProfileResponce(dynamic data, string requestID)
+ {
+ Command = "TrainerProfile";
+ Data = data;
+ RequestID = requestID;
+ }
+
+ public string RequestID { get; }
+ public string Command { get; }
+ public dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Events/WebResponce.cs b/Service/WebSocketHandler/GetCommands/Events/WebResponce.cs
new file mode 100644
index 0000000..4621474
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Events/WebResponce.cs
@@ -0,0 +1,9 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events
+{
+ public class WebResponce : IWebSocketResponce
+ {
+ public string RequestID { get; set; }
+ public string Command { get; set; }
+ public dynamic Data { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetConfigHandler.cs b/Service/WebSocketHandler/GetCommands/GetConfigHandler.cs
new file mode 100644
index 0000000..faf2981
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetConfigHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ internal class GetConfigHandler : IWebSocketRequestHandler
+ {
+ public GetConfigHandler()
+ {
+ Command = "GetConfig";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await GetConfigTask.Execute(session, webSocketSession, (string) message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetEggListHandler.cs b/Service/WebSocketHandler/GetCommands/GetEggListHandler.cs
new file mode 100644
index 0000000..2d6b1f3
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetEggListHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ internal class GetEggListHandler : IWebSocketRequestHandler
+ {
+ public GetEggListHandler()
+ {
+ Command = "GetEggList";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await GetEggListTask.Execute(session, webSocketSession, (string) message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetItemsListHandler.cs b/Service/WebSocketHandler/GetCommands/GetItemsListHandler.cs
new file mode 100644
index 0000000..f25a63b
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetItemsListHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ internal class GetItemsListHandler : IWebSocketRequestHandler
+ {
+ public GetItemsListHandler()
+ {
+ Command = "GetItemsList";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await GetItemListTask.Execute(session, webSocketSession, (string) message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetPokemonListHandler.cs b/Service/WebSocketHandler/GetCommands/GetPokemonListHandler.cs
new file mode 100644
index 0000000..9343fcc
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetPokemonListHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ public class GetPokemonListHandler : IWebSocketRequestHandler
+ {
+ public GetPokemonListHandler()
+ {
+ Command = "GetPokemonList";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await GetPokemonListTask.Execute(session, webSocketSession, (string) message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetPokemonSettingsHandler.cs b/Service/WebSocketHandler/GetCommands/GetPokemonSettingsHandler.cs
new file mode 100644
index 0000000..d59254a
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetPokemonSettingsHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ public class GetPokemonSettingsHandler : IWebSocketRequestHandler
+ {
+ public GetPokemonSettingsHandler()
+ {
+ Command = "GetPokemonSettings";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await GetPokemonSettingsTask.Execute(session, webSocketSession, (string) message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetPokemonSnipeListHandler.cs b/Service/WebSocketHandler/GetCommands/GetPokemonSnipeListHandler.cs
new file mode 100644
index 0000000..8f0d62b
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetPokemonSnipeListHandler.cs
@@ -0,0 +1,23 @@
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ class GetPokemonSnipeListHandler : IWebSocketRequestHandler
+ {
+ public string Command { get; private set; }
+
+ public GetPokemonSnipeListHandler()
+ {
+ Command = "PokemonSnipeList";
+ }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await HumanWalkSnipeTask.ExecuteFetchData(session);
+ //await GetPokemonSnipeListTask.Execute(session, webSocketSession, (string)message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/GetTrainerProfileHandler.cs b/Service/WebSocketHandler/GetCommands/GetTrainerProfileHandler.cs
new file mode 100644
index 0000000..b27fd6e
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/GetTrainerProfileHandler.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands
+{
+ internal class GetTrainerProfileHandler : IWebSocketRequestHandler
+ {
+ public GetTrainerProfileHandler()
+ {
+ Command = "GetTrainerProfile";
+ }
+
+ public string Command { get; }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ await GetTrainerProfileTask.Execute(session, webSocketSession, (string) message.RequestID);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Helpers/ConfigWeb.cs b/Service/WebSocketHandler/GetCommands/Helpers/ConfigWeb.cs
new file mode 100644
index 0000000..56ce0ae
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Helpers/ConfigWeb.cs
@@ -0,0 +1,10 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers
+{
+ internal class ConfigWeb
+ {
+ public object AuthJson { get; set; }
+ public object AuthSchemaJson { get; set; }
+ public object ConfigJson { get; set; }
+ public object ConfigSchemaJson { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Helpers/EggListWeb.cs b/Service/WebSocketHandler/GetCommands/Helpers/EggListWeb.cs
new file mode 100644
index 0000000..dc08c9e
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Helpers/EggListWeb.cs
@@ -0,0 +1,8 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers
+{
+ internal class EggListWeb
+ {
+ public object Incubators { get; set; }
+ public object UnusedEggs { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Helpers/PokemonListWeb.cs b/Service/WebSocketHandler/GetCommands/Helpers/PokemonListWeb.cs
new file mode 100644
index 0000000..a12a49e
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Helpers/PokemonListWeb.cs
@@ -0,0 +1,26 @@
+#region using directives
+
+using PoGo.NecroBot.Logic.PoGoUtils;
+using POGOProtos.Data;
+using PoGo.NecroBot.Logic.State;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers
+{
+ public class PokemonListWeb
+ {
+ public PokemonData Base;
+ private readonly ISession _session;
+
+ public PokemonListWeb(ISession session, PokemonData data)
+ {
+ Base = data;
+ _session = session;
+ }
+
+ public double IvPerfection => PokemonInfo.CalculatePokemonPerfection(Base);
+ public double Level => PokemonInfo.GetLevel(Base);
+ public int FamilyCandies => PokemonInfo.GetCandy(_session, Base).Result;
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Helpers/TrainerProfileWeb.cs b/Service/WebSocketHandler/GetCommands/Helpers/TrainerProfileWeb.cs
new file mode 100644
index 0000000..392b942
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Helpers/TrainerProfileWeb.cs
@@ -0,0 +1,21 @@
+#region using directives
+
+using POGOProtos.Data;
+using POGOProtos.Data.Player;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers
+{
+ internal class TrainerProfileWeb
+ {
+ public PlayerData Profile;
+ public PlayerStats Stats;
+
+ public TrainerProfileWeb(PlayerData profile, PlayerStats stats)
+ {
+ Profile = profile;
+ Stats = stats;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetConfigTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetConfigTask.cs
new file mode 100644
index 0000000..f672f93
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetConfigTask.cs
@@ -0,0 +1,46 @@
+#region using directives
+
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetConfigTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ await Task.Run(() =>
+ {
+ var profilePath = Path.Combine(Directory.GetCurrentDirectory(), "");
+ var profileConfigPath = Path.Combine(profilePath, "config");
+
+ var authFile = Path.Combine(profileConfigPath, "auth.json");
+ var authSchemaFile = Path.Combine(profileConfigPath, "auth.schema.json");
+ var authJson = File.ReadAllText(authFile, Encoding.UTF8);
+ var authSchemaJson = File.ReadAllText(authSchemaFile, Encoding.UTF8);
+
+ var configFile = Path.Combine(profileConfigPath, "config.json");
+ var configSchemaFile = Path.Combine(profileConfigPath, "config.schema.json");
+ var configJson = File.ReadAllText(configFile, Encoding.UTF8);
+ var configSchemaJson = File.ReadAllText(configSchemaFile, Encoding.UTF8);
+
+ var list = new ConfigWeb
+ {
+ AuthJson = authJson,
+ AuthSchemaJson = authSchemaJson,
+ ConfigJson = configJson,
+ ConfigSchemaJson = configSchemaJson
+ };
+
+ webSocketSession.Send(EncodingHelper.Serialize(new ConfigResponce(list, requestID)));
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetEggListTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetEggListTask.cs
new file mode 100644
index 0000000..617c1bf
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetEggListTask.cs
@@ -0,0 +1,43 @@
+#region using directives
+
+using System.Linq;
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers;
+using PoGo.NecroBot.Logic.State;
+using POGOProtos.Inventory.Item;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetEggListTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ // using (var blocker = new BlockableScope(session, BotActions.Eggs))
+ {
+ // if (!await blocker.WaitToRun()) return;
+
+ var incubators = (await session.Inventory.GetEggIncubators())
+ .Where(x => x.UsesRemaining > 0 || x.ItemId == ItemId.ItemIncubatorBasicUnlimited)
+ .OrderByDescending(x => x.ItemId == ItemId.ItemIncubatorBasicUnlimited)
+ .ToList();
+
+ var unusedEggs = (await session.Inventory.GetEggs())
+ .Where(x => string.IsNullOrEmpty(x.EggIncubatorId))
+ .OrderBy(x => x.EggKmWalkedTarget - x.EggKmWalkedStart)
+ .ToList();
+
+
+ var list = new EggListWeb
+ {
+ Incubators = incubators,
+ UnusedEggs = unusedEggs
+ };
+ webSocketSession.Send(EncodingHelper.Serialize(new EggListResponce(list, requestID)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetItemListTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetItemListTask.cs
new file mode 100644
index 0000000..5f13b59
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetItemListTask.cs
@@ -0,0 +1,25 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetItemListTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ // using (var blocker = new BlockableScope(session, BotActions.ListItems))
+ {
+ //if (!await blocker.WaitToRun()) return;
+
+ var allItems = await session.Inventory.GetItems();
+ webSocketSession.Send(EncodingHelper.Serialize(new ItemListResponce(allItems, requestID)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonListTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonListTask.cs
new file mode 100644
index 0000000..b301e07
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonListTask.cs
@@ -0,0 +1,30 @@
+#region using directives
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetPokemonListTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ //using (var blocker = new BlockableScope(session, BotActions.ListItems))
+ {
+ //if (!await blocker.WaitToRun()) return;
+
+ var allPokemonInBag = await session.Inventory.GetHighestsCp(1000);
+ var list = new List();
+ allPokemonInBag.ToList().ForEach(o => list.Add(new PokemonListWeb(session, o)));
+ webSocketSession.Send(EncodingHelper.Serialize(new PokemonListResponce(list, requestID)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonSettingsTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonSettingsTask.cs
new file mode 100644
index 0000000..9ec6cd9
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonSettingsTask.cs
@@ -0,0 +1,30 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetPokemonSettingsTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ //using (var blocker = new BlockableScope(session, BotActions.PokemonSettings))
+ {
+ // if (!await blocker.WaitToRun()) return;
+
+ var settings = await session.Inventory.GetPokemonSettings();
+ webSocketSession.Send(EncodingHelper.Serialize(new WebResponce
+ {
+ Command = "PokemonSettings",
+ Data = settings,
+ RequestID = requestID
+ }));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonSnipeListTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonSnipeListTask.cs
new file mode 100644
index 0000000..129296f
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetPokemonSnipeListTask.cs
@@ -0,0 +1,22 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetPokemonSnipeListTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ var allItems = await HumanWalkSnipeTask.GetCurrentQueueItems(session);
+
+ webSocketSession.Send(EncodingHelper.Serialize(new SnipeListResponce(allItems, requestID)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/GetCommands/Tasks/GetTrainerProfileTask.cs b/Service/WebSocketHandler/GetCommands/Tasks/GetTrainerProfileTask.cs
new file mode 100644
index 0000000..7148cb6
--- /dev/null
+++ b/Service/WebSocketHandler/GetCommands/Tasks/GetTrainerProfileTask.cs
@@ -0,0 +1,30 @@
+#region using directives
+
+using System.Linq;
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Events;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Helpers;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler.GetCommands.Tasks
+{
+ internal class GetTrainerProfileTask
+ {
+ public static async Task Execute(ISession session, WebSocketSession webSocketSession, string requestID)
+ {
+ //using (var blocker = new BlockableScope(session, BotActions.GetProfile))
+ {
+ // if (!await blocker.WaitToRun()) return;
+
+ var playerStats = (await session.Inventory.GetPlayerStats()).FirstOrDefault();
+ if (playerStats == null)
+ return;
+ var tmpData = new TrainerProfileWeb(session.Profile.PlayerData, playerStats);
+ webSocketSession.Send(EncodingHelper.Serialize(new TrainerProfileResponce(tmpData, requestID)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/IWebSocketRequestHandler.cs b/Service/WebSocketHandler/IWebSocketRequestHandler.cs
new file mode 100644
index 0000000..db8db51
--- /dev/null
+++ b/Service/WebSocketHandler/IWebSocketRequestHandler.cs
@@ -0,0 +1,16 @@
+#region using directives
+
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler
+{
+ internal interface IWebSocketRequestHandler
+ {
+ string Command { get; }
+ Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message);
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/IWebSocketResponce.cs b/Service/WebSocketHandler/IWebSocketResponce.cs
new file mode 100644
index 0000000..851898b
--- /dev/null
+++ b/Service/WebSocketHandler/IWebSocketResponce.cs
@@ -0,0 +1,9 @@
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler
+{
+ internal interface IWebSocketResponce
+ {
+ string RequestID { get; }
+ string Command { get; }
+ dynamic Data { get; }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketHandler/WebSocketEventManager.cs b/Service/WebSocketHandler/WebSocketEventManager.cs
new file mode 100644
index 0000000..6078620
--- /dev/null
+++ b/Service/WebSocketHandler/WebSocketEventManager.cs
@@ -0,0 +1,59 @@
+#region using directives
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using PoGo.NecroBot.Logic.State;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service.WebSocketHandler
+{
+ internal class WebSocketEventManager
+ {
+ private readonly Dictionary _registerdHandlers =
+ new Dictionary();
+
+ public void RegisterHandler(string actionName, IWebSocketRequestHandler action)
+ {
+ try
+ {
+ _registerdHandlers.Add(actionName, action);
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+
+ public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
+ {
+ if (_registerdHandlers.ContainsKey((string) message.Command))
+ {
+ await _registerdHandlers[(string) message.Command].Handle(session, webSocketSession, message);
+ }
+ }
+
+ // Registers all IWebSocketRequestHandler's automatically.
+
+ public static WebSocketEventManager CreateInstance()
+ {
+ var manager = new WebSocketEventManager();
+
+ var type = typeof(IWebSocketRequestHandler);
+ var types = AppDomain.CurrentDomain.GetAssemblies()
+ .SelectMany(s => s.GetTypes())
+ .Where(p => type.IsAssignableFrom(p) && p.IsClass);
+
+ foreach (var plugin in types)
+ {
+ var instance = (IWebSocketRequestHandler) Activator.CreateInstance(plugin);
+ manager.RegisterHandler(instance.Command, instance);
+ }
+
+ return manager;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/WebSocketInterface.cs b/Service/WebSocketInterface.cs
new file mode 100644
index 0000000..7ea652d
--- /dev/null
+++ b/Service/WebSocketInterface.cs
@@ -0,0 +1,233 @@
+#region using directives
+
+using System.Linq;
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PoGo.NecroBot.Logic.Service.WebSocketHandler;
+using PoGo.NecroBot.Logic.Common;
+using PoGo.NecroBot.Logic.Event;
+using PoGo.NecroBot.Logic.Logging;
+using PoGo.NecroBot.Logic.State;
+using PoGo.NecroBot.Logic.Tasks;
+using SuperSocket.SocketBase;
+using SuperSocket.SocketBase.Config;
+using SuperSocket.WebSocket;
+
+#endregion
+
+namespace PoGo.NecroBot.Logic.Service
+{
+ public class WebSocketInterface
+ {
+ private readonly WebSocketServer _server;
+ private readonly Session _session;
+ private readonly WebSocketEventManager _websocketHandler;
+ private PokeStopListEvent _lastPokeStopList;
+ private ProfileEvent _lastProfile;
+
+ public WebSocketInterface(int port, Session session)
+ {
+ _session = session;
+ var translations = session.Translation;
+ _server = new WebSocketServer();
+ _websocketHandler = WebSocketEventManager.CreateInstance();
+ var config = new ServerConfig
+ {
+ Name = "NecroWebSocket",
+ Mode = SocketMode.Tcp,
+ MaxRequestLength = int.MaxValue,
+ Certificate = new CertificateConfig
+ {
+ FilePath = @"cert.pfx",
+ Password = "necro"
+ },
+ Listeners = new List
+ {
+ new ListenerConfig
+ {
+ Ip = "Any",
+ Port = port,
+ Security = "tls"
+ },
+ new ListenerConfig
+ {
+ Ip = "Any",
+ Port = port + 1,
+ Security = "none"
+ }
+ }
+ };
+
+ var setupComplete = _server.Setup(config);
+
+ if (setupComplete == false)
+ {
+ Logger.Write(translations.GetTranslation(TranslationString.WebSocketFailStart, port), LogLevel.Error);
+ return;
+ }
+
+ _server.NewMessageReceived += HandleMessage;
+ _server.NewSessionConnected += HandleSession;
+
+ if (_server.Start())
+ {
+ Logger.Write(translations.GetTranslation(TranslationString.WebSocketStarted, port, port + 1), LogLevel.Info);
+
+ }
+ else
+ {
+ Logger.Write($"Counld't start socket server at port {port}, this port may be in use or blocked, please change your config to another port and restart bot if you want to use web gui.", LogLevel.Error);
+ }
+ }
+
+ private void Broadcast(string message)
+ {
+ foreach (var session in _server.GetAllSessions())
+ {
+ try
+ {
+ session.Send(message);
+ }
+ catch (Exception)
+ {
+#if DEBUG
+ //Logger.Write(ex.Message);
+#endif
+ }
+ }
+ }
+
+ private void HandleEvent(PokeStopListEvent evt)
+ {
+ if (_lastPokeStopList != null)
+ {
+ _lastPokeStopList.Forts.RemoveAll(x => evt.Forts.Any(t => x.Id == x.Id));
+ _lastPokeStopList.Forts.AddRange(evt.Forts);
+ }
+ else
+ _lastPokeStopList = evt;
+ }
+
+ private void HandleEvent(ProfileEvent evt)
+ {
+ _lastProfile = evt;
+ }
+
+ private async void HandleMessage(WebSocketSession session, string message)
+ {
+ switch (message)
+ {
+ case "PokemonList":
+ await PokemonListTask.Execute(_session);
+ break;
+ case "EggsList":
+ await EggsListTask.Execute(_session);
+ break;
+ case "InventoryList":
+ await InventoryListTask.Execute(_session);
+ break;
+ case "PokemonSnipeList":
+ await HumanWalkSnipeTask.ExecuteFetchData(_session);
+ break;
+ }
+
+ // Setup to only send data back to the session that requested it.
+ try
+ {
+ dynamic decodedMessage = JObject.Parse(message);
+ var handle = _websocketHandler?.Handle(_session, session, decodedMessage);
+ if (handle != null)
+ await handle;
+ }
+ catch (Exception)
+ {
+#if DEBUG
+ //Logger.Write(ex.Message);
+#endif
+ }
+
+ // When we first get a message from the web socket, turn off log buffering.
+ // This allows us to flush out buffered LogEvent messages to the GUI.
+ Logger.TurnOffLogBuffering();
+ }
+
+ private void HandleSession(WebSocketSession session)
+ {
+ if (_lastProfile != null)
+ session.Send(Serialize(_lastProfile));
+
+ if (_lastPokeStopList != null)
+ session.Send(Serialize(_lastPokeStopList));
+
+ try
+ {
+ session.Send(Serialize(new UpdatePositionEvent
+ {
+ Latitude = _session.Client.CurrentLatitude,
+ Longitude = _session.Client.CurrentLongitude
+ }));
+ }
+ catch (Exception )
+ {
+#if DEBUG
+ //Logger.Write(ex.Message);
+#endif
+ }
+ }
+
+ public void HandleEvent(IEvent evt)
+ {
+ }
+
+ public void Listen(IEvent evt, Session session)
+ {
+ dynamic eve = evt;
+
+ try
+ {
+ HandleEvent(eve);
+ }
+ catch (Exception )
+ {
+#if DEBUG
+ //Logger.Write(ex.Message);
+#endif
+ // ignored
+ }
+
+ Broadcast(Serialize(eve));
+ }
+
+ private static string Serialize(dynamic evt)
+ {
+ var jsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
+
+ // Add custom seriaizer to convert uong to string (ulong shoud not appear to json according to json specs)
+ jsonSerializerSettings.Converters.Add(new IdToStringConverter());
+
+ return JsonConvert.SerializeObject(evt, Formatting.None, jsonSerializerSettings);
+ }
+ }
+
+ public class IdToStringConverter : JsonConverter
+ {
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
+ JsonSerializer serializer)
+ {
+ var jt = JToken.ReadFrom(reader);
+ return jt.Value();
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return typeof(long) == objectType || typeof(ulong) == objectType;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ serializer.Serialize(writer, value.ToString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages.config b/packages.config
index 4619692..95127ef 100644
--- a/packages.config
+++ b/packages.config
@@ -9,6 +9,7 @@
+
@@ -22,6 +23,9 @@
+
+
+
@@ -67,4 +71,5 @@
+
\ No newline at end of file