/// <summary> /// Execute a command and waits for a response /// </summary> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> /// <param name="smooth"></param> /// <returns></returns> public async Task <CommandResult <T> > ExecuteCommandWithResponse <T>(METHODS method, int id = 0, List <object> parameters = null) { if (_currentCommandResults.ContainsKey(id)) { _currentCommandResults.Remove(id); } ExecuteCommand(method, id, parameters); DateTime startWait = DateTime.Now; while (!_currentCommandResults.ContainsKey(id) && DateTime.Now - startWait < TimeSpan.FromSeconds(5)) { await Task.Delay(10); } //wait for result during 5s //save results and remove if from results list if (_currentCommandResults.ContainsKey(id)) { CommandResult <T> result = _currentCommandResults[id] as CommandResult <T>; _currentCommandResults.Remove(id); return(result); } return(null); }
/// <summary> /// Gives a brief description of this function for the user /// </summary> /// <param name="M">The method you want info about.</param> /// <returns>String</returns> public static string GetDescription(METHODS M) { switch (M) { case METHODS.INIT: return("Login/ Initialize"); case METHODS.SCRIPT_ID: return("Provide Project Script ID"); case METHODS.CREATE_PROJECT: return("Create A New Project"); case METHODS.DOWNLOAD: return("Download Your Source Code"); case METHODS.DOWNLOAD_VERSION: return("Download Your Source Code for Version"); case METHODS.UPLOAD: return("Upload Your Changes"); case METHODS.UPLOAD_AND_VERSION: return("Upload Changes w/ New Version"); case METHODS.CREATE_FILE: return("Create Source Code File"); case METHODS.CREATE_MANIFEST: return("Create Manifest File (appsscript.json)"); case METHODS.CREATE_VERSION: return("Create New Version"); case METHODS.CREATE_VERSION_UPDATE_DEPLOYMENT: return("Create New Version and Update Deployment"); case METHODS.SYNC_DEPLOY_LIVE: return("Sync and Deploy for Live Version"); case METHODS.LIST_VERSIONS: return("List Your Project's Version History"); case METHODS.CHANGE_DEPLOYMENT_VERSION_NUM: return("Change Deployment's Assoc. Version Number"); case METHODS.CLEAR_CONSOLE: return("Clear the Console"); case METHODS.LOGOUT: return("Logout/ Remove Credentials"); case METHODS.EXIT: return("Exit"); default: return(""); } }
/// <summary> /// Check if the method is supported by the device /// </summary> /// <param name="method"></param> /// <returns></returns> private bool IsMethodSupported(METHODS method) { if (SupportedOperations?.Count != 0) { return(SupportedOperations.Contains(method)); } return(true); //no supported operations, so we can't check if the peration is permitted }
/// <summary> /// Execute a command and waits for a response /// </summary> /// <typeparam name="T"></typeparam> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> /// <returns></returns> public async Task <CommandResult <T> > ExecuteCommandWithResponse <T>(METHODS method, int id = 0, List <object> parameters = null) { try { return(await UnsafeExecuteCommandWithResponse <T>(method, id, parameters)); } catch (TaskCanceledException) { } return(null); }
private static StreamReader GetRequestResponse(METHODS method, string uri, object jsonRequest = null, bool tkRequired = true) { // build url string url = string.Format("{0}{1}", jsonBaseUrl, uri); // send request and get response int timeout = 60000; try { // create the request with defaults HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.AutomaticDecompression = DecompressionMethods.Deflate; req.Timeout = timeout; // add token if it is required if (tkRequired && !string.IsNullOrEmpty(token)) { req.Headers.Add("Authorization", token); } // setup request switch (method) { case METHODS.GET: req.Method = "GET"; break; case METHODS.POST: string send = JsonConvert.SerializeObject(jsonRequest); byte[] body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonRequest)); req.Method = "POST"; req.ContentType = "application/json"; req.Accept = "application/json"; req.ContentLength = body.Length; Stream reqStream = req.GetRequestStream(); reqStream.Write(body, 0, body.Length); reqStream.Close(); break; default: break; } WebResponse resp = req.GetResponse(); return(new StreamReader(resp.GetResponseStream(), Encoding.UTF8)); } catch { } return(null); }
/// <summary> /// Execute a command and waits for a response /// </summary> /// <typeparam name="T"></typeparam> /// <param name="method"></param> /// <param name="parameters"></param> /// <returns></returns> public async Task <CommandResult <T> > ExecuteCommandWithResponse <T>(METHODS method, List <object> parameters = null) { if (IsMusicModeEnabled) { //music mode enabled, there will be no response, we should assume everything works int uniqueId = GetUniqueIdForCommand(); ExecuteCommand(method, uniqueId, parameters); return(new CommandResult <T>() { Id = uniqueId, Error = null, IsMusicResponse = true }); } //default behavior : send command and wait for response return(await ExecuteCommandWithResponse <T>(method, GetUniqueIdForCommand(), parameters)); }
/// <summary> /// Execute a command /// </summary> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> /// <param name="smooth"></param> public void ExecuteCommand(METHODS method, int id = 0, List <object> parameters = null) { Command command = new Command() { Id = id, Method = method.GetRealName(), Params = parameters ?? new List <object>() }; string data = JsonConvert.SerializeObject(command, _serializerSettings); byte[] sentData = Encoding.ASCII.GetBytes(data + Constantes.LineSeparator); // \r\n is the end of the message, it needs to be sent for the message to be read by the device lock (_syncLock) { _tcpClient.Client.Send(sentData); } }
public static string GetRealName(this METHODS method) { if (realNames.TryGetValue(method, out var cached)) { return(cached); } var realNameAttr = typeof(METHODS) .GetMember(method.ToString()) .Single() .GetCustomAttribute(realNameAttrType, false) ?? throw new MemberAccessException($"[RealName] attribute is missing on METHODS.{method}."); var realName = (string?)propertyNameProp.GetValue(realNameAttr) ?? throw new MemberAccessException($"PropertyName of [RealName] attribute for METHODS.{method} was null."); _ = realNames.TryAdd(method, realName); return(realName); }
/// <summary> /// Execute a command and waits for a response (Unsafe because of Task Cancelation) /// </summary> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> /// <exception cref="TaskCanceledException"></exception> /// <returns></returns> private Task <CommandResult <T> > UnsafeExecuteCommandWithResponse <T>(METHODS method, int id = 0, List <object> parameters = null) { CommandResultHandler <T> commandResultHandler; lock (_currentCommandResults) { if (_currentCommandResults.TryGetValue(id, out ICommandResultHandler oldHandler)) { oldHandler.TrySetCanceled(); _currentCommandResults.Remove(id); } commandResultHandler = new CommandResultHandler <T>(); _currentCommandResults.Add(id, commandResultHandler); } ExecuteCommand(method, id, parameters); return(commandResultHandler.Task); }
/// <summary> /// Execute a command /// </summary> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> public void ExecuteCommand(METHODS method, int id = 0, List <object> parameters = null) { if (!IsMethodSupported(method)) { throw new InvalidOperationException($"The operation {method.GetRealName()} is not allowed by the device"); } Command command = new Command() { Id = id, Method = method.GetRealName(), Params = parameters ?? new List <object>() }; string data = JsonConvert.SerializeObject(command, Constants.DeviceSerializerSettings); byte[] sentData = Encoding.ASCII.GetBytes(data + Constants.LineSeparator); // \r\n is the end of the message, it needs to be sent for the message to be read by the device lock (_syncLock) { _tcpClient.Client.Send(sentData); } }
/// <summary> /// Execute a command and waits for a response (Unsafe because of Task Cancelation) /// </summary> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> /// <exception cref="TaskCanceledException"></exception> /// <returns></returns> private async Task <CommandResult <T> > UnsafeExecuteCommandWithResponse <T>(METHODS method, int id = 0, List <object> parameters = null) { CommandResultHandler <T> commandResultHandler; lock (_currentCommandResults) { if (_currentCommandResults.TryGetValue(id, out ICommandResultHandler oldHandler)) { oldHandler.TrySetCanceled(); _currentCommandResults.Remove(id); } commandResultHandler = new CommandResultHandler <T>(); _currentCommandResults.Add(id, commandResultHandler); } try { ExecuteCommand(method, id, parameters); return(await commandResultHandler.Task); } finally { lock (_currentCommandResults) { // remove the command if its the current handler in the dictionary if (_currentCommandResults.TryGetValue(id, out ICommandResultHandler currentHandler)) { if (commandResultHandler == currentHandler) { _currentCommandResults.Remove(id); } } } } }
/// <summary> /// Execute a command and waits for a response /// </summary> /// <typeparam name="T"></typeparam> /// <param name="method"></param> /// <param name="parameters"></param> /// <returns></returns> public async Task <CommandResult <T> > ExecuteCommandWithResponse <T>(METHODS method, List <object> parameters = null) { return(await ExecuteCommandWithResponse <T>(method, GetUniqueIdForCommand(), parameters)); }
private static DiscordResponse Send(METHODS method, string path, string json, string token) { HttpClient client; HttpRequestMessage request; string url = $"https://discord.com/api/" + path; // This is bad but I can't think of any other way to implement // multi-method support switch (method) { case METHODS.GET: client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Get, url); break; case METHODS.PUT: client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Put, url); break; case METHODS.POST: client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Post, url); break; case METHODS.PATCH: client = new HttpClient(); request = new HttpRequestMessage(new HttpMethod("PATCH"), url); break; case METHODS.DELETE: client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Delete, url); break; case METHODS.OPTIONS: client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Options, url); break; default: client = new HttpClient(); request = new HttpRequestMessage(HttpMethod.Post, url); break; } if (json != null) { client.DefaultRequestHeaders.Accept.Add( new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json") ); request.Content = new StringContent(json, Encoding.UTF8, "application/json"); } // Add the 'authorisation' header request.Headers.Add("authorization", token); // Send the request and return the result as response return(new DiscordResponse(client.SendAsync(request).Result)); }
/// <summary> /// Execute a command and waits for a response /// </summary> /// <param name="method"></param> /// <param name="id"></param> /// <param name="parameters"></param> /// <param name="smooth"></param> /// <returns></returns> public async Task <CommandResult> ExecuteCommandWithResponse(METHODS method, int id = 0, List <object> parameters = null) { CommandResult <List <string> > result = await ExecuteCommandWithResponse <List <string> >(method, id, parameters); return(result as CommandResult); }
/// <summary> /// Execute a command /// </summary> /// <param name="method"></param> /// <param name="parameters"></param> public void ExecuteCommand(METHODS method, List <object> parameters = null) { ExecuteCommand(method, GetUniqueIdForCommand(), parameters); }
/// <summary> /// A rather ridiculous function to pretty print a selection box for the user. /// </summary> private static void printQuestionBox() { System.Text.StringBuilder buffer = new System.Text.StringBuilder("+"); for (int spacing = 1; spacing < totalSpace; spacing++) { if (spacing == (totalSpace - 1) / 2 || spacing == totalSpace - 1) { buffer.Append("+"); } else { buffer.Append("="); } } string box = buffer.ToString(); PrintCentered(box); for (int i = 0; i < methods.Length; i++) { METHODS method = (METHODS)methods.GetValue(i); string des = GetDescription(method); buffer.Clear(); for (int spacing = 0; spacing < bufferSpace - des.Length; spacing++) { buffer.Append("—"); } string column1 = string.Format("| {0}{1}{2}{3} |", i, hyphen(i), buffer.ToString(), GetDescription(method)); i++; if (i < methods.Length) { method = (METHODS)methods.GetValue(i); des = GetDescription(method); buffer.Clear(); for (int spacing = 0; spacing < bufferSpace - des.Length; spacing++) { buffer.Append("-"); } PrintCentered(string.Format("{4} {2}{3}{1}{0} |", i, hyphen(i), GetDescription(method), buffer.ToString(), column1)); buffer.Clear(); //Prints in-between spacing if (i < methods.Length - 1) { for (int spacing = 0; spacing < bufferSpace + otherSpace; spacing++) { buffer.Append(" "); } PrintCentered(string.Format("| {0} | {1} |", buffer.ToString(), buffer.ToString())); } } else { des = ""; buffer.Clear(); for (int spacing = 0; spacing < bufferSpace - des.Length; spacing++) { buffer.Append(" "); } PrintCentered(string.Format("{1} {0}|", buffer.ToString(), column1)); } } PrintCentered(box); }
private static string sdGetRequestResponse(METHODS method, string uri, object jsonRequest = null, bool tkRequired = true) { // clear errorstring ErrorString = string.Empty; // build url string url = string.Format("{0}{1}{2}", jsonBaseUrl, jsonApi, uri); // send request and get response int maxTries = 1; int cntTries = 0; int timeout = 300000; do { try { // create the request with defaults HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.UserAgent = userAgent; req.AutomaticDecompression = DecompressionMethods.Deflate; req.Timeout = timeout; ++cntTries; // add token if it is required if (!string.IsNullOrEmpty(sdToken) && tkRequired) { req.Headers.Add("token", sdToken); } // setup request switch (method) { case METHODS.GET: req.Method = "GET"; break; case METHODS.GETVERBOSEMAP: req.Method = "GET"; req.Headers["verboseMap"] = "true"; break; case METHODS.PUT: req.Method = "PUT"; break; case METHODS.DELETE: req.Method = "DELETE"; break; case METHODS.POST: string send = JsonConvert.SerializeObject(jsonRequest); byte[] body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonRequest)); req.Method = "POST"; req.ContentType = "application/json"; req.Accept = "application/json"; req.ContentLength = body.Length; Stream reqStream = req.GetRequestStream(); reqStream.Write(body, 0, body.Length); reqStream.Close(); break; default: break; } WebResponse resp = req.GetResponse(); return(new StreamReader(resp.GetResponseStream(), Encoding.UTF8).ReadToEnd()); } catch (WebException wex) { switch (wex.Status) { case WebExceptionStatus.Timeout: if ((wex.Status == WebExceptionStatus.Timeout) && (cntTries <= maxTries)) { Logger.WriteVerbose(string.Format("SD API WebException Thrown. Message: {0} , Status: {1} . Trying again.", wex.Message, wex.Status)); } break; default: Logger.WriteVerbose(string.Format("SD API WebException Thrown. Message: {0} , Status: {1}", wex.Message, wex.Status)); try { StreamReader sr = new StreamReader(wex.Response.GetResponseStream(), Encoding.UTF8); sdError err = JsonConvert.DeserializeObject <sdError>(sr.ReadToEnd()); if (err != null) { ErrorString = string.Format("Message: {0} Response: {1}", err.Message ?? string.Empty, err.Response ?? string.Empty); Logger.WriteVerbose(string.Format("SD responded with error code: {0} , message: {1} , serverID: {2} , datetime: {3}", err.Code, err.Message ?? err.Response, err.ServerID, err.Datetime)); } } catch { } break; // try again until maxTries } } catch (Exception ex) { Logger.WriteError(string.Format("SD API Unknown exception thrown. Message: {0}", ex.Message)); return(null); } } while (cntTries <= maxTries); // failed miserably Logger.WriteError("Failed to complete request. Exiting"); return(null); }