mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-18 23:40:30 +00:00
Compare commits
1353 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d969758f6 | ||
|
|
55cd466a1e | ||
|
|
64b9aa409e | ||
|
|
bf89c005d7 | ||
|
|
bf6f4b8362 | ||
|
|
fda60037bb | ||
|
|
590e044391 | ||
|
|
8ffdd8bca0 | ||
|
|
d21d2473fe | ||
|
|
e60b54e402 | ||
|
|
cbabde1b38 | ||
|
|
2f96ae9e8f | ||
|
|
5ea6a167e4 | ||
|
|
daf37c723c | ||
|
|
8605c71f81 | ||
|
|
bc74c69ac5 | ||
|
|
69a12fadcf | ||
|
|
89d41e7cb3 | ||
|
|
64bbfa19cd | ||
|
|
462b720d89 | ||
|
|
48922300d0 | ||
|
|
e7537ca996 | ||
|
|
809a4bbfbf | ||
|
|
1661cf4be9 | ||
|
|
4a91b997a2 | ||
|
|
804008a5d1 | ||
|
|
90ff43dc98 | ||
|
|
377df12924 | ||
|
|
04ff460d69 | ||
|
|
a3d352c64d | ||
|
|
79a9a4e7c5 | ||
|
|
5a8e2720fa | ||
|
|
272cd1ff29 | ||
|
|
5745e00bda | ||
|
|
0e9b956ae9 | ||
|
|
559fdb34c6 | ||
|
|
9a8a61e111 | ||
|
|
143039c584 | ||
|
|
a8e3bd6473 | ||
|
|
aed11c59ee | ||
|
|
ef52e076d3 | ||
|
|
b6772b9b1e | ||
|
|
57bf294553 | ||
|
|
93c38ff4d4 | ||
|
|
65dc5def01 | ||
|
|
3903ef0dfb | ||
|
|
c9b01910d0 | ||
|
|
4f3aa4f8f6 | ||
|
|
dfffc3384b | ||
|
|
ae2713c0df | ||
|
|
371bbd8ff1 | ||
|
|
efb182c5c5 | ||
|
|
cbf06a359d | ||
|
|
150e22f302 | ||
|
|
c818fbedd9 | ||
|
|
b51bd498cd | ||
|
|
9a86f6f522 | ||
|
|
3f8a715334 | ||
|
|
7e5943bd24 | ||
|
|
f4d7b22441 | ||
|
|
db632145fb | ||
|
|
eb39a081d7 | ||
|
|
823f077cf2 | ||
|
|
7f283be03a | ||
|
|
6dc5cee846 | ||
|
|
9afbcee163 | ||
|
|
47184cb139 | ||
|
|
96dc24ed46 | ||
|
|
59e409f320 | ||
|
|
2ba714feb6 | ||
|
|
6e744e0181 | ||
|
|
c35d1be12d | ||
|
|
d6af1ae973 | ||
|
|
e26aec339f | ||
|
|
cac5d5fadb | ||
|
|
d394ba60c7 | ||
|
|
bd82af62c6 | ||
|
|
ecec08af9f | ||
|
|
c524e003b5 | ||
|
|
0808a38f48 | ||
|
|
8a2b0c9eea | ||
|
|
24ca82c526 | ||
|
|
a400ebccee | ||
|
|
c7dbaa0828 | ||
|
|
48471ca5a8 | ||
|
|
687021fd08 | ||
|
|
a6f634cae4 | ||
|
|
742857832a | ||
|
|
3ea5efe4e2 | ||
|
|
e7a19e0e9f | ||
|
|
739b3d5a9d | ||
|
|
40a9a88f43 | ||
|
|
fcd7848643 | ||
|
|
b70af76a5e | ||
|
|
1cfc3a7c71 | ||
|
|
198ada7d2a | ||
|
|
3695335927 | ||
|
|
890648e604 | ||
|
|
9ed27b5f66 | ||
|
|
1cfa11d316 | ||
|
|
249e226662 | ||
|
|
49c35108e5 | ||
|
|
dc5da86322 | ||
|
|
857e9a140f | ||
|
|
426626e3fe | ||
|
|
fb9616561d | ||
|
|
3c4755ab4c | ||
|
|
0349923a08 | ||
|
|
6a11b473ca | ||
|
|
8248864133 | ||
|
|
ac2551987a | ||
|
|
e99f3adcb5 | ||
|
|
260797b61c | ||
|
|
4ecb5f55f8 | ||
|
|
2522bb2cf2 | ||
|
|
64ce7a15c4 | ||
|
|
377c12e71b | ||
|
|
cd261ff626 | ||
|
|
8815fa32dd | ||
|
|
33bb981778 | ||
|
|
1b8da1971f | ||
|
|
a32e5e4f04 | ||
|
|
975cb8184d | ||
|
|
1d142f9346 | ||
|
|
f10caae94e | ||
|
|
e54414477f | ||
|
|
171e510fbe | ||
|
|
f4e4ea9aed | ||
|
|
a77c0d0599 | ||
|
|
9387c0f0e8 | ||
|
|
36a9319b87 | ||
|
|
a79e9839f8 | ||
|
|
a1b3710ff0 | ||
|
|
6d2c32a55f | ||
|
|
f6299324a8 | ||
|
|
649ff093be | ||
|
|
a65e9d01f6 | ||
|
|
f9eb6bfcff | ||
|
|
fa451da923 | ||
|
|
3bae07682f | ||
|
|
17d1648064 | ||
|
|
89264d1e70 | ||
|
|
ddbec692dc | ||
|
|
efec44e593 | ||
|
|
53a06126e8 | ||
|
|
f2eb9d9b37 | ||
|
|
6f001567fc | ||
|
|
bb21bb3cb4 | ||
|
|
4b80fbaf7a | ||
|
|
92e1a55583 | ||
|
|
4a8c97353d | ||
|
|
49d85807c7 | ||
|
|
68b0a34d94 | ||
|
|
f86c07fc06 | ||
|
|
17141ac982 | ||
|
|
d3a09ebc8c | ||
|
|
9cd173908f | ||
|
|
b6445aed86 | ||
|
|
9d3c816950 | ||
|
|
f3baf7101f | ||
|
|
a07403a8af | ||
|
|
5f2dc48dac | ||
|
|
a5d06a406f | ||
|
|
4033874a67 | ||
|
|
e9afd0ea5b | ||
|
|
f526d0f94a | ||
|
|
de8a83347e | ||
|
|
9b6b4fd690 | ||
|
|
d6e82680e7 | ||
|
|
8de7df2b9d | ||
|
|
2bc4e8acc1 | ||
|
|
663b4b05fc | ||
|
|
20cb23bc1a | ||
|
|
7dc47549c1 | ||
|
|
1317d86fb3 | ||
|
|
345ef35b00 | ||
|
|
0d93735e59 | ||
|
|
f8e01ec0e5 | ||
|
|
bfe453d9ca | ||
|
|
0ae12f09f3 | ||
|
|
27648db509 | ||
|
|
2288305fde | ||
|
|
cd8d095c8c | ||
|
|
82a007968e | ||
|
|
614f671962 | ||
|
|
ae4f97f5c1 | ||
|
|
e122939906 | ||
|
|
1c1c292082 | ||
|
|
1f7a2c21d9 | ||
|
|
fc3c758b5f | ||
|
|
442c780e71 | ||
|
|
07ce579cd8 | ||
|
|
8457e68639 | ||
|
|
1711a464d3 | ||
|
|
7a5a2537a3 | ||
|
|
9d7e2482f2 | ||
|
|
ca05c83442 | ||
|
|
62e6acc037 | ||
|
|
b1aec367f8 | ||
|
|
2497ab6c41 | ||
|
|
5b14586ee3 | ||
|
|
335f65546c | ||
|
|
d0c0f6ed33 | ||
|
|
f2487e4a03 | ||
|
|
e0fab89bdb | ||
|
|
2123e0022b | ||
|
|
6e4e4e9157 | ||
|
|
ae591d3ea8 | ||
|
|
f305561f47 | ||
|
|
511c3f956a | ||
|
|
1ea2a1ff8e | ||
|
|
ad6efc8279 | ||
|
|
e6bc1c0d1c | ||
|
|
7d0aeaa422 | ||
|
|
2c14846c2f | ||
|
|
9b7b595de8 | ||
|
|
c2b4a7a5fd | ||
|
|
691faced26 | ||
|
|
d23a75d2d1 | ||
|
|
0313e7a3a4 | ||
|
|
f39d34371b | ||
|
|
e7f2d4d89c | ||
|
|
193e6f8078 | ||
|
|
c68514dafc | ||
|
|
7a5e73667b | ||
|
|
51828c56ae | ||
|
|
821dee0c37 | ||
|
|
a7c38bb844 | ||
|
|
6a216819fa | ||
|
|
50e792f8a7 | ||
|
|
63c1f74064 | ||
|
|
f6fce273cf | ||
|
|
f5e1a1ce20 | ||
|
|
4102f59f5a | ||
|
|
487cfbd733 | ||
|
|
338c0ff48d | ||
|
|
876664d5fe | ||
|
|
e037ac885c | ||
|
|
34c990e5cf | ||
|
|
d1ea5755a4 | ||
|
|
47dcbb80f9 | ||
|
|
7ad5d63955 | ||
|
|
f60f3b313c | ||
|
|
52bc1b3845 | ||
|
|
b332e7b913 | ||
|
|
0bd8ff2d7d | ||
|
|
cfa8b61f31 | ||
|
|
6810e3324b | ||
|
|
6d0583e15a | ||
|
|
888ce68963 | ||
|
|
0012e627c6 | ||
|
|
c60edf3c63 | ||
|
|
2ac3619885 | ||
|
|
79f3cdfb75 | ||
|
|
69ac799ef6 | ||
|
|
ee3d2cdd72 | ||
|
|
ed802999cf | ||
|
|
08832816c6 | ||
|
|
a653aef04e | ||
|
|
0e29aaf20f | ||
|
|
a4310d28f7 | ||
|
|
d7c7b3813e | ||
|
|
1f3a064dc0 | ||
|
|
210e89be8e | ||
|
|
e83597db7a | ||
|
|
dce96b9097 | ||
|
|
5b776dc2a0 | ||
|
|
f33cd01667 | ||
|
|
9183421b0f | ||
|
|
6f6a9d06b5 | ||
|
|
ffdaa87702 | ||
|
|
e6e96cb2a6 | ||
|
|
9cc29462a3 | ||
|
|
61b8f83a40 | ||
|
|
998c9c47a0 | ||
|
|
65a1e80cf8 | ||
|
|
2ef64b08f1 | ||
|
|
40b2312e0e | ||
|
|
9fd31406e5 | ||
|
|
4d67a44d82 | ||
|
|
fe72d361e2 | ||
|
|
ff3d48340f | ||
|
|
42f09e0d81 | ||
|
|
ea773cb4d1 | ||
|
|
137f46ec3b | ||
|
|
6d853c7379 | ||
|
|
c688942a23 | ||
|
|
45e500069e | ||
|
|
f93f3f177d | ||
|
|
5120027a66 | ||
|
|
bb8430c056 | ||
|
|
989b2c4772 | ||
|
|
1f6e2e00bd | ||
|
|
7b2e804a62 | ||
|
|
c34812e4bc | ||
|
|
45b1454fde | ||
|
|
9d9a8af94f | ||
|
|
b2336504a3 | ||
|
|
b19c9048bf | ||
|
|
5ba3b7d81e | ||
|
|
0e48280d29 | ||
|
|
15f784e1d5 | ||
|
|
b6b0bb192e | ||
|
|
fc9cb55d51 | ||
|
|
2c7204c3ae | ||
|
|
68981e0ee9 | ||
|
|
b273fcd2e8 | ||
|
|
19fbd1b919 | ||
|
|
9d7c78b609 | ||
|
|
8376be250c | ||
|
|
bfc48425d3 | ||
|
|
f9775fd17b | ||
|
|
16c03d85c9 | ||
|
|
b98974a482 | ||
|
|
e0062449db | ||
|
|
9b362cb08f | ||
|
|
e836cb66e4 | ||
|
|
34fbb9f86d | ||
|
|
4054e60592 | ||
|
|
3acaa530b4 | ||
|
|
e7617fec5c | ||
|
|
904fe2c53f | ||
|
|
887049bf4a | ||
|
|
835611547f | ||
|
|
e87ef9498a | ||
|
|
29d1f9ff7a | ||
|
|
26cab42476 | ||
|
|
6acd516a36 | ||
|
|
302d59ecdd | ||
|
|
fdef8e8326 | ||
|
|
bee1731f13 | ||
|
|
7f7a0030b9 | ||
|
|
6f3a3fe06b | ||
|
|
2b55393dd6 | ||
|
|
52f45998d0 | ||
|
|
9580eb5155 | ||
|
|
16cef4ccbe | ||
|
|
646050f8a3 | ||
|
|
f32fb2c094 | ||
|
|
82310b2cbf | ||
|
|
6b68969357 | ||
|
|
c18e94714e | ||
|
|
7289f3bae4 | ||
|
|
61873cfd72 | ||
|
|
9c8fe06bfe | ||
|
|
47a90042a2 | ||
|
|
e56fb73997 | ||
|
|
9ff55b69b3 | ||
|
|
023b159c32 | ||
|
|
42f0692d8c | ||
|
|
1c13b89e6f | ||
|
|
7c5bf81e24 | ||
|
|
52547ee3d9 | ||
|
|
74d5ddaba7 | ||
|
|
29c8f408b5 | ||
|
|
0697e49011 | ||
|
|
dff6a8aca2 | ||
|
|
f9bd230ca2 | ||
|
|
b4a0ecdcff | ||
|
|
32429ab687 | ||
|
|
fd343c56d5 | ||
|
|
fe7cd72f13 | ||
|
|
fcd3a469bc | ||
|
|
4388fb7dcf | ||
|
|
45b87a1272 | ||
|
|
713d725e03 | ||
|
|
be2f59ef88 | ||
|
|
e2444d93cf | ||
|
|
f80cab3fc6 | ||
|
|
f491a6a9af | ||
|
|
074f199ee9 | ||
|
|
69b5488f54 | ||
|
|
d15b911fd9 | ||
|
|
5aa345df57 | ||
|
|
2fa0cf041b | ||
|
|
9d15bb1355 | ||
|
|
f23cde93e0 | ||
|
|
05e0885362 | ||
|
|
b613a561f5 | ||
|
|
3ed79cae84 | ||
|
|
6e4e6cebd8 | ||
|
|
2a5754305e | ||
|
|
65dfc08b95 | ||
|
|
f96e142042 | ||
|
|
6c4763db47 | ||
|
|
8366f6c8da | ||
|
|
5f21702592 | ||
|
|
28401d668f | ||
|
|
e95f29b42c | ||
|
|
b4ebd3e0f5 | ||
|
|
4d9b214735 | ||
|
|
2732fdfcff | ||
|
|
de7d7f857e | ||
|
|
384b6ad329 | ||
|
|
2e0cc7ce87 | ||
|
|
ce4984f8dc | ||
|
|
899fb93e4b | ||
|
|
1d7809a93a | ||
|
|
3adf1db1d0 | ||
|
|
924ff86bdc | ||
|
|
5520d75b54 | ||
|
|
05973a65c1 | ||
|
|
58ddf450c7 | ||
|
|
349a1912d4 | ||
|
|
89939e76fa | ||
|
|
bd8f753ea5 | ||
|
|
c92718e73f | ||
|
|
403993e5a6 | ||
|
|
f0c3b0bfa9 | ||
|
|
00bc2daeac | ||
|
|
01bc30e49c | ||
|
|
724cc8f6d4 | ||
|
|
e3436d6935 | ||
|
|
641eee88e5 | ||
|
|
b6a2bcd89e | ||
|
|
fb0eb9aec4 | ||
|
|
0eb5a4de82 | ||
|
|
b8fe02e2b6 | ||
|
|
434ea8096b | ||
|
|
5e85ca7e5a | ||
|
|
cc175b9847 | ||
|
|
945e94dd80 | ||
|
|
447850f2ed | ||
|
|
c3fbd60564 | ||
|
|
795c3d914e | ||
|
|
fc16e7b29a | ||
|
|
00fba90928 | ||
|
|
24d82503ff | ||
|
|
4b76d6875b | ||
|
|
222c26bcc5 | ||
|
|
d03209c98f | ||
|
|
56091070e8 | ||
|
|
323258b5cb | ||
|
|
2df7afded1 | ||
|
|
c6f5a8d252 | ||
|
|
a1d68d0827 | ||
|
|
253d8bf269 | ||
|
|
8c702a4d2d | ||
|
|
95a55e9c47 | ||
|
|
b2988e4829 | ||
|
|
ba870d07b9 | ||
|
|
9efe6ceb9a | ||
|
|
51a809d95d | ||
|
|
ddd7a0403e | ||
|
|
9d619ee269 | ||
|
|
cc1272026f | ||
|
|
432b18acd7 | ||
|
|
e00e615b02 | ||
|
|
3b9a63d9bf | ||
|
|
08f35dd6e3 | ||
|
|
83dcbc48db | ||
|
|
b3deaaec27 | ||
|
|
8a9f25edcb | ||
|
|
ff67231514 | ||
|
|
fc7f0571f9 | ||
|
|
400b19d190 | ||
|
|
4700ed2706 | ||
|
|
3d39583fa2 | ||
|
|
e45f06debf | ||
|
|
9eebd2e6e8 | ||
|
|
0b74f65c3b | ||
|
|
0c199b10f8 | ||
|
|
1509591a50 | ||
|
|
55c856755a | ||
|
|
3756a62eac | ||
|
|
aa372d020b | ||
|
|
df527b03e0 | ||
|
|
74ff715a62 | ||
|
|
a9ccc27f81 | ||
|
|
71b023c16d | ||
|
|
45a5fec95a | ||
|
|
32a8f4bed4 | ||
|
|
e2c7671f00 | ||
|
|
cc1eb6bee2 | ||
|
|
273a6b0fbe | ||
|
|
c7547e3b40 | ||
|
|
71f3dd5e5c | ||
|
|
bf21280cf7 | ||
|
|
4ff038f62f | ||
|
|
d15dcb337f | ||
|
|
a847585450 | ||
|
|
346b7d5182 | ||
|
|
d6de2bf7b9 | ||
|
|
fd3837beba | ||
|
|
9b31e334b2 | ||
|
|
a27b08e563 | ||
|
|
46891d6be2 | ||
|
|
e5efb86bd2 | ||
|
|
08ff0ac7e5 | ||
|
|
fef9582f52 | ||
|
|
0c727603a2 | ||
|
|
454e69b144 | ||
|
|
c4d6bb26a6 | ||
|
|
a054a9dbf0 | ||
|
|
a43fd5f48d | ||
|
|
541d5aac0d | ||
|
|
4962076089 | ||
|
|
c543941320 | ||
|
|
34a355f0ea | ||
|
|
eb14d75430 | ||
|
|
a81ba225c2 | ||
|
|
2cddf69322 | ||
|
|
b361b287cd | ||
|
|
d229ef90ff | ||
|
|
565c6300cf | ||
|
|
5f551f58dc | ||
|
|
b4d1925e45 | ||
|
|
b0e18edc9a | ||
|
|
26de0e1a59 | ||
|
|
1ddf3c6f02 | ||
|
|
0e4b6ab807 | ||
|
|
cb5f2a27cc | ||
|
|
fe9b3b2bc0 | ||
|
|
88ac54ae1a | ||
|
|
21eee5adec | ||
|
|
ff36cd4733 | ||
|
|
32bd163416 | ||
|
|
b320a3e95e | ||
|
|
5a44403cf0 | ||
|
|
affe8b26eb | ||
|
|
c6f5c89cb0 | ||
|
|
513af9f83c | ||
|
|
4bc2c3ecd8 | ||
|
|
12d5425453 | ||
|
|
e9374aaf1c | ||
|
|
6fa354c221 | ||
|
|
2358211b47 | ||
|
|
9c78a3334c | ||
|
|
0db004ae35 | ||
|
|
4ebed5a046 | ||
|
|
34c5f5cf8b | ||
|
|
c5c55dc44e | ||
|
|
aad3458ce2 | ||
|
|
be05a411cf | ||
|
|
302cd1dc44 | ||
|
|
626fa7f059 | ||
|
|
79a9f97157 | ||
|
|
c140b302eb | ||
|
|
58ae29d1eb | ||
|
|
3e2c7dcf2c | ||
|
|
610667c6e6 | ||
|
|
1e1924b913 | ||
|
|
e8898e6871 | ||
|
|
7c4b2638d1 | ||
|
|
b60b5cfa71 | ||
|
|
aa1f3fbe6a | ||
|
|
080adfa133 | ||
|
|
9d2bb9939d | ||
|
|
fcba8adedd | ||
|
|
edd9bb8f2a | ||
|
|
0d10382cef | ||
|
|
978cac9c01 | ||
|
|
5d3f1f308c | ||
|
|
192aab5371 | ||
|
|
1314e81937 | ||
|
|
e5cff3c496 | ||
|
|
98efacb4f2 | ||
|
|
7061f135e6 | ||
|
|
8fef6bfb71 | ||
|
|
9fd1d4ce7f | ||
|
|
bc8ee3592d | ||
|
|
4e190b7dfd | ||
|
|
6265aa7271 | ||
|
|
f66d5e6116 | ||
|
|
fda7755102 | ||
|
|
5f8482cdae | ||
|
|
31bc1a10b0 | ||
|
|
a9080ba01a | ||
|
|
31257449ed | ||
|
|
b712706149 | ||
|
|
82ff7762f2 | ||
|
|
6acca200c1 | ||
|
|
dc1ef983c2 | ||
|
|
9c845fb614 | ||
|
|
93582696fe | ||
|
|
a0dc81804e | ||
|
|
da129386a1 | ||
|
|
3b5b20c3e4 | ||
|
|
9eba229c91 | ||
|
|
627d7ca371 | ||
|
|
8ff0ea1bb5 | ||
|
|
14f58d5aec | ||
|
|
e522602535 | ||
|
|
698bf7b788 | ||
|
|
835d567fec | ||
|
|
ba702a1dae | ||
|
|
97ee4eaef2 | ||
|
|
8fb91fe58b | ||
|
|
be808be3db | ||
|
|
eebd7d6f45 | ||
|
|
2aaffaa208 | ||
|
|
bf89a162e2 | ||
|
|
fe5d3b4626 | ||
|
|
f3a1cfacf8 | ||
|
|
8f25f562e9 | ||
|
|
8bfbab57f7 | ||
|
|
e31f194938 | ||
|
|
8aeee1e238 | ||
|
|
0a25ee9197 | ||
|
|
c83c86592a | ||
|
|
f5300ecdf1 | ||
|
|
198db60c51 | ||
|
|
bb25c94aef | ||
|
|
d1ca1e9b2c | ||
|
|
178509eb21 | ||
|
|
2d6e8ed673 | ||
|
|
95eeba8e53 | ||
|
|
f0fbf318f4 | ||
|
|
4cb822cbf2 | ||
|
|
e1ad30ebe8 | ||
|
|
63b92bd4a9 | ||
|
|
c5de5cb1af | ||
|
|
71cf55be3f | ||
|
|
74a30a8215 | ||
|
|
db452a2da0 | ||
|
|
0b5d1211fa | ||
|
|
084388087e | ||
|
|
cbbd6fab2d | ||
|
|
d9e3496e5e | ||
|
|
d896f16cbf | ||
|
|
10381dfdba | ||
|
|
310048acf9 | ||
|
|
3ac04c6aaf | ||
|
|
6a8a3b9c8a | ||
|
|
d892661acd | ||
|
|
dd1bb75b8a | ||
|
|
2d7979e9ee | ||
|
|
f6c1c04394 | ||
|
|
38e1ece16f | ||
|
|
7513f136ba | ||
|
|
f429a7b618 | ||
|
|
1c1c9d107b | ||
|
|
f259d2a846 | ||
|
|
792babb049 | ||
|
|
a34b1724b1 | ||
|
|
51ad3b0c76 | ||
|
|
fc36174953 | ||
|
|
7e731b9826 | ||
|
|
63bec34d7a | ||
|
|
fc97cc7d70 | ||
|
|
4e302d0b7a | ||
|
|
3bdd6c76b9 | ||
|
|
e0e26f57aa | ||
|
|
b51e4c459c | ||
|
|
f4a4f0c19d | ||
|
|
88c659ac77 | ||
|
|
49841fa27e | ||
|
|
96ed2fa316 | ||
|
|
39c5529de0 | ||
|
|
b3788cfcdc | ||
|
|
1d94d54e9d | ||
|
|
79a9bdbb57 | ||
|
|
d890a6b345 | ||
|
|
a61ccc57a9 | ||
|
|
c37d935a1d | ||
|
|
986090fb9c | ||
|
|
e6d8200f3a | ||
|
|
f2a9d10e29 | ||
|
|
76818e28d7 | ||
|
|
9642b067a0 | ||
|
|
a90b49ecd8 | ||
|
|
e82560259b | ||
|
|
ea1429a209 | ||
|
|
63122bfbf8 | ||
|
|
0596c97267 | ||
|
|
1838710c0d | ||
|
|
49de5cdc77 | ||
|
|
f2c95bc075 | ||
|
|
d126824dfd | ||
|
|
cc923523be | ||
|
|
102ed7282a | ||
|
|
47b42d6fc0 | ||
|
|
6a811008eb | ||
|
|
1ebd9888be | ||
|
|
60ae4977da | ||
|
|
8ae8bc649e | ||
|
|
36afd25129 | ||
|
|
2d2bfca7af | ||
|
|
35f4651ed6 | ||
|
|
9a248858a5 | ||
|
|
7df85b5fad | ||
|
|
c45a5872c7 | ||
|
|
4deee0d990 | ||
|
|
6862af1323 | ||
|
|
4cc8d37d33 | ||
|
|
289815878a | ||
|
|
9829d3c243 | ||
|
|
2be4a43425 | ||
|
|
095006d12c | ||
|
|
52fd5d352f | ||
|
|
a9cdf2bc6f | ||
|
|
83f8187dbd | ||
|
|
7ed9085c31 | ||
|
|
ff9d025b65 | ||
|
|
99dd35250c | ||
|
|
69b2c875fe | ||
|
|
bf4aeeb809 | ||
|
|
ad90f79907 | ||
|
|
0a935ce583 | ||
|
|
0aef2d93fc | ||
|
|
f99d296687 | ||
|
|
12e232e240 | ||
|
|
1da0f01d16 | ||
|
|
943f538953 | ||
|
|
b642139679 | ||
|
|
b0227f7e9f | ||
|
|
4319175905 | ||
|
|
12c97d16b8 | ||
|
|
64d8eb85c5 | ||
|
|
55028b829c | ||
|
|
182f6d7857 | ||
|
|
efc610b17d | ||
|
|
d51f1e93c7 | ||
|
|
000e1607f8 | ||
|
|
2aee05201d | ||
|
|
bad0db1775 | ||
|
|
8835b4db7f | ||
|
|
93cd30f820 | ||
|
|
4b00be7f66 | ||
|
|
25e549b7e2 | ||
|
|
1f8b68f5ee | ||
|
|
4f44475629 | ||
|
|
ba08fe9631 | ||
|
|
71174f5978 | ||
|
|
e38887c607 | ||
|
|
7aea765612 | ||
|
|
9fbae6eb08 | ||
|
|
fe0df93176 | ||
|
|
f0e6cdaecc | ||
|
|
a90b9883d1 | ||
|
|
a8a1c4c64e | ||
|
|
b4f62362a3 | ||
|
|
37ee5e2a76 | ||
|
|
deb886066b | ||
|
|
4cd581ec04 | ||
|
|
cbbcc3a69e | ||
|
|
55dd3ab113 | ||
|
|
9741cfc2f6 | ||
|
|
071a25267e | ||
|
|
376cbc3116 | ||
|
|
ae6e840811 | ||
|
|
62a9f6572c | ||
|
|
25c4d627f1 | ||
|
|
7d7834a545 | ||
|
|
4e3befec24 | ||
|
|
65cbad5deb | ||
|
|
c1ba2b5338 | ||
|
|
2a71e2cb0b | ||
|
|
e1e4f9a8b4 | ||
|
|
eb7889e206 | ||
|
|
8e5d921113 | ||
|
|
340db9b939 | ||
|
|
3dc967003a | ||
|
|
dcf12130f4 | ||
|
|
eb1e2e011a | ||
|
|
3a7af6ecc8 | ||
|
|
da2a1f811a | ||
|
|
378232bc4d | ||
|
|
1d0447117a | ||
|
|
4223e12187 | ||
|
|
961e88c0bd | ||
|
|
bc5ef77216 | ||
|
|
a8c8c5050d | ||
|
|
0b16fe486a | ||
|
|
a3eb55c960 | ||
|
|
78c21c7b29 | ||
|
|
87ed2cbeff | ||
|
|
66f79aba05 | ||
|
|
c11dc4b318 | ||
|
|
8c188d1d40 | ||
|
|
d63288d21b | ||
|
|
a49adf93ee | ||
|
|
7b90dcf0a3 | ||
|
|
f5c6252b85 | ||
|
|
8bf47fc05a | ||
|
|
e0ba7f2a92 | ||
|
|
70915ecaed | ||
|
|
b986a7ebb3 | ||
|
|
1ce767b503 | ||
|
|
4faaf88da1 | ||
|
|
2cbe228c7c | ||
|
|
6186fbc671 | ||
|
|
5dc7a288a4 | ||
|
|
3b550198c7 | ||
|
|
c590fdc4fb | ||
|
|
a16063f030 | ||
|
|
b723a818cf | ||
|
|
caf63718e7 | ||
|
|
46d3360f8d | ||
|
|
0351725d80 | ||
|
|
a617ac0665 | ||
|
|
c4453f2571 | ||
|
|
12e0253cfe | ||
|
|
87db68baf8 | ||
|
|
6521ef0fde | ||
|
|
6d5530b64f | ||
|
|
6764313f66 | ||
|
|
0915458d34 | ||
|
|
62fc711cc2 | ||
|
|
c2ea04c889 | ||
|
|
368dd801e0 | ||
|
|
9489de5d95 | ||
|
|
f201955c0c | ||
|
|
a9064b2567 | ||
|
|
00fa293cb9 | ||
|
|
24d977d824 | ||
|
|
423a179308 | ||
|
|
6388188217 | ||
|
|
73170acfd4 | ||
|
|
5e8ff3cdef | ||
|
|
20c9f599c6 | ||
|
|
7aeac45d0e | ||
|
|
dc498f8927 | ||
|
|
88dd9edde5 | ||
|
|
e4198d91f8 | ||
|
|
e7802ca609 | ||
|
|
573d91cbc7 | ||
|
|
58186b0436 | ||
|
|
d4345a1a16 | ||
|
|
e125863fd4 | ||
|
|
38b40fe93a | ||
|
|
033814198f | ||
|
|
568f9bc2e6 | ||
|
|
a7a5401996 | ||
|
|
cb1c74bf9f | ||
|
|
91f466cd07 | ||
|
|
aa83caa993 | ||
|
|
3208d2ef3d | ||
|
|
8ff5337ad7 | ||
|
|
4fccbb49c9 | ||
|
|
bbfcd467c9 | ||
|
|
37870e8c39 | ||
|
|
d2f242f368 | ||
|
|
afdf9ced94 | ||
|
|
8d67658b6e | ||
|
|
706fe4d881 | ||
|
|
127b8bf62c | ||
|
|
6b724b4fc1 | ||
|
|
54945ad3d5 | ||
|
|
f51d9c36b0 | ||
|
|
42f388e370 | ||
|
|
ff5385e0af | ||
|
|
7c1ffe9b17 | ||
|
|
1f9a5cd831 | ||
|
|
6dd3e21498 | ||
|
|
b8e100664b | ||
|
|
9b6013fc45 | ||
|
|
fbb669046a | ||
|
|
487306a3a5 | ||
|
|
e3e4f57f92 | ||
|
|
1415547eb8 | ||
|
|
92d5d20595 | ||
|
|
1a58af5f05 | ||
|
|
11ce757846 | ||
|
|
b72b02ab1e | ||
|
|
4c3dc5a3ea | ||
|
|
675390a00d | ||
|
|
616e69dd92 | ||
|
|
b0f306193b | ||
|
|
2f8c626310 | ||
|
|
b3d476dea4 | ||
|
|
f99043db30 | ||
|
|
0ddba57c0d | ||
|
|
717257ec9b | ||
|
|
a15a6e6fe7 | ||
|
|
02c6fa734e | ||
|
|
c81122d745 | ||
|
|
9fc1ea65a5 | ||
|
|
e5f64ec9dd | ||
|
|
d7e7d85a40 | ||
|
|
c7ffa5a572 | ||
|
|
b18d97a4ed | ||
|
|
2cc6b1af11 | ||
|
|
e21994d54c | ||
|
|
55fcb5908f | ||
|
|
8c40eb69d5 | ||
|
|
28fa7ac538 | ||
|
|
3292816967 | ||
|
|
19aa60cccd | ||
|
|
0efb3eea8e | ||
|
|
1a6e554ee9 | ||
|
|
8587667e27 | ||
|
|
0c79b17163 | ||
|
|
0a5ac68df4 | ||
|
|
64eda2b44f | ||
|
|
3e978f44e7 | ||
|
|
370ab4f5d0 | ||
|
|
8e84dd0af6 | ||
|
|
f2875b1b2b | ||
|
|
702a525893 | ||
|
|
c4c11cf61f | ||
|
|
06b1b8deeb | ||
|
|
0beb000d4b | ||
|
|
acc871e609 | ||
|
|
e8545176e7 | ||
|
|
532a47bda5 | ||
|
|
ddc2d956ba | ||
|
|
563f57e3aa | ||
|
|
0a973cefd2 | ||
|
|
2563ade159 | ||
|
|
1763a109c4 | ||
|
|
f57b5a2166 | ||
|
|
7210e6b86c | ||
|
|
6b241d7439 | ||
|
|
833995ca61 | ||
|
|
40531e9554 | ||
|
|
7a5a9c8a51 | ||
|
|
daae97b3d4 | ||
|
|
eeeaacb4db | ||
|
|
5324a9127d | ||
|
|
bbd267d4f0 | ||
|
|
53495e34e5 | ||
|
|
7026d8b0d5 | ||
|
|
a3b57ac50e | ||
|
|
4910692576 | ||
|
|
5147835d48 | ||
|
|
3a8d79d4da | ||
|
|
f1684c11a3 | ||
|
|
f38b6ef6dd | ||
|
|
d895f3e4bb | ||
|
|
e8b7d7d908 | ||
|
|
e7195b0e68 | ||
|
|
2983ede83d | ||
|
|
091a6eabb6 | ||
|
|
63a793c22a | ||
|
|
9d91644ed7 | ||
|
|
813f8972f3 | ||
|
|
ea22da2c9b | ||
|
|
99536142bc | ||
|
|
3a11e79748 | ||
|
|
ad1b79270f | ||
|
|
a7417f1a1f | ||
|
|
db1ba37b59 | ||
|
|
1f60265502 | ||
|
|
463ba3dcf9 | ||
|
|
948f85bcb6 | ||
|
|
dcd2bfa65b | ||
|
|
b9ca301acc | ||
|
|
2f6a45d4b7 | ||
|
|
32d25937cb | ||
|
|
3fe9af3afa | ||
|
|
28c869f177 | ||
|
|
a003db77e4 | ||
|
|
c6b80083b8 | ||
|
|
f58b400364 | ||
|
|
bcfe69981d | ||
|
|
53b7017d12 | ||
|
|
2c17c5ed78 | ||
|
|
40347fa73b | ||
|
|
e01012b99e | ||
|
|
ded3ed510e | ||
|
|
1731a7e8ba | ||
|
|
9af75aca5d | ||
|
|
9a54e48d75 | ||
|
|
cdfc8e7e1b | ||
|
|
0a06133d3d | ||
|
|
1f28ff2ab6 | ||
|
|
99615a36d7 | ||
|
|
59c743ca8d | ||
|
|
01027e4f35 | ||
|
|
4d675f579d | ||
|
|
02ee3bce53 | ||
|
|
d053b07974 | ||
|
|
2668cc2bd0 | ||
|
|
d776e483cf | ||
|
|
3e9672bf30 | ||
|
|
70ab6dafd3 | ||
|
|
fb97e653cc | ||
|
|
a5f8fbdf80 | ||
|
|
2b1a3f6eb3 | ||
|
|
5839901e57 | ||
|
|
85466d8b5a | ||
|
|
b6446f5dd2 | ||
|
|
978e6a3d0c | ||
|
|
56cc106c11 | ||
|
|
97e5969362 | ||
|
|
0192bb5491 | ||
|
|
608f30e32f | ||
|
|
949af6b22c | ||
|
|
3b6ec4bf5e | ||
|
|
1647674da0 | ||
|
|
01aa08f0a3 | ||
|
|
f7647f851a | ||
|
|
cfdec679f1 | ||
|
|
3fe8ea27ba | ||
|
|
ddf03547a3 | ||
|
|
f0748dbf42 | ||
|
|
e14df4f83b | ||
|
|
4ead85965a | ||
|
|
0ce04415ea | ||
|
|
87fb343828 | ||
|
|
43a36c4f6c | ||
|
|
3da90114d1 | ||
|
|
f74253584b | ||
|
|
6ca4372d1b | ||
|
|
9718160aeb | ||
|
|
283f0c53f0 | ||
|
|
201372f9e8 | ||
|
|
e63274e6c0 | ||
|
|
7ff0579875 | ||
|
|
e0ba773e78 | ||
|
|
bdf924918e | ||
|
|
f0401f2b47 | ||
|
|
bddf099323 | ||
|
|
0580c8ae55 | ||
|
|
ac007a7d12 | ||
|
|
d5c55407b3 | ||
|
|
42ad54e3df | ||
|
|
d13da54dab | ||
|
|
21efa0371a | ||
|
|
ebf91cf98c | ||
|
|
4f4cf083ad | ||
|
|
a6a1781ab9 | ||
|
|
3f3a00e457 | ||
|
|
0382663191 | ||
|
|
f838b3389b | ||
|
|
73885f117a | ||
|
|
0bde6ed45f | ||
|
|
f550d65897 | ||
|
|
5246b2b82d | ||
|
|
6e99d5beed | ||
|
|
69936d55b6 | ||
|
|
d191820317 | ||
|
|
c144c1761d | ||
|
|
267f7b1e53 | ||
|
|
c45364ef99 | ||
|
|
a2542a8c12 | ||
|
|
2e2fb1828d | ||
|
|
f007f30c0d | ||
|
|
74881094ab | ||
|
|
ee98282475 | ||
|
|
e49ec14c41 | ||
|
|
56f4604819 | ||
|
|
56eb5ba8a8 | ||
|
|
8206dff4c1 | ||
|
|
f7426a4439 | ||
|
|
c478ca691d | ||
|
|
a3ff3cafa4 | ||
|
|
313d353ae5 | ||
|
|
dabf391576 | ||
|
|
8ad552b0da | ||
|
|
c16c25da77 | ||
|
|
aa1fc829b7 | ||
|
|
e5eea110f1 | ||
|
|
2e5828779f | ||
|
|
cc2e73ae5a | ||
|
|
b89840f103 | ||
|
|
12b32472ba | ||
|
|
86ac2ade1e | ||
|
|
a180c46b5d | ||
|
|
34555f8bb5 | ||
|
|
4db8826e4d | ||
|
|
69358541bf | ||
|
|
896c92b678 | ||
|
|
6ef52c5184 | ||
|
|
5b098b79a5 | ||
|
|
2cab6c82e4 | ||
|
|
91d3012581 | ||
|
|
354b60db53 | ||
|
|
fd89c42e48 | ||
|
|
79a862dd0e | ||
|
|
54a20246db | ||
|
|
822bfc239f | ||
|
|
f80bf929f7 | ||
|
|
e201d88e7a | ||
|
|
ce5443ca9a | ||
|
|
4b570f7928 | ||
|
|
b5152eb852 | ||
|
|
c5315be572 | ||
|
|
b4a2c76736 | ||
|
|
53726a6a26 | ||
|
|
84ec2b7b26 | ||
|
|
336a8b5150 | ||
|
|
4a6480d223 | ||
|
|
017b26986b | ||
|
|
6287bc85fe | ||
|
|
2a54c7101f | ||
|
|
6804f5b5f7 | ||
|
|
574e8739c1 | ||
|
|
89e3c9f76d | ||
|
|
2f45e28bae | ||
|
|
dd8a0a18c2 | ||
|
|
a2edbe42ed | ||
|
|
b4f73263e6 | ||
|
|
513397ca0f | ||
|
|
abb702ffa3 | ||
|
|
a13569e5fb | ||
|
|
84cd99468f | ||
|
|
723824ee7d | ||
|
|
f6c1e217f0 | ||
|
|
4d1bca5e51 | ||
|
|
70bb1e865a | ||
|
|
88b4856fe1 | ||
|
|
460689841a | ||
|
|
73014c71a1 | ||
|
|
0d8753f44e | ||
|
|
2a43a87e08 | ||
|
|
32b376d85a | ||
|
|
d40dbb2676 | ||
|
|
4cf4bae2e9 | ||
|
|
162ab3f693 | ||
|
|
5f7978f21e | ||
|
|
3d95ba63e3 | ||
|
|
55df09e04b | ||
|
|
bdc3beb15a | ||
|
|
fa7bb801db | ||
|
|
e68d6acf94 | ||
|
|
a9c1d58ddc | ||
|
|
0fa4d5e2a6 | ||
|
|
3203daf787 | ||
|
|
b576a97db0 | ||
|
|
a461ad6835 | ||
|
|
33ab56dc03 | ||
|
|
641766a828 | ||
|
|
452b551e88 | ||
|
|
d31fb4ff2b | ||
|
|
e325d58944 | ||
|
|
185dde9d34 | ||
|
|
04afb5b891 | ||
|
|
a7442e61b1 | ||
|
|
2a35de0afd | ||
|
|
5351e61687 | ||
|
|
e83c468fba | ||
|
|
70cf69d9db | ||
|
|
a84d16a1dd | ||
|
|
ea3347b36d | ||
|
|
2865259a6a | ||
|
|
cb6c5e2de2 | ||
|
|
a6a8dfb78b | ||
|
|
927f4c3a34 | ||
|
|
b8a6397533 | ||
|
|
5afd22a507 | ||
|
|
8c065bbe25 | ||
|
|
403a7d13a4 | ||
|
|
28ebc497d8 | ||
|
|
a8a05fc4c0 | ||
|
|
f2df0d9e4a | ||
|
|
b47ecaa5f9 | ||
|
|
a5d85a211d | ||
|
|
d9355ceab0 | ||
|
|
bc2cac5c08 | ||
|
|
e714778085 | ||
|
|
0be9bcef6b | ||
|
|
2511eac165 | ||
|
|
1343fbe15c | ||
|
|
34eca6b0ea | ||
|
|
1e0b874952 | ||
|
|
2c49920ea8 | ||
|
|
291a214051 | ||
|
|
cb2225d420 | ||
|
|
66bc45f96e | ||
|
|
814b7324b6 | ||
|
|
69fb043e96 | ||
|
|
7a54acc8eb | ||
|
|
2620c268b1 | ||
|
|
f255dd182d | ||
|
|
149f2e679f | ||
|
|
800d10de96 | ||
|
|
90a9fbe6af | ||
|
|
e0935f1e70 | ||
|
|
713cd19f47 | ||
|
|
07b3ab08b8 | ||
|
|
943788687d | ||
|
|
377ee76237 | ||
|
|
b080adc069 | ||
|
|
52c10f2223 | ||
|
|
ac8df87e08 | ||
|
|
f4c288bc6e | ||
|
|
b95c38ab38 | ||
|
|
bba2327aec | ||
|
|
35a5d8ca7f | ||
|
|
9eb2ab6dbb | ||
|
|
fad6e21dab | ||
|
|
f4c6481520 | ||
|
|
7930a652dd | ||
|
|
ee3a9cf6fd | ||
|
|
94a4211d63 | ||
|
|
80daf47f60 | ||
|
|
8b0af8469e | ||
|
|
a658bfcbde | ||
|
|
832ceb8827 | ||
|
|
884283b7b1 | ||
|
|
dac0fee8d4 | ||
|
|
566470cf2e | ||
|
|
f76fcfbcae | ||
|
|
2b770deee8 | ||
|
|
6e8c72dc22 | ||
|
|
4cb91bd46c | ||
|
|
437417dadd | ||
|
|
9c20956ac5 | ||
|
|
7c23250d83 | ||
|
|
fe71dc8a99 | ||
|
|
a261c555c9 | ||
|
|
94637d4a91 | ||
|
|
e337b3bb09 | ||
|
|
a0eda50175 | ||
|
|
d5d7a6a183 | ||
|
|
5a2caab7fc | ||
|
|
8db90b6c2f | ||
|
|
1c18fab68e | ||
|
|
42b59cd066 | ||
|
|
a47b85ff85 | ||
|
|
0f1b3f05f9 | ||
|
|
01482e8dd0 | ||
|
|
771d8b3391 | ||
|
|
9d17c5d791 | ||
|
|
0fe0e1a84d | ||
|
|
5d542fbf5e | ||
|
|
72979ee309 | ||
|
|
9054f03556 | ||
|
|
6db61d164f | ||
|
|
9c7b9a6c7a | ||
|
|
2b16198f22 | ||
|
|
88bb631eea | ||
|
|
6c22724835 | ||
|
|
ab57163695 | ||
|
|
e31b0403cd | ||
|
|
2642268383 | ||
|
|
690dca0bd7 | ||
|
|
28ba310b67 | ||
|
|
a58b1bd4a3 | ||
|
|
9259043e6d | ||
|
|
2d5b736e74 | ||
|
|
9fbbfe618b | ||
|
|
3ace90432f | ||
|
|
acd80a724d | ||
|
|
57edf48d13 | ||
|
|
eac5d2029f | ||
|
|
bfc9d8f66a | ||
|
|
c01f588541 | ||
|
|
cda211a3d6 | ||
|
|
b527ee56b7 | ||
|
|
a3145251de | ||
|
|
5c2f0edadc | ||
|
|
af22b5158a | ||
|
|
80d4f377b0 | ||
|
|
c611d1dee8 | ||
|
|
56d430046a | ||
|
|
30e9f36889 | ||
|
|
11ceb1098f | ||
|
|
031208f096 | ||
|
|
ba37ab445d | ||
|
|
7edbe4a82f | ||
|
|
4d0bdf6789 | ||
|
|
e98fe07c02 | ||
|
|
2e4142c93e | ||
|
|
38c9848509 | ||
|
|
8960478939 | ||
|
|
93ac4cf697 | ||
|
|
adf32e287f | ||
|
|
e056dee16c | ||
|
|
5db6df045c | ||
|
|
cc73707c73 | ||
|
|
ec90bd2d32 | ||
|
|
3d072cf14b | ||
|
|
3c5d40377f | ||
|
|
a4f88ca928 | ||
|
|
8e5735726b | ||
|
|
29c665fcf9 | ||
|
|
82e9ffe162 | ||
|
|
4b1d04733d | ||
|
|
574a5c65d3 | ||
|
|
05a1490e42 | ||
|
|
428e7b2966 | ||
|
|
e4060ad533 | ||
|
|
f436e692ae | ||
|
|
c9cd228850 | ||
|
|
cbe7fbbeea | ||
|
|
bc0eae4cf2 | ||
|
|
4b4f031421 | ||
|
|
767423b0dc | ||
|
|
d1556a68cf | ||
|
|
a19e131216 | ||
|
|
d14fbd8b59 | ||
|
|
6f8948010b | ||
|
|
e0cd052ea0 | ||
|
|
e12b64e20f | ||
|
|
05b697879d | ||
|
|
b1a54fe9db | ||
|
|
7b654d3a2d | ||
|
|
614307021b | ||
|
|
7d484437f9 | ||
|
|
af2c5c98ef | ||
|
|
b9aa5fbefc | ||
|
|
fe986c1aee | ||
|
|
23442b56b7 | ||
|
|
35d74cae1b | ||
|
|
8d862f75ee | ||
|
|
292867d4d9 | ||
|
|
9ee90d3cc2 | ||
|
|
91e398bace | ||
|
|
6e42d213df | ||
|
|
c6d6ebefe6 | ||
|
|
c6dfa65e93 | ||
|
|
789a846271 | ||
|
|
8bd926c05a | ||
|
|
7abc3b755b | ||
|
|
b65d8fb703 | ||
|
|
facbbb1a33 | ||
|
|
4ed9f5d293 | ||
|
|
ed0e4498b4 | ||
|
|
1d92dbe57f | ||
|
|
398febf8a3 | ||
|
|
0cb7404961 | ||
|
|
a3e8ed3df3 | ||
|
|
7b9bec217a | ||
|
|
83e6addd94 | ||
|
|
5d4e2eaf64 | ||
|
|
b23f634c9b | ||
|
|
1fe3d57cc8 | ||
|
|
cd848bf2bb | ||
|
|
0bbe8bf2b4 | ||
|
|
4b4b323164 | ||
|
|
df8044ba74 | ||
|
|
18de88dda8 | ||
|
|
95e546ad93 | ||
|
|
5bee79f3aa | ||
|
|
18d5893db1 | ||
|
|
06d9014ebe | ||
|
|
4b7369661c | ||
|
|
63c8a6540e | ||
|
|
b5ae8eafba | ||
|
|
70d89ad008 | ||
|
|
fab8c667d2 | ||
|
|
85d4dcbe27 | ||
|
|
278935661a | ||
|
|
ee2c3e5255 | ||
|
|
ee178455a3 | ||
|
|
9321f535ae | ||
|
|
486f8e30ed | ||
|
|
60a36066e5 | ||
|
|
9703336e81 | ||
|
|
4b24c0e472 | ||
|
|
08680fd359 | ||
|
|
027803a146 | ||
|
|
add79ba0b8 | ||
|
|
114822d319 | ||
|
|
1ab1cf1d6a | ||
|
|
876d275400 | ||
|
|
e05ea63e08 | ||
|
|
d57662811e | ||
|
|
ca83301ae3 | ||
|
|
ff9a7631ee | ||
|
|
6fa197d0d1 | ||
|
|
331297e4f8 | ||
|
|
b9f25c5e92 | ||
|
|
6d597afb99 | ||
|
|
e876b1fb3e | ||
|
|
830aea1f4e | ||
|
|
e0209d9d75 | ||
|
|
36bfbb69c6 | ||
|
|
289d3e90b7 | ||
|
|
24678372af |
@@ -15,9 +15,6 @@ ArchiSteamFarm/logs
|
||||
# Ignore standard out folders for publishing
|
||||
**/out
|
||||
|
||||
# Ignore crowdin CLI secret (if exists)
|
||||
tools/ArchiCrowdin/crowdin_identity.yml
|
||||
|
||||
# _ ____ _____ ____ _
|
||||
# / \ / ___|| ___| | _ \ ___ ___| | _____ _ __
|
||||
# / _ \ \___ \| |_ _____| | | |/ _ \ / __| |/ / _ \ '__|
|
||||
@@ -30,11 +27,8 @@ tools/ArchiCrowdin/crowdin_identity.yml
|
||||
**/[Bb]in/
|
||||
**/[Oo]bj/
|
||||
|
||||
ArchiSteamFarm.CustomPlugins.ExamplePlugin
|
||||
ASF-WebConfigGenerator
|
||||
ArchiSteamFarm.CustomPlugins.*
|
||||
ASF-ui/dist
|
||||
ASF-ui/tools
|
||||
tools
|
||||
wiki
|
||||
|
||||
# _ _
|
||||
|
||||
210
.editorconfig
210
.editorconfig
@@ -1,9 +1,9 @@
|
||||
root = true
|
||||
|
||||
###############################
|
||||
# Core EditorConfig Options #
|
||||
###############################
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
@@ -11,10 +11,17 @@ insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
# C# Coding Conventions #
|
||||
###############################
|
||||
|
||||
[*.cs]
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = false
|
||||
csharp_indent_labels = flush_left
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
csharp_new_line_before_catch = false
|
||||
csharp_new_line_before_else = false
|
||||
csharp_new_line_before_finally = false
|
||||
@@ -23,57 +30,172 @@ csharp_new_line_before_members_in_object_initializers = false
|
||||
csharp_new_line_before_open_brace = none
|
||||
csharp_new_line_between_query_expression_clauses = false
|
||||
|
||||
csharp_prefer_braces = true:suggestion
|
||||
csharp_prefer_braces = true:warning
|
||||
csharp_prefer_simple_default_expression = true:warning
|
||||
csharp_prefer_simple_using_statement = true:warning
|
||||
csharp_prefer_static_local_function = true:warning
|
||||
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||
csharp_preferred_modifier_order = public, protected, internal, private, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:warning
|
||||
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = false
|
||||
|
||||
csharp_space_after_cast = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = none
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
csharp_style_expression_bodied_accessors = true:suggestion
|
||||
csharp_style_expression_bodied_constructors = true:suggestion
|
||||
csharp_style_expression_bodied_indexers = true:suggestion
|
||||
csharp_style_expression_bodied_methods = true:suggestion
|
||||
csharp_style_expression_bodied_operators = true:suggestion
|
||||
csharp_style_expression_bodied_properties = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:warning
|
||||
csharp_style_deconstructed_variable_declaration = true:warning
|
||||
|
||||
csharp_style_var_elsewhere = false:suggestion
|
||||
csharp_style_var_for_built_in_types = false:suggestion
|
||||
csharp_style_var_when_type_is_apparent = false:suggestion
|
||||
csharp_style_expression_bodied_accessors = true:warning
|
||||
csharp_style_expression_bodied_constructors = true:warning
|
||||
csharp_style_expression_bodied_indexers = true:warning
|
||||
csharp_style_expression_bodied_lambdas = true:warning
|
||||
csharp_style_expression_bodied_local_functions = true:warning
|
||||
csharp_style_expression_bodied_methods = true:warning
|
||||
csharp_style_expression_bodied_operators = true:warning
|
||||
csharp_style_expression_bodied_properties = true:warning
|
||||
|
||||
csharp_using_directive_placement = outside_namespace:suggestion
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
|
||||
csharp_style_inlined_variable_declaration = true:warning
|
||||
|
||||
csharp_style_pattern_local_over_anonymous_function = true:warning
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:warning
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
|
||||
|
||||
csharp_style_prefer_index_operator = true:warning
|
||||
csharp_style_prefer_not_pattern = true:warning
|
||||
csharp_style_prefer_pattern_matching = true:warning
|
||||
csharp_style_prefer_range_operator = true:warning
|
||||
csharp_style_prefer_switch_expression = true:warning
|
||||
|
||||
csharp_style_throw_expression = true:warning
|
||||
|
||||
csharp_style_unused_value_assignment_preference = discard_variable :warning
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
|
||||
|
||||
csharp_style_var_elsewhere = false:warning
|
||||
csharp_style_var_for_built_in_types = false:warning
|
||||
csharp_style_var_when_type_is_apparent = false:warning
|
||||
|
||||
csharp_using_directive_placement = outside_namespace
|
||||
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
###############################
|
||||
|
||||
[*.{cs,vb}]
|
||||
# PascalCase for naming everything but parameters
|
||||
dotnet_naming_rule.all_members_must_be_capitalized.severity = suggestion
|
||||
dotnet_naming_rule.all_members_must_be_capitalized.style = all_symbols
|
||||
dotnet_naming_rule.all_members_must_be_capitalized.symbols = all_symbols
|
||||
dotnet_naming_style.all_symbols.capitalization = pascal_case
|
||||
dotnet_naming_symbols.all_symbols.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.all_symbols.applicable_kinds = class,struct,interface,enum,property,method,field,event,delegate
|
||||
dotnet_analyzer_diagnostic.severity = warning
|
||||
|
||||
# camelCase for naming parameters
|
||||
dotnet_naming_rule.parameters_must_be_camel_case.severity = suggestion
|
||||
dotnet_naming_rule.parameters_must_be_camel_case.style = params
|
||||
dotnet_naming_rule.parameters_must_be_camel_case.symbols = params
|
||||
dotnet_naming_style.params.capitalization = camel_case
|
||||
dotnet_naming_symbols.params.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.params.applicable_kinds = parameter
|
||||
dotnet_code_quality.ca3003.excluded_symbol_names = BotController
|
||||
dotnet_code_quality.ca3012.excluded_symbol_names = BotController|CommandController
|
||||
|
||||
dotnet_sort_system_directives_first = true:suggestion
|
||||
dotnet_code_quality_unused_parameters = all:warning
|
||||
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_return = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_require_accessibility_modifiers = always:suggestion
|
||||
dotnet_diagnostic.ca1028.severity = silent
|
||||
dotnet_diagnostic.ca1031.severity = silent
|
||||
|
||||
# Rule - almost everything
|
||||
dotnet_naming_rule.almost_everything_must_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.almost_everything_must_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.almost_everything_must_be_pascal_case.symbols = almost_everything
|
||||
|
||||
# Rule - interfaces
|
||||
dotnet_naming_rule.interfaces_must_be_i_pascal_case.severity = warning
|
||||
dotnet_naming_rule.interfaces_must_be_i_pascal_case.style = i_pascal_case
|
||||
dotnet_naming_rule.interfaces_must_be_i_pascal_case.symbols = interfaces
|
||||
|
||||
# Rule - local parameters
|
||||
dotnet_naming_rule.local_parameters_must_be_camel_case.severity = warning
|
||||
dotnet_naming_rule.local_parameters_must_be_camel_case.style = camel_case
|
||||
dotnet_naming_rule.local_parameters_must_be_camel_case.symbols = local_parameters
|
||||
|
||||
# Rule - type parameters
|
||||
dotnet_naming_rule.type_parameters_must_be_t_pascal_case.severity = warning
|
||||
dotnet_naming_rule.type_parameters_must_be_t_pascal_case.style = t_pascal_case
|
||||
dotnet_naming_rule.type_parameters_must_be_t_pascal_case.symbols = type_parameters
|
||||
|
||||
# Style - camelCase
|
||||
dotnet_naming_style.camel_case.capitalization = camel_case
|
||||
|
||||
# Style - IPascalCase
|
||||
dotnet_naming_style.i_pascal_case.capitalization = pascal_case
|
||||
dotnet_naming_style.i_pascal_case.required_prefix = I
|
||||
|
||||
# Style - PascalCase
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
# Style - TPascalCase
|
||||
dotnet_naming_style.t_pascal_case.capitalization = pascal_case
|
||||
dotnet_naming_style.t_pascal_case.required_prefix = T
|
||||
|
||||
# Symbol - almost everything
|
||||
dotnet_naming_symbols.almost_everything.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.almost_everything.applicable_kinds = namespace,class,struct,interface,enum,property,method,field,event,delegate,local_function
|
||||
|
||||
# Symbol - interfaces
|
||||
dotnet_naming_symbols.interfaces.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interfaces.applicable_accessibilities = *
|
||||
|
||||
# Symbol - local parameters
|
||||
dotnet_naming_symbols.local_parameters.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.local_parameters.applicable_kinds = parameter,local
|
||||
|
||||
# Symbol - type parameters
|
||||
dotnet_naming_symbols.type_parameters.applicable_kinds = type_parameter
|
||||
dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
|
||||
|
||||
dotnet_remove_unnecessary_suppression_exclusions = none:warning
|
||||
dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
||||
dotnet_style_coalesce_expression = true:warning
|
||||
dotnet_style_collection_initializer = true:warning
|
||||
dotnet_style_explicit_tuple_names = true:warning
|
||||
dotnet_style_null_propagation = true:warning
|
||||
dotnet_style_object_initializer = true:warning
|
||||
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:warning
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
|
||||
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
|
||||
dotnet_style_predefined_type_for_member_access = true:warning
|
||||
|
||||
dotnet_style_prefer_auto_properties = true:warning
|
||||
dotnet_style_prefer_compound_assignment = true:warning
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:warning
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:warning
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
|
||||
dotnet_style_prefer_inferred_tuple_names = true:warning
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:warning
|
||||
dotnet_style_prefer_simplified_interpolation = true:warning
|
||||
|
||||
dotnet_style_qualification_for_event = false:warning
|
||||
dotnet_style_qualification_for_field = false:warning
|
||||
dotnet_style_qualification_for_method = false:warning
|
||||
dotnet_style_qualification_for_property = false:warning
|
||||
|
||||
dotnet_style_readonly_field = true:warning
|
||||
dotnet_style_require_accessibility_modifiers = always:warning
|
||||
|
||||
123
.github/CODE_OF_CONDUCT.md
vendored
123
.github/CODE_OF_CONDUCT.md
vendored
@@ -2,45 +2,126 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at ASF@JustArchi.net. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at ASF@JustArchi.net.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
|
||||
16
.github/CONTRIBUTING.md
vendored
16
.github/CONTRIBUTING.md
vendored
@@ -4,7 +4,7 @@ Before making an issue or pull request, you should carefully read **[ASF wiki](h
|
||||
|
||||
## Issues
|
||||
|
||||
GitHub **[issues](https://github.com/JustArchiNET/ArchiSteamFarm/issues)** page is being used for ASF "todo" list, regarding both features and bugs. It has **strict policy** that applies to everybody - GitHub is **NOT** technical support, it's a place dedicated **only** to ASF bugs and suggestions. It's **not** proper place for technical issues, general discussion or questions that are unrelated to development. In short, GitHub is for the **development** part of the ASF, and all issues should be **development-oriented**. You have **[ASF chat](https://discord.gg/hSQgt8j)** and **[Steam group](https://steamcommunity.com/groups/archiasf/discussions/1)** for general discussion, questions, technical issues and everything else that is not related to ASF development. If you decide to use GitHub issues, please make sure that you're in fact dealing with a bug, or your suggestion makes sense, preferably by asking on chat/steam group first. Invalid issues will be closed immediately and won't be answered - if you're not sure if your issue is valid, then most likely it's not, and you shouldn't post it here. Valid bugs/suggestions will be forwarded and added as GitHub issues by us, if needed.
|
||||
**[GitHub issues](https://github.com/JustArchiNET/ArchiSteamFarm/issues)** page is being used for ASF "todo" list, regarding both features and bugs. It has **strict policy** that applies to everybody - GitHub issues is **NOT** technical support, it's a place dedicated **only** to ASF bugs and suggestions. It's **not** proper place for technical issues, general discussion or questions that are unrelated to development. In short, GitHub is for the **development** part of the ASF, and all issues should be **development-oriented**. You have **[GitHub discussions](https://github.com/JustArchiNET/ArchiSteamFarm/discussions/categories/support)**, **[Steam group](https://steamcommunity.com/groups/archiasf/discussions/1)** and **[Discord server](https://discord.gg/hSQgt8j)** for general discussion, questions, technical issues and everything else that is not related to ASF development. If you decide to use GitHub issues, please make sure that you're in fact dealing with a bug, or your suggestion makes sense, preferably by asking on one of our support channels first. Invalid issues will be closed immediately and won't be answered - if you're not sure if your issue is valid, then most likely it's not, and you shouldn't post it here. Valid bugs/suggestions will be forwarded and added as GitHub issues by us, if needed.
|
||||
|
||||
Examples of **invalid** issues:
|
||||
- Asking how to install the program or use one of its functions
|
||||
@@ -33,7 +33,7 @@ It would also be cool if you could reproduce your issue on latest **[pre-release
|
||||
|
||||
### Suggestions
|
||||
|
||||
While everybody is able to create suggestions how to improve ASF, GitHub issues is not the proper place to discuss if your enhancement makes sense - by posting it you already **believe** that it makes sense, and you're **ready to convince us how**. If you have some idea but you're not sure if it's possible, makes sense, or fits ASF purpose - you have **[Steam group](https://steamcommunity.com/groups/archiasf/discussions/1)** discussions where we'll be happy to discuss given enhancement in calm atmosphere, evaluating possibilities and pros/cons. This is what we suggest to do in the first place, as in GitHub issue you're switching from **having an idea** into **having a valid enhancement with general concept, given purpose and fixed details - you're ready to defend your idea and convince us how it can be useful for ASF**. This is the general reason why many issues are rejected - because you're lacking details that would prove your suggestion being worthy.
|
||||
While everybody is able to create suggestions how to improve ASF, GitHub issues is not the proper place to discuss if your enhancement makes sense - by posting it you already **believe** that it makes sense, and you're **ready to convince us how**. If you have some idea but you're not sure if it's possible, makes sense, or fits ASF purpose - you have our support channels where we'll be happy to discuss given enhancement in calm atmosphere, evaluating possibilities and pros/cons. This is what we suggest to do in the first place, as in GitHub issue you're switching from **having an idea** into **having a valid enhancement with general concept, given purpose and fixed details - you're ready to defend your idea and convince us how it can be useful for ASF**. This is the general reason why many issues are rejected - because you're lacking details that would prove your suggestion being worthy.
|
||||
|
||||
ASF has a strict scope - idling Steam cards from Steam games + basic bots management. ASF scope is very subjective and evaluated on practical/moral basis - how much this feature fits ASF, how much actual coding effort is required to make it happen, how useful/wanted this feature is by the community and likewise. In general we don't mind further enhancements to the program, as there is always a room for improvement, but at the same time we consider ASF to be feature-complete and vast majority of things that are suggested today are simply out of the scope of ASF as a program. This is why we've rejected **[a lot](https://github.com/JustArchiNET/ArchiSteamFarm/issues?q=label%3AEnhancement+label%3A%22Not+going+to+happen%22)** of general enhancements, for various different reasons, mainly regarding the scope of the program. Some people may find it hard to understand why we're rather sceptical towards suggestions, while the answer for that isn't obvious at first.
|
||||
|
||||
@@ -51,9 +51,9 @@ In any case, you should be able to explain to us in the issue why you consider y
|
||||
|
||||
## Pull requests
|
||||
|
||||
Pull requests are a bit different compared to issues, as in PR you're asking us to review the code and accept it, unless **we** have a reason against it. Very often we won't have enough arguments to accept given suggestion and code something, but we also won't have enough arguments **against** given suggestion, which makes it possible for you to code it yourself, then send a PR for review, and hopefully include your feature in ASF, even if we wouldn't code it otherwise. Such issues are appropriately tagged with **[PR-ok](https://github.com/JustArchiNET/ArchiSteamFarm/issues?q=is%3Aissue+is%3Aclosed+label%3APR-ok)** so you can easily take a look at those features that we wouldn't mind, but neither code ourselves. All of that is possible thanks to the fact that when dealing with PR, **we** are in position to find reasoning against it, and not necessarily you defending your own code. This is how **[a lot](https://github.com/JustArchiNET/ArchiSteamFarm/pulls?q=is%3Apr+is%3Amerged)** of ASF features were actually made possible, but at the same time there are still **[cases](https://github.com/JustArchiNET/ArchiSteamFarm/pulls?q=is%3Apr+is%3Aclosed+label%3A%22Not+going+to+happen%22)** of PRs that we decided to reject.
|
||||
Pull requests are a bit different compared to issues, as in PR you're asking us to review the code and accept it, unless **we** have a reason against it. Very often we won't have enough arguments to accept given suggestion and code something, but we also won't have enough arguments **against** given suggestion, which makes it possible for you to code it yourself, then send a PR for review, and hopefully include your feature in ASF, even if we wouldn't code it otherwise. Such issues are appropriately tagged with **[PR-ok](https://github.com/JustArchiNET/ArchiSteamFarm/issues?q=is%3Aissue+is%3Aclosed+label%3APR-ok)** so you can easily take a look at those features that we wouldn't mind, but neither code ourselves. All of that is possible thanks to the fact that when dealing with PR, **we** are in position to find reasoning against it, and not necessarily you defending your own code. This is how **[a lot](https://github.com/JustArchiNET/ArchiSteamFarm/pulls?q=is%3Apr+is%3Amerged+-label%3AAutomatic)** of ASF features were actually made possible, but at the same time there are still **[cases](https://github.com/JustArchiNET/ArchiSteamFarm/pulls?q=is%3Apr+is%3Aclosed+label%3A%22Not+going+to+happen%22)** of PRs that we decided to reject.
|
||||
|
||||
In general any pull request is welcome and should be accepted, unless there is a strong reason against it. A strong reason includes mainly only things we directly do not agree with, such as features that are against Steam ToS (like explained above), greatly against ASF scope (to the point it'd hurt overall maintenance), or likewise. If there is nothing severe enough to justify rejecting PR, we'll tell you how to fix it (if needed), so we can allow it in ASF. If you're improving existing code, rewriting it to be more efficient, clean, better commented - there is absolutely no reason to reject such PR, as long as it's in fact correct. If you want to add a missing feature, and you're not sure if it should be included in ASF, for example because you're not sure if it fits ASF scope - it won't hurt to ask before spending your own time, preferably in **[Steam group](https://steamcommunity.com/groups/archiasf/discussions/1)** discussions, so we can evaluate the idea and give feedback instead of accepting/rejecting the concept which is usually happening with GitHub issues - after all you want to code it yourself, so you shouldn't use GitHub issues that are being used for expecting us to add things. Still, as stated above, our entire GitHub repo is dedicated to development part of ASF, so feel free to post an issue in which you'll ask if given feature would be accepted in PR, if you prefer that way instead of using the Steam group.
|
||||
In general any pull request is welcome and should be accepted, unless there is a strong reason against it. A strong reason includes mainly only things we directly do not agree with, such as features that are against Steam ToS (like explained above), greatly against ASF scope (to the point it'd hurt overall maintenance), or likewise. If there is nothing severe enough to justify rejecting PR, we'll tell you how to fix it (if needed), so we can allow it in ASF. If you're improving existing code, rewriting it to be more efficient, clean, better commented - there is absolutely no reason to reject such PR, as long as it's in fact correct. If you want to add a missing feature, and you're not sure if it should be included in ASF, for example because you're not sure if it fits ASF scope - it won't hurt to ask before spending your own time, preferably on one of our support channels, so we can evaluate the idea and give feedback instead of accepting/rejecting the concept which is usually happening with GitHub issues - after all you want to code it yourself, so you shouldn't use GitHub issues that are being used for expecting us to add things. Still, as stated above, our entire GitHub repo is dedicated to development part of ASF, so feel free to post an issue in which you'll ask if given feature would be accepted in PR, if you prefer that way instead of using the Steam group.
|
||||
|
||||
Every pull request is carefully examined by our continuous integration system - it won't be accepted if it doesn't compile properly or causes any test to fail. We also expect that you at least barely tested the modification you're trying to add, so we can be sure that it works. Consider the fact that you're not coding it only for yourself, but for thousands of users.
|
||||
|
||||
@@ -67,7 +67,7 @@ ASF is open-source project, developed mainly by **[JustArchi](https://github.com
|
||||
|
||||
### License
|
||||
|
||||
ASF is using **[Apache License 2.0](https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/LICENSE-2.0.txt)**.
|
||||
ASF is using **[Apache License 2.0](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/LICENSE-2.0.txt)**.
|
||||
|
||||
> Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions.
|
||||
|
||||
@@ -79,8 +79,8 @@ For more info about the license, please check out **[license](https://github.com
|
||||
|
||||
Please stick with ASF code style when submitting PRs. In repo you can find several different files dedicated to making it easier for you:
|
||||
|
||||
- **[EditorConfig](https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/.editorconfig)** file which is supported by all major IDEs and requires no further setup. It's a good starting point, although it doesn't include all the rules that we'd like to see.
|
||||
- **[VS settings](https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/CodeStyle.vssettings)** file that you can use in Visual Studio for import. This one includes far more options than EditorConfig alone, and it's a very good choice if you're using bare VS.
|
||||
- **[DotSettings](https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/ArchiSteamFarm.sln.DotSettings)** file that is being used by **[ReSharper](https://www.jetbrains.com/resharper)** and **[Rider](https://www.jetbrains.com/rider)**. This one is the most complete config file that is also being loaded automatically when you're using ReSharper/Rider with our code.
|
||||
- **[EditorConfig](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.editorconfig)** file which is supported by all major IDEs and requires no further setup. It's a good starting point, although it doesn't include all the rules that we'd like to see.
|
||||
- **[VS settings](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/CodeStyle.vssettings)** file that you can use in Visual Studio for import. This one includes far more options than EditorConfig alone, and it's a very good choice if you're using bare VS.
|
||||
- **[DotSettings](https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/ArchiSteamFarm.sln.DotSettings)** file that is being used by **[ReSharper](https://www.jetbrains.com/resharper)** and **[Rider](https://www.jetbrains.com/rider)**. This one is the most complete config file that is also being loaded automatically when you're using ReSharper/Rider with our code.
|
||||
|
||||
Personally we're using Visual Studio + ReSharper, so no other action is needed after opening `ArchiSteamFarm.sln` solution. If you're using VS alone, it's probably a good idea to import our code style settings, although even editor config should be enough for majority of cases. If you can save us those few extra seconds cleaning up your code after accepting it, it would be great and surely improve overall code history.
|
||||
|
||||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -2,4 +2,4 @@
|
||||
|
||||
github: JustArchi
|
||||
patreon: JustArchi
|
||||
custom: https://www.paypal.me/JustArchi/5eur
|
||||
custom: ["https://www.paypal.me/JustArchi/5eur", "https://pay.revolut.com/profile/ukaszyxm", "https://commerce.coinbase.com/checkout/0c23b844-c51b-45f4-9135-8db7c6fcf98e", "https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_"]
|
||||
|
||||
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,7 +1,9 @@
|
||||
<!--
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
|
||||
I understand that if my issue is not meeting contributing guidelines specified above, especially if it's a question or technical issue that is not related to ASF development in any way, then it will be closed and left unanswered.
|
||||
ASF GITHUB ISSUES IS NOT A PROPER PLACE FOR ANY TECHNICAL SUPPORT RELATED TO USING THE PROGRAM.
|
||||
|
||||
I UNDERSTAND THAT IF MY ISSUE IS NOT MEETING CONTRIBUTING GUIDELINES SPECIFIED ABOVE, ESPECIALLY IF IT'S A QUESTION OR TECHNICAL ISSUE THAT IS NOT RELATED TO ASF DEVELOPMENT IN ANY WAY, THEN IT WILL BE CLOSED AND LEFT UNANSWERED.
|
||||
|
||||
Feel free to remove our notice and fill the template below with your details.
|
||||
-->
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
8
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -8,9 +8,11 @@ assignees: ''
|
||||
---
|
||||
|
||||
<!--
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
|
||||
I understand that if my issue is not meeting contributing guidelines specified above, especially if it's a question or technical issue that is not related to ASF development in any way, then it will be closed and left unanswered.
|
||||
ASF GITHUB ISSUES IS NOT A PROPER PLACE FOR ANY TECHNICAL SUPPORT RELATED TO USING THE PROGRAM.
|
||||
|
||||
I UNDERSTAND THAT IF MY ISSUE IS NOT MEETING CONTRIBUTING GUIDELINES SPECIFIED ABOVE, ESPECIALLY IF IT'S A QUESTION OR TECHNICAL ISSUE THAT IS NOT RELATED TO ASF DEVELOPMENT IN ANY WAY, THEN IT WILL BE CLOSED AND LEFT UNANSWERED.
|
||||
|
||||
Feel free to remove our notice and fill the template below with your details.
|
||||
-->
|
||||
@@ -40,7 +42,7 @@ Feel free to remove our notice and fill the template below with your details.
|
||||
|
||||
### Full log.txt recorded during reproducing the problem
|
||||
|
||||
```
|
||||
```text
|
||||
Paste here, in-between triple backtick tags
|
||||
|
||||
Ensure that your log is complete and was NOT recorded in Debug mode, as debug log may contain sensitive information that should not be shared publicly, as per our wiki statement. Standard ASF log does not include sensitive information.
|
||||
|
||||
6
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
6
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@@ -8,9 +8,11 @@ assignees: ''
|
||||
---
|
||||
|
||||
<!--
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
|
||||
I understand that if my issue is not meeting contributing guidelines specified above, especially if it's a question or technical issue that is not related to ASF development in any way, then it will be closed and left unanswered.
|
||||
ASF GITHUB ISSUES IS NOT A PROPER PLACE FOR ANY TECHNICAL SUPPORT RELATED TO USING THE PROGRAM.
|
||||
|
||||
I UNDERSTAND THAT IF MY ISSUE IS NOT MEETING CONTRIBUTING GUIDELINES SPECIFIED ABOVE, ESPECIALLY IF IT'S A QUESTION OR TECHNICAL ISSUE THAT IS NOT RELATED TO ASF DEVELOPMENT IN ANY WAY, THEN IT WILL BE CLOSED AND LEFT UNANSWERED.
|
||||
|
||||
Feel free to remove our notice and fill the template below with your details.
|
||||
-->
|
||||
|
||||
6
.github/ISSUE_TEMPLATE/Wiki_correction.md
vendored
6
.github/ISSUE_TEMPLATE/Wiki_correction.md
vendored
@@ -8,9 +8,11 @@ assignees: ''
|
||||
---
|
||||
|
||||
<!--
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/master/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
I fully read and understood contributing guidelines of ASF available under https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/CONTRIBUTING.md and I believe that my issue is valid - it requires a response from ASF development team, and not ASF support.
|
||||
|
||||
I understand that if my issue is not meeting contributing guidelines specified above, especially if it's a question or technical issue that is not related to ASF development in any way, then it will be closed and left unanswered.
|
||||
ASF GITHUB ISSUES IS NOT A PROPER PLACE FOR ANY TECHNICAL SUPPORT RELATED TO USING THE PROGRAM.
|
||||
|
||||
I UNDERSTAND THAT IF MY ISSUE IS NOT MEETING CONTRIBUTING GUIDELINES SPECIFIED ABOVE, ESPECIALLY IF IT'S A QUESTION OR TECHNICAL ISSUE THAT IS NOT RELATED TO ASF DEVELOPMENT IN ANY WAY, THEN IT WILL BE CLOSED AND LEFT UNANSWERED.
|
||||
|
||||
Feel free to remove our notice and fill the template below with your details.
|
||||
-->
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ASF-ui issue
|
||||
url: https://github.com/JustArchiNET/ASF-ui/issues/new/choose
|
||||
about: Please open issue in ASF-ui repo.
|
||||
- name: Localization improvement
|
||||
url: https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Localization
|
||||
about: Please use our crowdin platform.
|
||||
- name: Support question or technical issue
|
||||
url: https://github.com/JustArchiNET/ArchiSteamFarm/blob/main/.github/SUPPORT.md
|
||||
about: Please review our support guidelines.
|
||||
- name: Negative feedback, complaints and demands
|
||||
url: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
||||
about: We're taking those very seriously.
|
||||
17
.github/RELEASE_TEMPLATE.md
vendored
Normal file
17
.github/RELEASE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
### Notice
|
||||
|
||||
**Pre-releases are experimental versions that often contain unpatched bugs, work-in-progress features or rewritten implementations. If you don't consider yourself advanced user, please download **[latest stable release](https://github.com/JustArchiNET/ArchiSteamFarm/releases/latest)** instead. Pre-release versions are dedicated to users who know how to report bugs, deal with issues and give feedback - no technical support will be given. Check out ASF **[release cycle](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Release-cycle)** if you'd like to learn more.**
|
||||
|
||||
---
|
||||
|
||||
### Changelog
|
||||
|
||||
This is automated GitHub deployment, human-readable changelog should be available soon. In the meantime please refer to **[GitHub commits](https://github.com/JustArchiNET/ArchiSteamFarm/commits/main)**.
|
||||
|
||||
---
|
||||
|
||||
### Support
|
||||
|
||||
ASF is available for free, this release was made possible thanks to the people that decided to support the project. If you're grateful for what we're doing, please consider donating. Developing ASF requires massive amount of time and knowledge, especially when it comes to Steam (and its problems). Even $1 is highly appreciated and shows that you care. Thank you!
|
||||
|
||||
[](https://github.com/sponsors/JustArchi) [](https://www.patreon.com/JustArchi) [](https://commerce.coinbase.com/checkout/0c23b844-c51b-45f4-9135-8db7c6fcf98e) [](https://www.paypal.me/JustArchi/5eur) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HD2P2P3WGS5Y4) [](https://pay.revolut.com/profile/ukaszyxm) [](https://steamcommunity.com/tradeoffer/new/?partner=46697991&token=0ix2Ruv_)
|
||||
0
SECURITY.md → .github/SECURITY.md
vendored
0
SECURITY.md → .github/SECURITY.md
vendored
7
.github/SUPPORT.md
vendored
Normal file
7
.github/SUPPORT.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Support
|
||||
|
||||
Our **[wiki](https://github.com/JustArchiNET/ArchiSteamFarm/wiki)** is the official online documentation which covers at least a significant majority (if not all) of ASF subjects you could be interested in. We recommend to start with **[setting up](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Setting-up)**, **[configuration](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Configuration)** and our **[FAQ](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/FAQ)** which should help you with setting up ASF, configuring it, as well as answering the most common questions that you might have. For more advanced matters, as well as further elaboration, we have other pages available on our **[wiki](https://github.com/JustArchiNET/ArchiSteamFarm/wiki)** that you can visit.
|
||||
|
||||
We also have three independent support channels dedicated to our ASF users, in case you couldn't manage to solve the issue yourself. We answer all support and technical matters in our **[GitHub discussions](https://github.com/JustArchiNET/ArchiSteamFarm/discussions/categories/support)**, **[Steam group](https://steamcommunity.com/groups/archiasf/discussions/1)**, and on our **[Discord server](https://discord.gg/hSQgt8j)**. You're free to use the support channel that matches your preferences, although keep in mind that you have a higher chance solving your issue on the GitHub or Steam, where we're doing our best to answer all questions that couldn't be answered by our community itself (as opposed to Discord server where we're not active 24/7 and therefore not always able to answer).
|
||||
|
||||
**[GitHub issues](https://github.com/JustArchiNET/ArchiSteamFarm/issues)** page is being used solely for ASF development, especially in regards to bugs and enhancements. We have a very strict policy regarding that, as GitHub issues is **not** a general support channel, it's dedicated exclusively to ASF development and we're not answering common ASF matters there, as we have appropriate support channels (mentioned above) for that. Common matters include not only general questions or issues that are obviously related to program usage, but also users reporting "bugs" that are clearly considered intended behaviour coming for example (and mainly) from misconfiguration or lack of understanding how the program works. If you're not sure whether your matter relates to ASF development or not, especially if you're not sure if it's a bug or intended behaviour, we recommend to use a support channel instead, where we'll answer you in calm atmosphere and forward your matter to GitHub if deemed appropriate. Invalid GitHub issues will be closed immediately and won't be answered.
|
||||
34
.github/dependabot.yml.off
vendored
Normal file
34
.github/dependabot.yml.off
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "01:00"
|
||||
labels:
|
||||
- "Automatic"
|
||||
open-pull-requests-limit: 99
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "01:15"
|
||||
labels:
|
||||
- "Automatic"
|
||||
open-pull-requests-limit: 99
|
||||
- package-ecosystem: "nuget"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "01:30"
|
||||
labels:
|
||||
- "Automatic"
|
||||
open-pull-requests-limit: 99
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
time: "02:00"
|
||||
labels:
|
||||
- "Automatic"
|
||||
open-pull-requests-limit: 99
|
||||
31
.github/lock.yml
vendored
31
.github/lock.yml
vendored
@@ -1,31 +0,0 @@
|
||||
# Configuration for lock-threads - https://github.com/dessant/lock-threads
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 30
|
||||
|
||||
# Issues and pull requests with these labels will not be locked. Set to `[]` to disable
|
||||
exemptLabels: []
|
||||
|
||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
||||
lockLabel: false
|
||||
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: false
|
||||
|
||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
||||
setLockReason: true
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - help-wanted
|
||||
# lockLabel: outdated
|
||||
|
||||
# pulls:
|
||||
# daysUntilLock: 30
|
||||
|
||||
# Repository to extend settings from
|
||||
# _extends: repo
|
||||
20
.github/renovate.json
vendored
Normal file
20
.github/renovate.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base",
|
||||
":assignee(JustArchi)",
|
||||
":automergeBranch",
|
||||
":automergeDigest",
|
||||
":automergeMinor",
|
||||
":disableRateLimiting",
|
||||
":label(Automatic)"
|
||||
],
|
||||
"git-submodules": {
|
||||
"enabled": true
|
||||
},
|
||||
"packageRules": [
|
||||
{
|
||||
"allowedVersions": "<= 3.0",
|
||||
"matchPackageNames": [ "Microsoft.Extensions.Configuration.Json", "Microsoft.Extensions.Logging.Configuration" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
298
.github/workflows/ci.yml
vendored
298
.github/workflows/ci.yml
vendored
@@ -1,20 +1,22 @@
|
||||
name: ASF-CI
|
||||
name: ASF-ci
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
CONFIGURATION: Release
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
DOTNET_SDK_VERSION: 3.1.102
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
GITHUB_JOBS: 2 # 2-core CPU, without HT: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources
|
||||
NET_CORE_VERSION: netcoreapp3.1
|
||||
DOTNET_NOLOGO: 1
|
||||
DOTNET_SDK_VERSION: 5.0.x
|
||||
NET_CORE_VERSION: net5.0
|
||||
NET_FRAMEWORK_VERSION: net48
|
||||
NODE_JS_VERSION: 12
|
||||
NODE_JS_VERSION: 14 # Periodically bumped to follow latest LTS | https://github.com/actions/setup-node/issues/26
|
||||
STEAM_TOKEN_DUMPER_NAME: ArchiSteamFarm.OfficialPlugins.SteamTokenDumper
|
||||
STEAM_TOKEN_DUMPER_TOKEN: ${{ secrets.STEAM_TOKEN_DUMPER_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
main:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
|
||||
@@ -23,12 +25,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Sync git submodules
|
||||
run: git submodule sync --recursive
|
||||
|
||||
- name: Update git submodules
|
||||
run: git submodule update -j ${{ env.GITHUB_JOBS }} --init --recursive
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
@@ -39,8 +37,9 @@ jobs:
|
||||
run: dotnet --info
|
||||
|
||||
- name: Setup Node.js with npm
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
check-latest: true
|
||||
node-version: ${{ env.NODE_JS_VERSION }}
|
||||
|
||||
- name: Verify Node.js
|
||||
@@ -53,45 +52,109 @@ jobs:
|
||||
run: npm ci --no-progress --prefix ASF-ui
|
||||
|
||||
- name: Build ASF-ui
|
||||
run: npm run-script build:ci --no-progress --prefix ASF-ui
|
||||
run: npm run-script deploy --no-progress --prefix ASF-ui
|
||||
|
||||
- name: Build ArchiSteamFarm
|
||||
run: dotnet build ArchiSteamFarm -c "${{ env.CONFIGURATION }}" -f "${{ env.NET_CORE_VERSION }}" --nologo
|
||||
run: dotnet build ArchiSteamFarm -c "${{ env.CONFIGURATION }}" -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Build ArchiSteamFarm.CustomPlugins.ExamplePlugin
|
||||
run: dotnet build ArchiSteamFarm.CustomPlugins.ExamplePlugin -c "${{ env.CONFIGURATION }}" -f "${{ env.NET_CORE_VERSION }}" --nologo
|
||||
run: dotnet build ArchiSteamFarm.CustomPlugins.ExamplePlugin -c "${{ env.CONFIGURATION }}" -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Build ArchiSteamFarm.CustomPlugins.PeriodicGC
|
||||
run: dotnet build ArchiSteamFarm.CustomPlugins.PeriodicGC -c "${{ env.CONFIGURATION }}" -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Build ArchiSteamFarm.OfficialPlugins.SteamTokenDumper
|
||||
run: dotnet build "${{ env.STEAM_TOKEN_DUMPER_NAME }}" -c "${{ env.CONFIGURATION }}" -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Run ArchiSteamFarm.Tests
|
||||
run: dotnet test ArchiSteamFarm.Tests -c "${{ env.CONFIGURATION }}" -f "${{ env.NET_CORE_VERSION }}" --nologo
|
||||
run: dotnet test ArchiSteamFarm.Tests -c "${{ env.CONFIGURATION }}" -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Upload latest strings for translation on Crowdin
|
||||
continue-on-error: true
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && startsWith(matrix.os, 'ubuntu-') }}
|
||||
uses: crowdin/github-action@1.1.0
|
||||
with:
|
||||
crowdin_branch_name: main
|
||||
project_id: ${{ secrets.ASF_CROWDIN_PROJECT_ID }}
|
||||
token: ${{ secrets.ASF_CROWDIN_API_TOKEN }}
|
||||
|
||||
- name: Prepare ArchiSteamFarm.OfficialPlugins.SteamTokenDumper on Unix
|
||||
if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-')
|
||||
shell: sh
|
||||
run: |
|
||||
if [ -n "${STEAM_TOKEN_DUMPER_TOKEN-}" ] && [ -f "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs" ]; then
|
||||
sed "s/STEAM_TOKEN_DUMPER_TOKEN/${STEAM_TOKEN_DUMPER_TOKEN}/g" "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs" > "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs.new"
|
||||
mv "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs.new" "${STEAM_TOKEN_DUMPER_NAME}/SharedInfo.cs"
|
||||
fi
|
||||
|
||||
- name: Prepare ArchiSteamFarm.OfficialPlugins.SteamTokenDumper on Windows
|
||||
if: startsWith(matrix.os, 'windows-')
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
if ((Test-Path env:STEAM_TOKEN_DUMPER_TOKEN) -and (Test-Path "$env:STEAM_TOKEN_DUMPER_NAME\SharedInfo.cs" -PathType Leaf)) {
|
||||
(Get-Content "$env:STEAM_TOKEN_DUMPER_NAME\SharedInfo.cs").Replace('STEAM_TOKEN_DUMPER_TOKEN', "$env:STEAM_TOKEN_DUMPER_TOKEN") | Set-Content "$env:STEAM_TOKEN_DUMPER_NAME\SharedInfo.cs"
|
||||
}
|
||||
|
||||
- name: Publish ArchiSteamFarm.OfficialPlugins.SteamTokenDumper for .NET Core
|
||||
run: dotnet publish "${{ env.STEAM_TOKEN_DUMPER_NAME }}" -c "${{ env.CONFIGURATION }}" -f "${{ env.NET_CORE_VERSION }}" -o "out/${{ env.STEAM_TOKEN_DUMPER_NAME }}/${{ env.NET_CORE_VERSION }}" -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Publish ArchiSteamFarm.OfficialPlugins.SteamTokenDumper for .NET Framework
|
||||
if: startsWith(matrix.os, 'windows-')
|
||||
run: dotnet publish "${{ env.STEAM_TOKEN_DUMPER_NAME }}" -c "${{ env.CONFIGURATION }}" -f "${{ env.NET_FRAMEWORK_VERSION }}" -o "out/${{ env.STEAM_TOKEN_DUMPER_NAME }}/${{ env.NET_FRAMEWORK_VERSION }}" -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Perform cleanup of ArchiSteamFarm in preparation for publishing
|
||||
run: dotnet clean ArchiSteamFarm -c "${{ env.CONFIGURATION }}" -p:UseAppHost=false --nologo
|
||||
|
||||
- name: Restore packages in preparation for ArchiSteamFarm publishing
|
||||
run: dotnet restore ArchiSteamFarm
|
||||
|
||||
- name: Publish ArchiSteamFarm on Unix
|
||||
if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-')
|
||||
env:
|
||||
VARIANTS: generic linux-arm linux-x64 osx-x64 win-x64 # NOTE: When modifying variants, don't forget to update ASF_VARIANT definitions in SharedInfo.cs!
|
||||
VARIANTS: generic linux-arm linux-arm64 linux-x64 osx-x64 win-x64 # NOTE: When modifying variants, don't forget to update ASF_VARIANT definitions in SharedInfo.cs!
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
publish() {
|
||||
if [ "$1" = 'generic' ]; then
|
||||
local variantArgs="/p:UseAppHost=false"
|
||||
local variantArgs="-p:TargetLatestRuntimePatch=false -p:UseAppHost=false"
|
||||
else
|
||||
local variantArgs="-r $1 /p:PublishTrimmed=true"
|
||||
local variantArgs="-p:PublishSingleFile=true -p:PublishTrimmed=true -r $1"
|
||||
fi
|
||||
|
||||
dotnet publish ArchiSteamFarm -c "$CONFIGURATION" -f "$NET_CORE_VERSION" -o "out/${1}" --no-restore --nologo "/p:ASFVariant=$1" $variantArgs
|
||||
dotnet publish ArchiSteamFarm -c "$CONFIGURATION" -f "$NET_CORE_VERSION" -o "out/${1}" "-p:ASFVariant=$1" --no-restore --nologo $variantArgs
|
||||
|
||||
# If we include any overlay for this variant, copy it to output directory
|
||||
# If we're including any overlay for this variant, copy it to output directory
|
||||
if [ -d "ArchiSteamFarm/overlay/${1}" ]; then
|
||||
cp "ArchiSteamFarm/overlay/${1}/"* "out/${1}"
|
||||
cp -pR "ArchiSteamFarm/overlay/${1}/"* "out/${1}"
|
||||
fi
|
||||
|
||||
# If we're including SteamTokenDumper plugin for this framework, copy it to output directory
|
||||
if [ -d "out/${STEAM_TOKEN_DUMPER_NAME}/${NET_CORE_VERSION}" ]; then
|
||||
mkdir -p "out/${1}/plugins/${STEAM_TOKEN_DUMPER_NAME}"
|
||||
cp -pR "out/${STEAM_TOKEN_DUMPER_NAME}/${NET_CORE_VERSION}/"* "out/${1}/plugins/${STEAM_TOKEN_DUMPER_NAME}"
|
||||
fi
|
||||
|
||||
# Include .ico file for all platforms, since only Windows script can bundle it inside the exe
|
||||
cp "resources/ASF.ico" "out/${1}/ArchiSteamFarm.ico"
|
||||
}
|
||||
|
||||
dotnet clean ArchiSteamFarm -c "$CONFIGURATION" -f "$NET_CORE_VERSION" --nologo
|
||||
dotnet restore ArchiSteamFarm
|
||||
if command -v 7z >/dev/null; then
|
||||
7z a -bd -slp -tzip -mm=Deflate -mx=1 "out/ASF-${1}.zip" "${GITHUB_WORKSPACE}/out/${1}/*"
|
||||
elif command -v zip >/dev/null; then
|
||||
(
|
||||
cd "${GITHUB_WORKSPACE}/out/${1}"
|
||||
zip -1 -q -r "../ASF-${1}.zip" .
|
||||
)
|
||||
else
|
||||
echo "ERROR: No supported zip tool!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
jobs=""
|
||||
|
||||
@@ -107,7 +170,7 @@ jobs:
|
||||
- name: Publish ArchiSteamFarm on Windows
|
||||
if: startsWith(matrix.os, 'windows-')
|
||||
env:
|
||||
VARIANTS: generic generic-netf linux-arm linux-x64 osx-x64 win-x64 # NOTE: When modifying variants, don't forget to update ASF_VARIANT definitions in SharedInfo.cs!
|
||||
VARIANTS: generic generic-netf linux-arm linux-arm64 linux-x64 osx-x64 win-x64 # NOTE: When modifying variants, don't forget to update ASF_VARIANT definitions in SharedInfo.cs!
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-StrictMode -Version Latest
|
||||
@@ -124,87 +187,206 @@ jobs:
|
||||
Set-Location "$env:GITHUB_WORKSPACE"
|
||||
|
||||
if ($variant -like '*-netf') {
|
||||
$compressionMethod = 'Deflate' # This depends on what ZipArchive supports on given platform
|
||||
$targetFramework = $env:NET_FRAMEWORK_VERSION
|
||||
} else {
|
||||
$compressionMethod = 'Deflate64' # This depends on what ZipArchive supports on given platform
|
||||
$targetFramework = $env:NET_CORE_VERSION
|
||||
}
|
||||
|
||||
if ($variant -like 'generic*') {
|
||||
$variantArgs = '/p:UseAppHost=false'
|
||||
$variantArgs = '-p:TargetLatestRuntimePatch=false', '-p:UseAppHost=false'
|
||||
} else {
|
||||
$variantArgs = '-r', "$variant", '/p:PublishTrimmed=true'
|
||||
$variantArgs = '-p:PublishSingleFile=true', '-p:PublishTrimmed=true', '-r', "$variant"
|
||||
}
|
||||
|
||||
dotnet publish ArchiSteamFarm -c "$env:CONFIGURATION" -f "$targetFramework" -o "out\$variant" --no-restore --nologo "/p:ASFVariant=$variant" $variantArgs
|
||||
dotnet publish ArchiSteamFarm -c "$env:CONFIGURATION" -f "$targetFramework" -o "out\$variant" "-p:ASFVariant=$variant" --no-restore --nologo $variantArgs
|
||||
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Last command failed."
|
||||
}
|
||||
|
||||
# If we include any overlay for this variant, copy it output directory
|
||||
# If we're including any overlay for this variant, copy it to output directory
|
||||
if (Test-Path "ArchiSteamFarm\overlay\$variant" -PathType Container) {
|
||||
Copy-Item "ArchiSteamFarm\overlay\$variant\*" "out\$variant"
|
||||
Copy-Item "ArchiSteamFarm\overlay\$variant\*" "out\$variant" -Recurse
|
||||
}
|
||||
|
||||
# Include .ico file for non-Windows targets
|
||||
if (!(Test-Path "out\$variant\ArchiSteamFarm.exe" -PathType Leaf)) {
|
||||
# If we're including SteamTokenDumper plugin for this framework, copy it to output directory
|
||||
if (Test-Path "out\$env:STEAM_TOKEN_DUMPER_NAME\$targetFramework" -PathType Container) {
|
||||
if (!(Test-Path "out\$variant\plugins\$env:STEAM_TOKEN_DUMPER_NAME" -PathType Container)) {
|
||||
New-Item -ItemType Directory -Path "out\$variant\plugins\$env:STEAM_TOKEN_DUMPER_NAME" > $null
|
||||
}
|
||||
|
||||
Copy-Item "out\$env:STEAM_TOKEN_DUMPER_NAME\$targetFramework\*" "out\$variant\plugins\$env:STEAM_TOKEN_DUMPER_NAME" -Recurse
|
||||
}
|
||||
|
||||
# Icon is available only in .NET Framework and .NET Core Windows build, we'll bundle the .ico file for other flavours
|
||||
if (($targetFramework -eq "$env:NET_CORE_VERSION") -and !(Test-Path "out\$variant\ArchiSteamFarm.exe" -PathType Leaf)) {
|
||||
Copy-Item 'resources\ASF.ico' "out\$variant\ArchiSteamFarm.ico"
|
||||
}
|
||||
}
|
||||
|
||||
dotnet clean ArchiSteamFarm -c "$env:CONFIGURATION" -f "$env:NET_CORE_VERSION" --nologo
|
||||
# By default use fastest compression
|
||||
$compressionArgs = '-mx=1'
|
||||
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Last command failed."
|
||||
}
|
||||
# Include extra logic for builds marked for release
|
||||
if ($env:GITHUB_REF -like 'refs/tags/*') {
|
||||
$tag = $env:GITHUB_REF.Substring(10)
|
||||
|
||||
dotnet restore ArchiSteamFarm
|
||||
# Tweak compression args for release publishing
|
||||
$compressionArgs = '-mx=9', '-mfb=258', '-mpass=15'
|
||||
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Last command failed."
|
||||
# Update link in Changelog.html accordingly
|
||||
if (Test-Path "out\$variant\Changelog.html" -PathType Leaf) {
|
||||
(Get-Content "out\$variant\Changelog.html").Replace('ArchiSteamFarm/commits/main', "ArchiSteamFarm/releases/tag/$tag") | Set-Content "out\$variant\Changelog.html"
|
||||
}
|
||||
}
|
||||
|
||||
7z a -bd -slp -tzip -mm=Deflate $compressionArgs "out\ASF-$variant.zip" "$env:GITHUB_WORKSPACE\out\$variant\*"
|
||||
|
||||
if ($LastExitCode -ne 0) {
|
||||
throw "Last command failed."
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($variant in $env:VARIANTS.Split([char[]] $null, [System.StringSplitOptions]::RemoveEmptyEntries)) {
|
||||
Start-Job -Name "$variant" $PublishBlock -ArgumentList "$variant"
|
||||
}
|
||||
|
||||
Get-Job | Receive-Job -Wait -AutoRemoveJob
|
||||
Get-Job | Receive-Job -Wait
|
||||
|
||||
- name: Upload ASF-generic
|
||||
uses: actions/upload-artifact@v1
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-generic
|
||||
path: out/generic
|
||||
path: out/ASF-generic.zip
|
||||
|
||||
- name: Upload ASF-generic-netf
|
||||
continue-on-error: true
|
||||
if: startsWith(matrix.os, 'windows-')
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-generic-netf
|
||||
path: out/generic-netf
|
||||
path: out/ASF-generic-netf.zip
|
||||
|
||||
- name: Upload ASF-linux-arm
|
||||
uses: actions/upload-artifact@v1
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-linux-arm
|
||||
path: out/linux-arm
|
||||
path: out/ASF-linux-arm.zip
|
||||
|
||||
- name: Upload ASF-linux-arm64
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-linux-arm64
|
||||
path: out/ASF-linux-arm64.zip
|
||||
|
||||
- name: Upload ASF-linux-x64
|
||||
uses: actions/upload-artifact@v1
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-linux-x64
|
||||
path: out/linux-x64
|
||||
path: out/ASF-linux-x64.zip
|
||||
|
||||
- name: Upload ASF-osx-x64
|
||||
uses: actions/upload-artifact@v1
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-osx-x64
|
||||
path: out/osx-x64
|
||||
path: out/ASF-osx-x64.zip
|
||||
|
||||
- name: Upload ASF-win-x64
|
||||
uses: actions/upload-artifact@v1
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.os }}_ASF-win-x64
|
||||
path: out/win-x64
|
||||
path: out/ASF-win-x64.zip
|
||||
|
||||
- name: Create ArchiSteamFarm GitHub release
|
||||
id: github_release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ArchiSteamFarm V${{ github.ref }}
|
||||
body_path: .github/RELEASE_TEMPLATE.md
|
||||
prerelease: true
|
||||
|
||||
- name: Upload ASF-generic to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-generic.zip
|
||||
asset_name: ASF-generic.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload ASF-generic-netf to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-generic-netf.zip
|
||||
asset_name: ASF-generic-netf.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload ASF-linux-arm to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-linux-arm.zip
|
||||
asset_name: ASF-linux-arm.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload ASF-linux-arm64 to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-linux-arm64.zip
|
||||
asset_name: ASF-linux-arm64.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload ASF-linux-x64 to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-linux-x64.zip
|
||||
asset_name: ASF-linux-x64.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload ASF-osx-x64 to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-osx-x64.zip
|
||||
asset_name: ASF-osx-x64.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload ASF-win-x64 to GitHub release
|
||||
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.github_release.outputs.upload_url }}
|
||||
asset_path: out/ASF-win-x64.zip
|
||||
asset_name: ASF-win-x64.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
60
.github/workflows/docker-publish-latest.yml
vendored
Normal file
60
.github/workflows/docker-publish-latest.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: ASF-docker-publish-latest
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
env:
|
||||
TAG: latest
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_PACKAGES_PAT }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Prepare environment outputs
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
echo "FIXED_TAG=$(echo ${{ github.ref }} | cut -d '/' -f 3)" >> "$GITHUB_ENV"
|
||||
echo "DATE_ISO8601=$(date --iso-8601=seconds --utc)" >> "$GITHUB_ENV"
|
||||
echo "GHCR_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.Service
|
||||
platforms: linux/amd64,linux/arm,linux/arm64
|
||||
build-args: STEAM_TOKEN_DUMPER_TOKEN=${{ secrets.STEAM_TOKEN_DUMPER_TOKEN }}
|
||||
labels: |
|
||||
org.opencontainers.image.created=${{ env.DATE_ISO8601 }}
|
||||
org.opencontainers.image.version=${{ env.FIXED_TAG }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
tags: |
|
||||
ghcr.io/${{ env.GHCR_REPOSITORY }}:${{ env.TAG }}
|
||||
${{ env.DH_REPOSITORY }}:${{ env.TAG }}
|
||||
push: true
|
||||
67
.github/workflows/docker-publish-main.yml
vendored
Normal file
67
.github/workflows/docker-publish-main.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: ASF-docker-publish-main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
TAG: main
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_PACKAGES_PAT }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Prepare environment outputs
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
echo "DATE_ISO8601=$(date --iso-8601=seconds --utc)" >> "$GITHUB_ENV"
|
||||
echo "GHCR_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm,linux/arm64
|
||||
build-args: STEAM_TOKEN_DUMPER_TOKEN=${{ secrets.STEAM_TOKEN_DUMPER_TOKEN }}
|
||||
labels: |
|
||||
org.opencontainers.image.created=${{ env.DATE_ISO8601 }}
|
||||
org.opencontainers.image.version=${{ github.sha }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
tags: |
|
||||
ghcr.io/${{ env.GHCR_REPOSITORY }}:${{ env.TAG }}
|
||||
${{ env.DH_REPOSITORY }}:${{ env.TAG }}
|
||||
push: true
|
||||
|
||||
- name: Update DockerHub repository description
|
||||
continue-on-error: true
|
||||
uses: peter-evans/dockerhub-description@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
repository: ${{ env.DH_REPOSITORY }}
|
||||
62
.github/workflows/docker-publish-released.yml
vendored
Normal file
62
.github/workflows/docker-publish-released.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: ASF-docker-publish-released
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
TAG: released
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_PACKAGES_PAT }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Prepare environment outputs
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
echo "FIXED_TAG=$(echo ${{ github.ref }} | cut -d '/' -f 3)" >> "$GITHUB_ENV"
|
||||
echo "DATE_ISO8601=$(date --iso-8601=seconds --utc)" >> "$GITHUB_ENV"
|
||||
echo "GHCR_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm,linux/arm64
|
||||
build-args: STEAM_TOKEN_DUMPER_TOKEN=${{ secrets.STEAM_TOKEN_DUMPER_TOKEN }}
|
||||
labels: |
|
||||
org.opencontainers.image.created=${{ env.DATE_ISO8601 }}
|
||||
org.opencontainers.image.version=${{ env.FIXED_TAG }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
tags: |
|
||||
ghcr.io/${{ env.GHCR_REPOSITORY }}:${{ env.TAG }}
|
||||
ghcr.io/${{ env.GHCR_REPOSITORY }}:${{ env.FIXED_TAG }}
|
||||
${{ env.DH_REPOSITORY }}:${{ env.TAG }}
|
||||
${{ env.DH_REPOSITORY }}:${{ env.FIXED_TAG }}
|
||||
push: true
|
||||
16
.github/workflows/lock-threads.yml
vendored
Normal file
16
.github/workflows/lock-threads.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: ASF-lock-threads
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 1 * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Lock inactive threads
|
||||
uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-lock-inactive-days: 30
|
||||
pr-lock-inactive-days: 30
|
||||
80
.github/workflows/translations.yml
vendored
Normal file
80
.github/workflows/translations.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
name: ASF-translations
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '5 2 * * *'
|
||||
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Reset wiki to follow origin
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
cd wiki
|
||||
|
||||
git fetch --depth=1 origin master
|
||||
git reset --hard origin/master
|
||||
|
||||
- name: Download latest translations from Crowdin
|
||||
uses: crowdin/github-action@1.1.0
|
||||
with:
|
||||
upload_sources: false
|
||||
download_translations: true
|
||||
skip_untranslated_strings: true
|
||||
push_translations: false
|
||||
crowdin_branch_name: main
|
||||
project_id: ${{ secrets.ASF_CROWDIN_PROJECT_ID }}
|
||||
token: ${{ secrets.ASF_CROWDIN_API_TOKEN }}
|
||||
|
||||
- name: Commit the changes to wiki
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
cd wiki
|
||||
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
|
||||
git add -A "locale"
|
||||
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "Automatic translations update"
|
||||
fi
|
||||
|
||||
- name: Push changes to wiki
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: master
|
||||
directory: wiki
|
||||
repository: ${{ github.repository }}.wiki
|
||||
|
||||
- name: Commit the changes to ASF
|
||||
shell: sh
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
|
||||
git add -A "ArchiSteamFarm/Localization" "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization" "wiki"
|
||||
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "Automatic translations update"
|
||||
fi
|
||||
|
||||
- name: Push changes to ASF
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,9 +15,6 @@ ArchiSteamFarm/logs
|
||||
# Ignore standard out folders for publishing
|
||||
**/out
|
||||
|
||||
# Ignore crowdin CLI secret (if exists)
|
||||
tools/ArchiCrowdin/crowdin_identity.yml
|
||||
|
||||
# _ _
|
||||
# | | (_) _ __ _ _ __ __
|
||||
# | | | || '_ \ | | | |\ \/ /
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -1,12 +1,8 @@
|
||||
[submodule "ASF-WebConfigGenerator"]
|
||||
path = ASF-WebConfigGenerator
|
||||
url = https://github.com/JustArchiNET/ASF-WebConfigGenerator.git
|
||||
[submodule "ASF-ui"]
|
||||
path = ASF-ui
|
||||
url = https://github.com/JustArchiNET/ASF-ui.git
|
||||
[submodule "tools/ArchiCrowdin"]
|
||||
path = tools/ArchiCrowdin
|
||||
url = https://github.com/JustArchiNET/ArchiCrowdin.git
|
||||
branch = main
|
||||
[submodule "wiki"]
|
||||
path = wiki
|
||||
url = https://github.com/JustArchiNET/ArchiSteamFarm.wiki.git
|
||||
branch = master
|
||||
|
||||
80
.travis.yml
80
.travis.yml
@@ -1,80 +0,0 @@
|
||||
# ASF is a C# project with a solution file named ArchiSteamFarm.sln
|
||||
language: csharp
|
||||
solution: ArchiSteamFarm.sln
|
||||
|
||||
# We can save bandwidth by limiting git clone to only last 10 commits
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
# ASF is based on .NET Core platform, we're not building with Mono
|
||||
dotnet: 3.1
|
||||
mono: none
|
||||
|
||||
env:
|
||||
global:
|
||||
- CONFIGURATION: Release
|
||||
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
- NET_CORE_VERSION: netcoreapp3.1
|
||||
- VARIANTS="generic linux-arm linux-x64 osx-x64 win-x64" # NOTE: When modifying variants, don't forget to update ASF_VARIANT definitions in SharedInfo.cs!
|
||||
before_script:
|
||||
- |
|
||||
set -eu
|
||||
|
||||
dotnet --info
|
||||
set +u # This is needed to continue Travis build
|
||||
script:
|
||||
- |
|
||||
set -eu
|
||||
|
||||
nvm install lts/*
|
||||
npm ci --no-progress --prefix ASF-ui
|
||||
npm run-script deploy --no-progress --prefix ASF-ui
|
||||
|
||||
dotnet build ArchiSteamFarm -c "$CONFIGURATION" -f "$NET_CORE_VERSION" --nologo
|
||||
dotnet build ArchiSteamFarm.CustomPlugins.ExamplePlugin -c "$CONFIGURATION" -f "$NET_CORE_VERSION" --nologo
|
||||
dotnet test ArchiSteamFarm.Tests -c "$CONFIGURATION" -f "$NET_CORE_VERSION" --nologo
|
||||
|
||||
publish() {
|
||||
if [ "$1" = 'generic' ]; then
|
||||
local variantArgs="/p:UseAppHost=false"
|
||||
else
|
||||
local variantArgs="-r $1 /p:PublishTrimmed=true"
|
||||
fi
|
||||
|
||||
dotnet publish ArchiSteamFarm -c "$CONFIGURATION" -f "$NET_CORE_VERSION" -o "out/${1}" --no-restore --nologo "/p:ASFVariant=$1" $variantArgs
|
||||
|
||||
# If we include any overlay for this variant, copy it to output directory
|
||||
if [ -d "ArchiSteamFarm/overlay/${1}" ]; then
|
||||
cp "ArchiSteamFarm/overlay/${1}/"* "out/${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
dotnet clean ArchiSteamFarm -c "$CONFIGURATION" -f "$NET_CORE_VERSION" --nologo
|
||||
dotnet restore ArchiSteamFarm
|
||||
|
||||
jobs=""
|
||||
|
||||
for variant in $VARIANTS; do
|
||||
publish "$variant" &
|
||||
jobs="$jobs $!"
|
||||
done
|
||||
|
||||
for job in $jobs; do
|
||||
wait "$job"
|
||||
done
|
||||
|
||||
set +u # This is needed to continue Travis build
|
||||
matrix:
|
||||
# We can use fast finish, as we don't need to wait for allow_failures builds to mark build as success
|
||||
fast_finish: true
|
||||
include:
|
||||
# We're building ASF with dotnet on latest versions of Linux and OS X
|
||||
# Sadly, travis is still missing support for selecting latest images: https://github.com/travis-ci/travis-ci/issues/8922
|
||||
- os: linux
|
||||
# Ref: https://docs.travis-ci.com/user/reference/linux
|
||||
dist: bionic
|
||||
- os: osx
|
||||
# Ref: https://docs.travis-ci.com/user/reference/osx
|
||||
dotnet: 3.1.102 # For OSX, we need absolute dotnet version until https://github.com/dotnet/core-setup/issues/4187 is resolved
|
||||
osx_image: xcode11.3
|
||||
Submodule ASF-WebConfigGenerator deleted from 5646123e30
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: fdb3c4f11f...ca69b1c80e
@@ -1,47 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Authors>JustArchi</Authors>
|
||||
<Company>JustArchi</Company>
|
||||
<Copyright>Copyright © ArchiSteamFarm 2015-2020</Copyright>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);debug/**;out/**</DefaultItemExcludes>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<NoWarn />
|
||||
<OutputType>Library</OutputType>
|
||||
<PackageIcon>../resources/ASF.ico</PackageIcon>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/JustArchiNET/ArchiSteamFarm</PackageProjectUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/JustArchi/ArchiSteamFarm.git</RepositoryUrl>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' == 'Windows_NT' OR '$(ASFNetFramework)' != ''">
|
||||
<TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' != 'Windows_NT' AND '$(ASFNetFramework)' == ''">
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugType>none</DebugType>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" Version="4.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SteamKit2" Version="*" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" Version="*" />
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" IncludeAssets="compile" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" />
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
24
ArchiSteamFarm.CustomPlugins.ExamplePlugin/AssemblyInfo.cs
Normal file
24
ArchiSteamFarm.CustomPlugins.ExamplePlugin/AssemblyInfo.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -22,44 +22,46 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using ArchiSteamFarm.Web;
|
||||
using ArchiSteamFarm.Web.Responses;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// This is example class that shows how you can call third-party services within your plugin
|
||||
// You always wanted from your ASF to post cats, right? Now is your chance!
|
||||
// P.S. The code is almost 1:1 copy from the one I use in ArchiBoT, you can thank me later
|
||||
// You've always wanted from your ASF to post cats, right? Now is your chance!
|
||||
// P.S. The code is almost 1:1 copy from the one I use in ArchiBot, you can thank me later
|
||||
internal static class CatAPI {
|
||||
private const string URL = "https://aws.random.cat";
|
||||
|
||||
[ItemCanBeNull]
|
||||
internal static async Task<string> GetRandomCatURL([JetBrains.Annotations.NotNull] WebBrowser webBrowser) {
|
||||
const string request = URL + "/meow";
|
||||
internal static async Task<string?> GetRandomCatURL(WebBrowser webBrowser) {
|
||||
if (webBrowser == null) {
|
||||
throw new ArgumentNullException(nameof(webBrowser));
|
||||
}
|
||||
|
||||
WebBrowser.ObjectResponse<MeowResponse> response = await webBrowser.UrlGetToJsonObject<MeowResponse>(request).ConfigureAwait(false);
|
||||
Uri request = new(URL + "/meow");
|
||||
|
||||
if (response?.Content == null) {
|
||||
ObjectResponse<MeowResponse>? response = await webBrowser.UrlGetToJsonObject<MeowResponse>(request).ConfigureAwait(false);
|
||||
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(response.Content.Link)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(response.Content.Link));
|
||||
|
||||
return null;
|
||||
throw new InvalidOperationException(nameof(response.Content.Link));
|
||||
}
|
||||
|
||||
return Uri.EscapeUriString(response.Content.Link);
|
||||
return Uri.EscapeUriString(response.Content!.Link!);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1812 // False positive, the class is used during json deserialization
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
private sealed class MeowResponse {
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "file", Required = Required.Always)]
|
||||
internal readonly string Link;
|
||||
#pragma warning restore 649
|
||||
internal readonly string Link = "";
|
||||
|
||||
[JsonConstructor]
|
||||
private MeowResponse() { }
|
||||
}
|
||||
#pragma warning restore CA1812 // False positive, the class is used during json deserialization
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,8 +19,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.IPC.Controllers.Api;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -38,7 +40,11 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
[ProducesResponseType(typeof(GenericResponse<string>), (int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.ServiceUnavailable)]
|
||||
public async Task<ActionResult<GenericResponse>> CatGet() {
|
||||
string link = await CatAPI.GetRandomCatURL(ASF.WebBrowser).ConfigureAwait(false);
|
||||
if (ASF.WebBrowser == null) {
|
||||
throw new InvalidOperationException(nameof(ASF.WebBrowser));
|
||||
}
|
||||
|
||||
string? link = await CatAPI.GetRandomCatURL(ASF.WebBrowser).ConfigureAwait(false);
|
||||
|
||||
return !string.IsNullOrEmpty(link) ? Ok(new GenericResponse<string>(link)) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,12 +19,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Composition;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Json;
|
||||
using ArchiSteamFarm.Plugins;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Plugins.Interfaces;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using ArchiSteamFarm.Steam.Storage;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SteamKit2;
|
||||
|
||||
@@ -35,7 +43,6 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// Your plugin class should inherit the plugin interfaces it wants to handle
|
||||
// If you do not want to handle a particular action (e.g. OnBotMessage that is offered in IBotMessage), it's the best idea to not inherit it at all
|
||||
// This will keep your code compact, efficient and less dependent. You can always add additional interfaces when you'll need them, this example project will inherit quite a bit of them to show you potential usage
|
||||
// ReSharper disable once UnusedMember.Global - this is example plugin class that isn't used in our main code
|
||||
internal sealed class ExamplePlugin : IASF, IBot, IBotCommand, IBotConnection, IBotFriendRequest, IBotMessage, IBotModules, IBotTradeOffer {
|
||||
// This is used for identification purposes, typically you want to use a friendly name of your plugin here, such as the name of your main class
|
||||
// Please note that this property can have direct dependencies only on structures that were initialized by the constructor, as it's possible to be called before OnLoaded() takes place
|
||||
@@ -43,23 +50,26 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
|
||||
// This will be displayed to the user and written in the log file, typically you should point it to the version of your library, but alternatively you can do some more advanced logic if you'd like to
|
||||
// Please note that this property can have direct dependencies only on structures that were initialized by the constructor, as it's possible to be called before OnLoaded() takes place
|
||||
public Version Version => typeof(ExamplePlugin).Assembly.GetName().Version;
|
||||
public Version Version => typeof(ExamplePlugin).Assembly.GetName().Version ?? throw new InvalidOperationException(nameof(Version));
|
||||
|
||||
// Plugins can expose custom properties for our GET /Api/Plugins API call, simply annotate them with [JsonProperty] (or keep public)
|
||||
[JsonProperty]
|
||||
public bool CustomIsEnabledField { get; private set; } = true;
|
||||
|
||||
// This method, apart from being called before any bot initialization takes place, allows you to read custom global config properties that are not recognized by ASF
|
||||
// Thanks to that, you can extend default ASF config with your own stuff, then parse it here in order to customize your plugin during runtime
|
||||
// Keep in mind that, as noted in the interface, additionalConfigProperties can be null if no custom, unrecognized properties are found by ASF, you should handle that case appropriately
|
||||
// In addition to that, this method also guarantees that all plugins were already OnLoaded(), which allows cross-plugins-communication to be possible
|
||||
public void OnASFInit(IReadOnlyDictionary<string, JToken> additionalConfigProperties = null) {
|
||||
public void OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
if (additionalConfigProperties == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ReSharper disable once UseDeconstruction - deconstruction is not available in .NET Framework
|
||||
foreach (KeyValuePair<string, JToken> configProperty in additionalConfigProperties) {
|
||||
foreach ((string configProperty, JToken configValue) in additionalConfigProperties) {
|
||||
// It's a good idea to prefix your custom properties with the name of your plugin, so there will be no possible conflict of ASF or other plugins using the same name, neither now or in the future
|
||||
switch (configProperty.Key) {
|
||||
case nameof(ExamplePlugin) + "TestProperty" when configProperty.Value.Type == JTokenType.Boolean:
|
||||
bool exampleBooleanValue = configProperty.Value.Value<bool>();
|
||||
switch (configProperty) {
|
||||
case nameof(ExamplePlugin) + "TestProperty" when configValue.Type == JTokenType.Boolean:
|
||||
bool exampleBooleanValue = configValue.Value<bool>();
|
||||
ASF.ArchiLogger.LogGenericInfo(nameof(ExamplePlugin) + "TestProperty boolean property has been found with a value of: " + exampleBooleanValue);
|
||||
|
||||
break;
|
||||
@@ -74,14 +84,14 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// Since ASF already had to do initial parsing in order to determine that the command is unknown, args[] are splitted using standard ASF delimiters
|
||||
// If by any chance you want to handle message in its raw format, you also have it available, although for usual ASF pattern you can most likely stick with args[] exclusively. The message has CommandPrefix already stripped for your convenience
|
||||
// If you do not recognize the command, just return null/empty and allow ASF to gracefully return "unknown command" to user on usual basis
|
||||
public async Task<string> OnBotCommand(Bot bot, ulong steamID, string message, string[] args) {
|
||||
public async Task<string?> OnBotCommand(Bot bot, ulong steamID, string message, string[] args) {
|
||||
// In comparison with OnBotMessage(), we're using asynchronous CatAPI call here, so we declare our method as async and return the message as usual
|
||||
// Notice how we handle access here as well, it'll work only for FamilySharing+
|
||||
switch (args[0].ToUpperInvariant()) {
|
||||
case "CAT" when bot.HasPermission(steamID, BotConfig.EPermission.FamilySharing):
|
||||
case "CAT" when bot.HasAccess(steamID, BotConfig.EAccess.FamilySharing):
|
||||
// Notice how we can decide whether to use bot's AWH WebBrowser or ASF's one. For Steam-related requests, AWH's one should always be used, for third-party requests like those it doesn't really matter
|
||||
// Still, it makes sense to pass AWH's one, so in case you get some errors or alike, you know from which bot instance they come from. It's similar to using Bot's ArchiLogger compared to ASF's one
|
||||
string randomCatURL = await CatAPI.GetRandomCatURL(bot.ArchiWebHandler.WebBrowser).ConfigureAwait(false);
|
||||
string? randomCatURL = await CatAPI.GetRandomCatURL(bot.ArchiWebHandler.WebBrowser).ConfigureAwait(false);
|
||||
|
||||
return !string.IsNullOrEmpty(randomCatURL) ? randomCatURL : "God damn it, we're out of cats, care to notify my master? Thanks!";
|
||||
default:
|
||||
@@ -120,7 +130,7 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// Keep in mind that, as noted in the interface, additionalConfigProperties can be null if no custom, unrecognized properties are found by ASF, you should handle that case appropriately
|
||||
// Also keep in mind that this function can be called multiple times, e.g. when user edits his bot configs during runtime
|
||||
// Take a look at OnASFInit() for example parsing code
|
||||
public async void OnBotInitModules(Bot bot, IReadOnlyDictionary<string, JToken> additionalConfigProperties = null) {
|
||||
public async void OnBotInitModules(Bot bot, IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
// ASF marked this message as synchronous, in case we have async code to execute, we can just use async void return
|
||||
// For example, we'll ensure that every bot starts paused regardless of Paused property, in order to do this, we'll just call Pause here in InitModules()
|
||||
// Thanks to the fact that this method is called with each bot config reload, we'll ensure that our bot stays paused even if it'd get unpaused otherwise
|
||||
@@ -137,19 +147,29 @@ namespace ArchiSteamFarm.CustomPlugins.ExamplePlugin {
|
||||
// Keep in mind that there is no guarantee what is the actual access of steamID, so you should do the appropriate access checking yourself
|
||||
// You can use either ASF's default functions for that, or implement your own logic as you please
|
||||
// If you do not intend to return any response to user, just return null/empty and ASF will proceed with the silence as usual
|
||||
public Task<string> OnBotMessage(Bot bot, ulong steamID, string message) {
|
||||
// Normally ASF will expect from you async-capable responses, such as Task<string>. This allows you to make your code fully asynchronous which is a core fundament on which ASF is built upon
|
||||
public Task<string?> OnBotMessage(Bot bot, ulong steamID, string message) {
|
||||
// Normally ASF will expect from you async-capable responses, such as Task<string>. This allows you to make your code fully asynchronous which is a core foundation on which ASF is built upon
|
||||
// Since in this method we're not doing any async stuff, instead of defining this method as async (pointless), we just need to wrap our responses in Task.FromResult<>()
|
||||
if (Bot.BotsReadOnly == null) {
|
||||
throw new InvalidOperationException(nameof(Bot.BotsReadOnly));
|
||||
}
|
||||
|
||||
// As a starter, we can for example ignore messages sent from our own bots, since otherwise they can run into a possible infinite loop of answering themselves
|
||||
if (Bot.BotsReadOnly.Values.Any(existingBot => existingBot.SteamID == steamID)) {
|
||||
return Task.FromResult<string?>(null);
|
||||
}
|
||||
|
||||
// If this message doesn't come from one of our bots, we can reply to the user in some pre-defined way
|
||||
bot.ArchiLogger.LogGenericTrace("Hey boss, we got some unknown message here!");
|
||||
|
||||
return Task.FromResult("I didn't get that, did you mean to use a command?");
|
||||
return Task.FromResult((string?) "I didn't get that, did you mean to use a command?");
|
||||
}
|
||||
|
||||
// This method is called when bot receives a trade offer that ASF isn't willing to accept (ignored and rejected trades)
|
||||
// It allows you not only to analyze such trades, but generate a response whether ASF should accept it (true), or proceed like usual (false)
|
||||
// Thanks to that, you can implement custom rules for all trades that aren't handled by ASF, for example cross-set trading on your own custom rules
|
||||
// You'd implement your own logic here, as an example we'll allow all trades to be accepted if the bot's name starts from "TrashBot"
|
||||
public Task<bool> OnBotTradeOffer(Bot bot, Steam.TradeOffer tradeOffer) => Task.FromResult(bot.BotName.StartsWith("TrashBot", StringComparison.OrdinalIgnoreCase));
|
||||
public Task<bool> OnBotTradeOffer(Bot bot, TradeOffer tradeOffer) => Task.FromResult(bot.BotName.StartsWith("TrashBot", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// This is the earliest method that will be called, right after loading the plugin, long before any bot initialization takes place
|
||||
// It's a good place to initialize all potential (non-bot-specific) structures that you will need across lifetime of your plugin, such as global timers, concurrent dictionaries and alike
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
24
ArchiSteamFarm.CustomPlugins.PeriodicGC/AssemblyInfo.cs
Normal file
24
ArchiSteamFarm.CustomPlugins.PeriodicGC/AssemblyInfo.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
64
ArchiSteamFarm.CustomPlugins.PeriodicGC/PeriodicGCPlugin.cs
Normal file
64
ArchiSteamFarm.CustomPlugins.PeriodicGC/PeriodicGCPlugin.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.Composition;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Plugins.Interfaces;
|
||||
|
||||
namespace ArchiSteamFarm.CustomPlugins.PeriodicGC {
|
||||
[Export(typeof(IPlugin))]
|
||||
[SuppressMessage("ReSharper", "UnusedType.Global")]
|
||||
internal sealed class PeriodicGCPlugin : IPlugin {
|
||||
private const byte GCPeriod = 60; // In seconds
|
||||
|
||||
private static readonly object LockObject = new();
|
||||
private static readonly Timer PeriodicGCTimer = new(PerformGC);
|
||||
|
||||
public string Name => nameof(PeriodicGCPlugin);
|
||||
|
||||
public Version Version => typeof(PeriodicGCPlugin).Assembly.GetName().Version ?? throw new InvalidOperationException(nameof(Version));
|
||||
|
||||
public void OnLoaded() {
|
||||
TimeSpan timeSpan = TimeSpan.FromSeconds(GCPeriod);
|
||||
|
||||
ASF.ArchiLogger.LogGenericWarning("Periodic GC will occur every " + timeSpan.ToHumanReadable() + ". Please keep in mind that this plugin should be used for debugging tests only.");
|
||||
|
||||
lock (LockObject) {
|
||||
PeriodicGCTimer.Change(timeSpan, timeSpan);
|
||||
}
|
||||
}
|
||||
|
||||
private static void PerformGC(object? state) {
|
||||
ASF.ArchiLogger.LogGenericWarning("Performing GC, current memory: " + (GC.GetTotalMemory(false) / 1024) + " KB.");
|
||||
|
||||
lock (LockObject) {
|
||||
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
|
||||
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true);
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericWarning("GC finished, current memory: " + (GC.GetTotalMemory(false) / 1024) + " KB.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" IncludeAssets="compile" />
|
||||
<PackageReference Include="SteamKit2" IncludeAssets="compile" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" IncludeAssets="compile" />
|
||||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
|
||||
<PackageReference Include="System.Collections.Immutable" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Localization\Strings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Localization\Strings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,24 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
288
ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/GlobalCache.cs
Normal file
288
ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/GlobalCache.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using File = System.IO.File;
|
||||
using Path = System.IO.Path;
|
||||
#else
|
||||
using System.IO;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using Newtonsoft.Json;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
internal sealed class GlobalCache : SerializableFile {
|
||||
private static string SharedFilePath => Path.Combine(ArchiSteamFarm.SharedInfo.ConfigDirectory, nameof(SteamTokenDumper) + ".cache");
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, uint> AppChangeNumbers = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, ulong> AppTokens = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, string> DepotKeys = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, ulong> PackageTokens = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, ulong> SubmittedApps = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, string> SubmittedDepots = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentDictionary<uint, ulong> SubmittedPackages = new();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
internal uint LastChangeNumber { get; private set; }
|
||||
|
||||
internal GlobalCache() => FilePath = SharedFilePath;
|
||||
|
||||
internal ulong GetAppToken(uint appID) => AppTokens[appID];
|
||||
|
||||
internal Dictionary<uint, ulong> GetAppTokensForSubmission() => AppTokens.Where(appToken => (SteamTokenDumperPlugin.Config?.SecretAppIDs.Contains(appToken.Key) == false) && (appToken.Value > 0) && (!SubmittedApps.TryGetValue(appToken.Key, out ulong token) || (appToken.Value != token))).ToDictionary(appToken => appToken.Key, appToken => appToken.Value);
|
||||
internal Dictionary<uint, string> GetDepotKeysForSubmission() => DepotKeys.Where(depotKey => (SteamTokenDumperPlugin.Config?.SecretDepotIDs.Contains(depotKey.Key) == false) && !string.IsNullOrEmpty(depotKey.Value) && (!SubmittedDepots.TryGetValue(depotKey.Key, out string? key) || (depotKey.Value != key))).ToDictionary(depotKey => depotKey.Key, depotKey => depotKey.Value);
|
||||
internal Dictionary<uint, ulong> GetPackageTokensForSubmission() => PackageTokens.Where(packageToken => (SteamTokenDumperPlugin.Config?.SecretPackageIDs.Contains(packageToken.Key) == false) && (packageToken.Value > 0) && (!SubmittedPackages.TryGetValue(packageToken.Key, out ulong token) || (packageToken.Value != token))).ToDictionary(packageToken => packageToken.Key, packageToken => packageToken.Value);
|
||||
|
||||
internal static async Task<GlobalCache?> Load() {
|
||||
if (!File.Exists(SharedFilePath)) {
|
||||
GlobalCache result = new();
|
||||
|
||||
Utilities.InBackground(result.Save);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GlobalCache? globalCache;
|
||||
|
||||
try {
|
||||
string json = await Compatibility.File.ReadAllTextAsync(SharedFilePath).ConfigureAwait(false);
|
||||
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
globalCache = JsonConvert.DeserializeObject<GlobalCache>(json);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (globalCache == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(globalCache));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return globalCache;
|
||||
}
|
||||
|
||||
internal void OnPICSChanges(uint currentChangeNumber, IReadOnlyCollection<KeyValuePair<uint, SteamApps.PICSChangesCallback.PICSChangeData>> appChanges) {
|
||||
if (currentChangeNumber == 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (appChanges == null) {
|
||||
throw new ArgumentNullException(nameof(appChanges));
|
||||
}
|
||||
|
||||
if (currentChangeNumber <= LastChangeNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
LastChangeNumber = currentChangeNumber;
|
||||
|
||||
foreach ((uint appID, SteamApps.PICSChangesCallback.PICSChangeData appData) in appChanges) {
|
||||
if (!AppChangeNumbers.TryGetValue(appID, out uint previousChangeNumber) || (appData.ChangeNumber <= previousChangeNumber)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AppChangeNumbers.TryRemove(appID, out _);
|
||||
}
|
||||
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
|
||||
internal void OnPICSChangesRestart(uint currentChangeNumber) {
|
||||
if (currentChangeNumber == 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (currentChangeNumber <= LastChangeNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
LastChangeNumber = currentChangeNumber;
|
||||
AppChangeNumbers.Clear();
|
||||
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
|
||||
internal bool ShouldRefreshAppInfo(uint appID) => !AppChangeNumbers.ContainsKey(appID);
|
||||
internal bool ShouldRefreshDepotKey(uint depotID) => !DepotKeys.ContainsKey(depotID);
|
||||
|
||||
internal void UpdateAppChangeNumbers(IReadOnlyCollection<KeyValuePair<uint, uint>> appChangeNumbers) {
|
||||
if (appChangeNumbers == null) {
|
||||
throw new ArgumentNullException(nameof(appChangeNumbers));
|
||||
}
|
||||
|
||||
bool save = false;
|
||||
|
||||
foreach ((uint appID, uint changeNumber) in appChangeNumbers) {
|
||||
if (AppChangeNumbers.TryGetValue(appID, out uint previousChangeNumber) && (previousChangeNumber == changeNumber)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AppChangeNumbers[appID] = changeNumber;
|
||||
save = true;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAppTokens(IReadOnlyCollection<KeyValuePair<uint, ulong>> appTokens, IReadOnlyCollection<uint> publicAppIDs) {
|
||||
if (appTokens == null) {
|
||||
throw new ArgumentNullException(nameof(appTokens));
|
||||
}
|
||||
|
||||
if (publicAppIDs == null) {
|
||||
throw new ArgumentNullException(nameof(publicAppIDs));
|
||||
}
|
||||
|
||||
bool save = false;
|
||||
|
||||
foreach ((uint appID, ulong appToken) in appTokens) {
|
||||
if (AppTokens.TryGetValue(appID, out ulong previousAppToken) && (previousAppToken == appToken)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AppTokens[appID] = appToken;
|
||||
save = true;
|
||||
}
|
||||
|
||||
foreach (uint appID in publicAppIDs) {
|
||||
if (AppTokens.TryGetValue(appID, out ulong previousAppToken) && (previousAppToken == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AppTokens[appID] = 0;
|
||||
save = true;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateDepotKeys(ICollection<SteamApps.DepotKeyCallback> depotKeyResults) {
|
||||
if (depotKeyResults == null) {
|
||||
throw new ArgumentNullException(nameof(depotKeyResults));
|
||||
}
|
||||
|
||||
bool save = false;
|
||||
|
||||
foreach (SteamApps.DepotKeyCallback depotKeyResult in depotKeyResults) {
|
||||
if (depotKeyResult.Result != EResult.OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string depotKey = BitConverter.ToString(depotKeyResult.DepotKey).Replace("-", "", StringComparison.Ordinal);
|
||||
|
||||
if (DepotKeys.TryGetValue(depotKeyResult.DepotID, out string? previousDepotKey) && (previousDepotKey == depotKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DepotKeys[depotKeyResult.DepotID] = depotKey;
|
||||
save = true;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdatePackageTokens(IReadOnlyCollection<KeyValuePair<uint, ulong>> packageTokens) {
|
||||
if (packageTokens == null) {
|
||||
throw new ArgumentNullException(nameof(packageTokens));
|
||||
}
|
||||
|
||||
bool save = false;
|
||||
|
||||
foreach ((uint packageID, ulong packageToken) in packageTokens) {
|
||||
if (PackageTokens.TryGetValue(packageID, out ulong previousPackageToken) && (previousPackageToken == packageToken)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PackageTokens[packageID] = packageToken;
|
||||
save = true;
|
||||
}
|
||||
|
||||
if (save) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateSubmittedData(IReadOnlyDictionary<uint, ulong> apps, IReadOnlyDictionary<uint, ulong> packages, IReadOnlyDictionary<uint, string> depots) {
|
||||
if (apps == null) {
|
||||
throw new ArgumentNullException(nameof(apps));
|
||||
}
|
||||
|
||||
if (packages == null) {
|
||||
throw new ArgumentNullException(nameof(packages));
|
||||
}
|
||||
|
||||
if (depots == null) {
|
||||
throw new ArgumentNullException(nameof(depots));
|
||||
}
|
||||
|
||||
foreach ((uint appID, ulong token) in apps) {
|
||||
SubmittedApps[appID] = token;
|
||||
}
|
||||
|
||||
foreach ((uint packageID, ulong token) in packages) {
|
||||
SubmittedPackages[packageID] = token;
|
||||
}
|
||||
|
||||
foreach ((uint depotID, string key) in depots) {
|
||||
SubmittedDepots[depotID] = key;
|
||||
}
|
||||
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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 Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
public sealed class GlobalConfigExtension {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public SteamTokenDumperConfig? SteamTokenDumperPlugin { get; private set; }
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool SteamTokenDumperPluginEnabled { get; private set; }
|
||||
|
||||
[JsonConstructor]
|
||||
internal GlobalConfigExtension() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
This directory contains ASF strings for display and localization purposes.
|
||||
|
||||
All strings used by ASF can be found in main `Strings.resx` file, and that's also the only `resx` file that should be modified - all other `resx` files are managed automatically and should not be touched. Please visit **[localization](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Localization)** section on the wiki if you want to improve translation of other files.
|
||||
252
ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization/Strings.Designer.cs
generated
Normal file
252
ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization/Strings.Designer.cs
generated
Normal file
@@ -0,0 +1,252 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Strings {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Strings() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization.Strings", typeof(Strings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving {0} app access tokens..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving {0} app infos..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingAppInfos {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingAppInfos", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving {0} depot keys..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingDepotKeys {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingDepotKeys", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving a total of {0} app access tokens..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingTotalAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingTotalAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Finished retrieving all depot keys for a total of {0} apps..
|
||||
/// </summary>
|
||||
internal static string BotFinishedRetrievingTotalDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("BotFinishedRetrievingTotalDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to There are no apps that require a refresh on this bot instance..
|
||||
/// </summary>
|
||||
internal static string BotNoAppsToRefresh {
|
||||
get {
|
||||
return ResourceManager.GetString("BotNoAppsToRefresh", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving {0} app access tokens....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving {0} app infos....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingAppInfos {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingAppInfos", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving {0} depot keys....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingDepotKeys {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingDepotKeys", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving a total of {0} app access tokens....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingTotalAppAccessTokens {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingTotalAppAccessTokens", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Retrieving all depots for a total of {0} apps....
|
||||
/// </summary>
|
||||
internal static string BotRetrievingTotalDepots {
|
||||
get {
|
||||
return ResourceManager.GetString("BotRetrievingTotalDepots", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} could not be loaded, a fresh instance will be initialized....
|
||||
/// </summary>
|
||||
internal static string FileCouldNotBeLoadedFreshInit {
|
||||
get {
|
||||
return ResourceManager.GetString("FileCouldNotBeLoadedFreshInit", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} is currently disabled according to your configuration. If you'd like to help SteamDB in data submission, please check out our wiki..
|
||||
/// </summary>
|
||||
internal static string PluginDisabledInConfig {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginDisabledInConfig", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} has been disabled due to a missing build token.
|
||||
/// </summary>
|
||||
internal static string PluginDisabledMissingBuildToken {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginDisabledMissingBuildToken", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} has been initialized successfully, thank you in advance for your help. The first submission will happen in approximately {1} from now..
|
||||
/// </summary>
|
||||
internal static string PluginInitializedAndEnabled {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginInitializedAndEnabled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} initialized, the plugin will not resolve any of those: {1}..
|
||||
/// </summary>
|
||||
internal static string PluginSecretListInitialized {
|
||||
get {
|
||||
return ResourceManager.GetString("PluginSecretListInitialized", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The submission has failed due to too many requests sent, we'll try again in approximately {0} from now..
|
||||
/// </summary>
|
||||
internal static string SubmissionFailedTooManyRequests {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionFailedTooManyRequests", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Submitting a total of registered apps/subs/depots: {0}/{1}/{2}....
|
||||
/// </summary>
|
||||
internal static string SubmissionInProgress {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionInProgress", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not submit the data because there is no valid SteamID set that we could classify as a contributor. Consider setting up {0} property..
|
||||
/// </summary>
|
||||
internal static string SubmissionNoContributorSet {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionNoContributorSet", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to There is no new data to submit, everything is up-to-date..
|
||||
/// </summary>
|
||||
internal static string SubmissionNoNewData {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionNoNewData", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The data has been successfully submitted. The server has registered a total of new apps/subs/depots: {0}/{1}/{2}..
|
||||
/// </summary>
|
||||
internal static string SubmissionSuccessful {
|
||||
get {
|
||||
return ResourceManager.GetString("SubmissionSuccessful", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} wurde aufgrund eines zur Kompilierzeit fehlenden Schlüssels deaktiviert</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>{0} ist gemäß Ihrer Konfiguration derzeit deaktiviert. Wenn Sie SteamDB bei der Datenübermittlung helfen möchten, sehen Sie sich bitte unser Wiki an.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} wurde erfolgreich initialisiert, wir danken Ihnen im Voraus für Ihre Hilfe. Die erste Übermittlung wird in etwa {1} ab jetzt erfolgen.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} konnte nicht geladen werden. Eine frische Instanz wird initialisiert werden...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>Es gibt auf dieser Bot-Instanz keine Applikationen, die einer Auffrischung bedürfen.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Rufe insgesamt {0} Applikationszugriffstoken ab...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Rufe {0} Applikationszugriffstoken ab...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Abruf von {0} Applikationszugrifsstoken fertiggestellt.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Abruf von insgesamt {0} Applikationszugriffstoken fertiggestellt.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Rufe alle Depots für insgesamt {0} Applikationen ab...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Rufe {0} Applikationsinfos ab...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Abruf von {0} Applikationsinfos fertiggestellt.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Rufe {0} Depotschlüssel ab...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Abruf von {0} Depotschlüsseln fertiggestellt.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Abruf aller Depotschlüssel für insgesamt {0} Applikationen fertiggestellt.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>Es sind keine neuen Daten einzureichen. Alle Daten sind aktuell.</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>Konnte keine Daten einreichen, da keine SteamID identifiziert wurde, die als Einreichender valide ist. Bitte ziehe in Betracht {0} zu konfigurieren.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
<data name="SubmissionInProgress" xml:space="preserve">
|
||||
<value>Reiche insgesamt folgende Applikationen/Subs/Depots ein: {0}/{1}/{2}...</value>
|
||||
<comment>{0} will be replaced by the number of app access tokens being submitted, {1} will be replaced by the number of package access tokens being submitted, {2} will be replaced by the number of depot keys being submitted</comment>
|
||||
</data>
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>Das Einreichen schlug fehl, weil wir zu viele Einreichungen in zu kurzer Zeit versuchten. Wir versuchen es in ungefähr {0} wieder.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessful" xml:space="preserve">
|
||||
<value>Die Daten wurden erfolgreich übermittelt. Folgende Anzahl an Applikationen/Subs/Depots wurde vom Server als neu registriert: {0}/{1}/{2}.</value>
|
||||
<comment>{0} will be replaced by the number of new app access tokens that the server has registered, {1} will be replaced by the number of new package access tokens that the server has registered, {2} will be replaced by the number of new depot keys that the server has registered</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} initialisiert, das Plugin wird keines davon lösen: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} ha sido deshabilitado debido a que falta un token de compilación</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>{0} está deshabilitado actualmente de acuerdo a tu configuración. Si quieres ayudar a SteamDB enviando datos, por favor, revisa nuestra wiki.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} ha sido iniciado con éxito, gracias de antemano por tu ayuda. El primer envío tendrá lugar en aproximadamente {1} a partir de ahora.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} no se pudo cargar, se iniciará una nueva instancia...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>No hay aplicaciones que requieran actualizarse en esta instancia de bot.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Recuperando un total de {0} tokens de acceso de aplicación...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Recuperando {0} tokens de acceso de aplicación...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Se han terminado de recuperar {0} tokens de acceso de aplicación.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Se ha terminado de recuperar un total de {0} tokens de acceso de aplicación.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Recuperando todos los depots para un total de {0} aplicaciones...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Recuperando {0} datos de aplicación...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Se han terminado de recuperar {0} datos de aplicación.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Recuperando {0} depot keys...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Se han terminado de recuperar {0} depot keys.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Se han terminado de recuperar todos los depot keys para un total de {0} aplicaciones.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>No hay nuevos datos para enviar, todo está actualizado.</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>No se pudieron enviar los datos debido a que no hay un SteamID válido establecido que podamos clasificar como colaborador. Considera configurar la propiedad {0}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
<data name="SubmissionInProgress" xml:space="preserve">
|
||||
<value>Enviando un total de apps/subs/depots registrados: {0}/{1}/{2}...</value>
|
||||
<comment>{0} will be replaced by the number of app access tokens being submitted, {1} will be replaced by the number of package access tokens being submitted, {2} will be replaced by the number of depot keys being submitted</comment>
|
||||
</data>
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>El envío ha fallado debido a demasiadas solicitudes enviadas, lo intentaremos de nuevo en aproximadamente {0} a partir de ahora.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessful" xml:space="preserve">
|
||||
<value>Los datos se han enviado con éxito. El servidor ha registrado un total de nuevos apps/subs/depots: {0}/{1}/{2}.</value>
|
||||
<comment>{0} will be replaced by the number of new app access tokens that the server has registered, {1} will be replaced by the number of new package access tokens that the server has registered, {2} will be replaced by the number of new depot keys that the server has registered</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} iniciado, el plugin no resolverá ninguno de estos: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} został wyłączony z powodu brakującego tokena kompilacji</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>{0} jest obecnie wyłączony zgodnie z Twoją konfiguracją. Jeśli chciałbyś pomóc SteamDB w gromadzeniu danych, sprawdź naszą wiki.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} został pomyślnie zainicjowany, dziękujemy z góry za pomoc. Pierwsze zgłoszenie nastąpi za około {1} od teraz.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} nie może zostać załadowany, nowa instancja zostanie zainicjowana...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>Brak aplikacji, które wymagają odświeżenia instancji tego bota.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Pobieranie łącznie {0} tokenów dostępu aplikacji...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Pobieranie {0} tokenów dostępu aplikacji...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Zakończono pobieranie {0} tokenów dostępu aplikacji.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Zakończono pobieranie łącznie {0} tokenów dostępu aplikacji.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Pobieranie wszystkich magazynów dla łącznie {0} aplikacji...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Pobieranie {0} informacji o aplikacji...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Zakończono pobieranie {0} informacji o aplikacji.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Pobieranie {0} kluczy magazynu...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Zakończono pobieranie {0} kluczy magazynu.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Zakończono pobieranie wszystkich kluczy magazynu dla {0} aplikacji.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>Nie ma nowych danych do przesłania, wszystko jest aktualne.</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>Nie można przesłać danych, ponieważ nie ma poprawnego zestawu SteamID, który moglibyśmy sklasyfikować jako współtwórca. Rozważ ustawienie właściwości {0}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
<data name="SubmissionInProgress" xml:space="preserve">
|
||||
<value>Przesyłanie łącznej liczby zarejestrowanych aplikacji/subskrypcji/magazynów: {0}/{1}/{2}...</value>
|
||||
<comment>{0} will be replaced by the number of app access tokens being submitted, {1} will be replaced by the number of package access tokens being submitted, {2} will be replaced by the number of depot keys being submitted</comment>
|
||||
</data>
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>Przesyłanie nie powiodło się z powodu zbyt wielu wysłanych żądań, spróbujemy ponownie za około {0} od teraz.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessful" xml:space="preserve">
|
||||
<value>Dane zostały pomyślnie przesłane. Serwer zarejestrował łączną liczbę nowych aplikacji/subskrypcji/magazynów: {0}/{1}/{2}.</value>
|
||||
<comment>{0} will be replaced by the number of new app access tokens that the server has registered, {1} will be replaced by the number of new package access tokens that the server has registered, {2} will be replaced by the number of new depot keys that the server has registered</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} zainicjowano, wtyczka nie rozwiąże żadnego z tych: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,144 @@
|
||||
<?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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} foi desativado devido à falta de um token de compilação</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} HAZ BEEN DISABLD DUE 2 MISIN BUILD TOKEN</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>{0} IZ CURRENTLY DISABLD ACCORDIN 2 UR CONFIGURASHUN. IF UD LIEK 2 HALP STEAMDB IN DATA SUBMISHUN, PLZ CHECK OUT R WIKI.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} HAS BEEN INITIALIZD SUCCESFULLY, THANK U IN ADVANCE 4 UR HALP. TEH FURST SUBMISHUN WILL HAPPEN IN APPROXIMATELY {1} FRUM NAO.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} CUD NOT BE LOADD, FRESH INSTANCE WILL BE INITIALIZD...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>THAR R NO APPS DAT REQUIRE REFRESH ON DIS BOT INSTANCE.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>RETRIEVIN TOTAL OV {0} APP ACCES TOKENS...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>RETRIEVIN {0} APP ACCES TOKENS...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>FINISHD RETRIEVIN {0} APP ACCES TOKENS.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>FINISHD RETRIEVIN TOTAL OV {0} APP ACCES TOKENS.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>RETRIEVIN ALL DEPOTS 4 TOTAL OV {0} APPS...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>RETRIEVIN {0} APP INFOS...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>FINISHD RETRIEVIN {0} APP INFOS.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>RETRIEVIN {0} DEPOT KEYS...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>FINISHD RETRIEVIN {0} DEPOT KEYS.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>FINISHD RETRIEVIN ALL DEPOT KEYS 4 TOTAL OV {0} APPS.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>THAR IZ NO NEW DATA 2 SUBMIT, EVRYTHIN IZ UP-2-DATE.</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>CUD NOT SUBMIT TEH DATA CUZ THAR IZ NO VALID STEAMID SET DAT WE CUD CLASIFY AS CONTRIBUTOR. CONSIDR SETTIN UP {0} PROPERTY.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
<data name="SubmissionInProgress" xml:space="preserve">
|
||||
<value>SUBMITTIN TOTAL OV REGISTERD APPS/SUBS/DEPOTS: {0}/{1}/{2}...</value>
|
||||
<comment>{0} will be replaced by the number of app access tokens being submitted, {1} will be replaced by the number of package access tokens being submitted, {2} will be replaced by the number of depot keys being submitted</comment>
|
||||
</data>
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>TEH SUBMISHUN HAS FAILD DUE 2 2 LOTZ DA REQUESTS SENT, WELL TRY AGAIN IN APPROXIMATELY {0} FRUM NAO.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessful" xml:space="preserve">
|
||||
<value>TEH DATA HAS BEEN SUCCESFULLY SUBMITTD. TEH SERVR HAS REGISTERD TOTAL OV NEW APPS/SUBS/DEPOTS: {0}/{1}/{2}.</value>
|
||||
<comment>{0} will be replaced by the number of new app access tokens that the server has registered, {1} will be replaced by the number of new package access tokens that the server has registered, {2} will be replaced by the number of new depot keys that the server has registered</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} INITIALIZD, TEH PLUGIN WILL NOT RESOLVE ANY OV DOSE: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?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 id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>{0} has been disabled due to a missing build token</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>{0} is currently disabled according to your configuration. If you'd like to help SteamDB in data submission, please check out our wiki.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} has been initialized successfully, thank you in advance for your help. The first submission will happen in approximately {1} from now.</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} could not be loaded, a fresh instance will be initialized...</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>There are no apps that require a refresh on this bot instance.</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Retrieving a total of {0} app access tokens...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Retrieving {0} app access tokens...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>Finished retrieving {0} app access tokens.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>Finished retrieving a total of {0} app access tokens.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Retrieving all depots for a total of {0} apps...</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Retrieving {0} app infos...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>Finished retrieving {0} app infos.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Retrieving {0} depot keys...</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>Finished retrieving {0} depot keys.</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>Finished retrieving all depot keys for a total of {0} apps.</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>There is no new data to submit, everything is up-to-date.</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>Could not submit the data because there is no valid SteamID set that we could classify as a contributor. Consider setting up {0} property.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
<data name="SubmissionInProgress" xml:space="preserve">
|
||||
<value>Submitting a total of registered apps/subs/depots: {0}/{1}/{2}...</value>
|
||||
<comment>{0} will be replaced by the number of app access tokens being submitted, {1} will be replaced by the number of package access tokens being submitted, {2} will be replaced by the number of depot keys being submitted</comment>
|
||||
</data>
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>The submission has failed due to too many requests sent, we'll try again in approximately {0} from now.</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessful" xml:space="preserve">
|
||||
<value>The data has been successfully submitted. The server has registered a total of new apps/subs/depots: {0}/{1}/{2}.</value>
|
||||
<comment>{0} will be replaced by the number of new app access tokens that the server has registered, {1} will be replaced by the number of new package access tokens that the server has registered, {2} will be replaced by the number of new depot keys that the server has registered</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} initialized, the plugin will not resolve any of those: {1}.</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?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="PluginDisabledMissingBuildToken" xml:space="preserve">
|
||||
<value>因为缺少构建令牌,{0} 已被禁用。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginDisabledInConfig" xml:space="preserve">
|
||||
<value>按照您的配置,{0} 当前被禁用。如果您愿意帮助 SteamDB 提交数据,请查看我们的 Wiki。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin")</comment>
|
||||
</data>
|
||||
<data name="PluginInitializedAndEnabled" xml:space="preserve">
|
||||
<value>{0} 加载成功,感谢您的帮助。首次提交将会在大约 {1}后开始。</value>
|
||||
<comment>{0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="FileCouldNotBeLoadedFreshInit" xml:space="preserve">
|
||||
<value>{0} 无法加载,将初始化新实例……</value>
|
||||
<comment>{0} will be replaced by the name of the file (e.g. "GlobalCache")</comment>
|
||||
</data>
|
||||
<data name="BotNoAppsToRefresh" xml:space="preserve">
|
||||
<value>此机器人实例没有需要刷新的 App。</value>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>正在获取共计 {0} 个 App Token……</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>正在获取 {0} 个 App Token……</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppAccessTokens" xml:space="preserve">
|
||||
<value>已完成获取 {0} 个 App Token。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalAppAccessTokens" xml:space="preserve">
|
||||
<value>已完成获取共计 {0} 个 App Token。</value>
|
||||
<comment>{0} will be replaced by the number (total count) of app access tokens retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>正在获取共计 {0} 个 App 的所有 Depot……</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingAppInfos" xml:space="preserve">
|
||||
<value>正在获取 {0} 个 App 的信息……</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingAppInfos" xml:space="preserve">
|
||||
<value>已完成获取 {0} 个 App 的信息。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of app infos retrieved</comment>
|
||||
</data>
|
||||
<data name="BotRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>正在获取 {0} 个 Depot Key……</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys being retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingDepotKeys" xml:space="preserve">
|
||||
<value>已完成获取 {0} 个 Depot key。</value>
|
||||
<comment>{0} will be replaced by the number (count this batch) of depot keys retrieved</comment>
|
||||
</data>
|
||||
<data name="BotFinishedRetrievingTotalDepots" xml:space="preserve">
|
||||
<value>已完成获取共计 {0} 个 App 的所有 Depot Key。</value>
|
||||
<comment>{0} will be replaced by the number (total count) of apps retrieved</comment>
|
||||
</data>
|
||||
<data name="SubmissionNoNewData" xml:space="preserve">
|
||||
<value>没有可提交的新数据,所有数据都已更新。</value>
|
||||
</data>
|
||||
<data name="SubmissionNoContributorSet" xml:space="preserve">
|
||||
<value>无法提交数据,因为尚未设置有效的 Steam ID 供我们识别贡献者。请考虑设置 {0} 属性。</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SteamOwnerID") that the user is expected to set</comment>
|
||||
</data>
|
||||
<data name="SubmissionInProgress" xml:space="preserve">
|
||||
<value>正在提交已注册的 App/Sub/Depot:共计 {0}/{1}/{2} 个……</value>
|
||||
<comment>{0} will be replaced by the number of app access tokens being submitted, {1} will be replaced by the number of package access tokens being submitted, {2} will be replaced by the number of depot keys being submitted</comment>
|
||||
</data>
|
||||
<data name="SubmissionFailedTooManyRequests" xml:space="preserve">
|
||||
<value>由于发送请求过多,提交失败,我们将会在大约 {0}后重试。</value>
|
||||
<comment>{0} will be replaced by translated TimeSpan string (such as "53 minutes")</comment>
|
||||
</data>
|
||||
<data name="SubmissionSuccessful" xml:space="preserve">
|
||||
<value>数据已成功提交。服务器已注册新 App/Sub/Depot:共计 {0}/{1}/{2} 个。</value>
|
||||
<comment>{0} will be replaced by the number of new app access tokens that the server has registered, {1} will be replaced by the number of new package access tokens that the server has registered, {2} will be replaced by the number of new depot keys that the server has registered</comment>
|
||||
</data>
|
||||
<data name="PluginSecretListInitialized" xml:space="preserve">
|
||||
<value>{0} 已初始化,插件无法解析以下任何内容:{1}。</value>
|
||||
<comment>{0} will be replaced by the name of the config property (e.g. "SecretPackageIDs"), {1} will be replaced by list of the objects (IDs, numbers), separated by a comma</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</root>
|
||||
@@ -0,0 +1,79 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using ArchiSteamFarm.Core;
|
||||
using Newtonsoft.Json;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
internal sealed class RequestData {
|
||||
[JsonProperty(PropertyName = "guid", Required = Required.Always)]
|
||||
private static string Guid => ASF.GlobalDatabase?.Identifier.ToString("N") ?? throw new InvalidOperationException(nameof(ASF.GlobalDatabase.Identifier));
|
||||
|
||||
[JsonProperty(PropertyName = "token", Required = Required.Always)]
|
||||
private static string Token => SharedInfo.Token;
|
||||
|
||||
[JsonProperty(PropertyName = "v", Required = Required.Always)]
|
||||
private static byte Version => SharedInfo.ApiVersion;
|
||||
|
||||
[JsonProperty(PropertyName = "apps", Required = Required.Always)]
|
||||
private readonly ImmutableDictionary<string, string> Apps;
|
||||
|
||||
[JsonProperty(PropertyName = "depots", Required = Required.Always)]
|
||||
private readonly ImmutableDictionary<string, string> Depots;
|
||||
|
||||
private readonly ulong SteamID;
|
||||
|
||||
[JsonProperty(PropertyName = "subs", Required = Required.Always)]
|
||||
private readonly ImmutableDictionary<string, string> Subs;
|
||||
|
||||
[JsonProperty(PropertyName = "steamid", Required = Required.Always)]
|
||||
private string SteamIDText => new SteamID(SteamID).Render();
|
||||
|
||||
internal RequestData(ulong steamID, IReadOnlyCollection<KeyValuePair<uint, ulong>> apps, IReadOnlyCollection<KeyValuePair<uint, ulong>> accessTokens, IReadOnlyCollection<KeyValuePair<uint, string>> depots) {
|
||||
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
|
||||
throw new ArgumentOutOfRangeException(nameof(steamID));
|
||||
}
|
||||
|
||||
if (apps == null) {
|
||||
throw new ArgumentNullException(nameof(apps));
|
||||
}
|
||||
|
||||
if (accessTokens == null) {
|
||||
throw new ArgumentNullException(nameof(accessTokens));
|
||||
}
|
||||
|
||||
if (depots == null) {
|
||||
throw new ArgumentNullException(nameof(depots));
|
||||
}
|
||||
|
||||
SteamID = steamID;
|
||||
|
||||
Apps = apps.ToImmutableDictionary(app => app.Key.ToString(CultureInfo.InvariantCulture), app => app.Value.ToString(CultureInfo.InvariantCulture));
|
||||
Subs = accessTokens.ToImmutableDictionary(package => package.Key.ToString(CultureInfo.InvariantCulture), package => package.Value.ToString(CultureInfo.InvariantCulture));
|
||||
Depots = depots.ToImmutableDictionary(depot => depot.Key.ToString(CultureInfo.InvariantCulture), depot => depot.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.Diagnostics.CodeAnalysis;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
#pragma warning disable CA1812 // False positive, the class is used during json deserialization
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
internal sealed class ResponseData {
|
||||
#pragma warning disable CS0649 // False positive, the field is used during json deserialization
|
||||
[JsonProperty(PropertyName = "data", Required = Required.DisallowNull)]
|
||||
internal readonly InternalData? Data;
|
||||
#pragma warning restore CS0649 // False positive, the field is used during json deserialization
|
||||
|
||||
#pragma warning disable CS0649 // False positive, the field is used during json deserialization
|
||||
[JsonProperty(PropertyName = "success", Required = Required.Always)]
|
||||
internal readonly bool Success;
|
||||
#pragma warning restore CS0649 // False positive, the field is used during json deserialization
|
||||
|
||||
[JsonConstructor]
|
||||
private ResponseData() { }
|
||||
|
||||
internal sealed class InternalData {
|
||||
#pragma warning disable CS0649 // False positive, the field is used during json deserialization
|
||||
[JsonProperty(PropertyName = "new_apps", Required = Required.Always)]
|
||||
internal readonly uint NewAppsCount;
|
||||
#pragma warning restore CS0649 // False positive, the field is used during json deserialization
|
||||
|
||||
#pragma warning disable CS0649 // False positive, the field is used during json deserialization
|
||||
[JsonProperty(PropertyName = "new_depots", Required = Required.Always)]
|
||||
internal readonly uint NewDepotsCount;
|
||||
#pragma warning restore CS0649 // False positive, the field is used during json deserialization
|
||||
|
||||
#pragma warning disable CS0649 // False positive, the field is used during json deserialization
|
||||
[JsonProperty(PropertyName = "new_subs", Required = Required.Always)]
|
||||
internal readonly uint NewSubsCount;
|
||||
#pragma warning restore CS0649 // False positive, the field is used during json deserialization
|
||||
|
||||
[JsonConstructor]
|
||||
private InternalData() { }
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1812 // False positive, the class is used during json deserialization
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
internal static class SharedInfo {
|
||||
internal const byte ApiVersion = 1;
|
||||
internal const byte AppInfosPerSingleRequest = byte.MaxValue;
|
||||
internal const byte MaximumHoursBetweenRefresh = 8; // Per single bot account, makes sense to be 2 or 3 times less than MinimumHoursBetweenUploads
|
||||
internal const byte MaximumMinutesBeforeFirstUpload = 60; // Must be greater or equal to MinimumMinutesBeforeFirstUpload
|
||||
internal const byte MinimumHoursBetweenUploads = 24;
|
||||
internal const byte MinimumMinutesBeforeFirstUpload = 10; // Must be less or equal to MaximumMinutesBeforeFirstUpload
|
||||
internal const string ServerURL = "https://asf-token-dumper.xpaw.me";
|
||||
internal const string Token = "STEAM_TOKEN_DUMPER_TOKEN";
|
||||
|
||||
internal static bool HasValidToken => Token.Length == 128;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
public sealed class SteamTokenDumperConfig {
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool Enabled { get; internal set; }
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ImmutableHashSet<uint> SecretAppIDs { get; private set; } = ImmutableHashSet<uint>.Empty;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ImmutableHashSet<uint> SecretDepotIDs { get; private set; } = ImmutableHashSet<uint>.Empty;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ImmutableHashSet<uint> SecretPackageIDs { get; private set; } = ImmutableHashSet<uint>.Empty;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public bool SkipAutoGrantPackages { get; private set; }
|
||||
|
||||
[JsonConstructor]
|
||||
internal SteamTokenDumperConfig() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.Net;
|
||||
using ArchiSteamFarm.IPC.Controllers.Api;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
[Route("Api/SteamTokenDumperPlugin")]
|
||||
public sealed class SteamTokenDumperController : ArchiController {
|
||||
[HttpGet(nameof(GlobalConfigExtension))]
|
||||
[ProducesResponseType(typeof(GlobalConfigExtension), (int) HttpStatusCode.OK)]
|
||||
[SwaggerOperation(Tags = new[] { nameof(GlobalConfigExtension) })]
|
||||
public ActionResult<GlobalConfigExtension> Get() => Ok(new GlobalConfigExtension());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,570 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Composition;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.Localization;
|
||||
using ArchiSteamFarm.Plugins;
|
||||
using ArchiSteamFarm.Plugins.Interfaces;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Web;
|
||||
using ArchiSteamFarm.Web.Responses;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
|
||||
[Export(typeof(IPlugin))]
|
||||
internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotSteamClient, ISteamPICSChanges {
|
||||
[JsonProperty]
|
||||
internal static SteamTokenDumperConfig? Config { get; private set; }
|
||||
|
||||
private static readonly ConcurrentDictionary<Bot, IDisposable> BotSubscriptions = new();
|
||||
private static readonly ConcurrentDictionary<Bot, (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer)> BotSynchronizations = new();
|
||||
private static readonly SemaphoreSlim SubmissionSemaphore = new(1, 1);
|
||||
private static readonly Timer SubmissionTimer = new(SubmitData);
|
||||
|
||||
private static GlobalCache? GlobalCache;
|
||||
|
||||
[JsonProperty]
|
||||
public override string Name => nameof(SteamTokenDumperPlugin);
|
||||
|
||||
[JsonProperty]
|
||||
public override Version Version => typeof(SteamTokenDumperPlugin).Assembly.GetName().Version ?? throw new InvalidOperationException(nameof(Version));
|
||||
|
||||
public Task<uint> GetPreferredChangeNumberToStartFrom() => Task.FromResult(Config?.Enabled == true ? GlobalCache?.LastChangeNumber ?? 0 : 0);
|
||||
|
||||
public async void OnASFInit(IReadOnlyDictionary<string, JToken>? additionalConfigProperties = null) {
|
||||
if (!SharedInfo.HasValidToken) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.PluginDisabledMissingBuildToken, nameof(SteamTokenDumperPlugin)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool isEnabled = false;
|
||||
SteamTokenDumperConfig? config = null;
|
||||
|
||||
if (additionalConfigProperties != null) {
|
||||
foreach ((string configProperty, JToken configValue) in additionalConfigProperties) {
|
||||
try {
|
||||
switch (configProperty) {
|
||||
case nameof(GlobalConfigExtension.SteamTokenDumperPlugin):
|
||||
config = configValue.Value<SteamTokenDumperConfig>();
|
||||
|
||||
break;
|
||||
case nameof(GlobalConfigExtension.SteamTokenDumperPluginEnabled):
|
||||
isEnabled = configValue.Value<bool>();
|
||||
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config ??= new SteamTokenDumperConfig();
|
||||
|
||||
if (isEnabled) {
|
||||
config.Enabled = true;
|
||||
}
|
||||
|
||||
Config = config;
|
||||
|
||||
if (!config.Enabled) {
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginDisabledInConfig, nameof(SteamTokenDumperPlugin)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.SecretAppIDs.IsEmpty) {
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginSecretListInitialized, nameof(config.SecretAppIDs), string.Join(", ", config.SecretAppIDs)));
|
||||
}
|
||||
|
||||
if (!config.SecretPackageIDs.IsEmpty) {
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginSecretListInitialized, nameof(config.SecretPackageIDs), string.Join(", ", config.SecretPackageIDs)));
|
||||
}
|
||||
|
||||
if (!config.SecretDepotIDs.IsEmpty) {
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginSecretListInitialized, nameof(config.SecretDepotIDs), string.Join(", ", config.SecretDepotIDs)));
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
GlobalCache? globalCache = await GlobalCache.Load().ConfigureAwait(false);
|
||||
|
||||
if (globalCache == null) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.FileCouldNotBeLoadedFreshInit, nameof(GlobalCache)));
|
||||
|
||||
GlobalCache = new GlobalCache();
|
||||
} else {
|
||||
GlobalCache = globalCache;
|
||||
}
|
||||
}
|
||||
|
||||
TimeSpan startIn = TimeSpan.FromMinutes(Utilities.RandomNext(SharedInfo.MinimumMinutesBeforeFirstUpload, SharedInfo.MaximumMinutesBeforeFirstUpload));
|
||||
|
||||
lock (SubmissionSemaphore) {
|
||||
SubmissionTimer.Change(startIn, TimeSpan.FromHours(SharedInfo.MinimumHoursBetweenUploads));
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.PluginInitializedAndEnabled, nameof(SteamTokenDumperPlugin), startIn.ToHumanReadable()));
|
||||
}
|
||||
|
||||
public async void OnBotDestroy(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (BotSubscriptions.TryRemove(bot, out IDisposable? subscription)) {
|
||||
subscription.Dispose();
|
||||
}
|
||||
|
||||
if (BotSynchronizations.TryRemove(bot, out (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer) synchronization)) {
|
||||
synchronization.RefreshSemaphore.Dispose();
|
||||
|
||||
await synchronization.RefreshTimer.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public async void OnBotInit(Bot bot) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
SemaphoreSlim refreshSemaphore = new(1, 1);
|
||||
Timer refreshTimer = new(async _ => await Refresh(bot).ConfigureAwait(false));
|
||||
|
||||
if (!BotSynchronizations.TryAdd(bot, (refreshSemaphore, refreshTimer))) {
|
||||
refreshSemaphore.Dispose();
|
||||
|
||||
await refreshTimer.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (callbackManager == null) {
|
||||
throw new ArgumentNullException(nameof(callbackManager));
|
||||
}
|
||||
|
||||
if (BotSubscriptions.TryRemove(bot, out IDisposable? subscription)) {
|
||||
subscription.Dispose();
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
subscription = callbackManager.Subscribe<SteamApps.LicenseListCallback>(callback => OnLicenseList(bot, callback));
|
||||
|
||||
if (!BotSubscriptions.TryAdd(bot, subscription)) {
|
||||
subscription.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<ClientMsgHandler>? OnBotSteamHandlersInit(Bot bot) => null;
|
||||
|
||||
public override void OnLoaded() { }
|
||||
|
||||
public void OnPICSChanges(uint currentChangeNumber, IReadOnlyDictionary<uint, SteamApps.PICSChangesCallback.PICSChangeData> appChanges, IReadOnlyDictionary<uint, SteamApps.PICSChangesCallback.PICSChangeData> packageChanges) {
|
||||
if (currentChangeNumber == 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (appChanges == null) {
|
||||
throw new ArgumentNullException(nameof(appChanges));
|
||||
}
|
||||
|
||||
if (packageChanges == null) {
|
||||
throw new ArgumentNullException(nameof(packageChanges));
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
GlobalCache.OnPICSChanges(currentChangeNumber, appChanges);
|
||||
}
|
||||
|
||||
public void OnPICSChangesRestart(uint currentChangeNumber) {
|
||||
if (currentChangeNumber == 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(currentChangeNumber));
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
GlobalCache.OnPICSChangesRestart(currentChangeNumber);
|
||||
}
|
||||
|
||||
private static async void OnLicenseList(Bot bot, SteamApps.LicenseListCallback callback) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (callback == null) {
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
Dictionary<uint, ulong> packageTokens = callback.LicenseList.Where(license => !Config.SecretPackageIDs.Contains(license.PackageID) && ((license.PaymentMethod != EPaymentMethod.AutoGrant) || !Config.SkipAutoGrantPackages)).GroupBy(license => license.PackageID).ToDictionary(group => group.Key, group => group.OrderByDescending(license => license.TimeCreated).First().AccessToken);
|
||||
|
||||
GlobalCache.UpdatePackageTokens(packageTokens);
|
||||
|
||||
await Refresh(bot, packageTokens.Keys).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task Refresh(Bot bot, IReadOnlyCollection<uint>? packageIDs = null) {
|
||||
if (bot == null) {
|
||||
throw new ArgumentNullException(nameof(bot));
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
if (ASF.GlobalDatabase == null) {
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
if (!BotSynchronizations.TryGetValue(bot, out (SemaphoreSlim RefreshSemaphore, Timer RefreshTimer) synchronization)) {
|
||||
throw new InvalidOperationException(nameof(synchronization));
|
||||
}
|
||||
|
||||
if (!await synchronization.RefreshSemaphore.WaitAsync(0).ConfigureAwait(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!bot.IsConnectedAndLoggedOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
packageIDs ??= bot.OwnedPackageIDs.Where(package => !Config.SecretPackageIDs.Contains(package.Key) && ((package.Value.PaymentMethod != EPaymentMethod.AutoGrant) || !Config.SkipAutoGrantPackages)).Select(package => package.Key).ToHashSet();
|
||||
|
||||
HashSet<uint> appIDsToRefresh = new();
|
||||
|
||||
foreach (uint packageID in packageIDs.Where(packageID => !Config.SecretPackageIDs.Contains(packageID))) {
|
||||
if (!ASF.GlobalDatabase.PackagesDataReadOnly.TryGetValue(packageID, out (uint ChangeNumber, ImmutableHashSet<uint>? AppIDs) packageData) || (packageData.AppIDs == null)) {
|
||||
// ASF might not have the package info for us at the moment, we'll retry later
|
||||
continue;
|
||||
}
|
||||
|
||||
appIDsToRefresh.UnionWith(packageData.AppIDs.Where(appID => !Config.SecretAppIDs.Contains(appID) && GlobalCache.ShouldRefreshAppInfo(appID)));
|
||||
}
|
||||
|
||||
if (appIDsToRefresh.Count == 0) {
|
||||
bot.ArchiLogger.LogGenericDebug(Strings.BotNoAppsToRefresh);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotRetrievingTotalAppAccessTokens, appIDsToRefresh.Count));
|
||||
|
||||
HashSet<uint> appIDsThisRound = new(Math.Min(appIDsToRefresh.Count, SharedInfo.AppInfosPerSingleRequest));
|
||||
|
||||
using (HashSet<uint>.Enumerator enumerator = appIDsToRefresh.GetEnumerator()) {
|
||||
while (true) {
|
||||
while ((appIDsThisRound.Count < SharedInfo.AppInfosPerSingleRequest) && enumerator.MoveNext()) {
|
||||
appIDsThisRound.Add(enumerator.Current);
|
||||
}
|
||||
|
||||
if (appIDsThisRound.Count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bot.IsConnectedAndLoggedOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotRetrievingAppAccessTokens, appIDsThisRound.Count));
|
||||
|
||||
SteamApps.PICSTokensCallback response;
|
||||
|
||||
try {
|
||||
response = await bot.SteamApps.PICSGetAccessTokens(appIDsThisRound, Enumerable.Empty<uint>()).ToLongRunningTask().ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
bot.ArchiLogger.LogGenericWarningException(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotFinishedRetrievingAppAccessTokens, appIDsThisRound.Count));
|
||||
|
||||
appIDsThisRound.Clear();
|
||||
|
||||
GlobalCache.UpdateAppTokens(response.AppTokens, response.AppTokensDenied);
|
||||
}
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotFinishedRetrievingTotalAppAccessTokens, appIDsToRefresh.Count));
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotRetrievingTotalDepots, appIDsToRefresh.Count));
|
||||
|
||||
using (HashSet<uint>.Enumerator enumerator = appIDsToRefresh.GetEnumerator()) {
|
||||
while (true) {
|
||||
while ((appIDsThisRound.Count < SharedInfo.AppInfosPerSingleRequest) && enumerator.MoveNext()) {
|
||||
appIDsThisRound.Add(enumerator.Current);
|
||||
}
|
||||
|
||||
if (appIDsThisRound.Count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bot.IsConnectedAndLoggedOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotRetrievingAppInfos, appIDsThisRound.Count));
|
||||
|
||||
AsyncJobMultiple<SteamApps.PICSProductInfoCallback>.ResultSet response;
|
||||
|
||||
try {
|
||||
response = await bot.SteamApps.PICSGetProductInfo(appIDsThisRound.Select(appID => new SteamApps.PICSRequest { ID = appID, AccessToken = GlobalCache.GetAppToken(appID), Public = false }), Enumerable.Empty<SteamApps.PICSRequest>()).ToLongRunningTask().ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
bot.ArchiLogger.LogGenericWarningException(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.Results == null) {
|
||||
bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, ArchiSteamFarm.Localization.Strings.WarningFailedWithError, nameof(response.Results)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotFinishedRetrievingAppInfos, appIDsThisRound.Count));
|
||||
|
||||
appIDsThisRound.Clear();
|
||||
|
||||
Dictionary<uint, uint> appChangeNumbers = new();
|
||||
|
||||
HashSet<Task<SteamApps.DepotKeyCallback>> depotTasks = new();
|
||||
|
||||
foreach (SteamApps.PICSProductInfoCallback.PICSProductInfo app in response.Results.SelectMany(result => result.Apps.Values)) {
|
||||
appChangeNumbers[app.ID] = app.ChangeNumber;
|
||||
|
||||
if (GlobalCache.ShouldRefreshDepotKey(app.ID)) {
|
||||
depotTasks.Add(bot.SteamApps.GetDepotDecryptionKey(app.ID, app.ID).ToLongRunningTask());
|
||||
}
|
||||
|
||||
foreach (KeyValue depot in app.KeyValues["depots"].Children) {
|
||||
if (uint.TryParse(depot.Name, out uint depotID) && !Config.SecretDepotIDs.Contains(depotID) && GlobalCache.ShouldRefreshDepotKey(depotID)) {
|
||||
depotTasks.Add(bot.SteamApps.GetDepotDecryptionKey(depotID, app.ID).ToLongRunningTask());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GlobalCache.UpdateAppChangeNumbers(appChangeNumbers);
|
||||
|
||||
if (depotTasks.Count > 0) {
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotRetrievingDepotKeys, depotTasks.Count));
|
||||
|
||||
IList<SteamApps.DepotKeyCallback> results;
|
||||
|
||||
try {
|
||||
results = await Utilities.InParallel(depotTasks).ConfigureAwait(false);
|
||||
} catch (Exception e) {
|
||||
bot.ArchiLogger.LogGenericWarningException(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotFinishedRetrievingDepotKeys, depotTasks.Count));
|
||||
|
||||
GlobalCache.UpdateDepotKeys(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.BotFinishedRetrievingTotalDepots, appIDsToRefresh.Count));
|
||||
} finally {
|
||||
TimeSpan timeSpan = TimeSpan.FromHours(SharedInfo.MaximumHoursBetweenRefresh);
|
||||
|
||||
synchronization.RefreshTimer.Change(timeSpan, timeSpan);
|
||||
synchronization.RefreshSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private static async void SubmitData(object? state) {
|
||||
if (Bot.Bots == null) {
|
||||
throw new InvalidOperationException(nameof(Bot.Bots));
|
||||
}
|
||||
|
||||
if (Config == null) {
|
||||
throw new InvalidOperationException(nameof(Config));
|
||||
}
|
||||
|
||||
if (!Config.Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GlobalCache == null) {
|
||||
throw new InvalidOperationException(nameof(GlobalCache));
|
||||
}
|
||||
|
||||
if (ASF.GlobalConfig == null) {
|
||||
throw new InvalidOperationException(nameof(ASF.GlobalConfig));
|
||||
}
|
||||
|
||||
if (ASF.WebBrowser == null) {
|
||||
throw new InvalidOperationException(nameof(ASF.WebBrowser));
|
||||
}
|
||||
|
||||
if (!await SubmissionSemaphore.WaitAsync(0).ConfigureAwait(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Dictionary<uint, ulong> appTokens = GlobalCache.GetAppTokensForSubmission();
|
||||
Dictionary<uint, ulong> packageTokens = GlobalCache.GetPackageTokensForSubmission();
|
||||
Dictionary<uint, string> depotKeys = GlobalCache.GetDepotKeysForSubmission();
|
||||
|
||||
if ((appTokens.Count == 0) && (packageTokens.Count == 0) && (depotKeys.Count == 0)) {
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.SubmissionNoNewData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ulong contributorSteamID = (ASF.GlobalConfig.SteamOwnerID > 0) && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.Bots.Values.Where(bot => bot.SteamID > 0).OrderByDescending(bot => bot.OwnedPackageIDs.Count).FirstOrDefault()?.SteamID ?? 0;
|
||||
|
||||
if (contributorSteamID == 0) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionNoContributorSet, nameof(ASF.GlobalConfig.SteamOwnerID)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Uri request = new(SharedInfo.ServerURL + "/submit");
|
||||
RequestData requestData = new(contributorSteamID, appTokens, packageTokens, depotKeys);
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionInProgress, appTokens.Count, packageTokens.Count, depotKeys.Count));
|
||||
|
||||
ObjectResponse<ResponseData>? response = await ASF.WebBrowser.UrlPostToJsonObject<ResponseData, RequestData>(request, data: requestData, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
|
||||
|
||||
if (response == null) {
|
||||
ASF.ArchiLogger.LogGenericWarning(ArchiSteamFarm.Localization.Strings.WarningFailed);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.StatusCode.IsClientErrorCode()) {
|
||||
ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, ArchiSteamFarm.Localization.Strings.WarningFailedWithError, response.StatusCode));
|
||||
|
||||
#if NETFRAMEWORK
|
||||
if (response.StatusCode == (HttpStatusCode) 429) {
|
||||
#else
|
||||
if (response.StatusCode == HttpStatusCode.TooManyRequests) {
|
||||
#endif
|
||||
TimeSpan startIn = TimeSpan.FromMinutes(Utilities.RandomNext(SharedInfo.MinimumMinutesBeforeFirstUpload, SharedInfo.MaximumMinutesBeforeFirstUpload));
|
||||
|
||||
lock (SubmissionSemaphore) {
|
||||
SubmissionTimer.Change(startIn, TimeSpan.FromHours(SharedInfo.MinimumHoursBetweenUploads));
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionFailedTooManyRequests, startIn.ToHumanReadable()));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.Content.Success) {
|
||||
ASF.ArchiLogger.LogGenericError(ArchiSteamFarm.Localization.Strings.WarningFailed);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.Content.Data == null) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, ArchiSteamFarm.Localization.Strings.ErrorIsInvalid), nameof(response.Content.Data));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionSuccessful, response.Content.Data.NewAppsCount, response.Content.Data.NewSubsCount, response.Content.Data.NewDepotsCount));
|
||||
|
||||
GlobalCache.UpdateSubmittedData(appTokens, packageTokens, depotKeys);
|
||||
} finally {
|
||||
SubmissionSemaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Authors>JustArchi</Authors>
|
||||
<Company>JustArchi</Company>
|
||||
<Copyright>Copyright © ArchiSteamFarm 2015-2020</Copyright>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);debug/**;out/**</DefaultItemExcludes>
|
||||
<Description>ASF is an application that allows you to farm steam cards using multiple steam accounts simultaneously.</Description>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<NoWarn />
|
||||
<OutputType>Library</OutputType>
|
||||
<PackageIcon>../resources/ASF.ico</PackageIcon>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/JustArchiNET/ArchiSteamFarm</PackageProjectUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/JustArchiNET/ArchiSteamFarm.git</RepositoryUrl>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' == 'Windows_NT' OR '$(ASFNetFramework)' != ''">
|
||||
<TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' != 'Windows_NT' AND '$(ASFNetFramework)' == ''">
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugType>none</DebugType>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" Version="4.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="MSTest.TestAdapter" />
|
||||
<PackageReference Include="MSTest.TestFramework" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,6 +19,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
|
||||
|
||||
514
ArchiSteamFarm.Tests/Bot.cs
Normal file
514
ArchiSteamFarm.Tests/Bot.cs
Normal file
@@ -0,0 +1,514 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Ł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.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace ArchiSteamFarm.Tests {
|
||||
[TestClass]
|
||||
public sealed class Bot {
|
||||
[TestMethod]
|
||||
public void MaxItemsBarelyEnoughForOneSet() {
|
||||
const uint relevantAppID = 42;
|
||||
|
||||
Dictionary<uint, byte> itemsPerSet = new() {
|
||||
{ relevantAppID, Steam.Bot.MinCardsPerBadge },
|
||||
{ 43, Steam.Bot.MinCardsPerBadge + 1 }
|
||||
};
|
||||
|
||||
HashSet<Asset> items = new();
|
||||
|
||||
foreach ((uint appID, byte cards) in itemsPerSet) {
|
||||
for (byte i = 1; i <= cards; i++) {
|
||||
items.Add(CreateCard(i, appID));
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, itemsPerSet, Steam.Bot.MinCardsPerBadge);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = items.Where(item => item.RealAppID == relevantAppID)
|
||||
.GroupBy(item => (item.RealAppID, item.ContextID, item.ClassID))
|
||||
.ToDictionary(grouping => grouping.Key, grouping => (uint) grouping.Sum(item => item.Amount));
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||
public void MaxItemsTooSmall() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID),
|
||||
CreateCard(2, appID)
|
||||
};
|
||||
|
||||
GetItemsForFullBadge(items, 2, appID, Steam.Bot.MinCardsPerBadge - 1);
|
||||
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MoreCardsThanNeeded() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID),
|
||||
CreateCard(1, appID),
|
||||
CreateCard(2, appID),
|
||||
CreateCard(3, appID)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 3, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 3), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MultipleSets() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID),
|
||||
CreateCard(1, appID),
|
||||
CreateCard(2, appID),
|
||||
CreateCard(2, appID)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 2 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 2 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MultipleSetsDifferentAmount() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, 2),
|
||||
CreateCard(2, appID),
|
||||
CreateCard(2, appID)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 2 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 2 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MutliRarityAndType() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, type: Asset.EType.TradingCard, rarity: Asset.ERarity.Common),
|
||||
CreateCard(2, appID, type: Asset.EType.TradingCard, rarity: Asset.ERarity.Common),
|
||||
|
||||
CreateCard(1, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Uncommon),
|
||||
CreateCard(2, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Uncommon),
|
||||
|
||||
CreateCard(1, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Rare),
|
||||
CreateCard(2, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Rare),
|
||||
|
||||
// for better readability and easier verification when thinking about this test the items that shall be selected for sending are the ones below this comment
|
||||
CreateCard(1, appID, type: Asset.EType.TradingCard, rarity: Asset.ERarity.Uncommon),
|
||||
CreateCard(2, appID, type: Asset.EType.TradingCard, rarity: Asset.ERarity.Uncommon),
|
||||
CreateCard(3, appID, type: Asset.EType.TradingCard, rarity: Asset.ERarity.Uncommon),
|
||||
|
||||
CreateCard(1, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Common),
|
||||
CreateCard(3, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Common),
|
||||
CreateCard(7, appID, type: Asset.EType.FoilTradingCard, rarity: Asset.ERarity.Common),
|
||||
|
||||
CreateCard(2, appID, type: Asset.EType.Unknown, rarity: Asset.ERarity.Rare),
|
||||
CreateCard(3, appID, type: Asset.EType.Unknown, rarity: Asset.ERarity.Rare),
|
||||
CreateCard(4, appID, type: Asset.EType.Unknown, rarity: Asset.ERarity.Rare)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 3, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 2 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 2 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 3), 3 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 4), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 7), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NotAllCardsPresent() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID),
|
||||
CreateCard(2, appID)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 3, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new(0);
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OneSet() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID),
|
||||
CreateCard(2, appID)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherAppIDFullSets() {
|
||||
const uint appID0 = 42;
|
||||
const uint appID1 = 43;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID0),
|
||||
CreateCard(1, appID1)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(
|
||||
items, new Dictionary<uint, byte> {
|
||||
{ appID0, 1 },
|
||||
{ appID1, 1 }
|
||||
}
|
||||
);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID0, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID1, Asset.SteamCommunityContextID, 1), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherAppIDNoSets() {
|
||||
const uint appID0 = 42;
|
||||
const uint appID1 = 43;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID0),
|
||||
CreateCard(1, appID1)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(
|
||||
items, new Dictionary<uint, byte> {
|
||||
{ appID0, 2 },
|
||||
{ appID1, 2 }
|
||||
}
|
||||
);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new(0);
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherAppIDOneSet() {
|
||||
const uint appID0 = 42;
|
||||
const uint appID1 = 43;
|
||||
const uint appID2 = 44;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID0),
|
||||
CreateCard(2, appID0),
|
||||
|
||||
CreateCard(1, appID1),
|
||||
CreateCard(2, appID1),
|
||||
CreateCard(3, appID1)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(
|
||||
items, new Dictionary<uint, byte> {
|
||||
{ appID0, 3 },
|
||||
{ appID1, 3 },
|
||||
{ appID2, 3 }
|
||||
}
|
||||
);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID1, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID1, Asset.SteamCommunityContextID, 2), 1 },
|
||||
{ (appID1, Asset.SteamCommunityContextID, 3), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherRarityFullSets() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, rarity: Asset.ERarity.Common),
|
||||
CreateCard(1, appID, rarity: Asset.ERarity.Rare)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 1, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 2 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherRarityNoSets() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, rarity: Asset.ERarity.Common),
|
||||
CreateCard(1, appID, rarity: Asset.ERarity.Rare)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new(0);
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherRarityOneSet() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, rarity: Asset.ERarity.Common),
|
||||
CreateCard(2, appID, rarity: Asset.ERarity.Common),
|
||||
CreateCard(1, appID, rarity: Asset.ERarity.Uncommon),
|
||||
CreateCard(2, appID, rarity: Asset.ERarity.Uncommon),
|
||||
CreateCard(3, appID, rarity: Asset.ERarity.Uncommon)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 3, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 3), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherTypeFullSets() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, type: Asset.EType.TradingCard),
|
||||
CreateCard(1, appID, type: Asset.EType.FoilTradingCard)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 1, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 2 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherTypeNoSets() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, type: Asset.EType.TradingCard),
|
||||
CreateCard(1, appID, type: Asset.EType.FoilTradingCard)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new(0);
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherTypeOneSet() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID, type: Asset.EType.TradingCard),
|
||||
CreateCard(2, appID, type: Asset.EType.TradingCard),
|
||||
CreateCard(1, appID, type: Asset.EType.FoilTradingCard),
|
||||
CreateCard(2, appID, type: Asset.EType.FoilTradingCard),
|
||||
CreateCard(3, appID, type: Asset.EType.FoilTradingCard)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 3, appID);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 2), 1 },
|
||||
{ (appID, Asset.SteamCommunityContextID, 3), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TooHighAmount() {
|
||||
const uint appID0 = 42;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID0, 2),
|
||||
CreateCard(2, appID0)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID0);
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = new() {
|
||||
{ (appID0, Asset.SteamCommunityContextID, 1), 1 },
|
||||
{ (appID0, Asset.SteamCommunityContextID, 2), 1 }
|
||||
};
|
||||
|
||||
AssertResultMatchesExpectation(expectedResult, itemsToSend);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TooManyCardsForSingleTrade() {
|
||||
const uint appID = 42;
|
||||
|
||||
HashSet<Asset> items = new();
|
||||
|
||||
for (byte i = 0; i < Steam.Exchange.Trading.MaxItemsPerTrade; i++) {
|
||||
items.Add(CreateCard(1, appID));
|
||||
items.Add(CreateCard(2, appID));
|
||||
}
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, 2, appID);
|
||||
|
||||
Assert.IsTrue(itemsToSend.Count <= Steam.Exchange.Trading.MaxItemsPerTrade);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TooManyCardsForSingleTradeMultipleAppIDs() {
|
||||
const uint appID0 = 42;
|
||||
const uint appID1 = 43;
|
||||
|
||||
HashSet<Asset> items = new();
|
||||
|
||||
for (byte i = 0; i < 100; i++) {
|
||||
items.Add(CreateCard(1, appID0));
|
||||
items.Add(CreateCard(2, appID0));
|
||||
items.Add(CreateCard(1, appID1));
|
||||
items.Add(CreateCard(2, appID1));
|
||||
}
|
||||
|
||||
Dictionary<uint, byte> itemsPerSet = new() {
|
||||
{ appID0, 2 },
|
||||
{ appID1, 2 }
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToSend = GetItemsForFullBadge(items, itemsPerSet);
|
||||
|
||||
Assert.IsTrue(itemsToSend.Count <= Steam.Exchange.Trading.MaxItemsPerTrade);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public void TooManyCardsPerSet() {
|
||||
const uint appID0 = 42;
|
||||
const uint appID1 = 43;
|
||||
const uint appID2 = 44;
|
||||
|
||||
HashSet<Asset> items = new() {
|
||||
CreateCard(1, appID0),
|
||||
CreateCard(2, appID0),
|
||||
CreateCard(3, appID0),
|
||||
CreateCard(4, appID0)
|
||||
};
|
||||
|
||||
GetItemsForFullBadge(
|
||||
items, new Dictionary<uint, byte> {
|
||||
{ appID0, 3 },
|
||||
{ appID1, 3 },
|
||||
{ appID2, 3 }
|
||||
}
|
||||
);
|
||||
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
private static void AssertResultMatchesExpectation(IReadOnlyDictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult, IReadOnlyCollection<Asset> itemsToSend) {
|
||||
if (expectedResult == null) {
|
||||
throw new ArgumentNullException(nameof(expectedResult));
|
||||
}
|
||||
|
||||
if (itemsToSend == null) {
|
||||
throw new ArgumentNullException(nameof(itemsToSend));
|
||||
}
|
||||
|
||||
Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), long> realResult = itemsToSend.GroupBy(asset => (asset.RealAppID, asset.ContextID, asset.ClassID)).ToDictionary(group => group.Key, group => group.Sum(asset => asset.Amount));
|
||||
Assert.AreEqual(expectedResult.Count, realResult.Count);
|
||||
Assert.IsTrue(expectedResult.All(expectation => realResult.TryGetValue(expectation.Key, out long reality) && (expectation.Value == reality)));
|
||||
}
|
||||
|
||||
private static Asset CreateCard(ulong classID, uint realAppID, uint amount = 1, Asset.EType type = Asset.EType.TradingCard, Asset.ERarity rarity = Asset.ERarity.Common) => new(Asset.SteamAppID, Asset.SteamCommunityContextID, classID, amount, realAppID: realAppID, type: type, rarity: rarity);
|
||||
|
||||
private static HashSet<Asset> GetItemsForFullBadge(IReadOnlyCollection<Asset> inventory, byte cardsPerSet, uint appID, ushort maxItems = Steam.Exchange.Trading.MaxItemsPerTrade) => GetItemsForFullBadge(inventory, new Dictionary<uint, byte> { { appID, cardsPerSet } }, maxItems);
|
||||
|
||||
private static HashSet<Asset> GetItemsForFullBadge(IReadOnlyCollection<Asset> inventory, IDictionary<uint, byte> cardsPerSet, ushort maxItems = Steam.Exchange.Trading.MaxItemsPerTrade) {
|
||||
Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), List<uint>> inventorySets = Steam.Exchange.Trading.GetInventorySets(inventory);
|
||||
|
||||
return Steam.Bot.GetItemsForFullSets(inventory, inventorySets.ToDictionary(kv => kv.Key, kv => (SetsToExtract: inventorySets[kv.Key][0], cardsPerSet[kv.Key.RealAppID])), maxItems).ToHashSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -20,54 +20,53 @@
|
||||
// limitations under the License.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using ArchiSteamFarm.Json;
|
||||
using JetBrains.Annotations;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using static ArchiSteamFarm.Trading;
|
||||
using static ArchiSteamFarm.Steam.Exchange.Trading;
|
||||
|
||||
namespace ArchiSteamFarm.Tests {
|
||||
[TestClass]
|
||||
public sealed class Trading {
|
||||
[TestMethod]
|
||||
public void MismatchRarityIsNotFair() {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1, rarity: Steam.Asset.ERarity.Rare) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(1, rarity: Asset.ERarity.Rare) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(2) };
|
||||
|
||||
Assert.IsFalse(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MismatchRealAppIDsIsNotFair() {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1, realAppID: 570) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(1, realAppID: 570) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(2) };
|
||||
|
||||
Assert.IsFalse(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MismatchTypesIsNotFair() {
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1, type: Steam.Asset.EType.Emoticon) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(1, type: Asset.EType.Emoticon) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(2) };
|
||||
|
||||
Assert.IsFalse(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MultiGameMultiTypeBadReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 9),
|
||||
CreateItem(3, 9, 730, Steam.Asset.EType.Emoticon),
|
||||
CreateItem(4, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, 9, 730, Asset.EType.Emoticon),
|
||||
CreateItem(4, realAppID: 730, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(4, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(4, realAppID: 730, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(3, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, realAppID: 730, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
@@ -76,19 +75,19 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void MultiGameMultiTypeNeutralAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 9),
|
||||
CreateItem(3, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, realAppID: 730, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(3, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, realAppID: 730, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(4, realAppID: 730, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(4, realAppID: 730, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
@@ -97,18 +96,18 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void MultiGameSingleTypeBadReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 9),
|
||||
CreateItem(3, realAppID: 730),
|
||||
CreateItem(4, realAppID: 730)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(3, realAppID: 730)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(4, realAppID: 730)
|
||||
};
|
||||
@@ -119,17 +118,17 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void MultiGameSingleTypeNeutralAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 2),
|
||||
CreateItem(3, realAppID: 730)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(3, realAppID: 730)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(4, realAppID: 730)
|
||||
};
|
||||
@@ -138,19 +137,41 @@ namespace ArchiSteamFarm.Tests {
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameAbrynosWasWrongNeutralAccept() {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2, 2),
|
||||
CreateItem(3),
|
||||
CreateItem(4),
|
||||
CreateItem(5)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(2)
|
||||
};
|
||||
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(3)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameDonationAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(3, type: Steam.Asset.EType.SteamGems)
|
||||
CreateItem(3, type: Asset.EType.SteamGems)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
@@ -159,20 +180,20 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameMultiTypeBadReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 9),
|
||||
CreateItem(3, 9, type: Steam.Asset.EType.Emoticon),
|
||||
CreateItem(4, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, 9, type: Asset.EType.Emoticon),
|
||||
CreateItem(4, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(4, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(4, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(3, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
@@ -181,19 +202,19 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameMultiTypeNeutralAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 9),
|
||||
CreateItem(3, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(3, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(3, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(4, type: Steam.Asset.EType.Emoticon)
|
||||
CreateItem(4, type: Asset.EType.Emoticon)
|
||||
};
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
@@ -202,19 +223,19 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameQuantityBadReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2),
|
||||
CreateItem(3)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2),
|
||||
CreateItem(3)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(4, 3) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(4, 3) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -222,17 +243,17 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameQuantityBadReject2() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2, 2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2, 2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(3, 3) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(3, 3) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -240,17 +261,17 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameQuantityNeutralAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 2),
|
||||
CreateItem(2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(3, 2) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(3, 2) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -258,13 +279,13 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeBadReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(1) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(2) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsFalse(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -272,15 +293,15 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeBadWithOverpayingReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 2),
|
||||
CreateItem(2, 2),
|
||||
CreateItem(3, 2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(2) };
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(3)
|
||||
};
|
||||
@@ -291,14 +312,14 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeBigDifferenceAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2, 5),
|
||||
CreateItem(3)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(3) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(2) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(3) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -306,7 +327,7 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeBigDifferenceReject() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(2, 2),
|
||||
CreateItem(3, 2),
|
||||
@@ -314,12 +335,12 @@ namespace ArchiSteamFarm.Tests {
|
||||
CreateItem(5, 10)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToGive = new() {
|
||||
CreateItem(2),
|
||||
CreateItem(5)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(3),
|
||||
CreateItem(4)
|
||||
};
|
||||
@@ -330,9 +351,9 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeGoodAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> { CreateItem(1, 2) };
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> inventory = new() { CreateItem(1, 2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(1) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(2) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -340,9 +361,9 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeNeutralAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(1) };
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> inventory = new() { CreateItem(1) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(1) };
|
||||
HashSet<Asset> itemsToReceive = new() { CreateItem(2) };
|
||||
|
||||
Assert.IsTrue(IsFairExchange(itemsToGive, itemsToReceive));
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
@@ -350,14 +371,14 @@ namespace ArchiSteamFarm.Tests {
|
||||
|
||||
[TestMethod]
|
||||
public void SingleGameSingleTypeNeutralWithOverpayingAccept() {
|
||||
HashSet<Steam.Asset> inventory = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> inventory = new() {
|
||||
CreateItem(1, 2),
|
||||
CreateItem(2, 2)
|
||||
};
|
||||
|
||||
HashSet<Steam.Asset> itemsToGive = new HashSet<Steam.Asset> { CreateItem(2) };
|
||||
HashSet<Asset> itemsToGive = new() { CreateItem(2) };
|
||||
|
||||
HashSet<Steam.Asset> itemsToReceive = new HashSet<Steam.Asset> {
|
||||
HashSet<Asset> itemsToReceive = new() {
|
||||
CreateItem(1),
|
||||
CreateItem(3)
|
||||
};
|
||||
@@ -366,7 +387,6 @@ namespace ArchiSteamFarm.Tests {
|
||||
Assert.IsTrue(IsTradeNeutralOrBetter(inventory, itemsToGive, itemsToReceive));
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static Steam.Asset CreateItem(ulong classID, uint amount = 1, uint realAppID = Steam.Asset.SteamAppID, Steam.Asset.EType type = Steam.Asset.EType.TradingCard, Steam.Asset.ERarity rarity = Steam.Asset.ERarity.Common) => new Steam.Asset(Steam.Asset.SteamAppID, Steam.Asset.SteamCommunityContextID, classID, amount, realAppID: realAppID, type: type, rarity: rarity);
|
||||
private static Asset CreateItem(ulong classID, uint amount = 1, uint realAppID = Asset.SteamAppID, Asset.EType type = Asset.EType.TradingCard, Asset.ERarity rarity = Asset.ERarity.Common) => new(Asset.SteamAppID, Asset.SteamCommunityContextID, classID, amount, realAppID: realAppID, type: type, rarity: rarity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26621.2
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30114.105
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm", "ArchiSteamFarm\ArchiSteamFarm.csproj", "{CF84911C-2C4C-4195-8AF3-ABBB6D3DE9AA}"
|
||||
EndProject
|
||||
@@ -9,6 +9,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm.Tests", "Arc
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm.CustomPlugins.ExamplePlugin", "ArchiSteamFarm.CustomPlugins.ExamplePlugin\ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj", "{2E2C26B6-7C1D-4BAF-BCF9-79286DA08F82}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm.CustomPlugins.PeriodicGC", "ArchiSteamFarm.CustomPlugins.PeriodicGC\ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj", "{2C935C25-1B03-4C55-81C9-DF1D472D72F4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper", "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper\ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj", "{A9299EE5-AF67-4FCB-8D03-263B41819504}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -27,6 +31,14 @@ Global
|
||||
{2E2C26B6-7C1D-4BAF-BCF9-79286DA08F82}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2E2C26B6-7C1D-4BAF-BCF9-79286DA08F82}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2E2C26B6-7C1D-4BAF-BCF9-79286DA08F82}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C935C25-1B03-4C55-81C9-DF1D472D72F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C935C25-1B03-4C55-81C9-DF1D472D72F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C935C25-1B03-4C55-81C9-DF1D472D72F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C935C25-1B03-4C55-81C9-DF1D472D72F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A9299EE5-AF67-4FCB-8D03-263B41819504}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A9299EE5-AF67-4FCB-8D03-263B41819504}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A9299EE5-AF67-4FCB-8D03-263B41819504}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A9299EE5-AF67-4FCB-8D03-263B41819504}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 279 KiB |
@@ -1,455 +0,0 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Ł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.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Collections;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.Json;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
public sealed class Actions : IDisposable {
|
||||
private static readonly SemaphoreSlim GiftCardsSemaphore = new SemaphoreSlim(1, 1);
|
||||
private static readonly SemaphoreSlim GiftsSemaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
private readonly Bot Bot;
|
||||
private readonly ConcurrentHashSet<ulong> HandledGifts = new ConcurrentHashSet<ulong>();
|
||||
private readonly SemaphoreSlim TradingSemaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
private Timer CardsFarmerResumeTimer;
|
||||
private bool ProcessingGiftsScheduled;
|
||||
private bool TradingScheduled;
|
||||
|
||||
internal Actions([JetBrains.Annotations.NotNull] Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
|
||||
|
||||
public void Dispose() {
|
||||
// Those are objects that are always being created if constructor doesn't throw exception
|
||||
TradingSemaphore.Dispose();
|
||||
|
||||
// Those are objects that might be null and the check should be in-place
|
||||
CardsFarmerResumeTimer?.Dispose();
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public static (bool Success, string Message) Exit() {
|
||||
// Schedule the task after some time so user can receive response
|
||||
Utilities.InBackground(
|
||||
async () => {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
await Program.Exit().ConfigureAwait(false);
|
||||
}
|
||||
);
|
||||
|
||||
return (true, Strings.Done);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, string Token, string Message)> GenerateTwoFactorAuthenticationToken() {
|
||||
if (!Bot.HasMobileAuthenticator) {
|
||||
return (false, null, Strings.BotNoASFAuthenticator);
|
||||
}
|
||||
|
||||
string token = await Bot.BotDatabase.MobileAuthenticator.GenerateToken().ConfigureAwait(false);
|
||||
|
||||
return (true, token, Strings.Success);
|
||||
}
|
||||
|
||||
[ItemNotNull]
|
||||
[PublicAPI]
|
||||
public async Task<IDisposable> GetTradingLock() {
|
||||
await TradingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
return new SemaphoreLock(TradingSemaphore);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, string Message)> HandleTwoFactorAuthenticationConfirmations(bool accept, Steam.ConfirmationDetails.EType? acceptedType = null, IReadOnlyCollection<ulong> acceptedTradeOfferIDs = null, bool waitIfNeeded = false) {
|
||||
if (!Bot.HasMobileAuthenticator) {
|
||||
return (false, Strings.BotNoASFAuthenticator);
|
||||
}
|
||||
|
||||
if (!Bot.IsConnectedAndLoggedOn) {
|
||||
return (false, Strings.BotNotConnected);
|
||||
}
|
||||
|
||||
HashSet<ulong> handledTradeOfferIDs = null;
|
||||
|
||||
for (byte i = 0; (i == 0) || ((i < WebBrowser.MaxTries) && waitIfNeeded); i++) {
|
||||
if (i > 0) {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
HashSet<MobileAuthenticator.Confirmation> confirmations = await Bot.BotDatabase.MobileAuthenticator.GetConfirmations(acceptedType).ConfigureAwait(false);
|
||||
|
||||
if ((confirmations == null) || (confirmations.Count == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we can skip asking for details, we can handle confirmations right away
|
||||
if ((acceptedTradeOfferIDs == null) || (acceptedTradeOfferIDs.Count == 0)) {
|
||||
bool result = await Bot.BotDatabase.MobileAuthenticator.HandleConfirmations(confirmations, accept).ConfigureAwait(false);
|
||||
|
||||
return (result, result ? string.Format(Strings.BotHandledConfirmations, confirmations.Count) : Strings.WarningFailed);
|
||||
}
|
||||
|
||||
IList<Steam.ConfirmationDetails> results = await Utilities.InParallel(confirmations.Select(Bot.BotDatabase.MobileAuthenticator.GetConfirmationDetails)).ConfigureAwait(false);
|
||||
|
||||
foreach (MobileAuthenticator.Confirmation confirmation in results.Where(details => (details != null) && ((acceptedType.HasValue && (acceptedType.Value != details.Type)) || ((details.TradeOfferID != 0) && !acceptedTradeOfferIDs.Contains(details.TradeOfferID)))).Select(details => details.Confirmation)) {
|
||||
confirmations.Remove(confirmation);
|
||||
}
|
||||
|
||||
if (confirmations.Count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!await Bot.BotDatabase.MobileAuthenticator.HandleConfirmations(confirmations, accept).ConfigureAwait(false)) {
|
||||
return (false, Strings.WarningFailed);
|
||||
}
|
||||
|
||||
IEnumerable<ulong> handledTradeOfferIDsThisRound = results.Where(details => (details != null) && (details.TradeOfferID != 0)).Select(result => result.TradeOfferID);
|
||||
|
||||
if (handledTradeOfferIDs != null) {
|
||||
handledTradeOfferIDs.UnionWith(handledTradeOfferIDsThisRound);
|
||||
} else {
|
||||
handledTradeOfferIDs = handledTradeOfferIDsThisRound.ToHashSet();
|
||||
}
|
||||
|
||||
// Check if those are all that we were expected to confirm
|
||||
if (acceptedTradeOfferIDs.All(handledTradeOfferIDs.Contains)) {
|
||||
return (true, string.Format(Strings.BotHandledConfirmations, acceptedTradeOfferIDs.Count));
|
||||
}
|
||||
}
|
||||
|
||||
return (!waitIfNeeded, !waitIfNeeded ? Strings.Success : string.Format(Strings.ErrorRequestFailedTooManyTimes, WebBrowser.MaxTries));
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, string Message)> Pause(bool permanent, ushort resumeInSeconds = 0) {
|
||||
if (Bot.CardsFarmer.Paused) {
|
||||
return (false, Strings.BotAutomaticIdlingPausedAlready);
|
||||
}
|
||||
|
||||
await Bot.CardsFarmer.Pause(permanent).ConfigureAwait(false);
|
||||
|
||||
if (!permanent && (Bot.BotConfig.GamesPlayedWhileIdle.Count > 0)) {
|
||||
// We want to let family sharing users access our library, and in this case we must also stop GamesPlayedWhileIdle
|
||||
// We add extra delay because OnFarmingStopped() also executes PlayGames()
|
||||
// Despite of proper order on our end, Steam network might not respect it
|
||||
await Task.Delay(Bot.CallbackSleep).ConfigureAwait(false);
|
||||
await Bot.ArchiHandler.PlayGames(Enumerable.Empty<uint>(), Bot.BotConfig.CustomGamePlayedWhileIdle).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (resumeInSeconds > 0) {
|
||||
if (CardsFarmerResumeTimer == null) {
|
||||
CardsFarmerResumeTimer = new Timer(
|
||||
e => Resume(),
|
||||
null,
|
||||
TimeSpan.FromSeconds(resumeInSeconds), // Delay
|
||||
Timeout.InfiniteTimeSpan // Period
|
||||
);
|
||||
} else {
|
||||
CardsFarmerResumeTimer.Change(TimeSpan.FromSeconds(resumeInSeconds), Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
}
|
||||
|
||||
return (true, Strings.BotAutomaticIdlingNowPaused);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<(bool Success, string Message)> Play(IEnumerable<uint> gameIDs, string gameName = null) {
|
||||
if (gameIDs == null) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(gameIDs));
|
||||
|
||||
return (false, string.Format(Strings.ErrorObjectIsNull, nameof(gameIDs)));
|
||||
}
|
||||
|
||||
if (!Bot.IsConnectedAndLoggedOn) {
|
||||
return (false, Strings.BotNotConnected);
|
||||
}
|
||||
|
||||
if (!Bot.CardsFarmer.Paused) {
|
||||
await Bot.CardsFarmer.Pause(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await Bot.ArchiHandler.PlayGames(gameIDs, gameName).ConfigureAwait(false);
|
||||
|
||||
return (true, Strings.Done);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public async Task<ArchiHandler.PurchaseResponseCallback> RedeemKey(string key) {
|
||||
await LimitGiftsRequestsAsync().ConfigureAwait(false);
|
||||
|
||||
return await Bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public static (bool Success, string Message) Restart() {
|
||||
// Schedule the task after some time so user can receive response
|
||||
Utilities.InBackground(
|
||||
async () => {
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
await Program.Restart().ConfigureAwait(false);
|
||||
}
|
||||
);
|
||||
|
||||
return (true, Strings.Done);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public (bool Success, string Message) Resume() {
|
||||
if (!Bot.CardsFarmer.Paused) {
|
||||
return (false, Strings.BotAutomaticIdlingResumedAlready);
|
||||
}
|
||||
|
||||
Utilities.InBackground(() => Bot.CardsFarmer.Resume(true));
|
||||
|
||||
return (true, Strings.BotAutomaticIdlingNowResumed);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
|
||||
public async Task<(bool Success, string Message)> SendInventory(uint appID = Steam.Asset.SteamAppID, ulong contextID = Steam.Asset.SteamCommunityContextID, ulong targetSteamID = 0, string tradeToken = null, Func<Steam.Asset, bool> filterFunction = null) {
|
||||
if ((appID == 0) || (contextID == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(appID) + " || " + nameof(contextID));
|
||||
|
||||
return (false, string.Format(Strings.ErrorObjectIsNull, nameof(appID) + " || " + nameof(contextID)));
|
||||
}
|
||||
|
||||
if (!Bot.IsConnectedAndLoggedOn) {
|
||||
return (false, Strings.BotNotConnected);
|
||||
}
|
||||
|
||||
if (targetSteamID == 0) {
|
||||
targetSteamID = GetFirstSteamMasterID();
|
||||
|
||||
if (targetSteamID == 0) {
|
||||
return (false, Strings.BotLootingMasterNotDefined);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tradeToken) && !string.IsNullOrEmpty(Bot.BotConfig.SteamTradeToken)) {
|
||||
tradeToken = Bot.BotConfig.SteamTradeToken;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetSteamID == Bot.SteamID) {
|
||||
return (false, Strings.BotSendingTradeToYourself);
|
||||
}
|
||||
|
||||
lock (TradingSemaphore) {
|
||||
if (TradingScheduled) {
|
||||
return (false, Strings.ErrorAborted);
|
||||
}
|
||||
|
||||
TradingScheduled = true;
|
||||
}
|
||||
|
||||
filterFunction ??= item => true;
|
||||
await TradingSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
lock (TradingSemaphore) {
|
||||
TradingScheduled = false;
|
||||
}
|
||||
|
||||
HashSet<Steam.Asset> inventory;
|
||||
|
||||
try {
|
||||
inventory = await Bot.ArchiWebHandler.GetInventoryAsync(Bot.SteamID, appID, contextID).Where(item => item.Tradable && filterFunction(item)).ToHashSetAsync().ConfigureAwait(false);
|
||||
} catch (HttpRequestException e) {
|
||||
return (false, string.Format(Strings.WarningFailedWithError, e.Message));
|
||||
} catch (Exception e) {
|
||||
Bot.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return (false, string.Format(Strings.WarningFailedWithError, e.Message));
|
||||
}
|
||||
|
||||
if (inventory.Count == 0) {
|
||||
return (false, string.Format(Strings.ErrorIsEmpty, nameof(inventory)));
|
||||
}
|
||||
|
||||
if (!await Bot.ArchiWebHandler.MarkSentTrades().ConfigureAwait(false)) {
|
||||
return (false, Strings.BotLootingFailed);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(tradeToken) && (Bot.SteamFriends.GetFriendRelationship(targetSteamID) != EFriendRelationship.Friend)) {
|
||||
Bot targetBot = Bot.Bots.Values.FirstOrDefault(bot => bot.SteamID == targetSteamID);
|
||||
|
||||
if (targetBot?.IsConnectedAndLoggedOn == true) {
|
||||
tradeToken = await targetBot.ArchiHandler.GetTradeToken().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(targetSteamID, inventory, token: tradeToken).ConfigureAwait(false);
|
||||
|
||||
if ((mobileTradeOfferIDs != null) && (mobileTradeOfferIDs.Count > 0) && Bot.HasMobileAuthenticator) {
|
||||
(bool twoFactorSuccess, _) = await HandleTwoFactorAuthenticationConfirmations(true, Steam.ConfirmationDetails.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false);
|
||||
|
||||
if (!twoFactorSuccess) {
|
||||
return (false, Strings.BotLootingFailed);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
return (false, Strings.BotLootingFailed);
|
||||
}
|
||||
} finally {
|
||||
TradingSemaphore.Release();
|
||||
}
|
||||
|
||||
return (true, Strings.BotLootingSuccess);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public (bool Success, string Message) Start() {
|
||||
if (Bot.KeepRunning) {
|
||||
return (false, Strings.BotAlreadyRunning);
|
||||
}
|
||||
|
||||
Utilities.InBackground(Bot.Start);
|
||||
|
||||
return (true, Strings.Done);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public (bool Success, string Message) Stop() {
|
||||
if (!Bot.KeepRunning) {
|
||||
return (false, Strings.BotAlreadyStopped);
|
||||
}
|
||||
|
||||
Bot.Stop();
|
||||
|
||||
return (true, Strings.Done);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public static async Task<(bool Success, string Message, Version Version)> Update() {
|
||||
Version version = await ASF.Update(true).ConfigureAwait(false);
|
||||
|
||||
if (version == null) {
|
||||
return (false, null, null);
|
||||
}
|
||||
|
||||
if (SharedInfo.Version >= version) {
|
||||
return (false, "V" + SharedInfo.Version + " ≥ V" + version, version);
|
||||
}
|
||||
|
||||
Utilities.InBackground(ASF.RestartOrExit);
|
||||
|
||||
return (true, null, version);
|
||||
}
|
||||
|
||||
internal async Task AcceptDigitalGiftCards() {
|
||||
lock (GiftCardsSemaphore) {
|
||||
if (ProcessingGiftsScheduled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessingGiftsScheduled = true;
|
||||
}
|
||||
|
||||
await GiftCardsSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
lock (GiftCardsSemaphore) {
|
||||
ProcessingGiftsScheduled = false;
|
||||
}
|
||||
|
||||
HashSet<ulong> giftCardIDs = await Bot.ArchiWebHandler.GetDigitalGiftCards().ConfigureAwait(false);
|
||||
|
||||
if ((giftCardIDs == null) || (giftCardIDs.Count == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ulong giftCardID in giftCardIDs.Where(gid => !HandledGifts.Contains(gid))) {
|
||||
HandledGifts.Add(giftCardID);
|
||||
|
||||
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.BotAcceptingGift, giftCardID));
|
||||
await LimitGiftsRequestsAsync().ConfigureAwait(false);
|
||||
|
||||
bool result = await Bot.ArchiWebHandler.AcceptDigitalGiftCard(giftCardID).ConfigureAwait(false);
|
||||
|
||||
if (result) {
|
||||
Bot.ArchiLogger.LogGenericInfo(Strings.Success);
|
||||
} else {
|
||||
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
GiftCardsSemaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task AcceptGuestPasses(IReadOnlyCollection<ulong> guestPassIDs) {
|
||||
if ((guestPassIDs == null) || (guestPassIDs.Count == 0)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(guestPassIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ulong guestPassID in guestPassIDs.Where(guestPassID => !HandledGifts.Contains(guestPassID))) {
|
||||
HandledGifts.Add(guestPassID);
|
||||
|
||||
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.BotAcceptingGift, guestPassID));
|
||||
await LimitGiftsRequestsAsync().ConfigureAwait(false);
|
||||
|
||||
ArchiHandler.RedeemGuestPassResponseCallback response = await Bot.ArchiHandler.RedeemGuestPass(guestPassID).ConfigureAwait(false);
|
||||
|
||||
if (response != null) {
|
||||
if (response.Result == EResult.OK) {
|
||||
Bot.ArchiLogger.LogGenericInfo(Strings.Success);
|
||||
} else {
|
||||
Bot.ArchiLogger.LogGenericWarning(string.Format(Strings.WarningFailedWithError, response.Result));
|
||||
}
|
||||
} else {
|
||||
Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnDisconnected() => HandledGifts.Clear();
|
||||
|
||||
private ulong GetFirstSteamMasterID() => Bot.BotConfig.SteamUserPermissions.Where(kv => (kv.Key != 0) && (kv.Value == BotConfig.EPermission.Master)).Select(kv => kv.Key).OrderByDescending(steamID => steamID != Bot.SteamID).ThenBy(steamID => steamID).FirstOrDefault();
|
||||
|
||||
private static async Task LimitGiftsRequestsAsync() {
|
||||
if (ASF.GlobalConfig.GiftsLimiterDelay == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await GiftsSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
Utilities.InBackground(
|
||||
async () => {
|
||||
await Task.Delay(ASF.GlobalConfig.GiftsLimiterDelay * 1000).ConfigureAwait(false);
|
||||
GiftsSemaphore.Release();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Ł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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using CryptSharp.Utility;
|
||||
using JetBrains.Annotations;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
public static class ArchiCryptoHelper {
|
||||
private const ushort SteamParentalPbkdf2Iterations = 10000;
|
||||
private const byte SteamParentalSCryptBlocksCount = 8;
|
||||
private const ushort SteamParentalSCryptIterations = 8192;
|
||||
|
||||
[NotNull]
|
||||
private static IEnumerable<byte> SteamParentalCharacters => Enumerable.Range('0', 10).Select(character => (byte) character);
|
||||
|
||||
[NotNull]
|
||||
private static IEnumerable<byte[]> SteamParentalCodes {
|
||||
get {
|
||||
HashSet<byte> steamParentalCharacters = SteamParentalCharacters.ToHashSet();
|
||||
|
||||
return from a in steamParentalCharacters from b in steamParentalCharacters from c in steamParentalCharacters from d in steamParentalCharacters select new[] { a, b, c, d };
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] EncryptionKey = Encoding.UTF8.GetBytes(nameof(ArchiSteamFarm));
|
||||
|
||||
internal static string Decrypt(ECryptoMethod cryptoMethod, string encrypted) {
|
||||
if (!Enum.IsDefined(typeof(ECryptoMethod), cryptoMethod) || string.IsNullOrEmpty(encrypted)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(cryptoMethod) + " || " + nameof(encrypted));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (cryptoMethod) {
|
||||
case ECryptoMethod.PlainText:
|
||||
return encrypted;
|
||||
case ECryptoMethod.AES:
|
||||
return DecryptAES(encrypted);
|
||||
case ECryptoMethod.ProtectedDataForCurrentUser:
|
||||
return DecryptProtectedDataForCurrentUser(encrypted);
|
||||
default:
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(cryptoMethod), cryptoMethod));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Encrypt(ECryptoMethod cryptoMethod, string decrypted) {
|
||||
if (!Enum.IsDefined(typeof(ECryptoMethod), cryptoMethod) || string.IsNullOrEmpty(decrypted)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(cryptoMethod) + " || " + nameof(decrypted));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (cryptoMethod) {
|
||||
case ECryptoMethod.PlainText:
|
||||
return decrypted;
|
||||
case ECryptoMethod.AES:
|
||||
return EncryptAES(decrypted);
|
||||
case ECryptoMethod.ProtectedDataForCurrentUser:
|
||||
return EncryptProtectedDataForCurrentUser(decrypted);
|
||||
default:
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(cryptoMethod), cryptoMethod));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<byte> GenerateSteamParentalHash(byte[] password, byte[] salt, byte hashLength, ESteamParentalAlgorithm steamParentalAlgorithm) {
|
||||
if ((password == null) || (salt == null) || (hashLength == 0) || !Enum.IsDefined(typeof(ESteamParentalAlgorithm), steamParentalAlgorithm)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(password) + " || " + nameof(salt) + " || " + nameof(hashLength) + " || " + nameof(steamParentalAlgorithm));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (steamParentalAlgorithm) {
|
||||
case ESteamParentalAlgorithm.Pbkdf2:
|
||||
using (HMACSHA256 hmacAlgorithm = new HMACSHA256(password)) {
|
||||
return Pbkdf2.ComputeDerivedKey(hmacAlgorithm, salt, SteamParentalPbkdf2Iterations, hashLength);
|
||||
}
|
||||
case ESteamParentalAlgorithm.SCrypt:
|
||||
return SCrypt.ComputeDerivedKey(password, salt, SteamParentalSCryptIterations, SteamParentalSCryptBlocksCount, 1, null, hashLength);
|
||||
default:
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(steamParentalAlgorithm), steamParentalAlgorithm));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string RecoverSteamParentalCode(byte[] passwordHash, byte[] salt, ESteamParentalAlgorithm steamParentalAlgorithm) {
|
||||
if ((passwordHash == null) || (salt == null) || !Enum.IsDefined(typeof(ESteamParentalAlgorithm), steamParentalAlgorithm)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(passwordHash) + " || " + nameof(salt) + " || " + nameof(steamParentalAlgorithm));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] password = SteamParentalCodes.AsParallel().FirstOrDefault(passwordToTry => GenerateSteamParentalHash(passwordToTry, salt, (byte) passwordHash.Length, steamParentalAlgorithm)?.SequenceEqual(passwordHash) == true);
|
||||
|
||||
return password != null ? Encoding.UTF8.GetString(password) : null;
|
||||
}
|
||||
|
||||
internal static void SetEncryptionKey(string key) {
|
||||
if (string.IsNullOrEmpty(key)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(key));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EncryptionKey = Encoding.UTF8.GetBytes(key);
|
||||
}
|
||||
|
||||
private static string DecryptAES(string encrypted) {
|
||||
if (string.IsNullOrEmpty(encrypted)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(encrypted));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] key;
|
||||
|
||||
using (SHA256 sha256 = SHA256.Create()) {
|
||||
key = sha256.ComputeHash(EncryptionKey);
|
||||
}
|
||||
|
||||
byte[] decryptedData = Convert.FromBase64String(encrypted);
|
||||
decryptedData = CryptoHelper.SymmetricDecrypt(decryptedData, key);
|
||||
|
||||
return Encoding.UTF8.GetString(decryptedData);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string DecryptProtectedDataForCurrentUser(string encrypted) {
|
||||
if (string.IsNullOrEmpty(encrypted)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(encrypted));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] decryptedData = ProtectedData.Unprotect(
|
||||
Convert.FromBase64String(encrypted),
|
||||
EncryptionKey, // This is used as salt only and it's fine that it's known
|
||||
DataProtectionScope.CurrentUser
|
||||
);
|
||||
|
||||
return Encoding.UTF8.GetString(decryptedData);
|
||||
} catch (PlatformNotSupportedException e) {
|
||||
ASF.ArchiLogger.LogGenericWarningException(e);
|
||||
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string EncryptAES(string decrypted) {
|
||||
if (string.IsNullOrEmpty(decrypted)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(decrypted));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] key;
|
||||
|
||||
using (SHA256 sha256 = SHA256.Create()) {
|
||||
key = sha256.ComputeHash(EncryptionKey);
|
||||
}
|
||||
|
||||
byte[] encryptedData = Encoding.UTF8.GetBytes(decrypted);
|
||||
encryptedData = CryptoHelper.SymmetricEncrypt(encryptedData, key);
|
||||
|
||||
return Convert.ToBase64String(encryptedData);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string EncryptProtectedDataForCurrentUser(string decrypted) {
|
||||
if (string.IsNullOrEmpty(decrypted)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(decrypted));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] encryptedData = ProtectedData.Protect(
|
||||
Encoding.UTF8.GetBytes(decrypted),
|
||||
EncryptionKey, // This is used as salt only and it's fine that it's known
|
||||
DataProtectionScope.CurrentUser
|
||||
);
|
||||
|
||||
return Convert.ToBase64String(encryptedData);
|
||||
} catch (PlatformNotSupportedException e) {
|
||||
ASF.ArchiLogger.LogGenericWarningException(e);
|
||||
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ECryptoMethod : byte {
|
||||
PlainText,
|
||||
AES,
|
||||
ProtectedDataForCurrentUser
|
||||
}
|
||||
|
||||
internal enum ESteamParentalAlgorithm : byte {
|
||||
SCrypt,
|
||||
Pbkdf2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +1,62 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>ASF.ico</ApplicationIcon>
|
||||
<AssemblyVersion>4.2.0.2</AssemblyVersion>
|
||||
<Authors>JustArchi</Authors>
|
||||
<Company>JustArchi</Company>
|
||||
<Copyright>Copyright © ArchiSteamFarm 2015-2020</Copyright>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);config/**;debug/**;out/**;overlay/**</DefaultItemExcludes>
|
||||
<Description>ASF is a C# application with primary purpose of idling Steam cards from multiple accounts simultaneously.</Description>
|
||||
<ErrorReport>none</ErrorReport>
|
||||
<FileVersion>4.2.0.2</FileVersion>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);config/**;debug/**;logs/**;overlay/**</DefaultItemExcludes>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<NoWarn>1591</NoWarn>
|
||||
<OpenApiGenerateDocuments>false</OpenApiGenerateDocuments>
|
||||
<OutputType>Exe</OutputType>
|
||||
<PackageIcon>../resources/ASF.ico</PackageIcon>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/JustArchiNET/ArchiSteamFarm</PackageProjectUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/JustArchiNET/ArchiSteamFarm.git</RepositoryUrl>
|
||||
<RuntimeIdentifiers>linux-arm;linux-x64;osx-x64;win-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' == 'Windows_NT' OR '$(ASFNetFramework)' != ''">
|
||||
<TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' != 'Windows_NT' AND '$(ASFNetFramework)' == ''">
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<DebugType>none</DebugType>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<WarningsAsErrors />
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ASFVariant)' != ''">
|
||||
<DefineConstants>$(DefineConstants);ASF_VARIANT_$(ASFVariant.Replace('-', '_').ToUpperInvariant())</DefineConstants>
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net48'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Configuration needed for PublishTrimmed=true to work with custom plugins -->
|
||||
<!-- TODO: https://github.com/mono/linker/issues/652 -->
|
||||
<TrimmerRootAssembly Include="System.Threading.Tasks" />
|
||||
<TrimmerRootAssembly Include="System.Threading.Timer" />
|
||||
<PackageReference Include="AngleSharp.XPath" />
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="all" />
|
||||
<PackageReference Include="CryptSharpStandard" />
|
||||
<PackageReference Include="Humanizer" />
|
||||
<PackageReference Include="JetBrains.Annotations" />
|
||||
<PackageReference Include="Markdig.Signed" />
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
<PackageReference Include="Nito.AsyncEx.Coordination" />
|
||||
<PackageReference Include="NLog" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" />
|
||||
<PackageReference Include="SteamKit2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" />
|
||||
<PackageReference Include="System.Composition" />
|
||||
<PackageReference Include="System.Linq.Async" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AngleSharp.XPath" Version="1.1.7" />
|
||||
<PackageReference Include="ConfigureAwaitChecker.Analyzer" Version="4.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CryptSharpStandard" Version="1.0.0" />
|
||||
<PackageReference Include="Humanizer" Version="2.7.9" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
|
||||
<PackageReference Include="Markdig.Signed" Version="0.18.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.0.0" />
|
||||
<PackageReference Include="NLog" Version="4.7.0" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.1" />
|
||||
<PackageReference Include="SteamKit2" Version="2.3.0-Beta.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.3.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.3.1" />
|
||||
<PackageReference Include="System.Composition" Version="1.4.0" />
|
||||
<PackageReference Include="System.Linq.Async" Version="4.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.7.0" />
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'net48'">
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="3.1.3" />
|
||||
<PackageReference Include="System.Collections.Immutable" Version="1.7.0" />
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Security.dll</HintPath>
|
||||
</Reference>
|
||||
<PackageReference Include="IndexRange" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cors" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" />
|
||||
<Reference Include="System.Net.Http" HintPath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Net.Http.dll" />
|
||||
<Reference Include="System.Security" HintPath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Security.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootDescriptor Include="TrimmerRoots.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Localization\Strings.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -103,23 +67,15 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Localization\Strings.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="overlay\all\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
</Content>
|
||||
<Content Include="..\ASF-ui\dist\**\*.*" Exclude="**\README.md">
|
||||
<Content Include="..\ASF-ui\dist\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Link>www\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,6 +19,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: CLSCompliant(false)]
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.Tests")]
|
||||
[assembly: InternalsVisibleTo("ArchiSteamFarm.OfficialPlugins.SteamTokenDumper")]
|
||||
|
||||
@@ -1,478 +0,0 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Ł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.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Json;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
public sealed class BotConfig {
|
||||
internal const byte SteamParentalCodeLength = 4;
|
||||
|
||||
private const bool DefaultAcceptGifts = false;
|
||||
private const bool DefaultAutoSteamSaleEvent = false;
|
||||
private const EBotBehaviour DefaultBotBehaviour = EBotBehaviour.None;
|
||||
private const string DefaultCustomGamePlayedWhileFarming = null;
|
||||
private const string DefaultCustomGamePlayedWhileIdle = null;
|
||||
private const bool DefaultEnabled = false;
|
||||
private const byte DefaultHoursUntilCardDrops = 3;
|
||||
private const bool DefaultIdlePriorityQueueOnly = false;
|
||||
private const bool DefaultIdleRefundableGames = true;
|
||||
private const EPersonaState DefaultOnlineStatus = EPersonaState.Online;
|
||||
private const ArchiCryptoHelper.ECryptoMethod DefaultPasswordFormat = ArchiCryptoHelper.ECryptoMethod.PlainText;
|
||||
private const bool DefaultPaused = false;
|
||||
private const ERedeemingPreferences DefaultRedeemingPreferences = ERedeemingPreferences.None;
|
||||
private const bool DefaultSendOnFarmingFinished = false;
|
||||
private const byte DefaultSendTradePeriod = 0;
|
||||
private const bool DefaultShutdownOnFarmingFinished = false;
|
||||
private const string DefaultSteamLogin = null;
|
||||
private const ulong DefaultSteamMasterClanID = 0;
|
||||
private const string DefaultSteamParentalCode = null;
|
||||
private const string DefaultSteamPassword = null;
|
||||
private const string DefaultSteamTradeToken = null;
|
||||
private const ETradingPreferences DefaultTradingPreferences = ETradingPreferences.None;
|
||||
private const bool DefaultUseLoginKeys = true;
|
||||
|
||||
private static readonly ImmutableList<EFarmingOrder> DefaultFarmingOrders = ImmutableList<EFarmingOrder>.Empty;
|
||||
private static readonly ImmutableHashSet<uint> DefaultGamesPlayedWhileIdle = ImmutableHashSet<uint>.Empty;
|
||||
private static readonly ImmutableHashSet<Steam.Asset.EType> DefaultLootableTypes = ImmutableHashSet.Create(Steam.Asset.EType.BoosterPack, Steam.Asset.EType.FoilTradingCard, Steam.Asset.EType.TradingCard);
|
||||
private static readonly ImmutableHashSet<Steam.Asset.EType> DefaultMatchableTypes = ImmutableHashSet.Create(Steam.Asset.EType.TradingCard);
|
||||
private static readonly ImmutableDictionary<ulong, EPermission> DefaultSteamUserPermissions = ImmutableDictionary<ulong, EPermission>.Empty;
|
||||
private static readonly ImmutableHashSet<Steam.Asset.EType> DefaultTransferableTypes = ImmutableHashSet.Create(Steam.Asset.EType.BoosterPack, Steam.Asset.EType.FoilTradingCard, Steam.Asset.EType.TradingCard);
|
||||
|
||||
private static readonly SemaphoreSlim WriteSemaphore = new SemaphoreSlim(1, 1);
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool AcceptGifts = DefaultAcceptGifts;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool AutoSteamSaleEvent = DefaultAutoSteamSaleEvent;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly EBotBehaviour BotBehaviour = DefaultBotBehaviour;
|
||||
|
||||
[JsonProperty]
|
||||
public readonly string CustomGamePlayedWhileFarming = DefaultCustomGamePlayedWhileFarming;
|
||||
|
||||
[JsonProperty]
|
||||
public readonly string CustomGamePlayedWhileIdle = DefaultCustomGamePlayedWhileIdle;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool Enabled = DefaultEnabled;
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
public readonly ImmutableList<EFarmingOrder> FarmingOrders = DefaultFarmingOrders;
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
public readonly ImmutableHashSet<uint> GamesPlayedWhileIdle = DefaultGamesPlayedWhileIdle;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly byte HoursUntilCardDrops = DefaultHoursUntilCardDrops;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool IdlePriorityQueueOnly = DefaultIdlePriorityQueueOnly;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool IdleRefundableGames = DefaultIdleRefundableGames;
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
public readonly ImmutableHashSet<Steam.Asset.EType> LootableTypes = DefaultLootableTypes;
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
public readonly ImmutableHashSet<Steam.Asset.EType> MatchableTypes = DefaultMatchableTypes;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly EPersonaState OnlineStatus = DefaultOnlineStatus;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly ArchiCryptoHelper.ECryptoMethod PasswordFormat = DefaultPasswordFormat;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool Paused = DefaultPaused;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly ERedeemingPreferences RedeemingPreferences = DefaultRedeemingPreferences;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool SendOnFarmingFinished = DefaultSendOnFarmingFinished;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly byte SendTradePeriod = DefaultSendTradePeriod;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool ShutdownOnFarmingFinished = DefaultShutdownOnFarmingFinished;
|
||||
|
||||
[JsonProperty]
|
||||
public readonly string SteamTradeToken = DefaultSteamTradeToken;
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
public readonly ImmutableDictionary<ulong, EPermission> SteamUserPermissions = DefaultSteamUserPermissions;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly ETradingPreferences TradingPreferences = DefaultTradingPreferences;
|
||||
|
||||
[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)]
|
||||
public readonly ImmutableHashSet<Steam.Asset.EType> TransferableTypes = DefaultTransferableTypes;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public readonly bool UseLoginKeys = DefaultUseLoginKeys;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
public ulong SteamMasterClanID { get; private set; } = DefaultSteamMasterClanID;
|
||||
|
||||
[JsonExtensionData]
|
||||
internal Dictionary<string, JToken> AdditionalProperties {
|
||||
get;
|
||||
[UsedImplicitly]
|
||||
set;
|
||||
}
|
||||
|
||||
internal string DecryptedSteamPassword {
|
||||
get {
|
||||
if (string.IsNullOrEmpty(SteamPassword)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (PasswordFormat == ArchiCryptoHelper.ECryptoMethod.PlainText) {
|
||||
return SteamPassword;
|
||||
}
|
||||
|
||||
string result = ArchiCryptoHelper.Decrypt(PasswordFormat, SteamPassword);
|
||||
|
||||
if (string.IsNullOrEmpty(result)) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(SteamPassword)));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
set {
|
||||
if (!string.IsNullOrEmpty(value) && (PasswordFormat != ArchiCryptoHelper.ECryptoMethod.PlainText)) {
|
||||
value = ArchiCryptoHelper.Encrypt(PasswordFormat, value);
|
||||
}
|
||||
|
||||
SteamPassword = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsSteamLoginSet { get; private set; }
|
||||
internal bool IsSteamParentalCodeSet { get; private set; }
|
||||
internal bool IsSteamPasswordSet { get; private set; }
|
||||
internal bool ShouldSerializeEverything { private get; set; } = true;
|
||||
internal bool ShouldSerializeHelperProperties { private get; set; } = true;
|
||||
|
||||
[JsonProperty]
|
||||
internal string SteamLogin {
|
||||
get => BackingSteamLogin;
|
||||
|
||||
set {
|
||||
IsSteamLoginSet = true;
|
||||
BackingSteamLogin = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty]
|
||||
internal string SteamParentalCode {
|
||||
get => BackingSteamParentalCode;
|
||||
|
||||
set {
|
||||
IsSteamParentalCodeSet = true;
|
||||
BackingSteamParentalCode = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty]
|
||||
internal string SteamPassword {
|
||||
get => BackingSteamPassword;
|
||||
|
||||
set {
|
||||
IsSteamPasswordSet = true;
|
||||
BackingSteamPassword = value;
|
||||
}
|
||||
}
|
||||
|
||||
private string BackingSteamLogin = DefaultSteamLogin;
|
||||
private string BackingSteamParentalCode = DefaultSteamParentalCode;
|
||||
private string BackingSteamPassword = DefaultSteamPassword;
|
||||
private bool ShouldSerializeSensitiveDetails = true;
|
||||
|
||||
[JsonProperty(PropertyName = SharedInfo.UlongCompatibilityStringPrefix + nameof(SteamMasterClanID), Required = Required.DisallowNull)]
|
||||
[JetBrains.Annotations.NotNull]
|
||||
private string SSteamMasterClanID {
|
||||
get => SteamMasterClanID.ToString();
|
||||
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value) || !ulong.TryParse(value, out ulong result)) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(SSteamMasterClanID)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SteamMasterClanID = result;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
private BotConfig() { }
|
||||
|
||||
internal (bool Valid, string ErrorMessage) CheckValidation() {
|
||||
if (BotBehaviour > EBotBehaviour.All) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(BotBehaviour), BotBehaviour));
|
||||
}
|
||||
|
||||
foreach (EFarmingOrder farmingOrder in FarmingOrders.Where(farmingOrder => !Enum.IsDefined(typeof(EFarmingOrder), farmingOrder))) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(FarmingOrders), farmingOrder));
|
||||
}
|
||||
|
||||
if (GamesPlayedWhileIdle.Count > ArchiHandler.MaxGamesPlayedConcurrently) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), GamesPlayedWhileIdle.Count + " > " + ArchiHandler.MaxGamesPlayedConcurrently));
|
||||
}
|
||||
|
||||
foreach (Steam.Asset.EType lootableType in LootableTypes.Where(lootableType => !Enum.IsDefined(typeof(Steam.Asset.EType), lootableType))) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(LootableTypes), lootableType));
|
||||
}
|
||||
|
||||
foreach (Steam.Asset.EType matchableType in MatchableTypes.Where(matchableType => !Enum.IsDefined(typeof(Steam.Asset.EType), matchableType))) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(MatchableTypes), matchableType));
|
||||
}
|
||||
|
||||
if ((OnlineStatus < EPersonaState.Offline) || (OnlineStatus >= EPersonaState.Max)) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(OnlineStatus), OnlineStatus));
|
||||
}
|
||||
|
||||
if (!Enum.IsDefined(typeof(ArchiCryptoHelper.ECryptoMethod), PasswordFormat)) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(PasswordFormat), PasswordFormat));
|
||||
}
|
||||
|
||||
if (RedeemingPreferences > ERedeemingPreferences.All) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(RedeemingPreferences), RedeemingPreferences));
|
||||
}
|
||||
|
||||
if ((SteamMasterClanID != 0) && !new SteamID(SteamMasterClanID).IsClanAccount) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(SteamMasterClanID), SteamMasterClanID));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(SteamParentalCode) && (SteamParentalCode != "0") && (SteamParentalCode.Length != SteamParentalCodeLength)) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(SteamParentalCode), SteamParentalCode));
|
||||
}
|
||||
|
||||
foreach ((ulong steamID, EPermission permission) in SteamUserPermissions) {
|
||||
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(SteamUserPermissions), steamID));
|
||||
}
|
||||
|
||||
if (!Enum.IsDefined(typeof(EPermission), permission)) {
|
||||
return (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(SteamUserPermissions), permission));
|
||||
}
|
||||
}
|
||||
|
||||
return TradingPreferences <= ETradingPreferences.All ? (true, null) : (false, string.Format(Strings.ErrorConfigPropertyInvalid, nameof(TradingPreferences), TradingPreferences));
|
||||
}
|
||||
|
||||
[ItemCanBeNull]
|
||||
internal static async Task<BotConfig> Load(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(filePath));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BotConfig botConfig;
|
||||
|
||||
try {
|
||||
string json = await RuntimeCompatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
|
||||
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsEmpty, nameof(json)));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
botConfig = JsonConvert.DeserializeObject<BotConfig>(json);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (botConfig == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(botConfig));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
(bool valid, string errorMessage) = botConfig.CheckValidation();
|
||||
|
||||
if (!valid) {
|
||||
ASF.ArchiLogger.LogGenericError(errorMessage);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
botConfig.ShouldSerializeEverything = false;
|
||||
botConfig.ShouldSerializeSensitiveDetails = false;
|
||||
|
||||
return botConfig;
|
||||
}
|
||||
|
||||
internal static async Task<bool> Write(string filePath, BotConfig botConfig) {
|
||||
if (string.IsNullOrEmpty(filePath) || (botConfig == null)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(filePath) + " || " + nameof(botConfig));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string json = JsonConvert.SerializeObject(botConfig, Formatting.Indented);
|
||||
string newFilePath = filePath + ".new";
|
||||
|
||||
await WriteSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
await RuntimeCompatibility.File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
|
||||
|
||||
if (File.Exists(filePath)) {
|
||||
File.Replace(newFilePath, filePath, null);
|
||||
} else {
|
||||
File.Move(newFilePath, filePath);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
WriteSemaphore.Release();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum EBotBehaviour : byte {
|
||||
None = 0,
|
||||
RejectInvalidFriendInvites = 1,
|
||||
RejectInvalidTrades = 2,
|
||||
RejectInvalidGroupInvites = 4,
|
||||
DismissInventoryNotifications = 8,
|
||||
MarkReceivedMessagesAsRead = 16,
|
||||
MarkBotMessagesAsRead = 32,
|
||||
All = RejectInvalidFriendInvites | RejectInvalidTrades | RejectInvalidGroupInvites | DismissInventoryNotifications | MarkReceivedMessagesAsRead | MarkBotMessagesAsRead
|
||||
}
|
||||
|
||||
public enum EFarmingOrder : byte {
|
||||
Unordered,
|
||||
AppIDsAscending,
|
||||
AppIDsDescending,
|
||||
CardDropsAscending,
|
||||
CardDropsDescending,
|
||||
HoursAscending,
|
||||
HoursDescending,
|
||||
NamesAscending,
|
||||
NamesDescending,
|
||||
Random,
|
||||
BadgeLevelsAscending,
|
||||
BadgeLevelsDescending,
|
||||
RedeemDateTimesAscending,
|
||||
RedeemDateTimesDescending,
|
||||
MarketableAscending,
|
||||
MarketableDescending
|
||||
}
|
||||
|
||||
public enum EPermission : byte {
|
||||
None,
|
||||
FamilySharing,
|
||||
Operator,
|
||||
Master
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ERedeemingPreferences : byte {
|
||||
None = 0,
|
||||
Forwarding = 1,
|
||||
Distributing = 2,
|
||||
KeepMissingGames = 4,
|
||||
AssumeWalletKeyOnBadActivationCode = 8,
|
||||
All = Forwarding | Distributing | KeepMissingGames | AssumeWalletKeyOnBadActivationCode
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ETradingPreferences : byte {
|
||||
None = 0,
|
||||
AcceptDonations = 1,
|
||||
SteamTradeMatcher = 2,
|
||||
MatchEverything = 4,
|
||||
DontAcceptBotTrades = 8,
|
||||
MatchActively = 16,
|
||||
All = AcceptDonations | SteamTradeMatcher | MatchEverything | DontAcceptBotTrades | MatchActively
|
||||
}
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
public bool ShouldSerializeAcceptGifts() => ShouldSerializeEverything || (AcceptGifts != DefaultAcceptGifts);
|
||||
public bool ShouldSerializeAutoSteamSaleEvent() => ShouldSerializeEverything || (AutoSteamSaleEvent != DefaultAutoSteamSaleEvent);
|
||||
public bool ShouldSerializeBotBehaviour() => ShouldSerializeEverything || (BotBehaviour != DefaultBotBehaviour);
|
||||
public bool ShouldSerializeCustomGamePlayedWhileFarming() => ShouldSerializeEverything || (CustomGamePlayedWhileFarming != DefaultCustomGamePlayedWhileFarming);
|
||||
public bool ShouldSerializeCustomGamePlayedWhileIdle() => ShouldSerializeEverything || (CustomGamePlayedWhileIdle != DefaultCustomGamePlayedWhileIdle);
|
||||
public bool ShouldSerializeEnabled() => ShouldSerializeEverything || (Enabled != DefaultEnabled);
|
||||
public bool ShouldSerializeFarmingOrders() => ShouldSerializeEverything || ((FarmingOrders != DefaultFarmingOrders) && !FarmingOrders.SequenceEqual(DefaultFarmingOrders));
|
||||
public bool ShouldSerializeGamesPlayedWhileIdle() => ShouldSerializeEverything || ((GamesPlayedWhileIdle != DefaultGamesPlayedWhileIdle) && !GamesPlayedWhileIdle.SetEquals(DefaultGamesPlayedWhileIdle));
|
||||
public bool ShouldSerializeHoursUntilCardDrops() => ShouldSerializeEverything || (HoursUntilCardDrops != DefaultHoursUntilCardDrops);
|
||||
public bool ShouldSerializeIdlePriorityQueueOnly() => ShouldSerializeEverything || (IdlePriorityQueueOnly != DefaultIdlePriorityQueueOnly);
|
||||
public bool ShouldSerializeIdleRefundableGames() => ShouldSerializeEverything || (IdleRefundableGames != DefaultIdleRefundableGames);
|
||||
public bool ShouldSerializeLootableTypes() => ShouldSerializeEverything || ((LootableTypes != DefaultLootableTypes) && !LootableTypes.SetEquals(DefaultLootableTypes));
|
||||
public bool ShouldSerializeMatchableTypes() => ShouldSerializeEverything || ((MatchableTypes != DefaultMatchableTypes) && !MatchableTypes.SetEquals(DefaultMatchableTypes));
|
||||
public bool ShouldSerializeOnlineStatus() => ShouldSerializeEverything || (OnlineStatus != DefaultOnlineStatus);
|
||||
public bool ShouldSerializePasswordFormat() => ShouldSerializeEverything || (PasswordFormat != DefaultPasswordFormat);
|
||||
public bool ShouldSerializePaused() => ShouldSerializeEverything || (Paused != DefaultPaused);
|
||||
public bool ShouldSerializeRedeemingPreferences() => ShouldSerializeEverything || (RedeemingPreferences != DefaultRedeemingPreferences);
|
||||
public bool ShouldSerializeSendOnFarmingFinished() => ShouldSerializeEverything || (SendOnFarmingFinished != DefaultSendOnFarmingFinished);
|
||||
public bool ShouldSerializeSendTradePeriod() => ShouldSerializeEverything || (SendTradePeriod != DefaultSendTradePeriod);
|
||||
public bool ShouldSerializeShutdownOnFarmingFinished() => ShouldSerializeEverything || (ShutdownOnFarmingFinished != DefaultShutdownOnFarmingFinished);
|
||||
public bool ShouldSerializeSSteamMasterClanID() => ShouldSerializeEverything || (ShouldSerializeHelperProperties && (SteamMasterClanID != DefaultSteamMasterClanID));
|
||||
public bool ShouldSerializeSteamLogin() => ShouldSerializeSensitiveDetails && (ShouldSerializeEverything || (SteamLogin != DefaultSteamLogin));
|
||||
public bool ShouldSerializeSteamMasterClanID() => ShouldSerializeEverything || (SteamMasterClanID != DefaultSteamMasterClanID);
|
||||
public bool ShouldSerializeSteamParentalCode() => ShouldSerializeSensitiveDetails && (ShouldSerializeEverything || (SteamParentalCode != DefaultSteamParentalCode));
|
||||
public bool ShouldSerializeSteamPassword() => ShouldSerializeSensitiveDetails && (ShouldSerializeEverything || (SteamPassword != DefaultSteamPassword));
|
||||
public bool ShouldSerializeSteamTradeToken() => ShouldSerializeEverything || (SteamTradeToken != DefaultSteamTradeToken);
|
||||
public bool ShouldSerializeSteamUserPermissions() => ShouldSerializeEverything || ((SteamUserPermissions != DefaultSteamUserPermissions) && ((SteamUserPermissions.Count != DefaultSteamUserPermissions.Count) || SteamUserPermissions.Except(DefaultSteamUserPermissions).Any()));
|
||||
public bool ShouldSerializeTradingPreferences() => ShouldSerializeEverything || (TradingPreferences != DefaultTradingPreferences);
|
||||
public bool ShouldSerializeTransferableTypes() => ShouldSerializeEverything || ((TransferableTypes != DefaultTransferableTypes) && !TransferableTypes.SetEquals(DefaultTransferableTypes));
|
||||
public bool ShouldSerializeUseLoginKeys() => ShouldSerializeEverything || (UseLoginKeys != DefaultUseLoginKeys);
|
||||
|
||||
// ReSharper restore UnusedMember.Global
|
||||
}
|
||||
}
|
||||
@@ -1,311 +0,0 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Ł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.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.Collections;
|
||||
using ArchiSteamFarm.Helpers;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using SteamKit2;
|
||||
|
||||
namespace ArchiSteamFarm {
|
||||
internal sealed class BotDatabase : SerializableFile {
|
||||
internal uint GamesToRedeemInBackgroundCount {
|
||||
get {
|
||||
lock (GamesToRedeemInBackground) {
|
||||
return (uint) GamesToRedeemInBackground.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasGamesToRedeemInBackground => GamesToRedeemInBackgroundCount > 0;
|
||||
internal bool HasIdlingPriorityAppIDs => IdlingPriorityAppIDs.Count > 0;
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentHashSet<ulong> BlacklistedFromTradesSteamIDs = new ConcurrentHashSet<ulong>();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly OrderedDictionary GamesToRedeemInBackground = new OrderedDictionary();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentHashSet<uint> IdlingBlacklistedAppIDs = new ConcurrentHashSet<uint>();
|
||||
|
||||
[JsonProperty(Required = Required.DisallowNull)]
|
||||
private readonly ConcurrentHashSet<uint> IdlingPriorityAppIDs = new ConcurrentHashSet<uint>();
|
||||
|
||||
internal string LoginKey {
|
||||
get => BackingLoginKey;
|
||||
|
||||
set {
|
||||
if (BackingLoginKey == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
BackingLoginKey = value;
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal MobileAuthenticator MobileAuthenticator {
|
||||
get => BackingMobileAuthenticator;
|
||||
|
||||
set {
|
||||
if (BackingMobileAuthenticator == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
BackingMobileAuthenticator = value;
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(PropertyName = "_LoginKey")]
|
||||
private string BackingLoginKey;
|
||||
|
||||
[JsonProperty(PropertyName = "_MobileAuthenticator")]
|
||||
private MobileAuthenticator BackingMobileAuthenticator;
|
||||
|
||||
private BotDatabase([NotNull] string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
FilePath = filePath;
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
private BotDatabase() { }
|
||||
|
||||
internal void AddBlacklistedFromTradesSteamIDs(IReadOnlyCollection<ulong> steamIDs) {
|
||||
if ((steamIDs == null) || (steamIDs.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(steamIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (BlacklistedFromTradesSteamIDs.AddRange(steamIDs)) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddGamesToRedeemInBackground(IOrderedDictionary games) {
|
||||
if ((games == null) || (games.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(games));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool save = false;
|
||||
|
||||
lock (GamesToRedeemInBackground) {
|
||||
foreach (DictionaryEntry game in games.Cast<DictionaryEntry>().Where(game => !GamesToRedeemInBackground.Contains(game.Key))) {
|
||||
GamesToRedeemInBackground.Add(game.Key, game.Value);
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddIdlingBlacklistedAppIDs(IReadOnlyCollection<uint> appIDs) {
|
||||
if ((appIDs == null) || (appIDs.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IdlingBlacklistedAppIDs.AddRange(appIDs)) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddIdlingPriorityAppIDs(IReadOnlyCollection<uint> appIDs) {
|
||||
if ((appIDs == null) || (appIDs.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IdlingPriorityAppIDs.AddRange(appIDs)) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
[ItemCanBeNull]
|
||||
internal static async Task<BotDatabase> CreateOrLoad(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(filePath));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath)) {
|
||||
return new BotDatabase(filePath);
|
||||
}
|
||||
|
||||
BotDatabase botDatabase;
|
||||
|
||||
try {
|
||||
string json = await RuntimeCompatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
|
||||
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsEmpty, nameof(json)));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
botDatabase = JsonConvert.DeserializeObject<BotDatabase>(json);
|
||||
} catch (Exception e) {
|
||||
ASF.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (botDatabase == null) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(botDatabase));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
botDatabase.FilePath = filePath;
|
||||
|
||||
return botDatabase;
|
||||
}
|
||||
|
||||
internal IReadOnlyCollection<ulong> GetBlacklistedFromTradesSteamIDs() => BlacklistedFromTradesSteamIDs;
|
||||
|
||||
internal (string Key, string Name) GetGameToRedeemInBackground() {
|
||||
lock (GamesToRedeemInBackground) {
|
||||
foreach (DictionaryEntry game in GamesToRedeemInBackground) {
|
||||
return (game.Key as string, game.Value as string);
|
||||
}
|
||||
}
|
||||
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
internal IReadOnlyCollection<uint> GetIdlingBlacklistedAppIDs() => IdlingBlacklistedAppIDs;
|
||||
internal IReadOnlyCollection<uint> GetIdlingPriorityAppIDs() => IdlingPriorityAppIDs;
|
||||
|
||||
internal bool IsBlacklistedFromIdling(uint appID) {
|
||||
if (appID == 0) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appID));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return IdlingBlacklistedAppIDs.Contains(appID);
|
||||
}
|
||||
|
||||
internal bool IsBlacklistedFromTrades(ulong steamID) {
|
||||
if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(steamID));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return BlacklistedFromTradesSteamIDs.Contains(steamID);
|
||||
}
|
||||
|
||||
internal bool IsPriorityIdling(uint appID) {
|
||||
if (appID == 0) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appID));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return IdlingPriorityAppIDs.Contains(appID);
|
||||
}
|
||||
|
||||
internal void RemoveBlacklistedFromTradesSteamIDs(IReadOnlyCollection<ulong> steamIDs) {
|
||||
if ((steamIDs == null) || (steamIDs.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(steamIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (BlacklistedFromTradesSteamIDs.RemoveRange(steamIDs)) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveGameToRedeemInBackground(string key) {
|
||||
if (string.IsNullOrEmpty(key)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(key));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lock (GamesToRedeemInBackground) {
|
||||
if (!GamesToRedeemInBackground.Contains(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GamesToRedeemInBackground.Remove(key);
|
||||
}
|
||||
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
|
||||
internal void RemoveIdlingBlacklistedAppIDs(IReadOnlyCollection<uint> appIDs) {
|
||||
if ((appIDs == null) || (appIDs.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IdlingBlacklistedAppIDs.RemoveRange(appIDs)) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveIdlingPriorityAppIDs(IReadOnlyCollection<uint> appIDs) {
|
||||
if ((appIDs == null) || (appIDs.Count == 0)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appIDs));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IdlingPriorityAppIDs.RemoveRange(appIDs)) {
|
||||
Utilities.InBackground(Save);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
public bool ShouldSerializeBlacklistedFromTradesSteamIDs() => BlacklistedFromTradesSteamIDs.Count > 0;
|
||||
public bool ShouldSerializeGamesToRedeemInBackground() => HasGamesToRedeemInBackground;
|
||||
public bool ShouldSerializeIdlingBlacklistedAppIDs() => IdlingBlacklistedAppIDs.Count > 0;
|
||||
public bool ShouldSerializeIdlingPriorityAppIDs() => IdlingPriorityAppIDs.Count > 0;
|
||||
public bool ShouldSerializeLoginKey() => !string.IsNullOrEmpty(LoginKey);
|
||||
public bool ShouldSerializeMobileAuthenticator() => MobileAuthenticator != null;
|
||||
|
||||
// ReSharper restore UnusedMember.Global
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -22,29 +22,28 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.Collections {
|
||||
internal sealed class ConcurrentEnumerator<T> : IEnumerator<T> {
|
||||
public T Current => Enumerator.Current;
|
||||
|
||||
private readonly IEnumerator<T> Enumerator;
|
||||
private readonly IDisposable Lock;
|
||||
private readonly IDisposable LockObject;
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
object? IEnumerator.Current => Current;
|
||||
|
||||
internal ConcurrentEnumerator([NotNull] IReadOnlyCollection<T> collection, [NotNull] IDisposable @lock) {
|
||||
if ((collection == null) || (@lock == null)) {
|
||||
throw new ArgumentNullException(nameof(collection) + " || " + nameof(@lock));
|
||||
internal ConcurrentEnumerator(IReadOnlyCollection<T> collection, IDisposable lockObject) {
|
||||
if (collection == null) {
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
}
|
||||
|
||||
Lock = @lock;
|
||||
LockObject = lockObject ?? throw new ArgumentNullException(nameof(lockObject));
|
||||
Enumerator = collection.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Enumerator.Dispose();
|
||||
Lock.Dispose();
|
||||
LockObject.Dispose();
|
||||
}
|
||||
|
||||
public bool MoveNext() => Enumerator.MoveNext();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -23,12 +23,13 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.Collections {
|
||||
public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ISet<T> {
|
||||
public sealed class ConcurrentHashSet<T> : IReadOnlyCollection<T>, ISet<T> where T : notnull {
|
||||
public event EventHandler? OnModified;
|
||||
|
||||
public int Count => BackingCollection.Count;
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace ArchiSteamFarm.Collections {
|
||||
|
||||
public ConcurrentHashSet() => BackingCollection = new ConcurrentDictionary<T, bool>();
|
||||
|
||||
public ConcurrentHashSet([JetBrains.Annotations.NotNull] IEqualityComparer<T> comparer) {
|
||||
public ConcurrentHashSet(IEqualityComparer<T> comparer) {
|
||||
if (comparer == null) {
|
||||
throw new ArgumentNullException(nameof(comparer));
|
||||
}
|
||||
@@ -44,15 +45,35 @@ namespace ArchiSteamFarm.Collections {
|
||||
BackingCollection = new ConcurrentDictionary<T, bool>(comparer);
|
||||
}
|
||||
|
||||
public bool Add(T item) => BackingCollection.TryAdd(item, true);
|
||||
public void Clear() => BackingCollection.Clear();
|
||||
public bool Add(T item) {
|
||||
if (!BackingCollection.TryAdd(item, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OnModified?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
if (BackingCollection.IsEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
BackingCollection.Clear();
|
||||
|
||||
OnModified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
|
||||
public bool Contains(T item) => BackingCollection.ContainsKey(item);
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex) => BackingCollection.Keys.CopyTo(array, arrayIndex);
|
||||
|
||||
public void ExceptWith(IEnumerable<T> other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentNullException(nameof(other));
|
||||
}
|
||||
|
||||
foreach (T item in other) {
|
||||
Remove(item);
|
||||
}
|
||||
@@ -98,8 +119,15 @@ namespace ArchiSteamFarm.Collections {
|
||||
return otherSet.Any(Contains);
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
|
||||
public bool Remove(T item) => BackingCollection.TryRemove(item, out _);
|
||||
public bool Remove(T item) {
|
||||
if (!BackingCollection.TryRemove(item, out _)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OnModified?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetEquals(IEnumerable<T> other) {
|
||||
ISet<T> otherSet = other as ISet<T> ?? other.ToHashSet();
|
||||
@@ -109,7 +137,7 @@ namespace ArchiSteamFarm.Collections {
|
||||
|
||||
public void SymmetricExceptWith(IEnumerable<T> other) {
|
||||
ISet<T> otherSet = other as ISet<T> ?? other.ToHashSet();
|
||||
HashSet<T> removed = new HashSet<T>();
|
||||
HashSet<T> removed = new();
|
||||
|
||||
foreach (T item in otherSet.Where(Contains)) {
|
||||
removed.Add(item);
|
||||
@@ -122,27 +150,43 @@ namespace ArchiSteamFarm.Collections {
|
||||
}
|
||||
|
||||
public void UnionWith(IEnumerable<T> other) {
|
||||
if (other == null) {
|
||||
throw new ArgumentNullException(nameof(other));
|
||||
}
|
||||
|
||||
foreach (T otherElement in other) {
|
||||
Add(otherElement);
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "AnnotationConflictInHierarchy")]
|
||||
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
|
||||
void ICollection<T>.Add([JetBrains.Annotations.NotNull] T item) => Add(item);
|
||||
void ICollection<T>.Add(T item) => Add(item);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
// We use Count() and not Any() because we must ensure full loop pass
|
||||
[PublicAPI]
|
||||
public bool AddRange([JetBrains.Annotations.NotNull] IEnumerable<T> items) => items.Count(Add) > 0;
|
||||
public bool AddRange(IEnumerable<T> items) {
|
||||
bool result = false;
|
||||
|
||||
// We use Count() and not Any() because we must ensure full loop pass
|
||||
[PublicAPI]
|
||||
public bool RemoveRange([JetBrains.Annotations.NotNull] IEnumerable<T> items) => items.Count(Remove) > 0;
|
||||
foreach (T _ in items.Where(Add)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public bool ReplaceIfNeededWith([JetBrains.Annotations.NotNull] IReadOnlyCollection<T> other) {
|
||||
public bool RemoveRange(IEnumerable<T> items) {
|
||||
bool result = false;
|
||||
|
||||
foreach (T _ in items.Where(Remove)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public bool ReplaceIfNeededWith(IReadOnlyCollection<T> other) {
|
||||
if (SetEquals(other)) {
|
||||
return false;
|
||||
}
|
||||
@@ -153,12 +197,9 @@ namespace ArchiSteamFarm.Collections {
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public void ReplaceWith([JetBrains.Annotations.NotNull] IEnumerable<T> other) {
|
||||
BackingCollection.Clear();
|
||||
|
||||
foreach (T item in other) {
|
||||
BackingCollection[item] = true;
|
||||
}
|
||||
public void ReplaceWith(IEnumerable<T> other) {
|
||||
Clear();
|
||||
UnionWith(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Nito.AsyncEx;
|
||||
|
||||
namespace ArchiSteamFarm.Collections {
|
||||
@@ -36,8 +35,8 @@ namespace ArchiSteamFarm.Collections {
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<T> BackingCollection = new List<T>();
|
||||
private readonly AsyncReaderWriterLock Lock = new AsyncReaderWriterLock();
|
||||
private readonly List<T> BackingCollection = new();
|
||||
private readonly AsyncReaderWriterLock Lock = new();
|
||||
|
||||
int ICollection<T>.Count => Count;
|
||||
int IReadOnlyCollection<T>.Count => Count;
|
||||
@@ -80,8 +79,6 @@ namespace ArchiSteamFarm.Collections {
|
||||
}
|
||||
}
|
||||
|
||||
[JetBrains.Annotations.NotNull]
|
||||
[SuppressMessage("ReSharper", "AnnotationRedundancyInHierarchy")]
|
||||
public IEnumerator<T> GetEnumerator() => new ConcurrentEnumerator<T>(BackingCollection, Lock.ReaderLock());
|
||||
|
||||
public int IndexOf(T item) {
|
||||
@@ -108,11 +105,9 @@ namespace ArchiSteamFarm.Collections {
|
||||
}
|
||||
}
|
||||
|
||||
[JetBrains.Annotations.NotNull]
|
||||
[SuppressMessage("ReSharper", "AnnotationRedundancyInHierarchy")]
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
internal void ReplaceWith([JetBrains.Annotations.NotNull] IEnumerable<T> collection) {
|
||||
internal void ReplaceWith(IEnumerable<T> collection) {
|
||||
using (Lock.WriterLock()) {
|
||||
BackingCollection.Clear();
|
||||
BackingCollection.AddRange(collection);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2020 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -23,10 +23,11 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using ArchiSteamFarm.Core;
|
||||
|
||||
namespace ArchiSteamFarm.Collections {
|
||||
internal sealed class FixedSizeConcurrentQueue<T> : IEnumerable<T> {
|
||||
private readonly ConcurrentQueue<T> BackingQueue = new ConcurrentQueue<T>();
|
||||
private readonly ConcurrentQueue<T> BackingQueue = new();
|
||||
|
||||
internal byte MaxCount {
|
||||
get => BackingMaxCount;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
74
ArchiSteamFarm/Compatibility/File.cs
Normal file
74
ArchiSteamFarm/Compatibility/File.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
// _ _ _ ____ _ _____
|
||||
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
|
||||
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
|
||||
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// |
|
||||
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// |
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// |
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.Compatibility {
|
||||
[PublicAPI]
|
||||
public static class File {
|
||||
public static Task AppendAllTextAsync(string path, string contents) {
|
||||
#if NETFRAMEWORK
|
||||
System.IO.File.AppendAllText(path, contents);
|
||||
|
||||
return Task.CompletedTask;
|
||||
#else
|
||||
return System.IO.File.AppendAllTextAsync(path, contents);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Move(string sourceFileName, string destFileName, bool overwrite) {
|
||||
#if NETFRAMEWORK
|
||||
if (overwrite && System.IO.File.Exists(destFileName)) {
|
||||
System.IO.File.Delete(destFileName);
|
||||
}
|
||||
|
||||
System.IO.File.Move(sourceFileName, destFileName);
|
||||
#else
|
||||
System.IO.File.Move(sourceFileName, destFileName, overwrite);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Task<byte[]> ReadAllBytesAsync(string path) =>
|
||||
#if NETFRAMEWORK
|
||||
Task.FromResult(System.IO.File.ReadAllBytes(path));
|
||||
#else
|
||||
System.IO.File.ReadAllBytesAsync(path);
|
||||
#endif
|
||||
|
||||
public static Task<string> ReadAllTextAsync(string path) =>
|
||||
#if NETFRAMEWORK
|
||||
Task.FromResult(System.IO.File.ReadAllText(path));
|
||||
#else
|
||||
System.IO.File.ReadAllTextAsync(path);
|
||||
#endif
|
||||
|
||||
public static Task WriteAllTextAsync(string path, string contents) {
|
||||
#if NETFRAMEWORK
|
||||
System.IO.File.WriteAllText(path, contents);
|
||||
|
||||
return Task.CompletedTask;
|
||||
#else
|
||||
return System.IO.File.WriteAllTextAsync(path, contents);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user