Compare commits
906 Commits
1.0.180.47
...
2.0.31
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7bbdb79257 | ||
![]() |
afa40d3532 | ||
![]() |
4afae0fe56 | ||
![]() |
f43e61c7bb | ||
![]() |
646916dc7b | ||
![]() |
563c611e3e | ||
![]() |
579b090c85 | ||
![]() |
f49748da9f | ||
![]() |
534fdd0e49 | ||
![]() |
6070bddd7d | ||
![]() |
d8e2d9fcec | ||
![]() |
615defabb6 | ||
![]() |
0d719ee01f | ||
22c4cfb039 | |||
5f0ffb6f9a | |||
1b2a989441 | |||
![]() |
83dfc7152f | ||
d7e5f53e4f | |||
9b08b39a1f | |||
![]() |
8011f9eed7 | ||
1df791e7a8 | |||
![]() |
bbc2f9046f | ||
117ea7df91 | |||
6ec355f931 | |||
![]() |
343420f1d8 | ||
![]() |
1396c8b1da | ||
![]() |
9900f92133 | ||
![]() |
3be524d169 | ||
ed694ae95b | |||
e9a9e180a8 | |||
a8dfaf6239 | |||
bbdd1c7e01 | |||
e70e1ca4e6 | |||
![]() |
d65c20a05d | ||
f21976cf2d | |||
0c918106bc | |||
6c9ec57d87 | |||
![]() |
b0f491ac88 | ||
![]() |
a426ad9e02 | ||
![]() |
ba75b1583a | ||
![]() |
45068ea932 | ||
![]() |
181e9297a1 | ||
![]() |
e0417d3235 | ||
![]() |
17a244a536 | ||
![]() |
bd27360655 | ||
![]() |
b24eee3ecf | ||
![]() |
9068558a53 | ||
![]() |
9c22948ce9 | ||
![]() |
2b1a5d4c6e | ||
![]() |
2860dda41b | ||
![]() |
5483728a4e | ||
![]() |
32d318be5e | ||
![]() |
f349366b58 | ||
![]() |
73ce979b54 | ||
![]() |
73b95472bc | ||
![]() |
9b832a998d | ||
![]() |
b1087822c9 | ||
![]() |
ef2d35879c | ||
![]() |
83d8eea9ef | ||
![]() |
8cdd992350 | ||
![]() |
b9cb71e11f | ||
![]() |
1a1a7e779a | ||
![]() |
6bcd2ea58e | ||
![]() |
b8a06f7bd7 | ||
![]() |
d44b1a592c | ||
![]() |
d7d556d2f2 | ||
![]() |
850b313269 | ||
![]() |
fe985e1a9c | ||
![]() |
aeea192860 | ||
![]() |
b8be5b2dce | ||
![]() |
ea08d60d58 | ||
![]() |
6493a305f7 | ||
![]() |
bc0a2b89b8 | ||
![]() |
846c2aa42e | ||
![]() |
ac1ec431fd | ||
![]() |
3acaf25376 | ||
![]() |
e8928b6b3b | ||
![]() |
8478ee3752 | ||
![]() |
ead8e3a4fc | ||
![]() |
f73b9df924 | ||
![]() |
d524651da9 | ||
![]() |
2743e5b42d | ||
![]() |
02bd9df059 | ||
![]() |
a5cc132151 | ||
![]() |
92dea1986c | ||
![]() |
c03eb79f81 | ||
![]() |
0ee9c5f97c | ||
![]() |
c283059106 | ||
![]() |
422963517f | ||
![]() |
d2ac0e44be | ||
![]() |
c5acf61f7c | ||
![]() |
197d04a661 | ||
![]() |
99ab7d0eea | ||
![]() |
17f97af52f | ||
![]() |
ed7c897bd2 | ||
![]() |
e4d3c3987f | ||
![]() |
067d8802b6 | ||
![]() |
8f32f64ede | ||
![]() |
90ff3f93f0 | ||
![]() |
ad28b302f9 | ||
![]() |
a0d0976a6a | ||
![]() |
a9c9a0de68 | ||
![]() |
9a967345b9 | ||
![]() |
98a4be655f | ||
![]() |
76de8f3d0b | ||
![]() |
6f886d4f7d | ||
![]() |
a753abb8fd | ||
![]() |
452970d2fd | ||
![]() |
e28c38e04f | ||
![]() |
5d9fe01c69 | ||
![]() |
04227912b0 | ||
![]() |
44dd0805e2 | ||
![]() |
c5c8e527da | ||
![]() |
49f68a8fcc | ||
![]() |
f8a3647308 | ||
![]() |
0a40b1fe0f | ||
![]() |
a1e9434444 | ||
![]() |
d2d96df8be | ||
![]() |
b40f288827 | ||
![]() |
6267cffebe | ||
![]() |
5fe25fb781 | ||
![]() |
d05e979ede | ||
![]() |
1afb126cb5 | ||
![]() |
d52348149a | ||
![]() |
20eac508d3 | ||
![]() |
8ba02a84d3 | ||
![]() |
15be85b4f5 | ||
![]() |
cf5c00ce0e | ||
![]() |
9c185d5577 | ||
![]() |
8b6c401531 | ||
![]() |
92db8994ef | ||
![]() |
aee36661fd | ||
![]() |
feda84fac8 | ||
![]() |
2503cd6372 | ||
![]() |
f321034eeb | ||
![]() |
7573684520 | ||
![]() |
223eaa9fd0 | ||
![]() |
d138a46f25 | ||
![]() |
ce2bbd4a61 | ||
![]() |
85dd4b46b8 | ||
![]() |
166a9d1dbe | ||
![]() |
dfc15354ca | ||
![]() |
57c977deb4 | ||
![]() |
f6cdc2fe79 | ||
![]() |
f42b9c6674 | ||
![]() |
227557f421 | ||
![]() |
0632f68aaf | ||
![]() |
0a9f299527 | ||
![]() |
67f25ab20b | ||
![]() |
ad19a7dc9e | ||
![]() |
dd854a159a | ||
![]() |
879a373e6a | ||
![]() |
ec1b017946 | ||
![]() |
cf75210304 | ||
![]() |
3696f18714 | ||
![]() |
1f7e4e869d | ||
![]() |
ba5b611994 | ||
![]() |
2bcf79efdd | ||
![]() |
d5c101bf19 | ||
![]() |
e9841b4de1 | ||
![]() |
aea0011683 | ||
![]() |
d10528f9fe | ||
![]() |
66ea4d7307 | ||
![]() |
f6ce40a854 | ||
![]() |
bd62d31298 | ||
![]() |
b1cf5fb638 | ||
![]() |
1d6a2a9a60 | ||
![]() |
455be2393e | ||
![]() |
6131a9003b | ||
![]() |
2a17c4bc09 | ||
![]() |
ccc1df9349 | ||
![]() |
d80c7b9fba | ||
![]() |
64c6ce289c | ||
![]() |
67de82a103 | ||
![]() |
357e0446df | ||
![]() |
f2291a57c3 | ||
![]() |
8b862df6ea | ||
![]() |
1c92f69bd4 | ||
![]() |
70833adb44 | ||
![]() |
ab61674b47 | ||
![]() |
c8ddf691ba | ||
![]() |
76afccd9db | ||
![]() |
4882dc673a | ||
![]() |
8546165e59 | ||
![]() |
4cab214635 | ||
![]() |
9a6253d0ef | ||
![]() |
55eac7ecbf | ||
![]() |
057d126658 | ||
![]() |
8efe8ae398 | ||
![]() |
e2cdd803af | ||
![]() |
b6d8cf07f8 | ||
![]() |
1b23cd564e | ||
![]() |
f6ef662344 | ||
![]() |
58b9c926ae | ||
![]() |
81d11a32fe | ||
![]() |
eb9afd5e36 | ||
![]() |
1de0b63907 | ||
![]() |
f89170c37d | ||
![]() |
73ee686a84 | ||
![]() |
e49910e121 | ||
![]() |
83805cba77 | ||
![]() |
32a61d2feb | ||
![]() |
133e20c758 | ||
![]() |
d7c5aa3fa8 | ||
![]() |
f6d59c75c6 | ||
![]() |
fd8c731713 | ||
![]() |
55a552af60 | ||
![]() |
770d18859b | ||
![]() |
22e60edc1f | ||
![]() |
c97fd07f89 | ||
![]() |
7e87cdd5a0 | ||
![]() |
b67eff406f | ||
![]() |
29a5c09ac7 | ||
![]() |
a1668abcd4 | ||
![]() |
2d8ca29935 | ||
![]() |
4f9af817a5 | ||
![]() |
7bd4beb82d | ||
![]() |
1ec57bc4c9 | ||
![]() |
63f14c984d | ||
![]() |
6c227b4a6e | ||
![]() |
b846112c43 | ||
![]() |
23f9b1507d | ||
![]() |
2a0555ea4f | ||
![]() |
0395d0bc7f | ||
![]() |
f2c03cbc34 | ||
![]() |
147c94fd93 | ||
![]() |
0e2ecf16f3 | ||
![]() |
36eb256553 | ||
![]() |
e90ca41c3c | ||
![]() |
5528231cc2 | ||
![]() |
4d01b976f1 | ||
![]() |
ff12b214cd | ||
![]() |
55c9f5296f | ||
![]() |
61e1ed7a59 | ||
![]() |
218cd30152 | ||
![]() |
bf3b819d02 | ||
![]() |
b56c8f711c | ||
![]() |
c5c6ef1cd2 | ||
![]() |
3e01cecdcc | ||
![]() |
966b2f5756 | ||
![]() |
a5743701ea | ||
![]() |
7ea1a523e1 | ||
![]() |
5445459dc7 | ||
![]() |
f2eed13473 | ||
![]() |
af894e7507 | ||
![]() |
94475f7bd1 | ||
![]() |
b5ca0bf392 | ||
![]() |
fdd8479016 | ||
![]() |
c915b385e3 | ||
![]() |
f451c552ec | ||
![]() |
0aa17a26ac | ||
![]() |
41b16a6d75 | ||
![]() |
b5f53dd6c6 | ||
![]() |
5cc2d6652d | ||
![]() |
6fb6226be5 | ||
![]() |
cee5cb3c4d | ||
![]() |
b6fb470b84 | ||
![]() |
6c74ed3869 | ||
![]() |
2c44860a70 | ||
![]() |
169b543f7d | ||
![]() |
efd15fcd62 | ||
![]() |
b372230eae | ||
![]() |
e5cb3e5ae0 | ||
![]() |
8f30b7605b | ||
![]() |
bec29c5bb4 | ||
![]() |
f84a27d705 | ||
![]() |
19f9388a43 | ||
![]() |
f25a412a47 | ||
![]() |
f7a63f17cc | ||
![]() |
aa5963b29b | ||
![]() |
15c4276a81 | ||
![]() |
04b13cbd6c | ||
![]() |
f6971c715b | ||
![]() |
c3e65a5bdd | ||
![]() |
93167f349d | ||
![]() |
b12acddab3 | ||
![]() |
fb9dbf40da | ||
![]() |
1b8bddabc8 | ||
![]() |
a4edbf3bd9 | ||
![]() |
3d13460302 | ||
![]() |
fad656e837 | ||
![]() |
fc986c87a6 | ||
![]() |
80a820ae3d | ||
![]() |
e9e446f8ab | ||
![]() |
b53194184c | ||
![]() |
bcb921cd9d | ||
![]() |
c1632b6b20 | ||
![]() |
88d10d1955 | ||
![]() |
d6fe6234d7 | ||
![]() |
29fcdc0bf8 | ||
![]() |
48ddc6389f | ||
![]() |
a3d722eb16 | ||
![]() |
b386e53ff5 | ||
![]() |
1dd444759b | ||
![]() |
76ea5fdbc1 | ||
![]() |
035325da22 | ||
![]() |
33b2fa7094 | ||
![]() |
b220243b75 | ||
![]() |
f2a077deed | ||
![]() |
d3de1426b2 | ||
![]() |
86b6b94d25 | ||
![]() |
0a19663c33 | ||
![]() |
d236fd9bd9 | ||
![]() |
bc54b79098 | ||
![]() |
5035fa39b7 | ||
![]() |
2395c33995 | ||
![]() |
92ae252210 | ||
![]() |
5d40cf373d | ||
![]() |
9cbcc3ed85 | ||
![]() |
a1f397f9bf | ||
![]() |
540b17448a | ||
![]() |
21fd997554 | ||
![]() |
23b0318591 | ||
![]() |
5727e3b1b8 | ||
![]() |
28164b491b | ||
![]() |
b02d613a28 | ||
![]() |
c18d6d4795 | ||
![]() |
5780cf7c95 | ||
![]() |
cc91fa3653 | ||
![]() |
52ef0b4d6d | ||
![]() |
ef2be78102 | ||
![]() |
9c2dc69e3c | ||
![]() |
8107bf131b | ||
![]() |
0220f46741 | ||
![]() |
e4ad517cb1 | ||
![]() |
792151a8b7 | ||
![]() |
fb67b2f3d1 | ||
![]() |
30c1f07207 | ||
![]() |
562a4554f3 | ||
![]() |
9f22b63227 | ||
![]() |
c96e7a284a | ||
![]() |
dbcd696936 | ||
![]() |
79368aa6dd | ||
![]() |
d661c893d5 | ||
![]() |
ca99404b42 | ||
![]() |
aec03840cc | ||
![]() |
5630eb14c2 | ||
![]() |
6680b0adb2 | ||
![]() |
ff0d881273 | ||
![]() |
ed5d0ea474 | ||
![]() |
997a3ca31c | ||
![]() |
ef444730b7 | ||
![]() |
7bfc6077b9 | ||
![]() |
624bd5a2a4 | ||
![]() |
1e19f9aedf | ||
![]() |
1b4c5ace61 | ||
![]() |
28037e11df | ||
![]() |
036f21de81 | ||
![]() |
43adecaf99 | ||
![]() |
c58e4dccc0 | ||
![]() |
1a1f8b2235 | ||
![]() |
f1616f6532 | ||
![]() |
a42f5ab273 | ||
![]() |
f15139e907 | ||
![]() |
f4399d441d | ||
![]() |
fd4b49e0d5 | ||
![]() |
496a276524 | ||
![]() |
c831df74d0 | ||
![]() |
e77d53fd41 | ||
![]() |
983aff2091 | ||
![]() |
570bc83a6d | ||
![]() |
8dca8bbe65 | ||
![]() |
0e91b47dba | ||
![]() |
3f7e95b502 | ||
![]() |
4f30a47c07 | ||
![]() |
ecbbd6fbf2 | ||
![]() |
13f5648963 | ||
![]() |
dfb7314207 | ||
![]() |
9293801037 | ||
![]() |
d8ac3b2353 | ||
![]() |
056f0e5614 | ||
![]() |
ada5418413 | ||
![]() |
b79e970e66 | ||
![]() |
6fc02edd1e | ||
![]() |
9a8c03106e | ||
![]() |
4a5e41b747 | ||
![]() |
649dcf4019 | ||
![]() |
ae3d1262f5 | ||
![]() |
7b2b0edbdf | ||
![]() |
353746ec04 | ||
![]() |
2fb9b4173a | ||
![]() |
fe7242f36f | ||
![]() |
8015f8486c | ||
![]() |
92d7f8f578 | ||
![]() |
fc9a9f8e09 | ||
![]() |
f94bfc2850 | ||
![]() |
db283fad15 | ||
![]() |
dd7288b787 | ||
![]() |
a6e41b2a90 | ||
![]() |
0e6ac14b74 | ||
![]() |
97f380fb7b | ||
![]() |
3e5b29c84d | ||
![]() |
5d19cc7cf1 | ||
![]() |
19995eba1a | ||
![]() |
990ed0f6bf | ||
![]() |
dc0a085d86 | ||
![]() |
0a852c49e8 | ||
![]() |
59588517d8 | ||
![]() |
3a7cbe48b8 | ||
![]() |
ed298cdfb0 | ||
![]() |
3925c34610 | ||
![]() |
a6fa112050 | ||
![]() |
d97a6a52a4 | ||
![]() |
121846eeae | ||
![]() |
ebef1edc09 | ||
![]() |
bbaf1384ba | ||
![]() |
7036a4da81 | ||
![]() |
91ceb0aa22 | ||
![]() |
de12327ac2 | ||
![]() |
6f65b54883 | ||
![]() |
c0ffd7e641 | ||
![]() |
b0c1ccf9b4 | ||
![]() |
ed3e1aa846 | ||
![]() |
7f720a1753 | ||
![]() |
6cbcbc6f3f | ||
![]() |
53ae9bc42d | ||
![]() |
9813d6946a | ||
![]() |
c7651c9949 | ||
![]() |
34211c4b3f | ||
![]() |
8bc4c247e6 | ||
![]() |
92406a051a | ||
![]() |
56f7578d13 | ||
![]() |
068b074de0 | ||
![]() |
bb0ee3b861 | ||
![]() |
93bb11c135 | ||
![]() |
2fd8c17525 | ||
![]() |
b974487fc4 | ||
![]() |
8198243425 | ||
![]() |
b4addcc125 | ||
![]() |
2d7893b9de | ||
![]() |
60c0ae1049 | ||
![]() |
aaabfa2d01 | ||
![]() |
5c8a1f3677 | ||
![]() |
b37cd74e56 | ||
![]() |
af9a31f4ad | ||
![]() |
7d8838c0ee | ||
![]() |
2c47cfd60e | ||
![]() |
6422f7c576 | ||
![]() |
369a3217f7 | ||
![]() |
f44bf935d3 | ||
![]() |
0e43eee2f3 | ||
![]() |
c6121ab590 | ||
![]() |
72ceeffdad | ||
![]() |
5eb6e9990c | ||
![]() |
3d3769cf5a | ||
![]() |
2a64151f67 | ||
![]() |
34616607a8 | ||
![]() |
796feb05e6 | ||
![]() |
14ae58ca0c | ||
![]() |
b555f46f56 | ||
![]() |
dc5e7e4cb0 | ||
![]() |
deb0b202bf | ||
![]() |
0a5a70f583 | ||
![]() |
f16e825b57 | ||
![]() |
263a8229fa | ||
![]() |
dc7a27a5e3 | ||
![]() |
651865f28a | ||
![]() |
27493d3b23 | ||
![]() |
295bbd62b8 | ||
![]() |
5cf3ae1203 | ||
![]() |
c650e190fb | ||
![]() |
5cd5873ec3 | ||
![]() |
42a66b04c5 | ||
![]() |
a237185e4c | ||
![]() |
df225a3d2f | ||
![]() |
8c59098c28 | ||
![]() |
bbd45df54d | ||
![]() |
8aa0ccd437 | ||
![]() |
74cdd9d055 | ||
![]() |
704f202ce8 | ||
![]() |
fb3082094a | ||
![]() |
7a71cbf756 | ||
![]() |
53c279fa00 | ||
![]() |
8dc542a31c | ||
![]() |
4dee127ce8 | ||
![]() |
3e341e02c8 | ||
![]() |
a673848089 | ||
![]() |
642186678e | ||
![]() |
e37357aea5 | ||
![]() |
967d8ce068 | ||
![]() |
2bb3aa84a7 | ||
![]() |
82ddd3942b | ||
![]() |
ac672092f1 | ||
![]() |
1c6eec61af | ||
![]() |
dda7864c1a | ||
![]() |
ddc13cccec | ||
![]() |
95ac2392e8 | ||
![]() |
0122f9e989 | ||
![]() |
f265f7e773 | ||
![]() |
61307ce584 | ||
![]() |
8f755a5cfc | ||
![]() |
c3addd05f7 | ||
![]() |
bbcfc9fb07 | ||
![]() |
63ac99f97a | ||
![]() |
6d29bce267 | ||
![]() |
6b039288d5 | ||
![]() |
3f803b8107 | ||
![]() |
814a9def7f | ||
![]() |
8c7891809e | ||
![]() |
30729049b3 | ||
![]() |
1a0f80dce7 | ||
![]() |
6973bc8e7d | ||
![]() |
ae3edd67da | ||
![]() |
b66db19c0a | ||
![]() |
36b931f680 | ||
![]() |
9c63054926 | ||
![]() |
276a4522d6 | ||
![]() |
4e2e58bb4c | ||
![]() |
8b7a07ffe7 | ||
![]() |
ffc6a60ee9 | ||
![]() |
f990d27851 | ||
![]() |
fa1a968b8f | ||
![]() |
3d8bf78213 | ||
![]() |
90479dfea2 | ||
![]() |
471912759a | ||
![]() |
844d4be96a | ||
![]() |
0b76ded5aa | ||
![]() |
76aa95588e | ||
![]() |
6618752b84 | ||
![]() |
af5f39af44 | ||
![]() |
03ef57daeb | ||
![]() |
a059d18195 | ||
![]() |
9f610d5ae8 | ||
![]() |
c9adb2a212 | ||
![]() |
7fd814d595 | ||
![]() |
e7065a7159 | ||
![]() |
8625db7ae4 | ||
![]() |
68e6774e26 | ||
![]() |
a7c6ae7382 | ||
![]() |
9c06049628 | ||
![]() |
34e5f4df49 | ||
![]() |
b7b58f5870 | ||
![]() |
f9d75856d1 | ||
![]() |
66b7adf485 | ||
![]() |
76637b130c | ||
![]() |
9a1a31c424 | ||
![]() |
faef000245 | ||
![]() |
c2035668cd | ||
![]() |
f1201c6259 | ||
![]() |
bdaa674662 | ||
![]() |
3b17eb4750 | ||
![]() |
9221d412ca | ||
![]() |
65bb71aabf | ||
![]() |
dcd0fa86b9 | ||
![]() |
72be1b8dbf | ||
![]() |
1d7b642c50 | ||
![]() |
f7d45ca338 | ||
![]() |
831722dd84 | ||
![]() |
ee3dd0b5bd | ||
![]() |
7480847677 | ||
![]() |
0ff715af1b | ||
a318aa87cf | |||
![]() |
74b00d3ab1 | ||
![]() |
355375e9db | ||
![]() |
016203d2bc | ||
![]() |
b65efa2968 | ||
![]() |
4fc5f10bad | ||
![]() |
f8e9d68ceb | ||
![]() |
65e8d62391 | ||
![]() |
93fa82201a | ||
![]() |
71930182dd | ||
![]() |
8764540d3b | ||
![]() |
6a6676c1cb | ||
![]() |
5bf91f1891 | ||
![]() |
14e16a959f | ||
![]() |
3b72724966 | ||
![]() |
9a0e7809cd | ||
![]() |
94c25a70b3 | ||
![]() |
4901120be4 | ||
![]() |
21e45b5e45 | ||
![]() |
b829e90edb | ||
![]() |
fbf7fa6176 | ||
![]() |
2b413ef609 | ||
![]() |
0f06ee5688 | ||
![]() |
ec065ec329 | ||
![]() |
c9a5472282 | ||
![]() |
b12199c65b | ||
![]() |
b4ac097910 | ||
![]() |
aae4ec97a9 | ||
![]() |
45d931b351 | ||
![]() |
f53c9660fe | ||
![]() |
c889854818 | ||
![]() |
b8b0a0fcce | ||
![]() |
b3f9d7e5c7 | ||
![]() |
94b457d9c0 | ||
![]() |
0c58655708 | ||
![]() |
ba98e0a15a | ||
![]() |
5496ad1198 | ||
![]() |
7bad6149b5 | ||
![]() |
378905268d | ||
![]() |
f56a700fea | ||
![]() |
736176ce27 | ||
![]() |
96d749c512 | ||
![]() |
17514c89ad | ||
![]() |
8b08f2b747 | ||
![]() |
07bb0fc4cf | ||
![]() |
dbea9d83f4 | ||
![]() |
8989ae94a7 | ||
![]() |
4db83e6f65 | ||
![]() |
9286f2e559 | ||
![]() |
045a572058 | ||
![]() |
f68be8e4c9 | ||
![]() |
ec4572c390 | ||
![]() |
b89b61496b | ||
![]() |
63f504feb7 | ||
![]() |
06eca83ff9 | ||
![]() |
ebc8b7a7fd | ||
![]() |
4c34a653bd | ||
![]() |
38d2f1b62e | ||
![]() |
d8915d1893 | ||
![]() |
873acfcb4f | ||
![]() |
030df5029b | ||
![]() |
7404b6bd2d | ||
![]() |
b9e9be227a | ||
![]() |
f2537706e7 | ||
![]() |
a8251d9385 | ||
![]() |
b1edd62c0b | ||
![]() |
c1e315fa40 | ||
![]() |
bfcf96f1ad | ||
![]() |
d257e9e1e8 | ||
![]() |
85e307f8db | ||
![]() |
03fa0a73b6 | ||
![]() |
2f157a6438 | ||
![]() |
cdde72cbe0 | ||
![]() |
b18420ad55 | ||
![]() |
d92daccdbf | ||
![]() |
6b3cc6c421 | ||
![]() |
18af85c4d7 | ||
![]() |
6c6ff18ec3 | ||
![]() |
67e663f023 | ||
![]() |
3f717b304a | ||
![]() |
300af03012 | ||
![]() |
3d8d333f10 | ||
![]() |
d87cc7f1e7 | ||
![]() |
d59ef20f72 | ||
![]() |
b2bf0229ed | ||
![]() |
f03bfd2d7a | ||
![]() |
3dd646d6e9 | ||
![]() |
58ad553b39 | ||
![]() |
83056bacf4 | ||
![]() |
2751eaf399 | ||
![]() |
869ba0d33c | ||
![]() |
aeb29d9a69 | ||
![]() |
979d5914a9 | ||
![]() |
e72f5b7c37 | ||
![]() |
42d3324fc1 | ||
![]() |
e242ed6f1f | ||
![]() |
a2acb9c11c | ||
![]() |
444da941c9 | ||
![]() |
f19fd84f1d | ||
![]() |
b5793d36a8 | ||
![]() |
a71c03124b | ||
![]() |
66c484796d | ||
![]() |
a4927030d7 | ||
![]() |
c32badb750 | ||
![]() |
356eb849f2 | ||
![]() |
04e949ed0c | ||
![]() |
13dc8622c9 | ||
![]() |
a2b9c4724d | ||
![]() |
f326e569a1 | ||
![]() |
c1961dee5f | ||
![]() |
e42a231553 | ||
![]() |
b3d9a64632 | ||
![]() |
47c7c37fa9 | ||
![]() |
17413f81ff | ||
![]() |
725e555733 | ||
![]() |
6e7456605d | ||
![]() |
b652181dda | ||
![]() |
6764d80534 | ||
![]() |
6fbc06081e | ||
![]() |
0328876d50 | ||
![]() |
c5e1dd7c3a | ||
![]() |
714824df97 | ||
![]() |
2cb921087f | ||
![]() |
1ed3144428 | ||
![]() |
ba8fa01ce5 | ||
![]() |
3f6f077833 | ||
![]() |
74d9999202 | ||
![]() |
1be1c938cc | ||
![]() |
930f1d43e0 | ||
![]() |
1e04053026 | ||
![]() |
1e6b3faff8 | ||
![]() |
e6928b6ab1 | ||
![]() |
eb97d0d479 | ||
![]() |
0a75d57cf9 | ||
![]() |
383c9b9a33 | ||
![]() |
d2adbecc44 | ||
![]() |
834395bdc3 | ||
![]() |
18dad5bedf | ||
![]() |
c188367749 | ||
![]() |
5b098c68aa | ||
![]() |
22bd56652d | ||
![]() |
d07caea0f6 | ||
![]() |
897f75c069 | ||
![]() |
8167e04383 | ||
![]() |
72b6d0e7bb | ||
![]() |
039c5d9244 | ||
![]() |
7ea982c903 | ||
![]() |
f0adeddb66 | ||
![]() |
e709b6c321 | ||
![]() |
1b0dcc9808 | ||
![]() |
fe5dfa0ea7 | ||
![]() |
25e6f27854 | ||
![]() |
c07a01a427 | ||
![]() |
11bc7cb60c | ||
![]() |
6e3b7e7a04 | ||
![]() |
ff58cf5b19 | ||
![]() |
25a708a3d4 | ||
![]() |
004dcc19dc | ||
![]() |
ac95f5f89c | ||
![]() |
0fc9b49fba | ||
![]() |
600e73ad43 | ||
![]() |
0bc0b0dc77 | ||
![]() |
86f62e1f37 | ||
![]() |
7850b8368a | ||
![]() |
496bde733f | ||
![]() |
8b98deafca | ||
![]() |
b3ab0cbd74 | ||
![]() |
462eb77e0d | ||
![]() |
d5702d3065 | ||
![]() |
c8377b318e | ||
![]() |
6814a833be | ||
![]() |
98aae10126 | ||
![]() |
0558675132 | ||
![]() |
c8f42e8a48 | ||
![]() |
d30d16b855 | ||
![]() |
178957642c | ||
![]() |
cd77fe74d5 | ||
![]() |
90c91c3ebc | ||
![]() |
11dbf83faf | ||
![]() |
b7fa57c9b7 | ||
![]() |
7a63527d8f | ||
![]() |
4b33bedccd | ||
![]() |
473637ceaf | ||
![]() |
6f5142393b | ||
![]() |
fdc20d4e9d | ||
![]() |
4d0dcede41 | ||
![]() |
4ed262a330 | ||
![]() |
48f0f81f12 | ||
![]() |
7b9f2d680a | ||
![]() |
c69537b173 | ||
![]() |
794a4a23d3 | ||
![]() |
998ff6a13a | ||
![]() |
4ff4a60106 | ||
![]() |
eaaca5b003 | ||
![]() |
388b4731c7 | ||
![]() |
f285d67c87 | ||
![]() |
bc1a612a20 | ||
![]() |
b67879577d | ||
![]() |
2b5b9d44e6 | ||
![]() |
3e48638d8c | ||
![]() |
3307d2d23d | ||
![]() |
62d73cbf96 | ||
![]() |
2004f71290 | ||
![]() |
013dc43c2f | ||
![]() |
716e6cbc04 | ||
![]() |
9e81b6316f | ||
![]() |
d709bf68dd | ||
![]() |
c14b8ed23a | ||
![]() |
7ba6fb5a2e | ||
![]() |
4f1a03811a | ||
![]() |
0946d5a138 | ||
![]() |
6f650c8bbd | ||
![]() |
ad1502e998 | ||
![]() |
bb42dd026c | ||
![]() |
95b6c9dfe5 | ||
![]() |
9b1754a431 | ||
![]() |
0574d59e12 | ||
![]() |
4f7c35dfcf | ||
![]() |
967384ccfe | ||
![]() |
b906a32e23 | ||
![]() |
9b9a4c5ee1 | ||
![]() |
13f3e7ee11 | ||
![]() |
b7f2a62b3c | ||
![]() |
1f4197ce67 | ||
![]() |
f377d044d6 | ||
![]() |
205dd1a201 | ||
![]() |
9c505c4f5d | ||
![]() |
eb7f7f4244 | ||
![]() |
f1fc49d276 | ||
![]() |
d8e2072493 | ||
![]() |
96f813a17b | ||
![]() |
a97542e649 | ||
![]() |
5eceb21ec7 | ||
![]() |
a61b646295 | ||
![]() |
373c476d2d | ||
![]() |
b1145c8926 | ||
![]() |
0810e76474 | ||
![]() |
57acb274c6 | ||
![]() |
e57f885d3b | ||
![]() |
0073e101dd | ||
![]() |
b42d43c0e1 | ||
![]() |
9d8988a2ec | ||
![]() |
aa784c121b | ||
![]() |
a36e8a4065 | ||
![]() |
3fd7b66905 | ||
![]() |
44ebcc5d25 | ||
![]() |
9a68ed6bd0 | ||
![]() |
4f84cd8963 | ||
![]() |
837b56462f | ||
![]() |
9c3a22c556 | ||
![]() |
9471d83a45 | ||
![]() |
52b225d944 | ||
![]() |
c8f0a61209 | ||
![]() |
59c3e9eb54 | ||
![]() |
d20d68b831 | ||
![]() |
cfda1f8eef | ||
![]() |
2fb222125a | ||
![]() |
c7c3c00783 | ||
![]() |
dcc130e2cf | ||
![]() |
491f3d3af4 | ||
![]() |
140000df55 | ||
![]() |
4b2fee7614 | ||
![]() |
2c7b522378 | ||
![]() |
d9ef60d4e8 | ||
![]() |
178fcb8164 | ||
![]() |
3d6806b63a | ||
![]() |
22e3019610 | ||
![]() |
7937cbd122 | ||
![]() |
2bef34ee5b | ||
![]() |
efe7236d31 | ||
![]() |
67dba9c820 | ||
![]() |
52c509aba0 | ||
![]() |
437c7d293e | ||
![]() |
2b6ce4f25b | ||
![]() |
64f123abe9 | ||
![]() |
599a98bceb | ||
![]() |
2cd1b8bd4e | ||
![]() |
c0be9c25da | ||
![]() |
5cea66374f | ||
![]() |
ee1c270c68 | ||
![]() |
4ab08e2faf | ||
![]() |
dd094edb88 | ||
![]() |
56e45236d8 | ||
![]() |
be9a8c5839 | ||
![]() |
8c11baf3b9 | ||
![]() |
6ce679bd83 | ||
![]() |
a4b1b9bb96 | ||
![]() |
91ad78e6a2 | ||
![]() |
4a68d66ab0 | ||
![]() |
4cb50b556f | ||
![]() |
b5f73a99cc | ||
![]() |
e9476a59e8 | ||
![]() |
f48f23c2eb | ||
![]() |
ddf465d8c9 | ||
![]() |
7149287b8e | ||
![]() |
cc709c6bb3 | ||
![]() |
8d101c4c11 | ||
![]() |
64eef6cd8e | ||
![]() |
f8ae3c0dd1 | ||
![]() |
589205edc3 | ||
![]() |
48b212faaf | ||
![]() |
0554dbc608 | ||
![]() |
3564eb805c | ||
![]() |
62a8064edd | ||
![]() |
55ed45190b | ||
![]() |
a6ae96093f | ||
![]() |
5b1afe6d50 | ||
![]() |
60df71a74c | ||
![]() |
a6d5da861f | ||
![]() |
afc10911f7 | ||
![]() |
0686e95c72 | ||
![]() |
234754fd49 | ||
![]() |
efb8d0f226 | ||
![]() |
3f881f7d67 | ||
![]() |
64d38abc99 | ||
![]() |
4a39362702 | ||
![]() |
db2d3794ae | ||
![]() |
526ff6fff0 | ||
![]() |
eebc0e428e | ||
![]() |
80aca514b2 | ||
![]() |
3e8068e82d | ||
![]() |
601fbcd176 | ||
![]() |
40eab15d69 | ||
![]() |
ceb272c0b4 | ||
![]() |
80d4f62694 | ||
![]() |
42f58a8649 | ||
![]() |
6b9af71967 | ||
![]() |
dbd98a09c5 | ||
![]() |
c6a6363163 | ||
![]() |
82815f66e5 | ||
![]() |
0a38eb770d | ||
![]() |
97da740e7e | ||
![]() |
42bb24ca6a | ||
![]() |
2f3b6cdda7 | ||
![]() |
525b496774 | ||
![]() |
562bb77dda | ||
![]() |
76a13dc53a | ||
![]() |
df0f8072a9 | ||
![]() |
87d9825c91 | ||
![]() |
3dba4f744f | ||
![]() |
1fcfe6fb5f | ||
![]() |
3ece4baba6 | ||
![]() |
f49dae2cbf | ||
![]() |
ddf15d756a | ||
![]() |
96d1faddbe | ||
![]() |
17ee96038c | ||
![]() |
e9b432288e | ||
![]() |
b814d1210b | ||
![]() |
c137fb4953 | ||
![]() |
4acce1c9c9 | ||
![]() |
8ab16c3d30 | ||
![]() |
7373dd37a6 | ||
![]() |
1251b945bc | ||
![]() |
79fe6a08ab | ||
![]() |
5e0f69e0e6 |
117
.github/workflows/release.yaml
vendored
Normal file
117
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILD_CONFIGURATION: Release
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
get-version:
|
||||||
|
name: Get Version
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.version.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
name: Checkout
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Git Version
|
||||||
|
id: version
|
||||||
|
uses: codacy/git-version@2.7.1
|
||||||
|
|
||||||
|
build-nuget:
|
||||||
|
name: Build and Publish Nuget
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [get-version]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
name: Checkout
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
name: Setup dotnet
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x'
|
||||||
|
|
||||||
|
- name: Restore dependencies
|
||||||
|
run: dotnet restore Torch.Server/Torch.Server.csproj --locked-mode
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build Torch.Server/Torch.Server.csproj --no-restore -c ${{ env.BUILD_CONFIGURATION }} -p:Version="${{ needs.get-version.outputs.version }}" -p:AssemblyVersion="${{ needs.get-version.outputs.version }}"
|
||||||
|
|
||||||
|
- run: dotnet pack -c Release ./Torch.API/Torch.API.csproj -o pack -p:Version="${{ needs.get-version.outputs.version }}" -p:AssemblyVersion="${{ needs.get-version.outputs.version }}" --no-build
|
||||||
|
- run: dotnet pack -c Release ./Torch/Torch.csproj -o pack -p:Version="${{ needs.get-version.outputs.version }}" -p:AssemblyVersion="${{ needs.get-version.outputs.version }}" --no-build
|
||||||
|
- run: dotnet pack -c Release ./Torch.Server/Torch.Server.csproj -o pack -p:Version="${{ needs.get-version.outputs.version }}" -p:AssemblyVersion="${{ needs.get-version.outputs.version }}" --no-build
|
||||||
|
- run: mkdir blank && sed -i 's/torchVersion/${{ needs.get-version.outputs.version }}/g' Torch.Server.ReferenceAssemblies.net7.nuspec && nuget pack Torch.Server.ReferenceAssemblies.net7.nuspec -BasePath ./blank -OutputDirectory pack -NonInteractive -NoPackageAnalysis
|
||||||
|
|
||||||
|
- name: Install Sleet
|
||||||
|
run: dotnet tool install -g sleet
|
||||||
|
- name: Push Nuget Package
|
||||||
|
env:
|
||||||
|
SLEET_FEED_TYPE: s3
|
||||||
|
SLEET_FEED_PATH: https://nuget.storage.yandexcloud.net
|
||||||
|
SLEET_FEED_BUCKETNAME: nuget
|
||||||
|
SLEET_FEED_SERVICEURL: https://storage.yandexcloud.net
|
||||||
|
SLEET_FEED_ACCESSKEYID: ${{ secrets.S3_KEY_ID }}
|
||||||
|
SLEET_FEED_SECRETACCESSKEY: ${{ secrets.S3_KEY }}
|
||||||
|
run: sleet push ./pack
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build and Publish Package
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: [get-version]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
name: Checkout
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
name: Setup dotnet
|
||||||
|
with:
|
||||||
|
dotnet-version: '8.0.x'
|
||||||
|
|
||||||
|
- name: Restore dependencies
|
||||||
|
run: dotnet restore Torch.Server/Torch.Server.csproj --locked-mode
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build Torch.Server/Torch.Server.csproj --no-restore -c ${{ env.BUILD_CONFIGURATION }} -p:Version="${{ needs.get-version.outputs.version }}" -p:AssemblyVersion="${{ needs.get-version.outputs.version }}"
|
||||||
|
- name: Publish
|
||||||
|
run: dotnet publish Torch.Server/Torch.Server.csproj --no-build --sc -c ${{ env.BUILD_CONFIGURATION }} -o ./publish
|
||||||
|
|
||||||
|
- uses: vimtor/action-zip@v1
|
||||||
|
name: Zip Release
|
||||||
|
with:
|
||||||
|
files: publish/
|
||||||
|
dest: release.zip
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
id: create_release
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: ${{ needs.get-version.outputs.version }}
|
||||||
|
release_name: Release v${{ needs.get-version.outputs.version }}
|
||||||
|
body: ${{ steps.github_release.outputs.changelog }}
|
||||||
|
draft: true
|
||||||
|
prerelease: false
|
||||||
|
|
||||||
|
- name: Upload release asset
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: release.zip
|
||||||
|
asset_name: torch-server.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
|
|
||||||
|
- uses: eregon/publish-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
release_id: ${{ steps.create_release.outputs.id }}
|
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,6 +1,9 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
#Rider directory
|
||||||
|
.idea/
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
@@ -156,10 +159,6 @@ publish/
|
|||||||
|
|
||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
*.nupkg
|
*.nupkg
|
||||||
# The packages folder can be ignored because of Package Restore
|
|
||||||
**/packages/*
|
|
||||||
# except build/, which is used as an MSBuild target.
|
|
||||||
!**/packages/build/
|
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
#!**/packages/repositories.config
|
#!**/packages/repositories.config
|
||||||
# NuGet v3's project.json files produces more ignoreable files
|
# NuGet v3's project.json files produces more ignoreable files
|
||||||
@@ -252,3 +251,6 @@ ModelManifest.xml
|
|||||||
# FAKE - F# Make
|
# FAKE - F# Make
|
||||||
.fake/
|
.fake/
|
||||||
GameBinaries
|
GameBinaries
|
||||||
|
|
||||||
|
# Generated Files
|
||||||
|
**Gen.cs
|
||||||
|
26
CONTRIBUTING.md
Normal file
26
CONTRIBUTING.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Making a Pull Request
|
||||||
|
* Fork this repository and make sure your local **staging** branch is up to date with the main repository.
|
||||||
|
* Create a new branch from the **staging** branch for your addition with an appropriate name, e.g. **add-restart-command**
|
||||||
|
* PRs work by submitting the *entire* branch, so this allows you to continue work without locking up your whole repository.
|
||||||
|
* Commit your changes to that branch, making sure that you **follow the code guidelines below**.
|
||||||
|
* Submit your branch as a PR to be reviewed, with Torch's **staging** branch as the base.
|
||||||
|
|
||||||
|
## Naming Conventions
|
||||||
|
* Types: **PascalCase**
|
||||||
|
* Prefix interfaces with "**I**"
|
||||||
|
* Suffix delegates with "**Del**"
|
||||||
|
* Methods: **PascalCase**
|
||||||
|
* Method names should generally use verbs in the infinitive tense, for example `GetValue()` or `OpenFile()`. Callbacks and events should use present continuous (-ing) or past tense depending on the context.
|
||||||
|
* Non-Private Members: **PascalCase**
|
||||||
|
* Private Members: **_camelCase**
|
||||||
|
|
||||||
|
## Code Design
|
||||||
|
* **One type per file** with the exception of nested types and delegate declarations.
|
||||||
|
* **No public fields** except for consts, use properties instead
|
||||||
|
* **No stateful static types.** These are a pain to clean up, static types should not store any information.
|
||||||
|
* Use **[dependency injection](https://stackoverflow.com/a/130862)** when possible. Most Torch code uses constructor injection.
|
||||||
|
* **Events and actions** should be null checked before calling or invoked with the `action?.Invoke()` syntax.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
* All types and members not marked **private** or **internal** should have XML documentation using the `/// <summary>` tag.
|
||||||
|
* Interface implementations and overridden methods should use the `/// <inheritdoc />` tag unless the summary needs to be changed from the base/interface summary.
|
9
Directory.Build.props
Normal file
9
Directory.Build.props
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0-windows</TargetFramework>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||||
|
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||||
|
<RuntimeFrameworkVersion>7.0.4</RuntimeFrameworkVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
26
NLog.config
26
NLog.config
@@ -1,15 +1,31 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<variable name="logStamp" value="${time} ${pad:padding=-8:inner=[${level:uppercase=true}]}" />
|
||||||
|
<variable name="logContent" value="${message:withException=true}"/>
|
||||||
|
|
||||||
<targets>
|
<targets>
|
||||||
<target name="logfile" layout="${longdate} [${level:uppercase=true}] ${logger}: ${message}" xsi:type="File" fileName="Torch.log" deleteOldFileOnStartup="true"/>
|
<default-wrapper xsi:type="AsyncWrapper" overflowAction="Block" optimizeBufferReuse="true" />
|
||||||
<target name="console" layout="${longdate} [${level:uppercase=true}] ${logger}: ${message}" xsi:type="ColoredConsole" />
|
<target xsi:type="Null" name="null" formatMessage="false" />
|
||||||
|
<target xsi:type="File" keepFileOpen="true" concurrentWrites="false" name="keen" layout="${var:logStamp} ${logger}: ${var:logContent}"
|
||||||
|
fileName="Logs\Keen-${shortdate}.log" />
|
||||||
|
<target xsi:type="File" keepFileOpen="true" concurrentWrites="false" name="main" layout="${var:logStamp} ${logger}: ${var:logContent}"
|
||||||
|
fileName="Logs\Torch-${shortdate}.log" />
|
||||||
|
<target xsi:type="File" name="chat" layout="${longdate} ${message}" fileName="Logs\Chat.log" />
|
||||||
|
<target xsi:type="ColoredConsole" name="console" layout="${var:logStamp} ${logger:shortName=true}: ${var:logContent}" />
|
||||||
|
<target xsi:type="File" name="patch" layout="${var:logContent}" fileName="Logs\patch.log"/>
|
||||||
|
<target xsi:type="LogViewerTarget" name="wpf" layout="[${level:uppercase=true}] ${logger:shortName=true}: ${var:logContent}" />
|
||||||
</targets>
|
</targets>
|
||||||
|
|
||||||
<rules>
|
<rules>
|
||||||
<logger name="*" minlevel="Info" writeTo="logfile" />
|
<!-- Do not define custom rules here. Use NLog-user.config -->
|
||||||
<logger name="*" minlevel="Info" writeTo="console" />
|
<logger name="Keen" minlevel="Warn" writeTo="main"/>
|
||||||
</rules>
|
<logger name="Keen" minlevel="Info" writeTo="console, wpf"/>
|
||||||
|
<logger name="Keen" minlevel="Debug" writeTo="keen" final="true" />
|
||||||
|
<logger name="Keen" writeTo="null" final="true" />
|
||||||
|
|
||||||
|
<logger name="*" minlevel="Info" writeTo="main, console, wpf" />
|
||||||
|
<logger name="Chat" minlevel="Info" writeTo="chat" />
|
||||||
|
<!--<logger name="Torch.Managers.PatchManager.*" minlevel="Trace" writeTo="patch"/>-->
|
||||||
|
</rules>
|
||||||
</nlog>
|
</nlog>
|
42
README.md
42
README.md
@@ -1,32 +1,36 @@
|
|||||||
Discord: [](https://discord.gg/8uHZykr)
|
|
||||||
|
|
||||||
# What is Torch?
|
# What is Torch?
|
||||||
Torch is the successor to SE Server Extender and gives server admins the tools they need to keep their Space Engineers servers running smoothly. It features a user interface with live management tools and a plugin system so you can run your server exactly how you'd like. Torch is still in early development so there may be bugs and incomplete features.
|
Torch is the successor to SE Server Extender and gives server admins the tools they need to keep their Space Engineers servers running smoothly. It features a user interface with live management tools and a plugin system so you can run your server exactly how you'd like. Torch is still in early development so there may be bugs and incomplete features.
|
||||||
|
|
||||||
# Features
|
## Torch.Server
|
||||||
|
|
||||||
|
### Features
|
||||||
* WPF-based user interface
|
* WPF-based user interface
|
||||||
* Chat: interact with the game chat and run commands without having to join the game.
|
* Chat: interact with the game chat and run commands without having to join the game.
|
||||||
* Entity manager: realtime modification of ingame entities such as stopping grids and changing block settings without having to join the game
|
* Entity manager: realtime modification of ingame entities such as stopping grids and changing block settings without having to join the game
|
||||||
* Organized, easy to use configuration editor
|
* Organized, easy to use configuration editor
|
||||||
* Extensible using the Torch plugin system
|
* Extensible using the Torch plugin system
|
||||||
|
|
||||||
|
### Fork Difference
|
||||||
|
* .NET 6.0 runtime
|
||||||
|
* Optimized in-game scripts (also newer compiler & language versions)
|
||||||
|
* Better configuration via cli arguments, environment variables or xml config
|
||||||
|
* Designed to run multiple instance from same install directory without having you to waste disk space
|
||||||
|
* Mostly compatible with original torch's plugins
|
||||||
|
|
||||||
|
### Discord
|
||||||
|
|
||||||
|
If you have any questions or issues please join our [discord](https://discord.gg/UyYFSe3TyQ)
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
* Unzip the Torch release into its own directory and run the executable. It will automatically download the SE DS and generate the other necessary files.
|
||||||
|
- If you already have a DS installed you can:
|
||||||
|
* Unzip the Torch files into the folder that contains the DedicatedServer64 folder.
|
||||||
|
* Pass path to game files using config parameter `gamePath`
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
To build Torch you must first have a complete SE Dedicated installation somewhere. Before you open the solution, run the Setup batch file and enter the path of that installation's DedicatedServer64 folder. The script will make a symlink to that folder so the Torch solution can find the DLL references it needs.
|
|
||||||
|
|
||||||
# Installation Guide
|
As a regular dotnet project with cli by running `dotnet build Torch.Server/Torch.Server.csproj`, with VS 2022 or higher, with JB Rider or Fleet.
|
||||||
Note: Until Torch is in a stable, nearly feature complete state there will not be any binaries available. You'll have to compile the solution yourself.
|
|
||||||
|
|
||||||
### Automatic (recommended)
|
If you have a more enjoyable server experience because of Torch, please consider supporting us on Patreon. (https://www.patreon.com/TorchSE)
|
||||||
* Unzip Torch to its own folder, run Torch.Server.exe and enter 'y' in the prompt for automatic updates. Torch will automatically download the Space Engineers files and generate all of the configs/folders necessary.
|
|
||||||
|
|
||||||
### Manual (for hosting companies or the paranoid)
|
|
||||||
* Install the Space Engineers DS and then unzip the Torch files into the server's DedicatedServer64 directory. It will automatically detect the manual install and disable automatic updates.
|
|
||||||
|
|
||||||
In both cases you will need to set the InstancePath in TorchConfig.xml to an existing dedicated server instance as Torch can't fully generate it on its own yet.
|
|
||||||
|
|
||||||
# Official Plugins
|
|
||||||
Install plugins by unzipping them into the 'Plugins' folder which should be in the same location as the Torch files. If it doesn't exist you can simply create it.
|
|
||||||
* [Essentials](https://github.com/TorchAPI/Essentials): Adds a slew of chat commands and other tools to help manage your server.
|
|
||||||
* [Concealment](https://github.com/TorchAPI/Concealment): Adds game logic and physics optimizations that significantly improve sim speed.
|
|
||||||
|
|
||||||
If you have a more enjoyable server experience because of Torch, please consider supporting us on [Patreon](https://www.patreon.com/bePatron?u=847269)!
|
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
:: This script creates a symlink to the game binaries to account for different installation directories on different systems.
|
|
||||||
|
|
||||||
@echo off
|
|
||||||
set /p path="Please enter the folder location of your SpaceEngineersDedicated.exe: "
|
|
||||||
cd %~dp0
|
|
||||||
mklink /D GameBinaries %path%
|
|
||||||
if errorlevel 1 goto Error
|
|
||||||
echo Done! You can now open the Torch solution without issue.
|
|
||||||
goto End
|
|
||||||
:Error
|
|
||||||
echo An error occured creating the symlink.
|
|
||||||
:End
|
|
||||||
pause
|
|
28
Torch.API/Event/EventHandlerAttribute.cs
Normal file
28
Torch.API/Event/EventHandlerAttribute.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Torch.API.Event
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute indicating that a method should be invoked when the event occurs.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class EventHandlerAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Events are executed from low priority to high priority.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// While this may seem unintuitive this gives the high priority events the final say on changing/canceling events.
|
||||||
|
/// </remarks>
|
||||||
|
public int Priority { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies if this handler should ignore a consumed event.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If <see cref="SkipCancelled"/> is <em>true</em> and the event is cancelled by a lower priority handler this handler won't be invoked.
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="IEvent.Cancelled"/>
|
||||||
|
public bool SkipCancelled { get; set; } = false;
|
||||||
|
}
|
||||||
|
}
|
11
Torch.API/Event/IEvent.cs
Normal file
11
Torch.API/Event/IEvent.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Torch.API.Event
|
||||||
|
{
|
||||||
|
public interface IEvent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An event that has been cancelled will no be processed in the default manner.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="EventHandlerAttribute.SkipCancelled"/>
|
||||||
|
bool Cancelled { get; }
|
||||||
|
}
|
||||||
|
}
|
9
Torch.API/Event/IEventHandler.cs
Normal file
9
Torch.API/Event/IEventHandler.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Torch.API.Event
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface used to tag an event handler. This does <b>not</b> register it with the event manager.
|
||||||
|
/// </summary>
|
||||||
|
public interface IEventHandler
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
28
Torch.API/Event/IEventManager.cs
Normal file
28
Torch.API/Event/IEventManager.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
|
||||||
|
namespace Torch.API.Event
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manager class responsible for registration of event handlers.
|
||||||
|
/// </summary>
|
||||||
|
public interface IEventManager : IManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers all event handler methods contained in the given instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">Instance to register</param>
|
||||||
|
/// <returns><b>true</b> if added, <b>false</b> otherwise</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
bool RegisterHandler(IEventHandler handler);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unregisters all event handler methods contained in the given instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">Instance to unregister</param>
|
||||||
|
/// <returns><b>true</b> if removed, <b>false</b> otherwise</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
bool UnregisterHandler(IEventHandler handler);
|
||||||
|
}
|
||||||
|
}
|
30
Torch.API/IApplicationContext.cs
Normal file
30
Torch.API/IApplicationContext.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.IO;
|
||||||
|
namespace Torch.API;
|
||||||
|
|
||||||
|
public interface IApplicationContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Directory contains torch binaries.
|
||||||
|
/// </summary>
|
||||||
|
public DirectoryInfo TorchDirectory { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Root directory for all game files.
|
||||||
|
/// </summary>
|
||||||
|
public DirectoryInfo GameFilesDirectory { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Directory contains game binaries.
|
||||||
|
/// </summary>
|
||||||
|
public DirectoryInfo GameBinariesDirectory { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Current instance directory.
|
||||||
|
/// </summary>
|
||||||
|
public DirectoryInfo InstanceDirectory { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Current instance name.
|
||||||
|
/// </summary>
|
||||||
|
public string InstanceName { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Application running in service mode.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsService { get; }
|
||||||
|
}
|
@@ -1,31 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Torch.API
|
|
||||||
{
|
|
||||||
public interface IChatMessage
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The time the message was created.
|
|
||||||
/// </summary>
|
|
||||||
DateTime Timestamp { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The SteamID of the message author.
|
|
||||||
/// </summary>
|
|
||||||
ulong SteamId { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The name of the message author.
|
|
||||||
/// </summary>
|
|
||||||
string Name { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The content of the message.
|
|
||||||
/// </summary>
|
|
||||||
string Message { get; }
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,39 +1,154 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Torch.API.Managers;
|
using Torch.API.Managers;
|
||||||
|
using Torch.API.Session;
|
||||||
using VRage.Game.ModAPI;
|
using VRage.Game.ModAPI;
|
||||||
|
using Version = SemanticVersioning.Version;
|
||||||
|
|
||||||
namespace Torch.API
|
namespace Torch.API
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API for Torch functions shared between client and server.
|
||||||
|
/// </summary>
|
||||||
public interface ITorchBase
|
public interface ITorchBase
|
||||||
{
|
{
|
||||||
event Action SessionLoading;
|
/// <summary>
|
||||||
event Action SessionLoaded;
|
/// Gets the currently running session instance, or null if none exists.
|
||||||
event Action SessionUnloading;
|
/// </summary>
|
||||||
event Action SessionUnloaded;
|
ITorchSession CurrentSession { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configuration for the current instance.
|
||||||
|
/// </summary>
|
||||||
ITorchConfig Config { get; }
|
ITorchConfig Config { get; }
|
||||||
IMultiplayerManager Multiplayer { get; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extended Configuration for the current instance.
|
||||||
|
/// </summary>
|
||||||
|
IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IPluginManager"/>
|
||||||
|
[Obsolete]
|
||||||
IPluginManager Plugins { get; }
|
IPluginManager Plugins { get; }
|
||||||
Version TorchVersion { get; }
|
|
||||||
void Invoke(Action action);
|
/// <inheritdoc cref="IDependencyManager"/>
|
||||||
void InvokeBlocking(Action action);
|
IDependencyManager Managers { get; }
|
||||||
Task InvokeAsync(Action action);
|
|
||||||
string[] RunArgs { get; set; }
|
[Obsolete("Prefer using Managers.GetManager for global managers")]
|
||||||
bool IsOnGameThread();
|
|
||||||
void Start();
|
|
||||||
void Stop();
|
|
||||||
void Init();
|
|
||||||
T GetManager<T>() where T : class, IManager;
|
T GetManager<T>() where T : class, IManager;
|
||||||
|
|
||||||
|
[Obsolete("Prefer using Managers.AddManager for global managers")]
|
||||||
|
bool AddManager<T>(T manager) where T : class, IManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The binary version of the current instance.
|
||||||
|
/// </summary>
|
||||||
|
Version TorchVersion { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Path of the dedicated instance folder.
|
||||||
|
/// </summary>
|
||||||
|
string InstancePath { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the dedicated instance.
|
||||||
|
/// </summary>
|
||||||
|
string InstanceName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke an action on the game thread.
|
||||||
|
/// </summary>
|
||||||
|
void Invoke(Action action, [CallerMemberName] string caller = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke an action on the game thread and block until it has completed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">Action to execute</param>
|
||||||
|
/// <param name="caller">Caller of the invoke function</param>
|
||||||
|
/// <param name="timeoutMs">Timeout before <see cref="TimeoutException"/> is thrown, or -1 to never timeout</param>
|
||||||
|
/// <exception cref="TimeoutException">If the action times out</exception>
|
||||||
|
void InvokeBlocking(Action action, int timeoutMs = -1, [CallerMemberName] string caller = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke an action on the game thread asynchronously.
|
||||||
|
/// </summary>
|
||||||
|
Task InvokeAsync(Action action, [CallerMemberName] string caller = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoke a function on the game thread asynchronously.
|
||||||
|
/// </summary>
|
||||||
|
Task<T> InvokeAsync<T>(Func<T> func, [CallerMemberName] string caller = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signals the torch instance to start, then blocks until it's started.
|
||||||
|
/// </summary>
|
||||||
|
void Start();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signals the torch instance to stop, then blocks until it's stopped.
|
||||||
|
/// </summary>
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restart the Torch instance, blocking until the restart has been performed.
|
||||||
|
/// </summary>
|
||||||
|
void Restart(bool save = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a save of the game.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeoutMs">timeout before the save is treated as failed, or -1 for no timeout</param>
|
||||||
|
/// <param name="exclusive">Only start saving if we aren't already saving</param>
|
||||||
|
/// <returns>Future result of the save, or null if one is in progress and in exclusive mode</returns>
|
||||||
|
Task<GameSaveResult> Save(int timeoutMs = -1, bool exclusive = false);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the Torch instance. Before this <see cref="Start"/> is invalid.
|
||||||
|
/// </summary>
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes the Torch instance. After this <see cref="Start"/> is invalid.
|
||||||
|
/// </summary>
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current state of the game this instance of torch is controlling.
|
||||||
|
/// </summary>
|
||||||
|
TorchGameState GameState { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event raised when <see cref="GameState"/> changes.
|
||||||
|
/// </summary>
|
||||||
|
event TorchGameStateChangedDel GameStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API for the Torch server.
|
||||||
|
/// </summary>
|
||||||
public interface ITorchServer : ITorchBase
|
public interface ITorchServer : ITorchBase
|
||||||
{
|
{
|
||||||
string InstancePath { get; }
|
/// <summary>
|
||||||
|
/// The current <see cref="ServerState"/>
|
||||||
|
/// </summary>
|
||||||
|
ServerState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the server's Init() method has completed.
|
||||||
|
/// </summary>
|
||||||
|
event Action<ITorchServer> Initialized;
|
||||||
|
|
||||||
|
TimeSpan ElapsedPlayTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API for the Torch client.
|
||||||
|
/// </summary>
|
||||||
public interface ITorchClient : ITorchBase
|
public interface ITorchClient : ITorchBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -1,13 +1,54 @@
|
|||||||
namespace Torch
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Torch.API;
|
||||||
|
|
||||||
|
namespace Torch
|
||||||
{
|
{
|
||||||
public interface ITorchConfig
|
public interface ITorchConfig
|
||||||
{
|
{
|
||||||
|
bool Autostart { get; set; }
|
||||||
|
bool ForceUpdate { get; set; }
|
||||||
|
bool GetPluginUpdates { get; set; }
|
||||||
|
bool GetTorchUpdates { get; set; }
|
||||||
|
[Obsolete("Use Torch.InstanceName instead")]
|
||||||
string InstanceName { get; set; }
|
string InstanceName { get; set; }
|
||||||
|
[Obsolete("Use Torch.InstancePath instead")]
|
||||||
string InstancePath { get; set; }
|
string InstancePath { get; set; }
|
||||||
bool RedownloadPlugins { get; set; }
|
bool NoGui { get; set; }
|
||||||
bool AutomaticUpdates { get; set; }
|
bool NoUpdate { get; set; }
|
||||||
|
List<Guid> Plugins { get; set; }
|
||||||
|
bool LocalPlugins { get; set; }
|
||||||
bool RestartOnCrash { get; set; }
|
bool RestartOnCrash { get; set; }
|
||||||
|
bool ShouldUpdatePlugins { get; }
|
||||||
|
bool ShouldUpdateTorch { get; }
|
||||||
|
int TickTimeout { get; set; }
|
||||||
|
string ChatName { get; set; }
|
||||||
|
string ChatColor { get; set; }
|
||||||
|
string TestPlugin { get; set; }
|
||||||
|
bool DisconnectOnRestart { get; set; }
|
||||||
|
int WindowWidth { get; set; }
|
||||||
|
int WindowHeight { get; set; }
|
||||||
|
int FontSize { get; set; }
|
||||||
|
UGCServiceType UgcServiceType { get; set; }
|
||||||
|
bool EntityManagerEnabled { get; set; }
|
||||||
|
string LoginToken { get; set; }
|
||||||
|
UpdateSource UpdateSource { get; set; }
|
||||||
|
List<string> Packages { get; set; }
|
||||||
|
|
||||||
bool Save(string path = null);
|
void Save(string path = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UpdateSource
|
||||||
|
{
|
||||||
|
public UpdateSourceType SourceType { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public string Repository { get; set; }
|
||||||
|
public string Branch { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UpdateSourceType
|
||||||
|
{
|
||||||
|
Github,
|
||||||
|
Jenkins
|
||||||
}
|
}
|
||||||
}
|
}
|
30
Torch.API/Managers/DependencyManagerExtensions.cs
Normal file
30
Torch.API/Managers/DependencyManagerExtensions.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
public static class DependencyManagerExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a single manager from this dependency manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="managerType">The dependency type to remove</param>
|
||||||
|
/// <returns>The manager that was removed, or null if one wasn't removed</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">When removing managers from an initialized dependency manager</exception>
|
||||||
|
public static IManager RemoveManager(this IDependencyManager depManager, Type managerType)
|
||||||
|
{
|
||||||
|
IManager mgr = depManager.GetManager(managerType);
|
||||||
|
return depManager.RemoveManager(mgr) ? mgr : null;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a single manager from this dependency manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The dependency type to remove</typeparam>
|
||||||
|
/// <returns>The manager that was removed, or null if one wasn't removed</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">When removing managers from an initialized dependency manager</exception>
|
||||||
|
public static IManager RemoveManager<T>(this IDependencyManager depManager)
|
||||||
|
{
|
||||||
|
return depManager.RemoveManager(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
15
Torch.API/Managers/DependencyProviderExtensions.cs
Normal file
15
Torch.API/Managers/DependencyProviderExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
public static class DependencyProviderExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the manager that provides the given type. If there is no such manager, returns null.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of manager</typeparam>
|
||||||
|
/// <returns>manager, or null if none exists</returns>
|
||||||
|
public static T GetManager<T>(this IDependencyProvider depProvider) where T : class, IManager
|
||||||
|
{
|
||||||
|
return (T)depProvider.GetManager(typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
171
Torch.API/Managers/IChatManagerClient.cs
Normal file
171
Torch.API/Managers/IChatManagerClient.cs
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sandbox.Engine.Multiplayer;
|
||||||
|
using Sandbox.Game.Gui;
|
||||||
|
using Sandbox.Game.Multiplayer;
|
||||||
|
using Torch.Utils;
|
||||||
|
using VRage.Game;
|
||||||
|
using VRage.Network;
|
||||||
|
using VRage.Replication;
|
||||||
|
using VRageMath;
|
||||||
|
using VRageRender;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a scripted or user chat message.
|
||||||
|
/// </summary>
|
||||||
|
public readonly struct TorchChatMessage
|
||||||
|
{
|
||||||
|
private const string DEFAULT_FONT = MyFontEnum.Blue;
|
||||||
|
|
||||||
|
#region Backwards compatibility
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
|
public TorchChatMessage(string author, string message, string font = DEFAULT_FONT)
|
||||||
|
: this(author, message, default, font) { }
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
|
public TorchChatMessage(string author, ulong authorSteamId, string message, ChatChannel channel, long target, string font = DEFAULT_FONT)
|
||||||
|
: this(author, authorSteamId, message, channel, target, default, font) { }
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
|
public TorchChatMessage(ulong authorSteamId, string message, ChatChannel channel, long target, string font = DEFAULT_FONT)
|
||||||
|
: this(authorSteamId, message, channel, target, default, font) { }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new torch chat message with the given author and message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="author">Author's name</param>
|
||||||
|
/// <param name="message">Message</param>
|
||||||
|
/// <param name="font">Font</param>
|
||||||
|
public TorchChatMessage(string author, string message, Color color, string font = DEFAULT_FONT)
|
||||||
|
{
|
||||||
|
Timestamp = DateTime.Now;
|
||||||
|
AuthorSteamId = null;
|
||||||
|
Author = author;
|
||||||
|
Message = message;
|
||||||
|
Channel = ChatChannel.Global;
|
||||||
|
Target = 0;
|
||||||
|
Font = font;
|
||||||
|
Color = color == default ? ColorUtils.TranslateColor(font) : color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new torch chat message with the given author and message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="author">Author's name</param>
|
||||||
|
/// <param name="authorSteamId">Author's steam ID</param>
|
||||||
|
/// <param name="message">Message</param>
|
||||||
|
/// <param name="font">Font</param>
|
||||||
|
public TorchChatMessage(string author, ulong authorSteamId, string message, ChatChannel channel, long target, Color color, string font = DEFAULT_FONT)
|
||||||
|
{
|
||||||
|
Timestamp = DateTime.Now;
|
||||||
|
AuthorSteamId = authorSteamId;
|
||||||
|
Author = author;
|
||||||
|
Message = message;
|
||||||
|
Channel = channel;
|
||||||
|
Target = target;
|
||||||
|
Font = font;
|
||||||
|
Color = color == default ? ColorUtils.TranslateColor(font) : color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new torch chat message with the given author and message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="authorSteamId">Author's steam ID</param>
|
||||||
|
/// <param name="message">Message</param>
|
||||||
|
/// <param name="font">Font</param>
|
||||||
|
public TorchChatMessage(ulong authorSteamId, string message, ChatChannel channel, long target, Color color, string font = DEFAULT_FONT)
|
||||||
|
{
|
||||||
|
Timestamp = DateTime.Now;
|
||||||
|
AuthorSteamId = authorSteamId;
|
||||||
|
Author = MyMultiplayer.Static?.GetMemberName(authorSteamId) ?? "Player";
|
||||||
|
Message = message;
|
||||||
|
Channel = channel;
|
||||||
|
Target = target;
|
||||||
|
Font = font;
|
||||||
|
Color = color == default ? ColorUtils.TranslateColor(font) : color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This message's timestamp.
|
||||||
|
/// </summary>
|
||||||
|
public readonly DateTime Timestamp;
|
||||||
|
/// <summary>
|
||||||
|
/// The author's steam ID, if available. Else, null.
|
||||||
|
/// </summary>
|
||||||
|
public readonly ulong? AuthorSteamId;
|
||||||
|
/// <summary>
|
||||||
|
/// The author's name, if available. Else, null.
|
||||||
|
/// </summary>
|
||||||
|
public readonly string Author;
|
||||||
|
/// <summary>
|
||||||
|
/// The message contents.
|
||||||
|
/// </summary>
|
||||||
|
public readonly string Message;
|
||||||
|
/// <summary>
|
||||||
|
/// The chat channel the message is part of.
|
||||||
|
/// </summary>
|
||||||
|
public readonly ChatChannel Channel;
|
||||||
|
/// <summary>
|
||||||
|
/// The intended recipient of the message.
|
||||||
|
/// </summary>
|
||||||
|
public readonly long Target;
|
||||||
|
/// <summary>
|
||||||
|
/// The font, or null if default.
|
||||||
|
/// </summary>
|
||||||
|
public readonly string Font;
|
||||||
|
/// <summary>
|
||||||
|
/// The chat message color.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Color Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback used to indicate that a messaage has been recieved.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <param name="consumed">If true, this event has been consumed and should be ignored</param>
|
||||||
|
public delegate void MessageRecievedDel(TorchChatMessage msg, ref bool consumed);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback used to indicate the user is attempting to send a message locally.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">Message the user is attempting to send</param>
|
||||||
|
/// <param name="consumed">If true, this event has been consumed and should be ignored</param>
|
||||||
|
public delegate void MessageSendingDel(string msg, ref bool consumed);
|
||||||
|
|
||||||
|
public interface IChatManagerClient : IManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when a message addressed to us is recieved. <see cref="MessageRecievedDel"/>
|
||||||
|
/// </summary>
|
||||||
|
event MessageRecievedDel MessageRecieved;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when we are attempting to send a message. <see cref="MessageSendingDel"/>
|
||||||
|
/// </summary>
|
||||||
|
event MessageSendingDel MessageSending;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers the <see cref="MessageSending"/> event,
|
||||||
|
/// typically raised by the user entering text into the chat window.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message to send</param>
|
||||||
|
void SendMessageAsSelf(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displays a message on the UI given an author name and a message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="author">Author name</param>
|
||||||
|
/// <param name="message">Message content</param>
|
||||||
|
/// <param name="font">font to use</param>
|
||||||
|
void DisplayMessageOnSelf(string author, string message, string font = "Blue" );
|
||||||
|
}
|
||||||
|
}
|
71
Torch.API/Managers/IChatManagerServer.cs
Normal file
71
Torch.API/Managers/IChatManagerServer.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VRage.Collections;
|
||||||
|
using VRage.Game;
|
||||||
|
using VRage.Network;
|
||||||
|
using VRageMath;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback used to indicate the server has recieved a message to process and forward on to others.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="authorId">Steam ID of the user sending a message</param>
|
||||||
|
/// <param name="msg">Message the user is attempting to send</param>
|
||||||
|
/// <param name="consumed">If true, this event has been consumed and should be ignored</param>
|
||||||
|
public delegate void MessageProcessingDel(TorchChatMessage msg, ref bool consumed);
|
||||||
|
|
||||||
|
public interface IChatManagerServer : IChatManagerClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event triggered when the server has recieved a message and should process it. <see cref="MessageProcessingDel"/>
|
||||||
|
/// </summary>
|
||||||
|
event MessageProcessingDel MessageProcessing;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a message with the given author and message to the given player, or all players by default.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="authorId">Author's steam ID</param>
|
||||||
|
/// <param name="message">The message to send</param>
|
||||||
|
/// <param name="targetSteamId">Player to send the message to, or everyone by default</param>
|
||||||
|
void SendMessageAsOther(ulong authorId, string message, ulong targetSteamId = 0);
|
||||||
|
|
||||||
|
|
||||||
|
[Obsolete("Use the other overload with a Color parameter.")]
|
||||||
|
void SendMessageAsOther(string author, string message, string font, ulong targetSteamId = 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a scripted message with the given author and message to the given player, or all players by default.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="author">Author name</param>
|
||||||
|
/// <param name="message">The message to send</param>
|
||||||
|
/// <param name="color">Name color</param>
|
||||||
|
/// <param name="font">Font to use</param>
|
||||||
|
/// <param name="targetSteamId">Player to send the message to, or everyone by default</param>
|
||||||
|
void SendMessageAsOther(string author, string message, Color color = default, ulong targetSteamId = 0, string font = MyFontEnum.White);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mute user from global chat.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool MuteUser(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unmute user from global chat.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool UnmuteUser(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Users which are not allowed to chat.
|
||||||
|
/// </summary>
|
||||||
|
HashSetReader<ulong> MutedUsers { get; }
|
||||||
|
}
|
||||||
|
}
|
62
Torch.API/Managers/IDependencyManager.cs
Normal file
62
Torch.API/Managers/IDependencyManager.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages a set of <see cref="IManager"/> and the dependencies between them.
|
||||||
|
/// </summary>
|
||||||
|
public interface IDependencyManager : IDependencyProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers the given manager into the dependency system.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method only returns false when there is already a manager registered with a type derived from this given manager,
|
||||||
|
/// or when the given manager is derived from an already existing manager.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="manager">Manager to register</param>
|
||||||
|
/// <exception cref="InvalidOperationException">When adding a new manager to an initialized dependency manager</exception>
|
||||||
|
/// <returns>true if added, false if not</returns>
|
||||||
|
bool AddManager(IManager manager);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all managers registered with this dependency manager
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">When removing managers from an initialized dependency manager</exception>
|
||||||
|
void ClearManagers();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a single manager from this dependency manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="manager">The manager to remove</param>
|
||||||
|
/// <returns>true if successful, false if the manager wasn't found</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">When removing managers from an initialized dependency manager</exception>
|
||||||
|
bool RemoveManager(IManager manager);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sorts the dependency manager, then attaches all its registered managers in <see cref="AttachOrder" />
|
||||||
|
/// </summary>
|
||||||
|
void Attach();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Detaches all registered managers in <see cref="DetachOrder"/>
|
||||||
|
/// </summary>
|
||||||
|
void Detach();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The order that managers should be attached in. (Dependencies, then dependents)
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">When trying to determine load order before this dependency manager is initialized</exception>
|
||||||
|
IEnumerable<IManager> AttachOrder { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The order that managers should be detached in. (Dependents, then dependencies)
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">When trying to determine unload order before this dependency manager is initialized</exception>
|
||||||
|
IEnumerable<IManager> DetachOrder { get; }
|
||||||
|
}
|
||||||
|
}
|
18
Torch.API/Managers/IDependencyProvider.cs
Normal file
18
Torch.API/Managers/IDependencyProvider.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
public interface IDependencyProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the manager that provides the given type. If there is no such manager, returns null.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type of manager</param>
|
||||||
|
/// <returns>manager, or null if none exists</returns>
|
||||||
|
IManager GetManager(Type type);
|
||||||
|
}
|
||||||
|
}
|
20
Torch.API/Managers/IInstanceManager.cs
Normal file
20
Torch.API/Managers/IInstanceManager.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using VRage.Game;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers;
|
||||||
|
|
||||||
|
public interface IInstanceManager : IManager
|
||||||
|
{
|
||||||
|
IWorld SelectedWorld { get; }
|
||||||
|
void LoadInstance(string path, bool validate = true);
|
||||||
|
void SelectCreatedWorld(string worldPath);
|
||||||
|
void SelectWorld(string worldPath, bool modsOnly = true);
|
||||||
|
void ImportSelectedWorldConfig();
|
||||||
|
void SaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IWorld
|
||||||
|
{
|
||||||
|
string WorldPath { get; }
|
||||||
|
MyObjectBuilder_SessionSettings KeenSessionSettings { get; }
|
||||||
|
MyObjectBuilder_Checkpoint KeenCheckpoint { get; }
|
||||||
|
}
|
@@ -6,8 +6,19 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Torch.API.Managers
|
namespace Torch.API.Managers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base interface for Torch managers.
|
||||||
|
/// </summary>
|
||||||
public interface IManager
|
public interface IManager
|
||||||
{
|
{
|
||||||
void Init();
|
/// <summary>
|
||||||
|
/// Attaches the manager to the session. Called once this manager's dependencies have been attached.
|
||||||
|
/// </summary>
|
||||||
|
void Attach();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Detaches the manager from the session. Called before this manager's dependencies are detached.
|
||||||
|
/// </summary>
|
||||||
|
void Detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using VRage.Game;
|
|
||||||
using VRage.Game.ModAPI;
|
|
||||||
|
|
||||||
namespace Torch.API.Managers
|
|
||||||
{
|
|
||||||
public delegate void MessageReceivedDel(IChatMessage message, ref bool sendToOthers);
|
|
||||||
|
|
||||||
public interface IMultiplayerManager : IManager
|
|
||||||
{
|
|
||||||
event Action<IPlayer> PlayerJoined;
|
|
||||||
event Action<IPlayer> PlayerLeft;
|
|
||||||
event MessageReceivedDel MessageReceived;
|
|
||||||
void SendMessage(string message, string author = "Server", long playerId = 0, string font = MyFontEnum.Blue);
|
|
||||||
void KickPlayer(ulong steamId);
|
|
||||||
void BanPlayer(ulong steamId, bool banned = true);
|
|
||||||
IMyPlayer GetPlayerBySteamId(ulong id);
|
|
||||||
IMyPlayer GetPlayerByName(string name);
|
|
||||||
}
|
|
||||||
}
|
|
41
Torch.API/Managers/IMultiplayerManagerBase.cs
Normal file
41
Torch.API/Managers/IMultiplayerManagerBase.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using VRage.Game;
|
||||||
|
using VRage.Game.ModAPI;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API for multiplayer related functions common to servers and clients.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMultiplayerManagerBase : IManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when a player joins.
|
||||||
|
/// </summary>
|
||||||
|
event Action<IPlayer> PlayerJoined;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when a player disconnects.
|
||||||
|
/// </summary>
|
||||||
|
event Action<IPlayer> PlayerLeft;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a player by their Steam64 ID or returns null if the player isn't found.
|
||||||
|
/// </summary>
|
||||||
|
IMyPlayer GetPlayerBySteamId(ulong id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a player by their display name or returns null if the player isn't found.
|
||||||
|
/// </summary>
|
||||||
|
IMyPlayer GetPlayerByName(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the steam username of a member's steam ID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId">steam ID</param>
|
||||||
|
/// <returns>steam username</returns>
|
||||||
|
string GetSteamUsername(ulong steamId);
|
||||||
|
}
|
||||||
|
}
|
12
Torch.API/Managers/IMultiplayerManagerClient.cs
Normal file
12
Torch.API/Managers/IMultiplayerManagerClient.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
public interface IMultiplayerManagerClient : IMultiplayerManagerBase
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
71
Torch.API/Managers/IMultiplayerManagerServer.cs
Normal file
71
Torch.API/Managers/IMultiplayerManagerServer.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VRage.Game.ModAPI;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API for multiplayer functions that exist on servers and lobbies
|
||||||
|
/// </summary>
|
||||||
|
public interface IMultiplayerManagerServer : IMultiplayerManagerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Kicks the player from the game.
|
||||||
|
/// </summary>
|
||||||
|
void KickPlayer(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bans or unbans a player from the game.
|
||||||
|
/// </summary>
|
||||||
|
void BanPlayer(ulong steamId, bool banned = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Promotes user if possible.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId"></param>
|
||||||
|
void PromoteUser(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Demotes user if possible.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId"></param>
|
||||||
|
void DemoteUser(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a user's promote level.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
MyPromoteLevel GetUserPromoteLevel(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of the banned SteamID's
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyList<ulong> BannedPlayers { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the player with the given SteamID is banned.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="steamId">The SteamID of the player.</param>
|
||||||
|
/// <returns>True if the player is banned; otherwise false.</returns>
|
||||||
|
bool IsBanned(ulong steamId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when a player is kicked. Passes with SteamID of kicked player.
|
||||||
|
/// </summary>
|
||||||
|
event Action<ulong> PlayerKicked;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when a player is banned or unbanned. Passes SteamID of player, and true if banned, false if unbanned.
|
||||||
|
/// </summary>
|
||||||
|
event Action<ulong, bool> PlayerBanned;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when a player is promoted or demoted. Passes SteamID of player, and new promote level.
|
||||||
|
/// </summary>
|
||||||
|
event Action<ulong, MyPromoteLevel> PlayerPromoted;
|
||||||
|
}
|
||||||
|
}
|
@@ -9,14 +9,37 @@ using VRage.Network;
|
|||||||
|
|
||||||
namespace Torch.API.Managers
|
namespace Torch.API.Managers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API for the network intercept.
|
||||||
|
/// </summary>
|
||||||
public interface INetworkManager : IManager
|
public interface INetworkManager : IManager
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Register a network handler.
|
||||||
|
/// </summary>
|
||||||
void RegisterNetworkHandler(INetworkHandler handler);
|
void RegisterNetworkHandler(INetworkHandler handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unregister a network handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if the handler was unregistered, false if it wasn't registered to begin with</returns>
|
||||||
|
bool UnregisterNetworkHandler(INetworkHandler handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler for multiplayer network messages.
|
||||||
|
/// </summary>
|
||||||
public interface INetworkHandler
|
public interface INetworkHandler
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns if the handler can process the call site.
|
||||||
|
/// </summary>
|
||||||
bool CanHandle(CallSite callSite);
|
bool CanHandle(CallSite callSite);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes a network message.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if the message should be discarded</returns>
|
||||||
bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj, MyPacket packet);
|
bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj, MyPacket packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
Torch.API/Managers/IPackageManager.cs
Normal file
14
Torch.API/Managers/IPackageManager.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
using Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
namespace Torch.API.Managers;
|
||||||
|
|
||||||
|
public interface IPackageManager : IManager
|
||||||
|
{
|
||||||
|
IReadOnlySet<Package> Packages { get; }
|
||||||
|
|
||||||
|
bool TryGetPackageAssemblies(Package package, [MaybeNullWhen(false)] out Assembly[] assemblies);
|
||||||
|
}
|
@@ -6,11 +6,32 @@ using VRage.Plugins;
|
|||||||
|
|
||||||
namespace Torch.API.Managers
|
namespace Torch.API.Managers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API for the Torch plugin manager.
|
||||||
|
/// </summary>
|
||||||
public interface IPluginManager : IManager, IEnumerable<ITorchPlugin>
|
public interface IPluginManager : IManager, IEnumerable<ITorchPlugin>
|
||||||
{
|
{
|
||||||
event Action<List<ITorchPlugin>> PluginsLoaded;
|
/// <summary>
|
||||||
List<ITorchPlugin> Plugins { get; }
|
/// Fired when plugins are loaded.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Fired when plugins are loaded and immediately if subscribed after the plugins are loaded.
|
||||||
|
/// </remarks>
|
||||||
|
event Action<IReadOnlyCollection<ITorchPlugin>> PluginsLoaded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Collection of loaded plugins.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyDictionary<Guid, ITorchPlugin> Plugins { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates all loaded plugins.
|
||||||
|
/// </summary>
|
||||||
void UpdatePlugins();
|
void UpdatePlugins();
|
||||||
void DisposePlugins();
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load plugins.
|
||||||
|
/// </summary>
|
||||||
|
void LoadPlugins();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@ namespace Torch.API.Plugins
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The version of the plugin.
|
/// The version of the plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Version Version { get; }
|
string Version { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the plugin.
|
/// The name of the plugin.
|
||||||
@@ -34,5 +34,22 @@ namespace Torch.API.Plugins
|
|||||||
/// This is called on the game thread after each tick.
|
/// This is called on the game thread after each tick.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Plugin's enabled state. Mainly for UI niceness
|
||||||
|
/// </summary>
|
||||||
|
PluginState State { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PluginState
|
||||||
|
{
|
||||||
|
NotInitialized,
|
||||||
|
DisabledError,
|
||||||
|
DisabledUser,
|
||||||
|
UpdateRequired,
|
||||||
|
UninstallRequested,
|
||||||
|
NotInstalled,
|
||||||
|
MissingDependency,
|
||||||
|
Enabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +1,56 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Torch.API.Plugins
|
namespace Torch.API.Plugins
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the given type should be loaded by the plugin manager as a plugin.
|
||||||
|
/// </summary>
|
||||||
|
[Obsolete("All plugin meta-information is now defined in the manifest.xml.")]
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class PluginAttribute : Attribute
|
public class PluginAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The display name of the plugin
|
||||||
|
/// </summary>
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The version of the plugin
|
||||||
|
/// </summary>
|
||||||
public Version Version { get; }
|
public Version Version { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// The GUID of the plugin
|
||||||
|
/// </summary>
|
||||||
public Guid Guid { get; }
|
public Guid Guid { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new plugin attribute with the given attributes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <param name="version"></param>
|
||||||
|
/// <param name="guid"></param>
|
||||||
public PluginAttribute(string name, string version, string guid)
|
public PluginAttribute(string name, string version, string guid)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Version = Version.Parse(version);
|
Version = Version.Parse(version);
|
||||||
Guid = Guid.Parse(guid);
|
Guid = Guid.Parse(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new plugin attribute with the given attributes. Version is computed as the version of the assembly containing the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <param name="versionSupplier">Version is this type's assembly's version</param>
|
||||||
|
/// <param name="guid"></param>
|
||||||
|
public PluginAttribute(string name, Type versionSupplier, string guid)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Version = versionSupplier.Assembly.GetName().Version;
|
||||||
|
Guid = Guid.Parse(guid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,36 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("TorchAPI")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("TorchAPI")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("fba5d932-6254-4a1e-baf4-e229fa94e3c2")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
|
||||||
// by using the '*' as shown below:
|
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@@ -6,11 +6,29 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Torch.API
|
namespace Torch.API
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to indicate the state of the dedicated server.
|
||||||
|
/// </summary>
|
||||||
public enum ServerState
|
public enum ServerState
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The server is not running.
|
||||||
|
/// </summary>
|
||||||
Stopped,
|
Stopped,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The server is starting/loading the session.
|
||||||
|
/// </summary>
|
||||||
Starting,
|
Starting,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The server is running.
|
||||||
|
/// </summary>
|
||||||
Running,
|
Running,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The server encountered an error.
|
||||||
|
/// </summary>
|
||||||
Error
|
Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
Torch.API/Session/GameSaveResult.cs
Normal file
44
Torch.API/Session/GameSaveResult.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The result of a save operation
|
||||||
|
/// </summary>
|
||||||
|
public enum GameSaveResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Successfully saved
|
||||||
|
/// </summary>
|
||||||
|
Success = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The game wasn't ready to be saved
|
||||||
|
/// </summary>
|
||||||
|
GameNotReady = -1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Failed to take the snapshot of the current world state
|
||||||
|
/// </summary>
|
||||||
|
FailedToTakeSnapshot = -2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Failed to save the snapshot to disk
|
||||||
|
/// </summary>
|
||||||
|
FailedToSaveToDisk = -3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An unknown error occurred
|
||||||
|
/// </summary>
|
||||||
|
UnknownError = -4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The save operation timed out
|
||||||
|
/// </summary>
|
||||||
|
TimedOut = -5
|
||||||
|
}
|
||||||
|
}
|
44
Torch.API/Session/ITorchSession.cs
Normal file
44
Torch.API/Session/ITorchSession.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sandbox.Game.World;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
|
||||||
|
namespace Torch.API.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Torch code working with a single game session
|
||||||
|
/// </summary>
|
||||||
|
public interface ITorchSession
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The Torch instance this session is bound to
|
||||||
|
/// </summary>
|
||||||
|
ITorchBase Torch { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Space Engineers game session this session is bound to.
|
||||||
|
/// </summary>
|
||||||
|
MySession KeenSession { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Currently running world
|
||||||
|
/// </summary>
|
||||||
|
IWorld World { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDependencyManager"/>
|
||||||
|
IDependencyManager Managers { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current state of the session
|
||||||
|
/// </summary>
|
||||||
|
TorchSessionState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event raised when the <see cref="State"/> changes.
|
||||||
|
/// </summary>
|
||||||
|
event TorchSessionStateChangedDel StateChanged;
|
||||||
|
}
|
||||||
|
}
|
77
Torch.API/Session/ITorchSessionManager.cs
Normal file
77
Torch.API/Session/ITorchSessionManager.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
using VRage.Game;
|
||||||
|
|
||||||
|
namespace Torch.API.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a manager for the given session if applicable.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is for creating managers that will live inside the session, not the manager that controls sesssions.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="session">The session to construct a bound manager for</param>
|
||||||
|
/// <returns>The manager that will live in the session, or null if none.</returns>
|
||||||
|
public delegate IManager SessionManagerFactoryDel(ITorchSession session);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the creation and destruction of <see cref="ITorchSession"/> instances for each <see cref="Sandbox.Game.World.MySession"/> created by Space Engineers.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITorchSessionManager : IManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The currently running session
|
||||||
|
/// </summary>
|
||||||
|
ITorchSession CurrentSession { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when any <see cref="ITorchSession"/> <see cref="ITorchSession.State"/> changes.
|
||||||
|
/// </summary>
|
||||||
|
event TorchSessionStateChangedDel SessionStateChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the given factory as a supplier for session based managers
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factory">Session based manager supplier</param>
|
||||||
|
/// <returns>true if added, false if already present</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">If the factory is null</exception>
|
||||||
|
bool AddFactory(SessionManagerFactoryDel factory);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove the given factory from the suppliers for session based managers
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factory">Session based manager supplier</param>
|
||||||
|
/// <returns>true if removed, false if not present</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">If the factory is null</exception>
|
||||||
|
bool RemoveFactory(SessionManagerFactoryDel factory);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a mod to be injected into client's world download.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AddOverrideMod(ulong modId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a mod from the injected mod list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool RemoveOverrideMod(ulong modId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List over mods that will be injected into client world downloads.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyCollection<MyObjectBuilder_Checkpoint.ModItem> OverrideMods { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event raised when injected mod list changes.
|
||||||
|
/// </summary>
|
||||||
|
event Action<CollectionChangeEventArgs> OverrideModsChanged;
|
||||||
|
}
|
||||||
|
}
|
38
Torch.API/Session/TorchSessionState.cs
Normal file
38
Torch.API/Session/TorchSessionState.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the state of a <see cref="ITorchSession"/>
|
||||||
|
/// </summary>
|
||||||
|
public enum TorchSessionState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The session has been created, and is now loading.
|
||||||
|
/// </summary>
|
||||||
|
Loading,
|
||||||
|
/// <summary>
|
||||||
|
/// The session has loaded, and is now running.
|
||||||
|
/// </summary>
|
||||||
|
Loaded,
|
||||||
|
/// <summary>
|
||||||
|
/// The session was running, and is now unloading.
|
||||||
|
/// </summary>
|
||||||
|
Unloading,
|
||||||
|
/// <summary>
|
||||||
|
/// The session was unloading, and is now unloaded and stopped.
|
||||||
|
/// </summary>
|
||||||
|
Unloaded
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback raised when a session's state changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">The session who had a state change</param>
|
||||||
|
/// <param name="newState">The session's new state</param>
|
||||||
|
public delegate void TorchSessionStateChangedDel(ITorchSession session, TorchSessionState newState);
|
||||||
|
}
|
@@ -1,188 +1,27 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<AssemblyTitle>Torch API</AssemblyTitle>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Product>Torch</Product>
|
||||||
<ProjectGuid>{FBA5D932-6254-4A1E-BAF4-E229FA94E3C2}</ProjectGuid>
|
<Copyright>Copyright © Torch API 2017</Copyright>
|
||||||
<OutputType>Library</OutputType>
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<UseWpf>True</UseWpf>
|
||||||
<RootNamespace>Torch.API</RootNamespace>
|
|
||||||
<AssemblyName>Torch.API</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<TargetFrameworkProfile />
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<PropertyGroup Condition="$(Configuration) == 'Release'">
|
||||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
<NoWarn>1591</NoWarn>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
|
||||||
<OutputPath>bin\x64\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<DocumentationFile>bin\x64\Release\Torch.API.xml</DocumentationFile>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="HavokWrapper, Version=1.0.6278.22649, Culture=neutral, processorArchitecture=AMD64">
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<PackageReference Include="NLog" Version="5.2.7" />
|
||||||
<HintPath>..\GameBinaries\HavokWrapper.dll</HintPath>
|
<PackageReference Include="NuGet.Commands" Version="6.8.0" />
|
||||||
<Private>False</Private>
|
<PackageReference Include="NuGet.DependencyResolver.Core" Version="6.8.0" />
|
||||||
</Reference>
|
<PackageReference Include="SemanticVersioning" Version="2.0.2" />
|
||||||
<Reference Include="NLog">
|
<PackageReference Include="SpaceEngineersDedicated.ReferenceAssemblies" Version="1.203.505.1">
|
||||||
<HintPath>..\packages\NLog.4.4.1\lib\net45\NLog.dll</HintPath>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<Private>True</Private>
|
<IncludeAssets>compile</IncludeAssets>
|
||||||
</Reference>
|
</PackageReference>
|
||||||
<Reference Include="PresentationCore" />
|
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||||
<Reference Include="PresentationFramework" />
|
<PackageReference Include="System.Text.Json" Version="8.0.0" />
|
||||||
<Reference Include="Sandbox.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\Sandbox.Common.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Sandbox.Game, Version=0.1.6305.30774, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\Sandbox.Game.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Sandbox.Graphics, Version=0.1.6305.30761, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\Sandbox.Graphics.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SpaceEngineers.Game, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\SpaceEngineers.Game.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SpaceEngineers.ObjectBuilders, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\SpaceEngineers.ObjectBuilders.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SpaceEngineers.ObjectBuilders.XmlSerializers, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\SpaceEngineers.ObjectBuilders.XmlSerializers.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SteamSDK, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\SteamSDK.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Configuration" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.IO.Compression" />
|
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
|
||||||
<Reference Include="System.ServiceModel" />
|
|
||||||
<Reference Include="System.Transactions" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="VRage">
|
|
||||||
<HintPath>..\GameBinaries\VRage.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Audio, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Audio.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Dedicated">
|
|
||||||
<HintPath>..\GameBinaries\VRage.Dedicated.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Game, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Game.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Game.XmlSerializers, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Game.XmlSerializers.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Input, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Input.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Library">
|
|
||||||
<HintPath>..\GameBinaries\VRage.Library.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Math, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Math.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Native, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Native.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.OpenVRWrapper, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.OpenVRWrapper.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Render, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Render.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Render11, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Render11.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Scripting, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Scripting.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="ConnectionState.cs" />
|
|
||||||
<Compile Include="IChatMessage.cs" />
|
|
||||||
<Compile Include="Managers\IManager.cs" />
|
|
||||||
<Compile Include="Managers\IMultiplayerManager.cs" />
|
|
||||||
<Compile Include="IPlayer.cs" />
|
|
||||||
<Compile Include="Managers\INetworkManager.cs" />
|
|
||||||
<Compile Include="Managers\IPluginManager.cs" />
|
|
||||||
<Compile Include="ITorchConfig.cs" />
|
|
||||||
<Compile Include="Plugins\ITorchPlugin.cs" />
|
|
||||||
<Compile Include="IServerControls.cs" />
|
|
||||||
<Compile Include="ITorchBase.cs" />
|
|
||||||
<Compile Include="Plugins\IWpfPlugin.cs" />
|
|
||||||
<Compile Include="ModAPI\Ingame\GridExtensions.cs" />
|
|
||||||
<Compile Include="Plugins\PluginAttribute.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
<Compile Include="ServerState.cs" />
|
|
||||||
<Compile Include="ModAPI\TorchAPI.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
|
||||||
<Target Name="BeforeBuild">
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
</Target>
|
|
||||||
-->
|
|
||||||
</Project>
|
</Project>
|
47
Torch.API/TorchGameState.cs
Normal file
47
Torch.API/TorchGameState.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sandbox;
|
||||||
|
|
||||||
|
namespace Torch.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the state of a <see cref="MySandboxGame"/>
|
||||||
|
/// </summary>
|
||||||
|
public enum TorchGameState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The game is currently being created.
|
||||||
|
/// </summary>
|
||||||
|
Creating,
|
||||||
|
/// <summary>
|
||||||
|
/// The game has been created and is ready to begin loading.
|
||||||
|
/// </summary>
|
||||||
|
Created,
|
||||||
|
/// <summary>
|
||||||
|
/// The game is currently loading.
|
||||||
|
/// </summary>
|
||||||
|
Loading,
|
||||||
|
/// <summary>
|
||||||
|
/// The game is fully loaded and ready to start sessions
|
||||||
|
/// </summary>
|
||||||
|
Loaded,
|
||||||
|
/// <summary>
|
||||||
|
/// The game is beginning the unload sequence
|
||||||
|
/// </summary>
|
||||||
|
Unloading,
|
||||||
|
/// <summary>
|
||||||
|
/// The game has been shutdown and is no longer active
|
||||||
|
/// </summary>
|
||||||
|
Unloaded
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback raised when a game's state changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="game">The game who had a state change</param>
|
||||||
|
/// <param name="newState">The game's new state</param>
|
||||||
|
public delegate void TorchGameStateChangedDel(MySandboxGame game, TorchGameState newState);
|
||||||
|
}
|
8
Torch.API/UGCServiceType.cs
Normal file
8
Torch.API/UGCServiceType.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Torch.API
|
||||||
|
{
|
||||||
|
public enum UGCServiceType
|
||||||
|
{
|
||||||
|
Steam,
|
||||||
|
EOS
|
||||||
|
}
|
||||||
|
}
|
40
Torch.API/Utils/ColorUtils.cs
Normal file
40
Torch.API/Utils/ColorUtils.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using System.Windows.Media;
|
||||||
|
using VRage.Game;
|
||||||
|
using Color = VRageMath.Color;
|
||||||
|
|
||||||
|
namespace Torch.Utils
|
||||||
|
{
|
||||||
|
public static class ColorUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Convert the old "font" or a RGB hex code to a Color.
|
||||||
|
/// </summary>
|
||||||
|
public static Color TranslateColor(string font)
|
||||||
|
{
|
||||||
|
if (StringUtils.IsFontEnum(font))
|
||||||
|
{
|
||||||
|
// RGB values copied from Fonts.sbc
|
||||||
|
switch (font)
|
||||||
|
{
|
||||||
|
case MyFontEnum.Blue:
|
||||||
|
return new Color(220, 244, 252);
|
||||||
|
case MyFontEnum.Red:
|
||||||
|
return new Color(227, 65, 65);
|
||||||
|
case MyFontEnum.Green:
|
||||||
|
return new Color(101, 182, 193);
|
||||||
|
case MyFontEnum.DarkBlue:
|
||||||
|
return new Color(94, 115, 127);
|
||||||
|
default:
|
||||||
|
return Color.White;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// VRage color doesn't have its own hex code parser and I don't want to write one
|
||||||
|
var conv = (System.Windows.Media.Color)(ColorConverter.ConvertFromString(font) ??
|
||||||
|
System.Windows.Media.Color.FromRgb(255, 255, 255));
|
||||||
|
return new Color(conv.R, conv.G, conv.B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
Torch.API/Utils/SemanticVersionConverter.cs
Normal file
21
Torch.API/Utils/SemanticVersionConverter.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Version = SemanticVersioning.Version;
|
||||||
|
|
||||||
|
namespace Torch.API.Utils;
|
||||||
|
|
||||||
|
public class SemanticVersionConverter : JsonConverter<Version>
|
||||||
|
{
|
||||||
|
public override Version? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
Version.TryParse(reader.GetString(), out var ver);
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
writer.WriteStringValue(value.ToString());
|
||||||
|
}
|
||||||
|
}
|
73
Torch.API/Utils/StringUtils.cs
Normal file
73
Torch.API/Utils/StringUtils.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.Utils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Utility methods for strings
|
||||||
|
/// </summary>
|
||||||
|
public static class StringUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines a common prefix for the given set of strings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="set">Set of strings</param>
|
||||||
|
/// <returns>Common prefix</returns>
|
||||||
|
public static string CommonPrefix(IEnumerable<string> set)
|
||||||
|
{
|
||||||
|
StringBuilder builder = null;
|
||||||
|
foreach (string other in set)
|
||||||
|
{
|
||||||
|
if (builder == null)
|
||||||
|
builder = new StringBuilder(other);
|
||||||
|
if (builder.Length > other.Length)
|
||||||
|
builder.Remove(other.Length, builder.Length - other.Length);
|
||||||
|
for (var i = 0; i < builder.Length; i++)
|
||||||
|
if (builder[i] != other[i])
|
||||||
|
{
|
||||||
|
builder.Remove(i, builder.Length - i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder?.ToString() ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines a common suffix for the given set of strings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="set">Set of strings</param>
|
||||||
|
/// <returns>Common suffix</returns>
|
||||||
|
public static string CommonSuffix(IEnumerable<string> set)
|
||||||
|
{
|
||||||
|
StringBuilder builder = null;
|
||||||
|
foreach (string other in set)
|
||||||
|
{
|
||||||
|
if (builder == null)
|
||||||
|
builder = new StringBuilder(other);
|
||||||
|
if (builder.Length > other.Length)
|
||||||
|
builder.Remove(0, builder.Length - other.Length);
|
||||||
|
for (var i = 0; i < builder.Length; i++)
|
||||||
|
{
|
||||||
|
if (builder[builder.Length - 1 - i] != other[other.Length - 1 - i])
|
||||||
|
{
|
||||||
|
builder.Remove(0, builder.Length - i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder?.ToString() ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] FontEnumValues => _fontEnumValues ?? (_fontEnumValues = typeof(VRage.Game.MyFontEnum).GetFields(BindingFlags.Public | BindingFlags.Static).Where(x => x.IsLiteral && !x.IsInitOnly).Select(x => (string)x.GetValue(null)).ToArray());
|
||||||
|
|
||||||
|
private static string[] _fontEnumValues;
|
||||||
|
public static bool IsFontEnum(string str)
|
||||||
|
{
|
||||||
|
return FontEnumValues.Contains(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
Torch.API/WebAPI/Plugin/IPluginQuery.cs
Normal file
12
Torch.API/WebAPI/Plugin/IPluginQuery.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugin;
|
||||||
|
|
||||||
|
public interface IPluginQuery
|
||||||
|
{
|
||||||
|
Task<PluginsResponse> QueryAll();
|
||||||
|
Task<PluginItem> QueryOne(Guid guid);
|
||||||
|
Task<bool> DownloadPlugin(Guid guid, string path = null);
|
||||||
|
Task<bool> DownloadPlugin(PluginItem item, string path = null);
|
||||||
|
}
|
81
Torch.API/WebAPI/Plugin/LegacyPluginQuery.cs
Normal file
81
Torch.API/WebAPI/Plugin/LegacyPluginQuery.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugin;
|
||||||
|
|
||||||
|
public class LegacyPluginQuery : IPluginQuery
|
||||||
|
{
|
||||||
|
private const string BASE_URL = "https://torchapi.com/";
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private LegacyPluginQuery()
|
||||||
|
{
|
||||||
|
_client = new()
|
||||||
|
{
|
||||||
|
BaseAddress = new(BASE_URL)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LegacyPluginQuery Instance { get; } = new();
|
||||||
|
|
||||||
|
public async Task<PluginsResponse> QueryAll()
|
||||||
|
{
|
||||||
|
return await _client.GetFromJsonAsync<PluginsResponse>("/api/plugins/", CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PluginItem> QueryOne(Guid guid)
|
||||||
|
{
|
||||||
|
using var res = await _client.GetAsync($"/api/plugins/search/{guid}");
|
||||||
|
if (!res.IsSuccessStatusCode)
|
||||||
|
return null;
|
||||||
|
return await res.Content.ReadFromJsonAsync<PluginItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DownloadPlugin(Guid guid, string path = null)
|
||||||
|
{
|
||||||
|
var item = await QueryOne(guid);
|
||||||
|
if (item is null) return false;
|
||||||
|
return await DownloadPlugin(item, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DownloadPlugin(PluginItem item, string path = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
path ??= Path.Combine(AppContext.BaseDirectory, "Plugins", $"{item.Name}.zip");
|
||||||
|
|
||||||
|
if (item.Versions.Length == 0)
|
||||||
|
{
|
||||||
|
Log.Error($"Selected plugin {item.Name} does not have any versions to download!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var version = item.Versions.FirstOrDefault(v => v.Version == item.LatestVersion);
|
||||||
|
if (version is null)
|
||||||
|
{
|
||||||
|
Log.Error($"Could not find latest version for selected plugin {item.Name}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var s = await _client.GetStreamAsync(version.Url);
|
||||||
|
|
||||||
|
if(File.Exists(path))
|
||||||
|
File.Delete(path);
|
||||||
|
|
||||||
|
await using var f = File.Create(path);
|
||||||
|
await s.CopyToAsync(f);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Failed to download plugin!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
11
Torch.API/WebAPI/Plugin/PluginItem.cs
Normal file
11
Torch.API/WebAPI/Plugin/PluginItem.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugin;
|
||||||
|
|
||||||
|
public record PluginItem(Guid Id, string Name, string Author, string Description, string LatestVersion,
|
||||||
|
VersionItem[] Versions)
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool Installed { get; set; }
|
||||||
|
}
|
3
Torch.API/WebAPI/Plugin/PluginsResponse.cs
Normal file
3
Torch.API/WebAPI/Plugin/PluginsResponse.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Torch.API.WebAPI.Plugin;
|
||||||
|
|
||||||
|
public record PluginsResponse(PluginItem[] Plugins);
|
6
Torch.API/WebAPI/Plugin/VersionItem.cs
Normal file
6
Torch.API/WebAPI/Plugin/VersionItem.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugin;
|
||||||
|
|
||||||
|
public record VersionItem(string Version, string Note, [property: JsonPropertyName("is_beta")] bool IsBeta,
|
||||||
|
string Url);
|
11
Torch.API/WebAPI/Plugins/IPackageItem.cs
Normal file
11
Torch.API/WebAPI/Plugins/IPackageItem.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public interface IPackageItem
|
||||||
|
{
|
||||||
|
Task<Stream> OpenFileAsync();
|
||||||
|
public string FileName { get; }
|
||||||
|
}
|
12
Torch.API/WebAPI/Plugins/IPackageReader.cs
Normal file
12
Torch.API/WebAPI/Plugins/IPackageReader.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public interface IPackageReader
|
||||||
|
{
|
||||||
|
Task<(IEnumerable<IPackageItem> Root, IReadOnlyDictionary<PackageDependency, IEnumerable<IPackageItem>> Dependencies)> GetItemsAsync();
|
||||||
|
}
|
11
Torch.API/WebAPI/Plugins/IPackageResolver.cs
Normal file
11
Torch.API/WebAPI/Plugins/IPackageResolver.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public interface IPackageResolver
|
||||||
|
{
|
||||||
|
Task<IEnumerable<Package>> ResolvePackagesAsync(IReadOnlyDictionary<string, string> packages);
|
||||||
|
Task<IPackageReader> GetPackageAsync(Package package);
|
||||||
|
}
|
87
Torch.API/WebAPI/Plugins/NLogLogger.cs
Normal file
87
Torch.API/WebAPI/Plugins/NLogLogger.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NuGet.Common;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
internal class NLogLogger : ILogger
|
||||||
|
{
|
||||||
|
private readonly NLog.ILogger _logger;
|
||||||
|
|
||||||
|
public NLogLogger(NLog.ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogDebug(string data)
|
||||||
|
{
|
||||||
|
_logger.Debug(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogVerbose(string data)
|
||||||
|
{
|
||||||
|
_logger.Trace(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogInformation(string data)
|
||||||
|
{
|
||||||
|
_logger.Info(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogMinimal(string data)
|
||||||
|
{
|
||||||
|
_logger.Debug(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogWarning(string data)
|
||||||
|
{
|
||||||
|
_logger.Warn(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogError(string data)
|
||||||
|
{
|
||||||
|
_logger.Error(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogInformationSummary(string data)
|
||||||
|
{
|
||||||
|
_logger.Info(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, string data)
|
||||||
|
{
|
||||||
|
_logger.Log(ToNLogLevel(level), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NLog.LogLevel ToNLogLevel(LogLevel level)
|
||||||
|
{
|
||||||
|
return level switch
|
||||||
|
{
|
||||||
|
LogLevel.Debug => NLog.LogLevel.Debug,
|
||||||
|
LogLevel.Verbose => NLog.LogLevel.Trace,
|
||||||
|
LogLevel.Information => NLog.LogLevel.Info,
|
||||||
|
LogLevel.Minimal => NLog.LogLevel.Debug,
|
||||||
|
LogLevel.Warning => NLog.LogLevel.Warn,
|
||||||
|
LogLevel.Error => NLog.LogLevel.Error,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task LogAsync(LogLevel level, string data)
|
||||||
|
{
|
||||||
|
Log(level, data);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(ILogMessage message)
|
||||||
|
{
|
||||||
|
_logger.Log(ToNLogLevel(message.Level), message.FormatWithCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task LogAsync(ILogMessage message)
|
||||||
|
{
|
||||||
|
Log(message);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
10
Torch.API/WebAPI/Plugins/Package.cs
Normal file
10
Torch.API/WebAPI/Plugins/Package.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NuGet.DependencyResolver;
|
||||||
|
using SemanticVersioning;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public record Package(string Name, Version Version, IReadOnlySet<PackageDependency> Dependencies)
|
||||||
|
{
|
||||||
|
internal GraphItem<RemoteResolveResult> Graph { get; init; }
|
||||||
|
}
|
9
Torch.API/WebAPI/Plugins/PackageDependency.cs
Normal file
9
Torch.API/WebAPI/Plugins/PackageDependency.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using NuGet.DependencyResolver;
|
||||||
|
using SemanticVersioning;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public record PackageDependency(string Name, Version Version, PackageDependencyKind Kind)
|
||||||
|
{
|
||||||
|
internal RemoteMatch Match { get; init; }
|
||||||
|
}
|
8
Torch.API/WebAPI/Plugins/PackageDependencyKind.cs
Normal file
8
Torch.API/WebAPI/Plugins/PackageDependencyKind.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public enum PackageDependencyKind
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Transitive,
|
||||||
|
Direct
|
||||||
|
}
|
91
Torch.API/WebAPI/Plugins/PackageReader.cs
Normal file
91
Torch.API/WebAPI/Plugins/PackageReader.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NuGet.Common;
|
||||||
|
using NuGet.DependencyResolver;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
using NuGet.Packaging;
|
||||||
|
using NuGet.Protocol.Core.Types;
|
||||||
|
using NuGet.Versioning;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public class PackageReader : IPackageReader
|
||||||
|
{
|
||||||
|
private readonly Package _package;
|
||||||
|
private readonly SourceCacheContext _cacheContext;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly NuGetFramework _framework;
|
||||||
|
private readonly IFrameworkCompatibilityProvider _compatibilityProvider;
|
||||||
|
private readonly DirectoryInfo _packagesDirectory;
|
||||||
|
|
||||||
|
public PackageReader(Package package, SourceCacheContext cacheContext, ILogger logger, NuGetFramework framework,
|
||||||
|
IFrameworkCompatibilityProvider compatibilityProvider, DirectoryInfo packagesDirectory)
|
||||||
|
{
|
||||||
|
_package = package;
|
||||||
|
_cacheContext = cacheContext;
|
||||||
|
_logger = logger;
|
||||||
|
_framework = framework;
|
||||||
|
_compatibilityProvider = compatibilityProvider;
|
||||||
|
_packagesDirectory = packagesDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(IEnumerable<IPackageItem> Root, IReadOnlyDictionary<PackageDependency, IEnumerable<IPackageItem>>
|
||||||
|
Dependencies)>
|
||||||
|
GetItemsAsync()
|
||||||
|
{
|
||||||
|
async Task<IEnumerable<IPackageItem>> GetPackageItemsAsync(string id, NuGetVersion version,
|
||||||
|
IRemoteDependencyProvider provider)
|
||||||
|
{
|
||||||
|
var downloader =
|
||||||
|
await provider.GetPackageDownloaderAsync(new(id, version), _cacheContext, _logger,
|
||||||
|
CancellationToken.None);
|
||||||
|
|
||||||
|
await downloader.CopyNupkgFileToAsync(Path.Combine(_packagesDirectory.FullName, $"{id}.{version}.nupkg"),
|
||||||
|
CancellationToken.None);
|
||||||
|
|
||||||
|
var frameworks = await downloader.ContentReader.GetReferenceItemsAsync(CancellationToken.None);
|
||||||
|
var items = frameworks.Where(b => _compatibilityProvider.IsCompatible(_framework, b.TargetFramework))
|
||||||
|
.MaxBy(b => b.TargetFramework.Version)?.Items;
|
||||||
|
|
||||||
|
return items?.Select(b => new PackageItem(b, downloader)) ?? ImmutableArray<PackageItem>.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootIdentity = _package.Graph.Key;
|
||||||
|
return (await GetPackageItemsAsync(rootIdentity.Name, rootIdentity.Version, _package.Graph.Data.Match.Provider),
|
||||||
|
await _package.Dependencies.ToAsyncEnumerable().SelectManyAwait(async b =>
|
||||||
|
(await GetPackageItemsAsync(
|
||||||
|
b.Match.Library.Name,
|
||||||
|
b.Match.Library.Version,
|
||||||
|
b.Match.Provider))
|
||||||
|
.ToAsyncEnumerable()
|
||||||
|
.Select(c => (b, c)))
|
||||||
|
.GroupBy(b => b.b, b => b.c)
|
||||||
|
.ToDictionaryAwaitAsync<IAsyncGrouping<PackageDependency, IPackageItem>, PackageDependency,
|
||||||
|
IEnumerable<IPackageItem>>(b => ValueTask.FromResult(b.Key),
|
||||||
|
async b => await b.ToArrayAsync()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file class PackageItem : IPackageItem
|
||||||
|
{
|
||||||
|
private readonly string _path;
|
||||||
|
private readonly IPackageDownloader _downloader;
|
||||||
|
|
||||||
|
public string FileName => Path.GetFileName(_path);
|
||||||
|
|
||||||
|
public PackageItem(string path, IPackageDownloader downloader)
|
||||||
|
{
|
||||||
|
_path = path;
|
||||||
|
_downloader = downloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Stream> OpenFileAsync()
|
||||||
|
{
|
||||||
|
return _downloader.CoreReader.GetStreamAsync(_path, CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
104
Torch.API/WebAPI/Plugins/PackageResolver.cs
Normal file
104
Torch.API/WebAPI/Plugins/PackageResolver.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
using NuGet.Commands;
|
||||||
|
using NuGet.Configuration;
|
||||||
|
using NuGet.DependencyResolver;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
using NuGet.LibraryModel;
|
||||||
|
using NuGet.Protocol;
|
||||||
|
using NuGet.Protocol.Core.Types;
|
||||||
|
using NuGet.Versioning;
|
||||||
|
using Version = SemanticVersioning.Version;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public class PackageResolver : IPackageResolver
|
||||||
|
{
|
||||||
|
private static readonly ILogger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private readonly NuGetFramework _framework = NuGetFramework.Parse("net7.0-windows7.0");
|
||||||
|
private readonly NLogLogger _logger = new(Log);
|
||||||
|
private readonly SourceCacheContext _sourceCacheContext = new();
|
||||||
|
private readonly RemoteWalkContext _remoteWalkContext;
|
||||||
|
private readonly DirectoryInfo _packagesDirectory;
|
||||||
|
private readonly IFrameworkCompatibilityProvider _compatibilityProvider = DefaultCompatibilityProvider.Instance;
|
||||||
|
|
||||||
|
public PackageResolver(IEnumerable<PackageSource> sources, DirectoryInfo packagesDirectory)
|
||||||
|
{
|
||||||
|
_packagesDirectory = packagesDirectory;
|
||||||
|
IReadOnlySet<PackageSource> packageSources = sources.Where(b => b.Type is PackageSourceType.NuGet).ToImmutableHashSet();
|
||||||
|
|
||||||
|
var mapping = new PackageSourceMapping(packageSources.ToDictionary(b => b.Name, b => b.Patterns));
|
||||||
|
_remoteWalkContext = new RemoteWalkContext(_sourceCacheContext, mapping, _logger);
|
||||||
|
|
||||||
|
foreach (var (name, url, _, _) in packageSources)
|
||||||
|
{
|
||||||
|
var packageSource = new NuGet.Configuration.PackageSource(url, name);
|
||||||
|
var sourceRepository = new SourceRepository(packageSource, new INuGetResourceProvider[]
|
||||||
|
{
|
||||||
|
new DownloadResourceV3Provider(),
|
||||||
|
new DependencyInfoResourceV3Provider(),
|
||||||
|
new ServiceIndexResourceV3Provider(),
|
||||||
|
new RemoteV3FindPackageByIdResourceProvider(),
|
||||||
|
new V3FeedListResourceProvider(),
|
||||||
|
new HttpSourceResourceProvider(),
|
||||||
|
new RegistrationResourceV3Provider(),
|
||||||
|
new HttpHandlerResourceV3Provider()
|
||||||
|
}.Select(b => new Lazy<INuGetResourceProvider>(b)), FeedType.HttpV3);
|
||||||
|
|
||||||
|
_remoteWalkContext.RemoteLibraryProviders.Add(
|
||||||
|
new SourceRepositoryDependencyProvider(sourceRepository, _logger, _sourceCacheContext, true, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Package>> ResolvePackagesAsync(
|
||||||
|
IReadOnlyDictionary<string, string> packages)
|
||||||
|
{
|
||||||
|
Log.Info("Restoring {0} packages", packages.Count);
|
||||||
|
|
||||||
|
var graphs = await Task.WhenAll(packages.Select(b =>
|
||||||
|
{
|
||||||
|
var (key, versionRange) = b;
|
||||||
|
var libraryRange = new LibraryRange(key, VersionRange.Parse(versionRange), LibraryDependencyTarget.All);
|
||||||
|
return ResolverUtility.FindLibraryEntryAsync(libraryRange, _framework, "win-x64",
|
||||||
|
_remoteWalkContext, CancellationToken.None);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return await graphs.ToAsyncEnumerable().SelectAwait(async graph =>
|
||||||
|
{
|
||||||
|
return new Package(graph.Key.Name, Version.Parse(graph.Key.Version.ToFullString()),
|
||||||
|
await graph.Data.Dependencies
|
||||||
|
.ToAsyncEnumerable()
|
||||||
|
.SelectAwait(async b =>
|
||||||
|
{
|
||||||
|
var match = await ResolverUtility.FindLibraryByVersionAsync(
|
||||||
|
b.LibraryRange, _framework, _remoteWalkContext.RemoteLibraryProviders,
|
||||||
|
_sourceCacheContext, _logger, CancellationToken.None);
|
||||||
|
|
||||||
|
return new PackageDependency(
|
||||||
|
b.Name, Version.Parse(match.Library.Version.ToFullString()),
|
||||||
|
(PackageDependencyKind)b.ReferenceType)
|
||||||
|
{
|
||||||
|
Match = match
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.ToHashSetAsync())
|
||||||
|
{
|
||||||
|
Graph = graph
|
||||||
|
};
|
||||||
|
}).ToArrayAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IPackageReader> GetPackageAsync(Package package)
|
||||||
|
{
|
||||||
|
var reader = new PackageReader(package, _sourceCacheContext, _logger, _framework, _compatibilityProvider, _packagesDirectory);
|
||||||
|
return Task.FromResult<IPackageReader>(reader);
|
||||||
|
}
|
||||||
|
}
|
8
Torch.API/WebAPI/Plugins/PackageSource.cs
Normal file
8
Torch.API/WebAPI/Plugins/PackageSource.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
public record PackageSource
|
||||||
|
#nullable restore
|
||||||
|
(string Name, string Url, IReadOnlyList<string> Patterns, PackageSourceType Type);
|
8
Torch.API/WebAPI/Plugins/PackageSourceType.cs
Normal file
8
Torch.API/WebAPI/Plugins/PackageSourceType.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#nullable enable
|
||||||
|
namespace Torch.API.WebAPI.Plugins;
|
||||||
|
|
||||||
|
public enum PackageSourceType
|
||||||
|
{
|
||||||
|
NuGet,
|
||||||
|
LegacyTorch
|
||||||
|
}
|
127
Torch.API/WebAPI/Update/GithubQuery.cs
Normal file
127
Torch.API/WebAPI/Update/GithubQuery.cs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Version = SemanticVersioning.Version;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Update;
|
||||||
|
|
||||||
|
public class GithubQuery : IUpdateQuery
|
||||||
|
{
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
|
||||||
|
public GithubQuery(string url)
|
||||||
|
{
|
||||||
|
if (url == null) throw new ArgumentNullException(nameof(url));
|
||||||
|
|
||||||
|
_client = new()
|
||||||
|
{
|
||||||
|
BaseAddress = new(url),
|
||||||
|
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
|
||||||
|
DefaultRequestHeaders =
|
||||||
|
{
|
||||||
|
{"User-Agent", "TorchAPI"}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_client?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UpdateRelease> GetLatestReleaseAsync(string repository, string branch = null)
|
||||||
|
{
|
||||||
|
var response = await _client.GetFromJsonAsync<Release>($"/repos/{repository}/releases/latest", new JsonSerializerOptions(JsonSerializerDefaults.Web)
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response is null)
|
||||||
|
throw new($"Unable to get latest release for {repository}");
|
||||||
|
|
||||||
|
return new(Version.Parse(response.TagName), response.Assets.First(b => b.Name == "torch-server.zip").BrowserDownloadUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Asset(
|
||||||
|
string Url,
|
||||||
|
int Id,
|
||||||
|
string NodeId,
|
||||||
|
string Name,
|
||||||
|
string Label,
|
||||||
|
Uploader Uploader,
|
||||||
|
string ContentType,
|
||||||
|
string State,
|
||||||
|
int Size,
|
||||||
|
int DownloadCount,
|
||||||
|
DateTime CreatedAt,
|
||||||
|
DateTime UpdatedAt,
|
||||||
|
string BrowserDownloadUrl
|
||||||
|
);
|
||||||
|
|
||||||
|
private record Author(
|
||||||
|
string Login,
|
||||||
|
int Id,
|
||||||
|
string NodeId,
|
||||||
|
string AvatarUrl,
|
||||||
|
string GravatarId,
|
||||||
|
string Url,
|
||||||
|
string HtmlUrl,
|
||||||
|
string FollowersUrl,
|
||||||
|
string FollowingUrl,
|
||||||
|
string GistsUrl,
|
||||||
|
string StarredUrl,
|
||||||
|
string SubscriptionsUrl,
|
||||||
|
string OrganizationsUrl,
|
||||||
|
string ReposUrl,
|
||||||
|
string EventsUrl,
|
||||||
|
string ReceivedEventsUrl,
|
||||||
|
string Type,
|
||||||
|
bool SiteAdmin
|
||||||
|
);
|
||||||
|
|
||||||
|
private record Release(
|
||||||
|
string Url,
|
||||||
|
string AssetsUrl,
|
||||||
|
string UploadUrl,
|
||||||
|
string HtmlUrl,
|
||||||
|
int Id,
|
||||||
|
Author Author,
|
||||||
|
string NodeId,
|
||||||
|
string TagName,
|
||||||
|
string TargetCommitish,
|
||||||
|
string Name,
|
||||||
|
bool Draft,
|
||||||
|
bool Prerelease,
|
||||||
|
DateTime CreatedAt,
|
||||||
|
DateTime PublishedAt,
|
||||||
|
IReadOnlyList<Asset> Assets,
|
||||||
|
string TarballUrl,
|
||||||
|
string ZipballUrl,
|
||||||
|
string Body
|
||||||
|
);
|
||||||
|
|
||||||
|
private record Uploader(
|
||||||
|
string Login,
|
||||||
|
int Id,
|
||||||
|
string NodeId,
|
||||||
|
string AvatarUrl,
|
||||||
|
string GravatarId,
|
||||||
|
string Url,
|
||||||
|
string HtmlUrl,
|
||||||
|
string FollowersUrl,
|
||||||
|
string FollowingUrl,
|
||||||
|
string GistsUrl,
|
||||||
|
string StarredUrl,
|
||||||
|
string SubscriptionsUrl,
|
||||||
|
string OrganizationsUrl,
|
||||||
|
string ReposUrl,
|
||||||
|
string EventsUrl,
|
||||||
|
string ReceivedEventsUrl,
|
||||||
|
string Type,
|
||||||
|
bool SiteAdmin
|
||||||
|
);
|
||||||
|
}
|
9
Torch.API/WebAPI/Update/IUpdateQuery.cs
Normal file
9
Torch.API/WebAPI/Update/IUpdateQuery.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Update;
|
||||||
|
|
||||||
|
public interface IUpdateQuery : IDisposable
|
||||||
|
{
|
||||||
|
Task<UpdateRelease> GetLatestReleaseAsync(string repository, string branch = null);
|
||||||
|
}
|
65
Torch.API/WebAPI/Update/JenkinsQuery.cs
Normal file
65
Torch.API/WebAPI/Update/JenkinsQuery.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Torch.API.Utils;
|
||||||
|
using Version = SemanticVersioning.Version;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Update
|
||||||
|
{
|
||||||
|
public class JenkinsQuery : IUpdateQuery
|
||||||
|
{
|
||||||
|
private const string ApiPath = "api/json";
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
|
||||||
|
public JenkinsQuery(string url)
|
||||||
|
{
|
||||||
|
if (url == null) throw new ArgumentNullException(nameof(url));
|
||||||
|
|
||||||
|
_client = new()
|
||||||
|
{
|
||||||
|
BaseAddress = new(url)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UpdateRelease> GetLatestReleaseAsync(string repository, string branch = null)
|
||||||
|
{
|
||||||
|
branch ??= "master";
|
||||||
|
|
||||||
|
var response = await _client.GetFromJsonAsync<BranchResponse>($"/job/{repository}/job/{branch}/{ApiPath}");
|
||||||
|
|
||||||
|
if (response is null)
|
||||||
|
throw new($"Unable to get latest release for {repository}");
|
||||||
|
|
||||||
|
var job = await _client.GetFromJsonAsync<Job>(
|
||||||
|
$"/job/{repository}/job/{branch}/{response.LastBuild.Number}/{ApiPath}");
|
||||||
|
|
||||||
|
if (job is null)
|
||||||
|
throw new($"Unable to get latest release for job {repository}/{response.LastBuild.Number}");
|
||||||
|
|
||||||
|
return new(job.Version, job.Url + job.Artifacts.First(b => b.FileName == "torch-server.zip").RelativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_client?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record BranchResponse(string Name, string Url, Build LastBuild, Build LastStableBuild);
|
||||||
|
|
||||||
|
public record Build(int Number, string Url);
|
||||||
|
|
||||||
|
public record Job(int Number, bool Building, string Description, string Result, string Url,
|
||||||
|
[property: JsonConverter(typeof(SemanticVersionConverter))] Version Version,
|
||||||
|
IReadOnlyList<Artifact> Artifacts);
|
||||||
|
|
||||||
|
public record Artifact(
|
||||||
|
string DisplayPath,
|
||||||
|
string FileName,
|
||||||
|
string RelativePath
|
||||||
|
);
|
||||||
|
}
|
5
Torch.API/WebAPI/Update/UpdateRelease.cs
Normal file
5
Torch.API/WebAPI/Update/UpdateRelease.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
using SemanticVersioning;
|
||||||
|
|
||||||
|
namespace Torch.API.WebAPI.Update;
|
||||||
|
|
||||||
|
public record UpdateRelease(Version Version, string ArtifactUrl);
|
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="NLog" version="4.4.1" targetFramework="net461" />
|
|
||||||
</packages>
|
|
233
Torch.API/packages.lock.json
Normal file
233
Torch.API/packages.lock.json
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"dependencies": {
|
||||||
|
"net7.0-windows7.0": {
|
||||||
|
"Microsoft.Extensions.Configuration.Binder": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[8.0.0, )",
|
||||||
|
"resolved": "8.0.0",
|
||||||
|
"contentHash": "mBMoXLsr5s1y2zOHWmKsE9veDcx8h1x/c3rz4baEdQKTeDcmQAPNbB54Pi/lhFO3K431eEq6PFbMgLaa6PHFfA==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NLog": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[5.2.7, )",
|
||||||
|
"resolved": "5.2.7",
|
||||||
|
"contentHash": "Ww/0b6V1NL8iqpFKtRKVQFFX03LoowNzYeNG6FpVzmhgCfLAkW0h/4lT3+V8mHfyvtHptNoV8Cz0YePLFRUaPA=="
|
||||||
|
},
|
||||||
|
"NuGet.Commands": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[6.8.0, )",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "jTlbIYNXIiO25s/A2UMBHYhLmNm/lJP+/a/X4OJebejnSKmeKjXeCd9NYH+D9y21JMh3eS0khkCpPnLIgdHsCQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.FileProviders.Abstractions": "6.0.0",
|
||||||
|
"Microsoft.Extensions.FileSystemGlobbing": "6.0.0",
|
||||||
|
"NuGet.Credentials": "6.8.0",
|
||||||
|
"NuGet.ProjectModel": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.DependencyResolver.Core": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[6.8.0, )",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "dTdE5VmQnWfZU2tM4glgsO1ZpFZoEqLKUtpDkr11dkVV4nQn5/MqK9Wmvp/SbU1t7AoSEf7yIMAew9SHxganYA==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.Configuration": "6.8.0",
|
||||||
|
"NuGet.LibraryModel": "6.8.0",
|
||||||
|
"NuGet.Protocol": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SemanticVersioning": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[2.0.2, )",
|
||||||
|
"resolved": "2.0.2",
|
||||||
|
"contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
|
||||||
|
},
|
||||||
|
"SpaceEngineersDedicated.ReferenceAssemblies": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[1.203.505.1, )",
|
||||||
|
"resolved": "1.203.505.1",
|
||||||
|
"contentHash": "YokcOxKdIvtJ2fYdkF48/wvbdaDlNl+bbUd11vkdPRdHaprRj5b2F1wUk7faL0J0UIX87lyhgC/HsNn9rHVbJw==",
|
||||||
|
"dependencies": {
|
||||||
|
"protobuf-net": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Linq.Async": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[6.0.1, )",
|
||||||
|
"resolved": "6.0.1",
|
||||||
|
"contentHash": "0YhHcaroWpQ9UCot3Pizah7ryAzQhNvobLMSxeDIGmnXfkQn8u5owvpOH0K6EVB+z9L7u6Cc4W17Br/+jyttEQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Bcl.AsyncInterfaces": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Text.Json": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[8.0.0, )",
|
||||||
|
"resolved": "8.0.0",
|
||||||
|
"contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Text.Encodings.Web": "8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Bcl.AsyncInterfaces": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.0",
|
||||||
|
"contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "8.0.0",
|
||||||
|
"contentHash": "3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.FileProviders.Abstractions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.0",
|
||||||
|
"contentHash": "0pd4/fho0gC12rQswaGQxbU34jOS1TPS8lZPpkFCH68ppQjHNHYle9iRuHeev1LhrJ94YPvzcRd8UmIuFk23Qw==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Primitives": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.FileSystemGlobbing": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.0",
|
||||||
|
"contentHash": "ip8jnL1aPiaPeKINCqaTEbvBFDmVx9dXQEBZ2HOBRXPD1eabGNqP/bKlsIcp7U2lGxiXd5xIhoFcmY8nM4Hdiw=="
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "8.0.0",
|
||||||
|
"contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
|
||||||
|
},
|
||||||
|
"Newtonsoft.Json": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "13.0.3",
|
||||||
|
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
|
||||||
|
},
|
||||||
|
"NuGet.Common": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "voNZyM5L5s0CCDPU//vXKQke0M8y6kGvG+0Ll6gc/xV7Jh1C3/5OhHRzvekxBS6a9DO/lsFhTZtyCkL6n9lHEw==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.Frameworks": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.Configuration": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "FFEoY1L9G+C74HfSYt6epHTIuS5xJ8D+d9LZ5nnqhujMoBlQgHphaCTfRlul+e/bNIkAp1fDObzsGlPmu3CKAg==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.Common": "6.8.0",
|
||||||
|
"System.Security.Cryptography.ProtectedData": "4.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.Credentials": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "0Cp5iSgmweBKjDbywqNVVlVFCtjmt4z7ol5ED3hjMGNQp1HgthOZ+PSVD2xa+5rf4/in2Nt2/4W938KqreigJg==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.Protocol": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.Frameworks": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "cN9NyahKgYYScioH4CKn+TYj1eSODxd0RECFnQt6ZmzT6z7PfXlbYpVzbiPsxNgY23iNDMOVkSmOqNZyYxNlQA=="
|
||||||
|
},
|
||||||
|
"NuGet.LibraryModel": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "qdNqSa1E/VgpY95XJuLtJrSA74XpWCn5iGf/9r7FMa5smSZt7nClHcMrxOalfzilMKl4prUkE7AVw2AvKZ39Mg==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.Common": "6.8.0",
|
||||||
|
"NuGet.Versioning": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.Packaging": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "lyDnMCAWtoHNsNKGexIl6yHtyxuvn2j3rpKMrYYf86KwTV+JVY9eFIixNdwEPjBXBzWHQGpDKj9Im8v02t9AQQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Newtonsoft.Json": "13.0.3",
|
||||||
|
"NuGet.Configuration": "6.8.0",
|
||||||
|
"NuGet.Versioning": "6.8.0",
|
||||||
|
"System.Security.Cryptography.Pkcs": "6.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.ProjectModel": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "4lXoQxLn2fAN+Yu9SHLRcjPCXNVj039FMXE9vUm14ZjCk889dGCEbUWtF3PUqqRpMGnp6IckDd8zubvXI4H1cw==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.DependencyResolver.Core": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.Protocol": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "Nfvij7QlEevDbuRCXkhCrHk1oJN+mYkmeVzNvS9hxNTmwdtHqB+zhUIMFBlbye3MUicgc4bbtLAwoF+EKjUvcg==",
|
||||||
|
"dependencies": {
|
||||||
|
"NuGet.Packaging": "6.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NuGet.Versioning": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.8.0",
|
||||||
|
"contentHash": "WBu15cdv1lqKkPKXDQOEmEzwKemwrczKYlc2jtuZgRYiZ8TG8F4QzPYiE0Q9eVIpMSk8Aky7mUephf19HjBPOw=="
|
||||||
|
},
|
||||||
|
"protobuf-net": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "1.0.0",
|
||||||
|
"contentHash": "kTGOK0E87473sOImOjgZOnz3kTC2aMLffoRWQLYNuBLJnwNNmjanF9IkevZ9Q7yYLeABQfcF3BpeepuMntMVNw=="
|
||||||
|
},
|
||||||
|
"System.Formats.Asn1": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.0",
|
||||||
|
"contentHash": "T6fD00dQ3NTbPDy31m4eQUwKW84s03z0N2C8HpOklyeaDgaJPa/TexP4/SkORMSOwc7WhKifnA6Ya33AkzmafA=="
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.Pkcs": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "LGbXi1oUJ9QgCNGXRO9ndzBL/GZgANcsURpMhNR8uO+rca47SZmciS3RSQUvlQRwK3QHZSHNOXzoMUASKA+Anw==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Formats.Asn1": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.ProtectedData": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.4.0",
|
||||||
|
"contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
|
||||||
|
},
|
||||||
|
"System.Text.Encodings.Web": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "8.0.0",
|
||||||
|
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"net7.0-windows7.0/win-x64": {
|
||||||
|
"System.Security.Cryptography.Pkcs": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "6.0.4",
|
||||||
|
"contentHash": "LGbXi1oUJ9QgCNGXRO9ndzBL/GZgANcsURpMhNR8uO+rca47SZmciS3RSQUvlQRwK3QHZSHNOXzoMUASKA+Anw==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Formats.Asn1": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Security.Cryptography.ProtectedData": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "4.4.0",
|
||||||
|
"contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
|
||||||
|
},
|
||||||
|
"System.Text.Encodings.Web": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "8.0.0",
|
||||||
|
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows;
|
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace Torch.Client
|
|
||||||
{
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
private static Logger _log = LogManager.GetLogger("Torch");
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
|
||||||
|
|
||||||
var client = new TorchClient();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
client.Init();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_log.Fatal("Torch encountered an error trying to initialize the game.");
|
|
||||||
_log.Fatal(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
client.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
|
||||||
{
|
|
||||||
var ex = (Exception)e.ExceptionObject;
|
|
||||||
MessageBox.Show(ex.StackTrace, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
|
|
||||||
[assembly: AssemblyVersion("1.0.169.376")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.169.376")]
|
|
@@ -1,16 +0,0 @@
|
|||||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
|
||||||
<#@ assembly name="System.Core" #>
|
|
||||||
<#@ import namespace="System.Linq" #>
|
|
||||||
<#@ import namespace="System.Text" #>
|
|
||||||
<#@ import namespace="System.Collections.Generic" #>
|
|
||||||
<#@ output extension=".cs" #>
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
<# var dt = DateTime.Now;
|
|
||||||
int major = 1;
|
|
||||||
int minor = 0;
|
|
||||||
int build = dt.DayOfYear;
|
|
||||||
int rev = (int)dt.TimeOfDay.TotalMinutes / 2;
|
|
||||||
#>
|
|
||||||
[assembly: AssemblyVersion("<#= major #>.<#= minor #>.<#= build #>.<#= rev #>")]
|
|
||||||
[assembly: AssemblyFileVersion("<#= major #>.<#= minor #>.<#= build #>.<#= rev #>")]
|
|
@@ -1,12 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Torch Client")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("Torch")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © Torch API 2017")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
[assembly: ComVisible(false)]
|
|
63
Torch.Client/Properties/Resources.Designer.cs
generated
63
Torch.Client/Properties/Resources.Designer.cs
generated
@@ -1,63 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <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 Torch.Client.Properties {
|
|
||||||
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 Resources {
|
|
||||||
|
|
||||||
private static global::System.Resources.ResourceManager resourceMan;
|
|
||||||
|
|
||||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
|
||||||
|
|
||||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
|
||||||
internal Resources() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <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("Torch.Client.Properties.Resources", typeof(Resources).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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,117 +0,0 @@
|
|||||||
<?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.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: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" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
</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" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
26
Torch.Client/Properties/Settings.Designer.cs
generated
26
Torch.Client/Properties/Settings.Designer.cs
generated
@@ -1,26 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <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 Torch.Client.Properties {
|
|
||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.0.0")]
|
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
|
||||||
|
|
||||||
public static Settings Default {
|
|
||||||
get {
|
|
||||||
return defaultInstance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
|
||||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
|
||||||
<Profiles>
|
|
||||||
<Profile Name="(Default)" />
|
|
||||||
</Profiles>
|
|
||||||
<Settings />
|
|
||||||
</SettingsFile>
|
|
@@ -1,174 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProjectGuid>{E36DF745-260B-4956-A2E8-09F08B2E7161}</ProjectGuid>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<RootNamespace>Torch.Client</RootNamespace>
|
|
||||||
<AssemblyName>Torch.Client</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
|
||||||
<TargetFrameworkProfile />
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
|
||||||
<OutputPath>bin\x64\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
|
||||||
<DocumentationFile>bin\x64\Release\Torch.Client.xml</DocumentationFile>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<ApplicationIcon>torchicon.ico</ApplicationIcon>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\NLog.4.4.1\lib\net45\NLog.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Sandbox.Game">
|
|
||||||
<HintPath>..\GameBinaries\Sandbox.Game.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Sandbox.Graphics, Version=0.1.6108.20417, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\Sandbox.Graphics.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="SpaceEngineers.Game">
|
|
||||||
<HintPath>..\GameBinaries\SpaceEngineers.Game.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
|
||||||
<Reference Include="System.Xaml">
|
|
||||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage">
|
|
||||||
<HintPath>..\GameBinaries\VRage.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Game">
|
|
||||||
<HintPath>..\GameBinaries\VRage.Game.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Input, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Input.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Library">
|
|
||||||
<HintPath>..\GameBinaries\VRage.Library.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Math, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\GameBinaries\VRage.Math.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Render">
|
|
||||||
<HintPath>..\GameBinaries\VRage.Render.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="VRage.Render11">
|
|
||||||
<HintPath>..\GameBinaries\VRage.Render11.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="WindowsBase" />
|
|
||||||
<Reference Include="PresentationCore" />
|
|
||||||
<Reference Include="PresentationFramework" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs">
|
|
||||||
<DependentUpon>AssemblyInfo.tt</DependentUpon>
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DesignTime>True</DesignTime>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Properties\AssemblyInfo1.cs" />
|
|
||||||
<Compile Include="TorchClient.cs" />
|
|
||||||
<Compile Include="TorchConsoleScreen.cs" />
|
|
||||||
<Compile Include="TorchMainMenuScreen.cs" />
|
|
||||||
<Compile Include="TorchSettingsScreen.cs" />
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DesignTime>True</DesignTime>
|
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Properties\Settings.Designer.cs">
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DependentUpon>Settings.settings</DependentUpon>
|
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
|
||||||
</Compile>
|
|
||||||
<EmbeddedResource Include="Properties\Resources.resx">
|
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
|
||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="Properties\Settings.settings">
|
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
|
||||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
|
||||||
</None>
|
|
||||||
<AppDesigner Include="Properties\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Torch.API\Torch.API.csproj">
|
|
||||||
<Project>{fba5d932-6254-4a1e-baf4-e229fa94e3c2}</Project>
|
|
||||||
<Name>Torch.API</Name>
|
|
||||||
<Private>True</Private>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\Torch\Torch.csproj">
|
|
||||||
<Project>{7E01635C-3B67-472E-BCD6-C5539564F214}</Project>
|
|
||||||
<Name>Torch</Name>
|
|
||||||
<Private>True</Private>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Resource Include="torchicon.ico" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="Properties\AssemblyInfo.tt">
|
|
||||||
<Generator>TextTemplatingFileGenerator</Generator>
|
|
||||||
<LastGenOutput>AssemblyInfo.cs</LastGenOutput>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<PostBuildEvent>copy "$(SolutionDir)NLog.config" "$(TargetDir)"</PostBuildEvent>
|
|
||||||
</PropertyGroup>
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
|
||||||
<Target Name="BeforeBuild">
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
</Target>
|
|
||||||
-->
|
|
||||||
</Project>
|
|
@@ -1,141 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using Sandbox;
|
|
||||||
using Sandbox.Engine.Platform;
|
|
||||||
using Sandbox.Engine.Utils;
|
|
||||||
using Sandbox.Game;
|
|
||||||
using SpaceEngineers.Game;
|
|
||||||
using Torch.API;
|
|
||||||
using VRage.FileSystem;
|
|
||||||
using VRageRender;
|
|
||||||
|
|
||||||
namespace Torch.Client
|
|
||||||
{
|
|
||||||
public class TorchClient : TorchBase, ITorchClient
|
|
||||||
{
|
|
||||||
private MyCommonProgramStartup _startup;
|
|
||||||
private IMyRender _renderer;
|
|
||||||
private const uint APP_ID = 244850;
|
|
||||||
private VRageGameServices _services;
|
|
||||||
|
|
||||||
public override void Init()
|
|
||||||
{
|
|
||||||
Log.Info("Initializing Torch Client");
|
|
||||||
base.Init();
|
|
||||||
|
|
||||||
if (!File.Exists("steam_appid.txt"))
|
|
||||||
{
|
|
||||||
Directory.SetCurrentDirectory(Path.GetDirectoryName(typeof(VRage.FastResourceLock).Assembly.Location) + "\\..");
|
|
||||||
}
|
|
||||||
|
|
||||||
SpaceEngineersGame.SetupBasicGameInfo();
|
|
||||||
_startup = new MyCommonProgramStartup(RunArgs);
|
|
||||||
if (_startup.PerformReporting())
|
|
||||||
return;
|
|
||||||
|
|
||||||
_startup.PerformAutoconnect();
|
|
||||||
if (!_startup.CheckSingleInstance())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var appDataPath = _startup.GetAppDataPath();
|
|
||||||
MyInitializer.InvokeBeforeRun(APP_ID, MyPerGameSettings.BasicGameInfo.ApplicationName, appDataPath);
|
|
||||||
MyInitializer.InitCheckSum();
|
|
||||||
if (!_startup.Check64Bit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
_startup.DetectSharpDxLeaksBeforeRun();
|
|
||||||
using (var mySteamService = new SteamService(Game.IsDedicated, APP_ID))
|
|
||||||
{
|
|
||||||
_renderer = null;
|
|
||||||
SpaceEngineersGame.SetupPerGameSettings();
|
|
||||||
|
|
||||||
OverrideMenus();
|
|
||||||
|
|
||||||
InitializeRender();
|
|
||||||
|
|
||||||
_services = new VRageGameServices(mySteamService);
|
|
||||||
if (!Game.IsDedicated)
|
|
||||||
MyFileSystem.InitUserSpecific(mySteamService.UserId.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
_startup.DetectSharpDxLeaksAfterRun();
|
|
||||||
MyInitializer.InvokeAfterRun();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OverrideMenus()
|
|
||||||
{
|
|
||||||
var credits = new MyCreditsDepartment("Torch Developed By")
|
|
||||||
{
|
|
||||||
Persons = new List<MyCreditsPerson>
|
|
||||||
{
|
|
||||||
new MyCreditsPerson("THE TORCH TEAM"),
|
|
||||||
new MyCreditsPerson("http://github.com/TorchSE"),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
MyPerGameSettings.Credits.Departments.Insert(0, credits);
|
|
||||||
|
|
||||||
MyPerGameSettings.GUI.MainMenu = typeof(TorchMainMenuScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Start()
|
|
||||||
{
|
|
||||||
using (var spaceEngineersGame = new SpaceEngineersGame(_services, RunArgs))
|
|
||||||
{
|
|
||||||
Log.Info("Starting client");
|
|
||||||
spaceEngineersGame.OnGameLoaded += SpaceEngineersGame_OnGameLoaded;
|
|
||||||
spaceEngineersGame.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SpaceEngineersGame_OnGameLoaded(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Stop()
|
|
||||||
{
|
|
||||||
MySandboxGame.ExitThreadSafe();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeRender()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Game.IsDedicated)
|
|
||||||
{
|
|
||||||
_renderer = new MyNullRender();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var graphicsRenderer = MySandboxGame.Config.GraphicsRenderer;
|
|
||||||
if (graphicsRenderer == MySandboxGame.DirectX11RendererKey)
|
|
||||||
{
|
|
||||||
_renderer = new MyDX11Render();
|
|
||||||
if (!_renderer.IsSupported)
|
|
||||||
{
|
|
||||||
MySandboxGame.Log.WriteLine("DirectX 11 renderer not supported. No renderer to revert back to.");
|
|
||||||
_renderer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_renderer == null)
|
|
||||||
throw new MyRenderException("The current version of the game requires a Dx11 card. \\n For more information please see : http://blog.marekrosa.org/2016/02/space-engineers-news-full-source-code_26.html", MyRenderExceptionEnum.GpuNotSupported);
|
|
||||||
|
|
||||||
MySandboxGame.Config.GraphicsRenderer = graphicsRenderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyRenderProxy.Initialize(_renderer);
|
|
||||||
MyRenderProxy.GetRenderProfiler().SetAutocommit(false);
|
|
||||||
MyRenderProxy.GetRenderProfiler().InitMemoryHack("MainEntryPoint");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show(ex.Message, "Render Initialization Failed");
|
|
||||||
Environment.Exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using Sandbox.Graphics;
|
|
||||||
using Sandbox.Graphics.GUI;
|
|
||||||
using Sandbox.Gui;
|
|
||||||
using VRage.Utils;
|
|
||||||
using VRageMath;
|
|
||||||
|
|
||||||
namespace Torch.Client
|
|
||||||
{
|
|
||||||
public class TorchConsoleScreen : MyGuiScreenBase
|
|
||||||
{
|
|
||||||
private MyGuiControlTextbox _textBox;
|
|
||||||
|
|
||||||
public override string GetFriendlyName()
|
|
||||||
{
|
|
||||||
return "Torch Console";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TorchConsoleScreen() : base(isTopMostScreen: true)
|
|
||||||
{
|
|
||||||
BackgroundColor = new Vector4(0, 0, 0, 0.5f);
|
|
||||||
Size = new Vector2(0.5f);
|
|
||||||
RecreateControls(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed override void RecreateControls(bool constructor)
|
|
||||||
{
|
|
||||||
Elements.Clear();
|
|
||||||
Elements.Add(new MyGuiControlLabel
|
|
||||||
{
|
|
||||||
Text = "Torch Console",
|
|
||||||
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_TOP,
|
|
||||||
Position = MyGuiManager.ComputeFullscreenGuiCoordinate(MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_TOP)
|
|
||||||
});
|
|
||||||
|
|
||||||
Controls.Clear();
|
|
||||||
_textBox = new MyGuiControlTextbox
|
|
||||||
{
|
|
||||||
BorderEnabled = false,
|
|
||||||
Enabled = true,
|
|
||||||
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP,
|
|
||||||
Position = new Vector2(-0.5f)
|
|
||||||
};
|
|
||||||
Controls.Add(_textBox);
|
|
||||||
|
|
||||||
var pistonBtn = new MyGuiControlImageButton
|
|
||||||
{
|
|
||||||
Name = "TorchButton",
|
|
||||||
Text = "Torch",
|
|
||||||
HighlightType = MyGuiControlHighlightType.WHEN_CURSOR_OVER,
|
|
||||||
Visible = true,
|
|
||||||
OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP
|
|
||||||
};
|
|
||||||
|
|
||||||
Controls.Add(pistonBtn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,35 +0,0 @@
|
|||||||
#pragma warning disable 618
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Sandbox.Graphics;
|
|
||||||
using Sandbox.Graphics.GUI;
|
|
||||||
using Sandbox.Gui;
|
|
||||||
using SpaceEngineers.Game.GUI;
|
|
||||||
using VRage.Game;
|
|
||||||
using VRage.Utils;
|
|
||||||
using VRageMath;
|
|
||||||
|
|
||||||
namespace Torch.Client
|
|
||||||
{
|
|
||||||
public class TorchMainMenuScreen : MyGuiScreenMainMenu
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void RecreateControls(bool constructor)
|
|
||||||
{
|
|
||||||
base.RecreateControls(constructor);
|
|
||||||
|
|
||||||
var buttonSize = MyGuiControlButton.GetVisualStyle(MyGuiControlButtonStyleEnum.Default).NormalTexture.MinSizeGui;
|
|
||||||
Vector2 leftButtonPositionOrigin = MyGuiManager.ComputeFullscreenGuiCoordinate(MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_BOTTOM) + new Vector2(buttonSize.X / 2f, 0f);
|
|
||||||
var btn = MakeButton(leftButtonPositionOrigin - 9 * MyGuiConstants.MENU_BUTTONS_POSITION_DELTA, MyStringId.GetOrCompute("Torch"), TorchButtonClicked);
|
|
||||||
Controls.Add(btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TorchButtonClicked(MyGuiControlButton obj)
|
|
||||||
{
|
|
||||||
MyGuiSandbox.AddScreen(new TorchSettingsScreen());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Sandbox.Graphics;
|
|
||||||
using Sandbox.Graphics.GUI;
|
|
||||||
using VRage.Utils;
|
|
||||||
using VRageMath;
|
|
||||||
|
|
||||||
namespace Torch.Client
|
|
||||||
{
|
|
||||||
public class TorchSettingsScreen : MyGuiScreenBase
|
|
||||||
{
|
|
||||||
public override string GetFriendlyName() => "Torch Settings";
|
|
||||||
|
|
||||||
public TorchSettingsScreen() : base(new Vector2(0.5f), null, Vector2.One, true)
|
|
||||||
{
|
|
||||||
RecreateControls(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed override void RecreateControls(bool constructor)
|
|
||||||
{
|
|
||||||
base.RecreateControls(constructor);
|
|
||||||
AddCaption(MyStringId.GetOrCompute("Torch Settings"), null, new Vector2(0, 0), 1.2f);
|
|
||||||
var pluginList = new MyGuiControlListbox
|
|
||||||
{
|
|
||||||
VisibleRowsCount = 10,
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var plugin in TorchBase.Instance.Plugins)
|
|
||||||
{
|
|
||||||
pluginList.Items.Add(new MyGuiControlListbox.Item(new StringBuilder(plugin.Name)));
|
|
||||||
}
|
|
||||||
Controls.Add(pluginList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="NLog" version="4.4.1" targetFramework="net461" />
|
|
||||||
</packages>
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
72
Torch.Mod/Messages/DialogMessage.cs
Normal file
72
Torch.Mod/Messages/DialogMessage.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Sandbox.ModAPI;
|
||||||
|
|
||||||
|
namespace Torch.Mod.Messages
|
||||||
|
{
|
||||||
|
/// Dialogs are structured as follows
|
||||||
|
///
|
||||||
|
/// _____________________________________
|
||||||
|
/// | Title |
|
||||||
|
/// --------------------------------------
|
||||||
|
/// | Prefix Subtitle |
|
||||||
|
/// --------------------------------------
|
||||||
|
/// | ________________________________ |
|
||||||
|
/// | | Content | |
|
||||||
|
/// | --------------------------------- |
|
||||||
|
/// | ____________ |
|
||||||
|
/// | | ButtonText | |
|
||||||
|
/// | -------------- |
|
||||||
|
/// --------------------------------------
|
||||||
|
///
|
||||||
|
/// Button has a callback on click option,
|
||||||
|
/// but can't serialize that, so ¯\_(ツ)_/¯
|
||||||
|
[ProtoContract]
|
||||||
|
public class DialogMessage : MessageBase
|
||||||
|
{
|
||||||
|
[ProtoMember(201)]
|
||||||
|
public string Title;
|
||||||
|
[ProtoMember(202)]
|
||||||
|
public string Subtitle;
|
||||||
|
[ProtoMember(203)]
|
||||||
|
public string Prefix;
|
||||||
|
[ProtoMember(204)]
|
||||||
|
public string Content;
|
||||||
|
[ProtoMember(205)]
|
||||||
|
public string ButtonText;
|
||||||
|
|
||||||
|
public DialogMessage()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public DialogMessage(string title, string subtitle, string content)
|
||||||
|
{
|
||||||
|
Title = title;
|
||||||
|
Subtitle = subtitle;
|
||||||
|
Content = content;
|
||||||
|
Prefix = String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DialogMessage(string title = null, string prefix = null, string subtitle = null, string content = null, string buttonText = null)
|
||||||
|
{
|
||||||
|
Title = title;
|
||||||
|
Subtitle = subtitle;
|
||||||
|
Prefix = prefix ?? String.Empty;
|
||||||
|
Content = content;
|
||||||
|
ButtonText = buttonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessClient()
|
||||||
|
{
|
||||||
|
MyAPIGateway.Utilities.ShowMissionScreen(Title, Prefix, Subtitle, Content, null, ButtonText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessServer()
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
Torch.Mod/Messages/JoinServerMessage.cs
Normal file
52
Torch.Mod/Messages/JoinServerMessage.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Sandbox.ModAPI;
|
||||||
|
|
||||||
|
namespace Torch.Mod.Messages
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public class JoinServerMessage : MessageBase
|
||||||
|
{
|
||||||
|
[ProtoMember(201)]
|
||||||
|
public int Delay;
|
||||||
|
[ProtoMember(202)]
|
||||||
|
public string Address;
|
||||||
|
|
||||||
|
private JoinServerMessage()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public JoinServerMessage(string address)
|
||||||
|
{
|
||||||
|
Address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JoinServerMessage(string address, int delay)
|
||||||
|
{
|
||||||
|
Address = address;
|
||||||
|
Delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessClient()
|
||||||
|
{
|
||||||
|
if (Delay <= 0)
|
||||||
|
{
|
||||||
|
MyAPIGateway.Multiplayer.JoinServer(Address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAPIGateway.Parallel.StartBackground(() =>
|
||||||
|
{
|
||||||
|
MyAPIGateway.Parallel.Sleep(Delay);
|
||||||
|
MyAPIGateway.Multiplayer.JoinServer(Address);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessServer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
Torch.Mod/Messages/MessageBase.cs
Normal file
20
Torch.Mod/Messages/MessageBase.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using ProtoBuf;
|
||||||
|
|
||||||
|
namespace Torch.Mod.Messages
|
||||||
|
{
|
||||||
|
#region Includes
|
||||||
|
[ProtoInclude(1, typeof(DialogMessage))]
|
||||||
|
[ProtoInclude(2, typeof(NotificationMessage))]
|
||||||
|
[ProtoInclude(3, typeof(VoxelResetMessage))]
|
||||||
|
[ProtoInclude(4, typeof(JoinServerMessage))]
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public abstract class MessageBase
|
||||||
|
{
|
||||||
|
public ulong SenderId;
|
||||||
|
|
||||||
|
public abstract void ProcessClient();
|
||||||
|
public abstract void ProcessServer();
|
||||||
|
}
|
||||||
|
}
|
39
Torch.Mod/Messages/NotificationMessage.cs
Normal file
39
Torch.Mod/Messages/NotificationMessage.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Sandbox.ModAPI;
|
||||||
|
|
||||||
|
namespace Torch.Mod.Messages
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public class NotificationMessage : MessageBase
|
||||||
|
{
|
||||||
|
[ProtoMember(201)]
|
||||||
|
public string Message;
|
||||||
|
[ProtoMember(202)]
|
||||||
|
public string Font;
|
||||||
|
[ProtoMember(203)]
|
||||||
|
public int DisappearTimeMs;
|
||||||
|
|
||||||
|
public NotificationMessage()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public NotificationMessage(string message, int disappearTimeMs, string font)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
DisappearTimeMs = disappearTimeMs;
|
||||||
|
Font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessClient()
|
||||||
|
{
|
||||||
|
MyAPIGateway.Utilities.ShowNotification(Message, DisappearTimeMs, Font);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessServer()
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
Torch.Mod/Messages/VoxelResetMessage.cs
Normal file
44
Torch.Mod/Messages/VoxelResetMessage.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Sandbox.ModAPI;
|
||||||
|
using VRage.ModAPI;
|
||||||
|
using VRage.Voxels;
|
||||||
|
|
||||||
|
namespace Torch.Mod.Messages
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public class VoxelResetMessage : MessageBase
|
||||||
|
{
|
||||||
|
[ProtoMember(201)]
|
||||||
|
public long[] EntityId;
|
||||||
|
|
||||||
|
public VoxelResetMessage()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public VoxelResetMessage(long[] entityId)
|
||||||
|
{
|
||||||
|
EntityId = entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessClient()
|
||||||
|
{
|
||||||
|
//MyAPIGateway.Parallel.ForEach(EntityId, id =>
|
||||||
|
foreach (var id in EntityId)
|
||||||
|
{
|
||||||
|
IMyEntity e;
|
||||||
|
if (!MyAPIGateway.Entities.TryGetEntityById(id, out e))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var v = e as IMyVoxelBase;
|
||||||
|
v?.Storage.Reset(MyStorageDataTypeFlags.All);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ProcessServer()
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
Torch.Mod/ModCommunication.cs
Normal file
87
Torch.Mod/ModCommunication.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using Sandbox.ModAPI;
|
||||||
|
using Torch.Mod.Messages;
|
||||||
|
using VRage.Game.Components;
|
||||||
|
using VRage.Game.ModAPI;
|
||||||
|
#if TORCH
|
||||||
|
using Torch.Utils;
|
||||||
|
using VRage.Library.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Torch.Mod
|
||||||
|
{
|
||||||
|
[MySessionComponentDescriptor(MyUpdateOrder.AfterSimulation)]
|
||||||
|
public class ModCommunication : MySessionComponentBase
|
||||||
|
{
|
||||||
|
public const ulong MOD_ID = 2915950488;
|
||||||
|
private const ushort CHANNEL = 7654;
|
||||||
|
|
||||||
|
public override void BeforeStart()
|
||||||
|
{
|
||||||
|
base.BeforeStart();
|
||||||
|
MyAPIGateway.Multiplayer.RegisterSecureMessageHandler(CHANNEL, MessageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MessageHandler(ushort channel, byte[] data, ulong sender, bool fromServer)
|
||||||
|
{
|
||||||
|
if (!fromServer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var message = MyAPIGateway.Utilities.SerializeFromBinary<MessageBase>(data);
|
||||||
|
message.SenderId = sender;
|
||||||
|
|
||||||
|
if (MyAPIGateway.Multiplayer.IsServer) message.ProcessServer();
|
||||||
|
else message.ProcessClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TORCH
|
||||||
|
[ReflectedMethodInfo(typeof(MyAPIUtilities), "VRage.Game.ModAPI.IMyUtilities.SerializeToBinary")]
|
||||||
|
private static MethodInfo _serializeMethod = null!;
|
||||||
|
|
||||||
|
private static readonly CacheList<IMyPlayer> Players = new();
|
||||||
|
|
||||||
|
private static byte[] Serialize(MessageBase message)
|
||||||
|
{
|
||||||
|
return (byte[])_serializeMethod.MakeGenericMethod(message.GetType())
|
||||||
|
.Invoke(MyAPIGateway.Utilities, new object[] { message });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMessageTo(MessageBase message, ulong target)
|
||||||
|
{
|
||||||
|
if (!MyAPIGateway.Multiplayer.IsServer)
|
||||||
|
throw new Exception("Only server can send targeted messages");
|
||||||
|
|
||||||
|
MyAPIGateway.Multiplayer.SendMessageTo(CHANNEL, Serialize(message), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMessageToClients(MessageBase message)
|
||||||
|
{
|
||||||
|
if (!MyAPIGateway.Multiplayer.IsServer)
|
||||||
|
throw new Exception("Only server can send targeted messages");
|
||||||
|
|
||||||
|
MyAPIGateway.Multiplayer.SendMessageToOthers(CHANNEL, Serialize(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMessageExcept(MessageBase message, params ulong[] ignoredUsers)
|
||||||
|
{
|
||||||
|
if (!MyAPIGateway.Multiplayer.IsServer)
|
||||||
|
throw new Exception("Only server can send targeted messages");
|
||||||
|
|
||||||
|
using var players = Players;
|
||||||
|
MyAPIGateway.Multiplayer.Players.GetPlayers(players, player => !ignoredUsers.Contains(player.SteamUserId));
|
||||||
|
|
||||||
|
var data = Serialize(message);
|
||||||
|
foreach (var player in players)
|
||||||
|
{
|
||||||
|
MyAPIGateway.Multiplayer.SendMessageTo(CHANNEL, data, player.SteamUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMessageToServer(MessageBase message)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
19
Torch.Mod/Torch.Mod.projitems
Normal file
19
Torch.Mod/Torch.Mod.projitems
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
<HasSharedItems>true</HasSharedItems>
|
||||||
|
<SharedGUID>3ce4d2e9-b461-4f19-8233-f87e0dfddd74</SharedGUID>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Configuration">
|
||||||
|
<Import_RootNamespace>Torch.Mod</Import_RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\JoinServerMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\NotificationMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\DialogMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\MessageBase.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\VoxelResetMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)ModCommunication.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
12
Torch.Mod/Torch.Mod.shproj
Normal file
12
Torch.Mod/Torch.Mod.shproj
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>3ce4d2e9-b461-4f19-8233-f87e0dfddd74</ProjectGuid>
|
||||||
|
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||||
|
<Import Project="Torch.Mod.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||||
|
</Project>
|
24
Torch.Server.ReferenceAssemblies.net7.nuspec
Normal file
24
Torch.Server.ReferenceAssemblies.net7.nuspec
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Torch.Server.ReferenceAssemblies.net7</id>
|
||||||
|
<version>torchVersion</version>
|
||||||
|
<title>Torch Server Reference Assemblies</title>
|
||||||
|
<authors>zznty</authors>
|
||||||
|
<owners>zznty</owners>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<description>Torch Server Reference Assemblies (.NET 7 edition)</description>
|
||||||
|
<repository type="git" url="https://github.com/PveTeam/Torch" />
|
||||||
|
<dependencies>
|
||||||
|
<group targetFramework="net7.0-windows7.0">
|
||||||
|
<dependency id="SpaceEngineersDedicated.ReferenceAssemblies" version="1.203.22.3" />
|
||||||
|
<dependency id="Torch.Server" version="torchVersion" />
|
||||||
|
</group>
|
||||||
|
</dependencies>
|
||||||
|
<frameworkReferences>
|
||||||
|
<group targetFramework="net7.0-windows7.0">
|
||||||
|
<frameworkReference name="Microsoft.WindowsDesktop.App.WPF" />
|
||||||
|
</group>
|
||||||
|
</frameworkReferences>
|
||||||
|
</metadata>
|
||||||
|
</package>
|
26
Torch.Server.Tests/Torch.Server.Tests.csproj
Normal file
26
Torch.Server.Tests/Torch.Server.Tests.csproj
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<NoWarn>1591,0649</NoWarn>
|
||||||
|
<AssemblyTitle>Torch Server Tests</AssemblyTitle>
|
||||||
|
<Product>Torch</Product>
|
||||||
|
<Copyright>Copyright © Torch API 2017</Copyright>
|
||||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<OutputPath>$(SolutionDir)\bin-test\$(Platform)\$(Configuration)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="$(Configuration) == 'Release'">
|
||||||
|
<DocumentationFile>$(SolutionDir)\bin-test\$(Platform)\$(Configuration)\Torch.Server.Tests.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- <Import Project="$(SolutionDir)\TransformOnBuild.targets" /> -->
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
|
<PackageReference Include="NLog" Version="5.2.7" />
|
||||||
|
<PackageReference Include="xunit" Version="2.6.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Torch.API\Torch.API.csproj" />
|
||||||
|
<ProjectReference Include="..\Torch.Server\Torch.Server.csproj" />
|
||||||
|
<ProjectReference Include="..\Torch.Tests\Torch.Tests.csproj" />
|
||||||
|
<ProjectReference Include="..\Torch\Torch.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
83
Torch.Server.Tests/TorchServerReflectionTest.cs
Normal file
83
Torch.Server.Tests/TorchServerReflectionTest.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Torch.Tests;
|
||||||
|
using Torch.Utils;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Torch.Server.Tests
|
||||||
|
{
|
||||||
|
#warning Disabled reflection tests because of seemingly random failures
|
||||||
|
public class TorchServerReflectionTest
|
||||||
|
{
|
||||||
|
static TorchServerReflectionTest()
|
||||||
|
{
|
||||||
|
TestUtils.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReflectionTestManager _manager;
|
||||||
|
|
||||||
|
private static ReflectionTestManager Manager()
|
||||||
|
{
|
||||||
|
if (_manager != null)
|
||||||
|
return _manager;
|
||||||
|
|
||||||
|
return _manager = new ReflectionTestManager().Init(typeof(TorchServer).Assembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> Getters => Manager().Getters;
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> Setters => Manager().Setters;
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> Invokers => Manager().Invokers;
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> MemberInfo => Manager().MemberInfo;
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> Events => Manager().Events;
|
||||||
|
|
||||||
|
#region Binding
|
||||||
|
//[Theory]
|
||||||
|
[MemberData(nameof(Getters))]
|
||||||
|
public void TestBindingGetter(ReflectionTestManager.FieldRef field)
|
||||||
|
{
|
||||||
|
if (field.Field == null)
|
||||||
|
return;
|
||||||
|
Assert.True(ReflectedManager.Process(field.Field));
|
||||||
|
if (field.Field.IsStatic)
|
||||||
|
Assert.NotNull(field.Field.GetValue(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
//[Theory]
|
||||||
|
[MemberData(nameof(Setters))]
|
||||||
|
public void TestBindingSetter(ReflectionTestManager.FieldRef field)
|
||||||
|
{
|
||||||
|
if (field.Field == null)
|
||||||
|
return;
|
||||||
|
Assert.True(ReflectedManager.Process(field.Field));
|
||||||
|
if (field.Field.IsStatic)
|
||||||
|
Assert.NotNull(field.Field.GetValue(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
//[Theory]
|
||||||
|
[MemberData(nameof(Invokers))]
|
||||||
|
public void TestBindingInvoker(ReflectionTestManager.FieldRef field)
|
||||||
|
{
|
||||||
|
if (field.Field == null)
|
||||||
|
return;
|
||||||
|
Assert.True(ReflectedManager.Process(field.Field));
|
||||||
|
if (field.Field.IsStatic)
|
||||||
|
Assert.NotNull(field.Field.GetValue(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
//[Theory]
|
||||||
|
[MemberData(nameof(Events))]
|
||||||
|
public void TestBindingEvents(ReflectionTestManager.FieldRef field)
|
||||||
|
{
|
||||||
|
if (field.Field == null)
|
||||||
|
return;
|
||||||
|
Assert.True(ReflectedManager.Process(field.Field));
|
||||||
|
if (field.Field.IsStatic)
|
||||||
|
((Func<ReflectedEventReplacer>)field.Field.GetValue(null)).Invoke();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
34
Torch.Server.Tests/TorchServerSessionSettingsTest.cs
Normal file
34
Torch.Server.Tests/TorchServerSessionSettingsTest.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Torch.Server.ViewModels;
|
||||||
|
using VRage.Game;
|
||||||
|
using Xunit;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Torch.Server.Tests
|
||||||
|
{
|
||||||
|
public class TorchServerSessionSettingsTest
|
||||||
|
{
|
||||||
|
public static PropertyInfo[] ViewModelProperties = typeof(SessionSettingsViewModel).GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
public static IEnumerable<object[]> ModelFields = typeof(MyObjectBuilder_SessionSettings).GetFields(BindingFlags.Public | BindingFlags.Instance).Select(x => new object[] { x });
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(ModelFields))]
|
||||||
|
public void MissingPropertyTest(FieldInfo modelField)
|
||||||
|
{
|
||||||
|
// Ignore fields that aren't applicable to SE
|
||||||
|
if (modelField.GetCustomAttribute<GameRelationAttribute>()?.RelatedTo == Game.MedievalEngineers)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(modelField.GetCustomAttribute<DisplayAttribute>()?.Name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var match = ViewModelProperties.FirstOrDefault(p => p.Name.Equals(modelField.Name, StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
Assert.NotNull(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2446
Torch.Server.Tests/packages.lock.json
Normal file
2446
Torch.Server.Tests/packages.lock.json
Normal file
File diff suppressed because it is too large
Load Diff
66
Torch.Server/Commands/WhitelistCommands.cs
Normal file
66
Torch.Server/Commands/WhitelistCommands.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Torch.Commands;
|
||||||
|
|
||||||
|
namespace Torch.Server.Commands
|
||||||
|
{
|
||||||
|
[Category("whitelist")]
|
||||||
|
public class WhitelistCommands : CommandModule
|
||||||
|
{
|
||||||
|
private TorchConfig Config => (TorchConfig)Context.Torch.Config;
|
||||||
|
|
||||||
|
[Command("on", "Enables the whitelist.")]
|
||||||
|
public void On()
|
||||||
|
{
|
||||||
|
if (!Config.EnableWhitelist)
|
||||||
|
{
|
||||||
|
Config.EnableWhitelist = true;
|
||||||
|
Context.Respond("Whitelist enabled.");
|
||||||
|
Config.Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Context.Respond("Whitelist is already enabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("off", "Disables the whitelist")]
|
||||||
|
public void Off()
|
||||||
|
{
|
||||||
|
if (Config.EnableWhitelist)
|
||||||
|
{
|
||||||
|
Config.EnableWhitelist = false;
|
||||||
|
Context.Respond("Whitelist disabled.");
|
||||||
|
Config.Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Context.Respond("Whitelist is already disabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("add", "Add a Steam ID to the whitelist.")]
|
||||||
|
public void Add(ulong steamId)
|
||||||
|
{
|
||||||
|
if (!Config.Whitelist.Contains(steamId))
|
||||||
|
{
|
||||||
|
Config.Whitelist.Add(steamId);
|
||||||
|
Context.Respond($"Added {steamId} to the whitelist.");
|
||||||
|
Config.Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Context.Respond($"{steamId} is already whitelisted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("remove", "Remove a Steam ID from the whitelist.")]
|
||||||
|
public void Remove(ulong steamId)
|
||||||
|
{
|
||||||
|
if (Config.Whitelist.Remove(steamId))
|
||||||
|
{
|
||||||
|
Context.Respond($"Removed {steamId} from the whitelist.");
|
||||||
|
Config.Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Context.Respond($"{steamId} is not whitelisted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Torch.Server/FodyWeavers.xml
Normal file
3
Torch.Server/FodyWeavers.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||||
|
<PropertyChanged />
|
||||||
|
</Weavers>
|
74
Torch.Server/FodyWeavers.xsd
Normal file
74
Torch.Server/FodyWeavers.xsd
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||||
|
<xs:element name="Weavers">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="EventInvokerNames" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="CheckForEquality" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="SuppressWarnings" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
181
Torch.Server/Initializer.cs
Normal file
181
Torch.Server/Initializer.cs
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using NLog;
|
||||||
|
using NLog.Targets;
|
||||||
|
using Sandbox.Engine.Utils;
|
||||||
|
using SpaceEngineers.Game;
|
||||||
|
using Torch.Utils;
|
||||||
|
using VRage.FileSystem;
|
||||||
|
|
||||||
|
namespace Torch.Server
|
||||||
|
{
|
||||||
|
public class Initializer
|
||||||
|
{
|
||||||
|
internal static Initializer Instance { get; private set; }
|
||||||
|
|
||||||
|
private static readonly Logger Log = LogManager.GetLogger(nameof(Initializer));
|
||||||
|
private bool _init;
|
||||||
|
private const string TOOL_DIR = "tool";
|
||||||
|
private const string TOOL_ZIP = "temp.zip";
|
||||||
|
private static readonly string TOOL_EXE = "steamcmd.exe";
|
||||||
|
private const string TOOL_ARGS = "+force_install_dir \"{0}\" +login anonymous +app_update 298740 +quit";
|
||||||
|
private TorchServer _server;
|
||||||
|
|
||||||
|
internal Persistent<TorchConfig> ConfigPersistent { get; }
|
||||||
|
public TorchConfig Config => ConfigPersistent?.Data;
|
||||||
|
public TorchServer Server => _server;
|
||||||
|
|
||||||
|
public Initializer(Persistent<TorchConfig> torchConfig)
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
ConfigPersistent = torchConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Initialize(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
if (_init)
|
||||||
|
return false;
|
||||||
|
#if DEBUG
|
||||||
|
//enables logging debug messages when built in debug mode. Amazing.
|
||||||
|
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Debug, "main");
|
||||||
|
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Debug, "console");
|
||||||
|
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Debug, "wpf");
|
||||||
|
LogManager.ReconfigExistingLoggers();
|
||||||
|
Log.Debug("Debug logging enabled.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (configuration.GetValue("getGameUpdates", true) && !configuration.GetValue("noupdate", false))
|
||||||
|
RunSteamCmdAsync(configuration).Wait();
|
||||||
|
|
||||||
|
var processPid = configuration.GetValue<int>("waitForPid");
|
||||||
|
if (processPid != 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var waitProc = Process.GetProcessById(processPid);
|
||||||
|
Log.Info("Continuing in 5 seconds.");
|
||||||
|
Log.Warn($"Waiting for process {processPid} to close");
|
||||||
|
while (!waitProc.HasExited)
|
||||||
|
{
|
||||||
|
Console.Write(".");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_init = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_server = new TorchServer(Config, ApplicationContext.Current.InstanceDirectory.FullName, ApplicationContext.Current.InstanceName, configuration);
|
||||||
|
|
||||||
|
if (ApplicationContext.Current.IsService || Config.NoGui)
|
||||||
|
{
|
||||||
|
_server.Init();
|
||||||
|
_server.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if !DEBUG
|
||||||
|
if (!Config.IndependentConsole)
|
||||||
|
{
|
||||||
|
Console.SetOut(TextWriter.Null);
|
||||||
|
NativeMethods.FreeConsole();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_server.Init();
|
||||||
|
|
||||||
|
var uiThread = new Thread(() =>
|
||||||
|
{
|
||||||
|
var ui = new TorchUI(_server);
|
||||||
|
|
||||||
|
SynchronizationContext.SetSynchronizationContext(
|
||||||
|
new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
|
||||||
|
|
||||||
|
ui.ShowDialog();
|
||||||
|
});
|
||||||
|
|
||||||
|
uiThread.SetApartmentState(ApartmentState.STA);
|
||||||
|
uiThread.Start();
|
||||||
|
|
||||||
|
if (Config.Autostart || Config.TempAutostart)
|
||||||
|
{
|
||||||
|
Config.TempAutostart = false;
|
||||||
|
_server.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
uiThread.Join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task RunSteamCmdAsync(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var log = LogManager.GetLogger("SteamCMD");
|
||||||
|
|
||||||
|
var path = configuration.GetValue<string>("steamToolPath") ?? ApplicationContext.Current.TorchDirectory
|
||||||
|
.CreateSubdirectory(TOOL_DIR).FullName;
|
||||||
|
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
var toolExe = Path.Combine(path, TOOL_EXE);
|
||||||
|
if (!File.Exists(toolExe))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
log.Info("Downloading SteamCMD.");
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
await using (var file = File.Create(TOOL_ZIP))
|
||||||
|
await using (var stream = await client.GetStreamAsync("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip"))
|
||||||
|
await stream.CopyToAsync(file);
|
||||||
|
|
||||||
|
ZipFile.ExtractToDirectory(TOOL_ZIP, path);
|
||||||
|
File.Delete(TOOL_ZIP);
|
||||||
|
log.Info("SteamCMD downloaded successfully!");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.Error(e, "Failed to download SteamCMD, unable to update the DS.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Checking for DS updates.");
|
||||||
|
var steamCmdProc = new ProcessStartInfo(toolExe)
|
||||||
|
{
|
||||||
|
Arguments = string.Format(TOOL_ARGS, configuration.GetValue("gamePath", "../")),
|
||||||
|
WorkingDirectory = path,
|
||||||
|
RedirectStandardOutput = true
|
||||||
|
};
|
||||||
|
var cmd = Process.Start(steamCmdProc)!;
|
||||||
|
|
||||||
|
while (!cmd.HasExited)
|
||||||
|
{
|
||||||
|
if (await cmd.StandardOutput.ReadLineAsync() is { } line)
|
||||||
|
log.Info(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
Torch.Server/ListBoxExtensions.cs
Normal file
59
Torch.Server/ListBoxExtensions.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace Torch.Server
|
||||||
|
{
|
||||||
|
public static class ListBoxExtensions
|
||||||
|
{
|
||||||
|
//https://stackoverflow.com/questions/28689125/how-to-autoscroll-listbox-to-bottom-wpf-c
|
||||||
|
public static void ScrollToItem(this ListBox listBox, int index)
|
||||||
|
{
|
||||||
|
// Find a container
|
||||||
|
UIElement container = null;
|
||||||
|
for (int i = index; i > 0; i--)
|
||||||
|
{
|
||||||
|
container = listBox.ItemContainerGenerator.ContainerFromIndex(i) as UIElement;
|
||||||
|
if (container != null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (container == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Find the ScrollContentPresenter
|
||||||
|
ScrollContentPresenter presenter = null;
|
||||||
|
for (Visual vis = container; vis != null && vis != listBox; vis = VisualTreeHelper.GetParent(vis) as Visual)
|
||||||
|
if ((presenter = vis as ScrollContentPresenter) != null)
|
||||||
|
break;
|
||||||
|
if (presenter == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Find the IScrollInfo
|
||||||
|
var scrollInfo =
|
||||||
|
!presenter.CanContentScroll ? presenter :
|
||||||
|
presenter.Content as IScrollInfo ??
|
||||||
|
FirstVisualChild(presenter.Content as ItemsPresenter) as IScrollInfo ??
|
||||||
|
presenter;
|
||||||
|
|
||||||
|
// Find the amount of items that is "Visible" in the ListBox
|
||||||
|
var height = (container as ListBoxItem).ActualHeight;
|
||||||
|
var lbHeight = listBox.ActualHeight;
|
||||||
|
var showCount = (int)Math.Floor(lbHeight / height) - 1;
|
||||||
|
|
||||||
|
//Set the scrollbar
|
||||||
|
if (scrollInfo.CanVerticallyScroll)
|
||||||
|
scrollInfo.SetVerticalOffset(index - showCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DependencyObject FirstVisualChild(Visual visual)
|
||||||
|
{
|
||||||
|
if (visual == null) return null;
|
||||||
|
if (VisualTreeHelper.GetChildrenCount(visual) == 0) return null;
|
||||||
|
return VisualTreeHelper.GetChild(visual, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user