72 Commits

Author SHA1 Message Date
f4ac00d29f v0.11.6 2026-03-13 09:38:06 +01:00
b45ef12f5a Merge pull request #41 from alterware/dependabot/cargo/reqwest-0.13.2
build(deps): bump reqwest from 0.12.28 to 0.13.2
2026-03-11 14:35:42 +01:00
2b61682464 Merge pull request #40 from alterware/dependabot/github_actions/taiki-e/upload-rust-binary-action-1.28.0
build(deps): bump taiki-e/upload-rust-binary-action from 1.27.0 to 1.28.0
2026-03-11 14:35:34 +01:00
7928e4dbfb Merge pull request #42 from alterware/dependabot/cargo/indicatif-0.18.4
build(deps): bump indicatif from 0.18.3 to 0.18.4
2026-03-11 14:35:24 +01:00
863b9266b8 Merge pull request #43 from alterware/dependabot/cargo/serial_test-3.4.0
build(deps): bump serial_test from 3.2.0 to 3.4.0
2026-03-11 14:35:15 +01:00
cb2a278b14 Merge pull request #44 from alterware/dependabot/cargo/futures-util-0.3.32
build(deps): bump futures-util from 0.3.31 to 0.3.32
2026-03-11 14:35:07 +01:00
fb18d179b0 Merge pull request #39 from mxve/main
check http status code
2026-03-11 14:23:35 +01:00
dependabot[bot]
cc77ef778e build(deps): bump futures-util from 0.3.31 to 0.3.32
Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.31 to 0.3.32.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.31...0.3.32)

