Compare commits

..

346 Commits

Author SHA1 Message Date
JustArchi
21156a6c79 Link new translations 2017-02-09 13:45:31 +01:00
Łukasz Domeradzki
eb56b3c2ac Merge pull request #460 from JustArchi/l10n
New Crowdin translations
2017-02-09 13:44:28 +01:00
JustArchi
4b4f2626a8 Fix ASF crash on invalid IdentitySecret/SharedSecret 2017-02-09 13:23:54 +01:00
JustArchi
ec4439afb4 Make DismissInventoryNotifications false by default
The amount of people that have no clue what is happening is too damn high.
2017-02-09 13:16:30 +01:00
Łukasz Domeradzki
9b2a86d891 Translated 2017-02-09 11:42:42 +01:00
Łukasz Domeradzki
d2c2e30d47 New translations 2017-02-08 17:23:23 +01:00
JustArchi
d7f2610313 Bump MinHeartBeatTTL from 5 to 10 2017-02-08 14:55:40 +01:00
JustArchi
1363b23008 Handle temporary fetching failures appropriately 2017-02-08 14:41:28 +01:00
JustArchi
c1a1cf15b0 Misc 2017-02-08 14:36:10 +01:00
JustArchi
89a36beeae Improve statistics reporting
Skip reporting when user has private or empty inventory
2017-02-08 14:35:01 +01:00
JustArchi
92b9aeae31 Fix Mono compilation 2017-02-07 21:09:08 +01:00
Łukasz Domeradzki
ef01b304bb Translated 2017-02-07 20:22:25 +01:00
JustArchi
a8045ac50b Fix async/await with ConcurrentHashSet
Now this is a nice bug that was found accidentally by ArchiBoT...
ReaderWriterLockSlim() is very decent solution, but it's thread-based, and we're using our ConcurrentHashSet in mixed async/sync context. This means that if we use something like:
foreach (var item in concHashSet) {
    await AnythingAsync().ConfigureAwait(false);
}
It's totally possible that we'll request read lock as thread 1, and release the read lock as thread 2, which will lead to RWLock exception => System.Threading.SynchronizationLockException: The read lock is being released without being held.
Fortunately it looks like we didn't have any scenario like this in ASF, as this was possible only when we async/await while enumerating over ConcurrentHashSet, so that specific bug didn't affect ASF codebase (yet). Still, I must fix this as current implementation is not thread-safe, so our HashSet is in fact not concurrent in the first place.
I analyzed possible solutions and there are basically 3: either using ConcurrentDictionary and wrapping around it, replacing lock with SemaphoreSlim, or using third-party AsyncReaderWriterLock from StephenCleary. SemaphoreSlim entirely kills the concept of multiple readers one writer, and could affect performance negatively, moreover - it doesn't support upgreadable lock scenario we have with ReplaceIfNeededWith(). Concurrent dictionary would be nice if I didn't have that awful memory hit from storing mandatory pointless value, plus I don't really like concept of wrapping around conc dictionary if I can simply use it right away and drop my conc hashset entirely. AsyncReaderWriterLock seem to be really well written, and works on Mono + should be compatible with .NET core in the future, so we should go for it as it's the best bet both performance-wise and memory-wise.
This brings another package dependency and changes a bit backend of ConcurrentHashSet
2017-02-07 20:14:51 +01:00
JustArchi
f97379bf60 Misc 2017-02-07 17:35:52 +01:00
JustArchi
5197fffa3b Misc 2017-02-07 17:25:32 +01:00
Łukasz Domeradzki
dc74114f4c New translations 2017-02-07 14:23:13 +01:00
JustArchi
872151d2f7 Misc 2017-02-07 13:09:41 +01:00
JustArchi
d495d649ba Make WCF accept commands starting with '!' as well 2017-02-07 10:49:58 +01:00
Łukasz Domeradzki
dbd9389d6c Translated 2017-02-07 08:20:57 +01:00
Łukasz Domeradzki
965432d346 New translations 2017-02-07 02:40:49 +01:00
Łukasz Domeradzki
c4e1fe2bcf New translations 2017-02-06 22:51:51 +01:00
Łukasz Domeradzki
b0fc06f3d2 New translations 2017-02-06 22:51:48 +01:00
Łukasz Domeradzki
4845b21642 New translations 2017-02-06 22:40:49 +01:00
Łukasz Domeradzki
b7f3ce4036 New translations 2017-02-06 22:22:22 +01:00
Łukasz Domeradzki
6217552f23 New translations 2017-02-06 22:22:19 +01:00
Łukasz Domeradzki
a21689c76f New translations 2017-02-06 22:10:52 +01:00
Łukasz Domeradzki
a461b2da64 New translations 2017-02-06 22:01:52 +01:00
Łukasz Domeradzki
c653edfca8 New translations 2017-02-06 21:50:50 +01:00
Łukasz Domeradzki
53b38f5d55 New translations 2017-02-06 21:40:49 +01:00
Łukasz Domeradzki
9896758c3b New translations 2017-02-06 21:30:52 +01:00
Łukasz Domeradzki
855a09d4ea New translations 2017-02-06 21:21:27 +01:00
Łukasz Domeradzki
bfbcf59770 Translated 2017-02-06 21:10:59 +01:00
Łukasz Domeradzki
29924ad379 New translations 2017-02-06 21:10:55 +01:00
Łukasz Domeradzki
fd70edc5dd New translations 2017-02-06 21:02:33 +01:00
Łukasz Domeradzki
0431592be8 New translations 2017-02-06 20:52:44 +01:00
Łukasz Domeradzki
78405e9ccf New translations 2017-02-06 20:40:52 +01:00
Łukasz Domeradzki
a6f0c8f7c1 New translations 2017-02-06 20:30:51 +01:00
Łukasz Domeradzki
057a291f35 New translations 2017-02-06 20:21:17 +01:00
Łukasz Domeradzki
e0edfebe31 New translations 2017-02-06 20:00:18 +01:00
Łukasz Domeradzki
b210c24c9c New translations 2017-02-06 19:51:44 +01:00
Łukasz Domeradzki
f276762025 New translations 2017-02-06 19:31:44 +01:00
Łukasz Domeradzki
cdd9343903 New translations 2017-02-06 19:21:02 +01:00
Łukasz Domeradzki
33fc121e67 New translations 2017-02-06 19:20:57 +01:00
Łukasz Domeradzki
61bd191c15 Translated 2017-02-06 19:20:55 +01:00
Łukasz Domeradzki
05a7a40332 New translations 2017-02-06 19:00:57 +01:00
Łukasz Domeradzki
1535ec1c0c New translations 2017-02-06 18:44:40 +01:00
Łukasz Domeradzki
a7e2e8db73 New translations 2017-02-06 18:44:38 +01:00
Łukasz Domeradzki
1a91703157 New translations 2017-02-06 18:30:54 +01:00
Łukasz Domeradzki
7d0ff9f267 New translations 2017-02-06 18:30:51 +01:00
Łukasz Domeradzki
0753373ba9 New translations 2017-02-06 18:23:15 +01:00
Łukasz Domeradzki
96ee9692c0 New translations 2017-02-06 18:23:13 +01:00
Łukasz Domeradzki
4e6afe516a New translations 2017-02-06 16:21:08 +01:00
Łukasz Domeradzki
1f82a61346 New translations 2017-02-06 16:10:30 +01:00
JustArchi
8cf368ff88 Misc 2017-02-06 15:50:22 +01:00
JustArchi
d04e17a046 Code cleanup 2017-02-06 15:46:42 +01:00
Łukasz Domeradzki
b19a9fdf1f New translations 2017-02-06 09:42:34 +01:00
Łukasz Domeradzki
cc406998ff New translations 2017-02-06 09:42:32 +01:00
JustArchi
b4483057b9 Fix build 2017-02-05 14:35:55 +01:00
JustArchi
f72c51a2f8 Misc 2017-02-05 14:35:27 +01:00
JustArchi
c887dc102e Unify ASF/GUI startup 2017-02-05 14:32:38 +01:00
JustArchi
2af76f746d Closes #457 2017-02-05 13:52:00 +01:00
JustArchi
8fe30f7442 Bump 2017-02-05 09:08:59 +01:00
JustArchi
941e19ecc5 Apparently people do not understand this part clear enough 2017-02-05 09:05:50 +01:00
JustArchi
e7b6cc7801 Misc 2017-02-05 09:02:27 +01:00
JustArchi
3edc89c34e Bump 2017-02-05 08:12:41 +01:00
Łukasz Domeradzki
d1af9d0495 Merge pull request #455 from JustArchi/l10n
New Crowdin translations
2017-02-05 08:09:02 +01:00
JustArchi
ba3a792ca4 Misc 2017-02-05 08:06:38 +01:00
JustArchi
dba6fdfeeb TradingPreferences.DontAcceptBotTrades 2017-02-05 07:51:04 +01:00
Łukasz Domeradzki
5835bcbd54 New translations 2017-02-04 23:20:48 +01:00
Łukasz Domeradzki
1df0abb494 New translations 2017-02-04 23:10:53 +01:00
Łukasz Domeradzki
d6097106d8 New translations 2017-02-04 23:10:50 +01:00
Łukasz Domeradzki
db56078494 New translations 2017-02-04 23:00:50 +01:00
Łukasz Domeradzki
8d7098bf76 New translations 2017-02-04 16:00:52 +01:00
Łukasz Domeradzki
5a6edb4e25 New translations 2017-02-03 23:21:07 +01:00
Łukasz Domeradzki
089363af1b New translations 2017-02-03 23:11:11 +01:00
Łukasz Domeradzki
e0450452ab New translations 2017-02-03 20:12:14 +01:00
Łukasz Domeradzki
1dd1f81884 New translations 2017-02-03 18:23:48 +01:00
Łukasz Domeradzki
182975ce21 New translations 2017-02-03 17:53:11 +01:00
Łukasz Domeradzki
65a838c117 New translations 2017-02-03 17:42:58 +01:00
Łukasz Domeradzki
df8f5febd8 New translations 2017-02-03 17:31:41 +01:00
Łukasz Domeradzki
7e696125e8 New translations 2017-02-03 17:21:52 +01:00
Łukasz Domeradzki
3b5a9c6029 New translations 2017-02-03 17:21:49 +01:00
Łukasz Domeradzki
d4ebe33394 New translations 2017-02-03 17:13:13 +01:00
Łukasz Domeradzki
de0862c597 New translations 2017-02-03 17:06:54 +01:00
Łukasz Domeradzki
4252184f37 New translations 2017-02-03 16:44:14 +01:00
Łukasz Domeradzki
bd99f3fdc3 New translations 2017-02-03 16:34:29 +01:00
Łukasz Domeradzki
c8343993c7 New translations 2017-02-03 16:12:27 +01:00
Łukasz Domeradzki
a917d0133b New translations 2017-02-03 16:12:24 +01:00
Łukasz Domeradzki
05b4b9e907 New translations 2017-02-03 12:23:35 +01:00
Łukasz Domeradzki
10dd737e5c New translations 2017-02-03 12:23:31 +01:00
Łukasz Domeradzki
3b0ebf4126 New translations 2017-02-03 11:22:35 +01:00
JustArchi
1fb980f2bf Misc 2017-02-03 10:01:10 +01:00
JustArchi
8926297614 WCFProtocol -> WCFBinding
More appropriate
2017-02-03 09:59:02 +01:00
JustArchi
72141c53a3 Cleanup + missing CG bits 2017-02-03 09:56:18 +01:00
JustArchi
24350dcba5 Closes #448
Everything works on Windows, pending tests on Mono
2017-02-03 09:54:09 +01:00
JustArchi
0d6942b8ec Modify TradingPreferences default to None
Since introducing automated API keys, we do not want to make AcceptDonations the default option.
Existing configs will not be changed anyway.
2017-02-03 08:57:42 +01:00
Łukasz Domeradzki
6c1d28c978 Translated 2017-02-02 22:12:10 +01:00
Łukasz Domeradzki
fef93c5907 New translations 2017-02-02 21:31:37 +01:00
Łukasz Domeradzki
27072c688c New translations 2017-02-02 21:21:09 +01:00
Łukasz Domeradzki
94aa422cb8 New translations 2017-02-02 21:21:04 +01:00
Łukasz Domeradzki
3188a56af5 New translations 2017-02-02 21:11:49 +01:00
Łukasz Domeradzki
d5b1073f78 New translations 2017-02-02 21:11:45 +01:00
Łukasz Domeradzki
61c3b2f9cf Translated 2017-02-02 20:53:17 +01:00
Łukasz Domeradzki
861c502cb4 Translated 2017-02-02 20:41:46 +01:00
Łukasz Domeradzki
c622218a70 Translated 2017-02-02 20:33:01 +01:00
Łukasz Domeradzki
9089029d16 New translations 2017-02-02 20:21:33 +01:00
Łukasz Domeradzki
335c26efbc Translated 2017-02-02 20:21:25 +01:00
Łukasz Domeradzki
1f11817a37 New translations 2017-02-02 20:14:20 +01:00
Łukasz Domeradzki
9e2dfef644 New translations 2017-02-02 20:14:13 +01:00
Łukasz Domeradzki
cd287a4831 Translated 2017-02-02 20:14:06 +01:00
JustArchi
bd9fde0799 Misc 2017-02-02 19:04:31 +01:00
JustArchi
fd3aca7cbb Bump 2017-02-02 18:45:45 +01:00
Łukasz Domeradzki
e560456d52 Merge pull request #451 from JustArchi/l10n
New Crowdin translations
2017-02-02 18:40:00 +01:00
JustArchi
3de44af605 Misc 2017-02-02 18:02:02 +01:00
JustArchi
5bbb546b8a Closes #454 2017-02-02 17:56:37 +01:00
JustArchi
b1ff0a34db Fix possible crash 2017-02-02 14:04:34 +01:00
Łukasz Domeradzki
6d5fef4260 New translations 2017-02-02 12:23:17 +01:00
Łukasz Domeradzki
58725f0866 New translations 2017-02-01 23:32:17 +01:00
Łukasz Domeradzki
d4cb9a326e New translations 2017-02-01 23:01:03 +01:00
Łukasz Domeradzki
81f19c8971 New translations 2017-02-01 22:21:53 +01:00
Łukasz Domeradzki
b94c381263 New translations 2017-02-01 22:21:50 +01:00
Łukasz Domeradzki
6edc7d21a6 New translations 2017-02-01 22:11:42 +01:00
Łukasz Domeradzki
9cd6801e67 New translations 2017-02-01 22:01:53 +01:00
Łukasz Domeradzki
ec5e34d664 New translations 2017-02-01 21:51:41 +01:00
Łukasz Domeradzki
15c8ada4fa New translations 2017-02-01 21:41:42 +01:00
Łukasz Domeradzki
8d6842430d New translations 2017-02-01 21:31:49 +01:00
Łukasz Domeradzki
1e172b3266 New translations 2017-02-01 21:21:54 +01:00
Łukasz Domeradzki
f89fe15e4d New translations 2017-02-01 21:15:50 +01:00
Łukasz Domeradzki
f6b0589920 New translations 2017-02-01 21:15:46 +01:00
Łukasz Domeradzki
94d29720df New translations 2017-02-01 21:02:22 +01:00
Łukasz Domeradzki
cc13e1d423 New translations 2017-02-01 20:52:26 +01:00
Łukasz Domeradzki
4c960f3850 New translations 2017-02-01 20:43:13 +01:00
Łukasz Domeradzki
7912142dd3 New translations 2017-02-01 20:31:04 +01:00
Łukasz Domeradzki
68c9eb8dcc New translations 2017-02-01 20:11:50 +01:00
Łukasz Domeradzki
f905123946 New translations 2017-02-01 20:01:48 +01:00
Łukasz Domeradzki
a35a5af795 New translations 2017-02-01 19:54:09 +01:00
Łukasz Domeradzki
39fec43f29 New translations 2017-02-01 19:42:09 +01:00
Łukasz Domeradzki
6072cd21f0 New translations 2017-02-01 19:23:30 +01:00
Łukasz Domeradzki
1edb25b8cd New translations 2017-02-01 19:20:31 +01:00
Łukasz Domeradzki
94e18257b6 New translations 2017-02-01 19:02:35 +01:00
Łukasz Domeradzki
f938a2b21f New translations 2017-02-01 18:51:38 +01:00
Łukasz Domeradzki
91009af8f8 New translations 2017-02-01 18:42:21 +01:00
Łukasz Domeradzki
922f2476b3 Translated 2017-02-01 18:26:26 +01:00
Łukasz Domeradzki
b8e07ce765 Translated 2017-02-01 18:12:00 +01:00
Łukasz Domeradzki
58b1e5f92a New translations 2017-02-01 18:03:26 +01:00
Łukasz Domeradzki
c813e464fb Translated 2017-02-01 18:03:17 +01:00
Łukasz Domeradzki
3e837c9689 New translations 2017-02-01 17:52:30 +01:00
Łukasz Domeradzki
83baf9be92 Translated 2017-02-01 17:52:25 +01:00
Łukasz Domeradzki
67726e0dee New translations 2017-02-01 17:42:35 +01:00
Łukasz Domeradzki
cdd5bfd307 New translations 2017-02-01 17:32:13 +01:00
Łukasz Domeradzki
c2c262ea09 New translations 2017-02-01 17:32:10 +01:00
Łukasz Domeradzki
111d3c4cd5 New translations 2017-02-01 17:03:11 +01:00
Łukasz Domeradzki
de7f4f2857 New translations 2017-02-01 16:52:27 +01:00
Łukasz Domeradzki
66c8b32b8e New translations 2017-02-01 16:41:54 +01:00
Łukasz Domeradzki
09e738771b New translations 2017-02-01 16:32:37 +01:00
JustArchi
7d0d370330 Support case insensitivity for ASF matching 2017-02-01 15:35:03 +01:00
Łukasz Domeradzki
52fc58006d Translated 2017-02-01 15:23:45 +01:00
Łukasz Domeradzki
70952ad17e Translated 2017-02-01 14:14:07 +01:00
Łukasz Domeradzki
7e3a9dbb7c Translated 2017-02-01 14:06:21 +01:00
Łukasz Domeradzki
6fea823060 Translated 2017-02-01 14:06:18 +01:00
Łukasz Domeradzki
7cbfa24e7f Translated 2017-02-01 13:52:47 +01:00
JustArchi
245c04f7c5 Add more aliases 2017-02-01 13:02:47 +01:00
JustArchi
53c865d42b Add support for bot1..botN syntax 2017-02-01 12:20:49 +01:00
JustArchi
fa99281d49 Misc 2017-02-01 11:53:59 +01:00
Łukasz Domeradzki
88a0124ff0 Translated 2017-02-01 11:32:37 +01:00
Łukasz Domeradzki
5ee5dfb9b4 Translated 2017-02-01 11:32:29 +01:00
Łukasz Domeradzki
4c0971399c Translated 2017-02-01 11:21:50 +01:00
Łukasz Domeradzki
5dce8bed4c Translated 2017-02-01 11:02:22 +01:00
Łukasz Domeradzki
57cfac8e78 Translated 2017-02-01 11:02:16 +01:00
Łukasz Domeradzki
5854605446 Translated 2017-02-01 11:02:06 +01:00
JustArchi
5293b69261 Bring back no bots found + statusall extra response 2017-02-01 10:54:34 +01:00
Łukasz Domeradzki
f8f5df4e0e Translated 2017-02-01 09:02:27 +01:00
Łukasz Domeradzki
758bf868b2 Translated 2017-02-01 08:50:54 +01:00
Łukasz Domeradzki
f8f1de285f Translated 2017-02-01 08:50:52 +01:00
Łukasz Domeradzki
38112387ba Translated 2017-02-01 08:50:49 +01:00
Łukasz Domeradzki
3696f14e9a Translated 2017-02-01 08:11:40 +01:00
Łukasz Domeradzki
56ca507ca7 Translated 2017-02-01 06:02:21 +01:00
Łukasz Domeradzki
025e008bcb Translated 2017-02-01 03:00:55 +01:00
Łukasz Domeradzki
7659f5a994 Translated 2017-02-01 03:00:50 +01:00
Łukasz Domeradzki
23f2a5c269 Translated 2017-02-01 02:50:54 +01:00
Łukasz Domeradzki
d5aa87fe93 Translated 2017-02-01 02:50:50 +01:00
Łukasz Domeradzki
77a6461eb4 Translated 2017-02-01 02:20:54 +01:00
Łukasz Domeradzki
67a50ee6c1 Translated 2017-02-01 02:12:13 +01:00
Łukasz Domeradzki
368a19e76f Translated 2017-02-01 02:12:09 +01:00
Łukasz Domeradzki
23b722ebe0 Translated 2017-02-01 01:30:54 +01:00
Łukasz Domeradzki
5365ad09ba Translated 2017-02-01 01:21:58 +01:00
Łukasz Domeradzki
de5f5ae908 Translated 2017-02-01 01:21:56 +01:00
JustArchi
60eb99d4fd Bump 2017-02-01 00:53:38 +01:00
Łukasz Domeradzki
677e60328c Merge pull request #447 from JustArchi/l10n
New Crowdin translations
2017-02-01 00:52:02 +01:00
JustArchi
d5e865dff3 Misc 2017-02-01 00:49:49 +01:00
JustArchi
fb4cda513b Don't wait for bot being stopped too long 2017-02-01 00:44:52 +01:00
Łukasz Domeradzki
c3007d2d8f Translated 2017-01-31 22:42:45 +01:00
Łukasz Domeradzki
805f8d621b Translated 2017-01-31 22:42:42 +01:00
Łukasz Domeradzki
fb606b4459 Approved. Step name: Proofread 2017-01-31 22:42:37 +01:00
Łukasz Domeradzki
085d1a7290 Approved. Step name: Proofread 2017-01-31 22:42:35 +01:00
JustArchi
8e7ebfd2d1 Keep alphabetical order when targetting ASF commands 2017-01-31 22:32:38 +01:00
Łukasz Domeradzki
515ddedfd1 New translations 2017-01-31 22:32:06 +01:00
Łukasz Domeradzki
431621a125 Translated 2017-01-31 22:32:02 +01:00
JustArchi
ec697c2681 Remove obsolete commands 2017-01-31 22:27:16 +01:00
Łukasz Domeradzki
cece83e75d New translations 2017-01-31 22:24:08 +01:00
Łukasz Domeradzki
ed27bcf034 New translations 2017-01-31 22:24:05 +01:00
Łukasz Domeradzki
39301469ce New translations 2017-01-31 22:24:03 +01:00
Łukasz Domeradzki
83041622ad New translations 2017-01-31 22:24:00 +01:00
Łukasz Domeradzki
abbde82ab3 New translations 2017-01-31 22:23:58 +01:00
Łukasz Domeradzki
5c03d463ea New translations 2017-01-31 22:23:56 +01:00
Łukasz Domeradzki
cc1b47d765 New translations 2017-01-31 22:23:54 +01:00
Łukasz Domeradzki
720a6d1e32 New translations 2017-01-31 22:23:52 +01:00
Łukasz Domeradzki
6e8e8d2d39 Translated 2017-01-31 22:23:50 +01:00
Łukasz Domeradzki
6b0c894268 New translations 2017-01-31 22:23:48 +01:00
Łukasz Domeradzki
5a61512af6 New translations 2017-01-31 22:23:44 +01:00
Łukasz Domeradzki
9f6af19712 New translations 2017-01-31 22:23:42 +01:00
Łukasz Domeradzki
d882fe1a29 New translations 2017-01-31 22:23:39 +01:00
Łukasz Domeradzki
e4ce791e27 New translations 2017-01-31 22:23:38 +01:00
Łukasz Domeradzki
52128fd549 New translations 2017-01-31 22:23:35 +01:00
Łukasz Domeradzki
e5700e5518 New translations 2017-01-31 22:23:32 +01:00
Łukasz Domeradzki
a22079f38c New translations 2017-01-31 22:23:29 +01:00
Łukasz Domeradzki
4b0f5d2dad New translations 2017-01-31 22:23:26 +01:00
Łukasz Domeradzki
e9d8de9031 New translations 2017-01-31 22:23:24 +01:00
Łukasz Domeradzki
a5763ba1a8 New translations 2017-01-31 22:23:21 +01:00
Łukasz Domeradzki
77e5f98f37 New translations 2017-01-31 22:23:19 +01:00
Łukasz Domeradzki
23353fe1c1 New translations 2017-01-31 22:23:17 +01:00
Łukasz Domeradzki
1ee5d00486 New translations 2017-01-31 22:23:14 +01:00
Łukasz Domeradzki
3650af0a94 New translations 2017-01-31 22:23:12 +01:00
Łukasz Domeradzki
445e3ad9d4 Translated 2017-01-31 22:23:08 +01:00
JustArchi
69b829e883 Bump 2017-01-31 22:15:56 +01:00
Łukasz Domeradzki
71d9bcb5a0 New translations 2017-01-31 22:13:06 +01:00
Łukasz Domeradzki
ea38ead992 New translations 2017-01-31 22:13:04 +01:00
Łukasz Domeradzki
9101b0dc13 New translations 2017-01-31 22:13:02 +01:00
Łukasz Domeradzki
897dd9012f New translations 2017-01-31 22:12:59 +01:00
Łukasz Domeradzki
d3f3151ceb New translations 2017-01-31 22:12:56 +01:00
Łukasz Domeradzki
80129464ac Translated 2017-01-31 22:12:54 +01:00
Łukasz Domeradzki
5bf62ec4df Translated 2017-01-31 22:12:51 +01:00
Łukasz Domeradzki
9ea3e18c28 Translated 2017-01-31 22:12:49 +01:00
Łukasz Domeradzki
bfa3bdcaf0 Translated 2017-01-31 22:12:46 +01:00
Łukasz Domeradzki
3a2f0078f7 Translated 2017-01-31 22:12:44 +01:00
Łukasz Domeradzki
35ff24b28e Translated 2017-01-31 22:12:42 +01:00
Łukasz Domeradzki
0e22b0a577 Translated 2017-01-31 22:12:39 +01:00
Łukasz Domeradzki
b0efae7171 Translated 2017-01-31 22:12:37 +01:00
Łukasz Domeradzki
64d07b4764 Translated 2017-01-31 22:12:35 +01:00
Łukasz Domeradzki
53eeb87225 Translated 2017-01-31 22:12:32 +01:00
Łukasz Domeradzki
a3b323741b New translations 2017-01-31 22:12:31 +01:00
Łukasz Domeradzki
7e71fd706a New translations 2017-01-31 22:12:29 +01:00
Łukasz Domeradzki
8cd1210ee4 Translated 2017-01-31 22:12:27 +01:00
Łukasz Domeradzki
7ea771f3fa Approved. Step name: Proofread 2017-01-31 22:12:25 +01:00
Łukasz Domeradzki
f5c19c4cd3 New translations 2017-01-31 22:12:23 +01:00
Łukasz Domeradzki
32c12b14e4 Translated 2017-01-31 22:12:20 +01:00
Łukasz Domeradzki
1a15bd7677 Translated 2017-01-31 22:12:18 +01:00
Łukasz Domeradzki
40747ae55d Approved. Step name: Proofread 2017-01-31 22:12:17 +01:00
Łukasz Domeradzki
0c2d08af47 Translated 2017-01-31 22:12:14 +01:00
Łukasz Domeradzki
aa0269f987 New translations 2017-01-31 22:12:12 +01:00
Łukasz Domeradzki
8f0dd4960a Approved. Step name: Proofread 2017-01-31 22:12:09 +01:00
Łukasz Domeradzki
46ce27e0fb Translated 2017-01-31 22:12:07 +01:00
Łukasz Domeradzki
0cbca1e36f Translated 2017-01-31 22:12:05 +01:00
JustArchi
a5c1b0c253 Unify ASF newline responses 2017-01-31 22:03:20 +01:00
Łukasz Domeradzki
4deeb0fb10 New translations 2017-01-31 21:43:12 +01:00
Łukasz Domeradzki
a33b7b2278 New translations 2017-01-31 21:43:10 +01:00
Łukasz Domeradzki
019e52dc99 New translations 2017-01-31 21:43:08 +01:00
Łukasz Domeradzki
e7360188d0 New translations 2017-01-31 21:43:07 +01:00
Łukasz Domeradzki
95b19e8f93 New translations 2017-01-31 21:43:05 +01:00
Łukasz Domeradzki
0617bd7713 New translations 2017-01-31 21:43:03 +01:00
Łukasz Domeradzki
94363d79a9 New translations 2017-01-31 21:43:01 +01:00
Łukasz Domeradzki
a3de120d24 New translations 2017-01-31 21:42:59 +01:00
Łukasz Domeradzki
b75cdf927b New translations 2017-01-31 21:42:57 +01:00
Łukasz Domeradzki
14476863bd Translated 2017-01-31 21:42:55 +01:00
Łukasz Domeradzki
5d5fe7b32a New translations 2017-01-31 21:42:54 +01:00
Łukasz Domeradzki
4ea3a2859f Translated 2017-01-31 21:42:52 +01:00
Łukasz Domeradzki
8ca9366416 Translated 2017-01-31 21:42:50 +01:00
Łukasz Domeradzki
5c78923d21 New translations 2017-01-31 21:42:47 +01:00
Łukasz Domeradzki
478c890105 Translated 2017-01-31 21:42:45 +01:00
Łukasz Domeradzki
f87bd605fa Translated 2017-01-31 21:42:43 +01:00
Łukasz Domeradzki
e5fd1b85c8 Translated 2017-01-31 21:42:41 +01:00
Łukasz Domeradzki
b604206fd6 Translated 2017-01-31 21:42:38 +01:00
Łukasz Domeradzki
9a9c85baca Translated 2017-01-31 21:42:36 +01:00
JustArchi
265d869b58 Looks like fixed, add auto-cleanup for IgnoredAppIDs 2017-01-31 21:37:34 +01:00
Łukasz Domeradzki
beb1b63611 New translations 2017-01-31 21:33:33 +01:00
Łukasz Domeradzki
51e4b2341f New translations 2017-01-31 21:33:30 +01:00
Łukasz Domeradzki
8a71c550dd New translations 2017-01-31 21:33:27 +01:00
Łukasz Domeradzki
d6e5140c9b New translations 2017-01-31 21:33:24 +01:00
Łukasz Domeradzki
be05a63d1e New translations 2017-01-31 21:33:21 +01:00
Łukasz Domeradzki
1101ebc9d1 New translations 2017-01-31 21:33:19 +01:00
Łukasz Domeradzki
a601977b0a New translations 2017-01-31 21:33:17 +01:00
Łukasz Domeradzki
23e1834d2e New translations 2017-01-31 21:33:15 +01:00
Łukasz Domeradzki
6c336dc4d7 Translated 2017-01-31 21:33:12 +01:00
Łukasz Domeradzki
32071078ff Translated 2017-01-31 21:33:10 +01:00
Łukasz Domeradzki
3254c99f59 Translated 2017-01-31 21:33:08 +01:00
Łukasz Domeradzki
af3ee45e7d Translated 2017-01-31 21:33:06 +01:00
Łukasz Domeradzki
6c3808ff80 Translated 2017-01-31 21:33:03 +01:00
Łukasz Domeradzki
6c49a9d756 New translations 2017-01-31 21:33:00 +01:00
Łukasz Domeradzki
2c1f3280dd New translations 2017-01-31 21:32:58 +01:00
Łukasz Domeradzki
945868d2f3 New translations 2017-01-31 21:32:56 +01:00
Łukasz Domeradzki
2f861d7645 New translations 2017-01-31 21:32:54 +01:00
Łukasz Domeradzki
49388c4c22 New translations 2017-01-31 21:32:52 +01:00
Łukasz Domeradzki
ee2aae9d4c Translated 2017-01-31 21:32:50 +01:00
Łukasz Domeradzki
a7420d14ea Approved. Step name: Proofread 2017-01-31 21:32:47 +01:00
Łukasz Domeradzki
df6a1785a1 New translations 2017-01-31 21:32:45 +01:00
Łukasz Domeradzki
bb7d7558ef New translations 2017-01-31 21:32:44 +01:00
Łukasz Domeradzki
b975b9d2bf Translated 2017-01-31 21:32:41 +01:00
Łukasz Domeradzki
8f3eb6382c Translated 2017-01-31 21:32:39 +01:00
Łukasz Domeradzki
6d37fa958c Translated 2017-01-31 21:32:37 +01:00
Łukasz Domeradzki
276cc6bfc5 Approved. Step name: Proofread 2017-01-31 21:32:35 +01:00
Łukasz Domeradzki
0ce2f00a16 Translated 2017-01-31 21:32:33 +01:00
Łukasz Domeradzki
99e07056ea Translated 2017-01-31 21:32:31 +01:00
Łukasz Domeradzki
17bfe74deb Translated 2017-01-31 21:32:28 +01:00
Łukasz Domeradzki
ef462b241c Approved. Step name: Proofread 2017-01-31 21:32:26 +01:00
Łukasz Domeradzki
0b4dc6ac7b Translated 2017-01-31 21:32:25 +01:00
Łukasz Domeradzki
daa0e02fbe Translated 2017-01-31 21:32:23 +01:00
Łukasz Domeradzki
deee1093b9 Approved. Step name: Proofread 2017-01-31 21:32:17 +01:00
Łukasz Domeradzki
cc407e5d2c Approved. Step name: Proofread 2017-01-31 21:32:14 +01:00
Łukasz Domeradzki
37f46043f9 Translated 2017-01-31 21:32:12 +01:00
Łukasz Domeradzki
4a856ac31e Translated 2017-01-31 21:32:10 +01:00
Łukasz Domeradzki
892ede79a1 Translated 2017-01-31 21:32:08 +01:00
Łukasz Domeradzki
d7c4bbc7a6 Translated 2017-01-31 21:32:06 +01:00
Łukasz Domeradzki
283b255886 New translations 2017-01-31 21:32:03 +01:00
Łukasz Domeradzki
a6ef3a9259 Translated 2017-01-31 21:32:00 +01:00
Łukasz Domeradzki
737f90ca43 Translated 2017-01-31 21:31:58 +01:00
Łukasz Domeradzki
7d21015df3 Translated 2017-01-31 21:31:56 +01:00
Łukasz Domeradzki
7e86cf269c Translated 2017-01-31 21:31:54 +01:00
Łukasz Domeradzki
10578d0844 Translated 2017-01-31 21:31:52 +01:00
Łukasz Domeradzki
28efaae76a New translations 2017-01-31 21:31:50 +01:00
Łukasz Domeradzki
3cb7116809 Translated 2017-01-31 21:31:48 +01:00
Łukasz Domeradzki
86bd5d8843 Translated 2017-01-31 21:31:46 +01:00
Łukasz Domeradzki
27d0c9de04 Translated 2017-01-31 21:31:44 +01:00
Łukasz Domeradzki
c610d5cb01 Translated 2017-01-31 21:31:42 +01:00
Łukasz Domeradzki
29d6846dae Translated 2017-01-31 21:31:39 +01:00
Łukasz Domeradzki
2597e1b9da Translated 2017-01-31 21:31:37 +01:00
Łukasz Domeradzki
d37908cb00 Translated 2017-01-31 21:31:35 +01:00
Łukasz Domeradzki
1ccbcd737a Translated 2017-01-31 21:31:33 +01:00
Łukasz Domeradzki
40c5c322c5 Translated 2017-01-31 21:31:31 +01:00
JustArchi
602eec3596 Let's hope this will be final fix 2017-01-31 21:24:18 +01:00
JustArchi
c426ddece7 Second fix attempt 2017-01-31 21:03:06 +01:00
JustArchi
4133254f7f Test 2017-01-31 20:57:56 +01:00
JustArchi
281577698b First fix attempt 2017-01-31 20:47:37 +01:00
JustArchi
10085f9dd4 Kill root cause of this annoying fuckup 2017-01-31 19:52:20 +01:00
JustArchi
3bf792eba5 Test 2017-01-31 19:09:48 +01:00
JustArchi
ac3bf2eb31 Test 2017-01-31 18:54:25 +01:00
Łukasz Domeradzki
e5c6ca120b Translated 2017-01-31 16:53:44 +01:00
Łukasz Domeradzki
3ddf03de7b Translated 2017-01-31 16:43:43 +01:00
Łukasz Domeradzki
9743786aeb New translations 2017-01-31 15:11:01 +01:00
Łukasz Domeradzki
d6293101ec Translated 2017-01-31 15:10:54 +01:00
Łukasz Domeradzki
b70bde0b94 New translations 2017-01-31 15:01:46 +01:00
Łukasz Domeradzki
b858acfb79 New translations 2017-01-31 13:27:55 +01:00
Łukasz Domeradzki
816efbd712 New translations 2017-01-31 13:17:22 +01:00
Łukasz Domeradzki
29fbde4533 New translations 2017-01-31 10:27:45 +01:00
JustArchi
71a9e25720 Bump 2017-01-31 10:21:14 +01:00
JustArchi
22f3ca4c4f Fix debugging directory 2017-01-31 10:06:27 +01:00
JustArchi
b6dd768c0b Bump 2017-01-31 09:32:02 +01:00
278 changed files with 117647 additions and 1030 deletions

