Monologue explaining how it works: https://ptb.discord.com/channels/267292556709068800/332735075315744768/859854787634004049

(eventually also on wiki)
This commit is contained in:
Archi
2021-06-30 20:39:38 +02:00
parent 689dbc4db5
commit 874eb4d3a6
5 changed files with 187 additions and 1 deletions

View 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;
}
}
}
}

View 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;
}
}
}
}

View File

@@ -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 {

View File

@@ -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))) {

View File

@@ -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));
}