mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-21 16:58:37 +00:00
Add BGR action
Existing one soon to be deprecated
This commit is contained in:
@@ -33,7 +33,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
[Route("Api/ASF")]
|
[Route("Api/ASF")]
|
||||||
public sealed class ASFController : ControllerBase {
|
public sealed class ASFController : ControllerBase {
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public ActionResult<GenericResponse<ASFResponse>> Get() {
|
public ActionResult<GenericResponse<ASFResponse>> ASFGet() {
|
||||||
uint memoryUsage = (uint) GC.GetTotalMemory(false) / 1024;
|
uint memoryUsage = (uint) GC.GetTotalMemory(false) / 1024;
|
||||||
|
|
||||||
DateTime processStartTime;
|
DateTime processStartTime;
|
||||||
@@ -47,7 +47,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<GenericResponse>> Post([FromBody] ASFRequest request) {
|
public async Task<ActionResult<GenericResponse>> ASFPost([FromBody] ASFRequest request) {
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(request));
|
ASF.ArchiLogger.LogNullError(nameof(request));
|
||||||
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(request))));
|
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(request))));
|
||||||
@@ -73,19 +73,19 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Exit")]
|
[HttpPost("Exit")]
|
||||||
public ActionResult<GenericResponse> PostExit() {
|
public ActionResult<GenericResponse> ExitPost() {
|
||||||
(bool success, string output) = Actions.Exit();
|
(bool success, string output) = Actions.Exit();
|
||||||
return Ok(new GenericResponse(success, output));
|
return Ok(new GenericResponse(success, output));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Restart")]
|
[HttpPost("Restart")]
|
||||||
public ActionResult<GenericResponse> PostRestart() {
|
public ActionResult<GenericResponse> RestartPost() {
|
||||||
(bool success, string output) = Actions.Restart();
|
(bool success, string output) = Actions.Restart();
|
||||||
return Ok(new GenericResponse(success, output));
|
return Ok(new GenericResponse(success, output));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Update")]
|
[HttpPost("Update")]
|
||||||
public async Task<ActionResult<GenericResponse<Version>>> PostUpdate() {
|
public async Task<ActionResult<GenericResponse<Version>>> UpdatePost() {
|
||||||
(bool success, Version version) = await Actions.Update().ConfigureAwait(false);
|
(bool success, Version version) = await Actions.Update().ConfigureAwait(false);
|
||||||
return Ok(new GenericResponse<Version>(success, version));
|
return Ok(new GenericResponse<Version>(success, version));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -34,7 +35,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
[Route("Api/Bot")]
|
[Route("Api/Bot")]
|
||||||
public sealed class BotController : ControllerBase {
|
public sealed class BotController : ControllerBase {
|
||||||
[HttpDelete("{botNames:required}")]
|
[HttpDelete("{botNames:required}")]
|
||||||
public async Task<ActionResult<GenericResponse>> Delete(string botNames) {
|
public async Task<ActionResult<GenericResponse>> BotDelete(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(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))));
|
||||||
@@ -50,7 +51,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{botNames:required}")]
|
[HttpGet("{botNames:required}")]
|
||||||
public ActionResult<GenericResponse<HashSet<Bot>>> Get(string botNames) {
|
public ActionResult<GenericResponse<HashSet<Bot>>> BotGet(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(botNames));
|
ASF.ArchiLogger.LogNullError(nameof(botNames));
|
||||||
return BadRequest(new GenericResponse<HashSet<Bot>>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
|
return BadRequest(new GenericResponse<HashSet<Bot>>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
|
||||||
@@ -65,7 +66,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{botName:required}")]
|
[HttpPost("{botName:required}")]
|
||||||
public async Task<ActionResult<GenericResponse>> Post(string botName, [FromBody] BotRequest request) {
|
public async Task<ActionResult<GenericResponse>> BotPost(string botName, [FromBody] BotRequest request) {
|
||||||
if (string.IsNullOrEmpty(botName) || (request == null)) {
|
if (string.IsNullOrEmpty(botName) || (request == null)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
|
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
|
||||||
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botName) + " || " + nameof(request))));
|
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botName) + " || " + nameof(request))));
|
||||||
@@ -98,8 +99,67 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
return Ok(new GenericResponse(result));
|
return Ok(new GenericResponse(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{botNames:required}/GamesToRedeemInBackground")]
|
||||||
|
public async Task<ActionResult<GenericResponse>> GamesToRedeemInBackgroundDelete(string botNames) {
|
||||||
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
|
ASF.ArchiLogger.LogNullError(nameof(botNames));
|
||||||
|
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<Bot> bots = Bot.GetBots(botNames);
|
||||||
|
if ((bots == null) || (bots.Count == 0)) {
|
||||||
|
return BadRequest(new GenericResponse(false, string.Format(Strings.BotNotFound, botNames)));
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<bool> results = await Utilities.InParallel(bots.Select(bot => Task.Run(bot.DeleteRedeemedKeysFiles))).ConfigureAwait(false);
|
||||||
|
return Ok(results.All(result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{botNames:required}/GamesToRedeemInBackground")]
|
||||||
|
public async Task<ActionResult<GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>>> GamesToRedeemInBackgroundGet(string botNames) {
|
||||||
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
|
ASF.ArchiLogger.LogNullError(nameof(botNames));
|
||||||
|
return BadRequest(new GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<Bot> bots = Bot.GetBots(botNames);
|
||||||
|
if ((bots == null) || (bots.Count == 0)) {
|
||||||
|
return BadRequest(new GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>(false, string.Format(Strings.BotNotFound, botNames)));
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<(Dictionary<string, string> UnusedKeys, Dictionary<string, string> UsedKeys)> results = await Utilities.InParallel(bots.Select(bot => bot.GetUsedAndUnusedKeys())).ConfigureAwait(false);
|
||||||
|
|
||||||
|
Dictionary<string, GamesToRedeemInBackgroundResponse> result = new Dictionary<string, GamesToRedeemInBackgroundResponse>();
|
||||||
|
|
||||||
|
foreach (Bot bot in bots) {
|
||||||
|
(Dictionary<string, string> unusedKeys, Dictionary<string, string> usedKeys) = results[result.Count];
|
||||||
|
result[bot.BotName] = new GamesToRedeemInBackgroundResponse(unusedKeys, usedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(new GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{botName:required}/GamesToRedeemInBackground")]
|
||||||
|
public async Task<ActionResult<GenericResponse<OrderedDictionary>>> GamesToRedeemInBackgroundPost(string botName, [FromBody] GamesToRedeemInBackgroundRequest request) {
|
||||||
|
if (string.IsNullOrEmpty(botName) || (request == null)) {
|
||||||
|
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
|
||||||
|
return BadRequest(new GenericResponse<OrderedDictionary>(false, string.Format(Strings.ErrorIsEmpty, nameof(botName) + " || " + nameof(request))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.GamesToRedeemInBackground.Count == 0) {
|
||||||
|
return BadRequest(new GenericResponse<OrderedDictionary>(false, string.Format(Strings.ErrorIsEmpty, nameof(request.GamesToRedeemInBackground))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Bot.Bots.TryGetValue(botName, out Bot bot)) {
|
||||||
|
return BadRequest(new GenericResponse<OrderedDictionary>(false, string.Format(Strings.BotNotFound, botName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = await bot.ValidateAndAddGamesToRedeemInBackground(request.GamesToRedeemInBackground).ConfigureAwait(false);
|
||||||
|
return Ok(new GenericResponse<OrderedDictionary>(result, request.GamesToRedeemInBackground));
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("{botNames:required}/Pause")]
|
[HttpPost("{botNames:required}/Pause")]
|
||||||
public async Task<ActionResult<GenericResponse>> PostPause(string botNames, [FromBody] BotPauseRequest request) {
|
public async Task<ActionResult<GenericResponse>> PausePost(string botNames, [FromBody] BotPauseRequest request) {
|
||||||
if (string.IsNullOrEmpty(botNames) || (request == null)) {
|
if (string.IsNullOrEmpty(botNames) || (request == null)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request));
|
ASF.ArchiLogger.LogNullError(nameof(botNames) + " || " + nameof(request));
|
||||||
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request))));
|
return BadRequest(new GenericResponse(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames) + " || " + nameof(request))));
|
||||||
@@ -115,7 +175,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{botNames:required}/Resume")]
|
[HttpPost("{botNames:required}/Resume")]
|
||||||
public async Task<ActionResult<GenericResponse>> PostResume(string botNames) {
|
public async Task<ActionResult<GenericResponse>> ResumePost(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(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))));
|
||||||
@@ -131,7 +191,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{botNames:required}/Start")]
|
[HttpPost("{botNames:required}/Start")]
|
||||||
public async Task<ActionResult<GenericResponse>> PostStart(string botNames) {
|
public async Task<ActionResult<GenericResponse>> StartPost(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(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))));
|
||||||
@@ -147,7 +207,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{botNames:required}/Stop")]
|
[HttpPost("{botNames:required}/Stop")]
|
||||||
public async Task<ActionResult<GenericResponse>> PostStop(string botNames) {
|
public async Task<ActionResult<GenericResponse>> StopPost(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(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))));
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
[Route("Api/Command")]
|
[Route("Api/Command")]
|
||||||
public sealed class CommandController : ControllerBase {
|
public sealed class CommandController : ControllerBase {
|
||||||
[HttpPost("{command:required}")]
|
[HttpPost("{command:required}")]
|
||||||
public async Task<ActionResult<GenericResponse<string>>> Post(string command) {
|
public async Task<ActionResult<GenericResponse<string>>> CommandPost(string command) {
|
||||||
if (string.IsNullOrEmpty(command)) {
|
if (string.IsNullOrEmpty(command)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(command));
|
ASF.ArchiLogger.LogNullError(nameof(command));
|
||||||
return BadRequest(new GenericResponse<string>(false, string.Format(Strings.ErrorIsEmpty, nameof(command))));
|
return BadRequest(new GenericResponse<string>(false, string.Format(Strings.ErrorIsEmpty, nameof(command))));
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
[Route("Api/GamesToRedeemInBackground")]
|
[Route("Api/GamesToRedeemInBackground")]
|
||||||
public sealed class GamesToRedeemInBackgroundController : ControllerBase {
|
public sealed class GamesToRedeemInBackgroundController : ControllerBase {
|
||||||
[HttpDelete("{botNames:required}")]
|
[HttpDelete("{botNames:required}")]
|
||||||
public async Task<ActionResult<GenericResponse>> Delete(string botNames) {
|
public async Task<ActionResult<GenericResponse>> GamesToRedeemInBackgroundDelete(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(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))));
|
||||||
@@ -49,7 +49,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{botNames:required}")]
|
[HttpGet("{botNames:required}")]
|
||||||
public async Task<ActionResult<GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>>> Get(string botNames) {
|
public async Task<ActionResult<GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>>> GamesToRedeemInBackgroundGet(string botNames) {
|
||||||
if (string.IsNullOrEmpty(botNames)) {
|
if (string.IsNullOrEmpty(botNames)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(botNames));
|
ASF.ArchiLogger.LogNullError(nameof(botNames));
|
||||||
return BadRequest(new GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
|
return BadRequest(new GenericResponse<Dictionary<string, GamesToRedeemInBackgroundResponse>>(false, string.Format(Strings.ErrorIsEmpty, nameof(botNames))));
|
||||||
@@ -73,7 +73,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{botName:required}")]
|
[HttpPost("{botName:required}")]
|
||||||
public async Task<ActionResult<GenericResponse<OrderedDictionary>>> Post(string botName, [FromBody] GamesToRedeemInBackgroundRequest request) {
|
public async Task<ActionResult<GenericResponse<OrderedDictionary>>> GamesToRedeemInBackgroundPost(string botName, [FromBody] GamesToRedeemInBackgroundRequest request) {
|
||||||
if (string.IsNullOrEmpty(botName) || (request == null)) {
|
if (string.IsNullOrEmpty(botName) || (request == null)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
|
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(request));
|
||||||
return BadRequest(new GenericResponse<OrderedDictionary>(false, string.Format(Strings.ErrorIsEmpty, nameof(botName) + " || " + nameof(request))));
|
return BadRequest(new GenericResponse<OrderedDictionary>(false, string.Format(Strings.ErrorIsEmpty, nameof(botName) + " || " + nameof(request))));
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
private static readonly ConcurrentDictionary<WebSocket, SemaphoreSlim> ActiveLogWebSockets = new ConcurrentDictionary<WebSocket, SemaphoreSlim>();
|
private static readonly ConcurrentDictionary<WebSocket, SemaphoreSlim> ActiveLogWebSockets = new ConcurrentDictionary<WebSocket, SemaphoreSlim>();
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult> Get() {
|
public async Task<ActionResult> NLogGet() {
|
||||||
if (!HttpContext.WebSockets.IsWebSocketRequest) {
|
if (!HttpContext.WebSockets.IsWebSocketRequest) {
|
||||||
return BadRequest(new GenericResponse(false, string.Format(Strings.WarningFailedWithError, nameof(HttpContext.WebSockets.IsWebSocketRequest) + ": " + HttpContext.WebSockets.IsWebSocketRequest)));
|
return BadRequest(new GenericResponse(false, string.Format(Strings.WarningFailedWithError, nameof(HttpContext.WebSockets.IsWebSocketRequest) + ": " + HttpContext.WebSockets.IsWebSocketRequest)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
[Route("Api/Structure")]
|
[Route("Api/Structure")]
|
||||||
public sealed class StructureController : ControllerBase {
|
public sealed class StructureController : ControllerBase {
|
||||||
[HttpGet("{structure:required}")]
|
[HttpGet("{structure:required}")]
|
||||||
public ActionResult<GenericResponse<object>> Get(string structure) {
|
public ActionResult<GenericResponse<object>> StructureGet(string structure) {
|
||||||
if (string.IsNullOrEmpty(structure)) {
|
if (string.IsNullOrEmpty(structure)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(structure));
|
ASF.ArchiLogger.LogNullError(nameof(structure));
|
||||||
return BadRequest(new GenericResponse<object>(false, string.Format(Strings.ErrorIsEmpty, nameof(structure))));
|
return BadRequest(new GenericResponse<object>(false, string.Format(Strings.ErrorIsEmpty, nameof(structure))));
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
|||||||
[Route("Api/Type")]
|
[Route("Api/Type")]
|
||||||
public sealed class TypeController : ControllerBase {
|
public sealed class TypeController : ControllerBase {
|
||||||
[HttpGet("{type:required}")]
|
[HttpGet("{type:required}")]
|
||||||
public ActionResult<GenericResponse<TypeResponse>> Get(string type) {
|
public ActionResult<GenericResponse<TypeResponse>> TypeGet(string type) {
|
||||||
if (string.IsNullOrEmpty(type)) {
|
if (string.IsNullOrEmpty(type)) {
|
||||||
ASF.ArchiLogger.LogNullError(nameof(type));
|
ASF.ArchiLogger.LogNullError(nameof(type));
|
||||||
return BadRequest(new GenericResponse<TypeResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(type))));
|
return BadRequest(new GenericResponse<TypeResponse>(false, string.Format(Strings.ErrorIsEmpty, nameof(type))));
|
||||||
|
|||||||
Reference in New Issue
Block a user