* Update Actions.cs, Bot.cs, and BotConfig.cs
* First round of refactoring
* Check all badge pages
* Update Bot.cs
* Make sure multiple pages of badges work with foil badges and Make item selection algorithm work with all kinds of amount values we could get from Valve
* Change order of params in Actions.SendInventory(...), Cache amount of cards for game ids, Count card elements on page when fetching card count per game, Calculate items to send for all games in parallel
* Add unit tests
* Make sure only one real app id and one asset type are present while computing cards to send and Test it
* Update ArchiWebHandler.cs
* Update Bot.cs
* Fix iteration over badge pages
* Update Bot.cs
* Make stackable item stacks smaller if possible
* Simplify code based on changing stack size of stackable items and Adapt tests
* Consider only cards of the same rarity to be of one set and Add handling of already crafted level 5 badges
* Implement feedback
* Update Bot.cs
* Update Bot.cs
* Implement feedback from review
* Adapt tests
* Improve XPath efficiency
* Check real result for additional values in unit tests
* Implement feedback
* Add additional test combining classID, type and rarity
* Make collections readonly wherever you can
* Optimize misc. code and Add SetTypesToComplete to BotConfig
* Throw exception if we have more card types than cards per set
* Remove SendSetsOnCompleted and Make CompleteTypesToSend empty per default
* Fix existing unit tests and add new ones due to new exception
* Please nitpicky Archi
* Update Bot.cs
* Change expected exception type
* Make appID constants local
* Update Bot.cs and BotConfig.cs
* Do as JetBrains Rider says
* Only fetch card count for badge if we have cards for it
* Improve naming and fix handling of URIs for foil badges
* Add Bot.LoadCardsPerSet(...), Bot.GetItemsForFullSets(...) and Trading.GetInventorySets(...) to public API
* Let AWH do its job
* Make Bot.GetPossiblyCompletedBadgeAppIDs() part of public API as well
This makes it possible to accept other confirmation types than trading if they follow the same logic with creator ID. If somebody wants to ensure that he's accepting only trades with given IDs, then he should combine it with acceptedType, which is already supported and expected.
This makes it possible to use ASF's HandleTwoFactorAuthenticationConfirmations() e.g. for market listings in custom plugins.
Answers the remaining part of #1891
* Use IAsyncEnumerable for getting inventory
* Don't suppress exceptions, catch them in ResponseUnpackBoosters
* Make sure we don't get duplicate assets during unpack
* Rewrite inventory filters to LINQ methods
* Add handling duplicate items, mark GetInventory as obsolete, catch exceptions from getting inventory errors
* Mark GetInventoryEnumerable as NotNull, don't check received inventory for null, use comparison with nullable values
* Use specific types of exceptions, log exceptions using LogGenericWarningException, handle IOException separately (without logging the exception), remove default null value
* Use old method signature for obsolete API
* Use error level for generic exceptions
* Fix wantedSets not being used
* Correct exception types, rename function
* Replace exception types
* Make SendTradeOfferAsync that accepts Func<Steam.Asset, bool> as a filter
* Fix missing targetSteamID in ResponseTransferByRealAppIDs
* Make parameter name readable
* Rename method
* Implement basic plugin system
* The dawn of new era
* Add plugins warning
* Move more members to PublicAPI
* Open commands for the plugins
* Add IBotHackNewChat
* Run plugin events in parallel
* Use properties in IPlugin
* Hook our custom plugin into CI to ensure it compiles
* Fix dotnet brain damage
* Add IBotsComparer
* Add code documentation
* Add IBotTradeOffer
* Add IBotTradeOffer example
* Add IBotTradeOfferResults
* Final bulletproofing
* Final renaming
This will probably need a lot more tests, tweaking and bugfixing, but basic logic is:
- MatchActively added to TradingPreferences with value of 16
- User must also use SteamTradeMatcher, can't use MatchEverything
- User must have statistics enabled and be eligible for being listed (no requirement of having 100 items minimum)
Once all requirements are passed, statistics module will communicate with the listing and fetch match everything bots:
- The matching will start in 1h since ASF start and will repeat every day (right now it starts in 1 minute to aid debugging).
- Each matching is composed of up to 10 rounds maximum.
- In each round ASF will fetch our inventory and inventory of listed bots in order to find MatchableTypes items to be matched. If match is found, offer is being sent and confirmed automatically.
- Each set (composition of item type + appID it's from) can be matched in a single round only once, this is to minimize "items no longer available" as much as possible and also avoid a need to wait for each bot to react before sending all trades.
- Round ends when we try to match a total of 20 bots, or we hit no items to match in consecutive 10 tries with 10 different bots.
- If last round resulted in at least a single trade being sent, next round starts within 5 minutes since last one, otherwise matching ends and repeats the next day.
We'll see how it works in practice, expect a lot of follow-up commits, unless I won't have anything to fix or improve.