Commit graph

6499 commits

Author SHA1 Message Date
Łukasz Domeradzki
440e43935a
Misc 2024-09-19 14:08:45 +02:00
Łukasz Domeradzki
1dff9a48a8
Closes #3291
As presented in the issue, we might end up in situation when parallel-processing and accepting two neutral+ trade offers will result in unwanted inventory state, because while they're both neutral+ and therefore OK to accept standalone, the combination of them both causes active badge progress degradation.

Considering the requirements we have, e.g. still processing trades in parallel, being performant, low on resources and with limited Steam servers overhead, the solution that I came up with in regards to this issue is quite simple:

- After we determine the trade to be neutral+, but before we tell the parse trade routine to accept it, we check if shared with other parallel processes set of handled sets contains any sets that we're currently processing.
- If no, we update that set to include everything we're dealing with, and tell the caller to accept this trade.
- If yes, we tell the caller to retry this trade after (other) accepted trades are confirmed and handled as usual.

This solves some issues and creates some optimistic assumptions:
- First of all, it solves the original issue, since if trade A and B both touch set S, then only one of them will be accepted. It's not deterministic which one (the one that gets to the check first), and not important anyway.
- We do not "lock" the sets before we determine that trade is neutral+, because otherwise unrelated users could spam us with non-neutral+ trades in order to lock the bot in infinite retry. This way they can't, as if the trade is determined to not be neutral+ then it never checks for concurrent processing.
- We are optimistic about resources usage. This routine could be made much more complicated to be more synchronous in order to avoid unnecessary calls to inventory and matching, however, that'd slow down the whole process only because the next call MAYBE will be determined as unneeded. Due to that, ASF is optimistic that trades will (usually) be unrelated, and can be processed in parallel, and if the conflict happens then simply we end up in a situation where we did some extra work for no reason, which is better than waiting with the work till all previous trades are processed.
- As soon as the conditions are met, the conflicting trades are retried to check if the conditions allow to accept them. If yes, they'll be accepted almost immediately after previous ones, if not, they'll be rejected as non-neutral+ anymore.

This way the additional code does not hurt the performance, parallel processing or anything else in usually expected optimistic scenarios, while adding some additional overhead in pessimistic ones, which is justified considering we don't want to degrade the badge progress.
2024-09-19 13:53:11 +02:00
ArchiBot
dcdb2cb175
Automatic translations update 2024-09-18 08:49:16 +00:00
Łukasz Domeradzki
7b65c1aeb7
Add support for telling plugins if runtime is trimmed 2024-09-16 17:58:35 +02:00
Łukasz Domeradzki
a27973800c
Provide extra info when failing to initialize plugins with TypeLoadException 2024-09-16 16:45:52 +02:00
Łukasz Domeradzki
cefa3e1e1e
Fix reconnection with connection being lost
After changes regarding to callbacks handling, we accidentally broke the reconnection logic. In particular, forced connection implicitly did disconnect with disconnect callback, but disconnect callback killed our callbacks handling loop for future connection since it was instructed to not reconnect... Pretty convulated logic.

Let's attempt to fix and simplify it. There is no forced connection concept anymore, but rather a new reconnect function which either, triggers reconnection through usual disconnection logic, or connects in edge case if we attempted to reconnect with already disconnnected client.

This way the status transition is more predictable, as we Connect() only in 3 cases:
- Initial start, including !start command, when we actually spawn the callbacks handling loop
- Upon disconnection, if we're configured to reconnect
- Reconnection, in case we're already disconnected and can't use above

And we use reconnect when:
- Failure in heartbeats to detect disconnections sooner
- Failure in refreshing access tokens, since if we lose our refresh token then the only way to get a new one is to reconnect

And finally disconnect is triggered when:
- Stopping the bot, especially !stop
- Bulletproofing against trying to connect when !KeepRunning and likewise
- Usual Steam maintenance and other network issues (which usually trigger reconnection)