15
.gitignore vendored
View File

@@ -2,15 +2,22 @@
## ArchiSteamFarm
#################
# Ignore all config files, apart from ones we want to include
ArchiSteamFarm/config/*
# Ignore all config files
ArchiSteamFarm/config
GUI/config
# Include default config files
!ArchiSteamFarm/config/ASF.json
!ArchiSteamFarm/config/example.json
!ArchiSteamFarm/config/minimal.json
# Ignore local debugging
# Ignore local log
ArchiSteamFarm/log.txt
ArchiSteamFarm/debug/*
GUI/log.txt
# Ignore local debugging
ArchiSteamFarm/debug
GUI/debug
# Ignore out
out/

View File

@@ -324,6 +324,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AES/@EntryIndexedValue">AES</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ASF/@EntryIndexedValue">ASF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EWCF/@EntryIndexedValue">EWCF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FA/@EntryIndexedValue">FA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FS/@EntryIndexedValue">FS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HTML/@EntryIndexedValue">HTML</s:String>
@@ -337,6 +338,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TTL/@EntryIndexedValue">TTL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=URL/@EntryIndexedValue">URL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WCF/@EntryIndexedValue">WCF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WS/@EntryIndexedValue">WS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WTF/@EntryIndexedValue">WTF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XML/@EntryIndexedValue">XML</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="I" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>

View File

@@ -330,7 +330,7 @@ namespace ArchiSteamFarm {
CreateBot(botName).Forget();
}
private static void OnDeleted(object sender, FileSystemEventArgs e) {
private static async void OnDeleted(object sender, FileSystemEventArgs e) {
if ((sender == null) || (e == null)) {
ArchiLogger.LogNullError(nameof(sender) + " || " + nameof(e));
return;
@@ -343,7 +343,7 @@ namespace ArchiSteamFarm {
if (botName.Equals(SharedInfo.ASF)) {
ArchiLogger.LogGenericError(Strings.ErrorGlobalConfigRemoved);
Program.Exit(1);
await Program.Exit(1).ConfigureAwait(false);
return;
}
@@ -353,7 +353,7 @@ namespace ArchiSteamFarm {
}
}
private static void OnRenamed(object sender, RenamedEventArgs e) {
private static async void OnRenamed(object sender, RenamedEventArgs e) {
if ((sender == null) || (e == null)) {
ArchiLogger.LogNullError(nameof(sender) + " || " + nameof(e));
return;
@@ -366,7 +366,7 @@ namespace ArchiSteamFarm {
if (oldBotName.Equals(SharedInfo.ASF)) {
ArchiLogger.LogGenericError(Strings.ErrorGlobalConfigRemoved);
Program.Exit(1);
await Program.Exit(1).ConfigureAwait(false);
return;
}
@@ -387,11 +387,11 @@ namespace ArchiSteamFarm {
if (Program.GlobalConfig.AutoRestart) {
ArchiLogger.LogGenericInfo(Strings.Restarting);
await Task.Delay(5000).ConfigureAwait(false);
Program.Restart();
await Program.Restart().ConfigureAwait(false);
} else {
ArchiLogger.LogGenericInfo(Strings.Exiting);
await Task.Delay(5000).ConfigureAwait(false);
Program.Exit();
await Program.Exit().ConfigureAwait(false);
}
}

View File

@@ -79,10 +79,34 @@
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nito.AsyncEx, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nito.AsyncEx.Concurrent, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nito.AsyncEx.Enlightenment, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.5.0.0-beta05-test\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
@@ -99,6 +123,7 @@
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net" />
<Reference Include="System.Security" />
<Reference Include="System.ServiceModel" />
<Reference Include="Microsoft.CSharp" />
@@ -138,6 +163,7 @@
<Compile Include="Logging.cs" />
<Compile Include="InMemoryServerListProvider.cs" />
<Compile Include="MobileAuthenticator.cs" />
<Compile Include="OS.cs" />
<Compile Include="Runtime.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -205,6 +231,7 @@
<EmbeddedResource Include="Localization\Strings.ko-KR.resx" />
<EmbeddedResource Include="Localization\Strings.lt-LT.resx" />
<EmbeddedResource Include="Localization\Strings.mk-MK.resx" />
<EmbeddedResource Include="Localization\Strings.nl-BE.resx" />
<EmbeddedResource Include="Localization\Strings.nl-NL.resx" />
<EmbeddedResource Include="Localization\Strings.no-NO.resx" />
<EmbeddedResource Include="Localization\Strings.pl-PL.resx" />
@@ -242,6 +269,7 @@
copy "$(TargetDir)$(TargetName).exe" "$(SolutionDir)out\ASF.exe"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
set -e
if [ -f "$(SolutionDir)mono_envsetup.sh" ]; then
. "$(SolutionDir)mono_envsetup.sh"
fi
@@ -250,7 +278,13 @@
cp "$(TargetDir)config/ASF.json" "$(SolutionDir)out/config"
cp "$(TargetDir)config/example.json" "$(SolutionDir)out/config"
cp "$(TargetDir)config/minimal.json" "$(SolutionDir)out/config"
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-Service.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
if [ -n "$MONO_FACADES" ]; then
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" "/lib:$MONO_FACADES" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-Service.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
else
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-Service.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
fi
rm "$(SolutionDir)out/ASF-Service.exe.config"
cp "$(SolutionDir)out/ASF-Service.exe" "$(SolutionDir)out/ASF.exe"
</PostBuildEvent>
@@ -262,10 +296,12 @@
<Error Condition="!Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets'))" />
<Error Condition="!Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<Import Project="..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" />
<Import Project="..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" />
<Import Project="..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -58,14 +58,16 @@ namespace ArchiSteamFarm {
private static int Timeout = GlobalConfig.DefaultConnectionTimeout * 1000; // This must be int type
private readonly Bot Bot;
private readonly SemaphoreSlim PublicInventorySemaphore = new SemaphoreSlim(1);
private readonly SemaphoreSlim SessionSemaphore = new SemaphoreSlim(1);
private readonly SemaphoreSlim SteamApiKeySemaphore = new SemaphoreSlim(1);
private readonly WebBrowser WebBrowser;
internal bool Ready { get; private set; }
private bool? CachedPublicInventory;
private string CachedSteamApiKey;
private DateTime LastSessionRefreshCheck = DateTime.MinValue;
private string SteamApiKey;
private ulong SteamID;
internal ArchiWebHandler(Bot bot) {
@@ -79,6 +81,7 @@ namespace ArchiSteamFarm {
}
public void Dispose() {
PublicInventorySemaphore.Dispose();
SessionSemaphore.Dispose();
SteamApiKeySemaphore.Dispose();
}
@@ -172,7 +175,7 @@ namespace ArchiSteamFarm {
}
string steamApiKey = await GetApiKey().ConfigureAwait(false);
if (string.IsNullOrEmpty(SteamApiKey)) {
if (string.IsNullOrEmpty(steamApiKey)) {
return;
}
@@ -223,7 +226,7 @@ namespace ArchiSteamFarm {
internal async Task<HashSet<Steam.TradeOffer>> GetActiveTradeOffers() {
string steamApiKey = await GetApiKey().ConfigureAwait(false);
if (string.IsNullOrEmpty(SteamApiKey)) {
if (string.IsNullOrEmpty(steamApiKey)) {
return null;
}
@@ -611,7 +614,7 @@ namespace ArchiSteamFarm {
}
string steamApiKey = await GetApiKey().ConfigureAwait(false);
if (string.IsNullOrEmpty(SteamApiKey)) {
if (string.IsNullOrEmpty(steamApiKey)) {
return null;
}
@@ -784,6 +787,31 @@ namespace ArchiSteamFarm {
return response?.Success;
}
internal async Task<bool> HasPublicInventory() {
if (CachedPublicInventory.HasValue) {
return CachedPublicInventory.Value;
}
// We didn't fetch state yet
await PublicInventorySemaphore.WaitAsync().ConfigureAwait(false);
try {
if (CachedPublicInventory.HasValue) {
return CachedPublicInventory.Value;
}
bool? isInventoryPublic = await IsInventoryPublic().ConfigureAwait(false);
if (!isInventoryPublic.HasValue) {
return false;
}
CachedPublicInventory = isInventoryPublic.Value;
return isInventoryPublic.Value;
} finally {
PublicInventorySemaphore.Release();
}
}
internal async Task<bool> HasValidApiKey() => !string.IsNullOrEmpty(await GetApiKey().ConfigureAwait(false));
internal static void Init() => Timeout = Program.GlobalConfig.ConnectionTimeout * 1000;
@@ -984,18 +1012,18 @@ namespace ArchiSteamFarm {
}
private async Task<string> GetApiKey(bool allowRegister = true) {
if (SteamApiKey != null) {
if (CachedSteamApiKey != null) {
// We fetched API key already, and either got valid one, or permanent AccessDenied
// In any case, this is our final result
return SteamApiKey;
return CachedSteamApiKey;
}
// We didn't fetch API key yet
await SteamApiKeySemaphore.WaitAsync().ConfigureAwait(false);
try {
if (SteamApiKey != null) {
return SteamApiKey;
if (CachedSteamApiKey != null) {
return CachedSteamApiKey;
}
Tuple<ESteamApiKeyState, string> result = await GetApiKeyState().ConfigureAwait(false);
@@ -1008,8 +1036,8 @@ namespace ArchiSteamFarm {
case ESteamApiKeyState.Registered:
// We succeeded in fetching API key, and it resulted in registered key
// Cache the result and return it
SteamApiKey = result.Item2;
return SteamApiKey;
CachedSteamApiKey = result.Item2;
return CachedSteamApiKey;
case ESteamApiKeyState.NotRegisteredYet:
// We succeeded in fetching API key, and it resulted in no key registered yet
if (!allowRegister) {
@@ -1034,7 +1062,7 @@ namespace ArchiSteamFarm {
case ESteamApiKeyState.AccessDenied:
// We succeeded in fetching API key, but it resulted in access denied
// Cache the result as empty, and return null
SteamApiKey = "";
CachedSteamApiKey = "";
return null;
default:
// We got some kind of error, maybe it's temporary, maybe it's permanent
@@ -1183,6 +1211,25 @@ namespace ArchiSteamFarm {
}
}
private async Task<bool?> IsInventoryPublic() {
if (!Ready || !await RefreshSessionIfNeeded().ConfigureAwait(false)) {
return null;
}
const string request = SteamCommunityURL + "/my/edit/settings?l=english";
HtmlDocument htmlDocument = await WebBrowser.UrlGetToHtmlDocumentRetry(request).ConfigureAwait(false);
HtmlNode htmlNode = htmlDocument?.DocumentNode.SelectSingleNode("//input[@id='inventoryPrivacySetting_public']");
if (htmlNode == null) {
return null;
}
// Notice: checked doesn't have a value - null is lack of attribute, "" is attribute existing
string state = htmlNode.GetAttributeValue("checked", null);
return state != null;
}
private async Task<bool?> IsLoggedIn() {
// It would make sense to use /my/profile here, but it dismisses notifications related to profile comments
// So instead, we'll use some less intrusive link, such as /my/videos

View File

@@ -163,7 +163,7 @@ namespace ArchiSteamFarm {
SteamClient = new SteamClient(Program.GlobalConfig.SteamProtocol);
if (Program.GlobalConfig.Debug && Directory.Exists(SharedInfo.DebugDirectory)) {
string debugListenerPath = Path.Combine(SharedInfo.DebugDirectory);
string debugListenerPath = Path.Combine(SharedInfo.DebugDirectory, botName);
try {
Directory.CreateDirectory(debugListenerPath);
@@ -235,11 +235,8 @@ namespace ArchiSteamFarm {
ArchiWebHandler.Dispose();
CardsFarmer.Dispose();
HeartBeatTimer.Dispose();
HandledGifts.Dispose();
CallbackSemaphore.Dispose();
InitializationSemaphore.Dispose();
SteamFamilySharingIDs.Dispose();
OwnedPackageIDs.Dispose();
//SteamSaleEvent.Dispose();
Trading.Dispose();
@@ -322,48 +319,6 @@ namespace ArchiSteamFarm {
}
}
internal async Task<HashSet<uint>> GetUnreleasedAppIDs(HashSet<uint> appIDs) {
if ((appIDs == null) || (appIDs.Count == 0)) {
ArchiLogger.LogNullError(nameof(appIDs));
return null;
}
AsyncJobMultiple<SteamApps.PICSProductInfoCallback>.ResultSet productInfo;
try {
productInfo = await SteamApps.PICSGetProductInfo(appIDs, Enumerable.Empty<uint>());
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
return null;
}
HashSet<uint> result = new HashSet<uint>();
foreach (KeyValuePair<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo> app in productInfo.Results.SelectMany(productResult => productResult.Apps)) {
if (!appIDs.Contains(app.Key)) {
continue;
}
string releaseState = app.Value.KeyValues["common"]["ReleaseState"].Value;
if (string.IsNullOrEmpty(releaseState)) {
continue;
}
switch (releaseState) {
case "released":
break;
case "prerelease":
case "preloadonly":
result.Add(app.Key);
break;
default:
ArchiLogger.LogGenericWarning(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(releaseState), releaseState));
break;
}
}
return result;
}
internal static async Task InitializeCMs(uint cellID, IServerListProvider serverListProvider) {
if (serverListProvider == null) {
ASF.ArchiLogger.LogNullError(nameof(serverListProvider));
@@ -385,6 +340,37 @@ namespace ArchiSteamFarm {
}
}
internal async Task<bool?> IsReleased(uint appID) {
if (appID == 0) {
ArchiLogger.LogNullError(nameof(appID));
return null;
}
AsyncJobMultiple<SteamApps.PICSProductInfoCallback>.ResultSet productInfo;
try {
productInfo = await SteamApps.PICSGetProductInfo(appID, null);
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
return null;
}
foreach (string releaseState in productInfo.Results.SelectMany(productResult => productResult.Apps).Where(app => appID == app.Key).Select(app => app.Value.KeyValues["common"]["ReleaseState"].Value).Where(releaseState => !string.IsNullOrEmpty(releaseState))) {
switch (releaseState) {
case "released":
return true;
case "prerelease":
case "preloadonly":
return false;
default:
ArchiLogger.LogGenericWarning(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(releaseState), releaseState));
return null;
}
}
return null;
}
internal async Task LootIfNeeded() {
if (!BotConfig.SendOnFarmingFinished || (BotConfig.SteamMasterID == 0) || !IsConnectedAndLoggedOn || (BotConfig.SteamMasterID == SteamClient.SteamID)) {
return;
@@ -557,12 +543,10 @@ namespace ArchiSteamFarm {
return ResponseResume(steamID);
case "!RESTART":
return ResponseRestart(steamID);
case "!STARTALL":
return ResponseStartAll(steamID);
case "!SA":
return await ResponseStatus(steamID, SharedInfo.ASF).ConfigureAwait(false);
case "!STATUS":
return ResponseStatus(steamID);
case "!STATUSALL":
return ResponseStatusAll(steamID);
case "!STOP":
return ResponseStop(steamID);
case "!UPDATE":
@@ -594,6 +578,8 @@ namespace ArchiSteamFarm {
return await ResponseLoot(steamID, args[1]).ConfigureAwait(false);
case "!LOOT^":
return await ResponseLootSwitch(steamID, args[1]).ConfigureAwait(false);
case "!OA":
return await ResponseOwns(steamID, SharedInfo.ASF, args[1]).ConfigureAwait(false);
case "!OWNS":
if (args.Length > 2) {
return await ResponseOwns(steamID, args[1], args[2]).ConfigureAwait(false);
@@ -748,14 +734,40 @@ namespace ArchiSteamFarm {
HashSet<Bot> result = new HashSet<Bot>();
foreach (string botName in botNames.Where(botName => !string.IsNullOrEmpty(botName))) {
if (botName.Equals(SharedInfo.ASF)) {
foreach (Bot bot in Bots.Values) {
if (botName.Equals(SharedInfo.ASF, StringComparison.OrdinalIgnoreCase)) {
foreach (Bot bot in Bots.OrderBy(bot => bot.Key).Select(bot => bot.Value)) {
result.Add(bot);
}
return result;
}
if (botName.Contains("..")) {
string[] botRange = botName.Split(new[] { ".." }, StringSplitOptions.RemoveEmptyEntries);
if (botRange.Length == 2) {
Bot firstBot, lastBot;
if (Bots.TryGetValue(botRange[0], out firstBot) && Bots.TryGetValue(botRange[1], out lastBot)) {
bool inRange = false;
foreach (Bot bot in Bots.OrderBy(bot => bot.Key).Select(bot => bot.Value)) {
if (bot == firstBot) {
inRange = true;
} else if (!inRange) {
continue;
}
result.Add(bot);
if (bot == lastBot) {
break;
}
}
continue;
}
}
}
Bot targetBot;
if (!Bots.TryGetValue(botName, out targetBot)) {
continue;
@@ -825,7 +837,7 @@ namespace ArchiSteamFarm {
return;
}
if (++HeartBeatFailures >= (byte) Math.Ceiling(Program.GlobalConfig.ConnectionTimeout / 4.0)) {
if (++HeartBeatFailures >= (byte) Math.Ceiling(Program.GlobalConfig.ConnectionTimeout / 10.0)) {
HeartBeatFailures = byte.MaxValue;
ArchiLogger.LogGenericWarning(Strings.BotConnectionLost);
Connect(true).Forget();
@@ -1629,11 +1641,11 @@ namespace ArchiSteamFarm {
}
if (!HasMobileAuthenticator) {
return Strings.BotNoASFAuthenticator;
return Environment.NewLine + Strings.BotNoASFAuthenticator;
}
string token = await BotDatabase.MobileAuthenticator.GenerateToken().ConfigureAwait(false);
return !string.IsNullOrEmpty(token) ? string.Format(Strings.BotAuthenticatorToken, token) : Strings.WarningFailed;
return Environment.NewLine + (!string.IsNullOrEmpty(token) ? string.Format(Strings.BotAuthenticatorToken, token) : Strings.WarningFailed);
}
private static async Task<string> Response2FA(ulong steamID, string botNames) {
@@ -1644,7 +1656,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -1664,11 +1676,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private async Task<string> Response2FAConfirm(ulong steamID, bool confirm) {
@@ -1682,18 +1690,18 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
if (!HasMobileAuthenticator) {
return Strings.BotNoASFAuthenticator;
return Environment.NewLine + Strings.BotNoASFAuthenticator;
}
if (await AcceptConfirmations(confirm).ConfigureAwait(false)) {
return Strings.Success;
return Environment.NewLine + Strings.Success;
}
return Strings.WarningFailed;
return Environment.NewLine + Strings.WarningFailed;
}
private static async Task<string> Response2FAConfirm(ulong steamID, string botNames, bool confirm) {
@@ -1704,7 +1712,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -1724,11 +1732,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private async Task<string> ResponseAddLicense(ulong steamID, ICollection<uint> gameIDs) {
@@ -1742,29 +1746,38 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
StringBuilder result = new StringBuilder();
StringBuilder response = new StringBuilder();
foreach (uint gameID in gameIDs) {
SteamApps.FreeLicenseCallback callback = await SteamApps.RequestFreeLicense(gameID);
SteamApps.FreeLicenseCallback callback;
try {
callback = await SteamApps.RequestFreeLicense(gameID);
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
response.Append(Environment.NewLine + string.Format(Strings.BotAddLicenseResponse, BotName, gameID, EResult.Timeout));
break;
}
if (callback == null) {
result.AppendLine(Environment.NewLine + string.Format(Strings.BotAddLicenseResponse, BotName, gameID, EResult.Timeout));
response.Append(Environment.NewLine + string.Format(Strings.BotAddLicenseResponse, BotName, gameID, EResult.Timeout));
break;
}
if (callback.GrantedApps.Count > 0) {
result.AppendLine(Environment.NewLine + string.Format(Strings.BotAddLicenseResponseWithItems, BotName, gameID, callback.Result, string.Join(", ", callback.GrantedApps)));
response.Append(Environment.NewLine + string.Format(Strings.BotAddLicenseResponseWithItems, BotName, gameID, callback.Result, string.Join(", ", callback.GrantedApps)));
} else if (callback.GrantedPackages.Count > 0) {
result.AppendLine(Environment.NewLine + string.Format(Strings.BotAddLicenseResponseWithItems, BotName, gameID, callback.Result, string.Join(", ", callback.GrantedPackages)));
response.Append(Environment.NewLine + string.Format(Strings.BotAddLicenseResponseWithItems, BotName, gameID, callback.Result, string.Join(", ", callback.GrantedPackages)));
} else if (await ArchiWebHandler.AddFreeLicense(gameID).ConfigureAwait(false)) {
result.AppendLine(Environment.NewLine + string.Format(Strings.BotAddLicenseResponseWithItems, BotName, gameID, EResult.OK, gameID));
response.Append(Environment.NewLine + string.Format(Strings.BotAddLicenseResponseWithItems, BotName, gameID, EResult.OK, gameID));
} else {
result.AppendLine(Environment.NewLine + string.Format(Strings.BotAddLicenseResponse, BotName, gameID, EResult.AccessDenied));
response.Append(Environment.NewLine + string.Format(Strings.BotAddLicenseResponse, BotName, gameID, EResult.AccessDenied));
}
}
return result.ToString();
return response.Length > 0 ? response.ToString() : null;
}
private async Task<string> ResponseAddLicense(ulong steamID, string games) {
@@ -1778,7 +1791,7 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
string[] gameIDs = games.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
@@ -1787,14 +1800,14 @@ namespace ArchiSteamFarm {
foreach (string game in gameIDs.Where(game => !string.IsNullOrEmpty(game))) {
uint gameID;
if (!uint.TryParse(game, out gameID)) {
return string.Format(Strings.ErrorParsingObject, nameof(gameID));
return Environment.NewLine + string.Format(Strings.ErrorParsingObject, nameof(gameID));
}
gamesToRedeem.Add(gameID);
}
if (gamesToRedeem.Count == 0) {
return string.Format(Strings.ErrorIsEmpty, nameof(gamesToRedeem));
return Environment.NewLine + string.Format(Strings.ErrorIsEmpty, nameof(gamesToRedeem));
}
return await ResponseAddLicense(steamID, gamesToRedeem).ConfigureAwait(false);
@@ -1808,7 +1821,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -1828,16 +1841,12 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private static string ResponseAPI(ulong steamID) {
if (steamID != 0) {
return IsOwner(steamID) ? GetAPIStatus() : null;
return IsOwner(steamID) ? Environment.NewLine + GetAPIStatus() : null;
}
ASF.ArchiLogger.LogNullError(nameof(steamID));
@@ -1857,10 +1866,10 @@ namespace ArchiSteamFarm {
// Schedule the task after some time so user can receive response
Task.Run(async () => {
await Task.Delay(1000).ConfigureAwait(false);
Program.Exit();
await Program.Exit().ConfigureAwait(false);
}).Forget();
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private async Task<string> ResponseFarm(ulong steamID) {
@@ -1874,12 +1883,12 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
await CardsFarmer.StopFarming().ConfigureAwait(false);
CardsFarmer.StartFarming().Forget();
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private static async Task<string> ResponseFarm(ulong steamID, string botNames) {
@@ -1890,7 +1899,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -1910,11 +1919,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private string ResponseHelp(ulong steamID) {
@@ -1927,7 +1932,7 @@ namespace ArchiSteamFarm {
return null;
}
return "https://github.com/" + SharedInfo.GithubRepo + "/wiki/Commands";
return Environment.NewLine + "https://github.com/" + SharedInfo.GithubRepo + "/wiki/Commands";
}
private async Task<string> ResponseLoot(ulong steamID) {
@@ -1941,39 +1946,39 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
if (!LootingAllowed) {
return Strings.BotLootingTemporarilyDisabled;
return Environment.NewLine + Strings.BotLootingTemporarilyDisabled;
}
if (BotConfig.SteamMasterID == 0) {
return Strings.BotLootingMasterNotDefined;
return Environment.NewLine + Strings.BotLootingMasterNotDefined;
}
if (BotConfig.SteamMasterID == SteamClient.SteamID) {
return Strings.BotLootingYourself;
return Environment.NewLine + Strings.BotLootingYourself;
}
if (BotConfig.LootableTypes.Count == 0) {
return Strings.BotLootingNoLootableTypes;
return Environment.NewLine + Strings.BotLootingNoLootableTypes;
}
await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false);
HashSet<Steam.Item> inventory = await ArchiWebHandler.GetMySteamInventory(true, BotConfig.LootableTypes).ConfigureAwait(false);
if ((inventory == null) || (inventory.Count == 0)) {
return string.Format(Strings.ErrorIsEmpty, nameof(inventory));
return Environment.NewLine + string.Format(Strings.ErrorIsEmpty, nameof(inventory));
}
if (!await ArchiWebHandler.SendTradeOffer(inventory, BotConfig.SteamMasterID, BotConfig.SteamTradeToken).ConfigureAwait(false)) {
return Strings.BotLootingFailed;
return Environment.NewLine + Strings.BotLootingFailed;
}
await Task.Delay(3000).ConfigureAwait(false); // Sometimes we can be too fast for Steam servers to generate confirmations, wait a short moment
await AcceptConfirmations(true, Steam.ConfirmationDetails.EType.Trade, BotConfig.SteamMasterID).ConfigureAwait(false);
return Strings.BotLootingSuccess;
return Environment.NewLine + Strings.BotLootingSuccess;
}
private static async Task<string> ResponseLoot(ulong steamID, string botNames) {
@@ -1984,7 +1989,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2004,11 +2009,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private string ResponseLootSwitch(ulong steamID) {
@@ -2022,7 +2023,7 @@ namespace ArchiSteamFarm {
}
LootingAllowed = !LootingAllowed;
return LootingAllowed ? Strings.BotLootingNowEnabled : Strings.BotLootingNowDisabled;
return Environment.NewLine + (LootingAllowed ? Strings.BotLootingNowEnabled : Strings.BotLootingNowDisabled);
}
private static async Task<string> ResponseLootSwitch(ulong steamID, string botNames) {
@@ -2033,7 +2034,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2053,11 +2054,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private async Task<string> ResponseOwns(ulong steamID, string query) {
@@ -2071,7 +2068,7 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
Dictionary<uint, string> ownedGames;
@@ -2108,11 +2105,7 @@ namespace ArchiSteamFarm {
}
}
if (response.Length > 0) {
return response.ToString();
}
return Environment.NewLine + string.Format(Strings.BotNotOwnedYet, BotName, query);
return response.Length > 0 ? response.ToString() : Environment.NewLine + string.Format(Strings.BotNotOwnedYet, BotName, query);
}
private static async Task<string> ResponseOwns(ulong steamID, string botNames, string query) {
@@ -2123,7 +2116,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2143,11 +2136,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private string ResponsePassword(ulong steamID) {
@@ -2161,7 +2150,7 @@ namespace ArchiSteamFarm {
}
if (string.IsNullOrEmpty(BotConfig.SteamPassword)) {
return string.Format(Strings.ErrorIsEmpty, nameof(BotConfig.SteamPassword));
return Environment.NewLine + string.Format(Strings.ErrorIsEmpty, nameof(BotConfig.SteamPassword));
}
return Environment.NewLine + string.Format(Strings.BotEncryptedPassword, CryptoHelper.ECryptoMethod.AES, CryptoHelper.Encrypt(CryptoHelper.ECryptoMethod.AES, BotConfig.SteamPassword)) + Environment.NewLine + string.Format(Strings.BotEncryptedPassword, CryptoHelper.ECryptoMethod.ProtectedDataForCurrentUser, CryptoHelper.Encrypt(CryptoHelper.ECryptoMethod.ProtectedDataForCurrentUser, BotConfig.SteamPassword));
@@ -2175,7 +2164,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2195,11 +2184,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private async Task<string> ResponsePause(ulong steamID, bool sticky) {
@@ -2213,21 +2198,21 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
if (CardsFarmer.Paused) {
return Strings.BotAutomaticIdlingPausedAlready;
return Environment.NewLine + Strings.BotAutomaticIdlingPausedAlready;
}
await CardsFarmer.Pause(sticky).ConfigureAwait(false);
if (!SteamFamilySharingIDs.Contains(steamID)) {
return Strings.BotAutomaticIdlingNowPaused;
return Environment.NewLine + Strings.BotAutomaticIdlingNowPaused;
}
StartFamilySharingInactivityTimer();
return string.Format(Strings.BotAutomaticIdlingPausedWithCountdown, FamilySharingInactivityMinutes);
return Environment.NewLine + string.Format(Strings.BotAutomaticIdlingPausedWithCountdown, FamilySharingInactivityMinutes);
}
private static async Task<string> ResponsePause(ulong steamID, string botNames, bool sticky) {
@@ -2238,7 +2223,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2258,11 +2243,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private async Task<string> ResponsePlay(ulong steamID, HashSet<uint> gameIDs) {
@@ -2276,7 +2257,7 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
if (!CardsFarmer.Paused) {
@@ -2284,7 +2265,7 @@ namespace ArchiSteamFarm {
}
ArchiHandler.PlayGames(gameIDs);
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private async Task<string> ResponsePlay(ulong steamID, string games) {
@@ -2298,7 +2279,7 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
string[] gameIDs = games.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
@@ -2307,7 +2288,7 @@ namespace ArchiSteamFarm {
foreach (string game in gameIDs.Where(game => !string.IsNullOrEmpty(game))) {
uint gameID;
if (!uint.TryParse(game, out gameID)) {
return string.Format(Strings.ErrorParsingObject, nameof(gameID));
return Environment.NewLine + string.Format(Strings.ErrorParsingObject, nameof(gameID));
}
gamesToPlay.Add(gameID);
@@ -2318,7 +2299,7 @@ namespace ArchiSteamFarm {
}
if (gamesToPlay.Count == 0) {
return string.Format(Strings.ErrorIsEmpty, gamesToPlay);
return Environment.NewLine + string.Format(Strings.ErrorIsEmpty, gamesToPlay);
}
return await ResponsePlay(steamID, gamesToPlay).ConfigureAwait(false);
@@ -2332,7 +2313,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2352,11 +2333,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
@@ -2371,7 +2348,7 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
bool forward = !redeemFlags.HasFlag(ERedeemFlags.SkipForwarding) && (redeemFlags.HasFlag(ERedeemFlags.ForceForwarding) || BotConfig.RedeemingPreferences.HasFlag(BotConfig.ERedeemingPreferences.Forwarding));
@@ -2521,7 +2498,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2541,11 +2518,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private static string ResponseRejoinChat(ulong steamID) {
@@ -2562,7 +2535,7 @@ namespace ArchiSteamFarm {
bot.JoinMasterChat();
}
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private static string ResponseRestart(ulong steamID) {
@@ -2578,10 +2551,10 @@ namespace ArchiSteamFarm {
// Schedule the task after some time so user can receive response
Task.Run(async () => {
await Task.Delay(1000).ConfigureAwait(false);
Program.Restart();
await Program.Restart().ConfigureAwait(false);
}).Forget();
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private string ResponseResume(ulong steamID) {
@@ -2595,16 +2568,16 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return Strings.BotNotConnected;
return Environment.NewLine + Strings.BotNotConnected;
}
if (!CardsFarmer.Paused) {
return Strings.BotAutomaticIdlingResumedAlready;
return Environment.NewLine + Strings.BotAutomaticIdlingResumedAlready;
}
StopFamilySharingInactivityTimer();
CardsFarmer.Resume(true);
return Strings.BotAutomaticIdlingNowResumed;
return Environment.NewLine + Strings.BotAutomaticIdlingNowResumed;
}
private static async Task<string> ResponseResume(ulong steamID, string botNames) {
@@ -2615,7 +2588,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2635,11 +2608,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private string ResponseStart(ulong steamID) {
@@ -2653,12 +2622,12 @@ namespace ArchiSteamFarm {
}
if (KeepRunning) {
return Strings.BotAlreadyRunning;
return Environment.NewLine + Strings.BotAlreadyRunning;
}
SkipFirstShutdown = true;
Start().Forget();
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private static async Task<string> ResponseStart(ulong steamID, string botNames) {
@@ -2669,7 +2638,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2689,28 +2658,7 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
}
private static string ResponseStartAll(ulong steamID) {
if (steamID == 0) {
ASF.ArchiLogger.LogNullError(nameof(steamID));
return null;
}
if (!IsOwner(steamID)) {
return null;
}
foreach (Bot bot in Bots.Values.Where(bot => !bot.KeepRunning)) {
bot.ResponseStart(steamID);
}
return Strings.Done;
return responses.Count > 0 ? string.Join("", responses) : null;
}
private string ResponseStatus(ulong steamID) {
@@ -2724,31 +2672,31 @@ namespace ArchiSteamFarm {
}
if (!IsConnectedAndLoggedOn) {
return string.Format(KeepRunning ? Strings.BotStatusNotConnected : Strings.BotStatusNotRunning, BotName);
return Environment.NewLine + string.Format(KeepRunning ? Strings.BotStatusNotConnected : Strings.BotStatusNotRunning, BotName);
}
if (PlayingBlocked) {
return string.Format(Strings.BotStatusPlayingNotAvailable, BotName);
return Environment.NewLine + string.Format(Strings.BotStatusPlayingNotAvailable, BotName);
}
if (CardsFarmer.Paused) {
return string.Format(Strings.BotStatusPaused, BotName);
return Environment.NewLine + string.Format(Strings.BotStatusPaused, BotName);
}
if (IsLimitedUser) {
return string.Format(Strings.BotStatusLimited, BotName);
return Environment.NewLine + string.Format(Strings.BotStatusLimited, BotName);
}
if (CardsFarmer.CurrentGamesFarming.Count == 0) {
return string.Format(Strings.BotsStatusNotIdling, BotName);
return Environment.NewLine + string.Format(Strings.BotsStatusNotIdling, BotName);
}
if (CardsFarmer.CurrentGamesFarming.Count > 1) {
return string.Format(Strings.BotStatusIdlingList, BotName, string.Join(", ", CardsFarmer.CurrentGamesFarming.Select(game => game.AppID)), CardsFarmer.GamesToFarm.Count, CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining), CardsFarmer.TimeRemaining.ToHumanReadable());
return Environment.NewLine + string.Format(Strings.BotStatusIdlingList, BotName, string.Join(", ", CardsFarmer.CurrentGamesFarming.Select(game => game.AppID)), CardsFarmer.GamesToFarm.Count, CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining), CardsFarmer.TimeRemaining.ToHumanReadable());
}
CardsFarmer.Game soloGame = CardsFarmer.CurrentGamesFarming.First();
return string.Format(Strings.BotStatusIdling, BotName, soloGame.AppID, soloGame.GameName, soloGame.CardsRemaining, CardsFarmer.GamesToFarm.Count, CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining), CardsFarmer.TimeRemaining.ToHumanReadable());
return Environment.NewLine + string.Format(Strings.BotStatusIdling, BotName, soloGame.AppID, soloGame.GameName, soloGame.CardsRemaining, CardsFarmer.GamesToFarm.Count, CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining), CardsFarmer.TimeRemaining.ToHumanReadable());
}
private static async Task<string> ResponseStatus(ulong steamID, string botNames) {
@@ -2759,7 +2707,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2783,23 +2731,14 @@ namespace ArchiSteamFarm {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
}
private static string ResponseStatusAll(ulong steamID) {
if (steamID == 0) {
ASF.ArchiLogger.LogNullError(nameof(steamID));
return null;
if (bots.Count < Bots.Count) {
return string.Join("", responses);
}
if (!IsOwner(steamID)) {
return null;
}
HashSet<Bot> botsRunning = new HashSet<Bot>(Bots.Values.Where(bot => bot.KeepRunning));
string extraResponse = string.Format(Strings.BotsStatusOverview, botsRunning.Count, Bots.Count, botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Count), botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining)));
HashSet<Bot> botsRunning = new HashSet<Bot>(Bots.Where(bot => bot.Value.KeepRunning).OrderBy(bot => bot.Key).Select(bot => bot.Value));
IEnumerable<string> statuses = botsRunning.Select(bot => bot.ResponseStatus(steamID));
return Environment.NewLine + string.Join(Environment.NewLine, statuses) + Environment.NewLine + string.Format(Strings.BotsStatusOverview, botsRunning.Count, Bots.Count, botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Count), botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining)));
return string.Join("", responses) + Environment.NewLine + extraResponse;
}
private string ResponseStop(ulong steamID) {
@@ -2813,11 +2752,11 @@ namespace ArchiSteamFarm {
}
if (!KeepRunning) {
return Strings.BotAlreadyStopped;
return Environment.NewLine + Strings.BotAlreadyStopped;
}
Stop();
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private static async Task<string> ResponseStop(ulong steamID, string botNames) {
@@ -2828,7 +2767,7 @@ namespace ArchiSteamFarm {
HashSet<Bot> bots = GetBots(botNames);
if ((bots == null) || (bots.Count == 0)) {
return null;
return IsOwner(steamID) ? Environment.NewLine + string.Format(Strings.BotNotFound, botNames.Replace(",", " || ")) : null;
}
ICollection<string> results;
@@ -2848,16 +2787,12 @@ namespace ArchiSteamFarm {
}
List<string> responses = new List<string>(results.Where(result => !string.IsNullOrEmpty(result)));
if (responses.Count == 0) {
return null;
}
return Environment.NewLine + string.Join(Environment.NewLine, responses);
return responses.Count > 0 ? string.Join("", responses) : null;
}
private string ResponseUnknown(ulong steamID) {
if (steamID != 0) {
return IsMaster(steamID) ? Strings.UnknownCommand : null;
return IsMaster(steamID) ? Environment.NewLine + Strings.UnknownCommand : null;
}
ArchiLogger.LogNullError(nameof(steamID));
@@ -2875,7 +2810,7 @@ namespace ArchiSteamFarm {
}
await ASF.CheckForUpdate(true).ConfigureAwait(false);
return Strings.Done;
return Environment.NewLine + Strings.Done;
}
private string ResponseVersion(ulong steamID) {
@@ -2888,7 +2823,7 @@ namespace ArchiSteamFarm {
return null;
}
return "ASF V" + SharedInfo.Version;
return Environment.NewLine + "ASF V" + SharedInfo.Version;
}
private void SendMessageToChannel(ulong steamID, string message) {

View File

@@ -53,7 +53,7 @@ namespace ArchiSteamFarm {
internal readonly string CustomGamePlayedWhileIdle = null;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly bool DismissInventoryNotifications = true;
internal readonly bool DismissInventoryNotifications = false;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly bool Enabled = false;
@@ -108,7 +108,7 @@ namespace ArchiSteamFarm {
internal readonly string SteamTradeToken = null;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly ETradingPreferences TradingPreferences = ETradingPreferences.AcceptDonations;
internal readonly ETradingPreferences TradingPreferences = ETradingPreferences.None;
[JsonProperty]
internal string SteamLogin { get; set; }
@@ -193,7 +193,8 @@ namespace ArchiSteamFarm {
None = 0,
AcceptDonations = 1,
SteamTradeMatcher = 2,
MatchEverything = 4
MatchEverything = 4,
DontAcceptBotTrades = 8
}
}
}

View File

@@ -23,6 +23,7 @@
*/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -36,7 +37,9 @@ using Newtonsoft.Json;
namespace ArchiSteamFarm {
internal sealed class CardsFarmer : IDisposable {
private const byte HoursToBump = 2; // How many hours are required for restricted accounts
private const byte HoursToIgnore = 24; // How many hours we ignore unreleased appIDs and don't bother checking them again
private static readonly ConcurrentDictionary<uint, DateTime> IgnoredAppIDs = new ConcurrentDictionary<uint, DateTime>(); // Reserved for unreleased games
private static readonly HashSet<uint> UntrustedAppIDs = new HashSet<uint> { 440, 570, 730 };
[JsonProperty]
@@ -83,8 +86,6 @@ namespace ArchiSteamFarm {
public void Dispose() {
// Those are objects that are always being created if constructor doesn't throw exception
CurrentGamesFarming.Dispose();
GamesToFarm.Dispose();
FarmingSemaphore.Dispose();
FarmResetEvent.Dispose();
@@ -178,20 +179,6 @@ namespace ArchiSteamFarm {
return;
}
// Remove from our list all games that were not released yet
HashSet<uint> appIDs = new HashSet<uint>(GamesToFarm.Select(game => game.AppID));
HashSet<uint> unreleasedAppIDs = await Bot.GetUnreleasedAppIDs(appIDs).ConfigureAwait(false);
if ((unreleasedAppIDs != null) && (unreleasedAppIDs.Count > 0)) {
if (GamesToFarm.RemoveWhere(game => unreleasedAppIDs.Contains(game.AppID)) > 0) {
if (GamesToFarm.Count == 0) {
Bot.ArchiLogger.LogGenericInfo(Strings.NothingToIdle);
await Bot.OnFarmingFinished(false).ConfigureAwait(false);
return;
}
}
}
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.GamesToIdle, GamesToFarm.Count, GamesToFarm.Sum(game => game.CardsRemaining), TimeRemaining.ToHumanReadable()));
// This is the last moment for final check if we can farm
@@ -354,6 +341,17 @@ namespace ArchiSteamFarm {
continue;
}
DateTime lastPICSReport;
if (IgnoredAppIDs.TryGetValue(appID, out lastPICSReport)) {
if (lastPICSReport.AddHours(HoursToIgnore) < DateTime.UtcNow) {
// This game served its time as being ignored
IgnoredAppIDs.TryRemove(appID, out lastPICSReport);
} else {
// This game is still ignored
continue;
}
}
// Cards
HtmlNode progressNode = htmlNode.SelectSingleNode(".//span[@class='progress_info_bold']");
if (progressNode == null) {
@@ -370,9 +368,9 @@ namespace ArchiSteamFarm {
ushort cardsRemaining = 0;
Match progressMatch = Regex.Match(progressText, @"\d+");
// This might fail if we have no card drops remaining, that's fine
// This might fail if we have no card drops remaining, 0 is not printed in this case - that's fine
if (progressMatch.Success) {
if (!ushort.TryParse(progressMatch.Value, out cardsRemaining)) {
if (!ushort.TryParse(progressMatch.Value, out cardsRemaining) || (cardsRemaining == 0)) {
Bot.ArchiLogger.LogNullError(nameof(cardsRemaining));
continue;
}
@@ -435,12 +433,12 @@ namespace ArchiSteamFarm {
continue;
}
float hours = 0;
float hours = 0.0F;
Match hoursMatch = Regex.Match(hoursString, @"[0-9\.,]+");
// This might fail if we have exactly 0.0 hours played, that's fine
// This might fail if we have exactly 0.0 hours played, as it's not printed in that case - that's fine
if (hoursMatch.Success) {
if (!float.TryParse(hoursMatch.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours)) {
if (!float.TryParse(hoursMatch.Value, NumberStyles.Number, CultureInfo.InvariantCulture, out hours) || (hours <= 0.0F)) {
Bot.ArchiLogger.LogNullError(nameof(hours));
continue;
}
@@ -526,29 +524,35 @@ namespace ArchiSteamFarm {
return false;
}
Bot.ArchiHandler.PlayGame(game.AppID, Bot.BotConfig.CustomGamePlayedWhileFarming);
DateTime endFarmingDate = DateTime.UtcNow.AddHours(Program.GlobalConfig.MaxFarmingTime);
bool success = true;
bool? keepFarming = await ShouldFarm(game).ConfigureAwait(false);
bool? isReleased = await Bot.IsReleased(game.AppID).ConfigureAwait(false);
while (keepFarming.GetValueOrDefault(true) && (DateTime.UtcNow < endFarmingDate)) {
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.StillIdling, game.AppID, game.GameName));
if (isReleased.GetValueOrDefault(true)) {
Bot.ArchiHandler.PlayGame(game.AppID, Bot.BotConfig.CustomGamePlayedWhileFarming);
DateTime endFarmingDate = DateTime.UtcNow.AddHours(Program.GlobalConfig.MaxFarmingTime);
DateTime startFarmingPeriod = DateTime.UtcNow;
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
FarmResetEvent.Reset();
success = KeepFarming;
bool? keepFarming = await ShouldFarm(game).ConfigureAwait(false);
while (keepFarming.GetValueOrDefault(true) && (DateTime.UtcNow < endFarmingDate)) {
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.StillIdling, game.AppID, game.GameName));
DateTime startFarmingPeriod = DateTime.UtcNow;
if (FarmResetEvent.Wait(60 * 1000 * Program.GlobalConfig.FarmingDelay)) {
FarmResetEvent.Reset();
success = KeepFarming;
}
// Don't forget to update our GamesToFarm hours
game.HoursPlayed += (float) DateTime.UtcNow.Subtract(startFarmingPeriod).TotalHours;
if (!success) {
break;
}
keepFarming = await ShouldFarm(game).ConfigureAwait(false);
}
// Don't forget to update our GamesToFarm hours
game.HoursPlayed += (float) DateTime.UtcNow.Subtract(startFarmingPeriod).TotalHours;
if (!success) {
break;
}
keepFarming = await ShouldFarm(game).ConfigureAwait(false);
} else {
IgnoredAppIDs[game.AppID] = DateTime.UtcNow;
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.IdlingGameNotReleasedYet, game.AppID, game.GameName));
}
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.StoppedIdling, game.AppID, game.GameName));

View File

@@ -25,30 +25,27 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Nito.AsyncEx;
namespace ArchiSteamFarm {
internal sealed class ConcurrentEnumerator<T> : IEnumerator<T> {
public T Current => Enumerator.Current;
private readonly IEnumerator<T> Enumerator;
private readonly ReaderWriterLockSlim Lock;
private readonly IDisposable Lock;
object IEnumerator.Current => Current;
internal ConcurrentEnumerator(ICollection<T> collection, ReaderWriterLockSlim rwLock) {
internal ConcurrentEnumerator(ICollection<T> collection, AsyncReaderWriterLock rwLock) {
if ((collection == null) || (rwLock == null)) {
throw new ArgumentNullException(nameof(collection) + " || " + nameof(rwLock));
}
rwLock.EnterReadLock();
Lock = rwLock;
Lock = rwLock.ReaderLock();
Enumerator = collection.GetEnumerator();
}
public void Dispose() => Lock?.ExitReadLock();
public void Dispose() => Lock.Dispose();
public bool MoveNext() => Enumerator.MoveNext();
public void Reset() => Enumerator.Reset();
}

View File

@@ -22,21 +22,16 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Nito.AsyncEx;
namespace ArchiSteamFarm {
internal sealed class ConcurrentHashSet<T> : ICollection<T>, IDisposable {
internal sealed class ConcurrentHashSet<T> : ICollection<T> {
public int Count {
get {
Lock.EnterReadLock();
try {
using (Lock.ReaderLock()) {
return HashSet.Count;
} finally {
Lock.ExitReadLock();
}
}
}
@@ -44,48 +39,31 @@ namespace ArchiSteamFarm {
public bool IsReadOnly => false;
private readonly HashSet<T> HashSet = new HashSet<T>();
private readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
private readonly AsyncReaderWriterLock Lock = new AsyncReaderWriterLock();
public void Clear() {
Lock.EnterWriteLock();
try {
using (Lock.WriterLock()) {
HashSet.Clear();
} finally {
Lock.ExitWriteLock();
}
}
public bool Contains(T item) {
Lock.EnterReadLock();
try {
using (Lock.ReaderLock()) {
return HashSet.Contains(item);
} finally {
Lock.ExitReadLock();
}
}
public void CopyTo(T[] array, int arrayIndex) {
Lock.EnterReadLock();
try {
using (Lock.ReaderLock()) {
HashSet.CopyTo(array, arrayIndex);
} finally {
Lock.ExitReadLock();
}
}
public void Dispose() => Lock.Dispose();
public IEnumerator<T> GetEnumerator() => new ConcurrentEnumerator<T>(HashSet, Lock);
public bool Remove(T item) {
Lock.EnterWriteLock();
try {
using (Lock.WriterLock()) {
return HashSet.Remove(item);
} finally {
Lock.ExitWriteLock();
}
}
@@ -94,55 +72,43 @@ namespace ArchiSteamFarm {
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
internal void Add(T item) {
Lock.EnterWriteLock();
try {
using (Lock.WriterLock()) {
HashSet.Add(item);
} finally {
Lock.ExitWriteLock();
}
}
internal void ClearAndTrim() {
Lock.EnterWriteLock();
try {
using (Lock.WriterLock()) {
HashSet.Clear();
HashSet.TrimExcess();
} finally {
Lock.ExitWriteLock();
}
}
internal int RemoveWhere(Predicate<T> match) {
Lock.EnterWriteLock();
try {
return HashSet.RemoveWhere(match);
} finally {
Lock.ExitWriteLock();
}
}
internal bool ReplaceIfNeededWith(ICollection<T> items) {
Lock.EnterUpgradeableReadLock();
try {
using (AsyncReaderWriterLock.UpgradeableReaderKey readerKey = Lock.UpgradeableReaderLock()) {
if (HashSet.SetEquals(items)) {
return false;
}
ReplaceWith(items);
ReplaceWith(items, readerKey);
return true;
} finally {
Lock.ExitUpgradeableReadLock();
}
}
internal void ReplaceWith(IEnumerable<T> items) {
Lock.EnterWriteLock();
try {
using (Lock.WriterLock()) {
HashSet.Clear();
foreach (T item in items) {
HashSet.Add(item);
}
HashSet.TrimExcess();
}
}
private void ReplaceWith(IEnumerable<T> items, AsyncReaderWriterLock.UpgradeableReaderKey readerKey) {
using (readerKey.Upgrade()) {
HashSet.Clear();
foreach (T item in items) {
@@ -150,8 +116,6 @@ namespace ArchiSteamFarm {
}
HashSet.TrimExcess();
} finally {
Lock.ExitWriteLock();
}
}
}

View File

@@ -36,7 +36,7 @@ namespace ArchiSteamFarm {
ASF.ArchiLogger.LogGenericInfo(Strings.NoBotsAreRunning);
await Task.Delay(5000).ConfigureAwait(false);
Program.Exit();
await Program.Exit().ConfigureAwait(false);
}
internal static void OnPersonaState(Bot bot, SteamFriends.PersonaStateCallback callback) { }

View File

@@ -38,10 +38,6 @@ namespace ArchiSteamFarm {
internal const byte DefaultConnectionTimeout = 60;
internal const ushort DefaultWCFPort = 1242;
private const byte DefaultFarmingDelay = 15;
private const byte DefaultMaxFarmingTime = 10;
private const ProtocolType DefaultSteamProtocol = ProtocolType.Tcp;
// This is hardcoded blacklist which should not be possible to change
internal static readonly HashSet<uint> GlobalBlacklist = new HashSet<uint> { 267420, 303700, 335590, 368020, 425280, 480730, 566020 };
@@ -64,7 +60,7 @@ namespace ArchiSteamFarm {
internal readonly bool Debug = false;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly byte FarmingDelay = DefaultFarmingDelay;
internal readonly byte FarmingDelay = 15;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly byte GiftsLimiterDelay = 1;
@@ -82,7 +78,7 @@ namespace ArchiSteamFarm {
internal readonly byte LoginLimiterDelay = 10;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly byte MaxFarmingTime = DefaultMaxFarmingTime;
internal readonly byte MaxFarmingTime = 10;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly byte MaxTradeHoldDuration = 15;
@@ -97,11 +93,14 @@ namespace ArchiSteamFarm {
internal readonly ulong SteamOwnerID = 0;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly ProtocolType SteamProtocol = DefaultSteamProtocol;
internal readonly ProtocolType SteamProtocol = ProtocolType.Tcp;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly EUpdateChannel UpdateChannel = EUpdateChannel.Stable;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly EWCFBinding WCFBinding = EWCFBinding.NetTcp;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly ushort WCFPort = DefaultWCFPort;
@@ -182,5 +181,11 @@ namespace ArchiSteamFarm {
Stable,
Experimental
}
internal enum EWCFBinding : byte {
NetTcp,
BasicHttp,
WSHttp
}
}
}

View File

@@ -77,10 +77,7 @@ namespace ArchiSteamFarm {
ServerListProvider.ServerListUpdated += OnServerListUpdated;
}
public void Dispose() {
ServerListProvider.ServerListUpdated -= OnServerListUpdated;
ServerListProvider.Dispose();
}
public void Dispose() => ServerListProvider.ServerListUpdated -= OnServerListUpdated;
internal static GlobalDatabase Load(string filePath) {
if (string.IsNullOrEmpty(filePath)) {

View File

@@ -30,11 +30,10 @@ using Newtonsoft.Json;
using SteamKit2.Discovery;
namespace ArchiSteamFarm {
internal sealed class InMemoryServerListProvider : IDisposable, IServerListProvider {
internal sealed class InMemoryServerListProvider : IServerListProvider {
[JsonProperty(Required = Required.DisallowNull)]
private readonly ConcurrentHashSet<IPEndPoint> Servers = new ConcurrentHashSet<IPEndPoint>();
public void Dispose() => Servers.Dispose();
public Task<IEnumerable<IPEndPoint>> FetchServerListAsync() => Task.FromResult<IEnumerable<IPEndPoint>>(Servers);
public Task UpdateServerListAsync(IEnumerable<IPEndPoint> endPoints) {

View File

@@ -28,23 +28,36 @@ using Newtonsoft.Json;
namespace ArchiSteamFarm.JSON {
internal static class GitHub {
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
internal sealed class ReleaseResponse {
#pragma warning disable 649
internal sealed class Asset {
[JsonProperty(PropertyName = "browser_download_url", Required = Required.Always)]
internal readonly string DownloadURL;
[JsonProperty(PropertyName = "name", Required = Required.Always)]
internal readonly string Name;
}
[JsonProperty(PropertyName = "tag_name", Required = Required.Always)]
internal readonly string Tag;
[JsonProperty(PropertyName = "assets", Required = Required.Always)]
internal readonly List<Asset> Assets;
#pragma warning restore 649
#pragma warning disable 649
[JsonProperty(PropertyName = "tag_name", Required = Required.Always)]
internal readonly string Tag;
#pragma warning restore 649
// Deserialized from JSON
private ReleaseResponse() { }
internal sealed class Asset {
#pragma warning disable 649
[JsonProperty(PropertyName = "browser_download_url", Required = Required.Always)]
internal readonly string DownloadURL;
#pragma warning restore 649
#pragma warning disable 649
[JsonProperty(PropertyName = "name", Required = Required.Always)]
internal readonly string Name;
#pragma warning restore 649
// Deserialized from JSON
private Asset() { }
}
}
}
}

View File

@@ -26,7 +26,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
using HtmlAgilityPack;
using Newtonsoft.Json;
using SteamKit2;
@@ -40,6 +39,7 @@ namespace ArchiSteamFarm.JSON {
[JsonProperty(PropertyName = "success", Required = Required.Always)]
internal readonly bool Success;
#pragma warning restore 649
internal ulong OtherSteamID64 {
get {
if (_OtherSteamID64 != 0) {
@@ -103,6 +103,7 @@ namespace ArchiSteamFarm.JSON {
[JsonProperty(PropertyName = "html", Required = Required.DisallowNull)]
private readonly string HTML;
#pragma warning restore 649
private HtmlDocument HtmlDocument {
get {
if (_HtmlDocument != null) {
@@ -113,8 +114,7 @@ namespace ArchiSteamFarm.JSON {
return null;
}
_HtmlDocument = new HtmlDocument();
_HtmlDocument.LoadHtml(WebUtility.HtmlDecode(HTML));
_HtmlDocument = WebBrowser.StringToHtmlDocument(HTML);
return _HtmlDocument;
}
}
@@ -196,7 +196,9 @@ namespace ArchiSteamFarm.JSON {
private ulong _OtherSteamID64;
private ulong _TradeOfferID;
private EType _Type;
private ConfirmationDetails() { } // Deserialized from JSON
// Deserialized from JSON
private ConfirmationDetails() { }
internal enum EType : byte {
Unknown,
@@ -208,16 +210,18 @@ namespace ArchiSteamFarm.JSON {
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
internal sealed class ConfirmationResponse { // Deserialized from JSON
internal sealed class ConfirmationResponse {
#pragma warning disable 649
[JsonProperty(PropertyName = "success", Required = Required.Always)]
internal readonly bool Success;
#pragma warning restore 649
// Deserialized from JSON
private ConfirmationResponse() { }
}
internal sealed class Item { // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset | Deserialized from JSON (SteamCommunity) and constructed from code
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_Asset
internal sealed class Item {
internal const ushort SteamAppID = 753;
internal const byte SteamCommunityContextID = 6;
@@ -340,8 +344,8 @@ namespace ArchiSteamFarm.JSON {
set { AssetIDString = value; }
}
// This constructor is used for constructing items in trades being received
internal Item(uint appID, ulong contextID, ulong classID, uint amount, uint realAppID, EType type) {
// Constructed from trades being received
internal Item(uint appID, ulong contextID, ulong classID, uint amount, uint realAppID, EType type = EType.Unknown) {
if ((appID == 0) || (contextID == 0) || (classID == 0) || (amount == 0) || (realAppID == 0)) {
throw new ArgumentNullException(nameof(classID) + " || " + nameof(contextID) + " || " + nameof(classID) + " || " + nameof(amount) + " || " + nameof(realAppID));
}
@@ -354,6 +358,7 @@ namespace ArchiSteamFarm.JSON {
Type = type;
}
// Deserialized from JSON
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private Item() { }
@@ -371,27 +376,30 @@ namespace ArchiSteamFarm.JSON {
/*
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
internal sealed class NewDiscoveryQueueResponse { // Deserialized from JSON
internal sealed class NewDiscoveryQueueResponse {
#pragma warning disable 649
[JsonProperty(PropertyName = "queue", Required = Required.Always)]
internal readonly HashSet<uint> Queue;
#pragma warning restore 649
// Deserialized from JSON
private NewDiscoveryQueueResponse() { }
}
*/
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
internal sealed class RedeemWalletResponse { // Deserialized from JSON
internal sealed class RedeemWalletResponse {
#pragma warning disable 649
[JsonProperty(PropertyName = "detail", Required = Required.Always)]
internal readonly ArchiHandler.PurchaseResponseCallback.EPurchaseResult PurchaseResult;
#pragma warning restore 649
// Deserialized from JSON
private RedeemWalletResponse() { }
}
// REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer
internal sealed class TradeOffer {
internal readonly HashSet<Item> ItemsToGive = new HashSet<Item>();
internal readonly HashSet<Item> ItemsToReceive = new HashSet<Item>();
@@ -418,6 +426,7 @@ namespace ArchiSteamFarm.JSON {
private ulong _OtherSteamID64;
// Constructed from trades being received
internal TradeOffer(ulong tradeOfferID, uint otherSteamID3, ETradeOfferState state) {
if ((tradeOfferID == 0) || (otherSteamID3 == 0) || (state == ETradeOfferState.Unknown)) {
throw new ArgumentNullException(nameof(tradeOfferID) + " || " + nameof(otherSteamID3) + " || " + nameof(state));
@@ -486,7 +495,7 @@ namespace ArchiSteamFarm.JSON {
return true;
}
internal bool IsSteamCardsRequest() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && (item.Type == Item.EType.TradingCard)); // REF: https://developer.valvesoftware.com/wiki/Steam_Web_API/IEconService#CEcon_TradeOffer | Constructed from code
internal bool IsSteamCardsRequest() => ItemsToGive.All(item => (item.AppID == Item.SteamAppID) && (item.ContextID == Item.SteamCommunityContextID) && (item.Type == Item.EType.TradingCard));
[SuppressMessage("ReSharper", "UnusedMember.Global")]
internal enum ETradeOfferState : byte {
@@ -511,7 +520,7 @@ namespace ArchiSteamFarm.JSON {
internal readonly ItemList ItemsToGive = new ItemList();
[JsonProperty(PropertyName = "them", Required = Required.Always)]
internal readonly ItemList ItemsToReceive = new ItemList(); // Constructed from code
internal readonly ItemList ItemsToReceive = new ItemList();
internal sealed class ItemList {
[JsonProperty(PropertyName = "assets", Required = Required.Always)]

View File

@@ -954,6 +954,15 @@ namespace ArchiSteamFarm.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Idling {0} ({1}) is temporarily disabled, as that game was not released yet..
/// </summary>
internal static string IdlingGameNotReleasedYet {
get {
return ResourceManager.GetString("IdlingGameNotReleasedYet", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Idling status for {0} ({1}): {2} cards remaining.
/// </summary>

View File

@@ -278,6 +278,7 @@
</root>

View File

@@ -350,6 +350,7 @@
</root>

View File

@@ -118,7 +118,7 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AcceptingTrade" xml:space="preserve">
<value>Приемане на търговията: {0}</value>
<value>Приемане на замяната: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="AutoUpdateCheckInfo" xml:space="preserve">
@@ -133,57 +133,115 @@
<value>Конфигурираното свойство {0} е невалидно: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorEarlyFatalExceptionInfo" xml:space="preserve">
<value>ASF V{0} претърпя критичен срив, преди основния записващ модул, да стартира!</value>
<comment>{0} will be replaced by version number</comment>
</data>
<data name="ErrorEarlyFatalExceptionPrint" xml:space="preserve">
<value>Изключение: {0}() {1} StackTrace:{2}</value>
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
</data>
<data name="ErrorExitingWithNonZeroErrorCode" xml:space="preserve">
<value>Изключване при код за грешка различен от 0 (нула)!</value>
</data>
<data name="ErrorFailingRequest" xml:space="preserve">
<value>Провалена заявка: {0}</value>
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
<value>Общата настройка не може да бъде заредена, моля уверете се, че {0} съществува и е валидна! Прочетете наръчника за настройване в wiki страницата, ако сте объркани.</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
<value>{0} е невалидно!</value>
<value>{0} е невалиден!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorMobileAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>Отказва да изпълни тази функцията, поради невалиден DeviceID в ASF 2FA!</value>
</data>
<data name="ErrorNoBotsDefined" xml:space="preserve">
<value>Няма настроени ботове, да не би да сте забравили да настроите ASF?</value>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} е нулев!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorParsingObject" xml:space="preserve">
<value>Разборът {0} се провали!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRemovingOldBinary" xml:space="preserve">
<value>Не може да се премахне старият ASF файл, моля премахнете {0} ръчно, за може обновлението да сработи!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
<value>Операцията не може да се изпълни въпреки {0} опита!</value>
<comment>{0} will be replaced by maximum number of tries</comment>
</data>
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
<value>Не успя да се провери за последната версия!</value>
</data>
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
<value>Не може да се премине към обновление, защото няма файл, който е свързан с работещата в момента програма! Моля проверете, че вашата ASF програма е именувана правилно!</value>
</data>
<data name="ErrorUpdateNoAssets" xml:space="preserve">
<value>Не може да се премине към обновление, защото тази версия не включва никакви файлове!</value>
</data>
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
<value>Получено е желание за промяна от потребителя, но процеса продължава в режим без възможност за промяна!</value>
</data>
<data name="ErrorWCFAccessDenied" xml:space="preserve">
<value>Отказване на желанието, защото SteamOwnerID не е зададено!</value>
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
</data>
<data name="Exiting" xml:space="preserve">
<value>Излизане…</value>
</data>
<data name="WarningFailed" xml:space="preserve">
<value>Неуспешно!</value>
</data>
<data name="GlobalConfigChanged" xml:space="preserve">
<value>Файлът с общите настройки беше променен!</value>
</data>
<data name="IgnoringTrade" xml:space="preserve">
<value>Пренебрегване на замяната: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="LoggingIn" xml:space="preserve">
<value>Записване в {0}...</value>
<comment>{0} will be replaced by service's name</comment>
</data>
<data name="NoBotsAreRunning" xml:space="preserve">
<value>Не работят ботове, излизане...</value>
</data>
<data name="RefreshingOurSession" xml:space="preserve">
<value>Обновление на сесията!</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>Отказване на замяната: {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="Restarting" xml:space="preserve">
<value>Рестартиране…</value>
</data>
<data name="RuntimeVersionOK" xml:space="preserve">
<value>Вашата {0} версия е ОК.</value>
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
</data>
<data name="WarningRuntimeVersionTooOld" xml:space="preserve">
<value>Вашата {0} версия е твърде стара!</value>
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
</data>
<data name="Starting" xml:space="preserve">
<value>Стартиране...</value>
</data>
<data name="StatusCode" xml:space="preserve">
<value>Статус код: {0}</value>
<comment>{0} will be replaced by status code number/name</comment>
</data>
<data name="Success" xml:space="preserve">
<value>Успешно!</value>
</data>
@@ -215,39 +273,24 @@
<value>{0} секунди</value>
<comment>{0} will be replaced by number of seconds</comment>
</data>
<data name="Done" xml:space="preserve">
<value>Готово!</value>
<data name="UnlockingParentalAccount" xml:space="preserve">
<value>Отключване на родителския профил...</value>
</data>
<data name="UpdateCheckingNewVersion" xml:space="preserve">
<value>Проверяване за нова версия...</value>
</data>
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
<value>В момента се сваля новата версия... Докато чакате, помислете за дарение, ако оценявате свършената от нас работа! :)</value>
</data>
<data name="UpdateFinished" xml:space="preserve">
<value>Обновлението приключи!</value>
</data>
<data name="UpdateNewVersionAvailable" xml:space="preserve">
<value>Нова версия на ASF е налична! Помислете за обновление!</value>
</data>
<data name="UpdateVersionInfo" xml:space="preserve">
<value>Версия на компютъра Ви: {0} | Версия на сървъра: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
@@ -262,6 +305,13 @@
<data name="WCFReady" xml:space="preserve">
<value>WSF сървърът е готов!</value>
</data>
<data name="WCFResponseReceived" xml:space="preserve">
<value>WCF отговор получен: {0}</value>
<comment>{0} will be replaced by WCF response</comment>
</data>
@@ -269,6 +319,69 @@
<data name="CheckingFirstBadgePage" xml:space="preserve">
<value>Проверяване на първата страница със значки...</value>
</data>
<data name="CheckingOtherBadgePages" xml:space="preserve">
<value>Проверяване на други страници със значки...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>Избиране на алгоритъм за вадене на карти: {0}</value>
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
<value>Готово!</value>
</data>
<data name="IdlingFinished" xml:space="preserve">
<value>Изкарването на карти приключи!</value>
</data>
<data name="IdlingFinishedForGames" xml:space="preserve">
<value>Завърши ваденето на карти на: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="IdlingStopped" xml:space="preserve">
<value>Изкарването на карти е спряно!</value>
</data>
<data name="NowIdling" xml:space="preserve">
<value>Сега се вадят карти на: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="NowIdlingList" xml:space="preserve">
<value>Сега се вадят карти на: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StillIdling" xml:space="preserve">
<value>Все още се вадят карти на: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StillIdlingList" xml:space="preserve">
<value>Все още се вадят карти на: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StoppedIdling" xml:space="preserve">
<value>Прекратено е ваденето на карти на: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>Прекратено е ваденето на карти на: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Непозната команда!</value>
</data>
<data name="BotAcceptingGift" xml:space="preserve">
<value>Приемане на подарък: {0}...</value>
<comment>{0} will be replaced by giftID (number)</comment>
</data>
@@ -294,18 +407,22 @@
<data name="BotLoggedOn" xml:space="preserve">
<value>Влязли сте успешно!</value>
<value>Влезли сте успешно!</value>
</data>
<data name="BotLoggingIn" xml:space="preserve">
<value>Влизане…</value>
</data>
<data name="BotLootingFailed" xml:space="preserve">
<value>Предложението за замяна е неуспешно!</value>
</data>
<data name="BotLootingSuccess" xml:space="preserve">
<value>Предложението за замяна е изпратено успешно!</value>
</data>
@@ -329,18 +446,30 @@
</data>
<data name="BotStatusNotConnected" xml:space="preserve">
<value>Бот {0} не е свързан.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotRunning" xml:space="preserve">
<value>Бот {0} не работи.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotUnableToConnect" xml:space="preserve">
<value>Не може да се свърже със Steam: {0}</value>
<comment>{0} will be replaced by failure reason (string)</comment>
</data>
<data name="BotUnableToLogin" xml:space="preserve">
<value>Не може да се впише в Steam: {0}/{1}</value>
<comment>{0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string)</comment>
</data>
<data name="ErrorIsEmpty" xml:space="preserve">
<value>{0} е празен!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="UnusedKeys" xml:space="preserve">
<value>Неизползваните ключове: {0}</value>
<value>Неизползвани ключове: {0}</value>
<comment>{0} will be replaced by list of cd-keys (strings), separated by a comma</comment>
</data>
<data name="WarningFailedWithError" xml:space="preserve">
@@ -362,11 +491,12 @@
<data name="Initializing" xml:space="preserve">
<value>Инициализиране {0}…</value>
<value>Стартиране {0}…</value>
<comment>{0} will be replaced by service name that is being initialized</comment>
</data>
</root>

View File

@@ -278,6 +278,7 @@
</root>

View File

@@ -697,4 +697,8 @@ StackTrace:
<value>ASF se pokusí použít váš preferovaný jazyk {0}. Překlad tohoto jazyka je ale dokončen pouze z {1}. Možná chcete pomoci zlepšit překlad aplikace ASF pro váš jazyk?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Farmení hry {0} ({1}) je dočasně zrušeno, protože hra zatím nevyšla.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -278,6 +278,7 @@
</root>

View File

@@ -541,7 +541,7 @@ StackTrace:
<value>Erfolgreich angemeldet!</value>
</data>
<data name="BotLoggingIn" xml:space="preserve">
<value>Melde an...</value>
<value>Anmelden...</value>
</data>
<data name="BotLogonSessionReplaced" xml:space="preserve">
<value>Dieses Benutzerkonto scheint bereits von einer anderen ASF-Instanz verwendet zu werden, welches ein undefiniertes Verhalten ist, verweigere es weiter laufen zu lassen!</value>
@@ -697,4 +697,8 @@ StackTrace:
<value>ASF wird versuchen deine bevorzugte {0} Sprache zu verwenden, jedoch wurde die Übersetzung in dieser Sprache nur zu {1} abgeschlossen. Kannst du uns vielleicht helfen die ASF-Übersetzung in deiner Sprache zu verbessern?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Sammeln {0} ({1}) ist vorübergehend deaktiviert, da dieses Spiel bis jetzt noch nicht veröffentlicht wurde.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -144,7 +144,7 @@ StackTrace:
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
</data>
<data name="ErrorExitingWithNonZeroErrorCode" xml:space="preserve">
<value>Έξοδο με κωδικό σφάλματος μη μηδενική τιμή!</value>
<value>Έξοδο με κωδικό σφάλματος με μη μηδενική τιμή!</value>
</data>
<data name="ErrorFailingRequest" xml:space="preserve">
<value>Αποτυχία αίτησης: {0}</value>
@@ -173,11 +173,11 @@ StackTrace:
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRemovingOldBinary" xml:space="preserve">
<value>Αδυναμία να αφαιρεθεί το παλιό ASF binary, παρακαλώ αφαιρέστε το {0} χειροκίνητα ώστε να λειτουργήσει η διαδικασία ενημέρωσης!</value>
<value>Αδυναμία αφαίρεσης του παλιού ASF binary, παρακαλώ αφαιρέστε το {0} χειροκίνητα ώστε να λειτουργήσει η λειτουργία ενημέρωσης!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
<value>Η αίτηση απέτυχε παρά τις {0} προσπαθείες!</value>
<value>Το αίτημα απέτυχε παρά τις {0} προσπάθειες!</value>
<comment>{0} will be replaced by maximum number of tries</comment>
</data>
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
@@ -220,7 +220,7 @@ StackTrace:
<value>Δεν τρέχει κανένα bot, τερματισμός...</value>
</data>
<data name="RefreshingOurSession" xml:space="preserve">
<value>Επανεκκίνηση της συνεδρίας!</value>
<value>Ανανέωση της συνεδρίας!</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>Απόρριψη ανταλλαγής: {0}</value>
@@ -696,4 +696,8 @@ StackTrace:
<value>Το ASF θα επιχειρήσει να χρησιμοποιήσει τη γλώσσα {0}, αλλά η μετάφραση σ'αυτή τη γλώσσα έχει συμπληρωθεί μόνο κατά {1}. Ισως θα μπορούσατε να μας βοηθήσετε να βελτιώσουμε τη μετάφραση του ASF για τη γλώσσα σας;</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Η συλλογή καρτών για το {0} ({1}) έχει απενεργοποιηθεί προσωρινά, καθώς το παιχνίδι δεν έχει κυκλοφορήσει ακόμα.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -697,4 +697,8 @@ StackTrace:
<value>ASF will attempt to use your preferred {0} culture, but translation in that language was completed only in {1}. Perhaps you could help us improve ASF translation for your language?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Idling {0} ({1}) is temporarily disabled, as that game was not released yet.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -696,4 +696,8 @@ Trazo de pila:
<value>ASF intentará utilizar tu idioma {0}, pero la traducción en este idioma está completa sólo en un {1}. ¿Tal vez podrías ayudarnos a mejorar la traducción de ASF para tu idioma?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>No se pueden aumentar las horas jugadas de {0} ({1}) porque el juego aún no ha salido.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -122,7 +122,7 @@
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="AutoUpdateCheckInfo" xml:space="preserve">
<value>ASF tarkistaa automaattisesti uusia päivityksiä {0} tunnin välein.</value>
<value>ASF tarkistaa päivitykset automaattisesti {0} tunnin välein.</value>
<comment>{0} will be replaced by number of hours</comment>
</data>
<data name="Content" xml:space="preserve">
@@ -132,8 +132,13 @@
<data name="ErrorExitingWithNonZeroErrorCode" xml:space="preserve">
<value>Exiting with non-zero error code!</value>
</data>
<data name="ErrorFailingRequest" xml:space="preserve">
<value>Pyyntö evätty: {0}</value>
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
<value>{0} on virheellinen!</value>
@@ -145,32 +150,44 @@
<data name="Exiting" xml:space="preserve">
<value>Poistutaan...</value>
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
<value>Viimeisimmän version tarkistus epäonnistui!</value>
</data>
<data name="Exiting" xml:space="preserve">
<value>Suljetaan...</value>
</data>
<data name="LoggingIn" xml:space="preserve">
<value>Kirjaudutaan to {0}...</value>
<comment>{0} will be replaced by service's name</comment>
</data>
<data name="Restarting" xml:space="preserve">
<value>Käynnistetään uudelleen...</value>
</data>
<data name="RuntimeVersionComparison" xml:space="preserve">
<value>Vaadittu versio: {0} | Nykyinen versio: {1}</value>
<comment>{0} will be replaced by required version, {1} will be replaced by current version</comment>
</data>
<data name="Starting" xml:space="preserve">
<value>Käynnistetään...</value>
</data>
<data name="Success" xml:space="preserve">
<value>Valmis!</value>
</data>
<data name="TimeSpanDay" xml:space="preserve">
<value>1 päivä</value>
</data>
@@ -235,61 +252,129 @@
<data name="WCFReady" xml:space="preserve">
<value>WCF-palvelin on valmiina!</value>
</data>
<data name="BotNotFound" xml:space="preserve">
<value>Bottia nimeltä {0} ei voitu löytää!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="CheckingFirstBadgePage" xml:space="preserve">
<value>Tarkastellaan ensimmäistä badge sivua...</value>
</data>
<data name="CheckingOtherBadgePages" xml:space="preserve">
<value>Tarkastellaan muita badge sivuja...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>Asetettu idlaamisen algoritmi: {0}</value>
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
<value>Valmis!</value>
</data>
<data name="GamesToIdle" xml:space="preserve">
<value>Idlattavana yhteensä {0} peliä joissa ({1} korttia). Arvioitu aika (~{2})...</value>
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingFinished" xml:space="preserve">
<value>Idlaaminen valmis!</value>
</data>
<data name="IdlingFinishedForGame" xml:space="preserve">
<value>Idlaaminen valmis {0} ({1}) Kulunut aika: {2}!</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingStatusForGame" xml:space="preserve">
<value>Idlauksen tila kohteelle {0} ({1}): {2} korttia jäljellä</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle</comment>
</data>
<data name="IdlingStopped" xml:space="preserve">
<value>Idlaaminen pysäytetty!</value>
</data>
<data name="NothingToIdle" xml:space="preserve">
<value>Tällä accountilla ei ole mitään idlattavaa!</value>
</data>
<data name="NowIdling" xml:space="preserve">
<value>Nyt idlataan: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="NowIdlingList" xml:space="preserve">
<value>Nyt idlataan: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StillIdling" xml:space="preserve">
<value>Idlataan: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StillIdlingList" xml:space="preserve">
<value>Idlataan: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StoppedIdling" xml:space="preserve">
<value>Idlaaminen pysäytetty: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>Idlaaminen pysäytetty: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Tuntematon komento!</value>
</data>
<data name="BotAcceptingGift" xml:space="preserve">
<value>Hyväksytään lahjaa: {0}...</value>
<comment>{0} will be replaced by giftID (number)</comment>
</data>
<data name="BotAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>Sinun DeviceID on virheellinen tai sitä ei ole olemassa!</value>
</data>
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
<value>Automaattinen idlaaminen on pysäytetty!</value>
</data>
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
<value>Automaattinen idlaaminen on pysäytetty! Sinulla on {0} minuuttia aikaa käynnistää peli.</value>
<comment>{0} will be replaced by number of minutes</comment>
</data>
<data name="BotConnected" xml:space="preserve">
<value>Yhdistetty Steamiin!</value>
</data>
<data name="BotDisconnected" xml:space="preserve">
<value>Katkaistu yhteys Steamista!</value>
</data>
<data name="BotDisconnecting" xml:space="preserve">
<value>Katkaistaan yhteyttä...</value>
</data>
<data name="BotEncryptedPassword" xml:space="preserve">
<value>[{0}] salasana: {1}</value>
<comment>{0} will be replaced by password encryption method (string), {1} will be replaced by encrypted password using that method (string)</comment>
</data>
<data name="BotLoggedOn" xml:space="preserve">
<value>Onnistuneesti kirjauduttu sisään!</value>
</data>
<data name="BotLoggingIn" xml:space="preserve">
<value>Kirjaudutaan sisään...</value>
</data>
@@ -307,33 +392,59 @@
<data name="BotReconnecting" xml:space="preserve">
<value>Yhdistetään uudelleen...</value>
</data>
<data name="BotStatusNotConnected" xml:space="preserve">
<value>Botti {0} ei ole yhdistetty.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotRunning" xml:space="preserve">
<value>Botti {0} ei ole käynnissä.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="ErrorIsEmpty" xml:space="preserve">
<value>{0} on tyhjä!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="UnusedKeys" xml:space="preserve">
<value>Käyttämättömät CD-keyt: {0}</value>
<comment>{0} will be replaced by list of cd-keys (strings), separated by a comma</comment>
</data>
<data name="BotConnectionLost" xml:space="preserve">
<value>Yhteys Steamin palvelimeen katkesi, yhdistetään uudelleen...</value>
</data>
<data name="BotConnecting" xml:space="preserve">
<value>Yhdistetään...</value>
</data>
<data name="BotStopping" xml:space="preserve">
<value>Pysäytetään...</value>
</data>
<data name="Initializing" xml:space="preserve">
<value>Alustetaan {0}...</value>
<comment>{0} will be replaced by service name that is being initialized</comment>
</data>
<data name="Welcome" xml:space="preserve">
<value>Huomasin että käynnistit ohjelman ensimmäisen kerran, tervetuloa!</value>
</data>

View File

@@ -224,14 +224,14 @@ StackTrace :
<value>Rafraîchissement de notre session !</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>L'Offre : {0} est rejetée</value>
<value>Offre rejetée : {0}</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="Restarting" xml:space="preserve">
<value>Redémarrage...</value>
</data>
<data name="WarningRuntimeUnsupported" xml:space="preserve">
<value>ASF a détecté un environnement d'exécution en cours non pris en charge, le programme pourrait NE PAS fonctionner. Vous le lancer à vos propres risques et périls, et sans aide !</value>
<value>ASF a détecté un environnement d'exécution en cours non pris en charge, le programme pourrait NE PAS fonctionner. Vous le lancez à vos propres risques et périls, et sans aide !</value>
</data>
<data name="RuntimeVersionComparison" xml:space="preserve">
<value>Version requise : {0} | Version trouvée : {1}</value>
@@ -384,7 +384,7 @@ StackTrace :
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="BotStatusIdlingList" xml:space="preserve">
<value>Le bot {0} collecte les cartes des jeux : {1} sur un total de {2} jeux (cartes{3}) restant à farmer (~{4} restantes).</value>
<value>Le bot {0} collecte les cartes des jeux : {1} sur un total de {2} jeux ({3} cartes) restants à traiter (~{4} restant(e)s).</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="CheckingFirstBadgePage" xml:space="preserve">
@@ -470,7 +470,7 @@ StackTrace :
<comment>{0} will be replaced by giftID (number)</comment>
</data>
<data name="BotAccountLimited" xml:space="preserve">
<value>Ce compte est limité, le processus de farming est impossible tant que la restriction n'a pas été levée !</value>
<value>Ce compte est limité, le processus de collecte est impossible tant que la restriction n'a pas été levée !</value>
</data>
<data name="BotAddLicenseResponse" xml:space="preserve">
<value>&lt;{0}&gt; GameID : {1} | Statut : {2}</value>
@@ -697,4 +697,8 @@ StackTrace :
<value>ASF va tenter dutiliser votre langage préféré {0}, mais la traduction dans ce langage est achevée seulement à {1}. Peut-être vous pourriez nous aider à améliorer la traduction ASF pour votre langue ?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>La collecte des cartes pour {0} ({1}) est temporairement désactivée, car ce jeu nest pas encore sorti.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -323,7 +323,10 @@ StackTrace:
<value>&lt;{0}&gt; בבקשה הזן את את סיסמת הPIN (סיסמה בעלת 4 ספרות) של הגדרות ההרות של סטים: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamPassword" xml:space="preserve">
<value>lt&amp;;{0}&gt; הכנס בבקשה את סיסמת הסטים שלך:</value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputWCFHost" xml:space="preserve">
<value>&lt;{0} &gt;, נא להזין WCF host: </value>
@@ -450,7 +453,9 @@ StackTrace:
<value>מופע בוט זה פועל כבר!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotAuthenticatorConverting" xml:space="preserve">
<value>המרת .maFile לפורמט ASF</value>
</data>
<data name="BotAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>ה- DeviceID שלך שגוי או אינו קיים!</value>
@@ -618,4 +623,5 @@ StackTrace:
<value>CurrentCulture שסופק אינו חוקי, ConfigGenerator תמשיך לפעול עם ברירת המחדל!</value>
</data>
</root>

View File

@@ -331,6 +331,7 @@
</root>

View File

@@ -149,33 +149,62 @@ StackTrace: {2}</value>
<value>Kérés sikertelen: {0}</value>
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
<value>Nem lehet betölteni a globális konfigurációt! Kérlek, győződj meg róla, hogy {0} létezik és érvényes! Ha valami nem tiszta, olvasd el a wikin a telepítési segédletet.</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
<value>Érvénytelen {0}!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorMobileAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>Ez a funkció nem hajtható végre, mivel a DeviceID érvénytelen az ASF 2FA-ban!</value>
</data>
<data name="ErrorNoBotsDefined" xml:space="preserve">
<value>Nincsenek botok definiálva, elfelejtetted volna bekonfigurálni az ASF-t?</value>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} értéke nulla!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorParsingObject" xml:space="preserve">
<value>{0} feldolgozása sikertelen!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRemovingOldBinary" xml:space="preserve">
<value>Nem lehet törölni a régi ASF bináris fájlt, kérlek manuálisan töröld {0}-t, hogy sikerüljön a frissítés!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
<value>A kérést {0} próbálkozás után sem sikerült teljesíteni!</value>
<comment>{0} will be replaced by maximum number of tries</comment>
</data>
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
<value>Nem lehet lekérni a legújabb verziót!</value>
</data>
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
<value>Nem lehet folytatni a frissítést, mivel nincs olyan fájl, ami kapcsolatban állna a jelenleg futó binárissal! Győződj meg róla, hogy az ASF bináris fájlod rendesen van elnevezve!</value>
</data>
<data name="ErrorUpdateNoAssets" xml:space="preserve">
<value>Nem lehet folytatni a frissítést, mivel ez a verzió nem tartalmaz egyetlen fájlt sem!</value>
</data>
<data name="ErrorWCFAccessDenied" xml:space="preserve">
<value>A kérés nem teljesíthető, mivel a SteamOwnerID nincs beállítva!</value>
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
</data>
<data name="Exiting" xml:space="preserve">
<value>Kilépés...</value>
</data>
<data name="WarningFailed" xml:space="preserve">
<value>Sikertelen!</value>
</data>
<data name="GlobalConfigChanged" xml:space="preserve">
<value>A globális konfigurációs fájl megváltozott!</value>
</data>
<data name="ErrorGlobalConfigRemoved" xml:space="preserve">
<value>A globális konfigurációs fájl törölve lett!</value>
</data>
<data name="IgnoringTrade" xml:space="preserve">
<value>Csereajánlat figyelmen kívül hagyása: {0}</value>
<comment>{0} will be replaced by trade number</comment>
@@ -184,8 +213,12 @@ StackTrace: {2}</value>
<value>Belépés {0} szolgáltatásba...</value>
<comment>{0} will be replaced by service's name</comment>
</data>
<data name="NoBotsAreRunning" xml:space="preserve">
<value>Egyetlen bot sem fut, kilépés...</value>
</data>
<data name="RefreshingOurSession" xml:space="preserve">
<value>Munkamenet frissítése!</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>Csereajánlat elutasítása: {0}</value>
<comment>{0} will be replaced by trade number</comment>
@@ -193,10 +226,21 @@ StackTrace: {2}</value>
<data name="Restarting" xml:space="preserve">
<value>Újraindítás...</value>
</data>
<data name="WarningRuntimeUnsupported" xml:space="preserve">
<value>Az ASF nem támogatott futásidejű verziót észlelt, a program lehet hogy NEM fog megfelelően futni a jelenlegi környezetben. Futtatás csak saját felelősségre, segítséget ne várj!</value>
</data>
<data name="RuntimeVersionComparison" xml:space="preserve">
<value>Szükséges verzió: {0} | Észlelt verzió: {1}</value>
<comment>{0} will be replaced by required version, {1} will be replaced by current version</comment>
</data>
<data name="RuntimeVersionOK" xml:space="preserve">
<value>A {0} futásidejű verziója rendben van.</value>
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
</data>
<data name="WarningRuntimeVersionTooOld" xml:space="preserve">
<value>A {0} futásidejű verziója túl régi!</value>
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
</data>
<data name="Starting" xml:space="preserve">
<value>Indítás...</value>
</data>
@@ -241,118 +285,330 @@ StackTrace: {2}</value>
<data name="UpdateCheckingNewVersion" xml:space="preserve">
<value>Új verzió keresése...</value>
</data>
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
<value>Új verzió letöltése folyamatban... Mialatt várakozol, fontold meg, hogy pénzzel támogatod a munkámat, ha tetszik, amit csinálok! :)</value>
</data>
<data name="UpdateFinished" xml:space="preserve">
<value>Frissítés kész!</value>
</data>
<data name="UpdateNewVersionAvailable" xml:space="preserve">
<value>Új ASF verzió elérhető! Fontold meg a manuális frissítést!</value>
</data>
<data name="UpdateVersionInfo" xml:space="preserve">
<value>Lokális verzió: {0} | Távoli verzió: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceID" xml:space="preserve">
<value>&lt;{0}&gt; Adja meg az eszköz ID-t ("android:" részt is beleértve): </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a 2FA kódodat a Steam authenticator alkalmazásból: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamGuard" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a SteamGuard hitelesítő kódodat, amit az e-mail címedre küldtek: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamLogin" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a Steam belépési neved: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamParentalPIN" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a Steam szülői felügyelet PIN kódját: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamPassword" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a Steam jelszavad: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputUnknown" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a(z) {1} nem dokumentált értékét: </value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by property name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputWCFHost" xml:space="preserve">
<value>&lt;{0}&gt; Kérlek, add meg a WCF host-odat: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
<value>{0} ismeretlen értéket kapott, kérlek, jelentsd ezt: {1}</value>
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
</data>
<data name="WarningTooManyGamesToPlay" xml:space="preserve">
<value>Több mint {0} játék egyidejű játszására nincs lehetőség, csak az első {0} bejegyzés lesz használva {1}-ból!</value>
<comment>{0} will be replaced by max number of games, {1} will be replaced by name of the configuration property</comment>
</data>
<data name="WarningWCFIgnoringCommand" xml:space="preserve">
<value>WCF parancs figyelmen kívül hagyva, mivel --client nem volt megadva: {0}</value>
<comment>{0} will be replaced by WCF command</comment>
</data>
<data name="ErrorWCFAddressAccessDeniedException" xml:space="preserve">
<value>A WCF szolgáltatást nem lehetett elindítani AddressAccessDeniedException miatt! Ha szeretnéd az ASF által nyújtott WCF szolgáltatást használni, próbáld meg az ASF-t adminisztrátorként, vagy megfelelő engedélyekkel futtatni!</value>
</data>
<data name="WCFAnswered" xml:space="preserve">
<value>A WCF parancsra ({0}) a következő válasz érkezett: {1}</value>
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF answer</comment>
</data>
<data name="WCFReady" xml:space="preserve">
<value>A WCF szerver készen áll!</value>
</data>
<data name="WCFResponseReceived" xml:space="preserve">
<value>WCF válasz érkezett: {0}</value>
<comment>{0} will be replaced by WCF response</comment>
</data>
<data name="WCFSendingCommand" xml:space="preserve">
<value>{0} parancs küldése a WCF szervernek {1}-n...</value>
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF hostname</comment>
</data>
<data name="WCFStarting" xml:space="preserve">
<value>WCF szerver indítása {0}-n...</value>
<comment>{0} will be replaced by WCF hostname</comment>
</data>
<data name="BotAlreadyStopped" xml:space="preserve">
<value>Az a bot példány már le lett állítva!</value>
</data>
<data name="BotNotFound" xml:space="preserve">
<value>Egyetlen bot sem található {0} névvel!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotsStatusOverview" xml:space="preserve">
<value>{0}/{1} bot fut jelenleg. Összesen {2} játékot ({3} kártya) kell még futtatni.</value>
<comment>{0} will be replaced by number of active bots, {1} will be replaced by total number of bots, {2} will be replaced by total number of games left to idle, {3} will be replaced by total number of cards left to idle</comment>
</data>
<data name="BotStatusIdling" xml:space="preserve">
<value>Bot {0} az alábbi játékot farmolja: {1} ({2}, {3} kártya maradt még). Összesen {4} játék ({5} kártya) maradt (kb. {6} míg végez).</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="BotStatusIdlingList" xml:space="preserve">
<value>Bot {0} az alábbi játékokat farmolja: {1}. Összesen {2} játék ({3} kártya) maradt (kb. {4} míg végez).</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="CheckingFirstBadgePage" xml:space="preserve">
<value>A kitűzők első oldalának ellenőrzése...</value>
</data>
<data name="CheckingOtherBadgePages" xml:space="preserve">
<value>A többi kitűző oldal ellenőrzése...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>A kiválasztott farmoló algoritmus: {0}</value>
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
<value>Kész!</value>
</data>
<data name="GamesToIdle" xml:space="preserve">
<value>Még összesen {0} játék ({1} kártya) maradt (kb. {2} míg végez)...</value>
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingFinished" xml:space="preserve">
<value>Farmolás befejezve!</value>
</data>
<data name="IdlingFinishedForGame" xml:space="preserve">
<value>Farmolás befejezve: {0} ({1}) készen van {2} játékidő után!</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingFinishedForGames" xml:space="preserve">
<value>Az alábbi játékok farmolása befejeződött: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="IdlingStatusForGame" xml:space="preserve">
<value>A farmolás állapota {0} ({1}) számára: {2} kártya maradt</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle</comment>
</data>
<data name="IdlingStopped" xml:space="preserve">
<value>Farmolás leállítva!</value>
</data>
<data name="NothingToIdle" xml:space="preserve">
<value>Ezen az accounton nincs mit farmolni!</value>
</data>
<data name="NowIdling" xml:space="preserve">
<value>Farmolás alatt: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="NowIdlingList" xml:space="preserve">
<value>Farmolás alatt: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StillIdling" xml:space="preserve">
<value>Még mindig farmolás alatt: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StillIdlingList" xml:space="preserve">
<value>Még mindig farmolás alatt: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StoppedIdling" xml:space="preserve">
<value>Farmolás leállítva: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>Farmolás leállítva: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Ismeretlen parancs!</value>
</data>
<data name="WarningCouldNotCheckBadges" xml:space="preserve">
<value>Nem lehet lekérni a kitűző információkat, később újra lesz próbálva!</value>
</data>
<data name="WarningCouldNotCheckCardsStatus" xml:space="preserve">
<value>A kártyák állapota nem elérhető ehhez: {0} ({1}), később újra lesz próbálva!</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="BotAcceptingGift" xml:space="preserve">
<value>Ajándék elfogadása: {0}...</value>
<comment>{0} will be replaced by giftID (number)</comment>
</data>
<data name="BotAccountLimited" xml:space="preserve">
<value>Ez az account korlátozva van, a farmolás a korlátozás megszűnéséig nem elérhető!</value>
</data>
<data name="BotAddLicenseResponse" xml:space="preserve">
<value>&lt;{0}&gt; GameID: {1} | Állapot: {2}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string</comment>
</data>
<data name="BotAlreadyRunning" xml:space="preserve">
<value>Az a bot példány már fut!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotAuthenticatorConverting" xml:space="preserve">
<value>.maFile konvertálása ASF formátumba...</value>
</data>
<data name="BotAuthenticatorImportFinished" xml:space="preserve">
<value>A mobil hitelesítő importálása sikeres!</value>
</data>
<data name="BotAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>A DeviceID-d inkorrekt, vagy nem létezik!</value>
</data>
<data name="BotAuthenticatorToken" xml:space="preserve">
<value>2FA Token: {0}</value>
<comment>{0} will be replaced by generated 2FA token (string)</comment>
</data>
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
<value>Automatikus farmolás szüneteltetve!</value>
</data>
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
<value>Automatikus farmolás folytatva!</value>
</data>
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
<value>Az automatikus farmolás már szüneteltetve van!</value>
</data>
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
<value>Automatikus farmolás szüneteltetve! {0} perced van, hogy elindíts egy játékot.</value>
<comment>{0} will be replaced by number of minutes</comment>
</data>
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
<value>Az automatikus farmolás már folytatva van!</value>
</data>
<data name="BotConnected" xml:space="preserve">
<value>Csatlakozva a Steamhez!</value>
</data>
<data name="BotDisconnected" xml:space="preserve">
<value>Lecsatlakozva a Steamről!</value>
</data>
<data name="BotDisconnecting" xml:space="preserve">
<value>Kapcsolat bontása...</value>
</data>
<data name="BotEncryptedPassword" xml:space="preserve">
<value>[{0}] jelszó: {1}</value>
<comment>{0} will be replaced by password encryption method (string), {1} will be replaced by encrypted password using that method (string)</comment>
</data>
<data name="BotInstanceNotStartingBecauseDisabled" xml:space="preserve">
<value>Ezt a bot példányt nem lehet elindítani, mert a konfigurációs fájlban ki van kapcsolva!</value>
</data>
<data name="BotInvalidAuthenticatorDuringLogin" xml:space="preserve">
<value>TwoFactorCodeMismatch hibakód érkezett {0} alkalommal egymás után. Ez szinte mindig érvénytelen ASF 2FA adatokat jelent. Megszakítás!</value>
<comment>{0} will be replaced by maximum allowed number of failed 2FA attempts</comment>
</data>
<data name="BotLoggedOff" xml:space="preserve">
<value>Kijelentkezve a Steamből: {0}</value>
<comment>{0} will be replaced by logging off reason (string)</comment>
</data>
<data name="BotLoggedOn" xml:space="preserve">
<value>Sikeres bejelentkezés!</value>
</data>
<data name="BotLoggingIn" xml:space="preserve">
<value>Bejelentkezés...</value>
</data>
<data name="BotLogonSessionReplaced" xml:space="preserve">
<value>Ezt az accountot egy másik ASF példány már használja, ami nem várt viselkedést eredményez. A további futás megtagadva!</value>
</data>
<data name="BotLootingFailed" xml:space="preserve">
<value>Csereajánlat nem sikerült!</value>
</data>
<data name="BotLootingMasterNotDefined" xml:space="preserve">
<value>A csereajánlatot nem lehet elküldeni, mert a SteamMasterID nincs beállítva!</value>
<comment>SteamMasterID is name of bot config property, it should not be translated</comment>
</data>
<data name="BotLootingSuccess" xml:space="preserve">
<value>Csereajánlat sikeresen elküldve!</value>
</data>
<data name="BotNoASFAuthenticator" xml:space="preserve">
<value>Annál a botnál nincs bekapcsolva az ASF 2FA! Elfelejtetted volna ASF 2FA-ként importálni a hitelesítődet?</value>
</data>
<data name="BotNotConnected" xml:space="preserve">
<value>Ez a bot példány nincs csatlakozva!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotNotOwnedYet" xml:space="preserve">
<value>&lt;{0}&gt; Még nincs meg: {1}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by query (string)</comment>
</data>
<data name="BotOwnedAlready" xml:space="preserve">
<value>&lt;{0}&gt; Már megvan: {1} | {2}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name</comment>
</data>
<data name="BotReconnecting" xml:space="preserve">
<value>Újracsatlakozás...</value>
</data>
<data name="BotRedeemResponse" xml:space="preserve">
<value>&lt;{0}&gt; Kulcs: {1} | Állapot: {2}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string</comment>
</data>
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
<value>A lejárt belépési kulcs törölve!</value>
</data>
<data name="BotsStatusNotIdling" xml:space="preserve">
<value>Bot {0} nem farmol jelenleg semmit.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusLimited" xml:space="preserve">
<value>Bot {0} korlátozva van, ezért farmolással nem tud kártyákat dobni.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotConnected" xml:space="preserve">
<value>Bot {0} nincs csatlakoztatva.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotRunning" xml:space="preserve">
<value>Bot {0} nem fut jelenleg.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusPaused" xml:space="preserve">
<value>Bot {0} le van állítva, vagy manuális módban fut.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusPlayingNotAvailable" xml:space="preserve">
<value>Bot {0} jelenleg használatban van.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotUnableToConnect" xml:space="preserve">
<value>Nem lehet csatlakozni a Steamhez: {0}</value>
<comment>{0} will be replaced by failure reason (string)</comment>
</data>
<data name="BotUnableToLogin" xml:space="preserve">
<value>Nem lehet belépni a Steamre: {0}/{1}</value>
<comment>{0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string)</comment>
</data>
<data name="ErrorIsEmpty" xml:space="preserve">
<value>Üres {0}!</value>
<comment>{0} will be replaced by object's name</comment>
@@ -361,22 +617,59 @@ StackTrace: {2}</value>
<value>Fel nem használt kulcsok: {0}</value>
<comment>{0} will be replaced by list of cd-keys (strings), separated by a comma</comment>
</data>
<data name="WarningFailedWithError" xml:space="preserve">
<value>Hiba miatt nem sikerült: {0}</value>
<comment>{0} will be replaced by failure reason (string)</comment>
</data>
<data name="BotConnectionLost" xml:space="preserve">
<value>Megszakadt a kapcsolat a Steam hálózattal, újrakapcsolódás...</value>
</data>
<data name="BotAccountFree" xml:space="preserve">
<value>Az account már nincs használatban, a farmolási folyamat folytatódik!</value>
</data>
<data name="BotAccountOccupied" xml:space="preserve">
<value>Az account jelenleg használatban van, amikor felszabadul, az ASF folytatni fogja a farmolást...</value>
</data>
<data name="BotConnecting" xml:space="preserve">
<value>Kapcsolódás...</value>
</data>
<data name="BotHeartBeatFailed" xml:space="preserve">
<value>Nem lehet lecsatlakozni a kliensről, megszabadulunk ettől a bot példánytól!</value>
</data>
<data name="BotSteamDirectoryInitializationFailed" xml:space="preserve">
<value>A SteamDirectory-t nem sikerült inicializálni, a Steam hálózathoz való csatlakozás a szokásosnál tovább is eltarthat!</value>
</data>
<data name="BotStopping" xml:space="preserve">
<value>Leállás...</value>
</data>
<data name="ErrorBotConfigInvalid" xml:space="preserve">
<value>A bot konfigurációd érvénytelen, kérlek, ellenőrizd {0} tartalmát, majd próbáld meg újból!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorDatabaseInvalid" xml:space="preserve">
<value>A perzisztens adatbázist nem lehet betölteni! Ha a hiba továbbra is fennáll, kérlek, töröld {0}-t, hogy az adatbázis újra elkészülhessen!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="Initializing" xml:space="preserve">
<value>{0} inicializálása...</value>
<comment>{0} will be replaced by service name that is being initialized</comment>
</data>
<data name="WarningPrivacyPolicy" xml:space="preserve">
<value>Kérlek, olvasd el az adatvédelmi szabályzatunkat a wiki-n, ha szeretnéd tudni, mit is csinál valójában az ASF!</value>
</data>
<data name="Welcome" xml:space="preserve">
<value>Úgy tűnik, most indítottad el első alkalommal a programot, üdvözöllek!</value>
</data>
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>A te CurrentCulture változód érvénytelen, az ASF az alapértelmezettet fogja használni!</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>Az ASF megpróbálja az elsődleges kultúrádat ({0}) használni, de a fordítás azon a nyelven csak {1}-ban készült el eddig. Talán segíthetnél a saját nyelved ASF fordításában?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>A farmolás {0} ({1}) számára átmenetileg nem elérhető, mivel a játék még nem jelent meg.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -695,4 +695,8 @@
<value>ASF akan mencoba untuk menggunakan bahasa {0} pilihan Anda, tetapi terjemahan dalam bahasa tersebut baru {1}. Mungkin Anda bisa membantu ASF untuk melengkapi terjemahan ke dalam bahasa Anda?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Idling {0} ({1}) untuk sementara dinonaktifkan, karena permainan tersebut belum dirilis.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -692,7 +692,11 @@
<value>Il valore CurrentCulture che hai fornito non è valido, ASF continuerà ad utilizzare quello di default!</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>ASF proverà ad utilizzare la tua cultura preferita {0}, ma la traduzione in questa lingua é completa solo al {1}. Magari potresti aiutarci a migliorare la traduzione di ASF nella tua lingua?</value>
<value>ASF proverà ad utilizzare la tua lingua preferita {0}, ma la traduzione è completa solo al {1}. Forse potresti aiutarci a migliorare la traduzione di ASF nella tua lingua?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Idling di {0} ({1}) è temporaneamente disabilitato, poiché il gioco non è stato ancora rilasciato.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -690,5 +690,12 @@
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>指定されたCurrentCultureが有効ではありません。ASFはデフォルトで実行されます</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>ASFはあなたの言語{0} の使用を試みますが、この言語の翻訳の完成度は{1} です。もしかしたらあなたが翻訳の向上を助けられるかもしれませんよ?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>このゲームはまだリリースされていないため、{0} ({1}) のアイドリングは一時的に無効になります。</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -699,4 +699,8 @@ ASF 실행 파일의 이름이 적절한지 확인하시기 바랍니다!</value
<value>ASF는 {0} 지역 언어를 사용하려고 시도했지만, 해당 언어의 번역이 {1}만 완료되어 있습니다. 혹시 당신의 언어로 ASF 번역을 개선하는 것을 도와줄 수 있나요?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>해당 게임이 아직 출시 전이므로, {0} ({1})의 농사가 일시적으로 비활성화 되었습니다.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -694,4 +694,8 @@
<value>ASF bandys naudoti jūsų pageidaujamą {0} kalbą, bet vertimas į tą kalba buvo užbaigtas tik {1}. Galbūt jūs galėtumėte mums padėti pagerinti ASF vertimą į šią kalbą?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Kortelių rinkimas iš {0}({1}) laikinai sustabdytas, nes žaidimas dar nėra išleistas.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -278,6 +278,7 @@
</root>

View File

@@ -0,0 +1,703 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AcceptingTrade" xml:space="preserve">
<value>Ruilaanbieding {0} wordt geaccepteerd</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="AutoUpdateCheckInfo" xml:space="preserve">
<value>ASF controleert automatisch om de {0} uren op een nieuwe versie.</value>
<comment>{0} will be replaced by number of hours</comment>
</data>
<data name="Content" xml:space="preserve">
<value>Inhoud: {0}</value>
<comment>{0} will be replaced by content string. Please note that this string should include newline for formatting.</comment>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Geconfigureerde {0} eigenschap is niet geldig: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorEarlyFatalExceptionInfo" xml:space="preserve">
<value>ASF V{0} heeft een fatale uitzondering tegengekomen voordat het kern logboek module in staat was om te initialiseren!</value>
<comment>{0} will be replaced by version number</comment>
</data>
<data name="ErrorEarlyFatalExceptionPrint" xml:space="preserve">
<value>Uitzondering: {0}() {1}
StackTrace:
{2}</value>
<comment>{0} will be replaced by function name, {1} will be replaced by exception message, {2} will be replaced by entire stack trace. Please note that this string should include newlines for formatting.</comment>
</data>
<data name="ErrorExitingWithNonZeroErrorCode" xml:space="preserve">
<value>Afsluiten met een niet-nulzijnde foutcode!</value>
</data>
<data name="ErrorFailingRequest" xml:space="preserve">
<value>Vezoek mislukt: {0}</value>
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
<value>Globale configuratie kan niet worden geladen, controleer of het bestand {0} bestaat en of het geldig is! Volg de handleiding op de wiki als je niet weet je wat je moet doen.</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
<value>{0} is ongeldig!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorMobileAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>Deze functie wordt niet uitgevoerd als gevolg van de ongeldige DeviceID in ASF 2FA!</value>
</data>
<data name="ErrorNoBotsDefined" xml:space="preserve">
<value>Er zijn geen bots gedefinieerd, ben je vergeten om ASF te configureren?</value>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} is null!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorParsingObject" xml:space="preserve">
<value>Verwerking van {0} mislukt!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRemovingOldBinary" xml:space="preserve">
<value>Kon niet de oude ASF binary verwijderen, verwijder alsjeblieft {0} handmatig zodat de updatefunctie werkt!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
<value>Verzoek mislukt ondanks {0} pogingen!</value>
<comment>{0} will be replaced by maximum number of tries</comment>
</data>
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
<value>Controle voor de laatste versie is mislukt!</value>
</data>
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
<value>Kon niet verdergaan met updaten omdat er geen bestand bestaat dat gerelateerd is aan de momenteel actieve binary! Controleer of de ASF binary de juiste naam heeft!</value>
</data>
<data name="ErrorUpdateNoAssets" xml:space="preserve">
<value>Kon niet verdergaan met de update omdat deze versie niet alle bestanden omvat!</value>
</data>
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
<value>Aanvraag voor gebruikersinvoer ontvangen, maar het proces draait in headless mode!</value>
</data>
<data name="ErrorWCFAccessDenied" xml:space="preserve">
<value>Het verzoek wordt niet in behandeling genomen omdat SteamOwnerID niet is ingesteld!</value>
<comment>SteamOwnerID is name of bot config property, it should not be translated</comment>
</data>
<data name="Exiting" xml:space="preserve">
<value>Afsluiten...</value>
</data>
<data name="WarningFailed" xml:space="preserve">
<value>Mislukt!</value>
</data>
<data name="GlobalConfigChanged" xml:space="preserve">
<value>Globaal configuratiebestand is aangepast!</value>
</data>
<data name="ErrorGlobalConfigRemoved" xml:space="preserve">
<value>Globaal configuratiebestand is verwijderd!</value>
</data>
<data name="IgnoringTrade" xml:space="preserve">
<value>Ruilaanbieding {0} wordt genegeerd</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="LoggingIn" xml:space="preserve">
<value>Inloggen op {0}...</value>
<comment>{0} will be replaced by service's name</comment>
</data>
<data name="NoBotsAreRunning" xml:space="preserve">
<value>Geen bots actief, afsluiten...</value>
</data>
<data name="RefreshingOurSession" xml:space="preserve">
<value>Sessie wordt ververst!</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>Ruilaanbieding {0} wordt afgekeurd</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="Restarting" xml:space="preserve">
<value>Herstarten...</value>
</data>
<data name="WarningRuntimeUnsupported" xml:space="preserve">
<value>ASF heeft een niet ondersteunde runtime versie gedetecteerd, het programma kan mogelijk NIET correct worden uitgevoerd in de huidige omgeving. Je voert dit met eigen risico en zonder ondersteuning uit!</value>
</data>
<data name="RuntimeVersionComparison" xml:space="preserve">
<value>Vereiste versie: {0} | Gevonden versie: {1}</value>
<comment>{0} will be replaced by required version, {1} will be replaced by current version</comment>
</data>
<data name="RuntimeVersionOK" xml:space="preserve">
<value>Je {0} runtime versie is OK.</value>
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
</data>
<data name="WarningRuntimeVersionTooOld" xml:space="preserve">
<value>Je {0} runtime versie is te oud!</value>
<comment>{0} will be replaced by runtime name (e.g. "Mono")</comment>
</data>
<data name="Starting" xml:space="preserve">
<value>Starten...</value>
</data>
<data name="StatusCode" xml:space="preserve">
<value>Status code: {0}</value>
<comment>{0} will be replaced by status code number/name</comment>
</data>
<data name="Success" xml:space="preserve">
<value>Succes!</value>
</data>
<data name="TimeSpanDay" xml:space="preserve">
<value>1 dag</value>
</data>
<data name="TimeSpanDays" xml:space="preserve">
<value>{0} dagen</value>
<comment>{0} will be replaced by number of days</comment>
</data>
<data name="TimeSpanHour" xml:space="preserve">
<value>1 uur</value>
</data>
<data name="TimeSpanHours" xml:space="preserve">
<value>{0} uren</value>
<comment>{0} will be replaced by number of hours</comment>
</data>
<data name="TimeSpanMinute" xml:space="preserve">
<value>1 minuut</value>
</data>
<data name="TimeSpanMinutes" xml:space="preserve">
<value>{0} minuten</value>
<comment>{0} will be replaced by number of minutes</comment>
</data>
<data name="TimeSpanSecond" xml:space="preserve">
<value>1 seconde</value>
</data>
<data name="TimeSpanSeconds" xml:space="preserve">
<value>{0} seconden</value>
<comment>{0} will be replaced by number of seconds</comment>
</data>
<data name="UnlockingParentalAccount" xml:space="preserve">
<value>Ouderaccount wordt ontgrendeld...</value>
</data>
<data name="UpdateCheckingNewVersion" xml:space="preserve">
<value>Controleren op nieuwe versie...</value>
</data>
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
<value>Nieuwe versie wordt gedownloadt... Onder het wachten, overweeg te doneren als je het gedane werk waardeert! :)</value>
</data>
<data name="UpdateFinished" xml:space="preserve">
<value>Bijwerken afgerond!</value>
</data>
<data name="UpdateNewVersionAvailable" xml:space="preserve">
<value>Een nieuwe ASF-versie is beschikbaar! Overweeg om deze zelf bij te werken!</value>
</data>
<data name="UpdateVersionInfo" xml:space="preserve">
<value>Lokale versie: {0} | Externe versie: {1}</value>
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceID" xml:space="preserve">
<value>&lt;{0}&gt; Vul je Device ID in (inclusief "android:"): </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">
<value>&lt;{0}&gt; Vul je 2FA code in van je Steam authenticatie app: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamGuard" xml:space="preserve">
<value>&lt;{0}&gt; Vul de SteamGuard authenticatiecode in die naar je e-mail gestuurd is: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamLogin" xml:space="preserve">
<value>&lt;{0}&gt; Vul je Steam gebruikersnaam in: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamParentalPIN" xml:space="preserve">
<value>&lt;{0}&gt; Vul je Steam ouderlijktoezichtscode in: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteamPassword" xml:space="preserve">
<value>&lt;{0}&gt; Vul je Steam wachtwoord in: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputUnknown" xml:space="preserve">
<value>&lt;{0} &gt; Voer ongedocumenteerde waarde van {1}: </value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by property name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputWCFHost" xml:space="preserve">
<value>&lt;{0}&gt; Voer je WCF-host in: </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="WarningUnknownValuePleaseReport" xml:space="preserve">
<value>Onbekende waarde ontvangen voor {0}, gelieven dit melden: {1}</value>
<comment>{0} will be replaced by object's name, {1} will be replaced by value for that object</comment>
</data>
<data name="WarningTooManyGamesToPlay" xml:space="preserve">
<value>Het spelen van meer dan {0} games gelijktijdig is niet mogelijk, alleen de eerste {0} games van {1} worden gebruikt!</value>
<comment>{0} will be replaced by max number of games, {1} will be replaced by name of the configuration property</comment>
</data>
<data name="WarningWCFIgnoringCommand" xml:space="preserve">
<value>WCF opdracht word genegeerd omdat --cliënt niet gespecificeerd was: {0}</value>
<comment>{0} will be replaced by WCF command</comment>
</data>
<data name="ErrorWCFAddressAccessDeniedException" xml:space="preserve">
<value>WCF service kan niet worden gestart vanwege de AddressAccessDeniedException! Als je zelf gebruik wilt maken van de WCF service van ASF, overweeg om ASF te starten als administrator of geef de juiste machtigingen!</value>
</data>
<data name="WCFAnswered" xml:space="preserve">
<value>Beantwoordt aan WCF opdracht: {0} met: {1}</value>
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF answer</comment>
</data>
<data name="WCFReady" xml:space="preserve">
<value>WCF server gereed!</value>
</data>
<data name="WCFResponseReceived" xml:space="preserve">
<value>WCF reactie ontvangen: {0}</value>
<comment>{0} will be replaced by WCF response</comment>
</data>
<data name="WCFSendingCommand" xml:space="preserve">
<value>Opdracht {0} verzenden naar WCF server op {1}...</value>
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF hostname</comment>
</data>
<data name="WCFStarting" xml:space="preserve">
<value>WCF server starten op {0}...</value>
<comment>{0} will be replaced by WCF hostname</comment>
</data>
<data name="BotAlreadyStopped" xml:space="preserve">
<value>Deze bot-instantie is al gestopt!</value>
</data>
<data name="BotNotFound" xml:space="preserve">
<value>Kan geen bot vinden genaamd {0}!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotsStatusOverview" xml:space="preserve">
<value>Er zijn {0}/{1} bots actief, met in totaal {2} spellen ({3} kaarten) te gaan om te idlen.</value>
<comment>{0} will be replaced by number of active bots, {1} will be replaced by total number of bots, {2} will be replaced by total number of games left to idle, {3} will be replaced by total number of cards left to idle</comment>
</data>
<data name="BotStatusIdling" xml:space="preserve">
<value>Bot {0} is spel {1} aan het idlen ({2}, {3} kaarten te gaan) van een totaal van {4} spellen ({5} kaarten) nog te verzamelen (~{6} resterende).</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="BotStatusIdlingList" xml:space="preserve">
<value>Bot {0} is spellen aan het idlen: {1} uit een totaal van {2} spellen ({3} kaarten) nog te idlen (~{4} remaining).</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="CheckingFirstBadgePage" xml:space="preserve">
<value>Eerste badge pagina controleren...</value>
</data>
<data name="CheckingOtherBadgePages" xml:space="preserve">
<value>Andere badge pagina's controleren...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>Gekozen idling algoritme: {0}</value>
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
<value>Klaar!</value>
</data>
<data name="GamesToIdle" xml:space="preserve">
<value>We hebben een totaal van {0} spellen ({1} kaarten) nog te verzamelen (~{2} resterende)...</value>
<comment>{0} will be replaced by number of games, {1} will be replaced by number of cards, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingFinished" xml:space="preserve">
<value>Idling klaar!</value>
</data>
<data name="IdlingFinishedForGame" xml:space="preserve">
<value>Klaar met idlen: {0} ({1}) na {2} speeltijd!</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingFinishedForGames" xml:space="preserve">
<value>Het idlen is klaar voor de games: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="IdlingStatusForGame" xml:space="preserve">
<value>Idling status voor {0} {1}): {2} kaarten resterend</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by number of cards left to idle</comment>
</data>
<data name="IdlingStopped" xml:space="preserve">
<value>Het idlen is gestopt!</value>
</data>
<data name="IgnoredStickyPauseEnabled" xml:space="preserve">
<value>Dit verzoek wordt genegeerd. Permanente pauze staat aan!</value>
</data>
<data name="NothingToIdle" xml:space="preserve">
<value>We hebben niks om te idlen op dit account!</value>
</data>
<data name="NowIdling" xml:space="preserve">
<value>Nu aan het idlen: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="NowIdlingList" xml:space="preserve">
<value>Nu aan het idlen: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="PlayingNotAvailable" xml:space="preserve">
<value>Spelen is op dit moment niet mogelijk, we proberen het later nog een keer!</value>
</data>
<data name="StillIdling" xml:space="preserve">
<value>Nog steeds aan het idlen: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StillIdlingList" xml:space="preserve">
<value>Nog steeds aan het idlen: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="StoppedIdling" xml:space="preserve">
<value>Gestopt met idlen: {0} ({1})</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="StoppedIdlingList" xml:space="preserve">
<value>Gestopt met idlen: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Onbekende opdracht!</value>
</data>
<data name="WarningCouldNotCheckBadges" xml:space="preserve">
<value>Kan de badges informatie niet verkrijgen, we zullen het later nog een keer proberen!</value>
</data>
<data name="WarningCouldNotCheckCardsStatus" xml:space="preserve">
<value>Kaart status kan niet worden gecontroleerd voor {0} ({1}), wij zullen het later nogmaals proberen!</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
<data name="BotAcceptingGift" xml:space="preserve">
<value>Cadeau accepteren: {0}...</value>
<comment>{0} will be replaced by giftID (number)</comment>
</data>
<data name="BotAccountLimited" xml:space="preserve">
<value>Dit account is beperkt, het idling proces is permanent onbeschikbaar totdat de beperking is verwijderd!</value>
</data>
<data name="BotAddLicenseResponse" xml:space="preserve">
<value>&lt;{0}&gt; SpelID: {1} | Status: {2}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string</comment>
</data>
<data name="BotAddLicenseResponseWithItems" xml:space="preserve">
<value>&lt;{0}&gt; SpelID: {1} | Status: {2} | Items: {3}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by gameID (number), {2} will be replaced by status string, {3} will be replaced by list of granted appIDs (numbers), separated by a comma</comment>
</data>
<data name="BotAlreadyRunning" xml:space="preserve">
<value>Die bot-instantie is al bezig!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotAuthenticatorConverting" xml:space="preserve">
<value>.maFile omzetten naar ASF formaat...</value>
</data>
<data name="BotAuthenticatorImportFinished" xml:space="preserve">
<value>Met succes de mobiele authenticator geimporteerd!</value>
</data>
<data name="BotAuthenticatorInvalidDeviceID" xml:space="preserve">
<value>Je DeviceID is incorrect of bestaat niet!</value>
</data>
<data name="BotAuthenticatorToken" xml:space="preserve">
<value>2FA Token: {0}</value>
<comment>{0} will be replaced by generated 2FA token (string)</comment>
</data>
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
<value>Automatisch idling is nu gepauzeerd!</value>
</data>
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
<value>Automatisch idling is nu hervat!</value>
</data>
<data name="BotAutomaticIdlingPausedAlready" xml:space="preserve">
<value>Automatisch idling is al gepauzeerd!</value>
</data>
<data name="BotAutomaticIdlingPausedWithCountdown" xml:space="preserve">
<value>Automatisch idling is nu gepauzeerd! Je hebt {0} minuten om een spel te starten.</value>
<comment>{0} will be replaced by number of minutes</comment>
</data>
<data name="BotAutomaticIdlingResumedAlready" xml:space="preserve">
<value>Automatisch idling is al hervat!</value>
</data>
<data name="BotConnected" xml:space="preserve">
<value>Verbonden met Steam!</value>
</data>
<data name="BotDisconnected" xml:space="preserve">
<value>Verbinding met Steam verbroken!</value>
</data>
<data name="BotDisconnecting" xml:space="preserve">
<value>Verbinding verbreken...</value>
</data>
<data name="BotEncryptedPassword" xml:space="preserve">
<value>[{0}] Wachtwoord: {1}</value>
<comment>{0} will be replaced by password encryption method (string), {1} will be replaced by encrypted password using that method (string)</comment>
</data>
<data name="BotInstanceNotStartingBecauseDisabled" xml:space="preserve">
<value>Deze bot wordt niet gestart omdat hij uitgeschakeld is in het configuratie bestand!</value>
</data>
<data name="BotInvalidAuthenticatorDuringLogin" xml:space="preserve">
<value>TwoFactorCodeMisMatch foutmelding {0} ontvangen, dit betekent bijna altijd de verkeerde ASF 2FA login informatie, afbreken!</value>
<comment>{0} will be replaced by maximum allowed number of failed 2FA attempts</comment>
</data>
<data name="BotLoggedOff" xml:space="preserve">
<value>Uitgelogd op Steam: {0}</value>
<comment>{0} will be replaced by logging off reason (string)</comment>
</data>
<data name="BotLoggedOn" xml:space="preserve">
<value>Succesvol ingelogd!</value>
</data>
<data name="BotLoggingIn" xml:space="preserve">
<value>Inloggen...</value>
</data>
<data name="BotLogonSessionReplaced" xml:space="preserve">
<value>Het lijkt erop dat dit account wordt gebruikt in een ander ASF instantie, met onbepaald gedrag, weigeren om het draaiende te houden!</value>
</data>
<data name="BotLootingFailed" xml:space="preserve">
<value>Handelsvoorstel mislukt!</value>
</data>
<data name="BotLootingMasterNotDefined" xml:space="preserve">
<value>Trade kon niet verzonden worden, omdat SteamMasterID niet is ingesteld!</value>
<comment>SteamMasterID is name of bot config property, it should not be translated</comment>
</data>
<data name="BotLootingNoLootableTypes" xml:space="preserve">
<value>Je hebt geen lootable types ingesteld!</value>
</data>
<data name="BotLootingNowDisabled" xml:space="preserve">
<value>Looting is nu uitgeschakeld!</value>
</data>
<data name="BotLootingNowEnabled" xml:space="preserve">
<value>Looting is nu ingeschakeld!</value>
</data>
<data name="BotLootingSuccess" xml:space="preserve">
<value>Trade verzoek succesvol verzonden!</value>
</data>
<data name="BotLootingTemporarilyDisabled" xml:space="preserve">
<value>Looting is tijdelijk uitgeschakeld!</value>
</data>
<data name="BotLootingYourself" xml:space="preserve">
<value>Je kan je zelf niet looten!</value>
</data>
<data name="BotNoASFAuthenticator" xml:space="preserve">
<value>Die bot heeft ASF 2FA nog niet ingeschakeld! Ben je vergeten om je authenticator te importeren als ASF 2FA?</value>
</data>
<data name="BotNotConnected" xml:space="preserve">
<value>Deze bot instatie is niet verbonden!</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotNotOwnedYet" xml:space="preserve">
<value>&lt;{0}&gt; Nog niet in bezit: {1}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by query (string)</comment>
</data>
<data name="BotOwnedAlready" xml:space="preserve">
<value>&lt;{0}&gt; In bezit: {1} | {2}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name</comment>
</data>
<data name="BotRateLimitExceeded" xml:space="preserve">
<value>Limiet overschreden, we zullen het over {0} minuten opnieuw proberen...</value>
<comment>{0} will be replaced by number of minutes</comment>
</data>
<data name="BotReconnecting" xml:space="preserve">
<value>Opnieuw verbinden...</value>
</data>
<data name="BotRedeemResponse" xml:space="preserve">
<value>&lt;{0}&gt; Cd-key: {1} | Status: {2}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string</comment>
</data>
<data name="BotRedeemResponseWithItems" xml:space="preserve">
<value>&lt;{0}&gt; Cd-key: {1} | Status: {2} | Items: {3}</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by cd-key (string), {2} will be replaced by status string, {3} will be replaced by list of key-value pairs, separated by a comma</comment>
</data>
<data name="BotRemovedExpiredLoginKey" xml:space="preserve">
<value>Verlopen login sleutel verwijderd!</value>
</data>
<data name="BotsStatusNotIdling" xml:space="preserve">
<value>Bot {0} is niks aan het idlen.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusLimited" xml:space="preserve">
<value>Bot {0} is beperkt en kan geen kaarten laten vallen via idling.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotConnected" xml:space="preserve">
<value>Bot {0} is niet verbonden.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotRunning" xml:space="preserve">
<value>Bot {0} is niet actief.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusPaused" xml:space="preserve">
<value>Bot {0} is gepauzeerd of uitgevoerd in de handmatige modus.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusPlayingNotAvailable" xml:space="preserve">
<value>Bot {0} wordt momenteel gebruikt.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotUnableToConnect" xml:space="preserve">
<value>Niet in staat om op Steam in te loggen: {0}</value>
<comment>{0} will be replaced by failure reason (string)</comment>
</data>
<data name="BotUnableToLogin" xml:space="preserve">
<value>Niet in staat om op Steam inteloggen: {0}/{1}</value>
<comment>{0} will be replaced by failure reason (string), {1} will be replaced by extended failure reason (string)</comment>
</data>
<data name="ErrorIsEmpty" xml:space="preserve">
<value>{0} is leeg!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="UnusedKeys" xml:space="preserve">
<value>Ongebruikte cd-keys: {0}</value>
<comment>{0} will be replaced by list of cd-keys (strings), separated by a comma</comment>
</data>
<data name="WarningFailedWithError" xml:space="preserve">
<value>Mislukt door de fout: {0}</value>
<comment>{0} will be replaced by failure reason (string)</comment>
</data>
<data name="BotConnectionLost" xml:space="preserve">
<value>Verbinding met het Steam Netwerk verloren, opnieuw verbinden...</value>
</data>
<data name="BotAccountFree" xml:space="preserve">
<value>Account wordt niet meer gebruikt, idle proces hervat!</value>
</data>
<data name="BotAccountOccupied" xml:space="preserve">
<value>Account wordt momenteel gebruikt, ASF zal verder gaan met het idle-proces wanneer de account weer vrij is...</value>
</data>
<data name="BotAutomaticIdlingPauseTimeout" xml:space="preserve">
<value>Gedeelde bibliotheek is niet ingebruik genomen in de gegeven tijd periode, idling proces hervat!</value>
</data>
<data name="BotConnecting" xml:space="preserve">
<value>Verbinden...</value>
</data>
<data name="BotHeartBeatFailed" xml:space="preserve">
<value>Poging om de verbinding van de client te verbreken mislukt, x deze bot instantie!</value>
</data>
<data name="BotSteamDirectoryInitializationFailed" xml:space="preserve">
<value>Kan SteamDirectory niet initialiseren, verbinden met Steam Netwerk kan langer duren dan normaal!</value>
</data>
<data name="BotStopping" xml:space="preserve">
<value>Stoppen...</value>
</data>
<data name="ErrorBotConfigInvalid" xml:space="preserve">
<value>Je bot configuratie is ongeldig, controleer de inhoud van {0} en probeer het opnieuw!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorDatabaseInvalid" xml:space="preserve">
<value>Blijvende database kan niet worden geladen, als het probleem aanhoudt, verwijder dan {0} om de database opnieuw te maken!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="Initializing" xml:space="preserve">
<value>{0} Initialiseren...</value>
<comment>{0} will be replaced by service name that is being initialized</comment>
</data>
<data name="WarningPrivacyPolicy" xml:space="preserve">
<value>Raadpleeg onze privacy beleid op de ASF Wiki als je bezorgd bent over wat ASF in feite doet!</value>
</data>
<data name="Welcome" xml:space="preserve">
<value>Het lijkt erop dat je het programma voor het eerst opstart, welkom!</value>
</data>
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>De door jou geleverde CurrentCulture is incorrect, ASF zal de standaard blijven gebruiken!</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>ASF probeert de {0} taal te gebruiken, maar het vertalen in deze taal was tot {1} compleet. Misschien kan 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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Idling {0} ({1}) is tijdelijk uitgeschakeld, aangezien dat spel nog niet was uitgegeven.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -151,7 +151,7 @@ StackTrace:
<comment>{0} will be replaced by URL of the request</comment>
</data>
<data name="ErrorGlobalConfigNotLoaded" xml:space="preserve">
<value>Globale configuratie kan niet worden geladen, check of het bestand {0} bestaat en of het geldig is! Volg de handleiding op de wiki als je niet weet je wat je moet doen.</value>
<value>Globale configuratie kan niet worden geladen, controleer of het bestand {0} bestaat en of het geldig is! Volg de handleiding op de wiki als je niet weet je wat je moet doen.</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorIsInvalid" xml:space="preserve">
@@ -162,18 +162,18 @@ StackTrace:
<value>Deze functie wordt niet uitgevoerd als gevolg van de ongeldige DeviceID in ASF 2FA!</value>
</data>
<data name="ErrorNoBotsDefined" xml:space="preserve">
<value>Geen bots zijn gedefineerd, ben je vergeten om ASF te configureren?</value>
<value>Er zijn geen bots gedefinieerd, ben je vergeten om ASF te configureren?</value>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} is nul!</value>
<value>{0} is null!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorParsingObject" xml:space="preserve">
<value>Parsing {0} mislukt!</value>
<value>Verwerking van {0} mislukt!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRemovingOldBinary" xml:space="preserve">
<value>Kan niet de oude ASF binary verwijderen, verwijder alsjeblieft {0} handmatig zodat de update-functie werkt!</value>
<value>Kon niet de oude ASF binary verwijderen, verwijder alsjeblieft {0} handmatig zodat de updatefunctie werkt!</value>
<comment>{0} will be replaced by file's path</comment>
</data>
<data name="ErrorRequestFailedTooManyTimes" xml:space="preserve">
@@ -181,16 +181,16 @@ StackTrace:
<comment>{0} will be replaced by maximum number of tries</comment>
</data>
<data name="ErrorUpdateCheckFailed" xml:space="preserve">
<value>Controleren op de laatste versie is mislukt!</value>
<value>Controle voor de laatste versie is mislukt!</value>
</data>
<data name="ErrorUpdateNoAssetForThisBinary" xml:space="preserve">
<value>Kan niet verdergaan met update omdat er geen bezit is dat gerelateerd is aan de momenteel actieve binary! Controleer of de ASF Binary de juiste naam heeft!</value>
<value>Kon niet verdergaan met updaten omdat er geen bestand bestaat dat gerelateerd is aan de momenteel actieve binary! Controleer of de ASF binary de juiste naam heeft!</value>
</data>
<data name="ErrorUpdateNoAssets" xml:space="preserve">
<value>Kan niet verdergaan met update omdat deze versie niet alle bestanden omvat!</value>
</data>
<data name="ErrorUserInputRunningInHeadlessMode" xml:space="preserve">
<value>Aanvraag voor gebruikersinvoer gekregen, maar het proces draait momenteel in headless mode!</value>
<value>Aanvraag voor gebruikersinvoer ontvangen, maar het proces draait in headless mode!</value>
</data>
<data name="ErrorWCFAccessDenied" xml:space="preserve">
<value>Het verzoek wordt niet in behandeling genomen omdat SteamOwnerID niet is ingesteld!</value>
@@ -203,13 +203,13 @@ StackTrace:
<value>Mislukt!</value>
</data>
<data name="GlobalConfigChanged" xml:space="preserve">
<value>Globale configuratie bestand is gewijzigd!</value>
<value>Globaal configuratiebestand is aangepast!</value>
</data>
<data name="ErrorGlobalConfigRemoved" xml:space="preserve">
<value>Globale configuratie bestand is verwijderd!</value>
<value>Globaal configuratiebestand is verwijderd!</value>
</data>
<data name="IgnoringTrade" xml:space="preserve">
<value>Trade wordt genegeerd: {0}</value>
<value>Ruilaanbieding {0} wordt genegeerd</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="LoggingIn" xml:space="preserve">
@@ -217,23 +217,23 @@ StackTrace:
<comment>{0} will be replaced by service's name</comment>
</data>
<data name="NoBotsAreRunning" xml:space="preserve">
<value>Er zijn geen bots actief, afsluiten...</value>
<value>Geen bots actief, afsluiten...</value>
</data>
<data name="RefreshingOurSession" xml:space="preserve">
<value>Sessie wordt ververst!</value>
</data>
<data name="RejectingTrade" xml:space="preserve">
<value>Trade wordt afgekeurd: {0}</value>
<value>Ruilaanbieding {0} wordt afgekeurd</value>
<comment>{0} will be replaced by trade number</comment>
</data>
<data name="Restarting" xml:space="preserve">
<value>Herstarten...</value>
</data>
<data name="WarningRuntimeUnsupported" xml:space="preserve">
<value>ASF heeft een niet ondersteunde runtime versie gedetecteerd, het programma kan mogelijk NIET correct worden uitgevoerd in de huidige omgeving. Je voert dit met je eigen risico uit zonder ondersteuning!</value>
<value>ASF heeft een niet ondersteunde runtime versie gedetecteerd, het programma kan mogelijk NIET correct worden uitgevoerd in de huidige omgeving. Je voert dit met eigen risico en zonder ondersteuning uit!</value>
</data>
<data name="RuntimeVersionComparison" xml:space="preserve">
<value>Benodigde versie: {0} | Gevonden versie: {1}</value>
<value>Vereiste versie: {0} | Gevonden versie: {1}</value>
<comment>{0} will be replaced by required version, {1} will be replaced by current version</comment>
</data>
<data name="RuntimeVersionOK" xml:space="preserve">
@@ -289,13 +289,13 @@ StackTrace:
<value>Controleren op nieuwe versie...</value>
</data>
<data name="UpdateDownloadingNewVersion" xml:space="preserve">
<value>Nieuwe versie wordt gedownloadt.... Terwijl je aan het wachten bent, het wordt heel veel gewaardeerd als je een donatie geeft</value>
<value>Nieuwe versie wordt gedownloadt... Onder het wachten, overweeg te doneren als je het gedane werk waardeert! :)</value>
</data>
<data name="UpdateFinished" xml:space="preserve">
<value>Bijwerken afgerond!</value>
</data>
<data name="UpdateNewVersionAvailable" xml:space="preserve">
<value>Nieuwe ASF versie beschikbaar! Overweeg om handmatig bij te werken!</value>
<value>Nieuwe ASF-versie beschikbaar! Overweeg zelf bij te werken!</value>
</data>
<data name="UpdateVersionInfo" xml:space="preserve">
<value>Lokale versie: {0} | Externe versie: {1}</value>
@@ -696,4 +696,8 @@ StackTrace:
<value>ASF probeert de {0} taal te gebruiken, maar het vertalen in deze taal was tot {1} compleet. Misschien kan 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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Idling {0} ({1}) is tijdelijk uitgeschakeld, aangezien dat spel nog niet was uitgegeven.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -363,4 +363,5 @@
</root>

View File

@@ -697,4 +697,8 @@ StackTrace:
<value>ASF spróbuje użyć twojej preferowanej kultury {0}, ale tłumaczenie w tym języku zostało ukończone tylko w {1}. Być może mógłbyś pomóc nam w poprawieniu tłumaczenia ASF na Twój język?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Farmienie {0} ({1}) jest tymczasowo niemożliwe, jako że ta gra nie została jeszcze wydana.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -126,11 +126,12 @@
<comment>{0} will be replaced by number of hours</comment>
</data>
<data name="Content" xml:space="preserve">
<value>Conteúdo: {0}</value>
<value>Conteúdo:
{0}</value>
<comment>{0} will be replaced by content string. Please note that this string should include newline for formatting.</comment>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Configuração {0} inválida com a propriedade: {1}</value>
<value>A propriedade {0} possui valor inválido: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorEarlyFatalExceptionInfo" xml:space="preserve">
@@ -169,7 +170,7 @@ StackTrace:
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorParsingObject" xml:space="preserve">
<value>Falha em analisar o {0}!</value>
<value>Falha ao analisar {0}!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorRemovingOldBinary" xml:space="preserve">
@@ -302,7 +303,7 @@ StackTrace:
<comment>{0} will be replaced by current version, {1} will be replaced by remote version</comment>
</data>
<data name="UserInputDeviceID" xml:space="preserve">
<value>&lt;{0}&gt; Insira seu ID do dispositivo (incluindo "android:"): </value>
<value>&lt;{0}&gt; Insira o ID do dispositivo do autenticador móvel (incluindo "android:"): </value>
<comment>{0} will be replaced by bot's name. Please note that this translation should end with space</comment>
</data>
<data name="UserInputSteam2FA" xml:space="preserve">
@@ -353,18 +354,18 @@ StackTrace:
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF answer</comment>
</data>
<data name="WCFReady" xml:space="preserve">
<value>O servidor WCF está pronto!</value>
<value>Servidor WCF pronto!</value>
</data>
<data name="WCFResponseReceived" xml:space="preserve">
<value>Resposta do WCF recebida: {0}</value>
<comment>{0} will be replaced by WCF response</comment>
</data>
<data name="WCFSendingCommand" xml:space="preserve">
<value>Enviando o comando: {0} para o servidor WCF no {1}...</value>
<value>Enviando comando: {0} para o servidor WCF em {1}...</value>
<comment>{0} will be replaced by WCF command, {1} will be replaced by WCF hostname</comment>
</data>
<data name="WCFStarting" xml:space="preserve">
<value>Iniciando o servidor WCF em {0}...</value>
<value>Iniciando servidor WCF em {0}...</value>
<comment>{0} will be replaced by WCF hostname</comment>
</data>
<data name="BotAlreadyStopped" xml:space="preserve">
@@ -411,7 +412,7 @@ StackTrace:
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name, {2} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="IdlingFinishedForGames" xml:space="preserve">
<value>Finalizado o processo de receber cartas dos jogos: {0}</value>
<value>Finalizada a coleta de cartas dos jogos: {0}</value>
<comment>{0} will be replaced by list of the games (appIDs, numbers), separated by a comma</comment>
</data>
<data name="IdlingStatusForGame" xml:space="preserve">
@@ -422,7 +423,7 @@ StackTrace:
<value>Coleta de cartas interrompida!</value>
</data>
<data name="IgnoredStickyPauseEnabled" xml:space="preserve">
<value>Ignorando esse pedido, já que o pause manual está habilitado!</value>
<value>Ignorando esse pedido, já que a pausa forçada está habilitada!</value>
</data>
<data name="NothingToIdle" xml:space="preserve">
<value>Não temos cartas disponíveis nesta conta!</value>
@@ -497,7 +498,7 @@ StackTrace:
<comment>{0} will be replaced by generated 2FA token (string)</comment>
</data>
<data name="BotAutomaticIdlingNowPaused" xml:space="preserve">
<value>Processo automático de receber cartas está agora pausado!</value>
<value>A coleta automática de cartas foi pausada!</value>
</data>
<data name="BotAutomaticIdlingNowResumed" xml:space="preserve">
<value>A coleta automática de cartas foi retomada!</value>
@@ -696,4 +697,8 @@ StackTrace:
<value>O ASF tentará usar seu preferido {0} idle, mas a tradução para este idioma foi concluída somente em {1}. Talvez você possa nos ajudar a melhorar a tradução do ASF ao seu idioma?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>A execução de {0} ({1}) está temporariamente desativada, visto que esse jogo não foi lançado ainda.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -692,4 +692,5 @@ inválidas, abortando!</value>
<value>Seu CurrentCulture fornecido é inválido, ASF continuará a funcionar com o predefinido!</value>
</data>
</root>

View File

@@ -697,4 +697,8 @@ StackTrace:
<value>ASF will attempt to use your preferred {0} culture, but translation in that language was completed only in {1}. Perhaps you could help us improve ASF translation for your language?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Idling {0} ({1}) is temporarily disabled, as that game was not released yet.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -697,4 +697,8 @@ StackTrace:
<value>ASF va încerca să utilizeze cultura {0} preferată de tine, dar traducerea în această limbă a fost completată în proporție de {1}. Poate că ai putea ajuta la îmbunatățirea traducerii ASF pentru limba ta?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Farmatul {0} ({1}) este dezactivat temporar, deoarece acest joc nu a fost încă lansat.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -384,7 +384,7 @@
<comment>{0} will be replaced by bot's name, {1} will be replaced by game's appID (number), {2} will be replaced by game's name, {3} will be replaced by number of cards left to idle, {4} will be replaced by total number of games to idle, {5} will be replaced by total number of cards to idle, {6} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="BotStatusIdlingList" xml:space="preserve">
<value>Бот {0} фармит игры: {1}. Всего {2} игр ({3} карт) осталось фармить (займет примерно {4}).</value>
<value>Бот {0} фармит игры: {1}. Всего осталось {2} игр ({3} карт, ~{4} осталось).</value>
<comment>{0} will be replaced by bot's name, {1} will be replaced by list of the games (appIDs, numbers), {2} will be replaced by total number of games to idle, {3} will be replaced by total number of cards to idle, {4} will be replaced by translated TimeSpan string built from TimeSpan* translation parts</comment>
</data>
<data name="CheckingFirstBadgePage" xml:space="preserve">
@@ -697,4 +697,8 @@
<value>ASF будет пытаться использовать выбранный язык {0}, но перевод готов только на {1}. Возможно, Вы могли бы помочь улучшить перевод ASF на данный язык?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Фарм {0} ({1}) временно невозможен, потому что эта игра ещё не вышла.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -697,4 +697,5 @@ StackTrace:
<value>ASF će pokušati da koristi vašu preferiranu {0} "kulturu", ali prevod u taj jezik je samo {1} gotov. Možda bi ste mogli da nam pomogne u prevodu ASF na vaš jezik?</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>
</root>

View File

@@ -290,6 +290,7 @@
</root>

View File

@@ -395,7 +395,7 @@ StackTrace:
<value>Kollar andra märkessidor...</value>
</data>
<data name="ChosenFarmingAlgorithm" xml:space="preserve">
<value>Vald farm algoritm: {0}</value>
<value>Vald farmning algoritm: {0}</value>
<comment>{0} will be replaced by the name of chosen idling algorithm</comment>
</data>
<data name="Done" xml:space="preserve">
@@ -694,5 +694,12 @@ StackTrace:
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>Din angivna CurrentCulture är ogiltlig, ASF kommer fortsätta köras med standardvärdet!</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>ASF kommer försöka att använda din föredragna {0}, men den översättningen är endast {1} färdig. Du kanske kan hjälpa oss att förbättra ASF översättningarna för ditt språk?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Farmning {0} ({1}) är tillfälligt inaktiverad, då spelet inte är släppt ännu.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -278,6 +278,7 @@
</root>

View File

@@ -693,5 +693,12 @@ Hata bilgileri:
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>Sağlanan CurrentCulture geçersiz, ASF varsayılan ile çalışmaya devam edecek!</value>
</data>
<data name="TranslationIncomplete" xml:space="preserve">
<value>ASF tercih ettiğiniz {0} kültürünü kullanmaya çalışacak, ancak o dildeki çeviri yalnızca {1} içinde tamamlandı. Diliniz için ASF çevirisini geliştirmemize belki de yardımcı olabilir misiniz?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Rölantide {0} ({1}) geçici olarak devre dışı bırakıldı, Bu oyun henüz çıkış yapmadı.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -566,10 +566,10 @@
<value>Обмін надісланий!</value>
</data>
<data name="BotLootingTemporarilyDisabled" xml:space="preserve">
<value>Лутінг тимчасово відключений!</value>
<value>Збір предметів тимчасово відключений!</value>
</data>
<data name="BotLootingYourself" xml:space="preserve">
<value>Ви не можете лутати себе!</value>
<value>Неможливо збирати предмети з самого себе!</value>
</data>
<data name="BotNoASFAuthenticator" xml:space="preserve">
<value>Цей бот не має включеного ASF 2FA! Забули імпортувати автентифікатор у ASF 2FA?</value>
@@ -609,7 +609,7 @@
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusLimited" xml:space="preserve">
<value>Бот {0} має обмеження і не може ідліти карти.</value>
<value>Бот {0} має обмеження і не може отримувати карти.</value>
<comment>{0} will be replaced by bot's name</comment>
</data>
<data name="BotStatusNotConnected" xml:space="preserve">
@@ -652,13 +652,13 @@
<value>Підключення до мережі Steam втрачено, повторне підключення...</value>
</data>
<data name="BotAccountFree" xml:space="preserve">
<value>Аккаунт більше не зайнятий, іділінг відновлено!</value>
<value>Аккаунт більше не зайнятий, роботу відновлено!</value>
</data>
<data name="BotAccountOccupied" xml:space="preserve">
<value>Акаунт зараз використовується, ASF продовжить коли аккаунт звільниться...</value>
</data>
<data name="BotAutomaticIdlingPauseTimeout" xml:space="preserve">
<value>Сімейна бібліотека не була запущена у відведений період часу, фарм відновлено!</value>
<value>Сімейна бібліотека не була запущена у відведений період часу, роботу відновлено!</value>
</data>
<data name="BotConnecting" xml:space="preserve">
<value>Підключення...</value>
@@ -697,4 +697,8 @@
<value>ASF намагатиметься використовувати обрану мову {0}, але переклад на цю мову завершено лише на {1}. Можливо ви б змогли допомогти в перекладі ASF вашою мовою?</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>Обробка {0} ({1}) тимчасово неможлива, тому що ця гра ще не була випущена.</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -697,4 +697,5 @@ StackTrace:
<value>ASF sẽ cố gắng sử dụng mã ngôn ngữ {0} ưa thích của bạn, nhưng bản dịch ngôn ngữ đó hoàn thiện chỉ được {1}. Có lẽ bạn có thể giúp chúng tôi cải thiện bản dịch ASF cho ngôn ngữ của bạn?</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>
</root>

View File

@@ -694,4 +694,8 @@
<value>ASF将尝试使用您偏好的语言{0},但该语言当前的翻译完成度为{1}。或许你可以帮助我们改进ASF的翻译</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>{0} ({1}) 的挂卡暂时不可用,因为该游戏尚未发布。</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -694,4 +694,8 @@
<value>ASF 將使用您的偏好語系 {0} ,但該語言的翻譯只完成了 {1}。請協助我們改進 ASF 的翻譯品質。</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="IdlingGameNotReleasedYet" xml:space="preserve">
<value>掛卡 {0} ({1}) 已暫時停止,因為該遊戲尚未發行。</value>
<comment>{0} will be replaced by game's appID (number), {1} will be replaced by game's name</comment>
</data>
</root>

View File

@@ -46,10 +46,21 @@ namespace ArchiSteamFarm {
private static short? SteamTimeDifference;
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR"); // "ERROR" is being used by SteamDesktopAuthenticator
// "ERROR" is being used by SteamDesktopAuthenticator
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR");
private readonly SemaphoreSlim ConfirmationsSemaphore = new SemaphoreSlim(1);
#pragma warning disable 649
[JsonProperty(PropertyName = "identity_secret", Required = Required.Always)]
private readonly string IdentitySecret;
#pragma warning restore 649
#pragma warning disable 649
[JsonProperty(PropertyName = "shared_secret", Required = Required.Always)]
private readonly string SharedSecret;
#pragma warning restore 649
private Bot Bot;
[JsonProperty(PropertyName = "device_id")]
@@ -251,7 +262,15 @@ namespace ArchiSteamFarm {
return null;
}
byte[] identitySecret = Convert.FromBase64String(IdentitySecret);
byte[] identitySecret;
try {
identitySecret = Convert.FromBase64String(IdentitySecret);
} catch (FormatException e) {
Bot.ArchiLogger.LogGenericException(e);
Bot.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(IdentitySecret)));
return null;
}
byte bufferSize = 8;
if (!string.IsNullOrEmpty(tag)) {
@@ -284,7 +303,15 @@ namespace ArchiSteamFarm {
return null;
}
byte[] sharedSecret = Convert.FromBase64String(SharedSecret);
byte[] sharedSecret;
try {
sharedSecret = Convert.FromBase64String(SharedSecret);
} catch (FormatException e) {
Bot.ArchiLogger.LogGenericException(e);
Bot.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(SharedSecret)));
return null;
}
byte[] timeArray = BitConverter.GetBytes((long) time / CodeInterval);
if (BitConverter.IsLittleEndian) {
@@ -357,13 +384,5 @@ namespace ArchiSteamFarm {
Type = type;
}
}
#pragma warning disable 649
[JsonProperty(PropertyName = "shared_secret", Required = Required.Always)]
private readonly string SharedSecret;
[JsonProperty(PropertyName = "identity_secret", Required = Required.Always)]
private readonly string IdentitySecret;
#pragma warning restore 649
}
}

69
ArchiSteamFarm/OS.cs Normal file
View File

@@ -0,0 +1,69 @@
/*
_ _ _ ____ _ _____
/ \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
/ _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
/ ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
Copyright 2015-2017 Ł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;
using System.Runtime.InteropServices;
using ArchiSteamFarm.Localization;
namespace ArchiSteamFarm {
internal static class OS {
private static readonly PlatformID PlatformID = Environment.OSVersion.Platform;
internal static void Init() {
switch (PlatformID) {
case PlatformID.Win32NT:
case PlatformID.Win32S:
case PlatformID.Win32Windows:
case PlatformID.WinCE:
KeepWindowsSystemActive();
break;
}
}
private static void KeepWindowsSystemActive() {
// This function calls unmanaged API in order to tell Windows OS that it should not enter sleep state while the program is running
// If user wishes to enter sleep mode, then he should use ShutdownOnFarmingFinished or manage ASF process with third-party tool or script
// More info: https://msdn.microsoft.com/library/windows/desktop/aa373208(v=vs.85).aspx
EExecutionState result = SetThreadExecutionState(EExecutionState.Continuous | EExecutionState.AwayModeRequired | EExecutionState.SystemRequired);
// SetThreadExecutionState() returns NULL on failure, which is mapped to 0 (EExecutionState.Error) in our case
if (result == EExecutionState.Error) {
ASF.ArchiLogger.LogGenericError(string.Format(Strings.WarningFailedWithError, result));
}
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern EExecutionState SetThreadExecutionState(EExecutionState executionState);
[Flags]
private enum EExecutionState : uint {
Error = 0,
SystemRequired = 0x00000001,
// DisplayRequired = 0x00000002,
// UserPresent = 0x00000004,
AwayModeRequired = 0x00000040,
Continuous = 0x80000000
}
}
}

View File

@@ -52,12 +52,12 @@ namespace ArchiSteamFarm {
private static bool ShutdownSequenceInitialized;
internal static void Exit(byte exitCode = 0) {
internal static async Task Exit(byte exitCode = 0) {
if (exitCode != 0) {
ASF.ArchiLogger.LogGenericError(Strings.ErrorExitingWithNonZeroErrorCode);
}
Shutdown();
await Shutdown().ConfigureAwait(false);
Environment.Exit(exitCode);
}
@@ -114,8 +114,8 @@ namespace ArchiSteamFarm {
return !string.IsNullOrEmpty(result) ? result.Trim() : null;
}
internal static void Restart() {
if (!InitShutdownSequence()) {
internal static async Task Restart() {
if (!await InitShutdownSequence().ConfigureAwait(false)) {
return;
}
@@ -130,15 +130,61 @@ namespace ArchiSteamFarm {
}
private static async Task Init(string[] args) {
// We must register our logging target as soon as possible
Target.Register<SteamTarget>("Steam");
await InitCore(args).ConfigureAwait(false);
}
private static async Task InitCore(string[] args) {
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
// We must register our logging target as soon as possible
Target.Register<SteamTarget>("Steam");
InitCore(args);
await InitASF(args).ConfigureAwait(false);
}
private static async Task InitASF(string[] args) {
ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
await InitGlobalConfigAndLanguage().ConfigureAwait(false);
if (!Runtime.IsRuntimeSupported) {
ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported);
await Task.Delay(60 * 1000).ConfigureAwait(false);
}
await InitGlobalDatabaseAndServices().ConfigureAwait(false);
// If debugging is on, we prepare debug directory prior to running
if (GlobalConfig.Debug) {
if (Directory.Exists(SharedInfo.DebugDirectory)) {
try {
Directory.Delete(SharedInfo.DebugDirectory, true);
await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
} catch (IOException e) {
ASF.ArchiLogger.LogGenericException(e);
}
}
Directory.CreateDirectory(SharedInfo.DebugDirectory);
DebugLog.AddListener(new Debugging.DebugListener());
DebugLog.Enabled = true;
}
// Parse post-init args
if (args != null) {
await ParsePostInitArgs(args).ConfigureAwait(false);
}
// If we ran ASF as a client, we're done by now
if (Mode.HasFlag(EMode.Client) && !Mode.HasFlag(EMode.Server)) {
await Exit().ConfigureAwait(false);
}
await ASF.CheckForUpdate().ConfigureAwait(false);
await ASF.InitBots().ConfigureAwait(false);
ASF.InitFileWatcher();
}
private static void InitCore(string[] args) {
string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
if (!string.IsNullOrEmpty(homeDirectory)) {
Directory.SetCurrentDirectory(homeDirectory);
@@ -166,55 +212,16 @@ namespace ArchiSteamFarm {
}
Logging.InitLoggers();
ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
await InitServices().ConfigureAwait(false);
if (!Runtime.IsRuntimeSupported) {
ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported);
await Task.Delay(10 * 1000).ConfigureAwait(false);
}
// If debugging is on, we prepare debug directory prior to running
if (GlobalConfig.Debug) {
if (Directory.Exists(SharedInfo.DebugDirectory)) {
try {
Directory.Delete(SharedInfo.DebugDirectory, true);
await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
} catch (IOException e) {
ASF.ArchiLogger.LogGenericException(e);
}
}
Directory.CreateDirectory(SharedInfo.DebugDirectory);
DebugLog.AddListener(new Debugging.DebugListener());
DebugLog.Enabled = true;
}
// Parse post-init args
if (args != null) {
await ParsePostInitArgs(args).ConfigureAwait(false);
}
// If we ran ASF as a client, we're done by now
if (Mode.HasFlag(EMode.Client) && !Mode.HasFlag(EMode.Server)) {
Exit();
}
await ASF.CheckForUpdate().ConfigureAwait(false);
await ASF.InitBots().ConfigureAwait(false);
ASF.InitFileWatcher();
}
private static async Task InitServices() {
private static async Task InitGlobalConfigAndLanguage() {
string globalConfigFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName);
GlobalConfig = GlobalConfig.Load(globalConfigFile);
if (GlobalConfig == null) {
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorGlobalConfigNotLoaded, globalConfigFile));
await Task.Delay(5 * 1000).ConfigureAwait(false);
Exit(1);
await Exit(1).ConfigureAwait(false);
return;
}
@@ -228,24 +235,29 @@ namespace ArchiSteamFarm {
}
}
int defaultResourceSetCount = 0;
int currentResourceSetCount = 0;
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CreateSpecificCulture("en-US"), true, true);
ushort defaultResourceSetCount = 0;
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true);
if (defaultResourceSet != null) {
defaultResourceSetCount = defaultResourceSet.Cast<object>().Count();
defaultResourceSetCount = (ushort) defaultResourceSet.Cast<object>().Count();
}
if (defaultResourceSetCount == 0) {
return;
}
ushort currentResourceSetCount = 0;
ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, false);
if (currentResourceSet != null) {
currentResourceSetCount = currentResourceSet.Cast<object>().Count();
currentResourceSetCount = (ushort) currentResourceSet.Cast<object>().Count();
}
if (currentResourceSetCount < defaultResourceSetCount) {
float translationCompleteness = currentResourceSetCount / (float) defaultResourceSetCount;
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.TranslationIncomplete, CultureInfo.CurrentCulture.Name, translationCompleteness.ToString("P1")));
}
}
private static async Task InitGlobalDatabaseAndServices() {
string globalDatabaseFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName);
if (!File.Exists(globalDatabaseFile)) {
@@ -258,18 +270,19 @@ namespace ArchiSteamFarm {
if (GlobalDatabase == null) {
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile));
await Task.Delay(5 * 1000).ConfigureAwait(false);
Exit(1);
await Exit(1).ConfigureAwait(false);
return;
}
ArchiWebHandler.Init();
WebBrowser.Init();
OS.Init();
WCF.Init();
WebBrowser.Init();
WebBrowser = new WebBrowser(ASF.ArchiLogger);
}
private static bool InitShutdownSequence() {
private static async Task<bool> InitShutdownSequence() {
if (ShutdownSequenceInitialized) {
return false;
}
@@ -277,9 +290,9 @@ namespace ArchiSteamFarm {
ShutdownSequenceInitialized = true;
WCF.StopServer();
foreach (Bot bot in Bot.Bots.Values) {
bot.Stop();
}
IEnumerable<Task> tasks = Bot.Bots.Values.Select(bot => Task.Run(() => bot.Stop()));
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(10 * 1000));
return true;
}
@@ -293,7 +306,7 @@ namespace ArchiSteamFarm {
ShutdownResetEvent.Wait();
// We got a signal to shutdown
Exit();
Exit().Wait();
} else {
// Service
IsRunningAsService = true;
@@ -371,22 +384,23 @@ namespace ArchiSteamFarm {
}
}
private static void Shutdown() {
if (!InitShutdownSequence()) {
private static async Task Shutdown() {
if (!await InitShutdownSequence().ConfigureAwait(false)) {
return;
}
ShutdownResetEvent.Set();
}
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
private static async void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
if (args?.ExceptionObject == null) {
ASF.ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.ExceptionObject));
return;
}
ASF.ArchiLogger.LogFatalException((Exception) args.ExceptionObject);
Exit(1);
await Task.Delay(5000).ConfigureAwait(false);
await Exit(1).ConfigureAwait(false);
}
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
@@ -396,7 +410,8 @@ namespace ArchiSteamFarm {
}
ASF.ArchiLogger.LogFatalException(args.Exception);
Exit(1);
// Normally we should abort the application here, but many tasks are in fact failing in SK2 code which we can't easily fix
// Thanks Valve.
}
[Flags]
@@ -422,7 +437,7 @@ namespace ArchiSteamFarm {
Stop();
});
protected override void OnStop() => Shutdown();
protected override async void OnStop() => await Shutdown().ConfigureAwait(false);
}
}
}

View File

@@ -44,7 +44,7 @@ namespace ArchiSteamFarm {
internal const string ServiceDescription = "ASF is an application that allows you to farm steam cards using multiple steam accounts simultaneously.";
internal const string ServiceName = "ArchiSteamFarm";
internal const string StatisticsServer = "asf.justarchi.net";
internal const string VersionNumber = "2.2.1.8";
internal const string VersionNumber = "2.2.2.5";
internal static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
}

View File

@@ -24,14 +24,16 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.JSON;
using SteamKit2;
namespace ArchiSteamFarm {
internal sealed class Statistics : IDisposable {
private const byte MinHeartBeatTTL = 5; // Minimum amount of minutes we must wait before sending next HeartBeat
private const byte MinHeartBeatTTL = 10; // Minimum amount of minutes we must wait before sending next HeartBeat
private static readonly SemaphoreSlim InitializationSemaphore = new SemaphoreSlim(1);
@@ -85,6 +87,7 @@ namespace ArchiSteamFarm {
internal async Task OnLoggedOn() => await Bot.ArchiWebHandler.JoinGroup(SharedInfo.ASFGroupSteamID).ConfigureAwait(false);
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
internal async Task OnPersonaState(SteamFriends.PersonaStateCallback callback) {
if (callback == null) {
ASF.ArchiLogger.LogNullError(nameof(callback));
@@ -92,17 +95,17 @@ namespace ArchiSteamFarm {
}
// Don't announce if we don't meet conditions
if (!Bot.HasMobileAuthenticator || !Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher) || !await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false)) {
if (!Bot.HasMobileAuthenticator || !Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher) || !await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false) || !await Bot.ArchiWebHandler.HasPublicInventory().ConfigureAwait(false)) {
ShouldSendHeartBeats = false;
return;
}
string nickname = callback.Name ?? "";
string avatarHash = "";
string avatarHash = "";
if ((callback.AvatarHash != null) && (callback.AvatarHash.Length > 0) && callback.AvatarHash.Any(singleByte => singleByte != 0)) {
avatarHash = BitConverter.ToString(callback.AvatarHash).Replace("-", "").ToLowerInvariant();
if (avatarHash.Equals("0000000000000000000000000000000000000000")) {
if (avatarHash.All(singleChar => singleChar == '0')) {
avatarHash = "";
}
}
@@ -110,7 +113,7 @@ namespace ArchiSteamFarm {
bool matchEverything = Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchEverything);
// Skip announcing if we already announced this bot with the same data
if (!string.IsNullOrEmpty(LastNickname) && nickname.Equals(LastNickname) && !string.IsNullOrEmpty(LastAvatarHash) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
if (ShouldSendHeartBeats && (LastNickname != null) && nickname.Equals(LastNickname) && (LastAvatarHash != null) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
return;
}
@@ -118,7 +121,16 @@ namespace ArchiSteamFarm {
try {
// Skip announcing if we already announced this bot with the same data
if (!string.IsNullOrEmpty(LastNickname) && nickname.Equals(LastNickname) && !string.IsNullOrEmpty(LastAvatarHash) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
if (ShouldSendHeartBeats && (LastNickname != null) && nickname.Equals(LastNickname) && (LastAvatarHash != null) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) {
return;
}
await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false);
HashSet<Steam.Item> inventory = await Bot.ArchiWebHandler.GetMySteamInventory(true, new HashSet<Steam.Item.EType> { Steam.Item.EType.TradingCard }).ConfigureAwait(false);
if ((inventory == null) || (inventory.Count == 0)) {
// Don't announce, we have empty inventory
ShouldSendHeartBeats = false;
return;
}
@@ -126,12 +138,13 @@ namespace ArchiSteamFarm {
ShouldSendHeartBeats = true;
string request = await GetURL().ConfigureAwait(false) + "/api/Announce";
Dictionary<string, string> data = new Dictionary<string, string>(5) {
Dictionary<string, string> data = new Dictionary<string, string>(6) {
{ "SteamID", Bot.SteamID.ToString() },
{ "Guid", Program.GlobalDatabase.Guid.ToString("N") },
{ "Nickname", nickname },
{ "AvatarHash", avatarHash },
{ "MatchEverything", matchEverything ? "1" : "0" }
{ "MatchEverything", matchEverything ? "1" : "0" },
{ "CardsCount", inventory.Count.ToString() }
};
// We don't need retry logic here

View File

@@ -51,10 +51,7 @@ namespace ArchiSteamFarm {
Bot = bot;
}
public void Dispose() {
IgnoredTrades.Dispose();
TradesSemaphore.Dispose();
}
public void Dispose() => TradesSemaphore.Dispose();
internal async Task CheckTrades() {
// We aim to have a maximum of 2 tasks, one already parsing, and one waiting in the queue
@@ -192,7 +189,7 @@ namespace ArchiSteamFarm {
// If it's steam fuckup, temporarily ignore it, otherwise react accordingly, depending on our preference
if (tradeOffer.ItemsToReceive.Count == 0) {
donationResult = ParseTradeResult.EResult.RejectedTemporarily;
} else if (Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.AcceptDonations) || ((tradeOffer.OtherSteamID64 != 0) && Bot.Bots.Values.Any(bot => bot.SteamID == tradeOffer.OtherSteamID64))) {
} else if (Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.AcceptDonations) || (!Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.DontAcceptBotTrades) && (tradeOffer.OtherSteamID64 != 0) && Bot.Bots.Values.Any(bot => bot.SteamID == tradeOffer.OtherSteamID64))) {
donationResult = ParseTradeResult.EResult.AcceptedWithoutItemLose;
} else {
donationResult = ParseTradeResult.EResult.RejectedPermanently;

View File

@@ -39,8 +39,6 @@ namespace ArchiSteamFarm {
}
internal sealed class WCF : IWCF, IDisposable {
private static string URL = "net.tcp://127.0.0.1:1242/ASF";
internal bool IsServerRunning => ServiceHost != null;
private Client Client;
@@ -68,11 +66,13 @@ namespace ArchiSteamFarm {
return Strings.ErrorNoBotsDefined;
}
string command = "!" + input;
if (input[0] != '!') {
input = "!" + input;
}
// TODO: This should be asynchronous, but for some reason Mono doesn't return any WCF output if it is
// We must keep it synchronous until either Mono gets fixed, or culprit for freeze located (and corrected)
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, command).Result;
string output = bot.Response(Program.GlobalConfig.SteamOwnerID, input).Result;
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFAnswered, input, output));
return output;
@@ -81,12 +81,7 @@ namespace ArchiSteamFarm {
internal static void Init() {
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHost)) {
Program.GlobalConfig.WCFHost = Program.GetUserInput(ASF.EUserInputType.WCFHostname);
if (string.IsNullOrEmpty(Program.GlobalConfig.WCFHost)) {
return;
}
}
URL = "net.tcp://" + Program.GlobalConfig.WCFHost + ":" + Program.GlobalConfig.WCFPort + "/ASF";
}
internal string SendCommand(string input) {
@@ -95,17 +90,24 @@ namespace ArchiSteamFarm {
return null;
}
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFSendingCommand, input, URL));
Binding binding = GetTargetBinding();
if (binding == null) {
ASF.ArchiLogger.LogNullError(nameof(binding));
return null;
}
string url = GetUrlFromBinding(binding);
if (string.IsNullOrEmpty(url)) {
ASF.ArchiLogger.LogNullError(nameof(url));
return null;
}
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFSendingCommand, input, url));
if (Client == null) {
Client = new Client(
new NetTcpBinding {
// We use SecurityMode.None for Mono compatibility
// Yes, also on Windows, for Mono<->Windows communication
Security = { Mode = SecurityMode.None },
SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.ConnectionTimeout)
},
new EndpointAddress(URL)
binding,
new EndpointAddress(url)
);
}
@@ -117,20 +119,28 @@ namespace ArchiSteamFarm {
return;
}
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFStarting, URL));
Binding binding = GetTargetBinding();
if (binding == null) {
ASF.ArchiLogger.LogNullError(nameof(binding));
return;
}
string url = GetUrlFromBinding(binding);
if (string.IsNullOrEmpty(url)) {
ASF.ArchiLogger.LogNullError(nameof(url));
return;
}
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.WCFStarting, url));
try {
ServiceHost = new ServiceHost(typeof(WCF), new Uri(URL));
ServiceHost = new ServiceHost(typeof(WCF), new Uri(url));
ServiceHost.AddServiceEndpoint(
typeof(IWCF),
new NetTcpBinding {
// We use SecurityMode.None for Mono compatibility
// Yes, also on Windows, for Mono<->Windows communication
Security = { Mode = SecurityMode.None },
SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.ConnectionTimeout)
},
binding,
string.Empty
);
ServiceHost.Open();
ASF.ArchiLogger.LogGenericInfo(Strings.WCFReady);
@@ -157,6 +167,46 @@ namespace ArchiSteamFarm {
ServiceHost = null;
}
private static Binding GetTargetBinding() {
Binding result;
switch (Program.GlobalConfig.WCFBinding) {
case GlobalConfig.EWCFBinding.NetTcp:
result = new NetTcpBinding {
// We use SecurityMode.None for Mono compatibility
// Yes, also on Windows, for Mono<->Windows communication
Security = { Mode = SecurityMode.None }
};
break;
case GlobalConfig.EWCFBinding.BasicHttp:
result = new BasicHttpBinding();
break;
case GlobalConfig.EWCFBinding.WSHttp:
result = new WSHttpBinding {
// We use SecurityMode.None for Mono compatibility
// Yes, also on Windows, for Mono<->Windows communication
Security = { Mode = SecurityMode.None }
};
break;
default:
ASF.ArchiLogger.LogGenericWarning(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(Program.GlobalConfig.WCFBinding), Program.GlobalConfig.WCFBinding));
goto case GlobalConfig.EWCFBinding.NetTcp;
}
result.SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.ConnectionTimeout);
return result;
}
private static string GetUrlFromBinding(Binding binding) {
if (binding != null) {
return binding.Scheme + "://" + Program.GlobalConfig.WCFHost + ":" + Program.GlobalConfig.WCFPort + "/ASF";
}
ASF.ArchiLogger.LogNullError(nameof(binding));
return null;
}
private void StopClient() {
if (Client == null) {
return;

View File

@@ -81,12 +81,24 @@ namespace ArchiSteamFarm {
// Therefore, call mono-incompatible options in their own function to avoid that, and just leave the function call here
// When compiling on Mono, this section is omitted entirely as we never run Mono-compiled ASF on Windows
// Moreover, Mono compiler doesn't even include ReusePort field in ServicePointManager, so it's crucial to avoid compilation error
if (Runtime.IsRuntimeSupported && !Runtime.IsRunningOnMono) {
if (!Runtime.IsRunningOnMono) {
InitNonMonoBehaviour();
}
#endif
}
internal static HtmlDocument StringToHtmlDocument(string html) {
if (string.IsNullOrEmpty(html)) {
ASF.ArchiLogger.LogNullError(nameof(html));
return null;
}
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html);
return htmlDocument;
}
internal async Task<byte[]> UrlGetToBytesRetry(string request, string referer = null) {
if (string.IsNullOrEmpty(request)) {
ArchiLogger.LogNullError(nameof(request));
@@ -264,13 +276,7 @@ namespace ArchiSteamFarm {
}
string content = await UrlPostToContentRetry(request, data, referer).ConfigureAwait(false);
if (string.IsNullOrEmpty(content)) {
return null;
}
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(content);
return htmlDocument;
return !string.IsNullOrEmpty(content) ? StringToHtmlDocument(content) : null;
}
internal async Task<T> UrlPostToJsonResultRetry<T>(string request, ICollection<KeyValuePair<string, string>> data = null, string referer = null) {
@@ -353,13 +359,7 @@ namespace ArchiSteamFarm {
}
string content = await UrlGetToContent(request, referer).ConfigureAwait(false);
if (string.IsNullOrEmpty(content)) {
return null;
}
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(content);
return htmlDocument;
return !string.IsNullOrEmpty(content) ? StringToHtmlDocument(content) : null;
}
private async Task<JObject> UrlGetToJObject(string request, string referer = null) {

View File

@@ -26,6 +26,7 @@
"SteamOwnerID": 0,
"SteamProtocol": 6,
"UpdateChannel": 1,
"WCFBinding": 0,
"WCFHost": "127.0.0.1",
"WCFPort": 1242
}

View File

@@ -4,7 +4,7 @@
"CardDropsRestricted": true,
"CustomGamePlayedWhileFarming": null,
"CustomGamePlayedWhileIdle": null,
"DismissInventoryNotifications": true,
"DismissInventoryNotifications": false,
"Enabled": false,
"FarmingOrder": 0,
"FarmOffline": false,
@@ -28,5 +28,5 @@
"SteamParentalPIN": "0",
"SteamPassword": null,
"SteamTradeToken": null,
"TradingPreferences": 1
"TradingPreferences": 0
}

View File

@@ -3,7 +3,11 @@
<package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net461" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net461" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.2-beta2" targetFramework="net461" />
<package id="Nito.AsyncEx" version="4.0.1" targetFramework="net461" />
<package id="NLog" version="5.0.0-beta05-test" targetFramework="net461" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />
<package id="Resource.Embedder" version="1.2.2" targetFramework="net461" developmentDependency="true" />

View File

@@ -55,7 +55,7 @@ namespace ConfigGenerator {
public string CustomGamePlayedWhileIdle { get; set; } = null;
[JsonProperty(Required = Required.DisallowNull)]
public bool DismissInventoryNotifications { get; set; } = true;
public bool DismissInventoryNotifications { get; set; } = false;
[LocalizedCategory("Core")]
[JsonProperty(Required = Required.DisallowNull)]
@@ -136,7 +136,7 @@ namespace ConfigGenerator {
[LocalizedCategory("Advanced")]
[Editor(typeof(FlagEnumUiEditor), typeof(UITypeEditor))]
[JsonProperty(Required = Required.DisallowNull)]
public ETradingPreferences TradingPreferences { get; set; } = ETradingPreferences.AcceptDonations;
public ETradingPreferences TradingPreferences { get; set; } = ETradingPreferences.None;
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private BotConfig() { }
@@ -207,7 +207,8 @@ namespace ConfigGenerator {
None = 0,
AcceptDonations = 1,
SteamTradeMatcher = 2,
MatchEverything = 4
MatchEverything = 4,
DontAcceptBotTrades = 8
}
}
}

View File

@@ -115,6 +115,7 @@
<EmbeddedResource Include="Localization\CGStrings.ko-KR.resx" />
<EmbeddedResource Include="Localization\CGStrings.lt-LT.resx" />
<EmbeddedResource Include="Localization\CGStrings.mk-MK.resx" />
<EmbeddedResource Include="Localization\CGStrings.nl-BE.resx" />
<EmbeddedResource Include="Localization\CGStrings.nl-NL.resx" />
<EmbeddedResource Include="Localization\CGStrings.no-NO.resx" />
<EmbeddedResource Include="Localization\CGStrings.pl-PL.resx" />
@@ -176,11 +177,17 @@
copy "$(TargetDir)$(TargetName).exe" "$(SolutionDir)out\ASF-ConfigGenerator.exe"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
set -e
if [ -f "$(SolutionDir)mono_envsetup.sh" ]; then
. "$(SolutionDir)mono_envsetup.sh"
fi
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
if [ -n "$MONO_FACADES" ]; then
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" "/lib:$MONO_FACADES" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
else
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-ConfigGenerator.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
fi
rm "$(SolutionDir)out/ASF-ConfigGenerator.exe.config"
</PostBuildEvent>
</PropertyGroup>

View File

@@ -117,6 +117,10 @@ namespace ConfigGenerator {
[JsonProperty(Required = Required.DisallowNull)]
public EUpdateChannel UpdateChannel { get; set; } = EUpdateChannel.Stable;
[LocalizedCategory("Access")]
[JsonProperty(Required = Required.DisallowNull)]
public EWCFBinding WCFBinding { get; set; } = EWCFBinding.NetTcp;
[LocalizedCategory("Access")]
[JsonProperty]
public string WCFHost { get; set; } = "127.0.0.1";
@@ -220,5 +224,11 @@ namespace ConfigGenerator {
Stable,
Experimental
}
internal enum EWCFBinding : byte {
NetTcp,
BasicHttp,
WSHttp
}
}
}

View File

@@ -117,28 +117,88 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CategoryAccess" xml:space="preserve">
<value>Достъп</value>
</data>
<data name="CategoryAdvanced" xml:space="preserve">
<value>Разширени настройки</value>
</data>
<data name="CategoryCore" xml:space="preserve">
<value>Основни</value>
</data>
<data name="CategoryDebugging" xml:space="preserve">
<value>Отстраняване на грешки</value>
</data>
<data name="CategoryPerformance" xml:space="preserve">
<value>Производителност</value>
</data>
<data name="CategoryUpdates" xml:space="preserve">
<value>Обновления</value>
</data>
<data name="ConfirmRemoval" xml:space="preserve">
<value>Наистина ли искате да премахнете тези настройки?</value>
</data>
<data name="ErrorBotNameEmpty" xml:space="preserve">
<value>Не сте задали име на бота!</value>
</data>
<data name="ErrorCantRemoveGlobalConfig" xml:space="preserve">
<value>Не можете да премахнете общите настройки!</value>
</data>
<data name="ErrorCantRenameGlobalConfig" xml:space="preserve">
<value>Не можете да преименувате общите настройки!</value>
</data>
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
<value>Папката с настройките не може да бъде открита!</value>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Конфигурираното свойство {0} е невалидно: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>Задали сте невалиден CurrentCulture. ConfigGenerator ще продължи работа със зададения по подразбиране!</value>
</data>
<data name="ErrorNameAlreadyUsed" xml:space="preserve">
<value>Потребителското име вече използвано!</value>
<comment>This happens e.g. when user wants to create a bot with name that exists already</comment>
</data>
<data name="ErrorNameReserved" xml:space="preserve">
<value>Това име е вече запазено!</value>
<comment>This happens e.g. when user wants to create a bot with reserved name, such as "ASF"</comment>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} е нулев!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorVersionMismatch" xml:space="preserve">
<value>Опитахте се да ползвате невалидна версия на ConfigGenerator, за вашия ASF!
ASF: {0} | ConfigGenerator: {1}
Моля ползвайте ConfigGenerator със съответсваща версия на вашия ASF! Ще бъдете пренасочен към съответващата версия...</value>
<comment>{0} will be replaced by ASF version (string), {1} will be replaced by ConfigGenerator version (string). Please note that this string should include newlines for formatting.</comment>
</data>
<data name="New" xml:space="preserve">
<value>Ново</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="Removal" xml:space="preserve">
<value>Премахване</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="Rename" xml:space="preserve">
<value>Преименуване</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="TutorialBotFormEnabled" xml:space="preserve">
<value>Чудесно! Вече твоят бот е в готовност. Всъщност, това бе всичко, което ти трябваше да изпълниш, за да ползваш този бот в ASF, но все пак, може да поискаш да зададеш поне още 2 възможности: {0} и {1}. Ако искаш да продължиш с обучението, моля, заповявай. Не забравяй да се обърнеш към wiki ако не си сигурен, как различните настройки да бъдат зададени или ако искаш допълнителна помощ.</value>
<comment>{0} will be replaced by "SteamLogin" configuration property, {1} will be replaced by "SteamPassword" configuration property</comment>
</data>
<data name="TutorialBotFormReady" xml:space="preserve">
<value>Вашият ASF е вече готов! Стартирайте AFS.exe файлът и ако сте въвели всичко правилно, ще забележите, че ASF се вписва и започва да вади карти. Ако имате SteamGuard или двойна защита, ASF може да поиска да въведете съответните изисквания по време на работата.</value>
</data>
<data name="TutorialFinished" xml:space="preserve">
<value>Поздравления! Изпълнихте всичко, което беше необходимо, за да използвате ASF. С това завършва обучението, които Ви подготвихме. Силно препоръчително е да прочетете цялата секция за настройки в нашето wiki, тъй като ASF предлага много полезни функции, които Вие да си настроите, като вадите карти в режим offline или ASF да ползва най-ефективния метод за вадене на карти за Вашия профил. Всичко това са допълнителни възможности и сега спокойно можете да затворите конфигуратора, когато пожелаете. Надяваме се, че ще се радвате на софтуера, който сме Ви предоставили!</value>
</data>
@@ -148,13 +208,12 @@
<data name="UserInputBotName" xml:space="preserve">
<value>Моля, въведете ново име за бот: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="WarningConfigPropertyModified" xml:space="preserve">
<value>{0} бе зададено на: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by new value</comment>
</data>
</root>

View File

@@ -123,32 +123,92 @@
<data name="ConfirmRemoval" xml:space="preserve">
<value>Haluatko varmasti poistaa tämän config tiedoston?</value>
</data>
<data name="ErrorBotNameEmpty" xml:space="preserve">
<value>Botin nimi on tyhjä!</value>
</data>
<data name="ErrorCantRemoveGlobalConfig" xml:space="preserve">
<value>Et voi poistaa global config tiedostoa!</value>
</data>
<data name="ErrorCantRenameGlobalConfig" xml:space="preserve">
<value>Et voi uudelleennimetä global config tiedostoa!</value>
</data>
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
<value>Config kansiota ei löytynyt!</value>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Kohdassa {0} muokattu arvo {1} on epäkelpo.</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>Antamasi/syöttämäsi CurrentCulture on epäkelpo, ConfigGenerator jatkaa toimintaa oletusarvolla!</value>
</data>
<data name="ErrorNameAlreadyUsed" xml:space="preserve">
<value>Tämä nimi on jo käytössä!</value>
<comment>This happens e.g. when user wants to create a bot with name that exists already</comment>
</data>
<data name="ErrorNameReserved" xml:space="preserve">
<value>Tämä nimi on jo käytössä!</value>
<comment>This happens e.g. when user wants to create a bot with reserved name, such as "ASF"</comment>
</data>
<data name="ErrorVersionMismatch" xml:space="preserve">
<value>Yritit käyttää epäsopivaa ConfigGenerator versiota ASF :lläsi!
ASF: {0} | ConfigGenerator: {1}
Käytä yhteensopivaa ConfigGenerator versiota ASF binäärillesi. Sinut ohjataan oikean julkaisun sivulle...</value>
<comment>{0} will be replaced by ASF version (string), {1} will be replaced by ConfigGenerator version (string). Please note that this string should include newlines for formatting.</comment>
</data>
<data name="New" xml:space="preserve">
<value>Uusi</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="Removal" xml:space="preserve">
<value>Poistaminen</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="Rename" xml:space="preserve">
<value>Nimeä uudelleen</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="TutorialBotFormReady" xml:space="preserve">
<value>ASF on nyt valmis! Käynnistä ASF.exe binääri ja jos syötit kaikki tiedot oikein, pitäisi sinun huomata että ASF kirjautuu sisään ja aloittaa idlaamisen. Jos sinulla on SteamGuard tai kaksivaiheinen todennus käytössä, saattaa ASF joutua kysymään sinulta valtuuksia noita käyttäjiä varten.</value>
</data>
<data name="TutorialMainFormBotsManagementButtons" xml:space="preserve">
<value>Ikkunan yläosassa voit huomata tällä hetkellä ladatun configin ja 3 extra painiketta, poistamiselle [-], uudelleennimeämiselle [~] ja uusien lisäämiselle [+].</value>
<comment>If possible, try to keep visual representation of buttons: [-], [~] and [+]</comment>
</data>
<data name="TutorialMainFormFinished" xml:space="preserve">
<value>Okei. Aloitetaan konfiguroimaan meidän ASF :ää. Paina plus-painiketta [+] lisätäksesi ensimmäinen steam accountisi!</value>
<comment>If possible, try to keep visual representation of [+] button</comment>
</data>
<data name="TutorialMainFormHelpButton" xml:space="preserve">
<value>Oikeasta yläkulmasta löytyy apua-painike [?] joka ohjaa sinut ASF wikiin lisätiedon saamiseksi.</value>
<comment>If possible, try to keep visual representation of [?] button</comment>
</data>
<data name="TutorialMainFormShown" xml:space="preserve">
<value>Tämä on ASF ConfigGeneratorin pääikkuna, se on todella helppo käyttää!</value>
</data>
<data name="TutorialNewBotFormFinished" xml:space="preserve">
<value>Kuten näet, sinun bottisi on nyt valmiina muokattavaksi! Ensimmäinen asia jonka haluat tehdä on muuttaa kohdasta {0} arvo false to true, kokeile!</value>
<comment>{0} will be replaced by name of the configuration property ("Enabled")</comment>
</data>
<data name="TutorialNewBotFormShown" xml:space="preserve">
<value>Hienoa! Nyt sinua pyydetään nimeämään bottisi. Hyvä esimerkki on nimetä se steam accountin mukaan jota aiot konfiguroida. Mikä tahansa muukin nimi käy, kunhan se on sinulle helposti yhdistettävissä samaan botti-instanssiin jota aiot konfiguroida.</value>
</data>
<data name="TutorialStart" xml:space="preserve">
<value>Tervetuloa! Huomasin, että käytät ASF ConfigGeneratoria ensimmäistä kertaa, anna minun auttaa sinut alkuun.</value>
</data>
<data name="UserInputBotName" xml:space="preserve">
<value>Anna uudelle botillesi nimi: </value>
<comment>Please note that this translation should end with space</comment>
</data>
</root>

View File

@@ -0,0 +1,242 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string"/>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="mimetype" type="xsd:string"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
<xsd:attribute ref="xml:space"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CategoryAccess" xml:space="preserve">
<value>Toegang</value>
</data>
<data name="CategoryAdvanced" xml:space="preserve">
<value>Geavanceerd</value>
</data>
<data name="CategoryCore" xml:space="preserve">
<value>Kern</value>
</data>
<data name="CategoryDebugging" xml:space="preserve">
<value>Foutopsporing</value>
</data>
<data name="CategoryPerformance" xml:space="preserve">
<value>Prestaties</value>
</data>
<data name="CategoryUpdates" xml:space="preserve">
<value>Updates</value>
</data>
<data name="ConfirmRemoval" xml:space="preserve">
<value>Wil je deze configuratie echt verwijderen?</value>
</data>
<data name="ErrorBotNameEmpty" xml:space="preserve">
<value>Je bot heeft geen naam!</value>
</data>
<data name="ErrorCantRemoveGlobalConfig" xml:space="preserve">
<value>Je kan het globale config bestand niet verwijderen!</value>
</data>
<data name="ErrorCantRenameGlobalConfig" xml:space="preserve">
<value>Je kan het globale configuratie bestand niet hernoemen!</value>
</data>
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
<value>Configuratiefolder kon niet gevonden worden!</value>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Geconfigureerde {0} eigenschap is niet geldig: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by invalid value</comment>
</data>
<data name="ErrorInvalidCurrentCulture" xml:space="preserve">
<value>De opgegeven CurrentCulture is ongeldig, ConfigGenerator blijft draaien met de standaard!</value>
</data>
<data name="ErrorNameAlreadyUsed" xml:space="preserve">
<value>Deze naam is al in gebruik!</value>
<comment>This happens e.g. when user wants to create a bot with name that exists already</comment>
</data>
<data name="ErrorNameReserved" xml:space="preserve">
<value>Deze naam is gereserveerd!</value>
<comment>This happens e.g. when user wants to create a bot with reserved name, such as "ASF"</comment>
</data>
<data name="ErrorObjectIsNull" xml:space="preserve">
<value>{0} is null!</value>
<comment>{0} will be replaced by object's name</comment>
</data>
<data name="ErrorVersionMismatch" xml:space="preserve">
<value>Je hebt geprobeerd om een ongeldige ConfigGenerator versie te gebruiken voor ASF!
ASF: {0} | ConfigGenerator: {1}
Gebruik een zelfde versie ConfigGenerator voor je ASF bestand. Je wordt verwezen naar de juiste release...</value>
<comment>{0} will be replaced by ASF version (string), {1} will be replaced by ConfigGenerator version (string). Please note that this string should include newlines for formatting.</comment>
</data>
<data name="New" xml:space="preserve">
<value>Nieuw</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="Removal" xml:space="preserve">
<value>Verwijderen</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="Rename" xml:space="preserve">
<value>Hernoemen</value>
<comment>This is used as MessageBox title</comment>
</data>
<data name="TutorialBotFormEnabled" xml:space="preserve">
<value>Proficiat! Je bot instance is actief. Feitelijk was dat alles dat je moest doen om deze bot in ASF te gebruiken, maar je wilt misschien nog 2 andere config waardes instellen: {0} en {1}.
Je kan, als je wilt, doorgaan met deze tutorial. Vergeet niet de wiki te gebruiken als je niet zeker weet hoe een waarde moet worden ingesteld. Dit geldt ook als je meer hulp nodig hebt.</value>
<comment>{0} will be replaced by "SteamLogin" configuration property, {1} will be replaced by "SteamPassword" configuration property</comment>
</data>
<data name="TutorialBotFormReady" xml:space="preserve">
<value>Je ASF is nu klaar! Simpelweg ASF.exe starten en als je alles correct hebt ingevuld, zul je merken dat ASF aan het inloggen en begonnen is met idlen. Als je SteamGuard twee factor authenticatie aan hebt staan, kan het zijn dat ASF voor deze gegevens vraagt tijdens het starten.</value>
</data>
<data name="TutorialFinished" xml:space="preserve">
<value>Proficiat! Je hebt alles gedaan dat nodig is om ASF bruikbaar te maken, hiermee is deze tutorial die we hebben klaargezet ook afgerond. Het wordt sterk aanbevolen om de hele 'configuration' sectie op de wiki te lezen, aangezien ASF leuke eigenschappen heeft die geconfigureerd kunnen worden. Zoals offline farmen of afstemmen van ASF voor het meest efficiënte idling algoritme voor je account. Dit alles is optioneel en je kan de ConfigGenerator afsluiten als je dit wilt. We hopen dat je zult genieten van de software die we voor jou hebben geschreven!</value>
</data>
<data name="TutorialMainFormBotsManagementButtons" xml:space="preserve">
<value>Bovenaan het venster zie je de huidig geladen configuraties en 3 extra knoppen voor verwijderen [-], hernoemen [~] en toevoegen van nieuwe configuraties [+].</value>
<comment>If possible, try to keep visual representation of buttons: [-], [~] and [+]</comment>
</data>
<data name="TutorialMainFormConfigurationWiki" xml:space="preserve">
<value>Hou rekening dat alle informatie met betrekking tot alle beschikbare config eigenschappen, inclusief hun uitleg, doel en geaccepteerde waardes, beschikbaar is op onze GitHub wiki. Graag dit als referentie gebruiken.</value>
</data>
<data name="TutorialMainFormConfigurationWindow" xml:space="preserve">
<value>In het midden van de venster kan alle config eigenschappen die beschikbaar zijn configureren. Dit geldt voor de huidig geselecteerde config.</value>
</data>
<data name="TutorialMainFormFinished" xml:space="preserve">
<value>Laten we beginnen met het configureren van ASF. Klik op de plus [+] knop om je eerste Steam account toe te voegen!</value>
<comment>If possible, try to keep visual representation of [+] button</comment>
</data>
<data name="TutorialMainFormHelpButton" xml:space="preserve">
<value>In de bovenrechter hoek vindt je de help knop [?] die je doorverwijst naar de ASF wiki voor meer informatie.</value>
<comment>If possible, try to keep visual representation of [?] button</comment>
</data>
<data name="TutorialMainFormShown" xml:space="preserve">
<value>Dit is de hoofd ASF ConfigGenerator scherm, het is heel simpel in gebruik!</value>
</data>
<data name="TutorialNewBotFormFinished" xml:space="preserve">
<value>Zoals je ziet, je bot is nu gereed voor configuratie! Het eerste dat je wilt doen is {0} eigenschap schakelen van false naar true, probeer het!</value>
<comment>{0} will be replaced by name of the configuration property ("Enabled")</comment>
</data>
<data name="TutorialNewBotFormShown" xml:space="preserve">
<value>Goed gedaan! Je wordt nu gevraagd voor een naam voor je bot. Een goede voorbeeld is de nickname die je voor je Steam account gebruikt. Of elk ander naam die makkelijk voor jou is om te herinneren om welke bot het gaat.</value>
</data>
<data name="TutorialStart" xml:space="preserve">
<value>Welkom! Ik zie dat dit de eerste keer is dat je ASF ConfigGenerator gebruikt, laat me je daar een beetje mee helpen.</value>
</data>
<data name="UserInputBotName" xml:space="preserve">
<value>Voer een nieuwe naam in voor de bot: </value>
<comment>Please note that this translation should end with space</comment>
</data>
<data name="WarningConfigPropertyModified" xml:space="preserve">
<value>{0} staat nu op: {1}</value>
<comment>{0} will be replaced by name of the configuration property, {1} will be replaced by new value</comment>
</data>
</root>

View File

@@ -121,7 +121,7 @@
<value>Toegang</value>
</data>
<data name="CategoryAdvanced" xml:space="preserve">
<value>Geadvanceerd</value>
<value>Geavanceerd</value>
</data>
<data name="CategoryCore" xml:space="preserve">
<value>Kern</value>
@@ -145,10 +145,10 @@
<value>Je kan het globale config bestand niet verwijderen!</value>
</data>
<data name="ErrorCantRenameGlobalConfig" xml:space="preserve">
<value>Je kan het het globale config bestand niet verwijderen!</value>
<value>Je kan het globale config bestand niet hernoemen!</value>
</data>
<data name="ErrorConfigDirectoryNotFound" xml:space="preserve">
<value>Configuratie folder kon niet gevonden worden!</value>
<value>Configuratiefolder kon niet gevonden worden!</value>
</data>
<data name="ErrorConfigPropertyInvalid" xml:space="preserve">
<value>Geconfigureerde {0} eigenschap is ongeldig: {1}</value>
@@ -229,7 +229,7 @@ Je kan, als je wilt, doorgaan met deze tutorial. Vergeet niet de wiki te gebruik
<value>Goed gedaan! Je wordt nu gevraagd voor een naam voor je bot. Een goede voorbeeld is de nickname die je voor je Steam account gebruikt. Of elk ander naam die makkelijk voor jou is om te herinneren om welke bot het gaat.</value>
</data>
<data name="TutorialStart" xml:space="preserve">
<value>Welkom! Ik zie dat dit de eerste keer is dat ASF ConfigGenerator gebruikt, laat me je daar een beetje mee helpen.</value>
<value>Welkom! Ik zie dat dit de eerste keer is dat je ASF ConfigGenerator gebruikt, laat me je daar een beetje mee helpen.</value>
</data>
<data name="UserInputBotName" xml:space="preserve">
<value>Voer een nieuwe naam in voor de bot: </value>

View File

@@ -118,10 +118,10 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CategoryAccess" xml:space="preserve">
<value>Erişim</value>
<value>Erişim İzni</value>
</data>
<data name="CategoryAdvanced" xml:space="preserve">
<value>Gelişmiş</value>
<value>İleri düzey</value>
</data>
<data name="CategoryCore" xml:space="preserve">
<value>Temel</value>

View File

@@ -44,8 +44,6 @@ namespace ArchiSteamFarm {
AvatarPictureBox.LoadAsync();
}
private void AvatarPictureBox_LoadCompleted(object sender, AsyncCompletedEventArgs e) {
MainForm.UpdateBotAvatar(Bot.BotName, AvatarPictureBox.Image);
}
private void AvatarPictureBox_LoadCompleted(object sender, AsyncCompletedEventArgs e) => MainForm.UpdateBotAvatar(Bot.BotName, AvatarPictureBox.Image);
}
}

View File

@@ -30,7 +30,7 @@ namespace ArchiSteamFarm {
internal static void OnPersonaState(Bot bot, SteamFriends.PersonaStateCallback callback) {
if (bot == null) {
Program.ArchiLogger.LogNullError(nameof(bot));
ASF.ArchiLogger.LogNullError(nameof(bot));
return;
}

View File

@@ -48,10 +48,34 @@
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.2-beta2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nito.AsyncEx, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nito.AsyncEx.Concurrent, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nito.AsyncEx.Enlightenment, Version=4.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nito.AsyncEx.4.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.5.0.0-beta05-test\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
@@ -71,6 +95,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net" />
<Reference Include="System.Security" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Drawing" />
@@ -148,6 +173,9 @@
<Compile Include="..\ArchiSteamFarm\MobileAuthenticator.cs">
<Link>MobileAuthenticator.cs</Link>
</Compile>
<Compile Include="..\ArchiSteamFarm\OS.cs">
<Link>OS.cs</Link>
</Compile>
<Compile Include="..\ArchiSteamFarm\Runtime.cs">
<Link>Runtime.cs</Link>
</Compile>
@@ -251,6 +279,9 @@
<EmbeddedResource Include="..\ArchiSteamFarm\Localization\Strings.mk-MK.resx">
<Link>Localization\Strings.mk-MK.resx</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\ArchiSteamFarm\Localization\Strings.nl-BE.resx">
<Link>Localization\Strings.nl-BE.resx</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\ArchiSteamFarm\Localization\Strings.nl-NL.resx">
<Link>Localization\Strings.nl-NL.resx</Link>
</EmbeddedResource>
@@ -349,11 +380,17 @@
copy "$(TargetDir)$(TargetName).exe" "$(SolutionDir)out\ASF-GUI.exe"
</PostBuildEvent>
<PostBuildEvent Condition=" '$(OS)' == 'Unix' AND '$(ConfigurationName)' == 'Release' ">
set -e
if [ -f "$(SolutionDir)mono_envsetup.sh" ]; then
. "$(SolutionDir)mono_envsetup.sh"
fi
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
if [ -n "$MONO_FACADES" ]; then
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" "/lib:$MONO_FACADES" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
else
mono "$(SolutionDir)tools/ILRepack/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF-GUI.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
fi
rm "$(SolutionDir)out/ASF-GUI.exe.config"
</PostBuildEvent>
</PropertyGroup>
@@ -364,10 +401,12 @@
<Error Condition="!Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets'))" />
<Error Condition="!Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<Import Project="..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Fody.1.30.0-beta01\build\dotnet\Fody.targets')" />
<Import Project="..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" />
<Import Project="..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets" Condition="'$(OS)' != 'Unix' AND '$(ConfigurationName)' == 'Release' AND Exists('..\packages\Resource.Embedder.1.2.2\build\Resource.Embedder.targets')" />
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -22,7 +22,6 @@
*/
using System.Linq;
using NLog;
using NLog.Config;
using NLog.Targets;
@@ -30,46 +29,34 @@ using NLog.Windows.Forms;
namespace ArchiSteamFarm {
internal static class Logging {
private const string GeneralLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss} | ${level:uppercase=true} | ${logger} | ${message}${onexception:inner= | ${exception:format=toString,Data}}";
private const string GeneralLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss}|${processname}-${processid}|${level:uppercase=true}|${logger}|${message}${onexception:inner= ${exception:format=toString,Data}}";
private static bool IsUsingCustomConfiguration;
internal static void InitCoreLoggers() {
if (LogManager.Configuration == null) {
LogManager.Configuration = new LoggingConfiguration();
} else {
// User provided custom NLog config, but we still need to define our own logger
IsUsingCustomConfiguration = true;
if (LogManager.Configuration.AllTargets.Any(target => target is MessageBoxTarget)) {
return;
}
}
MessageBoxTarget messageBoxTarget = new MessageBoxTarget {
Name = "MessageBox",
Layout = GeneralLayout
};
LogManager.Configuration.AddTarget(messageBoxTarget);
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Fatal, messageBoxTarget));
LogManager.ReconfigExistingLoggers();
}
internal static void InitEnhancedLoggers() {
if (IsUsingCustomConfiguration) {
internal static void InitLoggers() {
if (LogManager.Configuration != null) {
// User provided custom NLog config, or we have it set already, so don't override it
return;
}
LoggingConfiguration config = new LoggingConfiguration();
FileTarget fileTarget = new FileTarget("File") {
DeleteOldFileOnStartup = true,
FileName = SharedInfo.LogFile,
Layout = GeneralLayout
};
LogManager.Configuration.AddTarget(fileTarget);
LogManager.Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));
config.AddTarget(fileTarget);
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));
LogManager.ReconfigExistingLoggers();
MessageBoxTarget messageBoxTarget = new MessageBoxTarget {
Name = "MessageBox",
Layout = GeneralLayout
};
config.AddTarget(messageBoxTarget);
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Fatal, messageBoxTarget));
LogManager.Configuration = config;
}
internal static void InitFormLogger() {

View File

@@ -1,11 +1,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ArchiSteamFarm {
@@ -22,7 +20,7 @@ namespace ArchiSteamFarm {
internal static void UpdateBotAvatar(string botName, Image image) {
if (string.IsNullOrEmpty(botName) || (image == null)) {
Program.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(image));
ASF.ArchiLogger.LogNullError(nameof(botName) + " || " + nameof(image));
return;
}
@@ -59,58 +57,39 @@ namespace ArchiSteamFarm {
BotStatusForm.BotForms[PreviouslySelectedBotName].Visible = true;
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e) => Program.InitShutdownSequence();
private async void MainForm_FormClosed(object sender, FormClosedEventArgs e) => await Program.InitShutdownSequence().ConfigureAwait(false);
private async void MainForm_Load(object sender, EventArgs e) {
Logging.InitFormLogger();
BotListView.LargeImageList = BotListView.SmallImageList = AvatarImageList;
await Task.Run(async () => {
Program.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
Program.InitCore();
Logging.InitFormLogger();
await Program.InitASF(); // No ConfigureAwait, we need GUI thread
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
Program.ArchiLogger.LogGenericError("Config directory could not be found!");
Environment.Exit(1);
}
foreach (KeyValuePair<string, Bot> bot in Bot.Bots) {
BotStatusForm botStatusForm = new BotStatusForm(bot.Value);
await ASF.CheckForUpdate().ConfigureAwait(false);
BotIndexes[bot.Key] = AvatarImageList.Images.Count;
// Before attempting to connect, initialize our list of CMs
await Bot.InitializeCMs(Program.GlobalDatabase.CellID, Program.GlobalDatabase.ServerListProvider).ConfigureAwait(false);
});
foreach (string botName in Directory.EnumerateFiles(SharedInfo.ConfigDirectory, "*.json").Select(Path.GetFileNameWithoutExtension)) {
switch (botName) {
case SharedInfo.ASF:
case "example":
case "minimal":
continue;
}
Bot bot = new Bot(botName);
BotStatusForm botStatusForm = new BotStatusForm(bot);
BotIndexes[botName] = AvatarImageList.Images.Count;
AvatarImageList.Images.Add(botName, botStatusForm.AvatarPictureBox.Image);
AvatarImageList.Images.Add(bot.Key, botStatusForm.AvatarPictureBox.Image);
botStatusForm.TopLevel = false;
BotStatusPanel.Controls.Add(botStatusForm);
ListViewItem botListViewItem = new ListViewItem {
ImageIndex = BotIndexes[botName],
Text = botName
ImageIndex = BotIndexes[bot.Key],
Text = bot.Key
};
BotListView.Items.Add(botListViewItem);
}
if (BotListView.Items.Count > 0) {
BotListView.Items[0].Selected = true;
BotListView.Select();
if (BotListView.Items.Count <= 0) {
return;
}
BotListView.Items[0].Selected = true;
BotListView.Select();
}
private void MainForm_Resize(object sender, EventArgs e) {
@@ -132,7 +111,7 @@ namespace ArchiSteamFarm {
private static Bitmap ResizeImage(Image image, int width, int height) {
if ((image == null) || (width <= 0) || (height <= 0)) {
Program.ArchiLogger.LogNullError(nameof(image) + " || " + nameof(width) + " || " + nameof(height));
ASF.ArchiLogger.LogNullError(nameof(image) + " || " + nameof(width) + " || " + nameof(height));
return null;
}

View File

@@ -1,58 +1,70 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Resources;
using System.Threading.Tasks;
using System.Windows.Forms;
using ArchiSteamFarm.Localization;
using NLog.Targets;
using SteamKit2;
namespace ArchiSteamFarm {
internal static class Program {
internal static readonly ArchiLogger ArchiLogger = new ArchiLogger(SharedInfo.ASF);
internal static GlobalConfig GlobalConfig { get; private set; }
internal static GlobalDatabase GlobalDatabase { get; private set; }
internal static WebBrowser WebBrowser { get; private set; }
internal static void Exit(int exitCode = 0) {
InitShutdownSequence();
Environment.Exit(exitCode);
}
private static bool ShutdownSequenceInitialized;
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) {
return null; // TODO
}
internal static void InitShutdownSequence() {
foreach (Bot bot in Bot.Bots.Values.Where(bot => bot.KeepRunning)) {
bot.Stop();
}
}
internal static void Restart() {
InitShutdownSequence();
try {
Process.Start(Assembly.GetEntryAssembly().Location, string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
internal static async Task Exit(byte exitCode = 0) {
if (exitCode != 0) {
ASF.ArchiLogger.LogGenericError(Strings.ErrorExitingWithNonZeroErrorCode);
}
Environment.Exit(0);
await Shutdown().ConfigureAwait(false);
Application.Exit();
}
private static void Init() {
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
internal static string GetUserInput(ASF.EUserInputType userInputType, string botName = SharedInfo.ASF, string extraInformation = null) => null; // TODO
Logging.InitCoreLoggers();
internal static async Task InitASF() {
ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version);
await InitGlobalConfigAndLanguage().ConfigureAwait(false);
if (!Runtime.IsRuntimeSupported) {
ArchiLogger.LogGenericError("ASF detected unsupported runtime version, program might NOT run correctly in current environment. You're running it at your own risk!");
ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported);
await Task.Delay(60 * 1000).ConfigureAwait(false);
}
await InitGlobalDatabaseAndServices().ConfigureAwait(false);
// If debugging is on, we prepare debug directory prior to running
if (GlobalConfig.Debug) {
if (Directory.Exists(SharedInfo.DebugDirectory)) {
try {
Directory.Delete(SharedInfo.DebugDirectory, true);
await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
} catch (IOException e) {
ASF.ArchiLogger.LogGenericException(e);
}
}
Directory.CreateDirectory(SharedInfo.DebugDirectory);
DebugLog.AddListener(new Debugging.DebugListener());
DebugLog.Enabled = true;
}
await ASF.CheckForUpdate().ConfigureAwait(false);
await ASF.InitBots().ConfigureAwait(false);
ASF.InitFileWatcher();
}
internal static void InitCore() {
string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
if (!string.IsNullOrEmpty(homeDirectory)) {
Directory.SetCurrentDirectory(homeDirectory);
@@ -62,12 +74,9 @@ namespace ArchiSteamFarm {
// Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
for (byte i = 0; i < 4; i++) {
Directory.SetCurrentDirectory("..");
if (!Directory.Exists(SharedInfo.ASFDirectory)) {
continue;
if (Directory.Exists(SharedInfo.ConfigDirectory)) {
break;
}
Directory.SetCurrentDirectory(SharedInfo.ASFDirectory);
break;
}
// If config directory doesn't exist after our adjustment, abort all of that
@@ -77,45 +86,101 @@ namespace ArchiSteamFarm {
}
}
InitServices();
// If debugging is on, we prepare debug directory prior to running
if (GlobalConfig.Debug) {
if (Directory.Exists(SharedInfo.DebugDirectory)) {
Directory.Delete(SharedInfo.DebugDirectory, true);
Thread.Sleep(1000); // Dirty workaround giving Windows some time to sync
}
Directory.CreateDirectory(SharedInfo.DebugDirectory);
DebugLog.AddListener(new Debugging.DebugListener());
DebugLog.Enabled = true;
}
Logging.InitEnhancedLoggers();
Logging.InitLoggers();
}
private static void InitServices() {
internal static async Task<bool> InitShutdownSequence() {
if (ShutdownSequenceInitialized) {
return false;
}
ShutdownSequenceInitialized = true;
IEnumerable<Task> tasks = Bot.Bots.Values.Select(bot => Task.Run(() => bot.Stop()));
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(10 * 1000));
return true;
}
internal static async Task Restart() {
if (!await InitShutdownSequence().ConfigureAwait(false)) {
return;
}
Application.Restart();
}
private static void Init() {
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
// We must register our logging target as soon as possible
Target.Register<SteamTarget>("Steam");
// The rest of ASF is initialized from MainForm.cs
}
private static async Task InitGlobalConfigAndLanguage() {
string globalConfigFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName);
GlobalConfig = GlobalConfig.Load(globalConfigFile);
if (GlobalConfig == null) {
ArchiLogger.LogGenericError("Global config could not be loaded, please make sure that " + globalConfigFile + " exists and is valid!");
Exit(1);
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorGlobalConfigNotLoaded, globalConfigFile));
await Task.Delay(5 * 1000).ConfigureAwait(false);
await Exit(1).ConfigureAwait(false);
return;
}
if (!string.IsNullOrEmpty(GlobalConfig.CurrentCulture)) {
try {
// GetCultureInfo() would be better but we can't use it for specifying neutral cultures such as "en"
CultureInfo culture = CultureInfo.CreateSpecificCulture(GlobalConfig.CurrentCulture);
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = culture;
} catch (CultureNotFoundException) {
ASF.ArchiLogger.LogGenericError(Strings.ErrorInvalidCurrentCulture);
}
}
int defaultResourceSetCount = 0;
ResourceSet defaultResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.GetCultureInfo("en-US"), true, true);
if (defaultResourceSet != null) {
defaultResourceSetCount = defaultResourceSet.Cast<object>().Count();
}
int currentResourceSetCount = 0;
ResourceSet currentResourceSet = Strings.ResourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, false);
if (currentResourceSet != null) {
currentResourceSetCount = currentResourceSet.Cast<object>().Count();
}
if (currentResourceSetCount < defaultResourceSetCount) {
float translationCompleteness = currentResourceSetCount / (float) defaultResourceSetCount;
ASF.ArchiLogger.LogGenericInfo(string.Format(Strings.TranslationIncomplete, CultureInfo.CurrentCulture.Name, translationCompleteness.ToString("P1")));
}
}
private static async Task InitGlobalDatabaseAndServices() {
string globalDatabaseFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName);
if (!File.Exists(globalDatabaseFile)) {
ASF.ArchiLogger.LogGenericInfo(Strings.Welcome);
ASF.ArchiLogger.LogGenericWarning(Strings.WarningPrivacyPolicy);
await Task.Delay(15 * 1000).ConfigureAwait(false);
}
GlobalDatabase = GlobalDatabase.Load(globalDatabaseFile);
if (GlobalDatabase == null) {
ArchiLogger.LogGenericError("Global database could not be loaded, if issue persists, please remove " + globalDatabaseFile + " in order to recreate database!");
Exit(1);
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile));
await Task.Delay(5 * 1000).ConfigureAwait(false);
await Exit(1).ConfigureAwait(false);
return;
}
ArchiWebHandler.Init();
OS.Init();
WebBrowser.Init();
WebBrowser = new WebBrowser(ArchiLogger);
WebBrowser = new WebBrowser(ASF.ArchiLogger);
}
/// <summary>
@@ -129,22 +194,34 @@ namespace ArchiSteamFarm {
Application.Run(new MainForm());
}
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
if (args?.ExceptionObject == null) {
ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.ExceptionObject));
private static async Task Shutdown() {
if (!await InitShutdownSequence().ConfigureAwait(false)) {
return;
}
ArchiLogger.LogFatalException((Exception) args.ExceptionObject);
Application.Exit();
}
private static async void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
if (args?.ExceptionObject == null) {
ASF.ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.ExceptionObject));
return;
}
ASF.ArchiLogger.LogFatalException((Exception) args.ExceptionObject);
await Task.Delay(5000).ConfigureAwait(false);
await Exit(1).ConfigureAwait(false);
}
private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
if (args?.Exception == null) {
ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.Exception));
ASF.ArchiLogger.LogNullError(nameof(args) + " || " + nameof(args.Exception));
return;
}
ArchiLogger.LogFatalException(args.Exception);
ASF.ArchiLogger.LogFatalException(args.Exception);
// Normally we should abort the application here, but many tasks are in fact failing in SK2 code which we can't easily fix
// Thanks Valve.
}
}
}

View File

@@ -3,7 +3,11 @@
<package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net461" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net461" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.2-beta2" targetFramework="net461" />
<package id="Nito.AsyncEx" version="4.0.1" targetFramework="net461" />
<package id="NLog" version="5.0.0-beta05-test" targetFramework="net461" />
<package id="NLog.Windows.Forms" version="4.2.3" targetFramework="net461" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net461" />

View File

@@ -71,4 +71,11 @@ else
echo "INFO: Skipping setting of MONO_ENV_OPTIONS as it's already declared with value: $MONO_ENV_OPTIONS"
fi
MONO_FACADES=""
if [ -d "/usr/lib/mono/4.5/Facades" ]; then
export MONO_FACADES="/usr/lib/mono/4.5/Facades"
else
echo "WARN: Could not find Mono facades!"
fi
echo "INFO: Mono environment setup finished!"

View File

@@ -0,0 +1,118 @@
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fswiss\fprq2\fcharset0 Calibri;}{\f3\fnil\fcharset0 Calibri;}{\f4\fnil\fcharset2 Symbol;}}
{\colortbl ;\red31\green73\blue125;\red0\green0\blue255;}
{\*\listtable
{\list\listhybrid
{\listlevel\levelnfc0\leveljc0\levelstartat1{\leveltext\'02\'00.;}{\levelnumbers\'01;}\jclisttab\tx360}
{\listlevel\levelnfc4\leveljc0\levelstartat1{\leveltext\'02\'01.;}{\levelnumbers\'01;}\jclisttab\tx363}
{\listlevel\levelnfc2\leveljc0\levelstartat1{\leveltext\'02\'02.;}{\levelnumbers\'01;}\jclisttab\tx720}\listid1 }
{\list\listhybrid
{\listlevel\levelnfc0\leveljc0\levelstartat1{\leveltext\'02\'00.;}{\levelnumbers\'01;}\jclisttab\tx363}
{\listlevel\levelnfc4\leveljc0\levelstartat1{\leveltext\'02\'01.;}{\levelnumbers\'01;}\jclisttab\tx363}\listid2 }}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}{\s3 heading 3;}}
{\*\generator Riched20 6.2.9200}\viewkind4\uc1
\pard\nowidctlpar\sb120\sa120\b\f0\fs24 MICROSOFT SOFTWARE LICENSE TERMS\par
\pard\brdrb\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 MICROSOFT .NET LIBRARY \par
\pard\nowidctlpar\sb120\sa120\fs19 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. Please read them. They apply to the software named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent363{\pntxtb\'B7}}\nowidctlpar\fi-363\li720\sb120\sa120\b0 updates,\par
{\pntext\f4\'B7\tab}supplements,\par
{\pntext\f4\'B7\tab}Internet-based services, and\par
{\pntext\f4\'B7\tab}support services\par
\pard\nowidctlpar\sb120\sa120\b for this software, unless other terms accompany those items. If so, those terms apply.\par
BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\par
\pard\brdrt\brdrs\brdrw10\brsp20 \nowidctlpar\sb120\sa120 IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE PERPETUAL RIGHTS BELOW.\par
\pard
{\listtext\f0 1.\tab}\jclisttab\tx360\ls1\nowidctlpar\s1\fi-357\li357\sb120\sa120 INSTALLATION AND USE RIGHTS. \par
\pard
{\listtext\f0 a.\tab}\jclisttab\tx363\ls1\ilvl1\nowidctlpar\s2\fi-363\li720\sb120\sa120 Installation and Use.\b0\fs20 You may install and use any number of copies of the software to design, develop and test your programs.\par
{\listtext\f0 b.\tab}\b\fs19 Third Party Programs.\b0\fs20 The software may include third party programs that Microsoft, not the third party, licenses to you under this agreement. Notices, if any, for the third party program are included for your information only.\b\fs19\par
\pard
{\listtext\f0 2.\tab}\jclisttab\tx360\ls1\nowidctlpar\s1\fi-357\li357\sb120\sa120\fs20 ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.\par
\pard
{\listtext\f0 a.\tab}\jclisttab\tx363\ls1\ilvl1\nowidctlpar\s2\fi-363\li720\sb120\sa120 DISTRIBUTABLE CODE.\~ \b0 The software is comprised of Distributable Code. \f1\ldblquote\f0 Distributable Code\f1\rdblquote\f0 is code that you are permitted to distribute in programs you develop if you comply with the terms below.\b\par
\pard
{\listtext\f0 i.\tab}\jclisttab\tx720\ls1\ilvl2\nowidctlpar\s3\fi-357\li1077\sb120\sa120\tx1077 Right to Use and Distribute. \par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-357\li1434\sb120\sa120\b0 You may copy and distribute the object code form of the software.\par
{\pntext\f4\'B7\tab}Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.\par
\pard\nowidctlpar\s3\fi-357\li1077\sb120\sa120\tx1077\b ii.\tab Distribution Requirements.\b0 \b For any Distributable Code you distribute, you must\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-357\li1434\sb120\sa120\b0 add significant primary functionality to it in your programs;\par
{\pntext\f4\'B7\tab}require distributors and external end users to agree to terms that protect it at least as much as this agreement;\par
{\pntext\f4\'B7\tab}display your valid copyright notice on your programs; and\par
{\pntext\f4\'B7\tab}indemnify, defend, and hold harmless Microsoft from any claims, including attorneys\rquote fees, related to the distribution or use of your programs.\par
\pard\nowidctlpar\s3\fi-357\li1077\sb120\sa120\tx1077\b iii.\tab Distribution Restrictions.\b0 \b You may not\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-357\li1434\sb120\sa120\b0 alter any copyright, trademark or patent notice in the Distributable Code;\par
{\pntext\f4\'B7\tab}use Microsoft\rquote s trademarks in your programs\rquote names or in a way that suggests your programs come from or are endorsed by Microsoft;\par
{\pntext\f4\'B7\tab}include Distributable Code in malicious, deceptive or unlawful programs; or\par
{\pntext\f4\'B7\tab}modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\fi-358\li1792\sb120\sa120 the code be disclosed or distributed in source code form; or\cf1\f2\par
{\pntext\f4\'B7\tab}\cf0\f0 others have the right to modify it.\cf1\f2\par
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\cf0\b\f0 3.\tab\fs19 SCOPE OF LICENSE. \b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent363{\pntxtb\'B7}}\nowidctlpar\fi-363\li720\sb120\sa120 work around any technical limitations in the software;\par
{\pntext\f4\'B7\tab}reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par
{\pntext\f4\'B7\tab}publish the software for others to copy;\par
{\pntext\f4\'B7\tab}rent, lease or lend the software;\par
{\pntext\f4\'B7\tab}transfer the software or this agreement to any third party; or\par
{\pntext\f4\'B7\tab}use the software for commercial software hosting services.\par
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\b\fs20 4.\tab\fs19 BACKUP COPY. \b0 You may make one backup copy of the software. You may use it only to reinstall the software.\par
\b\fs20 5.\tab\fs19 DOCUMENTATION. \b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\par
\b\fs20 6.\tab\fs19 EXPORT RESTRICTIONS. \b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {\cf2\ul\fs20{\field{\*\fldinst{HYPERLINK www.microsoft.com/exporting }}{\fldrslt{www.microsoft.com/exporting}}}}\f0\fs19 .\cf2\ul\fs20\par
\cf0\ulnone\b 7.\tab\fs19 SUPPORT SERVICES. \b0 Because this software is \ldblquote as is,\rdblquote we may not provide support services for it.\par
\b\fs20 8.\tab\fs19 ENTIRE AGREEMENT. \b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\par
\b\fs20 9.\tab\fs19 APPLICABLE LAW.\par
\pard
{\listtext\f0 a.\tab}\jclisttab\tx363\ls2\ilvl1\nowidctlpar\s2\fi-363\li720\sb120\sa120 United States. \b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\par
{\listtext\f0 b.\tab}\b Outside the United States. If you acquired the software in any other country, the laws of that country apply.\par
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\fs20 10.\tab\fs19 LEGAL EFFECT. \b0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\par
\b\fs20 11.\tab\fs19 DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED \ldblquote AS-IS.\rdblquote YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\par
\pard\nowidctlpar\li357\sb120\sa120 FOR AUSTRALIA \endash YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS.\par
\pard\nowidctlpar\s1\fi-357\li357\sb120\sa120\fs20 12.\tab\fs19 LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\par
\pard\nowidctlpar\li357\sb120\sa120\b0 This limitation applies to\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent363{\pntxtb\'B7}}\nowidctlpar\fi-363\li720\sb120\sa120 anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par
{\pntext\f4\'B7\tab}claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par
\pard\nowidctlpar\sb120\sa120 It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\par
\lang9 Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\par
Remarque : Ce logiciel \'e9tant distribu\'e9 au Qu\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\'e7ais.\par
\pard\nowidctlpar\s1\sb120\sa120\b\lang1033 EXON\'c9RATION DE GARANTIE. \b0 Le logiciel vis\'e9 par une licence est offert \'ab tel quel \'bb. Toute utilisation de ce logiciel est \'e0 votre seule risque et p\'e9ril. Microsoft n\rquote accorde aucune autre garantie expresse. Vous pouvez b\'e9n\'e9ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\'e9 marchande, d\rquote ad\'e9quation \'e0 un usage particulier et d\rquote absence de contrefa\'e7on sont exclues.\par
\b LIMITATION DES DOMMAGES-INT\'c9R\'caTS ET EXCLUSION DE RESPONSABILIT\'c9 POUR LES DOMMAGES. \b0 Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\'e9tendre \'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\'e9ciaux, indirects ou accessoires et pertes de b\'e9n\'e9fices.\par
\pard\nowidctlpar\sb120\sa120\lang9 Cette limitation concerne :\par
\pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent360{\pntxtb\'B7}}\nowidctlpar\li720\sb120\sa120 tout ce qui est reli\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\par
{\pntext\f4\'B7\tab}les r\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\'e9 stricte, de n\'e9gligence ou d\rquote une autre faute dans la limite autoris\'e9e par la loi en vigueur.\par
\pard\nowidctlpar\sb120\sa120 Elle s\rquote applique \'e9galement, m\'eame si Microsoft connaissait ou devrait conna\'eetre l\rquote\'e9ventualit\'e9 d\rquote un tel dommage. Si votre pays n\rquote autorise pas l\rquote exclusion ou la limitation de responsabilit\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l\rquote exclusion ci-dessus ne s\rquote appliquera pas \'e0 votre \'e9gard.\par
\pard\nowidctlpar\s1\sb120\sa120\b\lang1033 EFFET JURIDIQUE. \b0 Le pr\'e9sent contrat d\'e9crit certains droits juridiques. Vous pourriez avoir d\rquote autres droits pr\'e9vus par les lois de votre pays. Le pr\'e9sent contrat ne modifie pas les droits que vous conf\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\par
\pard\nowidctlpar\sb120\sa120\b\fs20\lang1036\par
\pard\sa200\sl276\slmult1\b0\f3\fs22\lang9\par
}

Binary file not shown.

View File

View File

View File

Binary file not shown.

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.IO</name>
</assembly>
<members>
</members>
</doc>

Binary file not shown.

View File

@@ -0,0 +1,56 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.Runtime</name>
</assembly>
<members>
<member name="T:System.IProgress`1">
<summary>Defines a provider for progress updates.</summary>
<typeparam name="T">The type of progress update value.</typeparam>
</member>
<member name="M:System.IProgress`1.Report(`0)">
<summary>Reports a progress update.</summary>
<param name="value">The value of the updated progress.</param>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncStateMachineAttribute">
<summary>Identities the async state machine type for this method.</summary>
</member>
<member name="T:System.Runtime.CompilerServices.StateMachineAttribute">
<summary>Identities the state machine type for this method.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.StateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="P:System.Runtime.CompilerServices.StateMachineAttribute.StateMachineType">
<summary>Gets the type that implements the state machine.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncStateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="T:System.Runtime.CompilerServices.CallerMemberNameAttribute">
<summary>
Allows you to obtain the method or property name of the caller to the method.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.CallerLineNumberAttribute">
<summary>
Allows you to obtain the line number in the source file at which the method is called.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.CallerFilePathAttribute">
<summary>
Allows you to obtain the full path of the source file that contains the caller.
This is the file path at the time of compile.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.IteratorStateMachineAttribute">
<summary>Identities the iterator state machine type for this method.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.IteratorStateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
</members>
</doc>

Binary file not shown.

View File

@@ -0,0 +1,475 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.Threading.Tasks</name>
</assembly>
<members>
<member name="T:System.Runtime.CompilerServices.AsyncMethodBuilderCore">
<summary>Holds state related to the builder's IAsyncStateMachine.</summary>
<remarks>This is a mutable struct. Be very delicate with it.</remarks>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodBuilderCore.m_stateMachine">
<summary>A reference to the heap-allocated state machine object associated with this builder.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start``1(``0@)">
<summary>Initiates the builder's execution with the associated state machine.</summary>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="stateMachine">The state machine instance, passed by reference.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="stateMachine"/> argument is null (Nothing in Visual Basic).</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodBuilderCore.SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)">
<summary>Associates the builder with the state machine it represents.</summary>
<param name="stateMachine">The heap-allocated state machine object.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The builder is incorrectly initialized.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodBuilderCore.GetCompletionAction``2(``0@,``1@)">
<summary>
Gets the Action to use with an awaiter's OnCompleted or UnsafeOnCompleted method.
On first invocation, the supplied state machine will be boxed.
</summary>
<typeparam name="TMethodBuilder">Specifies the type of the method builder used.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine used.</typeparam>
<param name="builder">The builder.</param>
<param name="stateMachine">The state machine.</param>
<returns>An Action to provide to the awaiter.</returns>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner">
<summary>Provides the ability to invoke a state machine's MoveNext method under a supplied ExecutionContext.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.m_context">
<summary>The context with which to run MoveNext.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.m_stateMachine">
<summary>The state machine whose MoveNext method should be invoked.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.#ctor(System.ExecutionContextLightup)">
<summary>Initializes the runner.</summary>
<param name="context">The context with which to run MoveNext.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run">
<summary>Invokes MoveNext under the provided context.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.s_invokeMoveNext">
<summary>Cached delegate used with ExecutionContext.Run.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext(System.Object)">
<summary>Invokes the MoveNext method on the supplied IAsyncStateMachine.</summary>
<param name="stateMachine">The IAsyncStateMachine machine instance.</param>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncMethodTaskCache`1">
<summary>Provides a base class used to cache tasks of a specific return type.</summary>
<typeparam name="TResult">Specifies the type of results the cached tasks return.</typeparam>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.Singleton">
<summary>
A singleton cache for this result type.
This may be null if there are no cached tasks for this TResult.
</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.CreateCompleted(`0)">
<summary>Creates a non-disposable task.</summary>
<param name="result">The result for the task.</param>
<returns>The cacheable task.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.CreateCache">
<summary>Creates a cache.</summary>
<returns>A task cache for this result type.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.FromResult(`0)">
<summary>Gets a cached task if one exists.</summary>
<param name="result">The result for which we want a cached task.</param>
<returns>A cached task if one exists; otherwise, null.</returns>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodBooleanTaskCache">
<summary>Provides a cache for Boolean tasks.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodBooleanTaskCache.m_true">
<summary>A true task.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodBooleanTaskCache.m_false">
<summary>A false task.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodBooleanTaskCache.FromResult(System.Boolean)">
<summary>Gets a cached task for the Boolean result.</summary>
<param name="result">true or false</param>
<returns>A cached task for the Boolean result.</returns>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodInt32TaskCache">
<summary>Provides a cache for zero Int32 tasks.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodInt32TaskCache.INCLUSIVE_INT32_MIN">
<summary>The minimum value, inclusive, for which we want a cached task.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodInt32TaskCache.EXCLUSIVE_INT32_MAX">
<summary>The maximum value, exclusive, for which we want a cached task.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodInt32TaskCache.Int32Tasks">
<summary>The cache of Task{Int32}.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodInt32TaskCache.CreateInt32Tasks">
<summary>Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX).</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncMethodTaskCache`1.AsyncMethodInt32TaskCache.FromResult(System.Int32)">
<summary>Gets a cached task for the zero Int32 result.</summary>
<param name="result">The integer value</param>
<returns>A cached task for the Int32 result or null if not cached.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncServices.ThrowAsync(System.Exception,System.Threading.SynchronizationContext)">
<summary>Throws the exception on the ThreadPool.</summary>
<param name="exception">The exception to propagate.</param>
<param name="targetContext">The target context on which to propagate the exception. Null to use the ThreadPool.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncServices.PrepareExceptionForRethrow(System.Exception)">
<summary>Copies the exception's stack trace so its stack trace isn't overwritten.</summary>
<param name="exc">The exception to prepare.</param>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncTaskMethodBuilder">
<summary>
Provides a builder for asynchronous methods that return <see cref="T:System.Threading.Tasks.Task"/>.
This type is intended for compiler use only.
</summary>
<remarks>
AsyncTaskMethodBuilder is a value type, and thus it is copied by value.
Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
or else the copies may end up building distinct Task instances.
</remarks>
</member>
<member name="T:System.Runtime.CompilerServices.IAsyncMethodBuilder">
<summary>Represents an asynchronous method builder.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.s_cachedCompleted">
<summary>A cached VoidTaskResult task used for builders that complete synchronously.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.m_builder">
<summary>The generic builder object to which this non-generic instance delegates.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Create">
<summary>Initializes a new <see cref="T:System.Runtime.CompilerServices.AsyncTaskMethodBuilder"/>.</summary>
<returns>The initialized <see cref="T:System.Runtime.CompilerServices.AsyncTaskMethodBuilder"/>.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start``1(``0@)">
<summary>Initiates the builder's execution with the associated state machine.</summary>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="stateMachine">The state machine instance, passed by reference.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)">
<summary>Associates the builder with the state machine it represents.</summary>
<param name="stateMachine">The heap-allocated state machine object.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The builder is incorrectly initialized.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.System#Runtime#CompilerServices#IAsyncMethodBuilder#PreBoxInitialization">
<summary>Perform any initialization necessary prior to lifting the builder to the heap.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitOnCompleted``2(``0@,``1@)">
<summary>
Schedules the specified state machine to be pushed forward when the specified awaiter completes.
</summary>
<typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="awaiter">The awaiter.</param>
<param name="stateMachine">The state machine.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted``2(``0@,``1@)">
<summary>
Schedules the specified state machine to be pushed forward when the specified awaiter completes.
</summary>
<typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="awaiter">The awaiter.</param>
<param name="stateMachine">The state machine.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult">
<summary>
Completes the <see cref="T:System.Threading.Tasks.Task"/> in the
<see cref="T:System.Threading.Tasks.TaskStatus">RanToCompletion</see> state.
</summary>
<exception cref="T:System.InvalidOperationException">The builder is not initialized.</exception>
<exception cref="T:System.InvalidOperationException">The task has already completed.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)">
<summary>
Completes the <see cref="T:System.Threading.Tasks.Task"/> in the
<see cref="T:System.Threading.Tasks.TaskStatus">Faulted</see> state with the specified exception.
</summary>
<param name="exception">The <see cref="T:System.Exception"/> to use to fault the task.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The builder is not initialized.</exception>
<exception cref="T:System.InvalidOperationException">The task has already completed.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetNotificationForWaitCompletion(System.Boolean)">
<summary>
Called by the debugger to request notification when the first wait operation
(await, Wait, Result, etc.) on this builder's task completes.
</summary>
<param name="enabled">
true to enable notification; false to disable a previously set notification.
</param>
</member>
<member name="P:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Task">
<summary>Gets the <see cref="T:System.Threading.Tasks.Task"/> for this builder.</summary>
<returns>The <see cref="T:System.Threading.Tasks.Task"/> representing the builder's asynchronous operation.</returns>
<exception cref="T:System.InvalidOperationException">The builder is not initialized.</exception>
</member>
<member name="P:System.Runtime.CompilerServices.AsyncTaskMethodBuilder.ObjectIdForDebugger">
<summary>
Gets an object that may be used to uniquely identify this builder to the debugger.
</summary>
<remarks>
This property lazily instantiates the ID in a non-thread-safe manner.
It must only be used by the debugger, and only in a single-threaded manner
when no other threads are in the middle of accessing this property or this.Task.
</remarks>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1">
<summary>
Provides a builder for asynchronous methods that return <see cref="T:System.Threading.Tasks.Task`1"/>.
This type is intended for compiler use only.
</summary>
<remarks>
AsyncTaskMethodBuilder{TResult} is a value type, and thus it is copied by value.
Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
or else the copies may end up building distinct Task instances.
</remarks>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.s_defaultResultTask">
<summary>A cached task for default(TResult).</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.m_coreState">
<summary>State related to the IAsyncStateMachine.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.m_task">
<summary>The lazily-initialized task.</summary>
<remarks>Must be named m_task for debugger step-over to work correctly.</remarks>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.m_taskCompletionSource">
<summary>The lazily-initialized task completion source.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.#cctor">
<summary>Temporary support for disabling crashing if tasks go unobserved.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Create">
<summary>Initializes a new <see cref="T:System.Runtime.CompilerServices.AsyncTaskMethodBuilder"/>.</summary>
<returns>The initialized <see cref="T:System.Runtime.CompilerServices.AsyncTaskMethodBuilder"/>.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start``1(``0@)">
<summary>Initiates the builder's execution with the associated state machine.</summary>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="stateMachine">The state machine instance, passed by reference.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)">
<summary>Associates the builder with the state machine it represents.</summary>
<param name="stateMachine">The heap-allocated state machine object.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The builder is incorrectly initialized.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.System#Runtime#CompilerServices#IAsyncMethodBuilder#PreBoxInitialization">
<summary>Perform any initialization necessary prior to lifting the builder to the heap.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AwaitOnCompleted``2(``0@,``1@)">
<summary>
Schedules the specified state machine to be pushed forward when the specified awaiter completes.
</summary>
<typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="awaiter">The awaiter.</param>
<param name="stateMachine">The state machine.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AwaitUnsafeOnCompleted``2(``0@,``1@)">
<summary>
Schedules the specified state machine to be pushed forward when the specified awaiter completes.
</summary>
<typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="awaiter">The awaiter.</param>
<param name="stateMachine">The state machine.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetResult(`0)">
<summary>
Completes the <see cref="T:System.Threading.Tasks.Task`1"/> in the
<see cref="T:System.Threading.Tasks.TaskStatus">RanToCompletion</see> state with the specified result.
</summary>
<param name="result">The result to use to complete the task.</param>
<exception cref="T:System.InvalidOperationException">The task has already completed.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetResult(System.Threading.Tasks.TaskCompletionSource{`0})">
<summary>
Completes the builder by using either the supplied completed task, or by completing
the builder's previously accessed task using default(TResult).
</summary>
<param name="completedTask">A task already completed with the value default(TResult).</param>
<exception cref="T:System.InvalidOperationException">The task has already completed.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetException(System.Exception)">
<summary>
Completes the <see cref="T:System.Threading.Tasks.Task`1"/> in the
<see cref="T:System.Threading.Tasks.TaskStatus">Faulted</see> state with the specified exception.
</summary>
<param name="exception">The <see cref="T:System.Exception"/> to use to fault the task.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The task has already completed.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetNotificationForWaitCompletion(System.Boolean)">
<summary>
Called by the debugger to request notification when the first wait operation
(await, Wait, Result, etc.) on this builder's task completes.
</summary>
<param name="enabled">
true to enable notification; false to disable a previously set notification.
</param>
<remarks>
This should only be invoked from within an asynchronous method,
and only by the debugger.
</remarks>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.GetTaskForResult(`0)">
<summary>
Gets a task for the specified result. This will either
be a cached or new task, never null.
</summary>
<param name="result">The result for which we need a task.</param>
<returns>The completed task containing the result.</returns>
</member>
<member name="P:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.CompletionSource">
<summary>Gets the lazily-initialized TaskCompletionSource.</summary>
</member>
<member name="P:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Task">
<summary>Gets the <see cref="T:System.Threading.Tasks.Task`1"/> for this builder.</summary>
<returns>The <see cref="T:System.Threading.Tasks.Task`1"/> representing the builder's asynchronous operation.</returns>
</member>
<member name="P:System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.ObjectIdForDebugger">
<summary>
Gets an object that may be used to uniquely identify this builder to the debugger.
</summary>
<remarks>
This property lazily instantiates the ID in a non-thread-safe manner.
It must only be used by the debugger, and only in a single-threaded manner
when no other threads are in the middle of accessing this property or this.Task.
</remarks>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncVoidMethodBuilder">
<summary>
Provides a builder for asynchronous methods that return void.
This type is intended for compiler use only.
</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.m_synchronizationContext">
<summary>The synchronization context associated with this operation.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.m_coreState">
<summary>State related to the IAsyncStateMachine.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.m_objectIdForDebugger">
<summary>An object used by the debugger to uniquely identify this builder. Lazily initialized.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.#cctor">
<summary>Temporary support for disabling crashing if tasks go unobserved.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.PreventUnobservedTaskExceptions">
<summary>Registers with UnobservedTaskException to suppress exception crashing.</summary>
</member>
<member name="F:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.s_preventUnobservedTaskExceptionsInvoked">
<summary>Non-zero if PreventUnobservedTaskExceptions has already been invoked.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create">
<summary>Initializes a new <see cref="T:System.Runtime.CompilerServices.AsyncVoidMethodBuilder"/>.</summary>
<returns>The initialized <see cref="T:System.Runtime.CompilerServices.AsyncVoidMethodBuilder"/>.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.#ctor(System.Threading.SynchronizationContext)">
<summary>Initializes the <see cref="T:System.Runtime.CompilerServices.AsyncVoidMethodBuilder"/>.</summary>
<param name="synchronizationContext">The synchronizationContext associated with this operation. This may be null.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start``1(``0@)">
<summary>Initiates the builder's execution with the associated state machine.</summary>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="stateMachine">The state machine instance, passed by reference.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)">
<summary>Associates the builder with the state machine it represents.</summary>
<param name="stateMachine">The heap-allocated state machine object.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The builder is incorrectly initialized.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.System#Runtime#CompilerServices#IAsyncMethodBuilder#PreBoxInitialization">
<summary>Perform any initialization necessary prior to lifting the builder to the heap.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitOnCompleted``2(``0@,``1@)">
<summary>
Schedules the specified state machine to be pushed forward when the specified awaiter completes.
</summary>
<typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="awaiter">The awaiter.</param>
<param name="stateMachine">The state machine.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted``2(``0@,``1@)">
<summary>
Schedules the specified state machine to be pushed forward when the specified awaiter completes.
</summary>
<typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
<typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
<param name="awaiter">The awaiter.</param>
<param name="stateMachine">The state machine.</param>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult">
<summary>Completes the method builder successfully.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)">
<summary>Faults the method builder with an exception.</summary>
<param name="exception">The exception that is the cause of this fault.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
<exception cref="T:System.InvalidOperationException">The builder is not initialized.</exception>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.NotifySynchronizationContextOfCompletion">
<summary>Notifies the current synchronization context that the operation completed.</summary>
</member>
<member name="P:System.Runtime.CompilerServices.AsyncVoidMethodBuilder.ObjectIdForDebugger">
<summary>
Gets an object that may be used to uniquely identify this builder to the debugger.
</summary>
<remarks>
This property lazily instantiates the ID in a non-thread-safe manner.
It must only be used by the debugger and only in a single-threaded manner.
</remarks>
</member>
<member name="T:System.Runtime.CompilerServices.IAsyncStateMachine">
<summary>
Represents state machines generated for asynchronous methods.
This type is intended for compiler use only.
</summary>
</member>
<member name="M:System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext">
<summary>Moves the state machine to its next state.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.IAsyncStateMachine.SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)">
<summary>Configures the state machine with a heap-allocated replica.</summary>
<param name="stateMachine">The heap-allocated replica.</param>
</member>
<member name="T:System.Runtime.CompilerServices.ICriticalNotifyCompletion">
<summary>
Represents an awaiter used to schedule continuations when an await operation completes.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.INotifyCompletion">
<summary>
Represents an operation that will schedule continuations when the operation completes.
</summary>
</member>
<member name="M:System.Runtime.CompilerServices.INotifyCompletion.OnCompleted(System.Action)">
<summary>Schedules the continuation action to be invoked when the instance completes.</summary>
<param name="continuation">The action to invoke when the operation completes.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
</member>
<member name="M:System.Runtime.CompilerServices.ICriticalNotifyCompletion.UnsafeOnCompleted(System.Action)">
<summary>Schedules the continuation action to be invoked when the instance completes.</summary>
<param name="continuation">The action to invoke when the operation completes.</param>
<exception cref="T:System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
<remarks>Unlike OnCompleted, UnsafeOnCompleted need not propagate ExecutionContext information.</remarks>
</member>
<member name="T:System.Runtime.CompilerServices.VoidTaskResult">
<summary>Used with Task(of void)</summary>
</member>
</members>
</doc>

View File

View File

@@ -0,0 +1,51 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.IO</name>
</assembly>
<members>
<member name="T:System.Strings">
<summary>
A strongly-typed resource class, for looking up localized strings, etc.
</summary>
</member>
<member name="P:System.Strings.ResourceManager">
<summary>
Returns the cached ResourceManager instance used by this class.
</summary>
</member>
<member name="P:System.Strings.Culture">
<summary>
Overrides the current thread's CurrentUICulture property for all
resource lookups using this strongly typed resource class.
</summary>
</member>
<member name="P:System.Strings.GenericInvalidData">
<summary>
Looks up a localized string similar to Found invalid data while decoding..
</summary>
</member>
<member name="T:System.IO.InvalidDataException">
<summary>
The exception that is thrown when a data stream is in an invalid format.
</summary>
</member>
<member name="M:System.IO.InvalidDataException.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.IO.InvalidDataException" /> class.
</summary>
</member>
<member name="M:System.IO.InvalidDataException.#ctor(System.String)">
<summary>
Initializes a new instance of the <see cref="T:System.IO.InvalidDataException" /> class with a specified error message.
</summary>
<param name="message">The error message that explains the reason for the exception.</param>
</member>
<member name="M:System.IO.InvalidDataException.#ctor(System.String,System.Exception)">
<summary>
Initializes a new instance of the <see cref="T:System.IO.InvalidDataException" /> class with a reference to the inner exception that is the cause of this exception.</summary>
<param name="message">The error message that explains the reason for the exception.</param>
<param name="innerException">The exception that is the cause of the current exception. If the <paramref name="innerException" /> parameter is not null, the current exception is raised in a catch block that handles the inner exception.</param>
</member>
</members>
</doc>

View File

@@ -0,0 +1,860 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.Runtime</name>
</assembly>
<members>
<member name="T:System.Strings">
<summary>
A strongly-typed resource class, for looking up localized strings, etc.
</summary>
</member>
<member name="P:System.Strings.ResourceManager">
<summary>
Returns the cached ResourceManager instance used by this class.
</summary>
</member>
<member name="P:System.Strings.Culture">
<summary>
Overrides the current thread's CurrentUICulture property for all
resource lookups using this strongly typed resource class.
</summary>
</member>
<member name="P:System.Strings.ArgumentException_TupleIncorrectType">
<summary>
Looks up a localized string similar to Argument must be of type {0}..
</summary>
</member>
<member name="P:System.Strings.ArgumentException_TupleLastArgumentNotATuple">
<summary>
Looks up a localized string similar to The last element of an eight element tuple must be a Tuple..
</summary>
</member>
<member name="T:System.Collections.IStructuralEquatable">
<summary>
Defines methods to support the comparison of objects for structural equality.
</summary>
</member>
<member name="M:System.Collections.IStructuralEquatable.Equals(System.Object,System.Collections.IEqualityComparer)">
<summary>
Determines whether an object is structurally equal to the current instance.
</summary>
<param name="other">The object to compare with the current instance.</param>
<param name="comparer">An object that determines whether the current instance and other are equal. </param>
<returns>true if the two objects are equal; otherwise, false.</returns>
</member>
<member name="M:System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer)">
<summary>
Returns a hash code for the current instance.
</summary>
<param name="comparer">An object that computes the hash code of the current object.</param>
<returns>The hash code for the current instance.</returns>
</member>
<member name="T:System.Collections.IStructuralComparable">
<summary>
Supports the structural comparison of collection objects.
</summary>
</member>
<member name="M:System.Collections.IStructuralComparable.CompareTo(System.Object,System.Collections.IComparer)">
<summary>
Determines whether the current collection object precedes, occurs in the same position as, or follows another object in the sort order.
</summary>
<param name="other">The object to compare with the current instance.</param>
<param name="comparer">An object that compares members of the current collection object with the corresponding members of other.</param>
<returns>An integer that indicates the relationship of the current collection object to other.</returns>
<exception cref="T:System.ArgumentException">
This instance and other are not the same type.
</exception>
</member>
<member name="T:System.Func`6">
<summary>
Encapsulates a method that has five parameters and returns a value of the type specified by the TResult parameter.
</summary>
<typeparam name="T1">The type of the first parameter of the method that this delegate encapsulates.</typeparam>
<typeparam name="T2">The type of the second parameter of the method that this delegate encapsulates.</typeparam>
<typeparam name="T3">The type of the third parameter of the method that this delegate encapsulates.</typeparam>
<typeparam name="T4">The type of the fourth parameter of the method that this delegate encapsulates.</typeparam>
<typeparam name="T5">The type of the fifth parameter of the method that this delegate encapsulates.</typeparam>
<typeparam name="TResult">The type of the return value of the method that this delegate encapsulates.</typeparam>
<param name="arg1">The first parameter of the method that this delegate encapsulates.</param>
<param name="arg2">The second parameter of the method that this delegate encapsulates.</param>
<param name="arg3">The third parameter of the method that this delegate encapsulates.</param>
<param name="arg4">The fourth parameter of the method that this delegate encapsulates.</param>
<param name="arg5">The fifth parameter of the method that this delegate encapsulates.</param>
<returns>The return value of the method that this delegate encapsulates.</returns>
</member>
<member name="T:System.IProgress`1">
<summary>Defines a provider for progress updates.</summary>
<typeparam name="T">The type of progress update value.</typeparam>
</member>
<member name="M:System.IProgress`1.Report(`0)">
<summary>Reports a progress update.</summary>
<param name="value">The value of the updated progress.</param>
</member>
<member name="T:System.Runtime.CompilerServices.AsyncStateMachineAttribute">
<summary>Identities the async state machine type for this method.</summary>
</member>
<member name="T:System.Runtime.CompilerServices.StateMachineAttribute">
<summary>Identities the state machine type for this method.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.StateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="P:System.Runtime.CompilerServices.StateMachineAttribute.StateMachineType">
<summary>Gets the type that implements the state machine.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.AsyncStateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="T:System.Runtime.CompilerServices.CallerMemberNameAttribute">
<summary>
Allows you to obtain the method or property name of the caller to the method.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.CallerLineNumberAttribute">
<summary>
Allows you to obtain the line number in the source file at which the method is called.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.CallerFilePathAttribute">
<summary>
Allows you to obtain the full path of the source file that contains the caller.
This is the file path at the time of compile.
</summary>
</member>
<member name="T:System.Runtime.CompilerServices.IteratorStateMachineAttribute">
<summary>Identities the iterator state machine type for this method.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.IteratorStateMachineAttribute.#ctor(System.Type)">
<summary>Initializes the attribute.</summary>
<param name="stateMachineType">The type that implements the state machine.</param>
</member>
<member name="T:System.ITuple">
<summary>
Helper so we can call some tuple methods recursively without knowing the underlying types.
</summary>
</member>
<member name="T:System.Tuple">
<summary>
Provides static methods for creating tuple objects.
</summary>
</member>
<member name="M:System.Tuple.Create``1(``0)">
<summary>
Creates a new 1-tuple, or singleton.
</summary>
<typeparam name="T1">The type of the only component of the tuple.</typeparam>
<param name="item1">The value of the only component of the tuple.</param>
<returns>A tuple whose value is (item1).</returns>
</member>
<member name="M:System.Tuple.Create``2(``0,``1)">
<summary>
Creates a new 3-tuple, or pair.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<returns>An 2-tuple (pair) whose value is (item1, item2).</returns>
</member>
<member name="M:System.Tuple.Create``3(``0,``1,``2)">
<summary>
Creates a new 3-tuple, or triple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<returns>An 3-tuple (triple) whose value is (item1, item2, item3).</returns>
</member>
<member name="M:System.Tuple.Create``4(``0,``1,``2,``3)">
<summary>
Creates a new 4-tuple, or quadruple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<returns>An 4-tuple (quadruple) whose value is (item1, item2, item3, item4).</returns>
</member>
<member name="M:System.Tuple.Create``5(``0,``1,``2,``3,``4)">
<summary>
Creates a new 5-tuple, or quintuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<returns>An 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5).</returns>
</member>
<member name="M:System.Tuple.Create``6(``0,``1,``2,``3,``4,``5)">
<summary>
Creates a new 6-tuple, or sextuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<param name="item6">The value of the sixth component of the tuple.</param>
<returns>An 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6).</returns>
</member>
<member name="M:System.Tuple.Create``7(``0,``1,``2,``3,``4,``5,``6)">
<summary>
Creates a new 7-tuple, or septuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
<typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<param name="item6">The value of the sixth component of the tuple.</param>
<param name="item7">The value of the seventh component of the tuple.</param>
<returns>An 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7).</returns>
</member>
<member name="M:System.Tuple.Create``8(``0,``1,``2,``3,``4,``5,``6,``7)">
<summary>
Creates a new 8-tuple, or octuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
<typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
<typeparam name="T8">The type of the eighth component of the tuple.</typeparam>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<param name="item6">The value of the sixth component of the tuple.</param>
<param name="item7">The value of the seventh component of the tuple.</param>
<param name="item8">The value of the eighth component of the tuple.</param>
<returns>An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8).</returns>
</member>
<member name="T:System.Tuple`1">
<summary>
Represents a 1-tuple, or singleton.
</summary>
<typeparam name="T1">The type of the tuple's only component.</typeparam>
</member>
<member name="M:System.Tuple`1.#ctor(`0)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`1"/> class.
</summary>
<param name="item1">The value of the current tuple object's single component.</param>
</member>
<member name="M:System.Tuple`1.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`1.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`1.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`1.Item1">
<summary>
Gets the value of the tuple object's single component.
</summary>
<value>
The value of the current tuple object's single component.
</value>
</member>
<member name="T:System.Tuple`2">
<summary>
Represents an 2-tuple, or pair.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
</member>
<member name="M:System.Tuple`2.#ctor(`0,`1)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`2"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
</member>
<member name="M:System.Tuple`2.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`2.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`2.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`2.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`2.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="T:System.Tuple`3">
<summary>
Represents an 3-tuple, or triple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
</member>
<member name="M:System.Tuple`3.#ctor(`0,`1,`2)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`3"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
</member>
<member name="M:System.Tuple`3.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`3.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`3.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`3.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`3.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="P:System.Tuple`3.Item3">
<summary>
Gets the value of the current tuple object's third component.
</summary>
<value>
The value of the current tuple object's third component.
</value>
</member>
<member name="T:System.Tuple`4">
<summary>
Represents an 4-tuple, or quadruple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
</member>
<member name="M:System.Tuple`4.#ctor(`0,`1,`2,`3)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`4"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
</member>
<member name="M:System.Tuple`4.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`4.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`4.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`4.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`4.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="P:System.Tuple`4.Item3">
<summary>
Gets the value of the current tuple object's third component.
</summary>
<value>
The value of the current tuple object's third component.
</value>
</member>
<member name="P:System.Tuple`4.Item4">
<summary>
Gets the value of the current tuple object's fourth component.
</summary>
<value>
The value of the current tuple object's fourth component.
</value>
</member>
<member name="T:System.Tuple`5">
<summary>
Represents an 5-tuple, or quintuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
</member>
<member name="M:System.Tuple`5.#ctor(`0,`1,`2,`3,`4)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`5"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
</member>
<member name="M:System.Tuple`5.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`5.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`5.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`5.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`5.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="P:System.Tuple`5.Item3">
<summary>
Gets the value of the current tuple object's third component.
</summary>
<value>
The value of the current tuple object's third component.
</value>
</member>
<member name="P:System.Tuple`5.Item4">
<summary>
Gets the value of the current tuple object's fourth component.
</summary>
<value>
The value of the current tuple object's fourth component.
</value>
</member>
<member name="P:System.Tuple`5.Item5">
<summary>
Gets the value of the current tuple object's fifth component.
</summary>
<value>
The value of the current tuple object's fifth component.
</value>
</member>
<member name="T:System.Tuple`6">
<summary>
Represents an 6-tuple, or sextuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
</member>
<member name="M:System.Tuple`6.#ctor(`0,`1,`2,`3,`4,`5)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`6"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<param name="item6">The value of the sixth component of the tuple.</param>
</member>
<member name="M:System.Tuple`6.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`6.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`6.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`6.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`6.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="P:System.Tuple`6.Item3">
<summary>
Gets the value of the current tuple object's third component.
</summary>
<value>
The value of the current tuple object's third component.
</value>
</member>
<member name="P:System.Tuple`6.Item4">
<summary>
Gets the value of the current tuple object's fourth component.
</summary>
<value>
The value of the current tuple object's fourth component.
</value>
</member>
<member name="P:System.Tuple`6.Item5">
<summary>
Gets the value of the current tuple object's fifth component.
</summary>
<value>
The value of the current tuple object's fifth component.
</value>
</member>
<member name="P:System.Tuple`6.Item6">
<summary>
Gets the value of the current tuple object's sixth component.
</summary>
<value>
The value of the current tuple object's sixth component.
</value>
</member>
<member name="T:System.Tuple`7">
<summary>
Represents an 7-tuple, or septuple.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
<typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
</member>
<member name="M:System.Tuple`7.#ctor(`0,`1,`2,`3,`4,`5,`6)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`7"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<param name="item6">The value of the sixth component of the tuple.</param>
<param name="item7">The value of the seventh component of the tuple.</param>
</member>
<member name="M:System.Tuple`7.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`7.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`7.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`7.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`7.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="P:System.Tuple`7.Item3">
<summary>
Gets the value of the current tuple object's third component.
</summary>
<value>
The value of the current tuple object's third component.
</value>
</member>
<member name="P:System.Tuple`7.Item4">
<summary>
Gets the value of the current tuple object's fourth component.
</summary>
<value>
The value of the current tuple object's fourth component.
</value>
</member>
<member name="P:System.Tuple`7.Item5">
<summary>
Gets the value of the current tuple object's fifth component.
</summary>
<value>
The value of the current tuple object's fifth component.
</value>
</member>
<member name="P:System.Tuple`7.Item6">
<summary>
Gets the value of the current tuple object's sixth component.
</summary>
<value>
The value of the current tuple object's sixth component.
</value>
</member>
<member name="P:System.Tuple`7.Item7">
<summary>
Gets the value of the current tuple object's seventh component.
</summary>
<value>
The value of the current tuple object's seventh component.
</value>
</member>
<member name="T:System.Tuple`8">
<summary>
Represents an n-tuple, where n is 8 or greater.
</summary>
<typeparam name="T1">The type of the first component of the tuple.</typeparam>
<typeparam name="T2">The type of the second component of the tuple.</typeparam>
<typeparam name="T3">The type of the third component of the tuple.</typeparam>
<typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
<typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
<typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
<typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
<typeparam name="TRest">Any generic Tuple object that defines the types of the tuple's remaining components.</typeparam>
</member>
<member name="M:System.Tuple`8.#ctor(`0,`1,`2,`3,`4,`5,`6,`7)">
<summary>
Initializes a new instance of the <see cref="T:System.Tuple`8"/> class.
</summary>
<param name="item1">The value of the first component of the tuple.</param>
<param name="item2">The value of the second component of the tuple.</param>
<param name="item3">The value of the third component of the tuple.</param>
<param name="item4">The value of the fourth component of the tuple.</param>
<param name="item5">The value of the fifth component of the tuple.</param>
<param name="item6">The value of the sixth component of the tuple.</param>
<param name="item7">The value of the seventh component of the tuple.</param>
<param name="rest">Any generic Tuple object that contains the values of the tuple's remaining components.</param>
<exception cref="T:System.ArgumentException">
rest is not a generic Tuple object.
</exception>
</member>
<member name="M:System.Tuple`8.Equals(System.Object)">
<summary>
Returns a value that indicates whether the current tuple object is equal to a specified object.
</summary>
<param name="obj">The object to compare with this instance.</param>
<returns>true if the current instance is equal to the specified object; otherwise, false.</returns>
</member>
<member name="M:System.Tuple`8.GetHashCode">
<summary>
Calculates the hash code for the current tuple object.
</summary>
<returns>A 32-bit signed integer hash code.</returns>
</member>
<member name="M:System.Tuple`8.ToString">
<summary>
Returns a string that represents the value of this tuple instance.
</summary>
<returns>The string representation of this tuple object.</returns>
</member>
<member name="P:System.Tuple`8.Item1">
<summary>
Gets the value of the current tuple object's first component.
</summary>
<value>
The value of the current tuple object's first component.
</value>
</member>
<member name="P:System.Tuple`8.Item2">
<summary>
Gets the value of the current tuple object's second component.
</summary>
<value>
The value of the current tuple object's second component.
</value>
</member>
<member name="P:System.Tuple`8.Item3">
<summary>
Gets the value of the current tuple object's third component.
</summary>
<value>
The value of the current tuple object's third component.
</value>
</member>
<member name="P:System.Tuple`8.Item4">
<summary>
Gets the value of the current tuple object's fourth component.
</summary>
<value>
The value of the current tuple object's fourth component.
</value>
</member>
<member name="P:System.Tuple`8.Item5">
<summary>
Gets the value of the current tuple object's fifth component.
</summary>
<value>
The value of the current tuple object's fifth component.
</value>
</member>
<member name="P:System.Tuple`8.Item6">
<summary>
Gets the value of the current tuple object's sixth component.
</summary>
<value>
The value of the current tuple object's sixth component.
</value>
</member>
<member name="P:System.Tuple`8.Item7">
<summary>
Gets the value of the current tuple object's seventh component.
</summary>
<value>
The value of the current tuple object's seventh component.
</value>
</member>
<member name="P:System.Tuple`8.Rest">
<summary>
Gets the current tuple object's remaining components.
</summary>
<value>
The value of the current tuple object's remaining components.
</value>
</member>
</members>
</doc>

Some files were not shown because too many files have changed in this diff Show More