mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-16 14:30:31 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6201774f52 | ||
|
|
4f71732ec2 | ||
|
|
a7e8ac5388 | ||
|
|
b3e9c38812 | ||
|
|
a3e7f7c461 | ||
|
|
10dc572b43 | ||
|
|
95356af9d3 | ||
|
|
dd2b1bde25 | ||
|
|
53ecd8d8e6 | ||
|
|
623f1d14cf | ||
|
|
3c53e9aff4 | ||
|
|
51f07b747e | ||
|
|
537b2eb55f | ||
|
|
ac14ce96af | ||
|
|
eefab22ead | ||
|
|
b9e1daa786 | ||
|
|
5e47914512 | ||
|
|
43679c647f | ||
|
|
ae8e9e4666 | ||
|
|
47b2aa137f | ||
|
|
546cc55ab9 | ||
|
|
e86bf695c8 | ||
|
|
a6e4208b40 | ||
|
|
3f43b641d9 | ||
|
|
60615ed163 | ||
|
|
ae48e8d93b |
Submodule ASF-WebConfigGenerator updated: 5acb62a4a9...adb2111205
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: 84019fc51c...6e328457f5
@@ -35,7 +35,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// Your plugin class should inherit the plugin interfaces it wants to handle
|
||||
// If you do not want to handle a particular action (e.g. OnBotMessage that is offered in IBotMessage), it's the best idea to not inherit it at all
|
||||
// This will keep your code compact, efficient and less dependent. You can always add additional interfaces when you'll need them, this example project will inherit quite a bit of them to show you potential usage
|
||||
internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, IBotMessage, IBotModules, IBotTradeOffer {
|
||||
internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, IBotFriendRequest, IBotMessage, IBotModules, IBotTradeOffer {
|
||||
// This is used for identification purposes, typically you want to use a friendly name of your plugin here, such as the name of your main class
|
||||
// Please note that this property can have direct dependencies only on structures that were initialized by the constructor, as it's possible to be called before OnLoaded() takes place
|
||||
public string Name => nameof(ExamplePlugin);
|
||||
@@ -105,6 +105,12 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// Still, you should take anything other than EResult.OK with a grain of salt, unless you want to assume that Steam knows why it disconnected us (hehe, you bet)
|
||||
public void OnBotDisconnected(Bot bot, EResult reason) { }
|
||||
|
||||
// This method is called when bot receives a friend request or group invite that ASF isn't willing to accept
|
||||
// It allows you to generate a response whether ASF should accept it (true) or proceed like usual (false)
|
||||
// If you wanted to do extra filtering (e.g. friend requests only), you can interpret the steamID as SteamID (SteamKit2 type) and then operate on AccountType
|
||||
// As an example, we'll run a trade bot that is open to all friend/group invites, therefore we'll accept all of them here
|
||||
public Task<bool> OnBotFriendRequest(Bot bot, ulong steamID) => Task.FromResult(true);
|
||||
|
||||
// This method is called at the end of Bot's constructor
|
||||
// You can initialize all your per-bot structures here
|
||||
// In general you should do that only when you have a particular need of custom modules or alike, since ASF's plugin system will always provide bot to you as a function argument
|
||||
@@ -156,7 +162,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// At this point you can access core ASF's functionality, such as logging or a web browser
|
||||
// Once all plugins execute their OnLoaded() methods, OnASFInit() will be called next
|
||||
public void OnLoaded() {
|
||||
ASF.ArchiLogger.LogGenericInfo("Hey! Thanks for checking if our example plugin works fine, this is a confirmation that indeed OnLoaded() method was called!");
|
||||
ASF.ArchiLogger.LogGenericInfo("Hey! Thanks for checking if our example plugin works fine, this is a confirmation that indeed " + nameof(OnLoaded) + "() method was called!");
|
||||
ASF.ArchiLogger.LogGenericInfo("Good luck in whatever you're doing!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" Version="3.0.0" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2018.3.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.0-preview-20181205-02" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.0-preview-20190124-02" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -19,12 +19,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using ArchiSteamFarm.Json;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using static ArchiSteamFarm.Trading;
|
||||
|
||||
namespace ArchiSteamFarm.Tests {
|
||||
[TestClass]
|
||||
@@ -47,7 +46,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(3, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -67,7 +66,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(4, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -88,7 +87,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(4, realAppID: 730)
|
||||
};
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -108,7 +107,25 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(4, realAppID: 730)
|
||||
};
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameDonationAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
CreateItem(1)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
CreateItem(1)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
CreateItem(2),
|
||||
CreateItem(3, type: Steam.Asset.EType.SteamGems)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -129,7 +146,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(3, type: Steam.Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -149,7 +166,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(4, type: Steam.Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -168,7 +185,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(4, 3) };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -185,7 +202,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(3, 3) };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -202,7 +219,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(3, 2) };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -215,7 +232,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -233,7 +250,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(3)
|
||||
};
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -247,7 +264,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(3) };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -270,7 +287,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(4)
|
||||
};
|
||||
|
||||
Assert.IsFalse(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -279,7 +296,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -288,7 +305,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -305,18 +322,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(3)
|
||||
};
|
||||
|
||||
Assert.IsTrue(AcceptsTrade(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
private static bool AcceptsTrade(IReadOnlyCollection<Steam.Asset> inventory, IReadOnlyCollection<Steam.Asset> itemsToGive, IReadOnlyCollection<Steam.Asset> itemsToReceive) {
|
||||
Type trading = typeof(ArchiSteamFarm.Trading);
|
||||
MethodInfo method = trading.GetMethod("IsTradeNeutralOrBetter", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
||||
|
||||
if (method == null) {
|
||||
throw new ArgumentNullException(nameof(method));
|
||||
}
|
||||
|
||||
return (bool) method.Invoke(null, new object[] { inventory, itemsToGive, itemsToReceive });
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -86,6 +87,10 @@ namespace ArchiSteamFarm {
|
||||
return (false, Strings.BotNoASFAuthenticator);
|
||||
}
|
||||
|
||||
if (!Bot.IsConnectedAndLoggedOn) {
|
||||
return (false, Strings.BotNotConnected);
|
||||
}
|
||||
|
||||
HashSet<ulong> handledTradeOfferIDs = null;
|
||||
|
||||
for (byte i = 0; (i == 0) || ((i < WebBrowser.MaxTries) && waitIfNeeded); i++) {
|
||||
@@ -202,7 +207,8 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, string Message)> SendTradeOffer(uint appID = Steam.Asset.SteamAppID, uint contextID = Steam.Asset.SteamCommunityContextID, ulong targetSteamID = 0, IReadOnlyCollection<uint> wantedRealAppIDs = null, IReadOnlyCollection<Steam.Asset.EType> wantedTypes = null) {
|
||||
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
|
||||
public async Task<(bool Success, string Message)> SendTradeOffer(uint appID = Steam.Asset.SteamAppID, uint contextID = Steam.Asset.SteamCommunityContextID, ulong targetSteamID = 0, string tradeToken = null, IReadOnlyCollection<uint> wantedRealAppIDs = null, IReadOnlyCollection<Steam.Asset.EType> wantedTypes = null) {
|
||||
if ((appID == 0) || (contextID == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(appID) + " || " + nameof(contextID));
|
||||
|
||||
@@ -219,6 +225,10 @@ namespace ArchiSteamFarm {
|
||||
if (targetSteamID == 0) {
|
||||
return (false, Strings.BotLootingMasterNotDefined);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tradeToken) && !string.IsNullOrEmpty(Bot.BotConfig.SteamTradeToken)) {
|
||||
tradeToken = Bot.BotConfig.SteamTradeToken;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetSteamID == Bot.SteamID) {
|
||||
@@ -250,7 +260,15 @@ namespace ArchiSteamFarm {
|
||||
return (false, Strings.BotLootingFailed);
|
||||
}
|
||||
|
||||
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(targetSteamID, inventory, token: Bot.BotConfig.SteamTradeToken).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(tradeToken) && (Bot.SteamFriends.GetFriendRelationship(targetSteamID) != EFriendRelationship.Friend)) {
|
||||
Bot targetBot = Bot.Bots.Values.FirstOrDefault(bot => bot.SteamID == targetSteamID);
|
||||
|
||||
if (targetBot?.IsConnectedAndLoggedOn == true) {
|
||||
tradeToken = await targetBot.ArchiHandler.GetTradeToken().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(targetSteamID, inventory, token: tradeToken).ConfigureAwait(false);
|
||||
|
||||
if ((mobileTradeOfferIDs != null) && (mobileTradeOfferIDs.Count > 0) && Bot.HasMobileAuthenticator) {
|
||||
(bool twoFactorSuccess, _) = await HandleTwoFactorAuthenticationConfirmations(true, Steam.ConfirmationDetails.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>ASF.ico</ApplicationIcon>
|
||||
<AssemblyVersion>4.0.0.1</AssemblyVersion>
|
||||
<AssemblyVersion>4.0.0.2</AssemblyVersion>
|
||||
<Authors>JustArchi</Authors>
|
||||
<Company>JustArchi</Company>
|
||||
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
|
||||
@@ -11,7 +11,7 @@
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);config/**;debug/**;out/**;overlay/**</DefaultItemExcludes>
|
||||
<Description>ASF is an application that allows you to farm steam cards using multiple steam accounts simultaneously.</Description>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<FileVersion>4.0.0.1</FileVersion>
|
||||
<FileVersion>4.0.0.2</FileVersion>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<NoWarn>1591</NoWarn>
|
||||
@@ -73,7 +73,7 @@
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.6.0-preview.18571.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="NLog" Version="4.5.11" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.7.1" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.8.0" />
|
||||
<PackageReference Include="protobuf-net" Version="3.0.0-alpha.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-beta" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.0.0-beta" />
|
||||
|
||||
@@ -377,7 +377,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
Bot targetBot = Bots.Values.FirstOrDefault(bot => bot.SteamID == steamID);
|
||||
|
||||
if (targetBot != null) {
|
||||
if (targetBot?.IsConnectedAndLoggedOn == true) {
|
||||
string targetTradeToken = await targetBot.ArchiHandler.GetTradeToken().ConfigureAwait(false);
|
||||
|
||||
if (!string.IsNullOrEmpty(targetTradeToken)) {
|
||||
@@ -1877,6 +1877,14 @@ namespace ArchiSteamFarm {
|
||||
|
||||
break;
|
||||
case EAccountType.Clan:
|
||||
bool acceptGroupRequest = await Core.OnBotFriendRequest(this, friend.SteamID).ConfigureAwait(false);
|
||||
|
||||
if (acceptGroupRequest) {
|
||||
ArchiHandler.AcknowledgeClanInvite(friend.SteamID, true);
|
||||
await JoinMasterChatGroupID().ConfigureAwait(false);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (BotConfig.BotBehaviour.HasFlag(BotConfig.EBotBehaviour.RejectInvalidGroupInvites)) {
|
||||
ArchiHandler.AcknowledgeClanInvite(friend.SteamID, false);
|
||||
@@ -1887,7 +1895,19 @@ namespace ArchiSteamFarm {
|
||||
|
||||
if (HasPermission(friend.SteamID, BotConfig.EPermission.FamilySharing)) {
|
||||
await ArchiHandler.AddFriend(friend.SteamID).ConfigureAwait(false);
|
||||
} else if (BotConfig.BotBehaviour.HasFlag(BotConfig.EBotBehaviour.RejectInvalidFriendInvites)) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
bool acceptFriendRequest = await Core.OnBotFriendRequest(this, friend.SteamID).ConfigureAwait(false);
|
||||
|
||||
if (acceptFriendRequest) {
|
||||
await ArchiHandler.AddFriend(friend.SteamID).ConfigureAwait(false);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (BotConfig.BotBehaviour.HasFlag(BotConfig.EBotBehaviour.RejectInvalidFriendInvites)) {
|
||||
await ArchiHandler.RemoveFriend(friend.SteamID).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private async Task<string> ResponseAddLicense(ulong steamID, IReadOnlyCollection<uint> gameIDs) {
|
||||
if ((steamID == 0) || (gameIDs == null) || (gameIDs.Count == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(gameIDs) + " || " + nameof(gameIDs.Count));
|
||||
Bot.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(gameIDs));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -378,9 +378,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
|
||||
/// <summary>
|
||||
/// Denies 2FA confirmations of given bots, requires ASF 2FA module to be active on them.
|
||||
/// </summary>
|
||||
[HttpPost("{botNames:required}/TwoFactorAuthentication/Confirmations/Deny")]
|
||||
[HttpPost("{botNames:required}/TwoFactorAuthentication/Confirmations/Cancel")]
|
||||
[ProducesResponseType(typeof(GenericResponse<IReadOnlyDictionary<string, GenericResponse>>), 200)]
|
||||
public async Task<ActionResult<GenericResponse<IReadOnlyDictionary<string, GenericResponse>>>> TwoFactorAuthenticationConfirmationsDenyPost(string botNames) => await TwoFactorAuthenticationConfirmationsPost(botNames, false).ConfigureAwait(false);
|
||||
public async Task<ActionResult<GenericResponse<IReadOnlyDictionary<string, GenericResponse>>>> TwoFactorAuthenticationConfirmationsCancelPost(string botNames) => await TwoFactorAuthenticationConfirmationsPost(botNames, false).ConfigureAwait(false);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches 2FA tokens of given bots, requires ASF 2FA module to be active on them.
|
||||
|
||||
@@ -647,16 +647,32 @@ StackTrace:
|
||||
<comment>{0} will be replaced by the bug's name provided by ASF</comment>
|
||||
</data>
|
||||
|
||||
<data name="BotWalletBalance" xml:space="preserve">
|
||||
<value>Lompakon saldo: {0} {1}</value>
|
||||
<comment>{0} will be replaced by wallet balance value, {1} will be replaced by currency name</comment>
|
||||
</data>
|
||||
<data name="BotHasNoWallet" xml:space="preserve">
|
||||
<value>Botilla ei ole lompakkoa.</value>
|
||||
</data>
|
||||
<data name="BotLevel" xml:space="preserve">
|
||||
<value>Botin taso on {0}.</value>
|
||||
<comment>{0} will be replaced by bot's level</comment>
|
||||
</data>
|
||||
|
||||
|
||||
<data name="ErrorAborted" xml:space="preserve">
|
||||
<value>Keskeytetty!</value>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<data name="PluginLoaded" xml:space="preserve">
|
||||
<value>{0} ladattiin onnistuneesti!</value>
|
||||
<comment>{0} will be replaced by the name of the custom ASF plugin</comment>
|
||||
</data>
|
||||
<data name="PluginLoading" xml:space="preserve">
|
||||
<value>Ladataan {0} V{1}...</value>
|
||||
<comment>{0} will be replaced by the name of the custom ASF plugin, {1} will be replaced by its version</comment>
|
||||
</data>
|
||||
<data name="NothingFound" xml:space="preserve">
|
||||
<value>Mitään ei löytynyt!</value>
|
||||
</data>
|
||||
|
||||
@@ -581,7 +581,7 @@ StackTrace:
|
||||
<value>De door jou ingevoerde CurrentCulture is ongeldig. ASF zal de standaardtaal blijven gebruiken!</value>
|
||||
</data>
|
||||
<data name="TranslationIncomplete" xml:space="preserve">
|
||||
<value>ASF probeert de {0} taalmodule te gebruiken, maar het vertalen in deze taal is slechts {1} compleet. Misschien kan je ons helpen om ASF te vertalen in jouw taal?</value>
|
||||
<value>ASF zal de {0} taalmodule gebruiken. De vertaling, inclusief de Wiki, is {1} compleet. Misschien kun je ons helpen om ASF te vertalen in jouw taal?</value>
|
||||
<comment>{0} will be replaced by culture code, such as "en-US", {1} will be replaced by completeness percentage, such as "78.5%"</comment>
|
||||
</data>
|
||||
<data name="IdlingGameNotPossible" xml:space="preserve">
|
||||
|
||||
@@ -248,6 +248,30 @@ namespace ArchiSteamFarm.Plugins {
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task<bool> OnBotFriendRequest(Bot bot, ulong steamID) {
|
||||
if ((bot == null) || (steamID == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(bot) + " || " + nameof(steamID));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((ActivePlugins == null) || (ActivePlugins.Count == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IList<bool> responses;
|
||||
|
||||
try {
|
||||
responses = await Utilities.InParallel(ActivePlugins.OfType<IBotFriendRequest>().Select(plugin => plugin.OnBotFriendRequest(bot, steamID))).ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return responses.Any(response => response);
|
||||
}
|
||||
|
||||
internal static async Task OnBotInit(Bot bot) {
|
||||
if (bot == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(bot));
|
||||
|
||||
37
ArchiSteamFarm/Plugins/IBotFriendRequest.cs
Normal file
37
ArchiSteamFarm/Plugins/IBotFriendRequest.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2019 Ł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.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.Plugins {
|
||||
[PublicAPI]
|
||||
public interface IBotFriendRequest : IPlugin {
|
||||
/// <summary>
|
||||
/// ASF will call this method for unhandled (ignored and rejected) friend requests and Steam group invites received by the bot.
|
||||
/// </summary>
|
||||
/// <param name="bot">Bot object related to this callback.</param>
|
||||
/// <param name="steamID">64-bit Steam identificator of the user that sent a friend request, or a group that the bot has been invited to.</param>
|
||||
/// <returns>True if the request should be accepted as part of this plugin, false otherwise.</returns>
|
||||
[NotNull]
|
||||
Task<bool> OnBotFriendRequest([NotNull] Bot bot, ulong steamID);
|
||||
}
|
||||
}
|
||||
@@ -152,8 +152,11 @@ namespace ArchiSteamFarm {
|
||||
Dictionary<(uint AppID, Steam.Asset.EType Type), List<uint>> finalSets = GetInventorySets(inventory);
|
||||
|
||||
// Once we have both states, we can check overall fairness
|
||||
foreach (((uint AppID, Steam.Asset.EType Type) set, List<uint> afterAmounts) in finalSets) {
|
||||
List<uint> beforeAmounts = initialSets[set];
|
||||
foreach (((uint AppID, Steam.Asset.EType Type) set, List<uint> beforeAmounts) in initialSets) {
|
||||
if (!finalSets.TryGetValue(set, out List<uint> afterAmounts)) {
|
||||
// If we have no info about this set, then it has to be a bad one
|
||||
return false;
|
||||
}
|
||||
|
||||
// If amount of unique items in the set decreases, this is always a bad trade (e.g. 1 1 -> 0 2)
|
||||
if (afterAmounts.Count < beforeAmounts.Count) {
|
||||
|
||||
Binary file not shown.
@@ -2013,6 +2013,7 @@
|
||||
</param>
|
||||
<returns>A <see cref="T:SteamKit2.CDNClient.DepotChunk"/> instance that contains the data for the given chunk.</returns>
|
||||
<exception cref="T:System.ArgumentNullException">chunk's <see cref="P:SteamKit2.DepotManifest.ChunkData.ChunkID"/> was null.</exception>
|
||||
<exception cref="T:System.IO.InvalidDataException">Thrown if the downloaded data does not match the expected length.</exception>
|
||||
</member>
|
||||
<member name="M:SteamKit2.CDNClient.DownloadDepotChunkAsync(System.UInt32,SteamKit2.DepotManifest.ChunkData,System.String,System.String,System.Byte[])">
|
||||
<summary>
|
||||
@@ -2035,6 +2036,7 @@
|
||||
This is used for decrypting filenames (if needed) in depot manifests, and processing depot chunks.
|
||||
</param>
|
||||
<exception cref="T:System.ArgumentNullException">chunk's <see cref="P:SteamKit2.DepotManifest.ChunkData.ChunkID"/> was null.</exception>
|
||||
<exception cref="T:System.IO.InvalidDataException">Thrown if the downloaded data does not match the expected length.</exception>
|
||||
</member>
|
||||
<member name="M:SteamKit2.CDNClient.Dispose">
|
||||
<summary>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2013,6 +2013,7 @@
|
||||
</param>
|
||||
<returns>A <see cref="T:SteamKit2.CDNClient.DepotChunk"/> instance that contains the data for the given chunk.</returns>
|
||||
<exception cref="T:System.ArgumentNullException">chunk's <see cref="P:SteamKit2.DepotManifest.ChunkData.ChunkID"/> was null.</exception>
|
||||
<exception cref="T:System.IO.InvalidDataException">Thrown if the downloaded data does not match the expected length.</exception>
|
||||
</member>
|
||||
<member name="M:SteamKit2.CDNClient.DownloadDepotChunkAsync(System.UInt32,SteamKit2.DepotManifest.ChunkData,System.String,System.String,System.Byte[])">
|
||||
<summary>
|
||||
@@ -2035,6 +2036,7 @@
|
||||
This is used for decrypting filenames (if needed) in depot manifests, and processing depot chunks.
|
||||
</param>
|
||||
<exception cref="T:System.ArgumentNullException">chunk's <see cref="P:SteamKit2.DepotManifest.ChunkData.ChunkID"/> was null.</exception>
|
||||
<exception cref="T:System.IO.InvalidDataException">Thrown if the downloaded data does not match the expected length.</exception>
|
||||
</member>
|
||||
<member name="M:SteamKit2.CDNClient.Dispose">
|
||||
<summary>
|
||||
|
||||
2
wiki
2
wiki
Submodule wiki updated: 18a3f6771a...92db2be904
Reference in New Issue
Block a user