The codebase is too huge to analyze every possible edge case, but with this logic I can no longer reproduce the previous issue
2024-09-13 14:41:11 +02:00
Łukasz Domeradzki
061e61b740
Closes #3289 2024-09-13 13:42:20 +02:00
Łukasz Domeradzki
3bb83610b8
Misc refactor after #3287 2024-09-13 10:04:56 +02:00
dm1tz
8e85b87764
Add loot& and transfer& commands (#3287)
* Add `loot&` and `transfer&` commands

* Remove trailing comment
2024-09-13 09:20:35 +02:00
ArchiBot
aa1cd98646
Automatic translations update 2024-09-10 02:18:00 +00:00
ArchiBot
5f545a9bbc
Automatic translations update 2024-09-09 02:18:15 +00:00
Łukasz Domeradzki
efdc3eb7bb
Misc 2024-09-04 22:24:31 +02:00
ArchiBot
720a24e9ad
Automatic translations update 2024-09-04 02:17:13 +00:00
Łukasz Domeradzki
63c61f8e47
Misc 2024-09-01 23:56:25 +02:00
Łukasz Domeradzki
54a092a822
Take into account extended_onlyallowrunincountries when deciding upon region locks 2024-09-01 14:05:08 +02:00
Łukasz Domeradzki
14388487fd
Fix build 2024-08-26 10:07:31 +02:00
Łukasz Domeradzki
a155748f88
Misc 2024-08-26 10:04:54 +02:00
ArchiBot
ebac577ede
Automatic translations update 2024-08-19 02:15:10 +00:00
Łukasz Domeradzki
fab9d95096
Allow nullable T for concurrent list
Even if we don't use it, no reason to not support it, since it is in underlying collection
2024-08-18 03:21:03 +02:00
Łukasz Domeradzki
2dc853ebfc
Misc 2024-08-18 03:17:30 +02:00
Łukasz Domeradzki
5867a351a8
Misc 2024-08-18 03:14:11 +02:00
Łukasz Domeradzki
5605e9a666
Misc 2024-08-18 01:59:25 +02:00
Łukasz Domeradzki
337b720d31
Misc deduplication 2024-08-18 01:53:13 +02:00
Łukasz Domeradzki
5a41d559a3
Misc
No point in making this available for all IEnumerables, only ICollections are affected
2024-08-16 03:35:09 +02:00
Łukasz Domeradzki
b6805a94a3
Add workaround for LINQ race condition with concurrent collections
This is some next-level race condition, so for those interested:
- Concurrent collections are thread-safe in a way that each operation is atomic
- Naturally if you call two atomic operations in a row, the result is no longer atomic, since there could be some changes between the first and the last
- Certain LINQ operations such as OrderBy(), Reverse(), ToArray(), among more, use internal buffer for operation with certain optimization that checks if input is ICollection, if yes, it calls Count and CopyTo(), for OrderBy in this example
- In result, such LINQ call is not guaranteed to be thread-safe, since it assumes those two calls to be atomic, while they're not in reality.

This issue is quite hard to spot in real applications, since it's not that easy to trigger it (you need to call the operation on ICollection and then have another thread modifying it while enumerating). This is probably why we've never had any real problem until I've discovered this madness with @Aareksio in entirely different project.

As a workaround, we'll explicitly convert some ICollection inputs to IEnumerable, in particular around OrderBy(), so the optimization is skipped and the result is not corrupted.

I've added unit tests which ensure this workaround works properly, and you can easily reproduce the problem by removing AsLinqThreadSafeEnumerable() in them.

See https://github.com/dotnet/runtime/discussions/50687 for more insight

I have no clue who thought that ignoring this issue is a good idea, at the very least concurrent collections should have opt-out mechanism from those optimizations, there is no reason for them to not do that.
2024-08-16 03:25:58 +02:00
ArchiBot
85c4e4ac37
Automatic translations update 2024-08-14 02:14:19 +00:00
ArchiBot
9540e564fc
Automatic translations update 2024-08-13 02:15:24 +00:00
Łukasz Domeradzki
90f2d93768
Optimize mobile authenticator, add unit tests 2024-08-11 02:21:00 +02:00
Łukasz Domeradzki
ff7a1e7c0e
Misc optimization 2024-08-09 23:03:56 +02:00
Łukasz Domeradzki
2c9d015f38
Fix @xPaw breaking changes
How could you!
2024-08-07 03:02:04 +02:00
Łukasz Domeradzki
ce4b41ee73
Misc 2024-08-06 12:04:52 +02:00
Łukasz Domeradzki
0c3c4c08ea
Rewrite callbacks handling loop to new mechanism 2024-08-06 12:02:38 +02:00
ArchiBot
bd00911f85
Automatic translations update 2024-08-06 02:12:59 +00:00
Łukasz Domeradzki
4cb3123ff6
Update BotConfig.cs 2024-08-06 03:12:06 +02:00
Łukasz Domeradzki
4ff1411c38
Closes #3261 2024-08-06 03:07:41 +02:00
Łukasz Domeradzki
f983a2eab2
Refactor UserInterfaceMode, kill SetCurrentMode() 2024-08-06 03:00:14 +02:00
Łukasz Domeradzki
afa602f940
Resolve remainings of CA1863 2024-08-05 02:45:53 +02:00
Łukasz Domeradzki
773698a0d4
Closes #3264
THANKS @ezhevita
2024-08-05 02:37:50 +02:00
Łukasz Domeradzki
7a8e2091a6
Use Microsoft.CodeAnalysis.ResxSourceGenerator for localization 2024-08-05 01:42:09 +02:00
Łukasz Domeradzki
d3dbfc5e9e
Closes #3262 2024-08-03 15:36:45 +02:00
Łukasz Domeradzki
c7b9751e0e
Bump, remove obsolete prop 2024-08-01 19:18:35 +02:00
Łukasz Domeradzki
c737c792f6
Misc SK2 improvements 2024-07-21 18:09:47 +02:00
Łukasz Domeradzki
b664b85495
Remove ConfigureAwaitChecker.Analyzer
Appropriate detecion is now available in Roslyn
2024-07-20 01:01:45 +02:00
Łukasz Domeradzki
62e786b9b8
Bring back deprecated function 2024-07-14 21:13:26 +02:00
Łukasz Domeradzki
f87b63d6ee
Merge branch 'main' of https://github.com/JustArchiNET/ArchiSteamFarm 2024-07-14 17:25:05 +02:00
Łukasz Domeradzki
3b3f1caf84
Misc 2024-07-14 17:25:03 +02:00
ArchiBot
e2f2b6aa5d
Automatic translations update 2024-07-12 02:10:43 +00:00
Łukasz Domeradzki
dc57860f0d
Misc optimization 2024-07-11 01:34:49 +02:00
Vita Chumakova
b14d5de641
Fix struct reordering (#3247) 2024-07-10 13:08:06 +02:00
ArchiBot
fe76ada8d0
Automatic translations update 2024-07-10 02:11:36 +00:00