Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ///////////////////////////////////////////////////////////////////////////////
- // OptiMargin
- // Copyright(c) 2017-2018, Ulysses Commodities
- //---------------------------------------------------------------------------//
- // Simple auto updater for OptiMargin.
- //
- // ----------------
- // Author : Dmitry «Vortex» Koteroff
- // E-mail : krakean@outlook.com
- // Skype : internat1onale
- // Telegram : @Krakean
- // Slack : Dmitry Koteroff
- //---------------------------------------------------------------------------//
- // Date Ver Who Comment //
- // -------- --- --- ------- //
- // 17.12.18 1.0 VtX Created
- // 05.01.19 2.0 VtX Rewritten
- ///////////////////////////////////////////////////////////////////////////////
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using RestSharp;
- using Switch.Cmd.Shared;
- using Switch.Cmd.Shared.Components;
- using System;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Security.Cryptography;
- using tar_cs;
- namespace SwitchCmd.Updater
- {
- class Program
- {
- /// <summary>
- /// Entry point.
- /// </summary>
- /// <param name="args">Arguments list, see remarks for details</param>
- /// <remarks>
- /// Arguments list is following:
- /// -n to create new update package.
- /// -f to specify that this update is mandatory and its better to update.
- /// It is decision on frontend side what to do with this info when reported after -c.
- /// -c to check whether new version is available.
- /// -u perform the update to new version. should be called only after -c.
- ///
- /// All of them above also expect: --clientid integer and --clientsecret "string"
- /// </remarks>
- static void Main(string[] args)
- {
- var input = String.Join(" ", args);
- var arg = Arguments.Parse(input).ArgumentDictionary;
- bool fail = false;
- if (arg == null)
- fail = true;
- // Mandatory args
- else if (!arg.ContainsKey("clientid") || !arg.ContainsKey("clientsecret"))
- fail = true;
- VersionInfo.Initialize();
- // Before we proceed, lets check whether this client is can receive updates at all
- if (!fail && !IsClientActive(arg["clientid"].ToString(), arg["clientsecret"].ToString()))
- {
- Console.WriteLine("Error: client inactive");
- return;
- }
- if (!fail && arg.ContainsKey("c"))
- ProceedCheckUpdate(arg["clientid"].ToString(), arg["clientsecret"].ToString());
- else
- fail = true;
- if (fail)
- Console.WriteLine("Error: wrong arguments");
- }
- /// <summary>
- /// Perform REST request to Optimargin API.
- /// </summary>
- /// <param name="clientid">Client's ID</param>
- /// <param name="clientsecret">Client's secret</param>
- /// <param name="query">Either update_check or client_check</param>
- static JObject PerformRequest(string clientid, string clientsecret, string query)
- {
- // Base URL for REST client.
- var client = new RestClient($"https://api.optimargin.com");
- client.Timeout = 3000;
- // Compose request URL
- var request = new RestRequest("{clientid}/{clientsecret}/{query}", Method.GET);
- request.Timeout = 3000;
- request.AddUrlSegment("clientid", clientid);
- request.AddUrlSegment("clientsecret", clientsecret);
- request.AddUrlSegment("query", query);
- // Execute request and get response.
- IRestResponse response = client.Execute(request);
- var jsoncontent = response.Content;
- // Json can be empty either due to server error, connection timeout,
- // or any other possible issue. Anyway, just show simple error
- // that indicates something went wrong.
- if (jsoncontent == String.Empty)
- {
- Console.WriteLine("Error: cannot get data");
- return null;
- }
- JsonTextReader reader = new JsonTextReader(new StringReader(jsoncontent));
- JObject obj = (JObject) JToken.ReadFrom(reader);
- // This also can be possible due to issue with parsing json.
- if (obj == null)
- {
- Console.WriteLine("Error: malformed json");
- return null;
- }
- // For example, if given client is not found.
- if (obj.ContainsKey("error"))
- {
- Console.WriteLine("Error: " + obj["error"]);
- return null;
- }
- return obj;
- }
- /// <summary>
- /// Checks whether this client is active and allowed to receive updates
- /// </summary>
- /// <param name="clientid"></param>
- /// <param name="clientsecret"></param>
- /// <returns></returns>
- static bool IsClientActive(string clientid, string clientsecret)
- {
- var obj = PerformRequest(clientid, clientsecret, "client_check");
- if (obj == null)
- return false;
- if (!obj.ContainsKey("user"))
- {
- // Seems like server-side issue.
- Console.WriteLine("Error: malformed client json");
- return false;
- }
- JToken user = obj["user"];
- return (bool)user["active"];
- }
- /// <summary>
- /// Perform check for updates availablity, and if update is available, perform the update.
- /// </summary>
- /// <param name="clientid">client's id</param>
- /// <param name="clientsecret">client's secret</param>
- static async void ProceedCheckUpdate(string clientid, string clientsecret)
- {
- var obj = PerformRequest(clientid, clientsecret, "update_check");
- if (obj == null)
- return;
- if (!obj.ContainsKey("updates"))
- {
- // Seems like server-side issue
- Console.WriteLine("Error: malformed updates json");
- return;
- }
- if (obj.ContainsKey("error"))
- {
- // For example, "Your account is disabled".
- Console.WriteLine("Error: " + obj["error"]);
- return;
- }
- JArray updates = (JArray) obj["updates"];
- if (!updates.Any())
- {
- // Though, its not really correct.
- // It means that updates array is empty, which can be possible issue on server side.
- // But for client, in result, its just no updates after all.
- Console.WriteLine("No update available");
- return;
- }
- // We have only last update in array.
- JToken update = updates[0];
- // Get the version tag and compare it with current running version
- string tag = (string)update["tagname"];
- tag = tag.Replace("v", "");
- tag = tag.Replace(".", "");
- // Running version
- int verRun = Int32.Parse(VersionInfo.Format("{MAJOR}{MINOR}{PATCH}"));
- // Version from update.
- int verUpd = Int32.Parse(tag);
- if (verUpd > verRun)
- Console.WriteLine("Update available: " + (string)update["tagname"]);
- else
- {
- Console.WriteLine("No update available");
- return;
- }
- Console.WriteLine("Downloading update...");
- var update_archive = Path.Combine(Utils.GetStoreFolder(), "update.tar");
- using (var webcl = new WebClient())
- {
- webcl.DownloadFile((string)update["fileurl"], update_archive);
- }
- if (!File.Exists(update_archive))
- {
- Console.WriteLine("Error: update archive is not exists");
- return;
- }
- Console.WriteLine("Done. Check md5...");
- using (var md5 = MD5.Create())
- {
- using (var stream = File.OpenRead(update_archive))
- {
- var hash = md5.ComputeHash(stream);
- string updMd5 = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
- if (updMd5 != (string) update["filemd5"])
- {
- Console.WriteLine("Error: md5 hash mismatch");
- return;
- }
- }
- }
- Console.WriteLine("Done. Extracting update...");
- var updDestFolder = Path.Combine(Utils.GetStoreFolder(), "Update", (string) update["tagname"]);
- using (var archTar = File.OpenRead(update_archive))
- {
- TarReader reader = new TarReader(archTar);
- await reader.ReadToEndAsync(updDestFolder);
- }
- Console.WriteLine("Done. Removing update.tar...");
- File.Delete(update_archive);
- Console.WriteLine("Done. Update location: " + updDestFolder);
- Console.WriteLine("Updater closing now...");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement