diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj
index 77470f06a..1d4275f03 100644
--- a/ArchiSteamFarm/ArchiSteamFarm.csproj
+++ b/ArchiSteamFarm/ArchiSteamFarm.csproj
@@ -56,6 +56,7 @@
+
diff --git a/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs b/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs
index a1fe2c457..0ef09f52d 100644
--- a/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs
+++ b/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs
@@ -27,16 +27,21 @@ using ArchiSteamFarm.IPC.Requests;
using ArchiSteamFarm.IPC.Responses;
using ArchiSteamFarm.Localization;
using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
namespace ArchiSteamFarm.IPC.Controllers.Api {
[ApiController]
[Produces("application/json")]
[Route("Api/ASF")]
+ [SwaggerResponse(400, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
+ [SwaggerResponse(401, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
+ [SwaggerResponse(403, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
public sealed class ASFController : ControllerBase {
///
/// Fetches common info related to ASF as a whole.
///
[HttpGet]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public ActionResult> ASFGet() {
uint memoryUsage = (uint) GC.GetTotalMemory(false) / 1024;
@@ -53,7 +58,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
///
/// Updates ASF's global config.
///
+ [Consumes("application/json")]
[HttpPost]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> ASFPost([FromBody] ASFRequest request) {
if (request == null) {
ASF.ArchiLogger.LogNullError(nameof(request));
@@ -81,6 +88,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Makes ASF shutdown itself.
///
[HttpPost("Exit")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public ActionResult ExitPost() {
(bool success, string output) = Actions.Exit();
return Ok(new GenericResponse(success, output));
@@ -90,6 +98,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Makes ASF restart itself.
///
[HttpPost("Restart")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public ActionResult RestartPost() {
(bool success, string output) = Actions.Restart();
return Ok(new GenericResponse(success, output));
@@ -99,6 +108,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Makes ASF update itself.
///
[HttpPost("Update")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task>> UpdatePost() {
(bool success, Version version) = await Actions.Update().ConfigureAwait(false);
return Ok(new GenericResponse(success, version));
diff --git a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs
index 7c750bbb5..825717cc6 100644
--- a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs
+++ b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs
@@ -29,16 +29,21 @@ using ArchiSteamFarm.IPC.Requests;
using ArchiSteamFarm.IPC.Responses;
using ArchiSteamFarm.Localization;
using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
namespace ArchiSteamFarm.IPC.Controllers.Api {
[ApiController]
[Produces("application/json")]
[Route("Api/Bot")]
+ [SwaggerResponse(400, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
+ [SwaggerResponse(401, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
+ [SwaggerResponse(403, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
public sealed class BotController : ControllerBase {
///
/// Deletes all files related to given bots.
///
[HttpDelete("{botNames:required}")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> BotDelete(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
@@ -58,24 +63,27 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Fetches common info related to given bots.
///
[HttpGet("{botNames:required}")]
- public ActionResult>> BotGet(string botNames) {
+ [SwaggerResponse(200, type: typeof(GenericResponse>))]
+ public ActionResult>> BotGet(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
- return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
+ return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
}
HashSet bots = Bot.GetBots(botNames);
if (bots == null) {
- return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsInvalid, nameof(bots))));
+ return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsInvalid, nameof(bots))));
}
- return Ok(new GenericResponse>(bots));
+ return Ok(new GenericResponse>(bots.ToDictionary(bot => bot.BotName, bot => bot)));
}
///
/// Updates bot config of given bot.
///
+ [Consumes("application/json")]
[HttpPost("{botName:required}")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> BotPost(string botName, [FromBody] BotRequest request) {
if (string.IsNullOrEmpty(botName) || (request == null)) {
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
@@ -113,6 +121,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Removes BGR output files of given bots.
///
[HttpDelete("{botNames:required}/GamesToRedeemInBackground")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> GamesToRedeemInBackgroundDelete(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
@@ -132,15 +141,16 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Fetches BGR output files of given bots.
///
[HttpGet("{botNames:required}/GamesToRedeemInBackground")]
- public async Task>>> GamesToRedeemInBackgroundGet(string botNames) {
+ [SwaggerResponse(200, type: typeof(GenericResponse>))]
+ public async Task>>> GamesToRedeemInBackgroundGet(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
- return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
+ return BadRequest(new GenericResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
}
HashSet bots = Bot.GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
- return BadRequest(new GenericResponse>(false, string.Format(Strings.BotNotFound, botNames)));
+ return BadRequest(new GenericResponse>(false, string.Format(Strings.BotNotFound, botNames)));
}
IList<(Dictionary UnusedKeys, Dictionary UsedKeys)> results = await Utilities.InParallel(bots.Select(bot => bot.GetUsedAndUnusedKeys())).ConfigureAwait(false);
@@ -152,13 +162,15 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
result[bot.BotName] = new GamesToRedeemInBackgroundResponse(unusedKeys, usedKeys);
}
- return Ok(new GenericResponse>(result));
+ return Ok(new GenericResponse>(result));
}
///
/// Adds keys to redeem using BGR to given bot.
///
+ [Consumes("application/json")]
[HttpPost("{botName:required}/GamesToRedeemInBackground")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task>> GamesToRedeemInBackgroundPost(string botName, [FromBody] GamesToRedeemInBackgroundRequest request) {
if (string.IsNullOrEmpty(botName) || (request == null)) {
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
@@ -180,7 +192,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
///
/// Pauses given bots.
///
+ [Consumes("application/json")]
[HttpPost("{botNames:required}/Pause")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> PausePost(string botNames, [FromBody] BotPauseRequest request) {
if (string.IsNullOrEmpty(botNames) || (request == null)) {
ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request));
@@ -200,6 +214,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Resumes given bots.
///
[HttpPost("{botNames:required}/Resume")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> ResumePost(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
@@ -219,6 +234,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Starts given bots.
///
[HttpPost("{botNames:required}/Start")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> StartPost(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
@@ -238,6 +254,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Stops given bots.
///
[HttpPost("{botNames:required}/Stop")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task> StopPost(string botNames) {
if (string.IsNullOrEmpty(botNames)) {
ASF.ArchiLogger.LogNullError(nameof(botNames));
diff --git a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs
index e2c1915da..273423c5a 100644
--- a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs
+++ b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs
@@ -25,11 +25,15 @@ using System.Threading.Tasks;
using ArchiSteamFarm.IPC.Responses;
using ArchiSteamFarm.Localization;
using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
namespace ArchiSteamFarm.IPC.Controllers.Api {
[ApiController]
[Produces("application/json")]
[Route("Api/Command")]
+ [SwaggerResponse(400, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
+ [SwaggerResponse(401, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
+ [SwaggerResponse(403, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
public sealed class CommandController : ControllerBase {
///
/// Executes a command.
@@ -39,6 +43,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// You should use "given bot" commands when executing this endpoint, omitting targets of the command will cause the command to be executed on first defined bot
///
[HttpPost("{command:required}")]
+ [SwaggerResponse(200, type: typeof(GenericResponse))]
public async Task>> CommandPost(string command) {
if (string.IsNullOrEmpty(command)) {
ASF.ArchiLogger.LogNullError(nameof(command));
diff --git a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs
index a564c9184..64c5f877d 100644
--- a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs
+++ b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs
@@ -20,6 +20,7 @@
// limitations under the License.
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
@@ -30,11 +31,15 @@ using ArchiSteamFarm.Localization;
using ArchiSteamFarm.NLog;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
+using Swashbuckle.AspNetCore.Annotations;
namespace ArchiSteamFarm.IPC.Controllers.Api {
[ApiController]
[Produces("application/json")]
[Route("Api/NLog")]
+ [SwaggerResponse(400, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
+ [SwaggerResponse(401, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
+ [SwaggerResponse(403, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
public sealed class NLogController : ControllerBase {
private static readonly ConcurrentDictionary ActiveLogWebSockets = new ConcurrentDictionary();
@@ -45,6 +50,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// This API endpoint requires a websocket connection.
///
[HttpGet]
+ [SwaggerResponse(200, type: typeof(IEnumerable>))]
public async Task NLogGet() {
if (!HttpContext.WebSockets.IsWebSocketRequest) {
return BadRequest(new GenericResponse(false, string.Format(Strings.WarningFailedWithError, nameof(HttpContext.WebSockets.IsWebSocketRequest) + ": " + HttpContext.WebSockets.IsWebSocketRequest)));
diff --git a/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs b/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs
index 1665d9038..2e335df6c 100644
--- a/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs
+++ b/ArchiSteamFarm/IPC/Controllers/Api/StructureController.cs
@@ -23,11 +23,15 @@ using System;
using ArchiSteamFarm.IPC.Responses;
using ArchiSteamFarm.Localization;
using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
namespace ArchiSteamFarm.IPC.Controllers.Api {
[ApiController]
[Produces("application/json")]
[Route("Api/Structure")]
+ [SwaggerResponse(400, "The request has failed, check " + nameof(GenericResponse.Message) + " from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
+ [SwaggerResponse(401, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set, but you've failed to authenticate. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
+ [SwaggerResponse(403, "ASF has " + nameof(GlobalConfig.IPCPassword) + " set and you've failed to authenticate too many times, try again in an hour. See " + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/IPC#authentication.")]
public sealed class StructureController : ControllerBase {
///
/// Fetches structure of given type.
@@ -36,6 +40,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
/// Structure is defined as a representation of given object in its default state.
///
[HttpGet("{structure:required}")]
+ [SwaggerResponse(200, type: typeof(GenericResponse