2022-12-15 18:46:37 +01:00
|
|
|
// _ _ _ ____ _ _____
|
|
|
|
|
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
|
|
|
|
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
|
|
|
|
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
|
|
|
|
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
|
|
|
|
// |
|
2023-01-14 15:08:28 +01:00
|
|
|
// Copyright 2015-2023 Łukasz "JustArchi" Domeradzki
|
2022-12-15 18:46:37 +01:00
|
|
|
// 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.Collections.Generic;
|
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using ArchiSteamFarm.Core;
|
|
|
|
|
using ArchiSteamFarm.IPC.Responses;
|
2022-12-15 19:16:28 +01:00
|
|
|
using ArchiSteamFarm.OfficialPlugins.ItemsMatcher.Data;
|
2022-12-15 18:46:37 +01:00
|
|
|
using ArchiSteamFarm.Steam;
|
|
|
|
|
using ArchiSteamFarm.Steam.Data;
|
|
|
|
|
using ArchiSteamFarm.Steam.Storage;
|
|
|
|
|
using ArchiSteamFarm.Storage;
|
|
|
|
|
using ArchiSteamFarm.Web;
|
|
|
|
|
using ArchiSteamFarm.Web.Responses;
|
2023-01-14 23:41:25 +01:00
|
|
|
using SteamKit2;
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
namespace ArchiSteamFarm.OfficialPlugins.ItemsMatcher;
|
|
|
|
|
|
|
|
|
|
internal static class Backend {
|
2023-01-21 20:32:42 +01:00
|
|
|
internal static async Task<BasicResponse?> AnnounceForListing(ulong steamID, WebBrowser webBrowser, IReadOnlyList<AssetForListing> inventory, IReadOnlyCollection<Asset.EType> acceptedMatchableTypes, uint totalInventoryCount, bool matchEverything, string tradeToken, string? nickname = null, string? avatarHash = null) {
|
2023-01-14 23:41:25 +01:00
|
|
|
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(steamID));
|
|
|
|
|
}
|
|
|
|
|
|
Use custom WebBrowser for items matcher
Now this is dictated by at least several reasons:
- Firstly, we must have a WebBrowser per bot, and not per ASF instance, as we preserve ASF STM cookies that are on per-bot basis, which are required e.g. for Announce
- At the same time we shouldn't use Bot's one, because there are settings like WebProxy that shouldn't be used in regards to our own server
- We also require higher timeout than default one, especially for Announce, but also Inventories
- Best we can do is optimize that to not create a WebBrowser for bots that are neither configured for public listing, nor match actively. Since those settings need to be explicitly turned on, we shouldn't be duplicating WebBrowser per each bot instance, but rather only few selected bots configured to participate.
2022-12-23 18:21:43 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(webBrowser);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
if ((inventory == null) || (inventory.Count == 0)) {
|
|
|
|
|
throw new ArgumentNullException(nameof(inventory));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((acceptedMatchableTypes == null) || (acceptedMatchableTypes.Count == 0)) {
|
|
|
|
|
throw new ArgumentNullException(nameof(acceptedMatchableTypes));
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 19:12:33 +01:00
|
|
|
ArgumentOutOfRangeException.ThrowIfZero(totalInventoryCount);
|
|
|
|
|
ArgumentException.ThrowIfNullOrEmpty(tradeToken);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
if (tradeToken.Length != BotConfig.SteamTradeTokenLength) {
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(tradeToken));
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-21 20:32:42 +01:00
|
|
|
Uri request = new(ArchiNet.URL, "/Api/Listing/Announce/v3");
|
2022-12-15 18:46:37 +01:00
|
|
|
|
2023-01-15 00:16:53 +01:00
|
|
|
AnnouncementRequest data = new(ASF.GlobalDatabase?.Identifier ?? Guid.NewGuid(), steamID, tradeToken, inventory, acceptedMatchableTypes, totalInventoryCount, matchEverything, ASF.GlobalConfig?.MaxTradeHoldDuration ?? GlobalConfig.DefaultMaxTradeHoldDuration, nickname, avatarHash);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
2023-01-15 21:26:03 +01:00
|
|
|
return await webBrowser.UrlPost(request, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections | WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.CompressRequest).ConfigureAwait(false);
|
2022-12-15 18:46:37 +01:00
|
|
|
}
|
|
|
|
|
|
Use custom WebBrowser for items matcher
Now this is dictated by at least several reasons:
- Firstly, we must have a WebBrowser per bot, and not per ASF instance, as we preserve ASF STM cookies that are on per-bot basis, which are required e.g. for Announce
- At the same time we shouldn't use Bot's one, because there are settings like WebProxy that shouldn't be used in regards to our own server
- We also require higher timeout than default one, especially for Announce, but also Inventories
- Best we can do is optimize that to not create a WebBrowser for bots that are neither configured for public listing, nor match actively. Since those settings need to be explicitly turned on, we shouldn't be duplicating WebBrowser per each bot instance, but rather only few selected bots configured to participate.
2022-12-23 18:21:43 +01:00
|
|
|
internal static async Task<(HttpStatusCode StatusCode, ImmutableHashSet<ListedUser> Users)?> GetListedUsersForMatching(Guid licenseID, Bot bot, WebBrowser webBrowser, IReadOnlyCollection<Asset> inventory, IReadOnlyCollection<Asset.EType> acceptedMatchableTypes) {
|
2023-11-14 19:12:33 +01:00
|
|
|
ArgumentOutOfRangeException.ThrowIfEqual(licenseID, Guid.Empty);
|
2022-12-15 18:46:37 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(bot);
|
Use custom WebBrowser for items matcher
Now this is dictated by at least several reasons:
- Firstly, we must have a WebBrowser per bot, and not per ASF instance, as we preserve ASF STM cookies that are on per-bot basis, which are required e.g. for Announce
- At the same time we shouldn't use Bot's one, because there are settings like WebProxy that shouldn't be used in regards to our own server
- We also require higher timeout than default one, especially for Announce, but also Inventories
- Best we can do is optimize that to not create a WebBrowser for bots that are neither configured for public listing, nor match actively. Since those settings need to be explicitly turned on, we shouldn't be duplicating WebBrowser per each bot instance, but rather only few selected bots configured to participate.
2022-12-23 18:21:43 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(webBrowser);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
if ((inventory == null) || (inventory.Count == 0)) {
|
|
|
|
|
throw new ArgumentNullException(nameof(inventory));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((acceptedMatchableTypes == null) || (acceptedMatchableTypes.Count == 0)) {
|
|
|
|
|
throw new ArgumentNullException(nameof(acceptedMatchableTypes));
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-11 18:40:46 +01:00
|
|
|
Uri request = new(ArchiNet.URL, "/Api/Listing/Inventories/v2");
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
Dictionary<string, string> headers = new(1, StringComparer.Ordinal) {
|
|
|
|
|
{ "X-License-Key", licenseID.ToString("N") }
|
|
|
|
|
};
|
|
|
|
|
|
2022-12-23 15:31:14 +01:00
|
|
|
InventoriesRequest data = new(ASF.GlobalDatabase?.Identifier ?? Guid.NewGuid(), bot.SteamID, inventory, acceptedMatchableTypes);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
2023-01-15 21:26:03 +01:00
|
|
|
ObjectResponse<GenericResponse<ImmutableHashSet<ListedUser>>>? response = await webBrowser.UrlPostToJsonObject<GenericResponse<ImmutableHashSet<ListedUser>>, InventoriesRequest>(request, headers, data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors | WebBrowser.ERequestOptions.CompressRequest).ConfigureAwait(false);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
if (response == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (response.StatusCode, response.Content?.Result ?? ImmutableHashSet<ListedUser>.Empty);
|
|
|
|
|
}
|
|
|
|
|
|
Use custom WebBrowser for items matcher
Now this is dictated by at least several reasons:
- Firstly, we must have a WebBrowser per bot, and not per ASF instance, as we preserve ASF STM cookies that are on per-bot basis, which are required e.g. for Announce
- At the same time we shouldn't use Bot's one, because there are settings like WebProxy that shouldn't be used in regards to our own server
- We also require higher timeout than default one, especially for Announce, but also Inventories
- Best we can do is optimize that to not create a WebBrowser for bots that are neither configured for public listing, nor match actively. Since those settings need to be explicitly turned on, we shouldn't be duplicating WebBrowser per each bot instance, but rather only few selected bots configured to participate.
2022-12-23 18:21:43 +01:00
|
|
|
internal static async Task<BasicResponse?> HeartBeatForListing(Bot bot, WebBrowser webBrowser) {
|
2022-12-15 18:46:37 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(bot);
|
Use custom WebBrowser for items matcher
Now this is dictated by at least several reasons:
- Firstly, we must have a WebBrowser per bot, and not per ASF instance, as we preserve ASF STM cookies that are on per-bot basis, which are required e.g. for Announce
- At the same time we shouldn't use Bot's one, because there are settings like WebProxy that shouldn't be used in regards to our own server
- We also require higher timeout than default one, especially for Announce, but also Inventories
- Best we can do is optimize that to not create a WebBrowser for bots that are neither configured for public listing, nor match actively. Since those settings need to be explicitly turned on, we shouldn't be duplicating WebBrowser per each bot instance, but rather only few selected bots configured to participate.
2022-12-23 18:21:43 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(webBrowser);
|
2022-12-15 18:46:37 +01:00
|
|
|
|
|
|
|
|
Uri request = new(ArchiNet.URL, "/Api/Listing/HeartBeat");
|
|
|
|
|
|
|
|
|
|
HeartBeatRequest data = new(ASF.GlobalDatabase?.Identifier ?? Guid.NewGuid(), bot.SteamID);
|
|
|
|
|
|
2023-01-15 21:26:03 +01:00
|
|
|
return await webBrowser.UrlPost(request, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections | WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.CompressRequest).ConfigureAwait(false);
|
2022-12-15 18:46:37 +01:00
|
|
|
}
|
|
|
|
|
}
|