mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-01 14:10:53 +00:00
Add helpful limitations on properties for https://github.com/JustArchiNET/ASF-ui/issues/1445
Monologue explaining how it works: https://ptb.discord.com/channels/267292556709068800/332735075315744768/859854787634004049 (eventually also on wiki)
This commit is contained in:
87
ArchiSteamFarm/IPC/Integration/BotConfigSchemaFilter.cs
Normal file
87
ArchiSteamFarm/IPC/Integration/BotConfigSchemaFilter.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// |
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ArchiSteamFarm.Steam.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using SteamKit2;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[UsedImplicitly]
|
||||
internal sealed class BotConfigSchemaFilter : ISchemaFilter {
|
||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (context.MemberInfo?.DeclaringType != typeof(BotConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OpenApiArray validValues;
|
||||
|
||||
switch (context.MemberInfo.Name) {
|
||||
case nameof(BotConfig.CompleteTypesToSend):
|
||||
validValues = new OpenApiArray();
|
||||
|
||||
validValues.AddRange(BotConfig.AllowedCompleteTypesToSend.Select(type => new OpenApiInteger((int) type)));
|
||||
|
||||
// Note, we'd love to add this to schema.Items, but since items are ref to the enum, it's not possible to add it that way
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
case nameof(BotConfig.GamesPlayedWhileIdle):
|
||||
schema.Items.Minimum = 1;
|
||||
schema.Items.Maximum = uint.MaxValue;
|
||||
|
||||
break;
|
||||
case nameof(BotConfig.SteamMasterClanID):
|
||||
schema.Maximum = new SteamID(uint.MaxValue, EUniverse.Public, EAccountType.Clan);
|
||||
schema.Minimum = new SteamID(1, EUniverse.Public, EAccountType.Clan);
|
||||
|
||||
validValues = new OpenApiArray();
|
||||
|
||||
validValues.Add(new OpenApiInteger(0));
|
||||
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
case nameof(BotConfig.SteamParentalCode):
|
||||
validValues = new OpenApiArray();
|
||||
|
||||
validValues.Add(new OpenApiString("0"));
|
||||
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
ArchiSteamFarm/IPC/Integration/GlobalConfigSchemaFilter.cs
Normal file
67
ArchiSteamFarm/IPC/Integration/GlobalConfigSchemaFilter.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// |
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Extensions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using SteamKit2;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Integration {
|
||||
[UsedImplicitly]
|
||||
internal sealed class GlobalConfigSchemaFilter : ISchemaFilter {
|
||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
|
||||
if (schema == null) {
|
||||
throw new ArgumentNullException(nameof(schema));
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (context.MemberInfo?.DeclaringType != typeof(GlobalConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (context.MemberInfo.Name) {
|
||||
case nameof(GlobalConfig.Blacklist):
|
||||
schema.Items.Minimum = 1;
|
||||
schema.Items.Maximum = uint.MaxValue;
|
||||
|
||||
break;
|
||||
case nameof(GlobalConfig.SteamOwnerID):
|
||||
schema.Maximum = new SteamID(uint.MaxValue, EUniverse.Public, EAccountType.Individual);
|
||||
schema.Minimum = new SteamID(1, EUniverse.Public, EAccountType.Individual);
|
||||
|
||||
OpenApiArray validValues = new();
|
||||
|
||||
validValues.Add(new OpenApiInteger(0));
|
||||
|
||||
schema.AddExtension("x-valid-values", validValues);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,10 @@ namespace ArchiSteamFarm.IPC {
|
||||
|
||||
options.CustomSchemaIds(type => type.GetUnifiedName());
|
||||
options.EnableAnnotations(true, true);
|
||||
|
||||
options.SchemaFilter<BotConfigSchemaFilter>();
|
||||
options.SchemaFilter<EnumSchemaFilter>();
|
||||
options.SchemaFilter<GlobalConfigSchemaFilter>();
|
||||
|
||||
options.SwaggerDoc(
|
||||
SharedInfo.ASF, new OpenApiInfo {
|
||||
|
||||
@@ -28,6 +28,7 @@ using System.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -173,9 +174,11 @@ namespace ArchiSteamFarm.Steam.Storage {
|
||||
public bool FarmPriorityQueueOnly { get; private set; } = DefaultFarmPriorityQueueOnly;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[MaxLength(ArchiHandler.MaxGamesPlayedConcurrently)]
|
||||
public ImmutableHashSet<uint> GamesPlayedWhileIdle { get; private set; } = DefaultGamesPlayedWhileIdle;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte HoursUntilCardDrops { get; private set; } = DefaultHoursUntilCardDrops;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
@@ -200,6 +203,7 @@ namespace ArchiSteamFarm.Steam.Storage {
|
||||
public bool SendOnFarmingFinished { get; private set; } = DefaultSendOnFarmingFinished;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte SendTradePeriod { get; private set; } = DefaultSendTradePeriod;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
@@ -222,6 +226,8 @@ namespace ArchiSteamFarm.Steam.Storage {
|
||||
public ulong SteamMasterClanID { get; private set; } = DefaultSteamMasterClanID;
|
||||
|
||||
[JsonProperty]
|
||||
[MaxLength(4)]
|
||||
[MinLength(4)]
|
||||
public string? SteamParentalCode {
|
||||
get => BackingSteamParentalCode;
|
||||
|
||||
@@ -242,6 +248,8 @@ namespace ArchiSteamFarm.Steam.Storage {
|
||||
}
|
||||
|
||||
[JsonProperty]
|
||||
[MaxLength(8)]
|
||||
[MinLength(8)]
|
||||
public string? SteamTradeToken { get; private set; } = DefaultSteamTradeToken;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
@@ -367,8 +375,12 @@ namespace ArchiSteamFarm.Steam.Storage {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(FarmingOrders), farmingOrder));
|
||||
}
|
||||
|
||||
if (GamesPlayedWhileIdle.Contains(0)) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), 0));
|
||||
}
|
||||
|
||||
if (GamesPlayedWhileIdle.Count > ArchiHandler.MaxGamesPlayedConcurrently) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), GamesPlayedWhileIdle.Count + " > " + ArchiHandler.MaxGamesPlayedConcurrently));
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), nameof(GamesPlayedWhileIdle.Count) + " " + GamesPlayedWhileIdle.Count + " > " + ArchiHandler.MaxGamesPlayedConcurrently));
|
||||
}
|
||||
|
||||
foreach (Asset.EType lootableType in LootableTypes.Where(lootableType => !Enum.IsDefined(typeof(Asset.EType), lootableType))) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -183,9 +184,11 @@ namespace ArchiSteamFarm.Storage {
|
||||
public string? CommandPrefix { get; private set; } = DefaultCommandPrefix;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte ConfirmationsLimiterDelay { get; private set; } = DefaultConfirmationsLimiterDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(1, byte.MaxValue)]
|
||||
public byte ConnectionTimeout { get; private set; } = DefaultConnectionTimeout;
|
||||
|
||||
[JsonProperty]
|
||||
@@ -195,18 +198,22 @@ namespace ArchiSteamFarm.Storage {
|
||||
public bool Debug { get; private set; } = DefaultDebug;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(1, byte.MaxValue)]
|
||||
public byte FarmingDelay { get; private set; } = DefaultFarmingDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte GiftsLimiterDelay { get; private set; } = DefaultGiftsLimiterDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool Headless { get; private set; } = DefaultHeadless;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte IdleFarmingPeriod { get; private set; } = DefaultIdleFarmingPeriod;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte InventoryLimiterDelay { get; private set; } = DefaultInventoryLimiterDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
@@ -219,12 +226,15 @@ namespace ArchiSteamFarm.Storage {
|
||||
public ArchiCryptoHelper.EHashingMethod IPCPasswordFormat { get; private set; } = DefaultIPCPasswordFormat;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte LoginLimiterDelay { get; private set; } = DefaultLoginLimiterDelay;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(1, byte.MaxValue)]
|
||||
public byte MaxFarmingTime { get; private set; } = DefaultMaxFarmingTime;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte MaxTradeHoldDuration { get; private set; } = DefaultMaxTradeHoldDuration;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
@@ -234,6 +244,7 @@ namespace ArchiSteamFarm.Storage {
|
||||
public bool Statistics { get; private set; } = DefaultStatistics;
|
||||
|
||||
[JsonProperty]
|
||||
[MaxLength(SteamChatMessage.MaxMessagePrefixBytes / 4)]
|
||||
public string? SteamMessagePrefix { get; private set; } = DefaultSteamMessagePrefix;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
@@ -246,9 +257,11 @@ namespace ArchiSteamFarm.Storage {
|
||||
public EUpdateChannel UpdateChannel { get; private set; } = DefaultUpdateChannel;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(byte.MinValue, byte.MaxValue)]
|
||||
public byte UpdatePeriod { get; private set; } = DefaultUpdatePeriod;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
[Range(ushort.MinValue, ushort.MaxValue)]
|
||||
public ushort WebLimiterDelay { get; private set; } = DefaultWebLimiterDelay;
|
||||
|
||||
[JsonProperty(PropertyName = nameof(WebProxy))]
|
||||
@@ -299,6 +312,10 @@ namespace ArchiSteamFarm.Storage {
|
||||
internal GlobalConfig() { }
|
||||
|
||||
internal (bool Valid, string? ErrorMessage) CheckValidation() {
|
||||
if (Blacklist.Contains(0)) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(Blacklist), 0));
|
||||
}
|
||||
|
||||
if (ConnectionTimeout == 0) {
|
||||
return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(ConnectionTimeout), ConnectionTimeout));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user