Compare commits

...

26 Commits

Author SHA1 Message Date
JustArchi
6201774f52 Update SK2 libs 2019-02-01 22:29:18 +01:00
JustArchi
4f71732ec2 Misc 2019-02-01 22:25:28 +01:00
JustArchi
a7e8ac5388 Translations update 2019-02-01 21:53:12 +01:00
dependabot[bot]
b3e9c38812 Bump ASF-WebConfigGenerator from 003693a to adb2111
Bumps [ASF-WebConfigGenerator](https://github.com/JustArchiNET/ASF-WebConfigGenerator) from `003693a` to `adb2111`.
- [Release notes](https://github.com/JustArchiNET/ASF-WebConfigGenerator/releases)
- [Commits](003693a1fe...adb2111205)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-01 01:32:14 +00:00
dependabot[bot]
a3e7f7c461 Bump ASF-ui from bb4b80b to bdcae2d
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `bb4b80b` to `bdcae2d`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](bb4b80befe...bdcae2df8b)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-01 01:25:20 +00:00
JustArchi
10dc572b43 Misc 2019-01-31 04:54:35 +01:00
JustArchi
95356af9d3 Add IBotFriendRequest plugin interface 2019-01-31 04:45:17 +01:00
dependabot[bot]
dd2b1bde25 Bump ASF-ui from 78f1eb5 to bb4b80b
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `78f1eb5` to `bb4b80b`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](78f1eb5262...bb4b80befe)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-31 01:33:51 +00:00
JustArchi
53ecd8d8e6 Misc 2019-01-31 02:31:01 +01:00
dependabot[bot]
623f1d14cf Bump wiki from 7181306 to ecb9a4d
Bumps [wiki](https://github.com/JustArchiNET/ArchiSteamFarm.wiki) from `7181306` to `ecb9a4d`.
- [Release notes](https://github.com/JustArchiNET/ArchiSteamFarm.wiki/releases)
- [Commits](7181306766...ecb9a4dcc7)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-31 01:27:25 +00:00
JustArchi
3c53e9aff4 Merge branch 'master' of https://github.com/JustArchiNET/ArchiSteamFarm 2019-01-30 23:25:54 +01:00
JustArchi
51f07b747e Misc 2019-01-30 23:25:51 +01:00
dependabot[bot]
537b2eb55f Bump ASF-ui from 9ad0548 to 78f1eb5
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `9ad0548` to `78f1eb5`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](9ad0548216...78f1eb5262)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-30 01:25:37 +00:00
dependabot[bot]
ac14ce96af Bump wiki from 18a3f67 to 7181306
Bumps [wiki](https://github.com/JustArchiNET/ArchiSteamFarm.wiki) from `18a3f67` to `7181306`.
- [Release notes](https://github.com/JustArchiNET/ArchiSteamFarm.wiki/releases)
- [Commits](18a3f6771a...7181306766)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-29 02:46:21 +00:00
dependabot[bot]
eefab22ead Bump Microsoft.NET.Test.Sdk
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.0.0-preview-20181205-02 to 16.0.0-preview-20190124-02.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v16.0.0-preview-20181205-02...v16.0.0-preview-20190124-02)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-29 02:45:21 +00:00
dependabot[bot]
b9e1daa786 Bump ASF-ui from 2a137a3 to 9ad0548
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `2a137a3` to `9ad0548`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](2a137a3fb4...9ad0548216)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-29 01:33:41 +00:00
dependabot[bot]
5e47914512 Bump ASF-ui from b5492c9 to 2a137a3
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `b5492c9` to `2a137a3`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](b5492c94ea...2a137a3fb4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-28 01:55:54 +00:00
dependabot[bot]
43679c647f Bump ASF-WebConfigGenerator from 5acb62a to 003693a
Bumps [ASF-WebConfigGenerator](https://github.com/JustArchiNET/ASF-WebConfigGenerator) from `5acb62a` to `003693a`.
- [Release notes](https://github.com/JustArchiNET/ASF-WebConfigGenerator/releases)
- [Commits](5acb62a4a9...003693a1fe)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-28 01:51:30 +00:00
dependabot[bot]
ae8e9e4666 Bump NLog.Web.AspNetCore from 4.7.1 to 4.8.0
Bumps [NLog.Web.AspNetCore](https://github.com/NLog/NLog.Web) from 4.7.1 to 4.8.0.
- [Release notes](https://github.com/NLog/NLog.Web/releases)
- [Changelog](https://github.com/NLog/NLog.Web/blob/master/CHANGELOG.MD)
- [Commits](https://github.com/NLog/NLog.Web/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-28 01:31:05 +00:00
JustArchi
47b2aa137f Move token fetching further below 2019-01-26 22:11:35 +01:00
JustArchi
546cc55ab9 Misc 2019-01-26 22:07:00 +01:00
JustArchi
e86bf695c8 Closes #1060 2019-01-26 22:05:31 +01:00
JustArchi
a6e4208b40 Misc optimization 2019-01-26 18:17:07 +01:00
JustArchi
3f43b641d9 Closes #1059 2019-01-26 18:14:07 +01:00
dependabot[bot]
60615ed163 Bump ASF-ui from 84019fc to b5492c9
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `84019fc` to `b5492c9`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](84019fc51c...b5492c94ea)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-25 01:27:11 +00:00
JustArchi
ae48e8d93b Bump 2019-01-24 21:13:14 +01:00
22 changed files with 188 additions and 54 deletions

2
ASF-ui

Submodule ASF-ui updated: 84019fc51c...6e328457f5

View File

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

View File

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

View File

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

View File

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

View File

@@ -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" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

Submodule wiki updated: 18a3f6771a...92db2be904