From 3b234f0a4dcfe7f4af047aa1ed35eaf5dc4534d1 Mon Sep 17 00:00:00 2001 From: JustArchi Date: Wed, 14 Feb 2018 19:14:33 +0100 Subject: [PATCH] Add /Api/GamesToRedeemInBackground P.S. Not tested yet, too lazy to do so as of now. --- ArchiSteamFarm/Bot.cs | 11 ++++- ArchiSteamFarm/IPC.cs | 104 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 103 insertions(+), 12 deletions(-) diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 6a0ca62f8..5b735e0e4 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -307,6 +307,15 @@ namespace ArchiSteamFarm { return await BotDatabase.MobileAuthenticator.HandleConfirmations(confirmations, accept).ConfigureAwait(false); } + internal async Task AddGamesToRedeemInBackground(IReadOnlyDictionary gamesToRedeemInBackground) { + if ((gamesToRedeemInBackground == null) || (gamesToRedeemInBackground.Count == 0)) { + ArchiLogger.LogNullError(nameof(gamesToRedeemInBackground)); + return; + } + + await BotDatabase.AddGamesToRedeemInBackground(gamesToRedeemInBackground).ConfigureAwait(false); + } + internal async Task DeleteAllRelatedFiles() { try { await BotDatabase.MakeReadOnly().ConfigureAwait(false); @@ -1350,7 +1359,7 @@ namespace ArchiSteamFarm { gamesToRedeemInBackground[key] = game; } - await BotDatabase.AddGamesToRedeemInBackground(gamesToRedeemInBackground).ConfigureAwait(false); + await AddGamesToRedeemInBackground(gamesToRedeemInBackground).ConfigureAwait(false); File.Delete(filePath); } } catch (Exception e) { diff --git a/ArchiSteamFarm/IPC.cs b/ArchiSteamFarm/IPC.cs index 200b47a79..129f94bea 100644 --- a/ArchiSteamFarm/IPC.cs +++ b/ArchiSteamFarm/IPC.cs @@ -152,6 +152,8 @@ namespace ArchiSteamFarm { case "Command": case "Command/": return await HandleApiCommand(context.Request, context.Response, arguments, ++argumentsIndex).ConfigureAwait(false); + case "GamesToRedeemInBackground/": + return await HandleApiGamesToRedeemInBackground(context.Request, context.Response, arguments, ++argumentsIndex).ConfigureAwait(false); case "Log": return await HandleApiLog(context, arguments, ++argumentsIndex).ConfigureAwait(false); case "Structure/": @@ -309,34 +311,34 @@ namespace ArchiSteamFarm { return true; } - BotRequest botRequest; + BotRequest jsonRequest; try { - botRequest = JsonConvert.DeserializeObject(body); + jsonRequest = JsonConvert.DeserializeObject(body); } catch (Exception e) { - await ResponseJsonObject(request, response, new GenericResponse(false, string.Format(Strings.ErrorParsingObject, nameof(botRequest)) + Environment.NewLine + e), HttpStatusCode.BadRequest).ConfigureAwait(false); + await ResponseJsonObject(request, response, new GenericResponse(false, string.Format(Strings.ErrorParsingObject, nameof(jsonRequest)) + Environment.NewLine + e), HttpStatusCode.BadRequest).ConfigureAwait(false); return true; } string botName = WebUtility.UrlDecode(arguments[argumentsIndex]); - if (botRequest.KeepSensitiveDetails && Bot.Bots.TryGetValue(botName, out Bot bot)) { - if (string.IsNullOrEmpty(botRequest.BotConfig.SteamLogin)) { - botRequest.BotConfig.SteamLogin = bot.BotConfig.SteamLogin; + if (jsonRequest.KeepSensitiveDetails && Bot.Bots.TryGetValue(botName, out Bot bot)) { + if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamLogin)) { + jsonRequest.BotConfig.SteamLogin = bot.BotConfig.SteamLogin; } - if (string.IsNullOrEmpty(botRequest.BotConfig.SteamParentalPIN)) { - botRequest.BotConfig.SteamParentalPIN = bot.BotConfig.SteamParentalPIN; + if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamParentalPIN)) { + jsonRequest.BotConfig.SteamParentalPIN = bot.BotConfig.SteamParentalPIN; } - if (string.IsNullOrEmpty(botRequest.BotConfig.SteamPassword)) { - botRequest.BotConfig.SteamPassword = bot.BotConfig.SteamPassword; + if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamPassword)) { + jsonRequest.BotConfig.SteamPassword = bot.BotConfig.SteamPassword; } } string filePath = Path.Combine(SharedInfo.ConfigDirectory, botName + ".json"); - if (!await BotConfig.Write(filePath, botRequest.BotConfig).ConfigureAwait(false)) { + if (!await BotConfig.Write(filePath, jsonRequest.BotConfig).ConfigureAwait(false)) { await ResponseJsonObject(request, response, new GenericResponse(false, "Writing bot config failed, check ASF log for details"), HttpStatusCode.BadRequest).ConfigureAwait(false); return true; } @@ -399,6 +401,75 @@ namespace ArchiSteamFarm { return true; } + private static async Task HandleApiGamesToRedeemInBackground(HttpListenerRequest request, HttpListenerResponse response, string[] arguments, byte argumentsIndex) { + if ((request == null) || (response == null) || (arguments == null) || (argumentsIndex == 0)) { + ASF.ArchiLogger.LogNullError(nameof(request) + " || " + nameof(response) + " || " + nameof(arguments) + " || " + nameof(argumentsIndex)); + return false; + } + + switch (request.HttpMethod) { + case HttpMethods.Post: + return await HandleApiGamesToRedeemInBackgroundPost(request, response, arguments, argumentsIndex).ConfigureAwait(false); + default: + await ResponseStatusCode(request, response, HttpStatusCode.MethodNotAllowed).ConfigureAwait(false); + return true; + } + } + + private static async Task HandleApiGamesToRedeemInBackgroundPost(HttpListenerRequest request, HttpListenerResponse response, string[] arguments, byte argumentsIndex) { + if ((request == null) || (response == null) || (arguments == null) || (argumentsIndex == 0)) { + ASF.ArchiLogger.LogNullError(nameof(request) + " || " + nameof(response) + " || " + nameof(arguments) + " || " + nameof(argumentsIndex)); + return false; + } + + if (arguments.Length <= argumentsIndex) { + return false; + } + + string botName = WebUtility.UrlDecode(arguments[argumentsIndex]); + + if (!Bot.Bots.TryGetValue(botName, out Bot bot)) { + await ResponseJsonObject(request, response, new GenericResponse(false, string.Format(Strings.BotNotFound, botName)), HttpStatusCode.BadRequest).ConfigureAwait(false); + return true; + } + + const string requiredContentType = "application/json"; + + if (request.ContentType != requiredContentType) { + await ResponseJsonObject(request, response, new GenericResponse(false, nameof(request.ContentType) + " must be declared as " + requiredContentType), HttpStatusCode.NotAcceptable).ConfigureAwait(false); + return true; + } + + string body; + using (StreamReader reader = new StreamReader(request.InputStream)) { + body = await reader.ReadToEndAsync().ConfigureAwait(false); + } + + if (string.IsNullOrEmpty(body)) { + await ResponseJsonObject(request, response, new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(body))), HttpStatusCode.BadRequest).ConfigureAwait(false); + return true; + } + + GamesToRedeemInBackgroundRequest jsonRequest; + + try { + jsonRequest = JsonConvert.DeserializeObject(body); + } catch (Exception e) { + await ResponseJsonObject(request, response, new GenericResponse(false, string.Format(Strings.ErrorParsingObject, nameof(jsonRequest)) + Environment.NewLine + e), HttpStatusCode.BadRequest).ConfigureAwait(false); + return true; + } + + if (jsonRequest.GamesToRedeemInBackground.Count == 0) { + await ResponseJsonObject(request, response, new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(jsonRequest.GamesToRedeemInBackground))), HttpStatusCode.BadRequest).ConfigureAwait(false); + return true; + } + + await bot.AddGamesToRedeemInBackground(jsonRequest.GamesToRedeemInBackground).ConfigureAwait(false); + + await ResponseJsonObject(request, response, new GenericResponse(true, "OK")).ConfigureAwait(false); + return true; + } + private static async Task HandleApiLog(HttpListenerContext context, string[] arguments, byte argumentsIndex) { if ((context == null) || (arguments == null) || (argumentsIndex == 0)) { ASF.ArchiLogger.LogNullError(nameof(context) + " || " + nameof(arguments) + " || " + nameof(argumentsIndex)); @@ -894,6 +965,17 @@ namespace ArchiSteamFarm { private BotRequest() { } } + [SuppressMessage("ReSharper", "ClassCannotBeInstantiated")] + private sealed class GamesToRedeemInBackgroundRequest { +#pragma warning disable 649 + [JsonProperty(Required = Required.Always)] + internal readonly Dictionary GamesToRedeemInBackground; +#pragma warning restore 649 + + // Deserialized from JSON + private GamesToRedeemInBackgroundRequest() { } + } + private sealed class GenericResponse { [JsonProperty] private readonly string Message;