Compare commits
265 Commits
v0.6.0-pre
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
dc6a61b8fc | ||
|
87535fb839 | ||
|
4d6f056d7b | ||
|
c9ead57ee5 | ||
|
d441eeaa36 | ||
|
2143b86d07 | ||
|
5372fba0d6 | ||
|
b0e445400a | ||
|
a71c789e29 | ||
|
a561839fd0 | ||
|
4ddd3c3ca7 | ||
|
bb66366f41 | ||
|
bd26533ae2 | ||
|
1452dfb265 | ||
|
55328a969b | ||
|
512a073b07 | ||
|
99010664bf | ||
|
c93fcba652 | ||
|
5450109cf2 | ||
|
02c3004231 | ||
|
6bb96006de | ||
|
9de8543590 | ||
|
dba849e3be | ||
|
399d7da9aa | ||
|
2454547c8f | ||
|
3d0a47ec60 | ||
|
5ef075d4c3 | ||
|
e8aee89f45 | ||
|
2760e2ab1e | ||
|
d44ae36f86 | ||
|
6e3c06af86 | ||
|
fcdc875272 | ||
|
32d1b129c8 | ||
|
1dd18317cf | ||
|
ccdde3d99f | ||
|
d5973b0aff | ||
|
652b908a39 | ||
|
f387a34b35 | ||
|
ea69e6d964 | ||
|
9cbfed8bf3 | ||
|
9f789ba556 | ||
|
7fc39f24bc | ||
|
1dd2e898d9 | ||
|
006ca15232 | ||
|
1730bf40be | ||
|
f40448b6fc | ||
|
b418732ddf | ||
|
bef7a88db0 | ||
|
9f95397bd2 | ||
|
c2ec4f6a45 | ||
|
cab26cfa16 | ||
|
1147e0673b | ||
|
4fec555c1f | ||
|
48fe7a4780 | ||
|
0e8b9285c9 | ||
|
725ec09e5e | ||
|
caaf73e9f3 | ||
|
458cd6d8bc | ||
|
2261a9a655 | ||
|
25a781df8e | ||
|
637fa0a504 | ||
|
23df31735d | ||
|
6ae5ff66f0 | ||
|
11f49cca32 | ||
|
ad024ab997 | ||
|
2db8e83502 | ||
|
8f674ef4e5 | ||
|
19484c8b79 | ||
|
92c46a9d87 | ||
|
e4de326b41 | ||
|
0728561eca | ||
|
7178f2ed22 | ||
|
ad4b5ca8aa | ||
|
9945fd1b1f | ||
|
3f8cadea8e | ||
|
08b04425a5 | ||
|
55fd51a1cc | ||
|
22bac811fc | ||
|
bb7786cb0a | ||
|
e3775ef3dc | ||
|
62e3569195 | ||
|
e48090a00c | ||
|
168e8bc110 | ||
|
8782642e4e | ||
|
646c10d95a | ||
|
25c3d25b10 | ||
|
570150777d | ||
|
0652f77355 | ||
|
6494af20de | ||
|
35a1d1866f | ||
|
3bbfc9bb81 | ||
|
3f6de0350b | ||
|
73c45de4be | ||
|
9fe9f58e70 | ||
|
09cec3f1ad | ||
|
1e62b5ffad | ||
|
f582cdd625 | ||
|
8cc1047367 | ||
|
0c004b6f0f | ||
|
f0a63a241a | ||
|
76896a22f9 | ||
|
7c37334199 | ||
|
897c5dae4b | ||
|
fdcf3d31bd | ||
|
935a72e05b | ||
|
174333ff93 | ||
|
17454d4dc8 | ||
|
9a6b7b531a | ||
|
806118862f | ||
|
9a9e64fb0e | ||
|
8c407de8fb | ||
|
7f6027fe2e | ||
|
dacaf322d4 | ||
|
78fa91ded4 | ||
|
aa69a26f1f | ||
|
f2f388e0bb | ||
|
9cf7049aaa | ||
|
f609a53377 | ||
|
24a745abff | ||
|
58b57f48ad | ||
|
9c26679a5a | ||
|
ca836bbda6 | ||
|
360d2376e1 | ||
|
0b60b2a893 | ||
|
cddc697e89 | ||
|
ec1b580b21 | ||
|
eeacb15d6f | ||
|
4273d00417 | ||
|
9596c5d491 | ||
|
123a8b7caf | ||
|
141b60393a | ||
|
4bdecabbe5 | ||
|
6a8c11b101 | ||
|
12526d7f36 | ||
|
f3e7a42043 | ||
|
fddd146361 | ||
|
b86d252c4b | ||
|
dee9011812 | ||
|
96bc7a73e5 | ||
|
f756e818b6 | ||
|
686a6e6352 | ||
|
a56b7f12ee | ||
|
e6cc1a9e34 | ||
|
3e5c0cc4ed | ||
|
5fa3332266 | ||
|
66b7187c0e | ||
|
eb8ada5040 | ||
|
e34939f303 | ||
|
1e7f2f6514 | ||
|
d50f3b83e9 | ||
|
ce18aea5aa | ||
|
93d1c9841a | ||
|
d8beb754fa | ||
|
af78ebfcaf | ||
|
79c48c240b | ||
|
fe6e3c227f | ||
|
65f106541c | ||
|
428c75bbf2 | ||
|
d47ebbcb28 | ||
|
a1004405ca | ||
|
3efecdad74 | ||
|
be3c45b79d | ||
|
b830ab7085 | ||
|
be3e7c8ac1 | ||
|
a5af98b0f3 | ||
|
0b4c6325c7 | ||
|
e1b76c8e04 | ||
|
26bb7567de | ||
|
0814c99363 | ||
|
f23acb6788 | ||
|
813d0613c1 | ||
|
349efa4e43 | ||
|
86b0bb1b7a | ||
|
32b1272ff6 | ||
|
ab8461b6df | ||
|
a7008ecbd5 | ||
|
a76efc6e6f | ||
|
932c41d369 | ||
|
0ec2a44082 | ||
|
94b6d26ddd | ||
|
7bc677cf81 | ||
|
1f76f8529c | ||
|
afda8902df | ||
|
bb5b3f8bf9 | ||
|
64c63bf24f | ||
|
9dc569e646 | ||
|
00c3740af0 | ||
|
42f48bbaf4 | ||
|
63f160ff4a | ||
|
ff13d11934 | ||
|
2cec22e170 | ||
|
7a2c6c7e37 | ||
|
416de17876 | ||
|
ced346f776 | ||
|
030c869fec | ||
|
5ad73dcc1c | ||
|
32f9fc2afe | ||
|
d8609fd7b1 | ||
|
7ea4db486b | ||
|
31d9f5497e | ||
|
917aa5cf6f | ||
|
c7da419866 | ||
|
86b969fa26 | ||
|
618227a484 | ||
|
5c3bd72482 | ||
|
2ccb17a342 | ||
|
f98e9ffed2 | ||
|
58423863f5 | ||
|
f787feed05 | ||
|
c8abf1567f | ||
|
5847b6a28a | ||
|
0dda3d295f | ||
|
ea209776b3 | ||
|
e3d13df76a | ||
|
4c4da71f6a | ||
|
d11326ffde | ||
|
ed82e072d0 | ||
|
39039c842f | ||
|
35ebdd4118 | ||
|
1efe17dc9e | ||
|
b8dd271aec | ||
|
e90255539a | ||
|
35da7817d1 | ||
|
02f98c732c | ||
|
7fd9381629 | ||
|
0a3edba1ba | ||
|
9205c0b12b | ||
|
5da40e87a5 | ||
|
dc36f83a9f | ||
|
bef4c64c81 | ||
|
ff43574c87 | ||
|
e296609ff3 | ||
|
bb1ab05588 | ||
|
f5216d7e29 | ||
|
a389b6d9fa | ||
|
97f24c27bb | ||
|
66f905e8d7 | ||
|
b46065a800 | ||
|
a5d3d9162e | ||
|
b2efdfd4b2 | ||
|
bc3eb8e5ba | ||
|
c7d8035eab | ||
|
753f60b83d | ||
|
21acf7893d | ||
|
389643078d | ||
|
e95e31610e | ||
|
06904102a4 | ||
|
e89f70e399 | ||
|
4620de247c | ||
|
27102f810a | ||
|
12550fd524 | ||
|
53bad9c7c4 | ||
|
dd3d1fd82b | ||
|
ee52e616c0 | ||
|
3a393776a3 | ||
|
62e8fc02ed | ||
|
8184d468bc | ||
|
58b361ed45 | ||
|
2289bcaa87 | ||
|
23dc1c085c | ||
|
13052d6727 | ||
|
f07a5684d3 | ||
|
cee51300b2 | ||
|
a2be263a7b | ||
|
000ebd466a |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -21,10 +21,14 @@ jobs:
|
||||
include:
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-20.04
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
os: ubuntu-20.04
|
||||
- target: x86_64-pc-windows-msvc
|
||||
os: windows-latest
|
||||
- target: i686-pc-windows-msvc
|
||||
os: windows-latest
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
400
Cargo.lock
generated
400
Cargo.lock
generated
@ -17,24 +17,15 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alterware-launcher"
|
||||
version = "0.5.4"
|
||||
version = "0.6.10"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"futures-util",
|
||||
"http_req",
|
||||
"indicatif",
|
||||
"mslnk",
|
||||
"openssl",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"self-replace",
|
||||
@ -127,11 +118,10 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.0.4"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6"
|
||||
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
"lazy_static",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
@ -174,6 +164,21 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
@ -196,22 +201,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "3.0.2"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -306,21 +312,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -329,21 +335,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@ -436,19 +442,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http_req"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "158d4edacc70c9bdb0464314063b8d9d60fa776442dc13b00a13581b88b0a0a0"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"unicase",
|
||||
"webpki",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
@ -520,9 +513,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indicatif"
|
||||
version = "0.17.7"
|
||||
version = "0.17.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25"
|
||||
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
|
||||
dependencies = [
|
||||
"console",
|
||||
"instant",
|
||||
@ -546,17 +539,6 @@ version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
@ -565,18 +547,18 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.63"
|
||||
version = "0.3.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
|
||||
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keyvalues-parser"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d990301996c856ea07a84bc291e76f1273db52683663efc05c8d355976897e5"
|
||||
checksum = "7e4c8354918309196302015ac9cae43362f1a13d0d5c5539a33b4c2fd2cd6d25"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
@ -585,14 +567,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "keyvalues-serde"
|
||||
version = "0.1.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da419ac133bb3ddf0dbf9c12fcc0ce01d994fcb65f6f1713faf15cc689320b5f"
|
||||
checksum = "0447866c47c00f8bd1949618e8f63017cf93e985b4684dc28d784527e2882390"
|
||||
dependencies = [
|
||||
"keyvalues-parser",
|
||||
"once_cell",
|
||||
"paste",
|
||||
"regex",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
@ -605,9 +584,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
version = "0.2.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
@ -644,9 +623,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
@ -715,9 +694,9 @@ checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.58"
|
||||
version = "0.10.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9dfc0783362704e97ef3bd24261995a699468440099ef95d869b4d9732f829a"
|
||||
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"cfg-if",
|
||||
@ -746,22 +725,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.94"
|
||||
name = "openssl-src"
|
||||
version = "300.1.6+3.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f55da20b29f956fb01f0add8683eb26ee13ebe3ebd935e49898717c6b4b2830"
|
||||
checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
@ -845,18 +834,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.63"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.28"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -920,40 +909,11 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.22"
|
||||
version = "0.11.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
|
||||
checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@ -973,9 +933,11 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
@ -989,35 +951,6 @@ dependencies = [
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin 0.5.2",
|
||||
"untrusted 0.7.1",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "911b295d2d302948838c8ac142da1ee09fa7863163b44e6715bc9357905878b8"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin 0.9.8",
|
||||
"untrusted 0.9.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
@ -1037,37 +970,15 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.16.20",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
|
||||
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
|
||||
dependencies = [
|
||||
"ring 0.16.20",
|
||||
"untrusted 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
@ -1083,16 +994,6 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring 0.16.20",
|
||||
"untrusted 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.9.2"
|
||||
@ -1129,24 +1030,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.20"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
|
||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.189"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.189"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1155,9 +1056,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.107"
|
||||
version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
|
||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -1214,50 +1115,45 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
|
||||
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "steamlocate"
|
||||
version = "2.0.0-alpha.0"
|
||||
version = "2.0.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b1568c4a70a26c4373fe1131ffa4eff055459631b6e40c6bc118615f2d870c3"
|
||||
checksum = "c3b6a4810c4e7fecb0123a9a8ba99b335c17d92e636c265ef99108ee4734c812"
|
||||
dependencies = [
|
||||
"crc",
|
||||
"dirs",
|
||||
"keyvalues-parser",
|
||||
"keyvalues-serde",
|
||||
"serde",
|
||||
"winreg 0.10.1",
|
||||
"winreg 0.51.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
@ -1294,18 +1190,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1329,9 +1225,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.33.0"
|
||||
version = "1.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
|
||||
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@ -1339,16 +1235,16 @@ dependencies = [
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"socket2 0.5.4",
|
||||
"socket2 0.5.5",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.1.0"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1431,15 +1327,6 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
@ -1467,18 +1354,6 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.1"
|
||||
@ -1519,9 +1394,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.86"
|
||||
version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
|
||||
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@ -1529,9 +1404,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.86"
|
||||
version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
|
||||
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@ -1544,9 +1419,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.36"
|
||||
version = "0.4.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e"
|
||||
checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@ -1556,9 +1431,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.86"
|
||||
version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
|
||||
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -1566,9 +1441,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.86"
|
||||
version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
|
||||
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1579,15 +1454,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.86"
|
||||
version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
|
||||
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7"
|
||||
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
@ -1598,30 +1473,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.63"
|
||||
version = "0.3.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2"
|
||||
checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
|
||||
dependencies = [
|
||||
"ring 0.17.2",
|
||||
"untrusted 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -1778,18 +1637,19 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
version = "0.50.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
checksum = "937f3df7948156640f46aacef17a70db0de5917bda9c92b0f751f3a955b588fc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
|
29
Cargo.toml
29
Cargo.toml
@ -1,36 +1,33 @@
|
||||
[package]
|
||||
name = "alterware-launcher"
|
||||
version = "0.5.4"
|
||||
version = "0.6.10"
|
||||
edition = "2021"
|
||||
build = "res/build.rs"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "s"
|
||||
|
||||
# Symbols are a nice thing
|
||||
debug = true
|
||||
|
||||
panic = "abort"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
http_req = { version = "0.10.0", default-features = false, features = [
|
||||
"rust-tls",
|
||||
] }
|
||||
sha1_smol = "1.0.0"
|
||||
serde = { version = "1.0.189", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
serde_json = "1.0.114"
|
||||
rand = "0.8.5"
|
||||
semver = "1.0.20"
|
||||
colored = "2.0.4"
|
||||
reqwest = { version = "0.11.22", features = ["stream"] }
|
||||
futures-util = "0.3.29"
|
||||
indicatif = "0.17.7"
|
||||
tokio = {version="1.33.0", features = ["rt-multi-thread", "macros"]}
|
||||
semver = "1.0.22"
|
||||
colored = "2.1.0"
|
||||
reqwest = { version = "0.11.24", features = ["stream"] }
|
||||
futures-util = "0.3.30"
|
||||
indicatif = "0.17.8"
|
||||
tokio = {version="1.36.0", features = ["rt-multi-thread", "macros"]}
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
openssl = { version = "0.10.64", default-features = false, features = ["vendored"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
steamlocate = "2.0.0-alpha.0"
|
||||
steamlocate = "=2.0.0-beta.2"
|
||||
mslnk = "0.1.8"
|
||||
self-replace = "1.3.7"
|
||||
|
||||
|
27
README.md
27
README.md
@ -4,13 +4,16 @@
|
||||
|
||||
##### IW4x | IW4-SP | IW5-Mod | IW6-Mod | S1-Mod
|
||||
|
||||
  
|
||||
|
||||
---
|
||||
|
||||
#### Installation
|
||||
## Installation
|
||||
|
||||
1. Download the [latest alterware-launcher.exe](https://github.com/mxve/alterware-launcher/releases/latest/download/alterware-launcher.exe)
|
||||
2. Place alterware-launcher.exe in the game directory
|
||||
3. Run alterware-launcher.exe, after updating the game will launch automatically
|
||||
1. Download the game from [Steam](https://store.steampowered.com/)
|
||||
2. Download the [latest alterware-launcher.exe](https://github.com/mxve/alterware-launcher/releases/latest/download/alterware-launcher.exe)
|
||||
3. Place alterware-launcher.exe in the game directory
|
||||
4. Run alterware-launcher.exe, after updating the game will launch automatically
|
||||
|
||||
---
|
||||
|
||||
@ -35,6 +38,8 @@
|
||||
- See [client-args.md](client-args.md)
|
||||
- ```--version```, ```-v```
|
||||
- Print the launcher version
|
||||
- ```--ignore-required-files```
|
||||
- Install client even if required files are missing
|
||||
|
||||
Example: ```alterware-launcher.exe iw4x --bonus -u --path "C:\Games\IW4x" --pass "-console"```
|
||||
|
||||
@ -63,6 +68,9 @@ alterware-launcher.json
|
||||
- ```args```
|
||||
- See --pass
|
||||
- Default: ""
|
||||
- ```use_https```
|
||||
- Use HTTPS for downloads
|
||||
- Default: false
|
||||
|
||||
---
|
||||
|
||||
@ -82,13 +90,6 @@ Visit the [AlterWare Forum](https://forum.alterware.dev/) or [Discord](https://d
|
||||
---
|
||||
|
||||
### Note for server owners:
|
||||
When the launcher updates itself it needs to be restarted. It will return exit code 201 in this case.
|
||||
When the launcher updates itself __on Windows__ it will restart by spawning a new console. If you are automating this process, you should probably use ```--skip-launcher-update``` and download the latest launcher yourself from [here](https://github.com/mxve/alterware-launcher/releases/latest/download/alterware-launcher.exe).
|
||||
|
||||
```
|
||||
@echo off
|
||||
:loop
|
||||
start /wait alterware-launcher.exe --update
|
||||
if %errorlevel% equ 201 (
|
||||
goto loop
|
||||
)
|
||||
```
|
||||
The linux build does __not__ update itself.
|
@ -36,6 +36,17 @@ pub fn save_value(config_path: PathBuf, key: &str, value: bool) {
|
||||
"download_bonus_content" => config.download_bonus_content = value,
|
||||
"ask_bonus_content" => config.ask_bonus_content = value,
|
||||
"force_update" => config.force_update = value,
|
||||
"use_https" => config.use_https = value,
|
||||
_ => (),
|
||||
}
|
||||
save(config_path, config);
|
||||
}
|
||||
|
||||
pub fn save_value_s(config_path: PathBuf, key: &str, value: String) {
|
||||
let mut config = load(config_path.clone());
|
||||
match key {
|
||||
"args" => config.args = value.to_string(),
|
||||
"engine" => config.engine = value.to_string(),
|
||||
_ => (),
|
||||
}
|
||||
save(config_path, config);
|
||||
|
@ -1,19 +1,21 @@
|
||||
use semver::Version;
|
||||
|
||||
pub fn latest_tag(owner: &str, repo: &str) -> String {
|
||||
let github_body = crate::http::get_body_string(
|
||||
pub async fn latest_tag(owner: &str, repo: &str) -> String {
|
||||
let github_body = crate::http_async::get_body_string(
|
||||
format!(
|
||||
"https://api.github.com/repos/{}/{}/releases/latest",
|
||||
owner, repo
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let github_json: serde_json::Value = serde_json::from_str(&github_body).unwrap();
|
||||
github_json["tag_name"].to_string().replace('"', "")
|
||||
}
|
||||
|
||||
pub fn latest_version(owner: &str, repo: &str) -> Version {
|
||||
let tag = latest_tag(owner, repo).replace('v', "");
|
||||
pub async fn latest_version(owner: &str, repo: &str) -> Version {
|
||||
let tag = latest_tag(owner, repo).await.replace('v', "");
|
||||
Version::parse(&tag).unwrap()
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub const MASTER: &str = "https://master.alterware.dev";
|
||||
pub const MASTER: &str = "cdn.alterware.ovh";
|
||||
pub const GH_OWNER: &str = "mxve";
|
||||
pub const GH_REPO: &str = "alterware-launcher";
|
||||
pub const GH_IW4X_OWNER: &str = "iw4x";
|
||||
|
84
src/http.rs
84
src/http.rs
@ -1,84 +0,0 @@
|
||||
use crate::global;
|
||||
use crate::misc;
|
||||
use std::{fs, io::Write, path::Path, str};
|
||||
|
||||
pub fn get_body(url: &str) -> Vec<u8> {
|
||||
let mut res: Vec<u8> = Vec::new();
|
||||
|
||||
match http_req::request::Request::new(&url.try_into().unwrap())
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
global::GH_OWNER,
|
||||
global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send(&mut res)
|
||||
{
|
||||
Ok(req) => {
|
||||
if req.status_code() == http_req::response::StatusCode::new(302)
|
||||
|| req.status_code() == http_req::response::StatusCode::new(301)
|
||||
{
|
||||
let location = req.headers().get("Location").unwrap().as_str();
|
||||
return get_body(location);
|
||||
}
|
||||
|
||||
if req.status_code() != http_req::response::StatusCode::new(200) {
|
||||
misc::fatal_error(&format!(
|
||||
"Could not get body from {}, got {}",
|
||||
url,
|
||||
req.status_code()
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!("Could not get body from {}, got:\n{}", url, e));
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn get_body_string(url: &str) -> String {
|
||||
String::from_utf8(get_body(url)).unwrap()
|
||||
}
|
||||
|
||||
pub fn download_file(url: &str, file_path: &Path) {
|
||||
let body = get_body(url);
|
||||
|
||||
match fs::File::create(file_path) {
|
||||
Ok(mut file) => match file.write_all(&body) {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!(
|
||||
"Could not write to file {}, got:\n{}",
|
||||
file_path.to_str().unwrap(),
|
||||
e
|
||||
));
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
match e.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
fs::create_dir_all(file_path.parent().unwrap()).unwrap();
|
||||
return download_file(url, file_path);
|
||||
}
|
||||
std::io::ErrorKind::PermissionDenied => {
|
||||
misc::fatal_error(&format!(
|
||||
"Permission to {} denied.\n Please try:\n 1. Running the launcher as administrator.\n 2. Manually deleting the last downloaded file.\n 3. If your game is in the program files directory try moving it to another location.\n 4. Create an exception/exclusion in your Anti-Virus Software for either the last downloaded file or the entire game directory.\n\n\n{}",
|
||||
file_path.to_str().unwrap(),
|
||||
e
|
||||
));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
misc::fatal_error(&format!(
|
||||
"Could not create file {}, got:\n{}",
|
||||
file_path.to_str().unwrap(),
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ use reqwest::Client;
|
||||
|
||||
use crate::misc;
|
||||
|
||||
pub async fn download_file(
|
||||
pub async fn download_file_progress(
|
||||
client: &Client,
|
||||
pb: &ProgressBar,
|
||||
url: &str,
|
||||
@ -19,6 +19,14 @@ pub async fn download_file(
|
||||
) -> Result<(), String> {
|
||||
let res = client
|
||||
.get(url)
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
crate::global::GH_OWNER,
|
||||
crate::global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
.or(Err(format!("Failed to GET from '{}'", &url)))?;
|
||||
@ -31,7 +39,7 @@ pub async fn download_file(
|
||||
misc::cute_path(path),
|
||||
misc::human_readable_bytes(total_size)
|
||||
));
|
||||
pb.set_message(misc::cute_path(path));
|
||||
pb.set_message(path.file_name().unwrap().to_str().unwrap().to_string());
|
||||
|
||||
let mut file =
|
||||
File::create(path).or(Err(format!("Failed to create file '{}'", path.display())))?;
|
||||
@ -47,6 +55,73 @@ pub async fn download_file(
|
||||
pb.set_position(new);
|
||||
}
|
||||
|
||||
pb.set_message("");
|
||||
pb.set_message(String::default());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn download_file(url: &str, path: &PathBuf) -> Result<(), String> {
|
||||
let client = Client::new();
|
||||
match client
|
||||
.get(url)
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
crate::global::GH_OWNER,
|
||||
crate::global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(res) => {
|
||||
let body = res.bytes().await.or(Err("Failed to download file"))?;
|
||||
let mut file = File::create(path).or(Err("Failed to create file"))?;
|
||||
file.write_all(&body).or(Err("Failed to write to file"))?;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!(
|
||||
"Could not download file from {}, got:\n{}",
|
||||
url, e
|
||||
));
|
||||
Err("Could not download file".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_body(url: &str) -> Result<Vec<u8>, String> {
|
||||
let client = Client::new();
|
||||
match client
|
||||
.get(url)
|
||||
.header(
|
||||
"User-Agent",
|
||||
&format!(
|
||||
"AlterWare Launcher | github.com/{}/{}",
|
||||
crate::global::GH_OWNER,
|
||||
crate::global::GH_REPO
|
||||
),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(res) => {
|
||||
println!(
|
||||
"[DEBUG] {} {}",
|
||||
res.status().to_string().bright_yellow(),
|
||||
url.bright_yellow()
|
||||
);
|
||||
let body = res.bytes().await.or(Err("Failed to get body"))?;
|
||||
Ok(body.to_vec())
|
||||
}
|
||||
Err(e) => {
|
||||
misc::fatal_error(&format!("Could not get body from {}, got:\n{}", url, e));
|
||||
Err("Could not get body".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_body_string(url: &str) -> Result<String, String> {
|
||||
let body = get_body(url).await?;
|
||||
Ok(String::from_utf8(body).unwrap())
|
||||
}
|
||||
|
22
src/io.rs
22
src/io.rs
@ -1,22 +0,0 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
pub fn unzip(zip_path: &Path, out_path: &Path) {
|
||||
let mut archive = zip::ZipArchive::new(fs::File::open(zip_path).unwrap()).unwrap();
|
||||
for i in 0..archive.len() {
|
||||
let mut file = archive.by_index(i).unwrap();
|
||||
let outpath = out_path.join(file.name());
|
||||
|
||||
if (*file.name()).ends_with('/') {
|
||||
fs::create_dir_all(outpath).unwrap();
|
||||
} else {
|
||||
println!("Unpacking {}", file.name());
|
||||
if let Some(p) = outpath.parent() {
|
||||
if !p.exists() {
|
||||
fs::create_dir_all(p).unwrap();
|
||||
}
|
||||
}
|
||||
let mut outfile = fs::File::create(&outpath).unwrap();
|
||||
std::io::copy(&mut file, &mut outfile).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
26
src/iw4x.rs
26
src/iw4x.rs
@ -1,6 +1,6 @@
|
||||
use crate::github;
|
||||
use crate::global::*;
|
||||
use crate::http;
|
||||
use crate::http_async;
|
||||
use crate::misc;
|
||||
|
||||
use colored::*;
|
||||
@ -14,29 +14,39 @@ pub fn local_revision(dir: &Path) -> u16 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remote_revision() -> u16 {
|
||||
misc::rev_to_int(&github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO))
|
||||
pub async fn remote_revision() -> u16 {
|
||||
misc::rev_to_int(&github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO).await)
|
||||
}
|
||||
|
||||
pub fn update(dir: &Path) {
|
||||
let remote = remote_revision();
|
||||
pub async fn update(dir: &Path) {
|
||||
let remote = remote_revision().await;
|
||||
let local = local_revision(dir);
|
||||
|
||||
if remote <= local && dir.join("iw4x.dll").exists() {
|
||||
println!(
|
||||
"[{}] No files to download for IW4x",
|
||||
"Info".bright_magenta(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
println!(
|
||||
"[{}] Downloading outdated or missing files for IW4x",
|
||||
"Info".bright_magenta()
|
||||
);
|
||||
println!(
|
||||
"[{}] {}",
|
||||
"Downloading".bright_yellow(),
|
||||
dir.join("iw4x.dll").display()
|
||||
misc::cute_path(&dir.join("iw4x.dll"))
|
||||
);
|
||||
http::download_file(
|
||||
http_async::download_file(
|
||||
&format!(
|
||||
"{}/download/iw4x.dll",
|
||||
github::latest_release_url(GH_IW4X_OWNER, GH_IW4X_REPO)
|
||||
),
|
||||
&dir.join("iw4x.dll"),
|
||||
);
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
fs::write(dir.join(".iw4xrevision"), format!("r{}", remote)).unwrap();
|
||||
}
|
||||
|
323
src/main.rs
323
src/main.rs
@ -1,7 +1,6 @@
|
||||
mod config;
|
||||
mod github;
|
||||
mod global;
|
||||
mod http;
|
||||
mod http_async;
|
||||
mod iw4x;
|
||||
mod misc;
|
||||
@ -12,28 +11,34 @@ use global::*;
|
||||
use structs::*;
|
||||
|
||||
use colored::*;
|
||||
use indicatif::ProgressBar;
|
||||
#[cfg(windows)]
|
||||
use mslnk::ShellLink;
|
||||
|
||||
use indicatif::ProgressBar;
|
||||
use std::{borrow::Cow, collections::HashMap, fs, path::Path, path::PathBuf};
|
||||
use std::{borrow::Cow, collections::HashMap, env, fs, path::Path, path::PathBuf};
|
||||
#[cfg(windows)]
|
||||
use steamlocate::SteamDir;
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_installed_games(games: &Vec<Game>) -> Vec<(u32, PathBuf)> {
|
||||
let mut installed_games = Vec::new();
|
||||
let mut steamdir = match SteamDir::locate() {
|
||||
Some(steamdir) => steamdir,
|
||||
None => {
|
||||
println!("{}", "Steam not found!".yellow());
|
||||
let steamdir_result = SteamDir::locate();
|
||||
|
||||
let steamdir = match steamdir_result {
|
||||
Ok(steamdir) => steamdir,
|
||||
Err(error) => {
|
||||
println!("Error locating Steam: {}", error);
|
||||
return installed_games;
|
||||
}
|
||||
};
|
||||
|
||||
for game in games {
|
||||
if let Some(app) = steamdir.app(&game.app_id) {
|
||||
installed_games.push((game.app_id, PathBuf::from(&app.path)));
|
||||
if let Ok(Some((app, library))) = steamdir.find_app(game.app_id) {
|
||||
let game_path = library
|
||||
.path()
|
||||
.join("steamapps")
|
||||
.join("common")
|
||||
.join(&app.install_dir);
|
||||
installed_games.push((game.app_id, game_path));
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,10 +83,7 @@ fn setup_desktop_links(path: &Path, game: &Game) {
|
||||
let input = misc::stdin().to_ascii_lowercase();
|
||||
|
||||
if input == "y" || input.is_empty() {
|
||||
let desktop = PathBuf::from(&format!(
|
||||
"{}\\Desktop",
|
||||
std::env::var("USERPROFILE").unwrap()
|
||||
));
|
||||
let desktop = PathBuf::from(&format!("{}\\Desktop", env::var("USERPROFILE").unwrap()));
|
||||
|
||||
for c in game.client.iter() {
|
||||
create_shortcut(
|
||||
@ -97,14 +99,14 @@ fn setup_desktop_links(path: &Path, game: &Game) {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn auto_install(path: &Path, game: &Game<'_>) {
|
||||
async fn auto_install(path: &Path, game: &Game<'_>, master_url: &String) {
|
||||
setup_client_links(game, path);
|
||||
setup_desktop_links(path, game);
|
||||
update(game, path, false, false).await;
|
||||
update(game, path, false, false, None, master_url, None).await;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
async fn windows_launcher_install(games: &Vec<Game<'_>>) {
|
||||
async fn windows_launcher_install(games: &Vec<Game<'_>>, master_url: &String) {
|
||||
println!(
|
||||
"{}",
|
||||
"No game specified/found. Checking for installed Steam games..".yellow()
|
||||
@ -112,13 +114,13 @@ async fn windows_launcher_install(games: &Vec<Game<'_>>) {
|
||||
let installed_games = get_installed_games(games);
|
||||
|
||||
if !installed_games.is_empty() {
|
||||
let current_dir = std::env::current_dir().unwrap();
|
||||
let current_dir = env::current_dir().unwrap();
|
||||
for (id, path) in installed_games.iter() {
|
||||
if current_dir.starts_with(path) {
|
||||
println!("Found game in current directory.");
|
||||
println!("Installing AlterWare client for {}.", id);
|
||||
let game = games.iter().find(|&g| g.app_id == *id).unwrap();
|
||||
auto_install(path, game).await;
|
||||
auto_install(path, game, master_url).await;
|
||||
println!("Installation complete. Please run the launcher again or use a shortcut to launch the game.");
|
||||
std::io::stdin().read_line(&mut String::new()).unwrap();
|
||||
std::process::exit(0);
|
||||
@ -131,25 +133,21 @@ async fn windows_launcher_install(games: &Vec<Game<'_>>) {
|
||||
println!("{}: {}", id, path.display());
|
||||
}
|
||||
|
||||
println!("Enter the ID of the game you want to install the AlterWare client for, enter 0 for manual selection:");
|
||||
println!("Enter the ID of the game you want to install the AlterWare client for:");
|
||||
let input: u32 = misc::stdin().parse().unwrap();
|
||||
|
||||
if input == 0 {
|
||||
return manual_install(games).await;
|
||||
}
|
||||
|
||||
for (id, path) in installed_games.iter() {
|
||||
if *id == input {
|
||||
let game = games.iter().find(|&g| g.app_id == input).unwrap();
|
||||
|
||||
let launcher_path = std::env::current_exe().unwrap();
|
||||
let launcher_path = env::current_exe().unwrap();
|
||||
let target_path = path.join("alterware-launcher.exe");
|
||||
|
||||
if launcher_path != target_path {
|
||||
fs::copy(launcher_path, target_path).unwrap();
|
||||
println!("Launcher copied to {}", path.display());
|
||||
}
|
||||
auto_install(path, game).await;
|
||||
auto_install(path, game, master_url).await;
|
||||
println!("Installation complete. Please run the launcher again or use a shortcut to launch the game.");
|
||||
std::io::stdin().read_line(&mut String::new()).unwrap();
|
||||
break;
|
||||
@ -157,32 +155,36 @@ async fn windows_launcher_install(games: &Vec<Game<'_>>) {
|
||||
}
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
manual_install(games).await;
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_client_selection(games: &[Game]) -> String {
|
||||
println!(
|
||||
"Couldn't detect any games, please select a client to install in the current directory:"
|
||||
"No installed games found. Make sure to place the launcher in the game directory."
|
||||
);
|
||||
for (i, g) in games.iter().enumerate() {
|
||||
for c in g.client.iter() {
|
||||
println!("{}: {}", i, c);
|
||||
}
|
||||
}
|
||||
let input: usize = misc::stdin().parse().unwrap();
|
||||
String::from(games[input].client[0])
|
||||
}
|
||||
|
||||
async fn manual_install(games: &[Game<'_>]) {
|
||||
let selection = prompt_client_selection(games);
|
||||
let game = games.iter().find(|&g| g.client[0] == selection).unwrap();
|
||||
update(game, &std::env::current_dir().unwrap(), false, false).await;
|
||||
println!("Installation complete. Please run the launcher again or use a shortcut to launch the game.");
|
||||
std::io::stdin().read_line(&mut String::new()).unwrap();
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// fn prompt_client_selection(games: &[Game]) -> String {
|
||||
// println!(
|
||||
// "Couldn't detect any games, please select a client to install in the current directory:"
|
||||
// );
|
||||
// for (i, g) in games.iter().enumerate() {
|
||||
// for c in g.client.iter() {
|
||||
// println!("{}: {}", i, c);
|
||||
// }
|
||||
// }
|
||||
// let input: usize = misc::stdin().parse().unwrap();
|
||||
// String::from(games[input].client[0])
|
||||
// }
|
||||
|
||||
// async fn manual_install(games: &[Game<'_>]) {
|
||||
// let selection = prompt_client_selection(games);
|
||||
// let game = games.iter().find(|&g| g.client[0] == selection).unwrap();
|
||||
// update(game, &env::current_dir().unwrap(), false, false).await;
|
||||
// println!("Installation complete. Please run the launcher again or use a shortcut to launch the game.");
|
||||
// std::io::stdin().read_line(&mut String::new()).unwrap();
|
||||
// std::process::exit(0);
|
||||
// }
|
||||
|
||||
fn total_download_size(cdn_info: &Vec<CdnFile>, remote_dir: &str) -> u64 {
|
||||
let remote_dir = format!("{}/", remote_dir);
|
||||
let mut size: u64 = 0;
|
||||
@ -201,6 +203,8 @@ async fn update_dir(
|
||||
dir: &Path,
|
||||
hashes: &mut HashMap<String, String>,
|
||||
pb: &ProgressBar,
|
||||
skip_iw4x_sp: bool,
|
||||
master_url: &String,
|
||||
) {
|
||||
misc::pb_style_download(pb, false);
|
||||
|
||||
@ -212,6 +216,9 @@ async fn update_dir(
|
||||
if !file.name.starts_with(&remote_dir_pre) || file.name == "iw4/iw4x.dll" {
|
||||
continue;
|
||||
}
|
||||
if skip_iw4x_sp && file.name == "iw4/iw4x-sp.exe" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let sha1_remote = file.hash.to_lowercase();
|
||||
let file_name = &file.name.replace(remote_dir_pre.as_str(), "");
|
||||
@ -231,6 +238,7 @@ async fn update_dir(
|
||||
"Checked".bright_blue(),
|
||||
misc::cute_path(&file_path)
|
||||
));
|
||||
hashes.insert(file_name.to_owned(), file.hash.to_lowercase());
|
||||
}
|
||||
} else {
|
||||
files_to_download.push(file.clone());
|
||||
@ -262,10 +270,10 @@ async fn update_dir(
|
||||
fs::create_dir_all(parent).unwrap();
|
||||
}
|
||||
}
|
||||
http_async::download_file(
|
||||
http_async::download_file_progress(
|
||||
&client,
|
||||
pb,
|
||||
&format!("{}/{}", MASTER, file.name),
|
||||
&format!("{}/{}", master_url, file.name),
|
||||
&file_path,
|
||||
file.size as u64,
|
||||
)
|
||||
@ -276,11 +284,31 @@ async fn update_dir(
|
||||
misc::pb_style_download(pb, false);
|
||||
}
|
||||
|
||||
async fn update(game: &Game<'_>, dir: &Path, bonus_content: bool, force: bool) {
|
||||
let cdn_info: Vec<CdnFile> = serde_json::from_str(&http::get_body_string(
|
||||
format!("{}/files.json", MASTER).as_str(),
|
||||
))
|
||||
async fn update(
|
||||
game: &Game<'_>,
|
||||
dir: &Path,
|
||||
bonus_content: bool,
|
||||
force: bool,
|
||||
skip_iw4x_sp: Option<bool>,
|
||||
master_url: &String,
|
||||
ignore_required_files: Option<bool>,
|
||||
) {
|
||||
let skip_iw4x_sp = skip_iw4x_sp.unwrap_or(false);
|
||||
let ignore_required_files = ignore_required_files.unwrap_or(false);
|
||||
|
||||
let res = http_async::get_body_string(format!("{}/files.json", master_url).as_str())
|
||||
.await
|
||||
.unwrap();
|
||||
let cdn_info: Vec<CdnFile> = serde_json::from_str(&res).unwrap();
|
||||
|
||||
if !ignore_required_files && !game.required_files_exist(dir) {
|
||||
println!(
|
||||
"{}\nVerify game file integrity on Steam or reinstall the game.",
|
||||
"Critical game files missing.".bright_red()
|
||||
);
|
||||
std::io::stdin().read_line(&mut String::new()).unwrap();
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
let mut hashes = HashMap::new();
|
||||
let hash_file = dir.join(".sha-sums");
|
||||
@ -294,21 +322,127 @@ async fn update(game: &Game<'_>, dir: &Path, bonus_content: bool, force: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
let pb = ProgressBar::new(0);
|
||||
update_dir(&cdn_info, game.engine, dir, &mut hashes, &pb).await;
|
||||
|
||||
if game.engine == "iw4" {
|
||||
iw4x::update(dir);
|
||||
iw4x::update(dir).await;
|
||||
|
||||
let iw4x_dirs = vec!["iw4x", "zone/patch"];
|
||||
for d in &iw4x_dirs {
|
||||
if let Ok(dir_iter) = dir.join(d).read_dir() {
|
||||
'outer: for file in dir_iter.filter_map(|entry| entry.ok()) {
|
||||
let file_path = file.path();
|
||||
|
||||
if file_path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file_path_rel = match file_path.strip_prefix(dir) {
|
||||
Ok(rel) => rel.to_path_buf(),
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if iw4x_dirs
|
||||
.iter()
|
||||
.any(|prefix| file_path_rel.starts_with(Path::new(prefix)))
|
||||
{
|
||||
if !cdn_info
|
||||
.iter()
|
||||
.any(|cdn_file| cdn_file.name.starts_with("iw4"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let should_continue = cdn_info.iter().any(|cdn_file| {
|
||||
let path_rem = Path::new(&cdn_file.name)
|
||||
.strip_prefix(Path::new("iw4"))
|
||||
.unwrap_or_else(|_| Path::new(&cdn_file.name));
|
||||
path_rem == file_path_rel
|
||||
});
|
||||
|
||||
if should_continue {
|
||||
continue 'outer;
|
||||
}
|
||||
|
||||
println!(
|
||||
"[{}] {}",
|
||||
"Removed".bright_red(),
|
||||
misc::cute_path(&file_path)
|
||||
);
|
||||
|
||||
if fs::remove_file(&file_path).is_err() {
|
||||
println!(
|
||||
"[{}] Couldn't delete {}",
|
||||
"Error".bright_red(),
|
||||
misc::cute_path(&file_path)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let pb = ProgressBar::new(0);
|
||||
update_dir(
|
||||
&cdn_info,
|
||||
game.engine,
|
||||
dir,
|
||||
&mut hashes,
|
||||
&pb,
|
||||
skip_iw4x_sp,
|
||||
master_url,
|
||||
)
|
||||
.await;
|
||||
|
||||
if bonus_content && !game.bonus.is_empty() {
|
||||
for bonus in game.bonus.iter() {
|
||||
update_dir(&cdn_info, bonus, dir, &mut hashes, &pb).await;
|
||||
update_dir(
|
||||
&cdn_info,
|
||||
bonus,
|
||||
dir,
|
||||
&mut hashes,
|
||||
&pb,
|
||||
skip_iw4x_sp,
|
||||
master_url,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
pb.finish();
|
||||
|
||||
for f in game.delete.iter() {
|
||||
let file_path = dir.join(f);
|
||||
if file_path.is_file() {
|
||||
if fs::remove_file(&file_path).is_err() {
|
||||
println!(
|
||||
"[{}] Couldn't delete {}",
|
||||
"Error".bright_red(),
|
||||
misc::cute_path(&file_path)
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"[{}] {}",
|
||||
"Removed".bright_red(),
|
||||
misc::cute_path(&file_path)
|
||||
);
|
||||
}
|
||||
} else if file_path.is_dir() {
|
||||
if fs::remove_dir_all(&file_path).is_err() {
|
||||
println!(
|
||||
"[{}] Couldn't delete {}",
|
||||
"Error".bright_red(),
|
||||
misc::cute_path(&file_path)
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"[{}] {}",
|
||||
"Removed".bright_red(),
|
||||
misc::cute_path(&file_path)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut hash_file_content = String::new();
|
||||
for (file, hash) in hashes.iter() {
|
||||
hash_file_content.push_str(&format!("{} {}\n", hash, file));
|
||||
@ -334,6 +468,22 @@ fn setup_env() {
|
||||
println!("{:#?}", error);
|
||||
colored::control::SHOULD_COLORIZE.set_override(false);
|
||||
});
|
||||
|
||||
if let Ok(system_root) = env::var("SystemRoot") {
|
||||
if let Ok(current_dir) = env::current_dir() {
|
||||
if current_dir.starts_with(system_root) {
|
||||
if let Ok(current_exe) = env::current_exe() {
|
||||
if let Some(parent) = current_exe.parent() {
|
||||
if let Err(error) = env::set_current_dir(parent) {
|
||||
eprintln!("{:#?}", error);
|
||||
} else {
|
||||
println!("Running from the system directory. Changed working directory to the executable location.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn arg_value(args: &[String], arg: &str) -> Option<String> {
|
||||
@ -361,8 +511,7 @@ fn arg_remove_value(args: &mut Vec<String>, arg: &str) {
|
||||
async fn main() {
|
||||
#[cfg(windows)]
|
||||
setup_env();
|
||||
|
||||
let mut args: Vec<String> = std::env::args().collect();
|
||||
let mut args: Vec<String> = env::args().collect();
|
||||
|
||||
if arg_bool(&args, "--help") {
|
||||
println!("CLI Args:");
|
||||
@ -375,6 +524,7 @@ async fn main() {
|
||||
println!(" --force/-f: Force file hash recheck");
|
||||
println!(" --pass <args>: Pass arguments to the game");
|
||||
println!(" --skip-launcher-update: Skip launcher self-update");
|
||||
println!(" --ignore-required-files: Skip required files check");
|
||||
println!(
|
||||
"\nExample:\n alterware-launcher.exe iw4x --bonus --pass \"-console -nointro\""
|
||||
);
|
||||
@ -409,13 +559,19 @@ async fn main() {
|
||||
install_path = PathBuf::from(path);
|
||||
arg_remove_value(&mut args, "-p");
|
||||
} else {
|
||||
install_path = std::env::current_dir().unwrap();
|
||||
install_path = env::current_dir().unwrap();
|
||||
}
|
||||
|
||||
let mut cfg = config::load(install_path.join("alterware-launcher.json"));
|
||||
|
||||
let master_url = if cfg.use_https {
|
||||
format!("https://{}", MASTER)
|
||||
} else {
|
||||
format!("http://{}", MASTER)
|
||||
};
|
||||
|
||||
if !arg_bool(&args, "--skip-launcher-update") && !cfg.skip_self_update {
|
||||
self_update::run(cfg.update_only);
|
||||
self_update::run(cfg.update_only).await;
|
||||
} else {
|
||||
arg_remove(&mut args, "--skip-launcher-update");
|
||||
}
|
||||
@ -438,15 +594,27 @@ async fn main() {
|
||||
arg_remove(&mut args, "-f");
|
||||
}
|
||||
|
||||
let ignore_required_files = arg_bool(&args, "--ignore-required-files");
|
||||
if ignore_required_files {
|
||||
arg_remove(&mut args, "--ignore-required-files");
|
||||
}
|
||||
|
||||
if let Some(pass) = arg_value(&args, "--pass") {
|
||||
cfg.args = pass;
|
||||
arg_remove_value(&mut args, "--pass");
|
||||
} else if cfg.args.is_empty() {
|
||||
cfg.args = String::from("");
|
||||
cfg.args = String::default();
|
||||
}
|
||||
|
||||
let games_json = http::get_body_string(format!("{}/games.json", MASTER).as_str());
|
||||
let games: Vec<Game> = serde_json::from_str(&games_json).unwrap();
|
||||
let games_json = http_async::get_body_string(format!("{}/games.json", master_url).as_str())
|
||||
.await
|
||||
.unwrap();
|
||||
let games: Vec<Game> = serde_json::from_str(&games_json).unwrap_or_else(|error| {
|
||||
println!("Error parsing games.json: {:#?}", error);
|
||||
fs::write("alterware-launcher-error.txt", &games_json).unwrap();
|
||||
misc::stdin();
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
||||
let mut game: String = String::new();
|
||||
if args.len() > 1 {
|
||||
@ -462,7 +630,7 @@ async fn main() {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
setup_client_links(g, &std::env::current_dir().unwrap());
|
||||
setup_client_links(g, &env::current_dir().unwrap());
|
||||
|
||||
#[cfg(not(windows))]
|
||||
println!("Multiple clients installed, set the client as the first argument to launch a specific client.");
|
||||
@ -483,6 +651,23 @@ async fn main() {
|
||||
for g in games.iter() {
|
||||
for c in g.client.iter() {
|
||||
if c == &game {
|
||||
if cfg.engine.is_empty() {
|
||||
cfg.engine = String::from(g.engine);
|
||||
config::save_value_s(
|
||||
install_path.join("alterware-launcher.json"),
|
||||
"engine",
|
||||
cfg.engine.clone(),
|
||||
);
|
||||
if cfg.engine == "iw4" && cfg.args.is_empty() {
|
||||
cfg.args = String::from("-stdout");
|
||||
config::save_value_s(
|
||||
install_path.join("alterware-launcher.json"),
|
||||
"args",
|
||||
cfg.args.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.ask_bonus_content && !g.bonus.is_empty() {
|
||||
println!("Download bonus content? (Y/n)");
|
||||
let input = misc::stdin().to_ascii_lowercase();
|
||||
@ -504,6 +689,9 @@ async fn main() {
|
||||
install_path.as_path(),
|
||||
cfg.download_bonus_content,
|
||||
cfg.force_update,
|
||||
Some(&game != "iw4x-sp"),
|
||||
&master_url,
|
||||
Some(ignore_required_files),
|
||||
)
|
||||
.await;
|
||||
if !cfg.update_only {
|
||||
@ -515,10 +703,7 @@ async fn main() {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
windows_launcher_install(&games).await;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
manual_install(&games).await;
|
||||
windows_launcher_install(&games, &master_url).await;
|
||||
|
||||
println!("{}", "Game not found!".bright_red());
|
||||
println!("Place the launcher in the game folder, if that doesn't work specify the client on the command line (ex. alterware-launcher.exe iw4-sp)");
|
||||
|
@ -2,34 +2,45 @@ use crate::github;
|
||||
use crate::global::*;
|
||||
|
||||
use semver::Version;
|
||||
#[cfg(not(windows))]
|
||||
use std::{thread, time};
|
||||
|
||||
pub fn self_update_available() -> bool {
|
||||
pub async fn self_update_available() -> bool {
|
||||
let current_version: Version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
|
||||
let latest_version = github::latest_version(GH_OWNER, GH_REPO);
|
||||
let latest_version = github::latest_version(GH_OWNER, GH_REPO).await;
|
||||
|
||||
current_version < latest_version
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn run(_update_only: bool) {
|
||||
if self_update_available() {
|
||||
pub async fn run(_update_only: bool) {
|
||||
if self_update_available().await {
|
||||
println!("A new version of the AlterWare launcher is available.");
|
||||
println!(
|
||||
"Download it at {}",
|
||||
github::latest_release_url(GH_OWNER, GH_REPO)
|
||||
);
|
||||
println!("Launching in 10 seconds..");
|
||||
thread::sleep(time::Duration::from_secs(10));
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn run(update_only: bool) {
|
||||
pub fn restart() -> std::io::Error {
|
||||
use std::os::windows::process::CommandExt;
|
||||
match std::process::Command::new(std::env::current_exe().unwrap())
|
||||
.args(std::env::args().skip(1))
|
||||
.creation_flags(0x00000010) // CREATE_NEW_CONSOLE
|
||||
.spawn()
|
||||
{
|
||||
Ok(_) => std::process::exit(0),
|
||||
Err(err) => err,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub async fn run(update_only: bool) {
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use crate::http;
|
||||
use crate::http_async;
|
||||
use crate::misc;
|
||||
|
||||
let working_dir = std::env::current_dir().unwrap();
|
||||
@ -43,11 +54,13 @@ pub fn run(update_only: bool) {
|
||||
&& (file_name.contains(".__relocated__.exe")
|
||||
|| file_name.contains(".__selfdelete__.exe"))
|
||||
{
|
||||
fs::remove_file(file.path()).unwrap();
|
||||
fs::remove_file(file.path()).unwrap_or_else(|_| {
|
||||
println!("Failed to remove old launcher file.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if self_update_available() {
|
||||
if self_update_available().await {
|
||||
println!("Performing launcher self-update.");
|
||||
println!(
|
||||
"If you run into any issues, please download the latest version at {}",
|
||||
@ -66,15 +79,17 @@ pub fn run(update_only: bool) {
|
||||
} else {
|
||||
"alterware-launcher.exe"
|
||||
};
|
||||
println!("{}", launcher_name);
|
||||
http::download_file(
|
||||
|
||||
http_async::download_file(
|
||||
&format!(
|
||||
"{}/download/{}",
|
||||
github::latest_release_url(GH_OWNER, GH_REPO),
|
||||
launcher_name
|
||||
),
|
||||
&file_path,
|
||||
);
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
if !file_path.exists() {
|
||||
println!("Failed to download launcher update.");
|
||||
@ -83,12 +98,12 @@ pub fn run(update_only: bool) {
|
||||
|
||||
self_replace::self_replace("alterware-launcher-update.exe").unwrap();
|
||||
fs::remove_file(&file_path).unwrap();
|
||||
println!(
|
||||
"Launcher updated. View the changelog at https://github.com/{}/{}/releases/latest",
|
||||
GH_OWNER, GH_REPO,
|
||||
);
|
||||
println!("Please restart the launcher.");
|
||||
|
||||
// restarting spawns a new console, automation should manually restart on exit code 201
|
||||
if !update_only {
|
||||
let restart_error = restart().to_string();
|
||||
println!("Failed to restart launcher: {}", restart_error);
|
||||
println!("Please restart the launcher manually.");
|
||||
misc::stdin();
|
||||
}
|
||||
std::process::exit(201);
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CdnFile {
|
||||
pub name: String,
|
||||
@ -12,6 +14,21 @@ pub struct Game<'a> {
|
||||
pub references: Vec<&'a str>,
|
||||
pub app_id: u32,
|
||||
pub bonus: Vec<&'a str>,
|
||||
pub delete: Vec<&'a str>,
|
||||
pub required: Vec<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> Game<'a> {
|
||||
pub fn required_files_exist(&self, dir: &Path) -> bool {
|
||||
for required_file in &self.required {
|
||||
let file_path = dir.join(required_file);
|
||||
if !file_path.exists() {
|
||||
println!("Required file {} does not exist", file_path.display());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
@ -22,6 +39,10 @@ pub struct Config {
|
||||
pub ask_bonus_content: bool,
|
||||
pub force_update: bool,
|
||||
pub args: String,
|
||||
#[serde(default)]
|
||||
pub engine: String,
|
||||
#[serde(default)]
|
||||
pub use_https: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@ -32,7 +53,9 @@ impl Default for Config {
|
||||
download_bonus_content: false,
|
||||
ask_bonus_content: true,
|
||||
force_update: false,
|
||||
args: String::from(""),
|
||||
args: String::default(),
|
||||
engine: String::default(),
|
||||
use_https: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user