---
updated-dependencies:
- dependency-name: futures-util
  dependency-version: 0.3.32
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 14:38:30 +00:00
dependabot[bot]
a3cb1bd6aa build(deps): bump serial_test from 3.2.0 to 3.4.0
Bumps [serial_test](https://github.com/palfrey/serial_test) from 3.2.0 to 3.4.0.
- [Release notes](https://github.com/palfrey/serial_test/releases)
- [Commits](https://github.com/palfrey/serial_test/compare/v3.2.0...v3.4.0)

---
updated-dependencies:
- dependency-name: serial_test
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 14:38:20 +00:00
dependabot[bot]
24c35c577f build(deps): bump indicatif from 0.18.3 to 0.18.4
Bumps [indicatif](https://github.com/console-rs/indicatif) from 0.18.3 to 0.18.4.
- [Release notes](https://github.com/console-rs/indicatif/releases)
- [Commits](https://github.com/console-rs/indicatif/compare/0.18.3...0.18.4)

---
updated-dependencies:
- dependency-name: indicatif
  dependency-version: 0.18.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 14:38:11 +00:00
dependabot[bot]
ff4d75bc7c build(deps): bump reqwest from 0.12.28 to 0.13.2
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.28 to 0.13.2.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.28...v0.13.2)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.13.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 14:38:01 +00:00
dependabot[bot]
0b700bd825 build(deps): bump taiki-e/upload-rust-binary-action
Bumps [taiki-e/upload-rust-binary-action](https://github.com/taiki-e/upload-rust-binary-action) from 1.27.0 to 1.28.0.
- [Release notes](https://github.com/taiki-e/upload-rust-binary-action/releases)
- [Changelog](https://github.com/taiki-e/upload-rust-binary-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/upload-rust-binary-action/compare/v1.27.0...v1.28.0)

---
updated-dependencies:
- dependency-name: taiki-e/upload-rust-binary-action
  dependency-version: 1.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-01 14:37:35 +00:00
c8d8964a33 check http status code
prevent fnaf morphing
2026-02-08 08:07:38 +01:00
4f5f1bc1a5 Merge pull request #31 from alterware/dependabot/github_actions/actions/checkout-6
build(deps): bump actions/checkout from 5 to 6
2026-02-02 10:44:22 +01:00
dependabot[bot]
c455278ca6 build(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-02 09:42:22 +00:00
86a3587aa7 Merge pull request #32 from alterware/dependabot/cargo/static_vcruntime-3.0.0
build(deps): bump static_vcruntime from 2.0.0 to 3.0.0
2026-02-02 10:40:37 +01:00
83d353ffba Merge pull request #30 from alterware/dependabot/github_actions/actions/cache-5
build(deps): bump actions/cache from 4 to 5
2026-02-02 10:40:21 +01:00
902fc70b56 Merge pull request #33 from alterware/dependabot/cargo/reqwest-0.12.28
build(deps): bump reqwest from 0.12.24 to 0.12.28
2026-02-02 10:40:11 +01:00
9a9153fc93 Merge pull request #34 from alterware/dependabot/cargo/indicatif-0.18.3
build(deps): bump indicatif from 0.18.0 to 0.18.3
2026-02-02 10:40:03 +01:00
c4425b786e Merge pull request #35 from alterware/dependabot/cargo/openssl-0.10.75
build(deps): bump openssl from 0.10.74 to 0.10.75
2026-02-02 10:39:55 +01:00
3d609ff570 Merge pull request #38 from alterware/dependabot/github_actions/taiki-e/create-gh-release-action-1.9.2
build(deps): bump taiki-e/create-gh-release-action from 1.9.1 to 1.9.2
2026-02-02 10:39:46 +01:00
dependabot[bot]
6be4c1a8e5 build(deps): bump taiki-e/create-gh-release-action from 1.9.1 to 1.9.2
Bumps [taiki-e/create-gh-release-action](https://github.com/taiki-e/create-gh-release-action) from 1.9.1 to 1.9.2.
- [Release notes](https://github.com/taiki-e/create-gh-release-action/releases)
- [Changelog](https://github.com/taiki-e/create-gh-release-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/create-gh-release-action/compare/v1.9.1...v1.9.2)

---
updated-dependencies:
- dependency-name: taiki-e/create-gh-release-action
  dependency-version: 1.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-01 14:37:11 +00:00
dependabot[bot]
f1cd1f225d build(deps): bump openssl from 0.10.74 to 0.10.75
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.74 to 0.10.75.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.74...openssl-v0.10.75)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.75
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 14:24:08 +00:00
dependabot[bot]
ec221ed543 build(deps): bump indicatif from 0.18.0 to 0.18.3
Bumps [indicatif](https://github.com/console-rs/indicatif) from 0.18.0 to 0.18.3.
- [Release notes](https://github.com/console-rs/indicatif/releases)
- [Commits](https://github.com/console-rs/indicatif/compare/0.18.0...0.18.3)

---
updated-dependencies:
- dependency-name: indicatif
  dependency-version: 0.18.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 14:23:59 +00:00
dependabot[bot]
b8cec3a404 build(deps): bump reqwest from 0.12.24 to 0.12.28
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.24 to 0.12.28.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.24...v0.12.28)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.12.28
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 14:23:49 +00:00
dependabot[bot]
a17e47b97d build(deps): bump static_vcruntime from 2.0.0 to 3.0.0
Bumps [static_vcruntime](https://github.com/ChrisDenton/static_vcruntime) from 2.0.0 to 3.0.0.
- [Commits](https://github.com/ChrisDenton/static_vcruntime/compare/2.0...3.0)

---
updated-dependencies:
- dependency-name: static_vcruntime
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 14:23:36 +00:00
dependabot[bot]
24d66aab75 build(deps): bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 14:23:17 +00:00
alterware
4e7f2fa03b chore: remove us-cdn 2025-11-30 17:43:43 +01:00
alterware
f9a64a9a45 chore: remove unused but there is like 20 more 2025-11-21 16:47:25 +01:00
alterware
72ac6d56aa chore: remove dead service (2nd attempt) 2025-11-21 16:44:07 +01:00
alterware
695a8174c8 chore: remove dead service 2025-11-21 16:29:45 +01:00
36aab56037 Merge pull request #29 from alterware/dependabot/cargo/openssl-0.10.74
Bump openssl from 0.10.73 to 0.10.74
2025-11-04 12:57:12 +01:00
79477bf231 Merge pull request #26 from alterware/dependabot/cargo/simple-log-2.4.0
Bump simple-log from 2.3.0 to 2.4.0
2025-11-04 12:56:59 +01:00
3d9bb6c424 Merge pull request #27 from alterware/dependabot/cargo/rand-0.9.2
Bump rand from 0.9.1 to 0.9.2
2025-11-04 12:56:51 +01:00
334e989c2d Merge pull request #28 from alterware/dependabot/cargo/reqwest-0.12.24
Bump reqwest from 0.12.23 to 0.12.24
2025-11-04 12:56:42 +01:00
dependabot[bot]
b4b6c93e3d Bump openssl from 0.10.73 to 0.10.74
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.73 to 0.10.74.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.73...openssl-v0.10.74)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.74
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 14:17:28 +00:00
dependabot[bot]
b658ac5ae1 Bump reqwest from 0.12.23 to 0.12.24
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.23 to 0.12.24.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.23...v0.12.24)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.12.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 14:17:19 +00:00
dependabot[bot]
57a3c315bf Bump rand from 0.9.1 to 0.9.2
Bumps [rand](https://github.com/rust-random/rand) from 0.9.1 to 0.9.2.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/rand_core-0.9.1...rand_core-0.9.2)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 14:17:09 +00:00
dependabot[bot]
3717f1315e Bump simple-log from 2.3.0 to 2.4.0
Bumps [simple-log](https://github.com/baoyachi/simple-log) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/baoyachi/simple-log/releases)
- [Commits](https://github.com/baoyachi/simple-log/compare/v2.3.0...v2.4.0)

---
updated-dependencies:
- dependency-name: simple-log
  dependency-version: 2.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 14:17:01 +00:00
9442c733f9 Merge pull request #22 from alterware/dependabot/cargo/serde_json-1.0.145
Bump serde_json from 1.0.142 to 1.0.145
2025-10-09 10:02:50 +02:00
71a3ccdf47 Merge pull request #21 from alterware/dependabot/cargo/reqwest-0.12.23
Bump reqwest from 0.12.22 to 0.12.23
2025-10-09 10:02:42 +02:00
2454b25d56 Merge pull request #23 from alterware/dependabot/cargo/semver-1.0.27
Bump semver from 1.0.26 to 1.0.27
2025-10-09 10:02:34 +02:00
c8155761f2 Merge pull request #24 from alterware/dependabot/cargo/tokio-1.47.1
Bump tokio from 1.45.1 to 1.47.1
2025-10-09 10:02:26 +02:00
ab872bd2ab Merge pull request #25 from alterware/dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-10-09 10:02:16 +02:00
dependabot[bot]
7f977ea680 Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 14:38:55 +00:00
dependabot[bot]
cfa3629fa0 Bump tokio from 1.45.1 to 1.47.1
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.45.1 to 1.47.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.1...tokio-1.47.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.47.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 14:34:32 +00:00
dependabot[bot]
0b35a865b4 Bump semver from 1.0.26 to 1.0.27
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.26 to 1.0.27.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.26...1.0.27)

---
updated-dependencies:
- dependency-name: semver
  dependency-version: 1.0.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 14:34:22 +00:00
dependabot[bot]
cc62261b2f Bump serde_json from 1.0.142 to 1.0.145
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.142 to 1.0.145.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.142...v1.0.145)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.145
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 14:34:11 +00:00
dependabot[bot]
cfc9826fb0 Bump reqwest from 0.12.22 to 0.12.23
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.22 to 0.12.23.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.22...v0.12.23)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.12.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 14:34:00 +00:00
066311f7bb Merge pull request #20 from alterware/dependabot/cargo/reqwest-0.12.22
Bump reqwest from 0.12.21 to 0.12.22
2025-08-06 09:15:39 +02:00
d9b7f7fc07 Merge pull request #19 from alterware/dependabot/cargo/indicatif-0.18.0
Bump indicatif from 0.17.12 to 0.18.0
2025-08-06 09:15:30 +02:00
1f7142b30b Merge pull request #18 from alterware/dependabot/cargo/winresource-0.1.23
Bump winresource from 0.1.19 to 0.1.23
2025-08-06 09:15:24 +02:00
b69f2e3338 Merge pull request #17 from alterware/dependabot/cargo/serde_json-1.0.142
Bump serde_json from 1.0.140 to 1.0.142
2025-08-06 09:15:07 +02:00
dependabot[bot]
2cd227fec4 Bump reqwest from 0.12.21 to 0.12.22
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.21 to 0.12.22.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.21...v0.12.22)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.12.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 15:05:55 +00:00
dependabot[bot]
c9cb2c3604 Bump indicatif from 0.17.12 to 0.18.0
Bumps [indicatif](https://github.com/console-rs/indicatif) from 0.17.12 to 0.18.0.
- [Release notes](https://github.com/console-rs/indicatif/releases)
- [Commits](https://github.com/console-rs/indicatif/compare/0.17.12...0.18.0)

---
updated-dependencies:
- dependency-name: indicatif
  dependency-version: 0.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 15:05:43 +00:00
dependabot[bot]
2c2184a8b3 Bump winresource from 0.1.19 to 0.1.23
Bumps [winresource](https://github.com/BenjaminRi/winresource) from 0.1.19 to 0.1.23.
- [Commits](https://github.com/BenjaminRi/winresource/commits)

---
updated-dependencies:
- dependency-name: winresource
  dependency-version: 0.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 15:05:34 +00:00
dependabot[bot]
609bfde418 Bump serde_json from 1.0.140 to 1.0.142
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.140 to 1.0.142.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.140...v1.0.142)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.142
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 15:05:25 +00:00
alterware
a2e4f304dc chore: more linting 2025-07-03 10:32:57 +02:00
alterware
2dab50111b chore: some linting 2025-07-03 10:27:52 +02:00
27795f6680 Merge pull request #13 from alterware/dependabot/cargo/openssl-0.10.73
Bump openssl from 0.10.71 to 0.10.73
2025-07-03 09:41:24 +02:00
39db6099e4 Merge pull request #12 from alterware/dependabot/cargo/reqwest-0.12.21
Bump reqwest from 0.12.20 to 0.12.21
2025-07-03 09:41:00 +02:00
0493a7a4d8 Merge pull request #14 from alterware/dependabot/cargo/indicatif-0.17.12
Bump indicatif from 0.17.11 to 0.17.12
2025-07-03 09:40:49 +02:00
bb9ebcf830 Merge pull request #15 from alterware/dependabot/cargo/semver-1.0.26
Bump semver from 1.0.25 to 1.0.26
2025-07-03 09:40:32 +02:00
1e2dca0162 Merge pull request #16 from alterware/dependabot/github_actions/taiki-e/upload-rust-binary-action-1.27.0
Bump taiki-e/upload-rust-binary-action from 1.26.0 to 1.27.0
2025-07-03 09:40:21 +02:00
dependabot[bot]
d4e7cb1eb1 Bump taiki-e/upload-rust-binary-action from 1.26.0 to 1.27.0
Bumps [taiki-e/upload-rust-binary-action](https://github.com/taiki-e/upload-rust-binary-action) from 1.26.0 to 1.27.0.
- [Release notes](https://github.com/taiki-e/upload-rust-binary-action/releases)
- [Changelog](https://github.com/taiki-e/upload-rust-binary-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/upload-rust-binary-action/compare/v1.26.0...v1.27.0)

---
updated-dependencies:
- dependency-name: taiki-e/upload-rust-binary-action
  dependency-version: 1.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 14:48:32 +00:00
dependabot[bot]
cb2f433c39 Bump semver from 1.0.25 to 1.0.26
Bumps [semver](https://github.com/dtolnay/semver) from 1.0.25 to 1.0.26.
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.25...1.0.26)

---
updated-dependencies:
- dependency-name: semver
  dependency-version: 1.0.26
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 14:44:26 +00:00
dependabot[bot]
764a892f71 Bump indicatif from 0.17.11 to 0.17.12
Bumps [indicatif](https://github.com/console-rs/indicatif) from 0.17.11 to 0.17.12.
- [Release notes](https://github.com/console-rs/indicatif/releases)
- [Commits](https://github.com/console-rs/indicatif/compare/0.17.11...0.17.12)

---
updated-dependencies:
- dependency-name: indicatif
  dependency-version: 0.17.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 14:44:19 +00:00
dependabot[bot]
66554a0374 Bump openssl from 0.10.71 to 0.10.73
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.71 to 0.10.73.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.71...openssl-v0.10.73)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.73
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 14:44:12 +00:00
dependabot[bot]
e96e0ca630 Bump reqwest from 0.12.20 to 0.12.21
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.20 to 0.12.21.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/commits)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.12.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 14:44:04 +00:00
alterware
a30d6950c8 chore: remove more iw4x stuff 2025-06-30 18:27:03 +02:00
alterware
6f241dffe2 v0.11.2 2025-06-13 08:35:26 +02:00
Spencer
806758088d maint: use UMU if found (#11) 2025-06-13 08:30:55 +02:00
16 changed files with 592 additions and 701 deletions

View File

@@ -15,7 +15,7 @@ jobs:
os: ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
@@ -23,7 +23,7 @@ jobs:
target: ${{ matrix.target }}
- name: Cache dependencies
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
@@ -46,7 +46,7 @@ jobs:
os: ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
@@ -54,7 +54,7 @@ jobs:
target: ${{ matrix.target }}
- name: Cache dependencies
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
@@ -77,7 +77,7 @@ jobs:
os: ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
@@ -86,7 +86,7 @@ jobs:
components: rustfmt, clippy
- name: Cache dependencies
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.cargo/registry

View File

@@ -9,8 +9,8 @@ jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: taiki-e/create-gh-release-action@v1.9.1
- uses: actions/checkout@v6
- uses: taiki-e/create-gh-release-action@v1.9.2
with:
draft: true
token: ${{ secrets.GITHUB_TOKEN }}
@@ -29,8 +29,8 @@ jobs:
os: windows-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: taiki-e/upload-rust-binary-action@v1.26.0
- uses: actions/checkout@v6
- uses: taiki-e/upload-rust-binary-action@v1.28.0
with:
target: ${{ matrix.target }}
bin: alterware-launcher

725
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[package]
name = "alterware-launcher"
version = "0.11.1"
version = "0.11.6"
edition = "2021"
build = "res/build.rs"
@@ -18,12 +18,12 @@ rand = "0.9"
semver = "1.0"
colored = "3.0"
once_cell = "1.21"
reqwest = { version = "0.12", features = ["stream"] }
reqwest = { version = "0.13", features = ["stream"] }
futures-util = "0.3"
futures = "0.3"
indicatif = "0.17"
tokio = { version="1.45", features = ["rt-multi-thread", "macros"] }
simple-log = "2.3"
indicatif = "0.18"
tokio = { version="1.47", features = ["rt-multi-thread", "macros"] }
simple-log = "2.4"
walkdir = "2.5"
[target.'cfg(unix)'.dependencies]
@@ -37,11 +37,11 @@ self-replace = "1.5"
[build-dependencies]
winresource = "0.1"
static_vcruntime = "2.0"
static_vcruntime = "3.0"
[dev-dependencies]
strip-ansi-escapes = "0.2"
serial_test = "3.2"
serial_test = "3.4"
[package.metadata.winresource]
OriginalFilename = "alterware-launcher.exe"

View File

@@ -146,11 +146,8 @@
- Install or reinstall redistributables
- ```--prerelease```
- Update to prerelease version of the launcher
- ```--rate```
- Rate and display CDN servers
- ```--cdn-url```
- ```--offline```
- ```--skip-connectivity-check```
##### Example:
@@ -175,7 +172,6 @@ alterware-launcher.exe iw6 --bonus -u --path "C:\Games\IW6x" --pass "-headless"
- `prerelease`: Update to prerelease version of clients and launcher. Default: `false`.
- `cdn_url`
- `offline`
- `skip-connectivity-check`
---

View File

@@ -15,7 +15,7 @@ pub fn save_cache(dir: &Path, cache: Cache) {
let cache_path = dir.join("awcache.json");
let cache_serialized = serde_json::to_string_pretty(&cache).unwrap();
fs::write(cache_path, cache_serialized).unwrap_or_else(|e| {
error!("Failed to save cache: {}", e);
error!("Failed to save cache: {e}");
});
}

View File

@@ -6,93 +6,19 @@ use std::time::Duration;
static CURRENT_CDN: Mutex<Option<Arc<Server>>> = Mutex::new(None);
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Region {
Africa,
Asia,
Europe,
NorthAmerica,
Oceania,
SouthAmerica,
Global,
Unknown,
}
impl Region {
pub fn from_str(region_str: &str) -> Self {
match region_str {
"Africa" => Region::Africa,
"Asia" => Region::Asia,
"Europe" => Region::Europe,
"NorthAmerica" => Region::NorthAmerica,
"Oceania" => Region::Oceania,
"SouthAmerica" => Region::SouthAmerica,
_ => Region::Unknown,
}
}
pub fn coordinates(&self) -> Option<(f64, f64)> {
match self {
Region::Europe => Some((54.0, 15.0)),
Region::Asia => Some((35.0, 105.0)),
Region::NorthAmerica => Some((45.0, -100.0)),
Region::SouthAmerica => Some((-15.0, -60.0)),
Region::Africa => Some((0.0, 20.0)),
Region::Oceania => Some((-25.0, 140.0)),
Region::Global => None,
Region::Unknown => None,
}
}
pub fn distance_to(&self, other: Region) -> f64 {
if *self == Region::Global || other == Region::Global {
return 0.0;
}
if *self == other {
return 0.0;
}
let (lat1, lon1) = match self.coordinates() {
Some(coords) => coords,
None => return 20000.0,
};
let (lat2, lon2) = match other.coordinates() {
Some(coords) => coords,
None => return 20000.0,
};
// haversine
let r = 6371.0;
let d_lat = (lat2 - lat1).to_radians();
let d_lon = (lon2 - lon1).to_radians();
let lat1_rad = lat1.to_radians();
let lat2_rad = lat2.to_radians();
let a = (d_lat / 2.0).sin().powi(2)
+ lat1_rad.cos() * lat2_rad.cos() * (d_lon / 2.0).sin().powi(2);
let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
r * c
}
}
#[derive(Clone, Copy, Debug)]
pub struct Server {
pub host: &'static str,
pub rating: u8,
pub latency: Option<std::time::Duration>,
pub region: Region,
}
impl Server {
pub const fn new(host: &'static str, region: Region) -> Self {
pub const fn new(host: &'static str) -> Self {
Server {
host,
rating: 255,
latency: None,
region,
}
}
@@ -100,7 +26,7 @@ impl Server {
format!("https://{}/", self.host)
}
async fn rate(&mut self, asn: u32, user_region: Region, is_initial: bool) {
async fn rate(&mut self, asn: u32, is_initial: bool) {
let timeout = if is_initial {
Duration::from_millis(1000)
} else {
@@ -109,16 +35,15 @@ impl Server {
match http::rating_request(&self.url(), timeout).await {
Ok((latency, is_cloudflare)) => {
self.latency = Some(latency);
self.rating = self.calculate_rating(latency, is_cloudflare, asn, user_region);
self.rating = self.calculate_rating(latency, is_cloudflare, asn);
info!(
"Server {} rated {} ({}ms, rating: {}, cloudflare: {}, region: {:?})",
"Server {} rated {} ({}ms, rating: {}, cloudflare: {})",
self.host,
self.rating,
latency.as_millis(),
self.rating,
is_cloudflare,
self.region
);
}
Err(e) => {
@@ -147,13 +72,7 @@ impl Server {
rating.clamp(1.0, 255.0) as u8
}
fn calculate_rating(
&self,
latency: std::time::Duration,
is_cloudflare: bool,
asn: u32,
user_region: Region,
) -> u8 {
fn calculate_rating(&self, latency: std::time::Duration, is_cloudflare: bool, asn: u32) -> u8 {
let mut rating = self.rate_latency(latency);
// Additional factors for full rating
@@ -165,25 +84,6 @@ impl Server {
}
}
let distance_km = user_region.distance_to(self.region);
let region_multiplier = if self.region == Region::Global {
1.4
} else if distance_km == 0.0 {
1.3
} else if user_region == Region::Unknown {
1.0
} else if distance_km <= 2000.0 {
1.25
} else if distance_km <= 5000.0 {
1.15
} else if distance_km <= 10000.0 {
1.05
} else {
1.0
};
rating = (rating as f32 * region_multiplier).min(255.0) as u8;
rating
}
}
@@ -198,23 +98,13 @@ impl Hosts {
pub async fn new() -> Self {
let cdn_hosts = crate::global::CDN_HOSTS.to_vec();
let mut hosts = Hosts {
let hosts = Hosts {
servers: cdn_hosts,
active_index: RwLock::new(None),
};
let (asn, region_str) = crate::http::get_location_info().await;
let user_region = Region::from_str(&region_str);
info!(
"Detected user region as {:?} (region: {})",
user_region, region_str
);
hosts.rate(asn, user_region, true).await;
if hosts.servers.iter().all(|server| server.rating == 0) {
info!("All CDN servers failed with 1000ms timeout, retrying with 5000ms timeout");
hosts.rate(asn, user_region, false).await;
}
hosts
@@ -250,11 +140,11 @@ impl Hosts {
}
/// rate and order all servers, then select the best one
pub async fn rate(&mut self, asn: u32, user_region: Region, is_initial: bool) {
pub async fn rate(&mut self, asn: u32, is_initial: bool) {
let rating_futures: Vec<_> = self
.servers
.iter_mut()
.map(|server| server.rate(asn, user_region, is_initial))
.map(|server| server.rate(asn, is_initial))
.collect();
join_all(rating_futures).await;
@@ -270,61 +160,3 @@ impl Hosts {
self.active_url()
}
}
/// CDN rating function for --rate flag
pub async fn rate_cdns_and_display() {
use colored::Colorize;
let (asn, region_str) = crate::http::get_location_info().await;
let user_region = Region::from_str(&region_str);
if user_region == Region::Unknown {
println!(
"User region: {} (using Global server preference)",
"Unknown".bright_red()
);
} else {
println!("User region: {:?}", user_region);
}
println!("Rating CDNs...");
let cdn_hosts = crate::global::CDN_HOSTS.to_vec();
let mut hosts = Hosts {
servers: cdn_hosts,
active_index: RwLock::new(None),
};
hosts.rate(asn, user_region, true).await;
if hosts.servers.iter().all(|server| server.rating == 0) {
println!("Retrying with longer timeout...");
hosts.rate(asn, user_region, false).await;
}
println!();
for server in hosts.servers.iter() {
let latency_str = server
.latency
.map_or("timeout".to_string(), |l| format!("{} ms", l.as_millis()));
println!(
"{}: rating {}, latency {}",
server.host.bright_white(),
server.rating.to_string().bright_cyan(),
latency_str
);
}
// Show selected CDN
if hosts.next() {
if let Some(best_url) = hosts.active_url() {
println!();
println!("Selected: {}", best_url.bright_green());
}
} else {
println!();
println!("{}", "No available CDN servers".bright_red());
}
}

View File

@@ -17,17 +17,13 @@ pub async fn latest_tag_full(
repo: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let github_body = crate::http_async::get_body_string(
format!(
"https://api.github.com/repos/{}/{}/releases/latest",
owner, repo
)
.as_str(),
format!("https://api.github.com/repos/{owner}/{repo}/releases/latest").as_str(),
)
.await
.map_err(|e| format!("Failed to fetch GitHub API: {}", e))?;
.map_err(|e| format!("Failed to fetch GitHub API: {e}"))?;
let github_json: serde_json::Value = serde_json::from_str(&github_body)
.map_err(|e| format!("Failed to parse GitHub API response: {}", e))?;
.map_err(|e| format!("Failed to parse GitHub API response: {e}"))?;
let tag_name = github_json
.get("tag_name")
@@ -43,13 +39,13 @@ pub async fn latest_tag_prerelease(
repo: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let github_body = crate::http_async::get_body_string(
format!("https://api.github.com/repos/{}/{}/releases", owner, repo).as_str(),
format!("https://api.github.com/repos/{owner}/{repo}/releases").as_str(),
)
.await
.map_err(|e| format!("Failed to fetch GitHub API: {}", e))?;
.map_err(|e| format!("Failed to fetch GitHub API: {e}"))?;
let github_json: serde_json::Value = serde_json::from_str(&github_body)
.map_err(|e| format!("Failed to parse GitHub API response: {}", e))?;
.map_err(|e| format!("Failed to parse GitHub API response: {e}"))?;
let latest_release = github_json.get(0).ok_or("No releases found")?;
@@ -70,7 +66,7 @@ pub async fn latest_version(
let tag = latest_tag(owner, repo, prerelease).await?;
let cleaned_tag = tag.replace('v', "");
Version::parse(&cleaned_tag)
.map_err(|e| format!("Failed to parse version '{}': {}", cleaned_tag, e).into())
.map_err(|e| format!("Failed to parse version '{cleaned_tag}': {e}").into())
}
pub fn download_url(owner: &str, repo: &str, tag: Option<&str>) -> String {

View File

@@ -6,20 +6,13 @@ use std::future::Future;
use std::pin::Pin;
use std::sync::Mutex;
use crate::cdn::{Hosts, Region, Server};
use crate::cdn::{Hosts, Server};
pub const GH_OWNER: &str = "alterware";
pub const GH_REPO: &str = "alterware-launcher";
pub const GH_IW4X_OWNER: &str = "iw4x";
pub const GH_IW4X_REPO: &str = "iw4x-client";
pub const DEFAULT_MASTER: &str = "https://cdn.alterware.ovh";
pub const CDN_HOSTS: [Server; 2] = [
Server::new("cdn.alterware.ovh", Region::Global),
Server::new("us-cdn.alterware.ovh", Region::NorthAmerica),
];
pub const IP2ASN: &str = "https://ip2asn.getserve.rs/v1/as/ip/self";
pub const CDN_HOSTS: [Server; 1] = [Server::new("cdn.alterware.ovh")];
pub static USER_AGENT: Lazy<String> = Lazy::new(|| {
format!(
@@ -33,8 +26,6 @@ pub static USER_AGENT: Lazy<String> = Lazy::new(|| {
pub static MASTER_URL: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new(String::from(DEFAULT_MASTER)));
pub static IS_OFFLINE: Lazy<Mutex<bool>> = Lazy::new(|| Mutex::new(false));
pub static PREFIXES: Lazy<HashMap<&'static str, PrintPrefix>> = Lazy::new(|| {
HashMap::from([
(
@@ -81,54 +72,3 @@ pub static PREFIXES: Lazy<HashMap<&'static str, PrintPrefix>> = Lazy::new(|| {
),
])
});
pub async fn check_connectivity_and_rate_cdns() -> Pin<Box<dyn Future<Output = bool> + Send>> {
Box::pin(async move {
crate::println_info!("Initializing CDN rating system...");
let hosts = Hosts::new().await;
let best_cdn = hosts.get_master_url();
if let Some(cdn_url) = best_cdn {
let cdn_url = cdn_url.trim_end_matches('/');
*MASTER_URL.lock().unwrap() = cdn_url.to_string();
crate::println_info!("Selected CDN: {}", cdn_url);
match crate::http_async::get_body_string(cdn_url).await {
Ok(_) => {
info!("Successfully connected to CDN: {}", cdn_url);
true
}
Err(e) => {
error!("Failed to connect to selected CDN {}: {}", cdn_url, e);
*IS_OFFLINE.lock().unwrap() = true;
false
}
}
} else {
crate::println_error!("No CDN hosts are available");
*IS_OFFLINE.lock().unwrap() = true;
false
}
})
}
pub fn check_connectivity(
master_url: Option<String>,
) -> Pin<Box<dyn Future<Output = bool> + Send>> {
Box::pin(async move {
if let Some(url) = master_url {
*MASTER_URL.lock().unwrap() = url.clone();
crate::println_info!("Using fallback connectivity check on {}", url);
match crate::http_async::get_body_string(&url).await {
Ok(_) => true,
Err(_) => {
*IS_OFFLINE.lock().unwrap() = true;
false
}
}
} else {
check_connectivity_and_rate_cdns().await.await
}
})
}

View File

@@ -1,5 +1,4 @@
use reqwest::header::HeaderMap;
use serde_json::Value;
use simple_log::*;
use std::time::{Duration, Instant};
@@ -17,18 +16,18 @@ pub async fn quick_request(url: &str) -> Result<String, Box<dyn std::error::Erro
.await;
if let Err(e) = &res {
error!("Failed to get {}: {}", url, e);
return Err(format!("Failed to get {} {}", url, e).into());
error!("Failed to get {url}: {e}");
return Err(format!("Failed to get {url} {e}").into());
}
let res = res.unwrap();
match res.text().await {
Ok(text) => {
info!("Successfully received response from: {}", url);
info!("Successfully received response from: {url}");
Ok(text)
}
Err(e) => {
warn!("Failed to get response text from {}: {}", url, e);
warn!("Failed to get response text from {url}: {e}");
Err(e.into())
}
}
@@ -64,8 +63,8 @@ pub async fn rating_request(
let latency = start.elapsed();
if let Err(e) = &res {
error!("Failed to get {}: {} (after {:?})", url, e, latency);
return Err(format!("Failed to get {} {} (after {:?})", url, e, latency).into());
error!("Failed to get {url}: {e} (after {latency:?})");
return Err(format!("Failed to get {url} {e} (after {latency:?})").into());
}
let res = res.unwrap();
@@ -74,36 +73,10 @@ pub async fn rating_request(
// We don't need the response body for rating
if let Err(e) = res.text().await {
warn!(
"Failed to get response text from {}: {} (after {:?})",
url, e, latency
);
warn!("Failed to get response text from {url}: {e} (after {latency:?})");
return Err(e.into());
}
info!(
"Successfully rated {} in {:?} (cloudflare: {})",
url, latency, is_cloudflare
);
info!("Successfully rated {url} in {latency:?} (cloudflare: {is_cloudflare})");
Ok((latency, is_cloudflare))
}
/// Retrieve client ASN and region
pub async fn get_location_info() -> (u32, String) {
let response = quick_request(crate::global::IP2ASN).await;
if let Ok(as_data_str) = response {
if let Ok(as_data) = serde_json::from_str::<Value>(&as_data_str) {
let as_number = as_data
.get("as_number")
.and_then(|v| v.as_u64())
.unwrap_or(0) as u32;
let region = as_data
.get("region")
.and_then(|v| v.as_str())
.unwrap_or("Unknown")
.to_string();
return (as_number, region);
}
}
(0, "Unknown".to_string())
}

View File

@@ -32,10 +32,14 @@ pub async fn download_file_progress(
.send()
.await
.map_err(|e| {
error!("Failed to GET from '{}': {}", url, e);
error!("Failed to GET from '{url}': {e}");
format!("Failed to GET from '{url}'")
})?;
if !res.status().is_success() {
return Err(format!("Request failed with status: {}", res.status()));
}
let total_size = res.content_length().unwrap_or(size);
debug!("Download size: {}", misc::human_readable_bytes(total_size));
pb.set_length(total_size);
@@ -89,14 +93,18 @@ pub async fn get_body(url: &str) -> Result<Vec<u8>, String> {
)
.send()
.await
.map_err(|e| format!("Failed to send request: {}", e))?;
.map_err(|e| format!("Failed to send request: {e}"))?;
debug!("{} {url}", res.status());
if !res.status().is_success() {
return Err(format!("Request failed with status: {}", res.status()));
}
res.bytes()
.await
.map(|b| b.to_vec())
.map_err(|e| format!("Failed to get body: {}", e))
.map_err(|e| format!("Failed to get body: {e}"))
}
pub async fn get_body_string(url: &str) -> Result<String, String> {
@@ -119,7 +127,7 @@ pub async fn get_json<T: serde::de::DeserializeOwned>(url: &str) -> Result<T, St
.header("Accept", "application/json")
.send()
.await
.map_err(|e| format!("Failed to send request: {}", e))?;
.map_err(|e| format!("Failed to send request: {e}"))?;
debug!("{} {}", res.status(), url);
@@ -130,7 +138,7 @@ pub async fn get_json<T: serde::de::DeserializeOwned>(url: &str) -> Result<T, St
let body = res
.bytes()
.await
.map_err(|e| format!("Failed to read response body: {}", e))?;
.map_err(|e| format!("Failed to read response body: {e}"))?;
serde_json::from_slice::<T>(&body).map_err(|e| format!("Failed to parse JSON: {}", e))
serde_json::from_slice::<T>(&body).map_err(|e| format!("Failed to parse JSON: {e}"))
}

View File

@@ -1,46 +0,0 @@
use crate::extend::*;
use crate::github;
use crate::global::*;
use crate::http_async;
use crate::misc;
use crate::structs;
use std::path::Path;
pub async fn remote_revision(prerelease: Option<bool>) -> u16 {
match github::latest_tag(GH_IW4X_OWNER, GH_IW4X_REPO, prerelease).await {
Ok(tag) => misc::rev_to_int(&tag),
Err(_) => {
crate::println_error!("Failed to get latest version for {GH_IW4X_OWNER}/{GH_IW4X_REPO}, assuming we are up to date.");
0
}
}
}
pub async fn update(dir: &Path, cache: &mut structs::Cache, prerelease: Option<bool>) {
let remote = remote_revision(prerelease).await;
let local = misc::rev_to_int(&cache.iw4x_revision);
if remote <= local && dir.join("iw4x.dll").exists() {
crate::println_info!("No files to download for IW4x");
return;
}
crate::println_info!("Downloading outdated or missing files for IW4x",);
println!(
"{}{}",
misc::prefix("downloading"),
dir.join("iw4x.dll").cute_path()
);
http_async::download_file(
&format!(
"{}/iw4x.dll",
github::download_url(GH_IW4X_OWNER, GH_IW4X_REPO, Some(&format!("r{remote}")))
),
&dir.join("iw4x.dll"),
)
.await
.unwrap();
cache.iw4x_revision = format!("r{remote}");
}

View File

@@ -6,7 +6,6 @@ mod github;
mod global;
mod http;
mod http_async;
mod iw4x;
mod misc;
mod self_update;
mod structs;
@@ -28,7 +27,7 @@ use mslnk::ShellLink;
use simple_log::LogConfigBuilder;
use std::{
borrow::Cow,
collections::{HashMap, HashSet},
collections::HashMap,
env, fs,
path::{Path, PathBuf},
};
@@ -117,7 +116,7 @@ fn setup_desktop_links(path: &Path, game: &Game) {
async fn auto_install(path: &Path, game: &Game<'_>) {
setup_client_links(game, path);
setup_desktop_links(path, game);
update(game, path, false, false, None, None, None).await;
update(game, path, false, false, None).await;
}
#[cfg(windows)]
@@ -187,7 +186,7 @@ fn total_download_size(cdn_info: &Vec<CdnFile>, remote_dir: &str) -> u64 {
let remote_dir = format!("{remote_dir}/");
let mut size: u64 = 0;
for file in cdn_info {
if !file.name.starts_with(&remote_dir) || file.name == "iw4/iw4x.dll" {
if !file.name.starts_with(&remote_dir) {
continue;
}
size += file.size as u64;
@@ -201,7 +200,6 @@ async fn update_dir(
dir: &Path,
hashes: &mut HashMap<String, String>,
pb: &ProgressBar,
skip_iw4x_sp: bool,
) {
misc::pb_style_download(pb, false);
@@ -210,10 +208,7 @@ async fn update_dir(
let mut files_to_download: Vec<CdnFile> = vec![];
for file in cdn_info {
if !file.name.starts_with(&remote_dir_pre) || file.name == "iw4/iw4x.dll" {
continue;
}
if skip_iw4x_sp && file.name == "iw4/iw4x-sp.exe" {
if !file.name.starts_with(&remote_dir_pre) {
continue;
}
@@ -337,15 +332,12 @@ async fn update(
dir: &Path,
bonus_content: bool,
force: bool,
skip_iw4x_sp: Option<bool>,
ignore_required_files: Option<bool>,
prerelease: Option<bool>,
) {
info!("Starting update for game engine: {}", game.engine);
info!("Update path: {}", dir.display());
debug!("Bonus content: {}, Force update: {}", bonus_content, force);
let skip_iw4x_sp = skip_iw4x_sp.unwrap_or(false);
let ignore_required_files = ignore_required_files.unwrap_or(false);
let res =
@@ -405,66 +397,12 @@ async fn update(
}
}
if game.engine == "iw4" {
iw4x::update(dir, &mut cache, prerelease).await;
let scan_dirs = ["iw4x", "zone/patch"];
let valid_files: HashSet<_> = cdn_info
.iter()
.filter_map(|cdn_file| {
if cdn_file.name.starts_with("iw4/") || cdn_file.name.starts_with("iw4-dlc/") {
Some(Path::new(&cdn_file.name).to_path_buf())
} else {
None
}
})
.collect();
for scan_dir in scan_dirs.iter() {
let full_scan_dir = dir.join(scan_dir);
if !full_scan_dir.exists() || !full_scan_dir.is_dir() {
continue;
}
for entry in walkdir::WalkDir::new(&full_scan_dir)
.into_iter()
.filter_map(Result::ok)
.filter(|e| e.file_type().is_file())
{
let rel_path = entry.path().strip_prefix(dir).unwrap_or(entry.path());
let cdn_paths = [
Path::new("iw4").join(rel_path),
Path::new("iw4-dlc").join(rel_path),
];
if !cdn_paths.iter().any(|path| valid_files.contains(path)) {
crate::println_info!("{}{}", misc::prefix("removed"), entry.path().cute_path());
if std::fs::remove_file(entry.path()).is_err() {
crate::println_error!(
"{}Couldn't delete {}",
misc::prefix("error"),
entry.path().cute_path()
);
}
}
}
}
}
let pb = ProgressBar::new(0);
update_dir(
&cdn_info,
game.engine,
dir,
&mut cache.hashes,
&pb,
skip_iw4x_sp,
)
.await;
update_dir(&cdn_info, game.engine, dir, &mut cache.hashes, &pb).await;
if bonus_content && !game.bonus.is_empty() {
for bonus in game.bonus.iter() {
update_dir(&cdn_info, bonus, dir, &mut cache.hashes, &pb, skip_iw4x_sp).await;
update_dir(&cdn_info, bonus, dir, &mut cache.hashes, &pb).await;
}
}
@@ -549,9 +487,18 @@ fn launch(file_path: &PathBuf, args: &str) {
fn launch(file_path: &PathBuf, args: &str) {
println!("\n\nJoin the AlterWare Discord server:\nhttps://discord.gg/2ETE8engZM\n\n");
crate::println_info!("Launching {} {args}", file_path.display());
let exit_status = if misc::is_program_in_path("wine") {
println!("Found wine, launching game using wine.\nIf you run into issues or want to launch a different way, run {} manually.", file_path.display());
std::process::Command::new("wine")
let launcher = if misc::is_program_in_path("umu-run") {
Some("umu-run")
} else if misc::is_program_in_path("wine") {
Some("wine")
} else {
None
};
let exit_status = if let Some(launcher) = launcher {
println!("Found {launcher}, launching game using {launcher}.\nIf you run into issues or want to launch a different way, run {} manually.", file_path.display());
std::process::Command::new(launcher)
.args([file_path.to_str().unwrap(), args.trim()])
.current_dir(file_path.parent().unwrap())
.spawn()
@@ -627,7 +574,7 @@ fn show_iw4x_info() {
"{}",
"IW4x is not provided through AlterWare anymore.".bright_red()
);
println!("Please use iw4x-launcher.exe instead or visit www.iw4x.dev/install");
println!("Please visit https://aka.alterware.dev/iw4x for more information");
misc::stdin();
std::process::exit(0);
}
@@ -679,8 +626,6 @@ async fn main() {
println!(" --redist: (Re-)Install redistributables");
println!(" --prerelease: Update to prerelease version of clients and launcher");
println!(" --offline: Run in offline mode");
println!(" --skip-connectivity-check: Don't check connectivity");
println!(" --rate: Display CDN rating information and exit");
println!("\nExample:\n alterware-launcher.exe iw6 --pass \"-headless\"");
return;
}
@@ -716,11 +661,6 @@ async fn main() {
install_path = env::current_dir().unwrap();
}
if arg_bool(&args, "--rate") {
cdn::rate_cdns_and_display().await;
return;
}
let mut cfg = config::load(install_path.join("alterware-launcher.json"));
if let Some(cdn_url) = arg_value(&args, "--cdn-url") {
@@ -733,11 +673,6 @@ async fn main() {
arg_remove(&mut args, "--offline");
}
if arg_bool(&args, "--skip-connectivity-check") {
cfg.skip_connectivity_check = true;
arg_remove(&mut args, "--skip-connectivity-check");
}
let initial_cdn = if !cfg.cdn_url.is_empty() {
info!("Using custom CDN URL: {}", cfg.cdn_url);
Some(cfg.cdn_url.clone())
@@ -745,14 +680,6 @@ async fn main() {
None
};
if !cfg.offline && !cfg.skip_connectivity_check {
if initial_cdn.is_some() {
cfg.offline = !global::check_connectivity(initial_cdn).await;
} else {
cfg.offline = !global::check_connectivity_and_rate_cdns().await.await;
}
}
if cfg.offline {
// Check if this is a first-time run (no stored data)
let stored_data = cache::get_stored_data();
@@ -816,9 +743,9 @@ async fn main() {
std::process::exit(1);
};
info!("Launching game in offline mode with client: {}", client);
info!("Launching game in offline mode with client: {client}");
// Launch game without updates
launch(&install_path.join(format!("{}.exe", client)), &cfg.args);
launch(&install_path.join(format!("{client}.exe")), &cfg.args);
return;
}
@@ -944,14 +871,6 @@ async fn main() {
"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(),
);
}
#[cfg(windows)]
if !cfg.skip_redist {
@@ -980,9 +899,7 @@ async fn main() {
install_path.as_path(),
cfg.download_bonus_content,
cfg.force_update,
Some(&game != "iw4x-sp"),
Some(ignore_required_files),
Some(cfg.prerelease),
)
.await;
if !cfg.update_only {

View File

@@ -12,13 +12,6 @@ pub fn stdin() -> String {
input.trim().to_string()
}
pub fn rev_to_int(rev: &str) -> u16 {
rev.strip_prefix('r')
.unwrap_or("0")
.parse::<u16>()
.unwrap_or(0)
}
pub fn human_readable_bytes(bytes: u64) -> String {
let mut bytes = bytes as f64;
let mut i = 0;
@@ -48,7 +41,7 @@ pub fn is_program_in_path(program: &str) -> bool {
paths.to_str().map(|paths| {
paths
.split(':')
.any(|dir| fs::metadata(format!("{}/{}", dir, program)).is_ok())
.any(|dir| fs::metadata(format!("{dir}/{program}")).is_ok())
})
})
.unwrap_or(false)
@@ -60,9 +53,9 @@ pub fn is_program_in_path(program: &str) -> bool {
.and_then(|paths| {
paths.to_str().map(|paths| {
paths.split(';').any(|dir| {
fs::metadata(format!("{}\\{}.exe", dir, program)).is_ok()
|| fs::metadata(format!("{}\\{}.cmd", dir, program)).is_ok()
|| fs::metadata(format!("{}\\{}.bat", dir, program)).is_ok()
fs::metadata(format!("{dir}\\{program}.exe")).is_ok()
|| fs::metadata(format!("{dir}\\{program}.cmd")).is_ok()
|| fs::metadata(format!("{dir}\\{program}.bat")).is_ok()
})
})
})

View File

@@ -15,7 +15,7 @@ pub async fn self_update_available(prerelease: Option<bool>) -> bool {
let latest_version = match github::latest_version(GH_OWNER, GH_REPO, prerelease).await {
Ok(v) => v,
Err(e) => {
error!("Failed to get latest version: {}", e);
error!("Failed to get latest version: {e}");
return false;
}
};
@@ -93,7 +93,7 @@ pub async fn run(update_only: bool, prerelease: Option<bool>) {
"alterware-launcher.exe"
};
http_async::download_file(
if let Err(e) = http_async::download_file(
&format!(
"{}/download/{}",
github::download_url(GH_OWNER, GH_REPO, None),
@@ -102,7 +102,11 @@ pub async fn run(update_only: bool, prerelease: Option<bool>) {
&file_path,
)
.await
.unwrap();
{
error!("Self-update download failed: {e}");
crate::println_error!("Self-update failed ({e}), skipping update.");
return;
}
if !file_path.exists() {
crate::println_error!("Failed to download launcher update.");

View File

@@ -54,8 +54,6 @@ pub struct Config {
pub cdn_url: String,
#[serde(default)]
pub offline: bool,
#[serde(default)]
pub skip_connectivity_check: bool,
}
impl Default for Config {
@@ -73,7 +71,6 @@ impl Default for Config {
prerelease: false,
cdn_url: String::default(),
offline: false,
skip_connectivity_check: false,
}
}
}