Compare commits

...

113 Commits

Author SHA1 Message Date
zhexu14
2d8efa5a7a Add NASAMs to MERAD unit list for campaign template (#3406) (#3410)
Adds NASAM launcher B and C to the list of units that can be placed in a
campaign template to define a MERAD spawn location.

This is needed to maintain compatibility with the new versions of my
campaigns.

Pull requests should be made against the `develop` branch. Any backports
necessary will be handled by the development team.

Pull requests should be focused on one task. Multiple bug fixes should
be
multiple PRs. We cannot merge half a PR, and combined PRs are much more
difficult to review. PRs that do not adhere to this will have their
review
delayed.

Prefer rebase to merge, and squash commits as needed to preserve a
readable
commit history. This project maintains linear history in the develop
branch, so
we will either rebase or squash your PR when merging. It is much easier
for us
if your branch already has a readable commit history (ensure that your
commit
subject lines are clear enough to identify the patch in the git log). An
exception to this is made for large PRs that are likely to require
multiple
rounds of review; in that case it's easier if you **don't** do this
(GitHub
does not preserve the history of old commits, so we cannot filter a PR
for only
new changes if a branch is force pushed) and we will squash it when
merging.

New features and bug fixes are usually worth mentioning in the
changelog.
Exceptions are fixes for bugs that never shipped (were only present in a
canary
build), and changes with no intended user observable behavior, such as a
refactor. If you're comfortable writing the note yourself, add it to
`changelog.md` in the root of the project in the section for the
upcoming
release.

Co-authored-by: Starfire13 <72491792+Starfire13@users.noreply.github.com>
2024-06-19 20:38:09 +10:00
zhexu14
524125b455 Add Starfire13's OH-58D resources (#3404)
Authored by: Starfire13

Adds OH-58 payloads and squadrons.
2024-06-07 20:40:15 +10:00
zhexu14
1be87ec16b Update README.md (#3403)
Remove reference to DCS Stable and Open Beta as they are now merged.
2024-06-06 23:20:04 +10:00
zhexu14
9066fafcb1 DCS 55918 (#3401)
This PR adds support for DCS 2.9.5.55918. Some limited support for the
Kiowa Warrior is also implemented.
2024-06-06 22:41:08 +10:00
zhexu14
fd8632a71d Add radio setup for F-5E, Mi-8, Mi-24 and F-86 (#3400) 2024-06-05 20:59:02 +10:00
ColonelAkirNakesh
352216bb5e Create FuSe-65.yaml (#3398)
Adds Wurzburg-Riese EWR to yamls
2024-06-05 20:44:14 +10:00
zhexu14
271ddf4503 Add contributors (#3396)
Add new contributors.
2024-06-05 20:41:10 +10:00
ColonelAkirNakesh
cef81c16c3 Update germany_1944.yaml (#3397)
Adds missing artillery pieces and U-boat to Germany '44 faction
2024-06-05 20:40:56 +10:00
tmz42
4e2c3dbc51 Allied Sword update (#3399)
Modified Allied Sword for F-4E
Included expansion to the North
2024-06-05 20:40:25 +10:00
zhexu14
d905f0cf7f Dcs 2.9.5 (#3393)
DCS 2.9.5 Support (including F-4)

---------

Co-authored-by: Raffson <Raffson@users.noreply.github.com>
Co-authored-by: Starfire13 <72491792+Starfire13@users.noreply.github.com>
2024-06-02 22:18:11 +10:00
dependabot[bot]
99bbdc3e77 Bump jinja2 from 3.1.3 to 3.1.4 (#3387)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pallets/jinja/releases">jinja2's
releases</a>.</em></p>
<blockquote>
<h2>3.1.4</h2>
<p>This is the Jinja 3.1.4 security release, which fixes security issues
and bugs but does not otherwise change behavior and should not result in
breaking changes.</p>
<p>PyPI: <a
href="https://pypi.org/project/Jinja2/3.1.4/">https://pypi.org/project/Jinja2/3.1.4/</a>
Changes: <a
href="https://jinja.palletsprojects.com/en/3.1.x/changes/#version-3-1-4">https://jinja.palletsprojects.com/en/3.1.x/changes/#version-3-1-4</a></p>
<ul>
<li>The <code>xmlattr</code> filter does not allow keys with
<code>/</code> solidus, <code>&gt;</code> greater-than sign, or
<code>=</code> equals sign, in addition to disallowing spaces.
Regardless of any validation done by Jinja, user input should never be
used as keys to this filter, or must be separately validated first.
GHSA-h75v-3vvj-5mfj</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pallets/jinja/blob/main/CHANGES.rst">jinja2's
changelog</a>.</em></p>
<blockquote>
<h2>Version 3.1.4</h2>
<p>Released 2024-05-05</p>
<ul>
<li>The <code>xmlattr</code> filter does not allow keys with
<code>/</code> solidus, <code>&gt;</code>
greater-than sign, or <code>=</code> equals sign, in addition to
disallowing spaces.
Regardless of any validation done by Jinja, user input should never be
used
as keys to this filter, or must be separately validated first.
:ghsa:<code>h75v-3vvj-5mfj</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="dd4a8b5466"><code>dd4a8b5</code></a>
release version 3.1.4</li>
<li><a
href="0668239dc6"><code>0668239</code></a>
Merge pull request from GHSA-h75v-3vvj-5mfj</li>
<li><a
href="d655030770"><code>d655030</code></a>
disallow invalid characters in keys to xmlattr filter</li>
<li><a
href="a7863ba9d3"><code>a7863ba</code></a>
add ghsa links</li>
<li><a
href="b5c98e78c2"><code>b5c98e7</code></a>
start version 3.1.4</li>
<li><a
href="da3a9f0b80"><code>da3a9f0</code></a>
update project files (<a
href="https://redirect.github.com/pallets/jinja/issues/1968">#1968</a>)</li>
<li><a
href="0ee5eb41d1"><code>0ee5eb4</code></a>
satisfy formatter, linter, and strict mypy</li>
<li><a
href="20477c6357"><code>20477c6</code></a>
update project files (<a
href="https://redirect.github.com/pallets/jinja/issues/5457">#5457</a>)</li>
<li><a
href="e491223739"><code>e491223</code></a>
update pyyaml dev dependency</li>
<li><a
href="36f98854c7"><code>36f9885</code></a>
fix pr link</li>
<li>Additional commits viewable in <a
href="https://github.com/pallets/jinja/compare/3.1.3...3.1.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jinja2&package-manager=pip&previous-version=3.1.3&new-version=3.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-29 22:40:40 +10:00
DillieKoe
4040f50d8a Update peru_1995.yaml (#3392)
Added 3 missing units.
2024-05-29 22:40:22 +10:00
zhexu14
11304542bd Wrap getLife with pcall to handle error where unit is lost (#3390) 2024-05-25 15:09:18 +10:00
Starfire13
cbf5f5ed90 Update Black Sea from 2/3 to 3/3 performance (#3391)
I think this campaign is really not performance friendly and should be
marked as a 3/3. It is the first campaign on the list and quite a few
new players pick it as their first one and then struggle with
performance issues. Framerate on this campaign is quite a bit lower than
on many of the other 2/3 campaigns, on account of the large number of
aircraft and very heavy SAM coverage.
2024-05-25 15:09:01 +10:00
zhexu14
6433d3159e Make window size of NGW consistent so position does not move around (#3386) 2024-05-04 16:10:20 +10:00
dependabot[bot]
b376ab135f Bump ejs from 3.1.7 to 3.1.10 in /client (#3385)
Bumps [ejs](https://github.com/mde/ejs) from 3.1.7 to 3.1.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/mde/ejs/releases">ejs's
releases</a>.</em></p>
<blockquote>
<h2>v3.1.10</h2>
<p>Version 3.1.10</p>
<h2>v3.1.9</h2>
<p>Version 3.1.9</p>
<h2>v3.1.8</h2>
<p>Version 3.1.8</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d3f807dea9"><code>d3f807d</code></a>
Version 3.1.10</li>
<li><a
href="9ee26dde5d"><code>9ee26dd</code></a>
Mocha TDD</li>
<li><a
href="e469741dca"><code>e469741</code></a>
Basic pollution protection</li>
<li><a
href="715e9507fa"><code>715e950</code></a>
Merge pull request <a
href="https://redirect.github.com/mde/ejs/issues/756">#756</a> from
Jeffrey-mu/main</li>
<li><a
href="cabe3146ad"><code>cabe314</code></a>
Include advanced usage examples</li>
<li><a
href="29b076cdbb"><code>29b076c</code></a>
Added header</li>
<li><a
href="11503c79af"><code>11503c7</code></a>
Merge branch 'main' of github.com:mde/ejs into main</li>
<li><a
href="7690404e2f"><code>7690404</code></a>
Added security banner to README</li>
<li><a
href="f47d7aedd5"><code>f47d7ae</code></a>
Update SECURITY.md</li>
<li><a
href="828cea1687"><code>828cea1</code></a>
Update SECURITY.md</li>
<li>Additional commits viewable in <a
href="https://github.com/mde/ejs/compare/v3.1.7...v3.1.10">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ejs&package-manager=npm_and_yarn&previous-version=3.1.7&new-version=3.1.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-04 15:58:31 +10:00
zhexu14
99089cc3d0 Fix waypoints list width (#3383)
Fix width of Flight Waypoints List. The vertical header width was
returning 0 so the table width was under estimated leading to the table
being too narrow. Used sizeHint to get vertical header width to work
around this issue.
2024-04-24 07:55:29 +10:00
zhexu14
13ff69c4df Set next version as 11.1 (#3382)
This PR sets versions & changelog to a 11.1 bugfix release.
2024-04-22 22:55:39 +10:00
zhexu14
55c77ed7c3 Lock python version to 3.11.4 as 3.11.5 introduces a change that brea… (#3380)
3.11.5 introduces a change that breaks unpickling of save files that
leads to #3379. This PR introduces a short term fix by locking the
python version used in the build until the root cause can be found and
fixed.
2024-04-18 07:55:04 +10:00
zhexu14
4c5d968dd7 Issue 3232: Clean up Air Wing Configuration Dialogue Box (#3377)
Set default size of Air Wing Configuration Dialogue Box so that a whole
squadron can be seen, addressing #3232

Make some UI elements smaller so that the Dialogue Box does not take too
much screen real estate and works on smaller monitors.
2024-04-15 20:49:42 +10:00
zhexu14
dc3d1b0b5b Make theater refuelling flight plan on-station time configurable based on the desired mission duration (#3375)
This PR 
- Addresses #1511 by setting the tanker on-station time to the desired
mission duration + 30 minutes
- Elaborate on what the desired mission duration setting does in the
Settings UI.
2024-04-14 21:58:30 +10:00
Chilli
75f904275c CJS Super hornet mod support update (#3376)
In this PR:

- Added EA-18G payload (made by @sgtfuzzle17)
- Added FA-18E payload (made by @sgtfuzzle17)
- Added FA-18F payload (made by @sgtfuzzle17)
- Corrected typo on my name
- Added SEAD Escort task to EA-18G.yaml
2024-04-14 21:58:15 +10:00
zhexu14
f59051c9f8 Issue 2778 (#3374)
This PR addresses #2778 by:
- Updating the logic for how redeployment of front line units works to
handle "out of order" captures e.g. for control points A->B->C, where A
starts friendly and B, C starts as enemy-controlled, the player captures
C first, typically using air assault.
- Updating the cheat logic so that capturing CPs using cheats behaves
the same way as capturing CPs normally.
2024-04-13 21:55:44 +10:00
zhexu14
c8c78d0b2a Stop naval control points from being moved onto land (#3373)
This PR fixes #3243 by checking whether the destination point is in the
sea for naval control points before permitting the movement.
2024-04-13 15:04:41 +10:00
dependabot[bot]
0ade5b9861 Bump idna from 3.6 to 3.7 (#3372)
Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/kjd/idna/releases">idna's
releases</a>.</em></p>
<blockquote>
<h2>v3.7</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix issue where specially crafted inputs to encode() could take
exceptionally long amount of time to process. [CVE-2024-3651]</li>
</ul>
<p>Thanks to Guido Vranken for reporting the issue.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/kjd/idna/compare/v3.6...v3.7">https://github.com/kjd/idna/compare/v3.6...v3.7</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/kjd/idna/blob/master/HISTORY.rst">idna's
changelog</a>.</em></p>
<blockquote>
<p>3.7 (2024-04-11)
++++++++++++++++</p>
<ul>
<li>Fix issue where specially crafted inputs to encode() could
take exceptionally long amount of time to process. [CVE-2024-3651]</li>
</ul>
<p>Thanks to Guido Vranken for reporting the issue.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1d365e17e1"><code>1d365e1</code></a>
Release v3.7</li>
<li><a
href="c1b3154939"><code>c1b3154</code></a>
Merge pull request <a
href="https://redirect.github.com/kjd/idna/issues/172">#172</a> from
kjd/optimize-contextj</li>
<li><a
href="0394ec76ff"><code>0394ec7</code></a>
Merge branch 'master' into optimize-contextj</li>
<li><a
href="cd58a23173"><code>cd58a23</code></a>
Merge pull request <a
href="https://redirect.github.com/kjd/idna/issues/152">#152</a> from
elliotwutingfeng/dev</li>
<li><a
href="5beb28b9dd"><code>5beb28b</code></a>
More efficient resolution of joiner contexts</li>
<li><a
href="1b121483ed"><code>1b12148</code></a>
Update ossf/scorecard-action to v2.3.1</li>
<li><a
href="d516b874c3"><code>d516b87</code></a>
Update Github actions/checkout to v4</li>
<li><a
href="c095c75943"><code>c095c75</code></a>
Merge branch 'master' into dev</li>
<li><a
href="60a0a4cb61"><code>60a0a4c</code></a>
Fix typo in GitHub Actions workflow key</li>
<li><a
href="5918a0ef80"><code>5918a0e</code></a>
Merge branch 'master' into dev</li>
<li>Additional commits viewable in <a
href="https://github.com/kjd/idna/compare/v3.6...v3.7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=idna&package-manager=pip&previous-version=3.6&new-version=3.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-12 21:21:17 +10:00
zhexu14
9611c01b93 Add mechanism to prevent double counting of damage induced kills when… (#3371)
… DCS reports multiple hits

This PR fixes a bug introduced when tracking OCA/Aircraft kills that
results in double counting when DCS reports multiple hits, typically
when guns are used.
2024-04-10 16:28:21 +10:00
dependabot[bot]
3234a2b28a Bump axios from 0.25.0 to 1.6.8 in /client (#3369)
Bumps [axios](https://github.com/axios/axios) from 0.25.0 to 1.6.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.6.8</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>AxiosHeaders:</strong> fix AxiosHeaders conversion to an
object during config merging (<a
href="https://redirect.github.com/axios/axios/issues/6243">#6243</a>)
(<a
href="2656612bc1">2656612</a>)</li>
<li><strong>import:</strong> use named export for EventEmitter; (<a
href="7320430aef">7320430</a>)</li>
<li><strong>vulnerability:</strong> update follow-redirects to 1.15.6
(<a
href="https://redirect.github.com/axios/axios/issues/6300">#6300</a>)
(<a
href="8786e0ff55">8786e0f</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/jasonsaayman"
title="+4572/-3446 ([#6238](https://github.com/axios/axios/issues/6238)
)">Jay</a></li>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+30/-0
([#6231](https://github.com/axios/axios/issues/6231) )">Dmitriy
Mozgovoy</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/Creaous"
title="+9/-9 ([#6300](https://github.com/axios/axios/issues/6300)
)">Mitchell</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/mannoeu"
title="+2/-2 ([#6196](https://github.com/axios/axios/issues/6196)
)">Emmanuel</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/ljkeller"
title="+3/-0 ([#6194](https://github.com/axios/axios/issues/6194)
)">Lucas Keller</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/ADITYA-176"
title="+1/-1 ()">Aditya Mogili</a></li>
<li><!-- raw HTML omitted --> <a
href="https://github.com/petrovmiroslav" title="+1/-1
([#6243](https://github.com/axios/axios/issues/6243) )">Miroslav
Petrov</a></li>
</ul>
<h2>Release v1.6.7</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li>capture async stack only for rejections with native error objects;
(<a
href="https://redirect.github.com/axios/axios/issues/6203">#6203</a>)
(<a
href="1a08f90f40">1a08f90</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+30/-26
([#6203](https://github.com/axios/axios/issues/6203) )">Dmitriy
Mozgovoy</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/zh-lx"
title="+0/-3 ([#6186](https://github.com/axios/axios/issues/6186)
)">zhoulixiang</a></li>
</ul>
<h2>Release v1.6.6</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li>fixed missed dispatchBeforeRedirect argument (<a
href="https://redirect.github.com/axios/axios/issues/5778">#5778</a>)
(<a
href="a1938ff073">a1938ff</a>)</li>
<li>wrap errors to improve async stack trace (<a
href="https://redirect.github.com/axios/axios/issues/5987">#5987</a>)
(<a
href="123f354b92">123f354</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/ikonst"
title="+91/-8 ([#5987](https://github.com/axios/axios/issues/5987)
)">Ilya Priven</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/zaosoula"
title="+6/-6 ([#5778](https://github.com/axios/axios/issues/5778) )">Zao
Soula</a></li>
</ul>
<h2>Release v1.6.5</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>ci:</strong> refactor notify action as a job of publish
action; (<a
href="https://redirect.github.com/axios/axios/issues/6176">#6176</a>)
(<a
href="0736f95ce8">0736f95</a>)</li>
<li><strong>dns:</strong> fixed lookup error handling; (<a
href="https://redirect.github.com/axios/axios/issues/6175">#6175</a>)
(<a
href="f4f2b039dd">f4f2b03</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/axios/axios/compare/v1.6.7...v1.6.8">1.6.8</a>
(2024-03-15)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>AxiosHeaders:</strong> fix AxiosHeaders conversion to an
object during config merging (<a
href="https://redirect.github.com/axios/axios/issues/6243">#6243</a>)
(<a
href="2656612bc1">2656612</a>)</li>
<li><strong>import:</strong> use named export for EventEmitter; (<a
href="7320430aef">7320430</a>)</li>
<li><strong>vulnerability:</strong> update follow-redirects to 1.15.6
(<a
href="https://redirect.github.com/axios/axios/issues/6300">#6300</a>)
(<a
href="8786e0ff55">8786e0f</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/jasonsaayman"
title="+4572/-3446 ([#6238](https://github.com/axios/axios/issues/6238)
)">Jay</a></li>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+30/-0
([#6231](https://github.com/axios/axios/issues/6231) )">Dmitriy
Mozgovoy</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/Creaous"
title="+9/-9 ([#6300](https://github.com/axios/axios/issues/6300)
)">Mitchell</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/mannoeu"
title="+2/-2 ([#6196](https://github.com/axios/axios/issues/6196)
)">Emmanuel</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/ljkeller"
title="+3/-0 ([#6194](https://github.com/axios/axios/issues/6194)
)">Lucas Keller</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/ADITYA-176"
title="+1/-1 ()">Aditya Mogili</a></li>
<li><!-- raw HTML omitted --> <a
href="https://github.com/petrovmiroslav" title="+1/-1
([#6243](https://github.com/axios/axios/issues/6243) )">Miroslav
Petrov</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.6.6...v1.6.7">1.6.7</a>
(2024-01-25)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>capture async stack only for rejections with native error objects;
(<a
href="https://redirect.github.com/axios/axios/issues/6203">#6203</a>)
(<a
href="1a08f90f40">1a08f90</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+30/-26
([#6203](https://github.com/axios/axios/issues/6203) )">Dmitriy
Mozgovoy</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/zh-lx"
title="+0/-3 ([#6186](https://github.com/axios/axios/issues/6186)
)">zhoulixiang</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.6.5...v1.6.6">1.6.6</a>
(2024-01-24)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>fixed missed dispatchBeforeRedirect argument (<a
href="https://redirect.github.com/axios/axios/issues/5778">#5778</a>)
(<a
href="a1938ff073">a1938ff</a>)</li>
<li>wrap errors to improve async stack trace (<a
href="https://redirect.github.com/axios/axios/issues/5987">#5987</a>)
(<a
href="123f354b92">123f354</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/ikonst"
title="+91/-8 ([#5987](https://github.com/axios/axios/issues/5987)
)">Ilya Priven</a></li>
<li><!-- raw HTML omitted --> <a href="https://github.com/zaosoula"
title="+6/-6 ([#5778](https://github.com/axios/axios/issues/5778) )">Zao
Soula</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.6.4...v1.6.5">1.6.5</a>
(2024-01-05)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>ci:</strong> refactor notify action as a job of publish
action; (<a
href="https://redirect.github.com/axios/axios/issues/6176">#6176</a>)
(<a
href="0736f95ce8">0736f95</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ab3f0f9a94"><code>ab3f0f9</code></a>
chore(release): v1.6.8 (<a
href="https://redirect.github.com/axios/axios/issues/6303">#6303</a>)</li>
<li><a
href="2656612bc1"><code>2656612</code></a>
fix(AxiosHeaders): fix AxiosHeaders conversion to an object during
config mer...</li>
<li><a
href="7320430aef"><code>7320430</code></a>
fix(import): use named export for EventEmitter;</li>
<li><a
href="8786e0ff55"><code>8786e0f</code></a>
fix(vulnerability): update follow-redirects to 1.15.6 (<a
href="https://redirect.github.com/axios/axios/issues/6300">#6300</a>)</li>
<li><a
href="d844227411"><code>d844227</code></a>
chore: update and bump deps (<a
href="https://redirect.github.com/axios/axios/issues/6238">#6238</a>)</li>
<li><a
href="caa0625201"><code>caa0625</code></a>
docs: update README responseEncoding types (<a
href="https://redirect.github.com/axios/axios/issues/6194">#6194</a>)</li>
<li><a
href="41c4584a41"><code>41c4584</code></a>
docs: Update README.md to point to current axios version in CDN links
(<a
href="https://redirect.github.com/axios/axios/issues/6196">#6196</a>)</li>
<li><a
href="bf6974f16a"><code>bf6974f</code></a>
chore(ci): add npm tag action; (<a
href="https://redirect.github.com/axios/axios/issues/6231">#6231</a>)</li>
<li><a
href="a52e4d9af5"><code>a52e4d9</code></a>
chore(release): v1.6.7 (<a
href="https://redirect.github.com/axios/axios/issues/6204">#6204</a>)</li>
<li><a
href="2b69888dd5"><code>2b69888</code></a>
chore: remove unnecessary check (<a
href="https://redirect.github.com/axios/axios/issues/6186">#6186</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v0.25.0...v1.6.8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=0.25.0&new-version=1.6.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-10 12:56:54 +10:00
zhexu14
8aa38a83ff Bump version to 12 (#3370)
Bump changelog, bug reports and version.py to appropriate values now
that 11 is released.
2024-04-10 12:54:26 +10:00
dependabot[bot]
7d5bb0356f Bump pillow from 10.2.0 to 10.3.0 (#3366)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.2.0 to
10.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/releases">pillow's
releases</a>.</em></p>
<blockquote>
<h2>10.3.0</h2>
<p><a
href="https://pillow.readthedocs.io/en/stable/releasenotes/10.3.0.html">https://pillow.readthedocs.io/en/stable/releasenotes/10.3.0.html</a></p>
<h2>Changes</h2>
<ul>
<li>CVE-2024-28219: Use strncpy to avoid buffer overflow <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7928">#7928</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Use <code>functools.lru_cache</code> for <code>hopper()</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7912">#7912</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Raise ValueError if seeking to greater than offset-sized integer in
TIFF <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7883">#7883</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Improve speed of loading QOI images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7925">#7925</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added RGB to I;16N conversion <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7920">#7920</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Add --report argument to <strong>main</strong>.py to omit supported
formats <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7818">#7818</a>
[<a href="https://github.com/nulano"><code>@​nulano</code></a>]</li>
<li>Added RGB to I;16, I;16L and I;16B conversion <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7918">#7918</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fix editable installation with custom build backend and
configuration options <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7658">#7658</a>
[<a href="https://github.com/nulano"><code>@​nulano</code></a>]</li>
<li>Fix putdata() for I;16N on big-endian <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7209">#7209</a>
[<a href="https://github.com/Yay295"><code>@​Yay295</code></a>]</li>
<li>Determine MPO size from markers, not EXIF data <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7884">#7884</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Improved conversion from RGB to RGBa, LA and La <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7888">#7888</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Support FITS images with GZIP_1 compression <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7894">#7894</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Use I;16 mode for 9-bit JPEG 2000 images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7900">#7900</a>
[<a
href="https://github.com/scaramallion"><code>@​scaramallion</code></a>]</li>
<li>Raise ValueError if kmeans is negative <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7891">#7891</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Remove TIFF tag OSUBFILETYPE when saving using libtiff <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7893">#7893</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Raise ValueError for negative values when loading P1-P3 PPM images
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/7882">#7882</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added reading of JPEG2000 palettes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7870">#7870</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added alpha_quality argument when saving WebP images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7872">#7872</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fixed joined corners for ImageDraw rounded_rectangle() non-integer
dimensions <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7881">#7881</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Removed Python and NumPy pinning on Cygwin <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7880">#7880</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update UnidentifiedImageError and <strong>version</strong> imports
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/7644">#7644</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Stop reading EPS image at EOF marker <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7753">#7753</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>PSD layer co-ordinates may be negative <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7706">#7706</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Use subprocess with CREATE_NO_WINDOW flag in ImageShow WindowsViewer
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/7791">#7791</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>When saving GIF frame that restores to background color, do not fill
identical pixels <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7788">#7788</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fixed reading PNG iCCP compression method <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7823">#7823</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Allow writing IFDRational to UNDEFINED tag <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7840">#7840</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fix logged tag name when loading Exif data <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7842">#7842</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Use maximum frame size in IHDR chunk when saving APNG images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7821">#7821</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Prevent opening P TGA images without a palette <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7797">#7797</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Use palette when loading ICO images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7798">#7798</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Use consistent arguments for load_read and load_seek <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7713">#7713</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Turn off nullability warnings for macOS SDK <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7827">#7827</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fix shift-sign issue in Convert.c <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7838">#7838</a>
[<a href="https://github.com/r-barnes"><code>@​r-barnes</code></a>]</li>
<li>winbuild: Refactor dependency versions into constants <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7843">#7843</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Build macOS arm64 wheels natively <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7852">#7852</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fixed typo <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7855">#7855</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Open 16-bit grayscale PNGs as I;16 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7849">#7849</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Handle truncated chunks at the end of PNG images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7709">#7709</a>
[<a href="https://github.com/lajiyuan"><code>@​lajiyuan</code></a>]</li>
<li>Match mask size to pasted image size in GifImagePlugin <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7779">#7779</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Changed SupportsGetMesh protocol to be public <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7841">#7841</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Release GIL while calling <code>WebPAnimDecoderGetNext</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7782">#7782</a>
[<a
href="https://github.com/evanmiller"><code>@​evanmiller</code></a>]</li>
<li>Fixed reading FLI/FLC images with a prefix chunk <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7804">#7804</a>
[<a href="https://github.com/twolife"><code>@​twolife</code></a>]</li>
<li>Updated package name for Tidelift <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7810">#7810</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Removed unused code <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7744">#7744</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst">pillow's
changelog</a>.</em></p>
<blockquote>
<h2>10.3.0 (2024-04-01)</h2>
<ul>
<li>
<p>CVE-2024-28219: Use <code>strncpy</code> to avoid buffer overflow <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7928">#7928</a>
[radarhere, hugovk]</p>
</li>
<li>
<p>Deprecate <code>eval()</code>, replacing it with
<code>lambda_eval()</code> and <code>unsafe_eval()</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7927">#7927</a>
[radarhere, hugovk]</p>
</li>
<li>
<p>Raise <code>ValueError</code> if seeking to greater than offset-sized
integer in TIFF <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7883">#7883</a>
[radarhere]</p>
</li>
<li>
<p>Add <code>--report</code> argument to <code>__main__.py</code> to
omit supported formats <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7818">#7818</a>
[nulano, radarhere, hugovk]</p>
</li>
<li>
<p>Added RGB to I;16, I;16L, I;16B and I;16N conversion <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7918">#7918</a>,
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/7920">#7920</a>
[radarhere]</p>
</li>
<li>
<p>Fix editable installation with custom build backend and configuration
options <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7658">#7658</a>
[nulano, radarhere]</p>
</li>
<li>
<p>Fix putdata() for I;16N on big-endian <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7209">#7209</a>
[Yay295, hugovk, radarhere]</p>
</li>
<li>
<p>Determine MPO size from markers, not EXIF data <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7884">#7884</a>
[radarhere]</p>
</li>
<li>
<p>Improved conversion from RGB to RGBa, LA and La <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7888">#7888</a>
[radarhere]</p>
</li>
<li>
<p>Support FITS images with GZIP_1 compression <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7894">#7894</a>
[radarhere]</p>
</li>
<li>
<p>Use I;16 mode for 9-bit JPEG 2000 images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7900">#7900</a>
[scaramallion, radarhere]</p>
</li>
<li>
<p>Raise ValueError if kmeans is negative <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7891">#7891</a>
[radarhere]</p>
</li>
<li>
<p>Remove TIFF tag OSUBFILETYPE when saving using libtiff <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7893">#7893</a>
[radarhere]</p>
</li>
<li>
<p>Raise ValueError for negative values when loading P1-P3 PPM images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7882">#7882</a>
[radarhere]</p>
</li>
<li>
<p>Added reading of JPEG2000 palettes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7870">#7870</a>
[radarhere]</p>
</li>
<li>
<p>Added alpha_quality argument when saving WebP images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7872">#7872</a>
[radarhere]</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5c89d88eee"><code>5c89d88</code></a>
10.3.0 version bump</li>
<li><a
href="63cbfcfdea"><code>63cbfcf</code></a>
Update CHANGES.rst [ci skip]</li>
<li><a
href="2776126aa9"><code>2776126</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7928">#7928</a>
from python-pillow/lcms</li>
<li><a
href="aeb51cbb16"><code>aeb51cb</code></a>
Merge branch 'main' into lcms</li>
<li><a
href="5beb0b6664"><code>5beb0b6</code></a>
Update CHANGES.rst [ci skip]</li>
<li><a
href="cac6ffa7b3"><code>cac6ffa</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7927">#7927</a>
from python-pillow/imagemath</li>
<li><a
href="f5eeeacf75"><code>f5eeeac</code></a>
Name as 'options' in lambda_eval and unsafe_eval, but '_dict' in
deprecated eval</li>
<li><a
href="facf3af93d"><code>facf3af</code></a>
Added release notes</li>
<li><a
href="2a93aba5cf"><code>2a93aba</code></a>
Use strncpy to avoid buffer overflow</li>
<li><a
href="a670597bc3"><code>a670597</code></a>
Update CHANGES.rst [ci skip]</li>
<li>Additional commits viewable in <a
href="https://github.com/python-pillow/Pillow/compare/10.2.0...10.3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pillow&package-manager=pip&previous-version=10.2.0&new-version=10.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-10 12:42:45 +10:00
dependabot[bot]
143b775639 Bump express from 4.17.3 to 4.19.2 in /client (#3365)
Bumps [express](https://github.com/expressjs/express) from 4.17.3 to
4.19.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/expressjs/express/releases">express's
releases</a>.</em></p>
<blockquote>
<h2>4.19.2</h2>
<h2>What's Changed</h2>
<ul>
<li><a
href="0b746953c4">Improved
fix for open redirect allow list bypass</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/expressjs/express/compare/4.19.1...4.19.2">https://github.com/expressjs/express/compare/4.19.1...4.19.2</a></p>
<h2>4.19.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix ci after location patch by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5552">expressjs/express#5552</a></li>
<li>fixed un-edited version in history.md for 4.19.0 by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5556">expressjs/express#5556</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/expressjs/express/compare/4.19.0...4.19.1">https://github.com/expressjs/express/compare/4.19.0...4.19.1</a></p>
<h2>4.19.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix typo in release date by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5527">expressjs/express#5527</a></li>
<li>docs: nominating <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> to be
project captian by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5511">expressjs/express#5511</a></li>
<li>docs: loosen TC activity rules by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5510">expressjs/express#5510</a></li>
<li>Add note on how to update docs for new release by <a
href="https://github.com/crandmck"><code>@​crandmck</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5541">expressjs/express#5541</a></li>
<li><a
href="660ccf5fa3">Prevent
open redirect allow list bypass due to encodeurl</a></li>
<li>Release 4.19.0 by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5551">expressjs/express#5551</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/crandmck"><code>@​crandmck</code></a>
made their first contribution in <a
href="https://redirect.github.com/expressjs/express/pull/5541">expressjs/express#5541</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/expressjs/express/compare/4.18.3...4.19.0">https://github.com/expressjs/express/compare/4.18.3...4.19.0</a></p>
<h2>4.18.3</h2>
<h2>Main Changes</h2>
<ul>
<li>Fix routing requests without method</li>
<li>deps: body-parser@1.20.2
<ul>
<li>Fix strict json error message on Node.js 19+</li>
<li>deps: content-type@~1.0.5</li>
<li>deps: raw-body@2.5.2</li>
</ul>
</li>
</ul>
<h2>Other Changes</h2>
<ul>
<li>Use https: protocol instead of deprecated git: protocol by <a
href="https://github.com/vcsjones"><code>@​vcsjones</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5032">expressjs/express#5032</a></li>
<li>build: Node.js@16.18 and Node.js@18.12 by <a
href="https://github.com/abenhamdine"><code>@​abenhamdine</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5034">expressjs/express#5034</a></li>
<li>ci: update actions/checkout to v3 by <a
href="https://github.com/armujahid"><code>@​armujahid</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5027">expressjs/express#5027</a></li>
<li>test: remove unused function arguments in params by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5124">expressjs/express#5124</a></li>
<li>Remove unused originalIndex from acceptParams by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5119">expressjs/express#5119</a></li>
<li>Fixed typos by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5117">expressjs/express#5117</a></li>
<li>examples: remove unused params by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5113">expressjs/express#5113</a></li>
<li>fix: parameter str is not described in JSDoc by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5130">expressjs/express#5130</a></li>
<li>fix: typos in History.md by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5131">expressjs/express#5131</a></li>
<li>build : add Node.js@19.7 by <a
href="https://github.com/abenhamdine"><code>@​abenhamdine</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5028">expressjs/express#5028</a></li>
<li>test: remove unused function arguments in params by <a
href="https://github.com/raksbisht"><code>@​raksbisht</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5137">expressjs/express#5137</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/expressjs/express/blob/master/History.md">express's
changelog</a>.</em></p>
<blockquote>
<h1>4.19.2 / 2024-03-25</h1>
<ul>
<li>Improved fix for open redirect allow list bypass</li>
</ul>
<h1>4.19.1 / 2024-03-20</h1>
<ul>
<li>Allow passing non-strings to res.location with new encoding handling
checks</li>
</ul>
<h1>4.19.0 / 2024-03-20</h1>
<ul>
<li>Prevent open redirect allow list bypass due to encodeurl</li>
<li>deps: cookie@0.6.0</li>
</ul>
<h1>4.18.3 / 2024-02-29</h1>
<ul>
<li>Fix routing requests without method</li>
<li>deps: body-parser@1.20.2
<ul>
<li>Fix strict json error message on Node.js 19+</li>
<li>deps: content-type@~1.0.5</li>
<li>deps: raw-body@2.5.2</li>
</ul>
</li>
<li>deps: cookie@0.6.0
<ul>
<li>Add <code>partitioned</code> option</li>
</ul>
</li>
</ul>
<h1>4.18.2 / 2022-10-08</h1>
<ul>
<li>Fix regression routing a large stack in a single route</li>
<li>deps: body-parser@1.20.1
<ul>
<li>deps: qs@6.11.0</li>
<li>perf: remove unnecessary object clone</li>
</ul>
</li>
<li>deps: qs@6.11.0</li>
</ul>
<h1>4.18.1 / 2022-04-29</h1>
<ul>
<li>Fix hanging on large stack of sync routes</li>
</ul>
<h1>4.18.0 / 2022-04-25</h1>
<ul>
<li>Add &quot;root&quot; option to <code>res.download</code></li>
<li>Allow <code>options</code> without <code>filename</code> in
<code>res.download</code></li>
<li>Deprecate string and non-integer arguments to
<code>res.status</code></li>
<li>Fix behavior of <code>null</code>/<code>undefined</code> as
<code>maxAge</code> in <code>res.cookie</code></li>
<li>Fix handling very large stacks of sync middleware</li>
<li>Ignore <code>Object.prototype</code> values in settings through
<code>app.set</code>/<code>app.get</code></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="04bc62787b"><code>04bc627</code></a>
4.19.2</li>
<li><a
href="da4d763ff6"><code>da4d763</code></a>
Improved fix for open redirect allow list bypass</li>
<li><a
href="4f0f6cc67d"><code>4f0f6cc</code></a>
4.19.1</li>
<li><a
href="a003cfab03"><code>a003cfa</code></a>
Allow passing non-strings to res.location with new encoding handling
checks f...</li>
<li><a
href="a1fa90fcea"><code>a1fa90f</code></a>
fixed un-edited version in history.md for 4.19.0</li>
<li><a
href="11f2b1db22"><code>11f2b1d</code></a>
build: fix build due to inconsistent supertest behavior in older
versions</li>
<li><a
href="084e36506a"><code>084e365</code></a>
4.19.0</li>
<li><a
href="0867302ddb"><code>0867302</code></a>
Prevent open redirect allow list bypass due to encodeurl</li>
<li><a
href="567c9c665d"><code>567c9c6</code></a>
Add note on how to update docs for new release (<a
href="https://redirect.github.com/expressjs/express/issues/5541">#5541</a>)</li>
<li><a
href="69a4cf2819"><code>69a4cf2</code></a>
deps: cookie@0.6.0</li>
<li>Additional commits viewable in <a
href="https://github.com/expressjs/express/compare/4.17.3...4.19.2">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~wesleytodd">wesleytodd</a>, a new releaser
for express since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=express&package-manager=npm_and_yarn&previous-version=4.17.3&new-version=4.19.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-29 22:44:03 +01:00
dependabot[bot]
f296925c22 Bump webpack-dev-middleware from 5.3.1 to 5.3.4 in /client (#3363)
Bumps
[webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware)
from 5.3.1 to 5.3.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpack/webpack-dev-middleware/releases">webpack-dev-middleware's
releases</a>.</em></p>
<blockquote>
<h2>v5.3.4</h2>
<h3><a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4">5.3.4</a>
(2024-03-20)</h3>
<h3>Bug Fixes</h3>
<ul>
<li><strong>security:</strong> do not allow to read files above (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1779">#1779</a>)
(<a
href="189c4ac7d2">189c4ac</a>)</li>
</ul>
<h2>v5.3.3</h2>
<h3><a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.2...v5.3.3">5.3.3</a>
(2022-05-18)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>types for <code>Request</code> and <code>Response</code> (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1271">#1271</a>)
(<a
href="eeb8aa8b11">eeb8aa8</a>)</li>
</ul>
<h2>v5.3.2</h2>
<h3><a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.1...v5.3.2">5.3.2</a>
(2022-05-17)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>node types (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1195">#1195</a>)
(<a
href="d68ab3607a">d68ab36</a>)</li>
<li>compatibility with Node.js 18</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md">webpack-dev-middleware's
changelog</a>.</em></p>
<blockquote>
<h3><a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4">5.3.4</a>
(2024-03-20)</h3>
<h3>Bug Fixes</h3>
<ul>
<li><strong>security:</strong> do not allow to read files above (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1779">#1779</a>)
(<a
href="189c4ac7d2">189c4ac</a>)</li>
</ul>
<h3><a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.2...v5.3.3">5.3.3</a>
(2022-05-18)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>types for <code>Request</code> and <code>Response</code> (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1271">#1271</a>)
(<a
href="eeb8aa8b11">eeb8aa8</a>)</li>
</ul>
<h3><a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.1...v5.3.2">5.3.2</a>
(2022-05-17)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>node types (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1195">#1195</a>)
(<a
href="d68ab3607a">d68ab36</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="86071ead69"><code>86071ea</code></a>
chore(release): 5.3.4</li>
<li><a
href="189c4ac7d2"><code>189c4ac</code></a>
fix(security): do not allow to read files above (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1779">#1779</a>)</li>
<li><a
href="f3c62b8176"><code>f3c62b8</code></a>
chore(release): 5.3.3</li>
<li><a
href="eeb8aa8b11"><code>eeb8aa8</code></a>
fix: types for <code>Request</code> and <code>Response</code> (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1271">#1271</a>)</li>
<li><a
href="1a45388bcf"><code>1a45388</code></a>
chore(release): 5.3.2</li>
<li><a
href="b8fb945b1b"><code>b8fb945</code></a>
chore(deps): memfs force update (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1269">#1269</a>)</li>
<li><a
href="f88067d31f"><code>f88067d</code></a>
chore: update deps and ci (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1260">#1260</a>)</li>
<li><a
href="71863189d8"><code>7186318</code></a>
chore(deps-dev): bump <code>@​commitlint/cli</code></li>
<li><a
href="57c50ef1b6"><code>57c50ef</code></a>
ci: update <code>checkout</code>, <code>setup-node</code>, and
<code>codecov</code> actions (<a
href="https://redirect.github.com/webpack/webpack-dev-middleware/issues/1267">#1267</a>)</li>
<li><a
href="840146a501"><code>840146a</code></a>
chore(deps-dev): bump <code>@​babel/preset-env</code></li>
<li>Additional commits viewable in <a
href="https://github.com/webpack/webpack-dev-middleware/compare/v5.3.1...v5.3.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=webpack-dev-middleware&package-manager=npm_and_yarn&previous-version=5.3.1&new-version=5.3.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-29 22:42:27 +01:00
dependabot[bot]
dfe0c0b315 Bump black from 23.11.0 to 24.3.0 (#3361)
Bumps [black](https://github.com/psf/black) from 23.11.0 to 24.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/psf/black/releases">black's
releases</a>.</em></p>
<blockquote>
<h2>24.3.0</h2>
<h3>Highlights</h3>
<p>This release is a milestone: it fixes Black's first CVE security
vulnerability. If you
run Black on untrusted input, or if you habitually put thousands of
leading tab
characters in your docstrings, you are strongly encouraged to upgrade
immediately to fix
<a
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-21503">CVE-2024-21503</a>.</p>
<p>This release also fixes a bug in Black's AST safety check that
allowed Black to make
incorrect changes to certain f-strings that are valid in Python 3.12 and
higher.</p>
<h3>Stable style</h3>
<ul>
<li>Don't move comments along with delimiters, which could cause crashes
(<a
href="https://redirect.github.com/psf/black/issues/4248">#4248</a>)</li>
<li>Strengthen AST safety check to catch more unsafe changes to strings.
Previous versions
of Black would incorrectly format the contents of certain unusual
f-strings containing
nested strings with the same quote type. Now, Black will crash on such
strings until
support for the new f-string syntax is implemented. (<a
href="https://redirect.github.com/psf/black/issues/4270">#4270</a>)</li>
<li>Fix a bug where line-ranges exceeding the last code line would not
work as expected
(<a
href="https://redirect.github.com/psf/black/issues/4273">#4273</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Fix catastrophic performance on docstrings that contain large
numbers of leading tab
characters. This fixes
<a
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-21503">CVE-2024-21503</a>.
(<a
href="https://redirect.github.com/psf/black/issues/4278">#4278</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Note what happens when <code>--check</code> is used with
<code>--quiet</code> (<a
href="https://redirect.github.com/psf/black/issues/4236">#4236</a>)</li>
</ul>
<h2>24.2.0</h2>
<h3>Stable style</h3>
<ul>
<li>Fixed a bug where comments where mistakenly removed along with
redundant parentheses
(<a
href="https://redirect.github.com/psf/black/issues/4218">#4218</a>)</li>
</ul>
<h3>Preview style</h3>
<ul>
<li>Move the <code>hug_parens_with_braces_and_square_brackets</code>
feature to the unstable style
due to an outstanding crash and proposed formatting tweaks (<a
href="https://redirect.github.com/psf/black/issues/4198">#4198</a>)</li>
<li>Fixed a bug where base expressions caused inconsistent formatting of
** in tenary
expression (<a
href="https://redirect.github.com/psf/black/issues/4154">#4154</a>)</li>
<li>Checking for newline before adding one on docstring that is almost
at the line limit
(<a
href="https://redirect.github.com/psf/black/issues/4185">#4185</a>)</li>
<li>Remove redundant parentheses in <code>case</code> statement
<code>if</code> guards (<a
href="https://redirect.github.com/psf/black/issues/4214">#4214</a>).</li>
</ul>
<h3>Configuration</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/psf/black/blob/main/CHANGES.md">black's
changelog</a>.</em></p>
<blockquote>
<h2>24.3.0</h2>
<h3>Highlights</h3>
<p>This release is a milestone: it fixes Black's first CVE security
vulnerability. If you
run Black on untrusted input, or if you habitually put thousands of
leading tab
characters in your docstrings, you are strongly encouraged to upgrade
immediately to fix
<a
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-21503">CVE-2024-21503</a>.</p>
<p>This release also fixes a bug in Black's AST safety check that
allowed Black to make
incorrect changes to certain f-strings that are valid in Python 3.12 and
higher.</p>
<h3>Stable style</h3>
<ul>
<li>Don't move comments along with delimiters, which could cause crashes
(<a
href="https://redirect.github.com/psf/black/issues/4248">#4248</a>)</li>
<li>Strengthen AST safety check to catch more unsafe changes to strings.
Previous versions
of Black would incorrectly format the contents of certain unusual
f-strings containing
nested strings with the same quote type. Now, Black will crash on such
strings until
support for the new f-string syntax is implemented. (<a
href="https://redirect.github.com/psf/black/issues/4270">#4270</a>)</li>
<li>Fix a bug where line-ranges exceeding the last code line would not
work as expected
(<a
href="https://redirect.github.com/psf/black/issues/4273">#4273</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Fix catastrophic performance on docstrings that contain large
numbers of leading tab
characters. This fixes
<a
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-21503">CVE-2024-21503</a>.
(<a
href="https://redirect.github.com/psf/black/issues/4278">#4278</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Note what happens when <code>--check</code> is used with
<code>--quiet</code> (<a
href="https://redirect.github.com/psf/black/issues/4236">#4236</a>)</li>
</ul>
<h2>24.2.0</h2>
<h3>Stable style</h3>
<ul>
<li>Fixed a bug where comments where mistakenly removed along with
redundant parentheses
(<a
href="https://redirect.github.com/psf/black/issues/4218">#4218</a>)</li>
</ul>
<h3>Preview style</h3>
<ul>
<li>Move the <code>hug_parens_with_braces_and_square_brackets</code>
feature to the unstable style
due to an outstanding crash and proposed formatting tweaks (<a
href="https://redirect.github.com/psf/black/issues/4198">#4198</a>)</li>
<li>Fixed a bug where base expressions caused inconsistent formatting of
** in tenary
expression (<a
href="https://redirect.github.com/psf/black/issues/4154">#4154</a>)</li>
<li>Checking for newline before adding one on docstring that is almost
at the line limit
(<a
href="https://redirect.github.com/psf/black/issues/4185">#4185</a>)</li>
<li>Remove redundant parentheses in <code>case</code> statement
<code>if</code> guards (<a
href="https://redirect.github.com/psf/black/issues/4214">#4214</a>).</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="552baf8229"><code>552baf8</code></a>
Prepare release 24.3.0 (<a
href="https://redirect.github.com/psf/black/issues/4279">#4279</a>)</li>
<li><a
href="f000936726"><code>f000936</code></a>
Fix catastrophic performance in lines_with_leading_tabs_expanded() (<a
href="https://redirect.github.com/psf/black/issues/4278">#4278</a>)</li>
<li><a
href="7b5a657285"><code>7b5a657</code></a>
Fix --line-ranges behavior when ranges are at EOF (<a
href="https://redirect.github.com/psf/black/issues/4273">#4273</a>)</li>
<li><a
href="1abcffc818"><code>1abcffc</code></a>
Use regex where we ignore case on windows (<a
href="https://redirect.github.com/psf/black/issues/4252">#4252</a>)</li>
<li><a
href="719e67462c"><code>719e674</code></a>
Fix 4227: Improve documentation for --quiet --check (<a
href="https://redirect.github.com/psf/black/issues/4236">#4236</a>)</li>
<li><a
href="e5510afc06"><code>e5510af</code></a>
update plugin url for Thonny (<a
href="https://redirect.github.com/psf/black/issues/4259">#4259</a>)</li>
<li><a
href="6af7d11096"><code>6af7d11</code></a>
Fix AST safety check false negative (<a
href="https://redirect.github.com/psf/black/issues/4270">#4270</a>)</li>
<li><a
href="f03ee113c9"><code>f03ee11</code></a>
Ensure <code>blib2to3.pygram</code> is initialized before use (<a
href="https://redirect.github.com/psf/black/issues/4224">#4224</a>)</li>
<li><a
href="e4bfedbec2"><code>e4bfedb</code></a>
fix: Don't move comments while splitting delimiters (<a
href="https://redirect.github.com/psf/black/issues/4248">#4248</a>)</li>
<li><a
href="d0287e1f75"><code>d0287e1</code></a>
Make trailing comma logic more concise (<a
href="https://redirect.github.com/psf/black/issues/4202">#4202</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/psf/black/compare/23.11.0...24.3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=black&package-manager=pip&previous-version=23.11.0&new-version=24.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 22:05:57 +11:00
zhexu14
bd5087b3c7 Update changelog, contributors list for Superhornet mod support (#3362)
Update changelog, contributors list for Superhornet mod support
2024-03-21 22:05:33 +11:00
Chilli935
88ebb8b612 FA18EFG mod support Patch 4 (#3340)
- Corrected banner file types.
- Corrected australia_2005.yaml and usn_2005.yaml
- Added australia_2009.yaml and usn_2009.yaml
2024-03-21 21:52:34 +11:00
dependabot[bot]
63702f859d Bump follow-redirects from 1.15.4 to 1.15.6 in /client (#3359)
Bumps
[follow-redirects](https://github.com/follow-redirects/follow-redirects)
from 1.15.4 to 1.15.6.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="35a517c586"><code>35a517c</code></a>
Release version 1.15.6 of the npm package.</li>
<li><a
href="c4f847f851"><code>c4f847f</code></a>
Drop Proxy-Authorization across hosts.</li>
<li><a
href="8526b4a1b2"><code>8526b4a</code></a>
Use GitHub for disclosure.</li>
<li><a
href="b1677ce001"><code>b1677ce</code></a>
Release version 1.15.5 of the npm package.</li>
<li><a
href="d8914f7982"><code>d8914f7</code></a>
Preserve fragment in responseUrl.</li>
<li>See full diff in <a
href="https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=follow-redirects&package-manager=npm_and_yarn&previous-version=1.15.4&new-version=1.15.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-17 22:29:19 +11:00
zhexu14
cc5e2ba26c Update pydcs (#3360)
This PR updates pydcs version to fix issues from the DCS 2.9.3.51704
export.
2024-03-17 20:52:36 +11:00
zhexu14
b0a8d53fa6 Beacon update (#3357)
This PR cherry-picks some DCS-update related changes from Retribution
fork:
- Updates to beacon information 
- Fixes to script used to import beacons.

---------

Authored-by: Raffson <Raffson@users.noreply.github.com>
2024-03-16 10:51:41 +11:00
zhexu14
77b7f777f6 Issue 3337 (#3356)
This PR addresses #3337 by:
- Updating the UI to identify that a destroyed carrier/LHA as "Sunk"
- Fall back on targeting other groups in the NavalControlPoint (e.g.
escorts if present) if the carrier/LHA is sunk.
2024-03-15 22:33:25 +11:00
zhexu14
e59da610e9 resources: reformat yaml files to be friendly to git (#3354)
This PR reformats some yaml files to be more friendly to Git. No
contents have been changed.
2024-03-09 17:31:31 +11:00
Starfire13
b61310d229 Update Starfire's campaigns (#3352)
This updates all ten of my campaigns with the improvements I made for
the Retribution versions. There are Retribution-specific units and
trigger zones in the miz templates, but I've tested them and they don't
appear to cause any issues (since Liberation will just ignore the
unknown units and trigger zones). This will make things easier for me in
the future, because then I don't have to maintain two separate sets of
the same campaign files.

The changes include a total redo of supply routes for better convoy
on-road pathing, as well as a balance pass for squadron distribution and
strength.

I have also made a slight edit to one of my faction files to fix a typo.
2024-03-09 15:19:38 +11:00
zhexu14
6550400604 Track damage (#3351)
This PR partially addresses #3313 by:
- Tracking DCS hit events and storing the unit hit point updates in
state.json
- Adding logic to kill aircraft when the hit points is reduced to 1, as
opposed to the DCS logic of hit points to 0. This behavior allows
Liberation to track deaths to parked aircraft, which are uncontrolled
and seem to have different damage logic in DCS.
- Tracking damage to TheaterGroundObjects across turns and killing the
unit when the unit's hitpoints reduces to 1 or lower.

Intention is to build on this PR by also tracking front line objects and
statics (buildings). However, larger refactoring is required and so
splitting those into a separate PR.
2024-03-09 15:07:38 +11:00
zhexu14
1ee1113e48 Bump starlette and fastapi versions (#3350)
Bump starlette to 0.35.1 and fastapi to 0.109.1 in one commit as they
depend on each other.
2024-03-08 22:30:02 +11:00
dependabot[bot]
01f22d6da7 Bump follow-redirects from 1.15.2 to 1.15.4 in /client (#3326)
Bumps
[follow-redirects](https://github.com/follow-redirects/follow-redirects)
from 1.15.2 to 1.15.4.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="65858205e5"><code>6585820</code></a>
Release version 1.15.4 of the npm package.</li>
<li><a
href="7a6567e16d"><code>7a6567e</code></a>
Disallow bracketed hostnames.</li>
<li><a
href="05629af696"><code>05629af</code></a>
Prefer native URL instead of deprecated url.parse.</li>
<li><a
href="1cba8e85fa"><code>1cba8e8</code></a>
Prefer native URL instead of legacy url.resolve.</li>
<li><a
href="72bc2a4229"><code>72bc2a4</code></a>
Simplify _processResponse error handling.</li>
<li><a
href="3d42aecdca"><code>3d42aec</code></a>
Add bracket tests.</li>
<li><a
href="bcbb096b32"><code>bcbb096</code></a>
Do not directly set Error properties.</li>
<li><a
href="192dbe7ce6"><code>192dbe7</code></a>
Release version 1.15.3 of the npm package.</li>
<li><a
href="bd8c81e4f3"><code>bd8c81e</code></a>
Fix resource leak on destroy.</li>
<li><a
href="9c728c314b"><code>9c728c3</code></a>
Split linting and testing.</li>
<li>Additional commits viewable in <a
href="https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=follow-redirects&package-manager=npm_and_yarn&previous-version=1.15.2&new-version=1.15.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-08 22:00:36 +11:00
dependabot[bot]
8e6893d550 Bump ip from 1.1.5 to 1.1.9 in /client (#3342)
Bumps [ip](https://github.com/indutny/node-ip) from 1.1.5 to 1.1.9.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1ecbf2fd8c"><code>1ecbf2f</code></a>
1.1.9</li>
<li><a
href="6a3ada9b47"><code>6a3ada9</code></a>
lib: fixed CVE-2023-42282 and added unit test</li>
<li><a
href="5dc3b2f3f4"><code>5dc3b2f</code></a>
1.1.8</li>
<li><a
href="8e6f28b23a"><code>8e6f28b</code></a>
lib: even better node 6 support</li>
<li><a
href="088c9e5664"><code>088c9e5</code></a>
1.1.7</li>
<li><a
href="1a4ca35ddc"><code>1a4ca35</code></a>
lib: add back support for Node.js 6</li>
<li><a
href="af82ef42ad"><code>af82ef4</code></a>
1.1.6</li>
<li><a
href="dba19f6c0c"><code>dba19f6</code></a>
package: exclude test folder from publishing</li>
<li><a
href="7cd7f30991"><code>7cd7f30</code></a>
ci: use github workflows</li>
<li><a
href="4de50aec87"><code>4de50ae</code></a>
lib: node 18 support</li>
<li>See full diff in <a
href="https://github.com/indutny/node-ip/compare/v1.1.5...v1.1.9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ip&package-manager=npm_and_yarn&previous-version=1.1.5&new-version=1.1.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-08 22:00:26 +11:00
zhexu14
fa9d5525c0 Update requirements.txt to point to a temporary build of pydcs that f… (#3349)
…ixes a bug with loading legacy missions like what Liberation ships with
for layouts
2024-03-07 22:01:40 +11:00
zhexu14
5127022910 Update README.md due to changes in URLs (#3348)
This PR updates a link in README.md.
2024-03-06 22:24:38 +11:00
Starfire13
e42a7b9a59 Remove squadrons from Nevatim in Exercise Bright Star (#3345)
This is a (potentially) temporary modification for Exercise Bright Star
that moves one of its squadrons to Hatzerim and disables the other two.
The reason is because Nevatim is currently bugged and only 11 out of its
120 airfield parking spots are usable. You can place aircraft into the
other parking spots in the mission editor but they will all explode upon
entering the mission.
2024-02-28 20:35:03 +11:00
Starfire13
24c9ca5d12 Add FCR to the Apache Blk II's new loadout slot (#3343)
The Apache Blk II now has a dedicated loadout slot for the CFR, rather
than it being set by a checkbox in the mission editor. This PR updates
the loadouts for that new slot.

This PR should not be merged until Liberation/pydcs has been updated to
support the change.
2024-02-24 16:25:25 +11:00
zhexu14
678dd58e7d Update pydcs version for DCS 2.9.3.51704 (#3344)
- Updates pydcs version for DCS 2.9.3.51704
- Removes AH-64 FCR/RFI default override, which does not exist any more.
- Update custom payloads for SA342L/M due to changes to CLSIDs. SA342
Minigun payloads also updated but not tested as the unit type does not
have any tasks assigned.

This PR is missing updates to the AH-64 payloads, so this PR complements
#3343
2024-02-24 16:22:54 +11:00
zhexu14
d6879040ad Fix syntax error in tripoint_hostility.yaml campaign definition (#3341)
This PR fixes a minor syntax error in tripoint_hostility.yaml that was
preventing the New Game Wizard from opening successfully.
2024-02-21 20:47:40 +11:00
Starfire13
d0be4b6a29 Update Vectron's Claw (#3339)
Modernises Vectron's Claw, which is my oldest campaign and is getting a
little outdated.
2024-02-21 20:47:10 +11:00
dependabot[bot]
0d71372377 Bump jinja2 from 3.1.2 to 3.1.3 (#3327)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pallets/jinja/releases">jinja2's
releases</a>.</em></p>
<blockquote>
<h2>3.1.3</h2>
<p>This is a fix release for the 3.1.x feature branch.</p>
<ul>
<li>Fix for <a
href="https://github.com/pallets/jinja/security/advisories/GHSA-h5c8-rqwp-cp95">GHSA-h5c8-rqwp-cp95</a>.
You are affected if you are using <code>xmlattr</code> and passing user
input as attribute keys.</li>
<li>Changes: <a
href="https://jinja.palletsprojects.com/en/3.1.x/changes/#version-3-1-3">https://jinja.palletsprojects.com/en/3.1.x/changes/#version-3-1-3</a></li>
<li>Milestone: <a
href="https://github.com/pallets/jinja/milestone/15?closed=1">https://github.com/pallets/jinja/milestone/15?closed=1</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pallets/jinja/blob/main/CHANGES.rst">jinja2's
changelog</a>.</em></p>
<blockquote>
<h2>Version 3.1.3</h2>
<p>Released 2024-01-10</p>
<ul>
<li>Fix compiler error when checking if required blocks in parent
templates are
empty. :pr:<code>1858</code></li>
<li><code>xmlattr</code> filter does not allow keys with spaces.
GHSA-h5c8-rqwp-cp95</li>
<li>Make error messages stemming from invalid nesting of <code>{% trans
%}</code> blocks
more helpful. :pr:<code>1918</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d9de4bb215"><code>d9de4bb</code></a>
release version 3.1.3</li>
<li><a
href="50124e1656"><code>50124e1</code></a>
skip test pypi</li>
<li><a
href="9ea7222ef3"><code>9ea7222</code></a>
use trusted publishing</li>
<li><a
href="da703f7aae"><code>da703f7</code></a>
use trusted publishing</li>
<li><a
href="bce1746925"><code>bce1746</code></a>
use trusted publishing</li>
<li><a
href="7277d8068b"><code>7277d80</code></a>
update pre-commit hooks</li>
<li><a
href="5c8a105224"><code>5c8a105</code></a>
Make nested-trans-block exceptions nicer (<a
href="https://redirect.github.com/pallets/jinja/issues/1918">#1918</a>)</li>
<li><a
href="19a55db3b4"><code>19a55db</code></a>
Make nested-trans-block exceptions nicer</li>
<li><a
href="716795349a"><code>7167953</code></a>
Merge pull request from GHSA-h5c8-rqwp-cp95</li>
<li><a
href="7dd3680e6e"><code>7dd3680</code></a>
xmlattr filter disallows keys with spaces</li>
<li>Additional commits viewable in <a
href="https://github.com/pallets/jinja/compare/3.1.2...3.1.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jinja2&package-manager=pip&previous-version=3.1.2&new-version=3.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-20 22:55:03 +11:00
dependabot[bot]
86de5df21e Bump pillow from 10.0.1 to 10.2.0 (#3330)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.0.1 to
10.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/releases">pillow's
releases</a>.</em></p>
<blockquote>
<h2>10.2.0</h2>
<p><a
href="https://pillow.readthedocs.io/en/stable/releasenotes/10.2.0.html">https://pillow.readthedocs.io/en/stable/releasenotes/10.2.0.html</a></p>
<h2>Changes</h2>
<ul>
<li>Add <code>keep_rgb</code> option when saving JPEG to prevent
conversion of RGB colorspace <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7553">#7553</a>
[<a href="https://github.com/bgilbert"><code>@​bgilbert</code></a>]</li>
<li>Trim negative glyph offsets in ImageFont.getmask() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7672">#7672</a>
[<a href="https://github.com/nulano"><code>@​nulano</code></a>]</li>
<li>Removed unnecessary &quot;pragma: no cover&quot; <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7668">#7668</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Trim glyph size in ImageFont.getmask() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7669">#7669</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fix loading IPTC images and update test <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7667">#7667</a>
[<a href="https://github.com/nulano"><code>@​nulano</code></a>]</li>
<li>Allow uncompressed TIFF images to be saved in chunks <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7650">#7650</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Concatenate multiple JPEG EXIF markers <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7496">#7496</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Changed IPTC tile tuple to match other plugins <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7661">#7661</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Do not assign new fp attribute when exiting context manager <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7566">#7566</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Support arbitrary masks for uncompressed RGB DDS images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7589">#7589</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Support setting ROWSPERSTRIP tag <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7654">#7654</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Apply ImageFont.MAX_STRING_LENGTH to ImageFont.getmask() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7662">#7662</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Optimise <code>ImageColor</code> using
<code>functools.lru_cache</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7657">#7657</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Restricted environment keys for ImageMath.eval() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7655">#7655</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Optimise <code>ImageMode.getmode</code> using
<code>functools.lru_cache</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7641">#7641</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Added trusted PyPI publishing <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7616">#7616</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Compile FriBiDi for Windows ARM64 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7629">#7629</a>
[<a href="https://github.com/nulano"><code>@​nulano</code></a>]</li>
<li>Fix incorrect color blending for overlapping glyphs <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7497">#7497</a>
[<a
href="https://github.com/ZachNagengast"><code>@​ZachNagengast</code></a>]</li>
<li>Add .git-blame-ignore-revs file <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7528">#7528</a>
[<a href="https://github.com/akx"><code>@​akx</code></a>]</li>
<li>Attempt memory mapping when tile args is a string <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7565">#7565</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fill identical pixels with transparency in subsequent frames when
saving GIF <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7568">#7568</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Removed unnecessary string length check <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7560">#7560</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Determine mask mode in Python instead of C <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7548">#7548</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Corrected duration when combining multiple GIF frames into single
frame <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7521">#7521</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Handle disposing GIF background from outside palette <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7515">#7515</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Seek past the data when skipping a PSD layer <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7483">#7483</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>ImageMath: Inline <code>isinstance</code> check <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7623">#7623</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Update actions/upload-artifact action to v4 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7619">#7619</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Import plugins relative to the module <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7576">#7576</a>
[<a
href="https://github.com/deliangyang"><code>@​deliangyang</code></a>]</li>
<li>Translate encoder error codes to strings; deprecate
<code>ImageFile.raise_oserror()</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7609">#7609</a>
[<a href="https://github.com/bgilbert"><code>@​bgilbert</code></a>]</li>
<li>Updated readthedocs to latest version of Python <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7611">#7611</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Support reading BC4U and DX10 BC1 images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/6486">#6486</a>
[<a href="https://github.com/REDxEYE"><code>@​REDxEYE</code></a>]</li>
<li>Optimize ImageStat.Stat.extrema <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7593">#7593</a>
[<a href="https://github.com/florath"><code>@​florath</code></a>]</li>
<li>Handle pathlib.Path in FreeTypeFont <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7578">#7578</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Use list comprehensions to create transformed lists <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7597">#7597</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Added support for reading DX10 BC4 DDS images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7603">#7603</a>
[<a href="https://github.com/sambvfx"><code>@​sambvfx</code></a>]</li>
<li>Optimized ImageStat.Stat.count <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7599">#7599</a>
[<a href="https://github.com/florath"><code>@​florath</code></a>]</li>
<li>Moved error from truetype() to FreeTypeFont <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7587">#7587</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Correct PDF palette size when saving <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7555">#7555</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Fixed closing file pointer with olefile 0.47 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7594">#7594</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>ruff: Minor optimizations of list comprehensions, x in set, etc. <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7524">#7524</a>
[<a href="https://github.com/cclauss"><code>@​cclauss</code></a>]</li>
<li>Build Windows wheels using cibuildwheel <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7580">#7580</a>
[<a href="https://github.com/nulano"><code>@​nulano</code></a>]</li>
<li>Raise ValueError when TrueType font size is zero or less <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7584">#7584</a>
[<a href="https://github.com/akx"><code>@​akx</code></a>]</li>
<li>Install cibuildwheel from requirements file <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7581">#7581</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst">pillow's
changelog</a>.</em></p>
<blockquote>
<h2>10.2.0 (2024-01-02)</h2>
<ul>
<li>
<p>Add <code>keep_rgb</code> option when saving JPEG to prevent
conversion of RGB colorspace <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7553">#7553</a>
[bgilbert, radarhere]</p>
</li>
<li>
<p>Trim glyph size in ImageFont.getmask() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7669">#7669</a>,
<a
href="https://redirect.github.com/python-pillow/Pillow/issues/7672">#7672</a>
[radarhere, nulano]</p>
</li>
<li>
<p>Deprecate IptcImagePlugin helpers <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7664">#7664</a>
[nulano, hugovk, radarhere]</p>
</li>
<li>
<p>Allow uncompressed TIFF images to be saved in chunks <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7650">#7650</a>
[radarhere]</p>
</li>
<li>
<p>Concatenate multiple JPEG EXIF markers <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7496">#7496</a>
[radarhere]</p>
</li>
<li>
<p>Changed IPTC tile tuple to match other plugins <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7661">#7661</a>
[radarhere]</p>
</li>
<li>
<p>Do not assign new fp attribute when exiting context manager <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7566">#7566</a>
[radarhere]</p>
</li>
<li>
<p>Support arbitrary masks for uncompressed RGB DDS images <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7589">#7589</a>
[radarhere, akx]</p>
</li>
<li>
<p>Support setting ROWSPERSTRIP tag <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7654">#7654</a>
[radarhere]</p>
</li>
<li>
<p>Apply ImageFont.MAX_STRING_LENGTH to ImageFont.getmask() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7662">#7662</a>
[radarhere]</p>
</li>
<li>
<p>Optimise <code>ImageColor</code> using
<code>functools.lru_cache</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7657">#7657</a>
[hugovk]</p>
</li>
<li>
<p>Restricted environment keys for ImageMath.eval() <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7655">#7655</a>
[wiredfool, radarhere]</p>
</li>
<li>
<p>Optimise <code>ImageMode.getmode</code> using
<code>functools.lru_cache</code> <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7641">#7641</a>
[hugovk, radarhere]</p>
</li>
<li>
<p>Fix incorrect color blending for overlapping glyphs <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7497">#7497</a>
[ZachNagengast, nulano, radarhere]</p>
</li>
<li>
<p>Attempt memory mapping when tile args is a string <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7565">#7565</a>
[radarhere]</p>
</li>
<li>
<p>Fill identical pixels with transparency in subsequent frames when
saving GIF <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7568">#7568</a>
[radarhere]</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6956d0b285"><code>6956d0b</code></a>
10.2.0 version bump</li>
<li><a
href="31c8dacdc7"><code>31c8dac</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7675">#7675</a>
from python-pillow/pre-commit-ci-update-config</li>
<li><a
href="40a3f91af2"><code>40a3f91</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7674">#7674</a>
from nulano/url-example</li>
<li><a
href="cb41b0cc78"><code>cb41b0c</code></a>
[pre-commit.ci] pre-commit autoupdate</li>
<li><a
href="de62b25ed3"><code>de62b25</code></a>
fix image url in &quot;Reading from URL&quot; example</li>
<li><a
href="7c526a6c6b"><code>7c526a6</code></a>
Update CHANGES.rst [ci skip]</li>
<li><a
href="d93a5ad70b"><code>d93a5ad</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7553">#7553</a>
from bgilbert/jpeg-rgb</li>
<li><a
href="aed764fe84"><code>aed764f</code></a>
Update CHANGES.rst [ci skip]</li>
<li><a
href="f8df5303fa"><code>f8df530</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7672">#7672</a>
from nulano/imagefont-negative-crop</li>
<li><a
href="24e9485e6b"><code>24e9485</code></a>
Merge pull request <a
href="https://redirect.github.com/python-pillow/Pillow/issues/7671">#7671</a>
from radarhere/imagetransform</li>
<li>Additional commits viewable in <a
href="https://github.com/python-pillow/Pillow/compare/10.0.1...10.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pillow&package-manager=pip&previous-version=10.0.1&new-version=10.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/dcs-liberation/dcs_liberation/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-20 22:54:52 +11:00
tmz42
d1daa0521c Tripoint correction for max A-10C size 2024-02-08 20:44:46 -08:00
tmz42
ffa88688dc Added new merged campaign of both Scenic Routes, Scenic Merge. 2024-02-08 20:44:46 -08:00
tmz42
5ecaeca910 Campaign corrections : A-10C II instead of A-10CI, From Incirlik is actually from Incirlik in Tripoint 2024-02-08 20:44:46 -08:00
Chilli935
e1d443b697 Super Hornet mod support (#3331)
F/A-18E and F/A-18F are added to their factions, Growler is currently in
its respective factions but was released in 2009, this will be changed
if needed.
2024-01-27 23:14:57 +00:00
zhexu14
5af4e56f30 Add hit points to unit yamls.
This PR:

- Introduces a new member of UnitType, hit_points, which is an abstract
representation of the durability of a unit, and loads it in from the
YAML files in the various subclasses (Ship, Ground etc).
- Adds scripts for populating/updating the unit YAML files with hit
point data from DCS. This script also gets the data for static objects,
but I'll leave the plugging in of static object data into Liberation for
another PR.
- Updates the unit YAML files by running the above scripts.

I did toy with the idea of adding this data to the unit definitions in
pydcs via an export from DCS, but it would be a more involved change,
since the current pydcs export script runs in the Hooks Lua environment
in DCS and AFAICT the hit points (via Unit.getLife()) is run in the
mission scripting environment.
2024-01-04 00:49:33 -08:00
zhexu14
5b858886c0 Doctrine cleanup (#3318)
This PR:

- Refactors the doctrine class to have a bit more structure, in
anticipation of adding more elements to Doctrine.
- Moves previously hard coded helo-specific altitudes into the Doctrine
class, aligning a bunch of altitudes ~200ft in the process.
- Refactors ingress_altitude to combat_altitude to clarify that the
altitude is applied to multiple waypoint types, not just the ingress
altitude.
2024-01-01 13:31:26 -08:00
Dan Albert
c695e7724a Update bug templates for 10.0.0. 2023-12-31 12:57:12 -08:00
Dan Albert
2fb22e4e17 Bump develop to 11.0.0. 2023-12-30 16:05:45 -08:00
Astro-739
ce073c24bc Update of Campaign Falcon Went over the Mountain.
Added secondary mission types to all air-to-air squadrons for more
flexibility.
2023-12-30 20:33:03 +00:00
Starfire13
8de053cc7d Add Operation Aegean Aegis.
Adds a new Apache and Harrier campaign to the Syria map.
2023-12-28 20:01:34 -08:00
Astro-739
fe6e49b22b Update of Campaign Falcon Went over the Mountain.
Campaign update of Falcon Went over the Mountain (Syria map) to v11.0

1. Added squadron sizes
2. Rebalanced scenario
3. Added (non zero) heading to all SAM and EWR sites
2023-12-28 23:03:46 +00:00
Starfire13
3653dc8cbd Campaign inversion support for Battle for No Man's Land. 2023-12-27 14:06:46 -08:00
Starfire13
d2b5eea0de Update Harrier loadout (#3316)
I had a look and the default Harrier loadouts were very outdated and
quite sub-optimal. So I fixed it up.
2023-12-27 14:05:43 -08:00
zhexu14
211ec86e2e Apache speed fix (#3315)
This PR 1) introduces a cruise_speed parameter to the AircraftType class
and uses it as an override for default TOT/Ground Speed calculations and
2) sets this for the AH64.

The reason for this change is that air starts with the Apache at a speed
>130kt seems to completely break the FCR, even if you subsequently slow
down. In the development branch, Liberation sets the Apache to travel at
168kt, so any player air starting won't be able to use their FCR and it
wouldn't be readily apparent as to why.

In the longer run this parameter may also be useful for other aircraft
e.g. to override the cruise speed to the most efficient etc.
2023-12-27 14:04:16 -08:00
Starfire13
03caddc1b4 Update F-15E Suite 4+ loadouts to add the fixed GBU31v3 (#3314) 2023-12-21 22:15:16 -08:00
Dan Albert
3f7618d75d Update pydcs.
Has the __eq__ implementation for Task which fixes inconsistent save
loading issues.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3288.
2023-12-21 21:48:17 -08:00
Dan Albert
dcf23c655d Describe non-airport "runways" better.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3290.
2023-12-21 16:46:06 -08:00
Dan Albert
ef69275f34 Don't send the selected flight plan to the back.
We want the selected flight plan to show on top of all the other flight
plans, and because we can't properly z-order with the other elements of
the map (see the code comment), this is probably the best we can do.

This means that the selected flight will be drawn on top of the front
line again, and will in some cases intercept mouse clicks meant for the
front line, but it's much less of a problem than when all the paths were
drawn on top.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3305.
2023-12-21 15:43:12 -08:00
Dan Albert
167cea08f6 Update pydcs.
Normandy terrain update.
2023-12-21 15:34:47 -08:00
zhexu14
48ae55bdc2 Default overrides fix (#3307)
This PR makes sure that the Payload tab of the Edit Flight window shows
the correct property values (with `default_overrides` applied in the
aircraft YAML). It looks like the issue only affects an obscure
parameter on F14s (INS reference alignment stored) so may not have been
noticed until now.
2023-12-21 02:51:34 -08:00
zhexu14
ff2bd3f815 Enable AH-64 FCR by default. 2023-12-20 21:42:18 -08:00
Starfire13
ba5d0bed4d Add Battle for No Man's Land campaign. 2023-12-20 18:40:31 -08:00
Dan Albert
4a07b8a2d8 Update pydcs. 2023-12-20 18:01:39 -08:00
Dan Albert
1efce862fb Send flight plan paths to the back of the map.
This fixes the unusual case where the `interactive: false` property had
no effect, which would make it impossible to plan missions against UI
elements that were overflown by many flights (such as the front line).

As an added bonus, it looks a bit nicer.

This impacts the test in an odd way, but the cure for that is probably
rewriting the test to not use a mock now that we've figured out how to
do that.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3295.
2023-12-18 20:16:08 -08:00
Starfire13
80cb440e7d Adds Private Military Company - Russian (Hard) faction.
This is a new faction that expands on the current PMC Russian faction by
adding in a substantial number of new units for additional variety and
challenge. It'll be the default faction for my helicopter campaign (I'll
open a PR for that tomorrow. It's all done apart from the campaign
description).
2023-12-18 17:49:12 -08:00
Starfire13
e970c281e8 Add DEAD loadouts to AH-64D, KA-50, and KA-50 BS3 (#3301) 2023-12-18 17:41:19 -08:00
dependabot[bot]
b863e2fb83 Bump pyinstaller from 5.13.0 to 5.13.1
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 5.13.0 to 5.13.1.
- [Release notes](https://github.com/pyinstaller/pyinstaller/releases)
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v5.13.0...v5.13.1)

---
updated-dependencies:
- dependency-name: pyinstaller
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-17 18:45:43 -08:00
Starfire13
3007a96343 Add DEAD capability to AH-64D Blk II 2023-12-17 18:43:16 -08:00
Starfire13
463981f4bf Add DEAD mission capability to Blackshark 3 2023-12-17 18:43:05 -08:00
Starfire13
816d1cd787 Add DEAD mission capability to KA-50 2023-12-17 18:42:54 -08:00
zhexu14
4631ee0d74 Doctrine load from YAML (#3291)
This PR refactors the Doctrine class to load from YAML files in the
resources folder instead of being hardcoded as a step towards making
doctrines moddable (Issue #829).

I haven't added anything to the changelog as a couple of things should
get cleaned up first:
- As far as I can tell, the flags in the Doctrine class (cap, cas, sead
etc.) aren't used anywhere. Need to test further, and if they're truly
not used, will remove them.
- Probably need to update the Wiki
2023-12-17 18:42:31 -08:00
zhexu14
a213215c3f Fix exception when campaign has only off map CPs.
This PR fixes an exception in custom campaigns that only contain off map
spawns.
2023-12-15 14:25:11 -08:00
Starfire13
b014f2e543 Improve F-15E S4+ loadouts (#3286)
I've come to realise that two external tanks is overkill for pretty much
all A2G mission types. The AI no longer have a problem with fuel, and
player flights will essentially never run out of fuel with the 2 CFTs
and a single external tank. I have done 700+ mile trips at mil power the
whole way with fuel to spare. I have therefore switched all A2G mission
loadouts to a single tank. A2A loadouts still carry 2 tanks, as players
may require the extra fuel if they make very extensive use of
afterburner in air combat.

It turns out the GBU31v3 JDAMs are bugged in more than one way. We've
known that they vanish if carried in pairs on the CFT pylons, but now it
turns out their penetration doesn't actually work. This means they are
no better in any way than the GBU31v1s, which are not bugged on CFT
pylons.

I have therefore removed the penetrator JDAMs from all loadouts,
replacing them with regular JDAMs.
2023-12-06 16:46:16 -08:00
Nosajthedevil
f3d3c5f43a Aim-9 Updates (#3287)
Adds the Aim-9P3 between the Aim-9P5 and the Aim-9P. Also adds fallback
support for sidewinder versions for the VSN 104 mod, the JAS39 mod, and
the AJS-37.
2023-12-06 16:45:38 -08:00
Dan Albert
5ee3afeddb Disconnect log signals on exit.
If we don't do this, the uvicorn server may log its shutdown after the
Qt application has closed, and the signal this attempts to emit may not
be valid. Disconnect the log signals when the application exits to
prevent that.

There's actually another solution that I thought would be better, but I
couldn't get it to work:
https://www.pyinstaller.org/en/stable/feature-notes.html#automatic-hiding-and-minimization-of-console-window-under-windows
describes a way to have pyinstaller hide or minimize the console rather
than disabling it entirely. I was never really fond of getting rid of
the console window in the first place, but it did bother some users. If
we could get the hide or minimize option working, that'd probably avoid
bothering users, but also make the logs much easier to find, get us out
of the trouble of maintaining our own log viewer, and fix the problem
mentioned in the comment I add here (the log window only works if
there's only one in memory log handler).

Another option would be ditching our log window and instead just having
that menu item open the log file or directory in whatever program the OS
defaults to (probably notepad). It would still have the quirk of maybe
needing to open more than one location, since logging is use
configurable.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3278.
2023-12-02 15:59:00 -08:00
Dan Albert
88591fd18c Downgrade Qt.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3276.
2023-12-02 15:01:07 -08:00
Dan Albert
f5573cfc19 Revert "Update to Python 3.12."
Might fix https://github.com/dcs-liberation/dcs_liberation/issues/3276.
If not, we need to revert the Qt upgrade too, and if we downgrade Qt we
can't use Python 3.12 anyway.

This reverts commit 65eb10639b.
2023-12-02 15:01:07 -08:00
Dan Albert
f7141a9882 Fix a few more Pydantic conversions.
One of the newer versions got a lot more strict. It now only expects
dicts that match the model, or objects of the model. Previously it also
accepted objects which had the same properties as the model. Convert a
few more LatLngs to LeafletPoints.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3279.
2023-12-02 12:25:01 -08:00
dependabot[bot]
a599b503f8 Bump @adobe/css-tools from 4.3.1 to 4.3.2 in /client
Bumps [@adobe/css-tools](https://github.com/adobe/css-tools) from 4.3.1 to 4.3.2.
- [Changelog](https://github.com/adobe/css-tools/blob/main/History.md)
- [Commits](https://github.com/adobe/css-tools/commits)

---
updated-dependencies:
- dependency-name: "@adobe/css-tools"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 16:15:04 -08:00
Dan Albert
6c4b8c81ee Update mypy.
Needed so mypy can recognize the new Python 3.12 generic syntax.
2023-12-01 16:14:54 -08:00
Dan Albert
2447cc156d Update black.
Required for the new syntax in Python 3.12.
2023-11-30 21:10:14 -08:00
Dan Albert
28954d05eb Downgrade pyinstaller.
I forgot to test the pyinstaller binary when I upgraded all the other
dependencies, and there's a breaking change in 6.0.0:

https://pyinstaller.org/en/latest/CHANGES.html#incompatible-changes

> All of onedir build's contents except for the executable are now moved
> into a sub-directory (called _internal by default). sys._MEIPASS is
> adjusted to point to this _internal directory. The breaking
> implications for this are:
>
> * Assumptions that os.path.dirname(sys.executable) == sys._MEIPASS
>   will break. Code locating application resources using
>   os.path.dirname(sys.executable) should be adjusted to use __file__
>   or sys._MEIPASS and any code locating the original executable using
>   sys._MEIPASS should use sys.executable directly.
> * Any custom post processing steps (either in the .spec file or
>   externally) which modify the bundle will likely need adjusting to
>   accommodate the new directory.

This is actually great because it declutters the top level directory to
just `dcs_liberation.exe` and a directory named `_internal` that has all
the guts, but the CWD is no longer the directory that has `resources/`
in it, so we can't find any of our resources. There are a few options
for fixing that (cd into that directory probably being the easiest, or
we could stop relying on CWD relative paths), but for now just downgrade
to unbreak the build.
2023-11-30 21:01:13 -08:00
Dan Albert
65eb10639b Update to Python 3.12. 2023-11-30 20:45:19 -08:00
Dan Albert
7bc35ef7f4 Update most Python dependencies.
A lot of the dependency versions we have pinned don't have wheels for
Python 3.12. Update almost all of them so we can upgrade Python.

The few that weren't upgraded here are black and mypy, since those will
be a bit invasive, and Pillow, which has an API change I don't want to
deal with right now (I've got a commit on another machine that has
already done the migration, so I'll do it later).
2023-11-30 20:24:28 -08:00
Starfire13
46766ecbd4 Remove AI F-15E from Starfire's campaigns.
Now that the F-15E Suite 4+ has JDAMs and the bug preventing AI from
using LGBs has been fixed, I have removed the AI-only F-15Es from my
campaigns. Also minor tweaks to a couple of squadron types/sizes based
on play-testing results.
2023-11-30 19:12:45 -08:00
Dan Albert
3469d08461 Remove recommendation to dedicated server.
DCS multithreading made this unnecessary.
2023-11-30 19:10:26 -08:00
Dan Albert
28d959bba0 Fix disappearing aircraft when deleting packages.
There are a few different code paths for deleting packages depending on
the state of the package, and two of them were deleting items from a
list they were iterating over without first making a copy, causing each
iteration of the loop to skip over a flight, making it still used since
the flight was never deleted, but unreachable since the package that
owned it was deleted.

This only happened when the package was canceled in its draft state
(the user clicked the X without ever saving the package), or if the user
canceled a package mid fast forward (the controls for which aren't even
visible to users) while only a portion of the package was active. In
both cases, only even numbered flights were lost.

There's a better fix lurking in here somewhere but the interaction with
the Qt model complicates it. Fortunately that mess would be cleaned up
automatically by moving this dialog into React, which we'll do some day.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3257.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3258.
2023-11-30 19:00:58 -08:00
Dan Albert
b99eb49dcf Renumber flight members for meatbags.
Puny humans count wrong, but we ought to match DCS.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/3244.
2023-11-30 18:47:43 -08:00
Starfire13
c6f812238c Update Exercise Vegas Nerve.
Updated Exercise Vegas Nerve with off map spawns for B-52 and B-1.
2023-12-01 02:02:21 +00:00
Starfire13
cc5b5fa3bb Add new Mariana Islands campaign - Operation Velvet Thunder.
Vietnam War era campaign for the Mariana Islands map, utilising the two
new Vietnam War factions.
2023-12-01 01:57:50 +00:00
Starfire13
5271b3d32c Switch F-15E S4+ loadouts from LGBs to JDAMs (AI still won't use LGBs) (#3259)
It appears the AI is still incapable of using LGBs (and laser JDAMs),
even though Razbam had said the issues was fixed. I have switched
loadouts to JDAMs because the AI will use those.
2023-11-30 17:56:34 -08:00
Starfire13
8f4192edc3 Fix Operation Grabthar's Hammer map object strike target.
This fixes a map object strike target (yes, just one. Fortunately!) that
was broken by the latest DCS open beta update that removed the buildings
the strike target was using.
2023-11-30 17:51:55 -08:00
Starfire13
183d6df8bf Add guided bombs to F-15E Suite 4+ loadouts.
GBUs have been added to the F-15E Suite 4+ loadouts

Also switched CAP loadouts to 2 external tanks instead of 3 to improve
aircraft performance, as 2 tanks is plenty for players and the AI has
infinite fuel now.
2023-11-18 18:51:42 -08:00
Dan Albert
a825651330 Update pydcs.
Terrain updates for Normandy and South Atlantic.
2023-11-18 15:00:21 -08:00
Dan Albert
f3c02816fc Update pydcs.
Includes F-15E JDAM support.
2023-11-18 14:54:14 -08:00
Starfire13
c4e2e45650 Add Vietnam War factions for USA and NVA.
This adds factions for Vietnam War for both the US and North Vietnamese
Army.
2023-11-18 14:20:14 -08:00
Starfire13
6613642517 Add LARC-V and Speedboat.
This adds LARC-V to Liberation (required by USA 1970)
Also adds Speedboat to Liberation (required by NVA 1970)

Both units are available via pydcs but have not been added to Liberation
thus far as no factions used them (until now).
2023-11-18 22:12:40 +00:00
Dan Albert
b73ca2c62e Update bug templates. 2023-11-11 13:32:10 -08:00
Dan Albert
8abd3c7cf9 Fix typo in changelog. 2023-11-11 13:28:57 -08:00
Dan Albert
f8a72d8f22 Bump version to 10.0.0. 2023-11-10 19:15:41 -08:00
645 changed files with 9912 additions and 1438 deletions

View File

@@ -31,7 +31,7 @@ body:
If the bug was found in a development build, select "Development build"
and provide a link to the build in the field below.
options:
- 8.1.0
- 11.0.0
- Development build
- type: textarea
attributes:

View File

@@ -39,7 +39,7 @@ body:
If the bug was found in a development build, select "Development build"
and provide a link to the build in the field below.
options:
- 8.1.0
- 11.0.0
- Development build
- type: textarea
attributes:

View File

@@ -6,7 +6,7 @@ runs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.11"
python-version: "3.11.4"
cache: pip
- name: Install environment

View File

@@ -11,7 +11,7 @@ jobs:
- uses: actions/setup-python@v2
- uses: psf/black@stable
with:
version: ~=22.12
version: ~=23.11
src: "."
options: "--check"

View File

@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
rev: 22.12.0
rev: 23.11.0
hooks:
- id: black
language_version: python3

View File

@@ -2,7 +2,7 @@
(Github Readme Banner and Splash screen Artwork by Andriy Dankovych, CC BY-SA 4.0)
[![Patreon](https://img.shields.io/badge/patreon-become%20a%20patron-orange?logo=patreon)](https://patreon.com/khopa)
[![Patreon](https://img.shields.io/badge/patreon-become%20a%20patron-orange?logo=patreon)](https://patreon.com/dcsliberation)
[![Download](https://img.shields.io/github/downloads/dcs-liberation/dcs_liberation/total?label=Download)](https://github.com/dcs-liberation/dcs_liberation/releases)
@@ -17,11 +17,6 @@
DCS Liberation is a [DCS World](https://www.digitalcombatsimulator.com/en/products/world/) turn based single-player or co-op dynamic campaign.
It is an external program that generates full and complex DCS missions and manage a persistent combat environment.
**Note that DCS Liberation does not support the stable release of DCS. We can
only guarantee compatibility with either the open beta or the stable release,
and more people play the open beta. DCS stable _might_ work sometimes, but it's
untested, and we will be unable to fix any bugs unique to stable DCS.**
![Screenshot](https://user-images.githubusercontent.com/315852/120939254-0b4a9f80-c6cc-11eb-82f5-ce3f8d714bfe.png)
## Downloads

View File

@@ -1,3 +1,58 @@
# 11.1.0
Saves from 11.0.0 are compatible with 11.1.0. See Known Issues section for exceptions.
## Features/Improvements
* **[Engine]** Support for DCS 2.9.5.55918 including Heatblur F-4E and Polychop OH-58D Kiowa Warrior support.
## Fixes
* **[Campaign]** Fixed double counting of parked aircraft kills when DCS reports multiple kill events.
* **[Campaign]** Fixed error where frontline units are not re-deployed when multiple control points were captured in one turn or when control points are captured "out of order" using air-assault missions.
* **[Cheat Menu]** Re-deploy frontline units when using cheats to capture control points, so that cheats behave the same way as capturing a control point in-mission.
* **[Data]** Added FuSe-65 Early Warning Radar.
* **[Data]** Updated Peru 1995 and Germany 1944 factions.
* **[Flight Planning]** Theater refuelling flight plans (those not tied to a particular package) will remain on station for a longer period, specifically the desired mission duration + 30 minutes. By default, this increases the on-station time from 1 hour to 1.5 hours.
* **[Mission Generation]** Patched bug where Liberation crashed when aborting a turn when Fighter Sweep missions were planned.
* **[Radios]** Added radio setup for F-5E, F-86, Mi-8 and Mi-24.
* **[UI]** Naval control points (carriers, LHAs) can no longer be moved onto land.
## Known Issues
* When loading saves from 11.0, loadouts with AGM-45B (Imp), typically on A-4E-C mod, will have the AGM-45B replaced with an empty pylon due to changes in DCS for this weapon. The AGM-45A is not affected by this issue.
# 11.0.0
Saves from 10.x are not compatible with 11.0.0.
## Features/Improvements
* **[Engine]** Support for DCS 2.9.3.51704.
* **[Campaign]** Improved tracking of parked aircraft deaths. Parked aircraft are now considered dead once sufficient damage is done, meaning guns, rockets and AGMs are viable weapons for OCA/Aircraft missions. Previously Liberation relied on DCS death tracking which required parked aircraft to be hit with more powerful weapons e.g. 2000lb bombs as they were uncontrolled.
* **[Campaign]** Track damage to theater ground objects across turns. Damage can accumulate across turns leading to death of the unit. This behavior only applies to SAMs, ships and other units that appear on the Liberation map. Frontline units and buildings are not tracked (yet).
* **[Mods]** F/A-18 E/F/G Super Hornet mod (v2.2.5) support added.
## Fixes
* **[Mission Generation]** When planning anti-ship missions against carriers or LHAs, target escorts (if present) if the carrier/LHA is sunk.
* **[UI]** Identify that a carrier or LHA is sunk instead of "damaged".
# 10.0.0
Saves from 9.x are not compatible with 10.0.0.
## Features/Improvements
* **[Engine]** Support for DCS 2.9.2.49629 Open Beta. (F-15E JDAM and JSOW, F-16 AIM-9P, updated Falklands and Normandy airfields).
* **[UI]** Improved the description of "runway" state for FARPs, FOBs, carriers, and off-map spawns.
## Fixes
* **[Flight Planning]** Aircraft from even numbered flights will no longer become inaccessible when canceling a draft package.
* **[UI]** Flight members in the loadout menu are now numbered starting from 1 instead of 0.
* **[UI]** Flight plan paths are now drawn behind all other map elements, fixing rare cases where they could prevent other UI elements from being clickable.
# 9.0.0
Saves from 8.x are not compatible with 9.0.0.
@@ -46,7 +101,7 @@ Saves from 8.x are not compatible with 9.0.0.
* **[UI]** Fixed deleting waypoints in custom flight plans deleting the wrong waypoint.
* **[UI]** Fixed flight properties UI to support F-15E S4+ laser codes.
* **[UI]** In unit transfer dialog, only list control points that are reachable from the control point units are being transferred from.
* **[UI]** Fixed UI bug where altering an "ahead of package" TOT offset would change the offset back to a "behind pacakge" offset.
* **[UI]** Fixed UI bug where altering an "ahead of package" TOT offset would change the offset back to a "behind package" offset.
* **[UI]** Fixed bug where changing TOT offsets could result in flight startup times that are in the past.
* **[UI]** Fixed odd spacing of the finance window when there were not enough items to fill the page.
* **[UI]** Fixed regression where waypoint altitude changes in the waypoint list screen are applied to the wrong waypoint.

546
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
import { Flight } from "../../api/liberationApi";
import { useGetCommitBoundaryForFlightQuery } from "../../api/liberationApi";
import WaypointMarker from "../waypointmarker";
import { ReactElement } from "react";
import { Polyline as LPolyline } from "leaflet";
import { ReactElement, useEffect, useRef } from "react";
import { Polyline } from "react-leaflet";
const BLUE_PATH = "#0084ff";
@@ -27,16 +28,41 @@ const pathColor = (props: FlightPlanProps) => {
function FlightPlanPath(props: FlightPlanProps) {
const color = pathColor(props);
const waypoints = props.flight.waypoints;
const polylineRef = useRef<LPolyline | null>(null);
// Flight paths should be drawn under everything else. There seems to be an
// issue where `interactive: false` doesn't do as its told (there's nuance,
// see the bug for details). It looks better if we draw the other elements on
// top of the flight plans anyway, so just push the flight plan to the back.
//
// https://github.com/dcs-liberation/dcs_liberation/issues/3295
//
// It's not possible to z-index a polyline (and leaflet says it never will be,
// because this is a limitation of SVG, not leaflet:
// https://github.com/Leaflet/Leaflet/issues/185), so we need to use
// bringToBack() to push the flight paths to the back of the drawing once
// they've been added to the map. They'll still draw on top of the map, but
// behind everything than was added before them. Anything added after always
// goes on top.
useEffect(() => {
if (!props.selected) {
polylineRef.current?.bringToBack();
}
});
if (waypoints == null) {
return <></>;
}
const points = waypoints
.filter((waypoint) => waypoint.include_in_path)
.map((waypoint) => waypoint.position);
return (
<Polyline
positions={points}
pathOptions={{ color: color, interactive: false }}
ref={polylineRef}
/>
);
}

View File

@@ -95,8 +95,12 @@ describe("FlightPlansLayer", () => {
},
},
});
expect(mockPolyline).toHaveBeenCalledTimes(2);
expect(mockLayerGroup).toBeCalledTimes(1);
// For some reason passing ref to PolyLine causes it and its group to be
// redrawn, so these numbers don't match what you'd expect from the test.
// It probably needs to be rewritten without mocks.
expect(mockPolyline).toHaveBeenCalledTimes(3);
expect(mockLayerGroup).toBeCalledTimes(2);
});
it("are not drawn if wrong coalition", () => {
renderWithProviders(<FlightPlansLayer blue={true} />, {

View File

@@ -7,9 +7,9 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = "DCS Liberation"
copyright = "2023, DCS Liberation Team"
copyright = "2024, DCS Liberation Team"
author = "DCS Liberation Team"
release = "9.0.0"
release = "11.1.0"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

View File

@@ -88,7 +88,7 @@ class Builder(IBuilder[AirAssaultFlightPlan, AirAssaultLayout]):
raise PlanningError("Air assault is only usable by helicopters")
assert self.package.waypoints is not None
altitude = feet(1500) if self.flight.is_helo else self.doctrine.ingress_altitude
altitude = self.doctrine.helicopter.air_assault_nav_altitude
altitude_is_agl = self.flight.is_helo
builder = WaypointBuilder(self.flight, self.coalition)

View File

@@ -19,7 +19,7 @@ class BarCapFlightPlan(PatrollingFlightPlan[PatrollingLayout]):
@property
def patrol_duration(self) -> timedelta:
return self.flight.coalition.doctrine.cap_duration
return self.flight.coalition.doctrine.cap.duration
@property
def patrol_speed(self) -> Speed:
@@ -29,7 +29,7 @@ class BarCapFlightPlan(PatrollingFlightPlan[PatrollingLayout]):
@property
def engagement_distance(self) -> Distance:
return self.flight.coalition.doctrine.cap_engagement_range
return self.flight.coalition.doctrine.cap.engagement_range
class Builder(CapBuilder[BarCapFlightPlan, PatrollingLayout]):
@@ -44,8 +44,8 @@ class Builder(CapBuilder[BarCapFlightPlan, PatrollingLayout]):
preferred_alt = self.flight.unit_type.preferred_patrol_altitude
randomized_alt = preferred_alt + feet(random.randint(-2, 1) * 1000)
patrol_alt = max(
self.doctrine.min_patrol_altitude,
min(self.doctrine.max_patrol_altitude, randomized_alt),
self.doctrine.cap.min_patrol_altitude,
min(self.doctrine.cap.max_patrol_altitude, randomized_alt),
)
builder = WaypointBuilder(self.flight, self.coalition)

View File

@@ -90,10 +90,10 @@ class CapBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
# buffer.
distance_to_no_fly = (
meters(position.distance(self.threat_zones.all))
- self.doctrine.cap_engagement_range
- self.doctrine.cap.engagement_range
- nautical_miles(5)
)
max_track_length = self.doctrine.cap_max_track_length
max_track_length = self.doctrine.cap.max_track_length
else:
# Other race tracks (TARCAPs, currently) just try to keep some
# distance from the nearest enemy airbase, but since they are by
@@ -108,15 +108,15 @@ class CapBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
distance_to_no_fly = distance_to_airfield - min_distance_from_enemy
# TARCAPs fly short racetracks because they need to react faster.
max_track_length = self.doctrine.cap_min_track_length + 0.3 * (
self.doctrine.cap_max_track_length - self.doctrine.cap_min_track_length
max_track_length = self.doctrine.cap.min_track_length + 0.3 * (
self.doctrine.cap.max_track_length - self.doctrine.cap.min_track_length
)
min_cap_distance = min(
self.doctrine.cap_min_distance_from_cp, distance_to_no_fly
self.doctrine.cap.min_distance_from_cp, distance_to_no_fly
)
max_cap_distance = min(
self.doctrine.cap_max_distance_from_cp, distance_to_no_fly
self.doctrine.cap.max_distance_from_cp, distance_to_no_fly
)
end = location.position.point_from_heading(
@@ -125,7 +125,7 @@ class CapBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
)
track_length = random.randint(
int(self.doctrine.cap_min_track_length.meters),
int(self.doctrine.cap.min_track_length.meters),
int(max_track_length.meters),
)
start = end.point_from_heading(heading.opposite.degrees, track_length)

View File

@@ -44,7 +44,7 @@ class CasFlightPlan(PatrollingFlightPlan[CasLayout], UiZoneDisplay):
@property
def patrol_duration(self) -> timedelta:
return self.flight.coalition.doctrine.cas_duration
return self.flight.coalition.doctrine.cas.duration
@property
def patrol_speed(self) -> Speed:
@@ -96,7 +96,7 @@ class Builder(IBuilder[CasFlightPlan, CasLayout]):
builder = WaypointBuilder(self.flight, self.coalition)
is_helo = self.flight.unit_type.dcs_unit_type.helicopter
patrol_altitude = self.doctrine.ingress_altitude if not is_helo else meters(50)
patrol_altitude = self.doctrine.resolve_combat_altitude(is_helo)
use_agl_patrol_altitude = is_helo
ip_solver = IpSolver(

View File

@@ -33,7 +33,7 @@ class Builder(FormationAttackBuilder[EscortFlightPlan, FormationAttackLayout]):
departure=builder.takeoff(self.flight.departure),
hold=hold,
nav_to=builder.nav_path(
hold.position, join.position, self.doctrine.ingress_altitude
hold.position, join.position, self.doctrine.combat_altitude
),
join=join,
ingress=ingress,
@@ -43,7 +43,7 @@ class Builder(FormationAttackBuilder[EscortFlightPlan, FormationAttackLayout]):
nav_from=builder.nav_path(
refuel.position,
self.flight.arrival.position,
self.doctrine.ingress_altitude,
self.doctrine.combat_altitude,
),
arrival=builder.land(self.flight.arrival),
divert=builder.divert(self.flight.divert),

View File

@@ -163,7 +163,7 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
departure=builder.takeoff(self.flight.departure),
hold=hold,
nav_to=builder.nav_path(
hold.position, join.position, self.doctrine.ingress_altitude
hold.position, join.position, self.doctrine.combat_altitude
),
join=join,
ingress=ingress,
@@ -173,7 +173,7 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
nav_from=builder.nav_path(
refuel.position,
self.flight.arrival.position,
self.doctrine.ingress_altitude,
self.doctrine.combat_altitude,
),
arrival=builder.land(self.flight.arrival),
divert=builder.divert(self.flight.divert),

View File

@@ -65,7 +65,6 @@ class RecoveryTankerFlightPlan(StandardFlightPlan[RecoveryTankerLayout]):
class Builder(IBuilder[RecoveryTankerFlightPlan, RecoveryTankerLayout]):
def layout(self) -> RecoveryTankerLayout:
builder = WaypointBuilder(self.flight, self.coalition)
# TODO: Propagate the ship position to the Tanker's TOT,

View File

@@ -114,11 +114,11 @@ class Builder(IBuilder[SweepFlightPlan, SweepLayout]):
self.package.waypoints.join.heading_between_point(target)
)
start_pos = target.point_from_heading(
heading.degrees, -self.doctrine.sweep_distance.meters
heading.degrees, -self.doctrine.sweep.distance.meters
)
builder = WaypointBuilder(self.flight, self.coalition)
start, end = builder.sweep(start_pos, target, self.doctrine.ingress_altitude)
start, end = builder.sweep(start_pos, target, self.doctrine.combat_altitude)
hold = builder.hold(self._hold_point())
@@ -126,12 +126,12 @@ class Builder(IBuilder[SweepFlightPlan, SweepLayout]):
departure=builder.takeoff(self.flight.departure),
hold=hold,
nav_to=builder.nav_path(
hold.position, start.position, self.doctrine.ingress_altitude
hold.position, start.position, self.doctrine.combat_altitude
),
nav_from=builder.nav_path(
end.position,
self.flight.arrival.position,
self.doctrine.ingress_altitude,
self.doctrine.combat_altitude,
),
sweep_start=start,
sweep_end=end,

View File

@@ -40,7 +40,7 @@ class TarCapFlightPlan(PatrollingFlightPlan[TarCapLayout]):
# flights in the package that have requested escort. If the package
# requests an escort the CAP self.flight will remain on station for the
# duration of the escorted mission, or until it is winchester/bingo.
return self.flight.coalition.doctrine.cap_duration
return self.flight.coalition.doctrine.cap.duration
@property
def patrol_speed(self) -> Speed:
@@ -50,7 +50,7 @@ class TarCapFlightPlan(PatrollingFlightPlan[TarCapLayout]):
@property
def engagement_distance(self) -> Distance:
return self.flight.coalition.doctrine.cap_engagement_range
return self.flight.coalition.doctrine.cap.engagement_range
@staticmethod
def builder_type() -> Type[Builder]:
@@ -90,8 +90,8 @@ class Builder(CapBuilder[TarCapFlightPlan, TarCapLayout]):
preferred_alt = self.flight.unit_type.preferred_patrol_altitude
randomized_alt = preferred_alt + feet(random.randint(-2, 1) * 1000)
patrol_alt = max(
self.doctrine.min_patrol_altitude,
min(self.doctrine.max_patrol_altitude, randomized_alt),
self.doctrine.cap.min_patrol_altitude,
min(self.doctrine.cap.max_patrol_altitude, randomized_alt),
)
builder = WaypointBuilder(self.flight, self.coalition)

View File

@@ -17,7 +17,13 @@ class TheaterRefuelingFlightPlan(RefuelingFlightPlan):
@property
def patrol_duration(self) -> timedelta:
return timedelta(hours=1)
# Add 30 minutes to desired_player_mission_duration as TOTs for flights
# can sit up to this time. This extension means the tanker remains on
# station for the flights' return.
return (
self.flight.coalition.game.settings.desired_player_mission_duration
+ timedelta(minutes=30)
)
class Builder(IBuilder[TheaterRefuelingFlightPlan, PatrollingLayout]):

View File

@@ -72,7 +72,7 @@ class WaypointBuilder:
"NAV",
FlightWaypointType.NAV,
position,
meters(500) if self.is_helo else self.doctrine.rendezvous_altitude,
self.doctrine.resolve_rendezvous_altitude(self.is_helo),
description="Enter theater",
pretty_name="Enter theater",
)
@@ -99,7 +99,7 @@ class WaypointBuilder:
"NAV",
FlightWaypointType.NAV,
position,
meters(500) if self.is_helo else self.doctrine.rendezvous_altitude,
self.doctrine.resolve_rendezvous_altitude(self.is_helo),
description="Exit theater",
pretty_name="Exit theater",
)
@@ -127,10 +127,7 @@ class WaypointBuilder:
position = divert.position
altitude_type: AltitudeReference
if isinstance(divert, OffMapSpawn):
if self.is_helo:
altitude = meters(500)
else:
altitude = self.doctrine.rendezvous_altitude
altitude = self.doctrine.resolve_rendezvous_altitude(self.is_helo)
altitude_type = "BARO"
else:
altitude = meters(0)
@@ -168,10 +165,7 @@ class WaypointBuilder:
"HOLD",
FlightWaypointType.LOITER,
position,
# Bug: DCS only accepts MSL altitudes for the orbit task and 500 meters is
# below the ground for most if not all of NTTR (and lots of places in other
# maps).
meters(500) if self.is_helo else self.doctrine.rendezvous_altitude,
self.doctrine.resolve_rendezvous_altitude(self.is_helo),
alt_type,
description="Wait until push time",
pretty_name="Hold",
@@ -186,7 +180,7 @@ class WaypointBuilder:
"JOIN",
FlightWaypointType.JOIN,
position,
meters(80) if self.is_helo else self.doctrine.ingress_altitude,
self.doctrine.resolve_combat_altitude(self.is_helo),
alt_type,
description="Rendezvous with package",
pretty_name="Join",
@@ -201,7 +195,7 @@ class WaypointBuilder:
"REFUEL",
FlightWaypointType.REFUEL,
position,
meters(80) if self.is_helo else self.doctrine.ingress_altitude,
self.doctrine.resolve_combat_altitude(self.is_helo),
alt_type,
description="Refuel from tanker",
pretty_name="Refuel",
@@ -229,7 +223,7 @@ class WaypointBuilder:
"SPLIT",
FlightWaypointType.SPLIT,
position,
meters(80) if self.is_helo else self.doctrine.ingress_altitude,
self.doctrine.resolve_combat_altitude(self.is_helo),
alt_type,
description="Depart from package",
pretty_name="Split",
@@ -249,7 +243,7 @@ class WaypointBuilder:
"INGRESS",
ingress_type,
position,
meters(60) if self.is_helo else self.doctrine.ingress_altitude,
self.doctrine.resolve_combat_altitude(self.is_helo),
alt_type,
description=f"INGRESS on {objective.name}",
pretty_name=f"INGRESS on {objective.name}",
@@ -294,7 +288,7 @@ class WaypointBuilder:
f"SEAD on {target.name}",
target,
flyover=True,
altitude=self.doctrine.ingress_altitude,
altitude=self.doctrine.combat_altitude,
alt_type="BARO",
)
@@ -484,7 +478,7 @@ class WaypointBuilder:
"TARGET",
FlightWaypointType.TARGET_GROUP_LOC,
target.position,
meters(60) if self.is_helo else self.doctrine.ingress_altitude,
self.doctrine.resolve_combat_altitude(self.is_helo),
alt_type,
description="Escort the package",
pretty_name="Target area",

View File

@@ -18,6 +18,9 @@ class GroundSpeed:
# on fuel, but mission speed will be fast enough to keep the flight
# safer.
if flight.squadron.aircraft.cruise_speed is not None:
return mach(flight.squadron.aircraft.cruise_speed.mach(), altitude)
# DCS's max speed is in kph at 0 MSL.
max_speed = flight.unit_type.max_speed
if max_speed > SPEED_OF_SOUND_AT_SEA_LEVEL:

View File

@@ -29,7 +29,6 @@ class DefaultSquadronAssigner:
self.coalition.player
):
for squadron_config in self.config.by_location[control_point]:
squadron_def = self.override_squadron_defaults(
self.find_squadron_for(squadron_config, control_point),
squadron_config,
@@ -162,7 +161,6 @@ class DefaultSquadronAssigner:
def override_squadron_defaults(
squadron_def: Optional[SquadronDef], config: SquadronConfig
) -> Optional[SquadronDef]:
if squadron_def is None:
return None

View File

@@ -61,6 +61,8 @@ class MizCampaignLoader:
AirDefence.Hawk_ln.id,
AirDefence.S_75M_Volhov.id,
AirDefence.X_5p73_s_125_ln.id,
AirDefence.NASAMS_LN_B.id,
AirDefence.NASAMS_LN_C.id,
}
SHORT_RANGE_SAM_UNIT_TYPES = {

View File

@@ -25,6 +25,7 @@ from game.utils import meters, nautical_miles
if TYPE_CHECKING:
from game import Game
from game.transfers import CargoShip, Convoy
from game.threatzones import ThreatZones
MissionTargetType = TypeVar("MissionTargetType", bound=MissionTarget)
@@ -193,17 +194,36 @@ class ObjectiveFinder:
def farthest_friendly_control_point(self) -> ControlPoint:
"""Finds the friendly control point that is farthest from any threats."""
def find_farthest(
control_points: Iterator[ControlPoint],
threat_zones: ThreatZones,
consider_off_map_spawn: bool,
) -> ControlPoint | None:
farthest = None
max_distance = meters(0)
for cp in control_points:
if isinstance(cp, OffMapSpawn) and not consider_off_map_spawn:
continue
distance = threat_zones.distance_to_threat(cp.position)
if distance > max_distance:
farthest = cp
max_distance = distance
return farthest
threat_zones = self.game.threat_zone_for(not self.is_player)
farthest = None
max_distance = meters(0)
for cp in self.friendly_control_points():
if isinstance(cp, OffMapSpawn):
continue
distance = threat_zones.distance_to_threat(cp.position)
if distance > max_distance:
farthest = cp
max_distance = distance
farthest = find_farthest(
self.friendly_control_points(), threat_zones, consider_off_map_spawn=False
)
# If there are only off-map spawn control points, fall back to the farthest amongst off map spawn points
if farthest is None:
farthest = find_farthest(
self.friendly_control_points(),
threat_zones,
consider_off_map_spawn=True,
)
if farthest is None:
raise RuntimeError("Found no friendly control points. You probably lost.")

View File

@@ -158,7 +158,7 @@ class TheaterState(WorldState["TheaterState"]):
# Plan enough rounds of CAP that the target has coverage over the expected
# mission duration.
mission_duration = game.settings.desired_player_mission_duration.total_seconds()
barcap_duration = coalition.doctrine.cap_duration.total_seconds()
barcap_duration = coalition.doctrine.cap.duration.total_seconds()
barcap_rounds = math.ceil(mission_duration / barcap_duration)
refueling_targets: list[MissionTarget] = []

View File

@@ -1,3 +1,9 @@
from __future__ import annotations
from pathlib import Path
import yaml
from typing import Any, ClassVar
from dataclasses import dataclass
from datetime import timedelta
@@ -15,19 +21,105 @@ class GroundUnitProcurementRatios:
except KeyError:
return 0.0
@staticmethod
def from_dict(data: dict[str, float]) -> GroundUnitProcurementRatios:
unit_class_enum_from_name = {unit.value: unit for unit in UnitClass}
r = {}
for unit_class in data:
if unit_class not in unit_class_enum_from_name:
raise ValueError(f"Could not find unit type {unit_class}")
r[unit_class_enum_from_name[unit_class]] = float(data[unit_class])
return GroundUnitProcurementRatios(r)
@dataclass
class Helicopter:
#: The altitude used for combat section of a flight, overrides the base combat_altitude parameter for helos
combat_altitude: Distance
#: The altitude used for forming up a pacakge. Overrides the base rendezvous_altitude parameter for helos
rendezvous_altitude: Distance
#: Altitude of the nav points (cruise section) of air assault missions.
air_assault_nav_altitude: Distance
@staticmethod
def from_dict(data: dict[str, Any]) -> Helicopter:
return Helicopter(
combat_altitude=feet(data["combat_altitude_ft_agl"]),
rendezvous_altitude=feet(data["rendezvous_altitude_ft_agl"]),
air_assault_nav_altitude=feet(data["air_assault_nav_altitude_ft_agl"]),
)
@dataclass
class Cas:
#: The duration that CAP flights will remain on-station.
duration: timedelta
@staticmethod
def from_dict(data: dict[str, Any]) -> Cas:
return Cas(duration=timedelta(minutes=data["duration_minutes"]))
@dataclass
class Sweep:
#: Length of the sweep / patrol leg
distance: Distance
@staticmethod
def from_dict(data: dict[str, Any]) -> Sweep:
return Sweep(
distance=nautical_miles(data["distance_nm"]),
)
@dataclass
class Cap:
#: The duration that CAP flights will remain on-station.
duration: timedelta
#: The minimum length of the CAP race track.
min_track_length: Distance
#: The maximum length of the CAP race track.
max_track_length: Distance
#: The minimum distance between the defended position and the *end* of the
#: CAP race track.
min_distance_from_cp: Distance
#: The maximum distance between the defended position and the *end* of the
#: CAP race track.
max_distance_from_cp: Distance
#: The engagement range of CAP flights. Any enemy aircraft within this range
#: of the CAP's current position will be engaged by the CAP.
engagement_range: Distance
#: Defines the range of altitudes CAP racetracks are planned at.
min_patrol_altitude: Distance
max_patrol_altitude: Distance
@staticmethod
def from_dict(data: dict[str, Any]) -> Cap:
return Cap(
duration=timedelta(minutes=data["duration_minutes"]),
min_track_length=nautical_miles(data["min_track_length_nm"]),
max_track_length=nautical_miles(data["max_track_length_nm"]),
min_distance_from_cp=nautical_miles(data["min_distance_from_cp_nm"]),
max_distance_from_cp=nautical_miles(data["max_distance_from_cp_nm"]),
engagement_range=nautical_miles(data["engagement_range_nm"]),
min_patrol_altitude=feet(data["min_patrol_altitude_ft_msl"]),
max_patrol_altitude=feet(data["max_patrol_altitude_ft_msl"]),
)
@dataclass(frozen=True)
class Doctrine:
#: Name of the doctrine, used to assign a doctrine in a faction.
name: str
cas: bool
cap: bool
sead: bool
strike: bool
antiship: bool
rendezvous_altitude: Distance
#: The minimum distance between the departure airfield and the hold point.
hold_distance: Distance
@@ -46,155 +138,87 @@ class Doctrine:
#: target.
min_ingress_distance: Distance
ingress_altitude: Distance
#: The altitude used for combat section of a flight.
combat_altitude: Distance
min_patrol_altitude: Distance
max_patrol_altitude: Distance
pattern_altitude: Distance
#: The duration that CAP flights will remain on-station.
cap_duration: timedelta
#: The minimum length of the CAP race track.
cap_min_track_length: Distance
#: The maximum length of the CAP race track.
cap_max_track_length: Distance
#: The minimum distance between the defended position and the *end* of the
#: CAP race track.
cap_min_distance_from_cp: Distance
#: The maximum distance between the defended position and the *end* of the
#: CAP race track.
cap_max_distance_from_cp: Distance
#: The engagement range of CAP flights. Any enemy aircraft within this range
#: of the CAP's current position will be engaged by the CAP.
cap_engagement_range: Distance
cas_duration: timedelta
sweep_distance: Distance
#: The altitude used for forming up a pacakge.
rendezvous_altitude: Distance
#: Defines prioritization of ground unit purchases.
ground_unit_procurement_ratios: GroundUnitProcurementRatios
#: Helicopter specific doctrines.
helicopter: Helicopter
MODERN_DOCTRINE = Doctrine(
"modern",
cap=True,
cas=True,
sead=True,
strike=True,
antiship=True,
rendezvous_altitude=feet(25000),
hold_distance=nautical_miles(25),
push_distance=nautical_miles(20),
join_distance=nautical_miles(20),
max_ingress_distance=nautical_miles(45),
min_ingress_distance=nautical_miles(10),
ingress_altitude=feet(20000),
min_patrol_altitude=feet(15000),
max_patrol_altitude=feet(33000),
pattern_altitude=feet(5000),
cap_duration=timedelta(minutes=30),
cap_min_track_length=nautical_miles(15),
cap_max_track_length=nautical_miles(40),
cap_min_distance_from_cp=nautical_miles(10),
cap_max_distance_from_cp=nautical_miles(40),
cap_engagement_range=nautical_miles(50),
cas_duration=timedelta(minutes=30),
sweep_distance=nautical_miles(60),
ground_unit_procurement_ratios=GroundUnitProcurementRatios(
{
UnitClass.TANK: 3,
UnitClass.ATGM: 2,
UnitClass.APC: 2,
UnitClass.IFV: 3,
UnitClass.ARTILLERY: 1,
UnitClass.SHORAD: 2,
UnitClass.RECON: 1,
}
),
)
#: Doctrine for CAS missions.
cas: Cas
COLDWAR_DOCTRINE = Doctrine(
name="coldwar",
cap=True,
cas=True,
sead=True,
strike=True,
antiship=True,
rendezvous_altitude=feet(22000),
hold_distance=nautical_miles(15),
push_distance=nautical_miles(10),
join_distance=nautical_miles(10),
max_ingress_distance=nautical_miles(30),
min_ingress_distance=nautical_miles(10),
ingress_altitude=feet(18000),
min_patrol_altitude=feet(10000),
max_patrol_altitude=feet(24000),
pattern_altitude=feet(5000),
cap_duration=timedelta(minutes=30),
cap_min_track_length=nautical_miles(12),
cap_max_track_length=nautical_miles(24),
cap_min_distance_from_cp=nautical_miles(8),
cap_max_distance_from_cp=nautical_miles(25),
cap_engagement_range=nautical_miles(35),
cas_duration=timedelta(minutes=30),
sweep_distance=nautical_miles(40),
ground_unit_procurement_ratios=GroundUnitProcurementRatios(
{
UnitClass.TANK: 4,
UnitClass.ATGM: 2,
UnitClass.APC: 3,
UnitClass.IFV: 2,
UnitClass.ARTILLERY: 1,
UnitClass.SHORAD: 2,
UnitClass.RECON: 1,
}
),
)
#: Doctrine for CAP missions.
cap: Cap
WWII_DOCTRINE = Doctrine(
name="ww2",
cap=True,
cas=True,
sead=False,
strike=True,
antiship=True,
hold_distance=nautical_miles(10),
push_distance=nautical_miles(5),
join_distance=nautical_miles(5),
rendezvous_altitude=feet(10000),
max_ingress_distance=nautical_miles(7),
min_ingress_distance=nautical_miles(5),
ingress_altitude=feet(8000),
min_patrol_altitude=feet(4000),
max_patrol_altitude=feet(15000),
pattern_altitude=feet(5000),
cap_duration=timedelta(minutes=30),
cap_min_track_length=nautical_miles(8),
cap_max_track_length=nautical_miles(18),
cap_min_distance_from_cp=nautical_miles(0),
cap_max_distance_from_cp=nautical_miles(5),
cap_engagement_range=nautical_miles(20),
cas_duration=timedelta(minutes=30),
sweep_distance=nautical_miles(10),
ground_unit_procurement_ratios=GroundUnitProcurementRatios(
{
UnitClass.TANK: 3,
UnitClass.ATGM: 3,
UnitClass.APC: 3,
UnitClass.ARTILLERY: 1,
UnitClass.SHORAD: 3,
UnitClass.RECON: 1,
}
),
)
#: Doctrine for Fighter Sweep missions.
sweep: Sweep
ALL_DOCTRINES = [
COLDWAR_DOCTRINE,
MODERN_DOCTRINE,
WWII_DOCTRINE,
]
_by_name: ClassVar[dict[str, Doctrine]] = {}
_loaded: ClassVar[bool] = False
def resolve_combat_altitude(self, is_helo: bool = False) -> Distance:
if is_helo:
return self.helicopter.combat_altitude
return self.combat_altitude
def resolve_rendezvous_altitude(self, is_helo: bool = False) -> Distance:
if is_helo:
return self.helicopter.rendezvous_altitude
return self.rendezvous_altitude
@classmethod
def register(cls, doctrine: Doctrine) -> None:
if doctrine.name in cls._by_name:
duplicate = cls._by_name[doctrine.name]
raise ValueError(f"Doctrine {doctrine.name} is already loaded")
cls._by_name[doctrine.name] = doctrine
@classmethod
def named(cls, name: str) -> Doctrine:
if not cls._loaded:
cls.load_all()
return cls._by_name[name]
@classmethod
def all_doctrines(cls) -> list[Doctrine]:
if not cls._loaded:
cls.load_all()
return list(cls._by_name.values())
@classmethod
def load_all(cls) -> None:
if cls._loaded:
return
for doctrine_file_path in Path("resources/doctrines").glob("**/*.yaml"):
with doctrine_file_path.open(encoding="utf8") as doctrine_file:
data = yaml.safe_load(doctrine_file)
cls.register(
Doctrine(
name=data["name"],
rendezvous_altitude=feet(data["rendezvous_altitude_ft_msl"]),
hold_distance=nautical_miles(data["hold_distance_nm"]),
push_distance=nautical_miles(data["push_distance_nm"]),
join_distance=nautical_miles(data["join_distance_nm"]),
max_ingress_distance=nautical_miles(
data["max_ingress_distance_nm"]
),
min_ingress_distance=nautical_miles(
data["min_ingress_distance_nm"]
),
combat_altitude=feet(data["combat_altitude_ft_msl"]),
ground_unit_procurement_ratios=GroundUnitProcurementRatios.from_dict(
data["ground_unit_procurement_ratios"]
),
helicopter=Helicopter.from_dict(data["helicopter"]),
cas=Cas.from_dict(data["cas"]),
cap=Cap.from_dict(data["cap"]),
sweep=Sweep.from_dict(data["sweep"]),
)
)
cls._loaded = True

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
import logging
from collections import defaultdict
from dataclasses import dataclass
from dataclasses import dataclass, replace as dataclasses_replace
from functools import cache, cached_property
from pathlib import Path
from typing import Any, ClassVar, Dict, Iterator, Optional, TYPE_CHECKING, Type
@@ -34,6 +34,10 @@ from game.radio.channels import (
ViggenRadioChannelAllocator,
ViperChannelNamer,
WarthogChannelNamer,
PhantomChannelNamer,
HindChannelNamer,
HipChannelNamer,
KiowaChannelNamer,
)
from game.utils import (
Distance,
@@ -110,6 +114,10 @@ class RadioConfig:
"apache": ApacheChannelNamer,
"a10c-legacy": LegacyWarthogChannelNamer,
"a10c-ii": WarthogChannelNamer,
"phantom": PhantomChannelNamer,
"hind": HindChannelNamer,
"hip": HipChannelNamer,
"kiowa": KiowaChannelNamer,
}[config.get("namer", "default")]
@@ -182,6 +190,9 @@ class AircraftType(UnitType[Type[FlyingType]]):
#: planner will consider this aircraft usable for a mission.
max_mission_range: Distance
#: Speed used for TOT calculations
cruise_speed: Optional[Speed]
fuel_consumption: Optional[FuelConsumption]
default_livery: Optional[str]
@@ -400,6 +411,12 @@ class AircraftType(UnitType[Type[FlyingType]]):
for k in config:
if k in aircraft.property_defaults:
aircraft.property_defaults[k] = config[k]
# In addition to setting the property_defaults, we have to set the "default" property in the
# value of aircraft.properties for the key, as this is used in parts of the codebase to get
# the default value.
aircraft.properties[k] = dataclasses_replace(
aircraft.properties[k], default=config[k]
)
else:
logging.warning(
f"'{aircraft.id}' attempted to set default prop '{k}' that does not exist"
@@ -489,6 +506,11 @@ class AircraftType(UnitType[Type[FlyingType]]):
patrol_altitude=patrol_config.altitude,
patrol_speed=patrol_config.speed,
max_mission_range=mission_range,
cruise_speed=(
knots(data["cruise_speed_kt_indicated"])
if "cruise_speed_kt_indicated" in data
else None
),
fuel_consumption=fuel_consumption,
default_livery=data.get("default_livery"),
intra_flight_radio=radio_config.intra_flight,
@@ -505,6 +527,7 @@ class AircraftType(UnitType[Type[FlyingType]]):
LaserCodeConfig.from_yaml(d) for d in data.get("laser_codes", [])
],
use_f15e_waypoint_names=data.get("use_f15e_waypoint_names", False),
hit_points=data.get("hit_points", 1),
)
def __hash__(self) -> int:

View File

@@ -133,4 +133,5 @@ class GroundUnitType(UnitType[Type[VehicleType]]):
data.get("skynet_properties", {})
),
reversed_heading=data.get("reversed_heading", False),
hit_points=data.get("hit_points", 1),
)

View File

@@ -79,4 +79,5 @@ class ShipUnitType(UnitType[Type[ShipType]]):
manufacturer=data.get("manufacturer", "No data."),
role=data.get("role", "No data."),
price=data["price"],
hit_points=data.get("hit_points", 1),
)

View File

@@ -27,6 +27,7 @@ class UnitType(ABC, Generic[DcsUnitTypeT]):
role: str
price: int
unit_class: UnitClass
hit_points: int
_loaded: ClassVar[bool] = False

View File

@@ -1,5 +1,5 @@
from __future__ import annotations
from abc import ABC
import itertools
import logging
from collections import defaultdict
@@ -9,7 +9,9 @@ from typing import (
Dict,
Iterator,
List,
Optional,
TYPE_CHECKING,
TypeVar,
Union,
)
from uuid import UUID
@@ -21,8 +23,10 @@ from game.theater import Airfield, ControlPoint
if TYPE_CHECKING:
from game import Game
from game.ato.flight import Flight
from game.dcs.unittype import UnitType
from game.sim.simulationresults import SimulationResults
from game.transfers import CargoShip
from game.theater import TheaterUnit
from game.unitmap import (
AirliftUnits,
ConvoyUnit,
@@ -90,6 +94,103 @@ class BaseCaptureEvent:
captured_by_player: bool
@dataclass
class UnitHitpointUpdate(ABC):
unit: Any
hit_points: int
@classmethod
def from_json(
cls, data: dict[str, Any], unit_map: UnitMap
) -> Optional[UnitHitpointUpdate]:
raise NotImplementedError()
def is_dead(self) -> bool:
# Use hit_points > 1 to indicate unit is alive, rather than >=1 (DCS logic) to account for uncontrolled units which often have a
# health floor of 1
if self.hit_points > 1:
return False
return True
def is_friendly(self, to_player: bool) -> bool:
raise NotImplementedError()
@dataclass
class FlyingUnitHitPointUpdate(UnitHitpointUpdate):
unit: FlyingUnit
@classmethod
def from_json(
cls, data: dict[str, Any], unit_map: UnitMap
) -> Optional[FlyingUnitHitPointUpdate]:
unit = unit_map.flight(data["name"])
if unit is None:
return None
return cls(unit, int(float(data["hit_points"])))
def is_friendly(self, to_player: bool) -> bool:
if to_player:
return self.unit.flight.departure.captured
return not self.unit.flight.departure.captured
@dataclass
class TheaterUnitHitPointUpdate(UnitHitpointUpdate):
unit: TheaterUnitMapping
@classmethod
def from_json(
cls, data: dict[str, Any], unit_map: UnitMap
) -> Optional[TheaterUnitHitPointUpdate]:
unit = unit_map.theater_units(data["name"])
if unit is None:
return None
if unit.theater_unit.unit_type is None:
logging.debug(
f"Ground unit {data['name']} does not have a valid unit type."
)
return None
if unit.theater_unit.hit_points is None:
logging.debug(f"Ground unit {data['name']} does not have hit_points set.")
return None
sim_hit_points = int(
float(data["hit_points"])
) # Hit points out of the sim i.e. new unit hit points - damage in this turn
previous_turn_hit_points = (
unit.theater_unit.hit_points
) # Hit points at the end of the previous turn
full_health_hit_points = (
unit.theater_unit.unit_type.hit_points
) # Hit points of a new unit
# Hit points left after damage this turn is subtracted from hit points at the end of the previous turn
new_hit_points = previous_turn_hit_points - (
full_health_hit_points - sim_hit_points
)
return cls(unit, new_hit_points)
def is_dead(self) -> bool:
# Some TheaterUnits can start with low health of around 1, make sure we don't always kill them off.
if (
self.unit.theater_unit.unit_type is not None
and self.unit.theater_unit.unit_type.hit_points is not None
and self.unit.theater_unit.unit_type.hit_points <= 1
):
return False
return super().is_dead()
def is_friendly(self, to_player: bool) -> bool:
return self.unit.theater_unit.ground_object.is_friendly(to_player)
def commit(self) -> None:
self.unit.theater_unit.hit_points = self.hit_points
@dataclass(frozen=True)
class StateData:
#: True if the mission ended. If False, the mission exited abnormally.
@@ -108,6 +209,10 @@ class StateData:
#: Mangled names of bases that were captured during the mission.
base_capture_events: List[str]
# List of descriptions of damage done to units. Each list element is a dict like the following
# {"name": "<damaged unit name>", "hit_points": <hit points as float>}
unit_hit_point_updates: List[dict[str, Any]]
@classmethod
def from_json(cls, data: Dict[str, Any], unit_map: UnitMap) -> StateData:
def clean_unit_list(unit_list: List[Any]) -> List[str]:
@@ -147,6 +252,7 @@ class StateData:
killed_ground_units=killed_ground_units,
destroyed_statics=data["destroyed_objects_positions"],
base_capture_events=data["base_capture_events"],
unit_hit_point_updates=data["unit_hit_point_updates"],
)
@@ -284,6 +390,25 @@ class Debriefing:
player_losses.append(aircraft)
else:
enemy_losses.append(aircraft)
# Keep track of damaged units that are counted as killed so we don't double count
# when DCS reports damage multiple times.
units_killed_by_damage = set()
for unit_data in self.state_data.unit_hit_point_updates:
damaged_unit = FlyingUnitHitPointUpdate.from_json(unit_data, self.unit_map)
if damaged_unit is None:
continue
if damaged_unit.is_dead():
# If unit already killed, nothing to do.
if unit_data["name"] in self.state_data.killed_aircraft:
continue
if unit_data["name"] in units_killed_by_damage:
continue
units_killed_by_damage.add(unit_data["name"])
if damaged_unit.is_friendly(to_player=True):
player_losses.append(damaged_unit.unit)
else:
enemy_losses.append(damaged_unit.unit)
return AirLosses(player_losses, enemy_losses)
def dead_ground_units(self) -> GroundLosses:
@@ -356,8 +481,29 @@ class Debriefing:
losses.enemy_airlifts.append(airlift_unit)
continue
for unit_data in self.state_data.unit_hit_point_updates:
damaged_unit = TheaterUnitHitPointUpdate.from_json(unit_data, self.unit_map)
if damaged_unit is None:
continue
if damaged_unit.is_dead():
if unit_data["name"] in self.state_data.killed_ground_units:
continue
if damaged_unit.is_friendly(to_player=True):
losses.player_ground_objects.append(damaged_unit.unit)
else:
losses.enemy_ground_objects.append(damaged_unit.unit)
return losses
def unit_hit_point_update_events(self) -> List[TheaterUnitHitPointUpdate]:
damaged_units = []
for unit_data in self.state_data.unit_hit_point_updates:
unit = TheaterUnitHitPointUpdate.from_json(unit_data, self.unit_map)
if unit is None:
continue
damaged_units.append(unit)
return damaged_units
def base_capture_events(self) -> List[BaseCaptureEvent]:
"""Keeps only the last instance of a base capture event for each base ID."""
blue_coalition_id = 2

View File

@@ -19,12 +19,7 @@ from game.data.building_data import (
WW2_FREE,
WW2_GERMANY_BUILDINGS,
)
from game.data.doctrine import (
COLDWAR_DOCTRINE,
Doctrine,
MODERN_DOCTRINE,
WWII_DOCTRINE,
)
from game.data.doctrine import Doctrine
from game.data.groups import GroupRole
from game.data.units import UnitClass
from game.dcs.aircrafttype import AircraftType
@@ -106,7 +101,7 @@ class Faction:
jtac_unit: Optional[AircraftType] = field(default=None)
# doctrine
doctrine: Doctrine = field(default=MODERN_DOCTRINE)
doctrine: Doctrine = field(default=Doctrine.named("modern"))
# List of available building layouts for this faction
building_set: List[str] = field(default_factory=list)
@@ -238,14 +233,7 @@ class Faction:
# Load doctrine
doctrine = json.get("doctrine", "modern")
if doctrine == "modern":
faction.doctrine = MODERN_DOCTRINE
elif doctrine == "coldwar":
faction.doctrine = COLDWAR_DOCTRINE
elif doctrine == "ww2":
faction.doctrine = WWII_DOCTRINE
else:
faction.doctrine = MODERN_DOCTRINE
faction.doctrine = Doctrine.named(doctrine)
# Load the building set
faction.building_set = []
@@ -312,6 +300,11 @@ class Faction:
self.remove_aircraft("Su-57")
if not mod_settings.ov10a_bronco:
self.remove_aircraft("Bronco-OV-10A")
if not mod_settings.fa18efg:
self.remove_aircraft("FA_18E")
self.remove_aircraft("FA_18F")
self.remove_aircraft("EA_18G")
# frenchpack
if not mod_settings.frenchpack:
self.remove_vehicle("AMX10RCR")

View File

@@ -11,17 +11,14 @@ from shapely import transform
from shapely.geometry import shape
from shapely.geometry.base import BaseGeometry
from game.data.doctrine import Doctrine, ALL_DOCTRINES
from game.data.doctrine import Doctrine
from .ipsolver import IpSolver
from .waypointsolver import WaypointSolver
from ..theater.theaterloader import TERRAINS_BY_NAME
def doctrine_from_name(name: str) -> Doctrine:
for doctrine in ALL_DOCTRINES:
if doctrine.name == name:
return doctrine
raise KeyError
return Doctrine.named(name)
def geometry_ll_to_xy(geometry: BaseGeometry, terrain: Terrain) -> BaseGeometry:

View File

@@ -119,7 +119,6 @@ class RequirementBuilder:
def maximum_turn_to(
self, turn_point: Point, next_point: Point, turn_limit: Heading
) -> None:
large_distance = nautical_miles(400)
next_heading = Heading.from_degrees(
angle_between_points(next_point, turn_point)

View File

@@ -89,7 +89,6 @@ class GroundPlanner:
self.reserve: List[CombatGroup] = []
def plan_groundwar(self) -> None:
ground_unit_limit = self.cp.frontline_unit_count_limit
remaining_available_frontline_units = ground_unit_limit
@@ -139,7 +138,6 @@ class GroundPlanner:
remaining_available_frontline_units -= available
while available > 0:
if role == CombatGroupRole.SHORAD:
count = 1
else:

View File

@@ -241,7 +241,6 @@ class AntiAirLayout(TgoLayout):
location: PresetLocation,
control_point: ControlPoint,
) -> IadsGroundObject:
if GroupTask.EARLY_WARNING_RADAR in self.tasks:
return EwrGroundObject(name, location, control_point)
elif any(tasking in self.tasks for tasking in GroupRole.AIR_DEFENSE.tasks):

View File

@@ -132,7 +132,6 @@ class LayoutLoader:
temp_mis.country(country.name).ship_group,
temp_mis.country(country.name).static_group,
):
try:
g_id, u_id, group_name, group_mapping = mapping.group_for_name(
dcs_group.name

View File

@@ -20,8 +20,14 @@ class AntiShipIngressBuilder(PydcsWaypointBuilder):
group_names.append(target.name)
elif isinstance(target, NavalControlPoint):
carrier_name = target.get_carrier_group_name()
if carrier_name:
if carrier_name and self.mission.find_group(
carrier_name
): # Found a carrier, target it.
group_names.append(carrier_name)
else: # Could not find carrier/LHA, indicating it was sunk. Target other groups if present e.g. escorts.
for ground_object in target.ground_objects:
for group in ground_object.groups:
group_names.append(group.group_name)
else:
logging.error(
"Unexpected target type for anti-ship mission: %s",

View File

@@ -8,7 +8,6 @@ from .pydcswaypointbuilder import PydcsWaypointBuilder
class RecoveryTankerBuilder(PydcsWaypointBuilder):
def add_tasks(self, waypoint: MovingPoint) -> None:
assert self.flight.flight_type == FlightType.REFUELING
# Tanker task required in conjunction with RecoveryTanker task.
@@ -48,7 +47,6 @@ class RecoveryTankerBuilder(PydcsWaypointBuilder):
)
def configure_tanker_tacan(self, waypoint: MovingPoint) -> None:
if self.flight.unit_type.dcs_unit_type.tacan:
tanker_info = self.mission_data.tankers[-1]
tacan = tanker_info.tacan

View File

@@ -6,7 +6,6 @@ from .pydcswaypointbuilder import PydcsWaypointBuilder
class SplitPointBuilder(PydcsWaypointBuilder):
def add_tasks(self, waypoint: MovingPoint) -> None:
if not self.flight.flight_type.is_air_to_air:
# Capture any non A/A type to avoid issues with SPJs that use the primary radar such as the F/A-18C.
# You can bully them with STT to not be able to fire radar guided missiles at you,

View File

@@ -59,7 +59,6 @@ class DrawingsGenerator:
if destination in seen:
continue
else:
# Determine path color
if cp.captured and destination.captured:
color = BLUE_PATH_COLOR

View File

@@ -191,7 +191,6 @@ class FlotGenerator:
side: Country,
forward_heading: Heading,
) -> None:
infantry_position = self.conflict.find_ground_position(
group.points[0].position.random_point_within(250, 50),
500,
@@ -304,7 +303,6 @@ class FlotGenerator:
# Artillery will fall back when under attack
if stance != CombatStance.RETREAT:
# Hold position
dcs_group.points[1].tasks.append(Hold())
retreat = self.find_retreat_point(
@@ -476,7 +474,6 @@ class FlotGenerator:
from_cp: ControlPoint,
to_cp: ControlPoint,
) -> None:
if not self.game.settings.perf_moving_units:
return

View File

@@ -185,7 +185,6 @@ class NumberedWaypoint:
class FlightPlanBuilder:
WAYPOINT_DESC_MAX_LEN = 25
def __init__(self, start_time: datetime.datetime, units: UnitSystem) -> None:
@@ -503,7 +502,6 @@ class SupportPage(KneeboardPage):
aewc_ladder = []
for single_aewc in self.awacs:
if single_aewc.depature_location is None:
dep = "-"
arr = "-"

View File

@@ -402,7 +402,6 @@ class GenericCarrierGenerator(GroundObjectGenerator):
self.mission_data = mission_data
def generate(self) -> None:
# This can also be refactored as the general generation was updated
atc = self.radio_registry.alloc_uhf()

View File

@@ -41,7 +41,6 @@ class ProcurementAi:
manage_front_line: bool,
manage_aircraft: bool,
) -> None:
self.game = game
self.is_player = for_player
self.air_wing = game.air_wing_for(for_player)

View File

@@ -389,3 +389,64 @@ class WarthogChannelNamer(ChannelNamer):
@classmethod
def name(cls) -> str:
return "a10c-ii"
class PhantomChannelNamer(ChannelNamer):
"""Channel namer for the F4-E."""
@staticmethod
def channel_name(radio_id: int, channel_id: int) -> str:
radio_name = [
"COMM", # AN/ARC-164 COMM
"AUX", # AN/ARC-164 AUX
][radio_id - 1]
return f"{radio_name} Ch {channel_id}"
@classmethod
def name(cls) -> str:
return "phantom"
class HindChannelNamer(ChannelNamer):
"""Channel namer for Mi-24 Hind"""
@staticmethod
def channel_name(radio_id: int, channel_id: int) -> str:
radio_name = [
"R863",
"R828",
][radio_id - 1]
return f"{radio_name} Ch {channel_id-1}"
@classmethod
def name(cls) -> str:
return "hind"
class HipChannelNamer(ChannelNamer):
"""Channel namer for Mi-8 Hip"""
@staticmethod
def channel_name(radio_id: int, channel_id: int) -> str:
radio_name = [
"R863",
"R828",
][radio_id - 1]
return f"{radio_name} Ch {channel_id}"
@classmethod
def name(cls) -> str:
return "hip"
class KiowaChannelNamer(ChannelNamer):
"""Channel namer for OH58D Kiowa Warrior"""
@staticmethod
def channel_name(radio_id: int, channel_id: int) -> str:
radio_name = ["UHF AM", "VHF AM", "VHF FM1", "VHF FM2"][radio_id - 1]
return f"{radio_name} Ch {channel_id}"
@classmethod
def name(cls) -> str:
return "kiowa"

View File

@@ -1,4 +1,5 @@
"""Radio frequency types and allocators."""
from __future__ import annotations
import itertools
@@ -159,6 +160,7 @@ RADIOS: List[Radio] = [
Radio("AN/ARC-164", (RadioRange(MHz(225), MHz(400), MHz(1), Modulation.AM),)),
Radio("AN/ARC-186(V) AM", (RadioRange(MHz(116), MHz(152), MHz(1), Modulation.AM),)),
Radio("AN/ARC-186(V) FM", (RadioRange(MHz(30), MHz(76), MHz(1), Modulation.FM),)),
Radio("AN/ARC-201", (RadioRange(MHz(30), MHz(88), kHz(25), Modulation.FM),)),
Radio(
"AN/ARC-210",
(
@@ -185,6 +187,7 @@ RADIOS: List[Radio] = [
),
),
Radio("AN/ARC-222", (RadioRange(MHz(116), MHz(152), MHz(1), Modulation.AM),)),
Radio("AN/ARC-27", (RadioRange(MHz(225), MHz(400), kHz(100), Modulation.AM),)),
Radio("SCR-522", (RadioRange(MHz(100), MHz(156), MHz(1), Modulation.AM),)),
Radio("A.R.I. 1063", (RadioRange(MHz(100), MHz(156), MHz(1), Modulation.AM),)),
Radio("BC-1206", (RadioRange(kHz(200), kHz(400), kHz(10), Modulation.AM),)),
@@ -292,6 +295,9 @@ RADIOS: List[Radio] = [
),
),
),
# Mi-8/Mi-24
Radio("R863", (RadioRange(MHz(220), MHz(400), kHz(25), Modulation.AM),)),
Radio("R828", (RadioRange(MHz(20), MHz(60), kHz(25), Modulation.FM),)),
]

View File

@@ -33,15 +33,19 @@ class FrozenCombatJs(BaseModel):
if isinstance(combat, AtIp):
return FrozenCombatJs(
id=combat.id,
flight_position=combat.flight.position().latlng(),
target_positions=[combat.flight.package.target.position.latlng()],
flight_position=LeafletPoint.from_pydcs(combat.flight.position()),
target_positions=[
LeafletPoint.from_pydcs(combat.flight.package.target.position)
],
footprint=None,
)
if isinstance(combat, DefendingSam):
return FrozenCombatJs(
id=combat.id,
flight_position=combat.flight.position().latlng(),
target_positions=[sam.position.latlng() for sam in combat.air_defenses],
flight_position=LeafletPoint.from_pydcs(combat.flight.position()),
target_positions=[
LeafletPoint.from_pydcs(sam.position) for sam in combat.air_defenses
],
footprint=None,
)
raise NotImplementedError(f"Unhandled FrozenCombat type: {combat.__class__}")

View File

@@ -28,12 +28,12 @@ class ControlPointJs(BaseModel):
def for_control_point(control_point: ControlPoint) -> ControlPointJs:
destination = None
if control_point.target_position is not None:
destination = control_point.target_position.latlng()
destination = LeafletPoint.from_pydcs(control_point.target_position)
return ControlPointJs(
id=control_point.id,
name=control_point.name,
blue=control_point.captured,
position=control_point.position.latlng(),
position=LeafletPoint.from_pydcs(control_point.position),
mobile=control_point.moveable and control_point.captured,
destination=destination,
sidc=str(control_point.sidc()),

View File

@@ -89,6 +89,11 @@ def set_destination(
detail=f"Cannot move {cp} more than "
f"{cp.max_move_distance.nautical_miles}nm.",
)
if cp.is_fleet and not game.theater.is_in_sea(point):
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail=f"Cannot move naval control point {cp} onto land.",
)
cp.target_position = point
from .. import EventStream

View File

@@ -47,7 +47,6 @@ class GameUpdateEventsJs(BaseModel):
def from_events(
cls, events: GameUpdateEvents, game: Game | None
) -> GameUpdateEventsJs:
# We still need to be able to send update events when there is no game loaded
# because we need to send the unload event.
new_combats = []
@@ -81,9 +80,13 @@ class GameUpdateEventsJs(BaseModel):
for f in events.updated_front_lines
]
reset_on_map_center: LeafletPoint | None = None
if events.reset_on_map_center is not None:
reset_on_map_center = LeafletPoint.from_pydcs(events.reset_on_map_center)
return GameUpdateEventsJs(
updated_flight_positions={
f[0].id: f[1].latlng() for f in events.updated_flight_positions
f[0].id: LeafletPoint.from_pydcs(f[1])
for f in events.updated_flight_positions
},
new_combats=new_combats,
updated_combats=updated_combats,
@@ -110,7 +113,7 @@ class GameUpdateEventsJs(BaseModel):
],
updated_iads=updated_iads,
deleted_iads=events.deleted_iads_connections,
reset_on_map_center=events.reset_on_map_center,
reset_on_map_center=reset_on_map_center,
game_unloaded=events.game_unloaded,
new_turn=events.new_turn,
)

View File

@@ -1,5 +1,5 @@
import asyncio
from asyncio import wait
from asyncio import wait, Future
from fastapi import APIRouter, WebSocket
from fastapi.encoders import jsonable_encoder
@@ -16,9 +16,9 @@ class ConnectionManager:
self.active_connections: list[WebSocket] = []
async def shutdown(self) -> None:
futures = []
futures: list[Future[None]] = []
for connection in self.active_connections:
futures.append(connection.close())
futures.append(asyncio.create_task(connection.close()))
await wait(futures)
async def connect(self, websocket: WebSocket) -> None:

View File

@@ -37,7 +37,7 @@ class FlightJs(BaseModel):
# lost.
position = None
if isinstance(flight.state, InFlight) or isinstance(flight.state, Killed):
position = flight.position().latlng()
position = LeafletPoint.from_pydcs(flight.position())
waypoints = None
if with_waypoints:
waypoints = waypoints_for_flight(flight)

View File

@@ -27,7 +27,10 @@ class FrontLineJs(BaseModel):
bounds = FrontLineConflictDescription.frontline_bounds(front_line, theater)
return FrontLineJs(
id=front_line.id,
extents=[bounds.left_position.latlng(), bounds.right_position.latlng()],
extents=[
LeafletPoint.from_pydcs(bounds.left_position),
LeafletPoint.from_pydcs(bounds.right_position),
],
)
@staticmethod

View File

@@ -7,12 +7,12 @@ from pydantic import BaseModel
from game.server.controlpoints.models import ControlPointJs
from game.server.flights.models import FlightJs
from game.server.frontlines.models import FrontLineJs
from game.server.iadsnetwork.models import IadsNetworkJs
from game.server.leaflet import LeafletPoint
from game.server.mapzones.models import ThreatZoneContainerJs, UnculledZoneJs
from game.server.navmesh.models import NavMeshesJs
from game.server.supplyroutes.models import SupplyRouteJs
from game.server.tgos.models import TgoJs
from game.server.iadsnetwork.models import IadsConnectionJs, IadsNetworkJs
if TYPE_CHECKING:
from game import Game
@@ -44,6 +44,8 @@ class GameJs(BaseModel):
iads_network=IadsNetworkJs.from_network(game.theater.iads_network),
threat_zones=ThreatZoneContainerJs.for_game(game),
navmeshes=NavMeshesJs.from_game(game),
map_center=game.theater.terrain.map_view_default.position.latlng(),
map_center=LeafletPoint.from_pydcs(
game.theater.terrain.map_view_default.position
),
unculled_zones=UnculledZoneJs.from_game(game),
)

View File

@@ -1,11 +1,11 @@
from __future__ import annotations
from uuid import UUID
from pydantic import BaseModel
from game.server.leaflet import LeafletPoint
from game.theater.iadsnetwork.iadsnetwork import IadsNetworkNode, IadsNetwork
from game.theater.theatergroundobject import TheaterGroundObject
class IadsConnectionJs(BaseModel):
@@ -45,8 +45,8 @@ class IadsConnectionJs(BaseModel):
IadsConnectionJs(
id=id,
points=[
tgo.position.latlng(),
connection.ground_object.position.latlng(),
LeafletPoint.from_pydcs(tgo.position),
LeafletPoint.from_pydcs(connection.ground_object.position),
],
node=tgo.id,
connected=connection.ground_object.id,

View File

@@ -19,6 +19,11 @@ class LeafletPoint(BaseModel):
title = "LatLng"
@staticmethod
def from_pydcs(point: Point) -> LeafletPoint:
latlng = point.latlng()
return LeafletPoint(lat=latlng.lat, lng=latlng.lng)
LeafletLine = list[LeafletPoint]

View File

@@ -36,7 +36,7 @@ class UnculledZoneJs(BaseModel):
def from_game(game: Game) -> list[UnculledZoneJs]:
return [
UnculledZoneJs(
position=zone.latlng(),
position=LeafletPoint.from_pydcs(zone),
radius=game.settings.perf_culling_distance * 1000,
)
for zone in game.get_culling_zones()

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
from functools import lru_cache
from pydantic import BaseSettings
from pydantic_settings import BaseSettings
class ServerSettings(BaseSettings):

View File

@@ -92,7 +92,7 @@ class SupplyRouteJs(BaseModel):
# https://reactjs.org/docs/lists-and-keys.html#keys
# https://github.com/dcs-liberation/dcs_liberation/issues/2167
id=uuid.uuid4(),
points=[p.latlng() for p in points],
points=[LeafletPoint.from_pydcs(p) for p in points],
front_active=not sea and a.front_is_active(b),
is_sea=sea,
blue=a.captured,

View File

@@ -38,7 +38,7 @@ class TgoJs(BaseModel):
control_point_name=tgo.control_point.name,
category=tgo.category,
blue=tgo.control_point.captured,
position=tgo.position.latlng(),
position=LeafletPoint.from_pydcs(tgo.position),
units=[unit.display_name for unit in tgo.units],
threat_ranges=threat_ranges,
detection_ranges=detection_ranges,

View File

@@ -82,7 +82,7 @@ class FlightWaypointJs(BaseModel):
return FlightWaypointJs(
name=waypoint.name,
position=waypoint.position.latlng(),
position=LeafletPoint.from_pydcs(waypoint.position),
altitude_ft=waypoint.alt.feet,
altitude_reference=waypoint.alt_type,
is_movable=is_movable,

View File

@@ -467,6 +467,12 @@ class Settings:
default=timedelta(minutes=60),
min=30,
max=150,
detail=(
"Period of time after the start of a turn where "
"there is coverage by one or more CAP flight(s), "
"refuelling flights not tied to a specific package are on station, "
"and other flights have their TOTs."
),
)
# Performance

View File

@@ -5,7 +5,6 @@ from typing import TYPE_CHECKING
from uuid import UUID
from dcs import Point
from dcs.mapping import LatLng
if TYPE_CHECKING:
from game import Game
@@ -38,7 +37,7 @@ class GameUpdateEvents:
updated_control_points: set[ControlPoint] = field(default_factory=set)
updated_iads: set[IadsNetworkNode] = field(default_factory=set)
deleted_iads_connections: set[UUID] = field(default_factory=set)
reset_on_map_center: LatLng | None = None
reset_on_map_center: Point | None = None
game_unloaded: bool = False
new_turn: bool = False
shutting_down: bool = False
@@ -140,9 +139,7 @@ class GameUpdateEvents:
self.game_unloaded = True
self.reset_on_map_center = None
else:
self.reset_on_map_center = (
game.theater.terrain.map_view_default.position.latlng()
)
self.reset_on_map_center = game.theater.terrain.map_view_default.position
self.game_unloaded = False
return self

View File

@@ -34,6 +34,7 @@ class MissionResultsProcessor:
self.commit_damaged_runways(debriefing)
self.commit_captures(debriefing, events)
self.commit_front_line_battle_impact(debriefing, events)
self.commit_unit_damage(debriefing)
self.record_carcasses(debriefing)
def commit_air_losses(self, debriefing: Debriefing) -> None:
@@ -245,7 +246,6 @@ class MissionResultsProcessor:
delta = DEFEAT_INFLUENCE
status_msg = f"Enemy casualties outnumber allied casualties along the {cp.name}-{enemy_cp.name} frontline. Allied forces claim a victory."
elif ally_casualties > enemy_casualties:
if (
ally_units_alive > 2 * enemy_units_alive
and player_aggresive
@@ -308,42 +308,52 @@ class MissionResultsProcessor:
f"{enemy_cp.name}. {status_msg}",
)
@staticmethod
def commit_unit_damage(debriefing: Debriefing) -> None:
for damaged_unit in debriefing.unit_hit_point_update_events():
logging.info(
f"{damaged_unit.unit.theater_unit.name} damaged, setting hit points to {damaged_unit.hit_points}"
)
damaged_unit.commit()
def redeploy_units(self, cp: ControlPoint) -> None:
""" "
Auto redeploy units to newly captured base
"""
# Find the set of friendly CPs that can either contribute or receive frontline units
all_ally_connected_cps = cp.transitive_connected_friendly_points() + [cp]
ally_connected_cps = [
ocp for ocp in cp.connected_points if cp.captured == ocp.captured
]
enemy_connected_cps = [
ocp for ocp in cp.connected_points if cp.captured != ocp.captured
]
# Split into frontline CPs that are connected to enemy CPs and should receive units
# vs. non-frontline CPs that are not connected to enemy CPs and should send units.
frontline_cps = []
non_frontline_cps = []
for cp in all_ally_connected_cps:
is_frontline = False
for ocp in cp.connected_points:
if not ocp.captured:
is_frontline = True
break
if is_frontline:
frontline_cps.append(cp)
else:
non_frontline_cps.append(cp)
# If the newly captured cp does not have enemy connected cp,
# then it is not necessary to redeploy frontline units there.
if len(enemy_connected_cps) == 0:
# If there are no frontline CPs, then nothing to do.
if len(frontline_cps) == 0:
return
# From each ally cp, send reinforcements
for ally_cp in ally_connected_cps:
self.redeploy_between(cp, ally_cp)
# Equally split between all frontline CPs
move_factor = 1.0 / len(frontline_cps)
for non_frontline_cp in non_frontline_cps:
for frontline_cp in frontline_cps:
self.redeploy_between(frontline_cp, non_frontline_cp, move_factor)
def redeploy_between(self, destination: ControlPoint, source: ControlPoint) -> None:
def redeploy_between(
self, destination: ControlPoint, source: ControlPoint, move_factor: float
) -> None:
total_units_redeployed = 0
moved_units = {}
if source.has_active_frontline or not destination.captured:
# If there are still active front lines to defend at the
# transferring CP we should not transfer all units.
#
# Opfor also does not transfer all of their units.
# TODO: Balance the CPs rather than moving half from everywhere.
move_factor = 0.5
else:
# Otherwise we can move everything.
move_factor = 1
for frontline_unit, count in source.base.armor.items():
moved_units[frontline_unit] = int(count * move_factor)
total_units_redeployed = total_units_redeployed + int(count * move_factor)

View File

@@ -54,7 +54,6 @@ class SquadronDef:
@classmethod
def from_yaml(cls, path: Path) -> SquadronDef:
with path.open(encoding="utf8") as squadron_file:
data = yaml.safe_load(squadron_file)

View File

@@ -271,15 +271,15 @@ class RunwayStatus:
def needs_repair(self) -> bool:
return self.damaged and self.repair_turns_remaining is None
def __str__(self) -> str:
def describe(self) -> str:
if not self.damaged:
return "Runway operational"
return "operational"
turns_remaining = self.repair_turns_remaining
if turns_remaining is None:
return "Runway damaged"
return "damaged"
return f"Runway repairing, {turns_remaining} turns remaining"
return f"repairing, {turns_remaining} turns remaining"
@total_ordering
@@ -915,6 +915,10 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
def runway_status(self) -> RunwayStatus:
...
@abstractmethod
def describe_runway_status(self) -> str | None:
"""Description of the runway status suitable for UI use."""
@property
def runway_can_be_repaired(self) -> bool:
return self.runway_status.needs_repair
@@ -1157,6 +1161,9 @@ class Airfield(ControlPoint):
def runway_status(self) -> RunwayStatus:
return self._runway_status
def describe_runway_status(self) -> str:
return f"Runway {self.runway_status.describe()}"
def damage_runway(self) -> None:
self.runway_status.damage()
@@ -1275,6 +1282,12 @@ class NavalControlPoint(ControlPoint, ABC):
def runway_status(self) -> RunwayStatus:
return RunwayStatus(damaged=not self.runway_is_operational())
def describe_runway_status(self) -> str:
if self.runway_is_operational():
return f"Flight deck {self.runway_status.describe()}"
# Special handling for not operational carriers/LHAs
return f"Sunk"
@property
def runway_can_be_repaired(self) -> bool:
return False
@@ -1428,6 +1441,9 @@ class OffMapSpawn(ControlPoint):
def runway_status(self) -> RunwayStatus:
return RunwayStatus()
def describe_runway_status(self) -> str:
return f"Off-map airport {self.runway_status.describe()}"
@property
def can_deploy_ground_units(self) -> bool:
return False
@@ -1474,6 +1490,11 @@ class Fob(ControlPoint):
def runway_status(self) -> RunwayStatus:
return RunwayStatus()
def describe_runway_status(self) -> str | None:
if not self.has_helipads:
return None
return f"FARP {self.runway_status.describe()}"
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from game.ato import FlightType

View File

@@ -66,6 +66,7 @@ class ModSettings:
frenchpack: bool = False
high_digit_sams: bool = False
ov10a_bronco: bool = False
fa18efg: bool = False
def save_player_settings(self) -> None:
"""Saves the player's global settings to the user directory."""

View File

@@ -35,6 +35,8 @@ class TheaterUnit:
position: PointWithHeading
# The parent ground object
ground_object: TheaterGroundObject
# Number of hit points the unit has
hit_points: Optional[int] = None
# State of the unit, dead or alive
alive: bool = True
@@ -42,13 +44,17 @@ class TheaterUnit:
def from_template(
id: int, dcs_type: Type[DcsUnitType], t: LayoutUnit, go: TheaterGroundObject
) -> TheaterUnit:
return TheaterUnit(
unit = TheaterUnit(
id,
t.name,
dcs_type,
PointWithHeading.from_point(t.position, Heading.from_degrees(t.heading)),
go,
)
# if the TheaterUnit represents a GroundUnitType or ShipUnitType, initialize health to full hit points
if unit.unit_type is not None:
unit.hit_points = unit.unit_type.hit_points
return unit
@property
def unit_type(self) -> Optional[UnitType[Any]]:
@@ -70,14 +76,12 @@ class TheaterUnit:
@property
def display_name(self) -> str:
dead_label = " [DEAD]" if not self.alive else ""
unit_label = self.unit_type or self.type.name or self.name
return f"{str(self.id).zfill(4)} | {unit_label}{dead_label}"
return f"{str(self.id).zfill(4)} | {unit_label}{self._status_label()}"
@property
def short_name(self) -> str:
dead_label = " [DEAD]" if not self.alive else ""
return f"<b>{self.type.id[0:18]}</b> {dead_label}"
return f"<b>{self.type.id[0:18]}</b> {self._status_label()}"
@property
def is_static(self) -> bool:
@@ -117,6 +121,18 @@ class TheaterUnit:
unit_range = getattr(self.type, "threat_range", None)
return meters(unit_range if unit_range is not None and self.alive else 0)
def _status_label(self) -> str:
if not self.alive:
return " [DEAD]"
if self.unit_type is None:
return ""
if self.hit_points is None:
return ""
if self.unit_type.hit_points == self.hit_points:
return ""
damage_percentage = 100 - int(100 * self.hit_points / self.unit_type.hit_points)
return f" [DAMAGED {damage_percentage}%]"
class SceneryUnit(TheaterUnit):
"""Special TheaterUnit for handling scenery ground objects"""
@@ -196,7 +212,8 @@ class TheaterGroup:
def max_threat_range(self, radar_only: bool = False) -> Distance:
"""Calculate the maximum threat range of the TheaterGroup.
This also checks for Launcher and Tracker Pairs and if they are functioning or not. Allows to also use only radar emitting units for the calculation with the parameter."""
This also checks for Launcher and Tracker Pairs and if they are functioning or not. Allows to also use only radar emitting units for the calculation with the parameter.
"""
max_non_radar = meters(0)
max_telar_range = meters(0)
max_tel_range = meters(0)

View File

@@ -165,7 +165,7 @@ class ThreatZones:
cls, doctrine: Doctrine, control_point: ControlPoint
) -> Distance:
cap_threat_range = (
doctrine.cap_max_distance_from_cp + doctrine.cap_engagement_range
doctrine.cap.max_distance_from_cp + doctrine.cap.engagement_range
)
opposing_airfield = cls.closest_enemy_airbase(
control_point, cap_threat_range * 2

View File

@@ -718,7 +718,6 @@ class PendingTransfers:
self.order_airlift_assets_at(control_point)
def desired_airlift_capacity(self, control_point: ControlPoint) -> int:
if control_point.has_factory:
is_major_hub = control_point.total_aircraft_parking > 0
# Check if there is a CP which is only reachable via Airlift

View File

@@ -1,8 +1,8 @@
from pathlib import Path
MAJOR_VERSION = 9
MINOR_VERSION = 0
MAJOR_VERSION = 11
MINOR_VERSION = 1
MICRO_VERSION = 0
VERSION_NUMBER = ".".join(str(v) for v in (MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION))

View File

@@ -190,7 +190,6 @@ class Weather(ABC):
def interpolate_solar_activity(
time_of_day: TimeOfDay, high: float, low: float
) -> float:
scale: float = 0
match time_of_day:

View File

@@ -9,6 +9,7 @@ from .jas39 import *
from .ov10a import *
from .su57 import *
from .uh60l import *
from .fa18efg import *
def load_mods() -> None:

View File

@@ -1004,7 +1004,7 @@ class A_4E_C(PlaneType):
LAU3_WP156 = (1, Weapons.LAU3_WP156)
LAU3_HE151 = (1, Weapons.LAU3_HE151)
AGM_45A_Shrike_ARM = (1, Weapons.AGM_45A_Shrike_ARM)
AGM_45B_Shrike_ARM__Imp_ = (1, Weapons.AGM_45B_Shrike_ARM__Imp_)
AGM_45B_Shrike_ARM = (1, Weapons.AGM_45B_Shrike_ARM)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
1,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
@@ -1213,7 +1213,7 @@ class A_4E_C(PlaneType):
WeaponsA4EC._2_x_LAU_3_pod___19_x_2_75_Hydra__UnGd_Rkts_WTU_1_B__Practice__TER__,
)
AGM_45A_Shrike_ARM = (2, Weapons.AGM_45A_Shrike_ARM)
AGM_45B_Shrike_ARM__Imp_ = (2, Weapons.AGM_45B_Shrike_ARM__Imp_)
AGM_45B_Shrike_ARM = (2, Weapons.AGM_45B_Shrike_ARM)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
2,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
@@ -1850,7 +1850,7 @@ class A_4E_C(PlaneType):
WeaponsA4EC._2_x_LAU_3_pod___19_x_2_75_Hydra__UnGd_Rkts_WTU_1_B__Practice__TER___,
)
AGM_45A_Shrike_ARM = (4, Weapons.AGM_45A_Shrike_ARM)
AGM_45B_Shrike_ARM__Imp_ = (4, Weapons.AGM_45B_Shrike_ARM__Imp_)
AGM_45B_Shrike_ARM = (4, Weapons.AGM_45B_Shrike_ARM)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
4,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
@@ -2048,7 +2048,7 @@ class A_4E_C(PlaneType):
LAU3_WP156 = (5, Weapons.LAU3_WP156)
LAU3_HE151 = (5, Weapons.LAU3_HE151)
AGM_45A_Shrike_ARM = (5, Weapons.AGM_45A_Shrike_ARM)
AGM_45B_Shrike_ARM__Imp_ = (5, Weapons.AGM_45B_Shrike_ARM__Imp_)
AGM_45B_Shrike_ARM = (5, Weapons.AGM_45B_Shrike_ARM)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
5,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,

View File

@@ -542,7 +542,7 @@ class VSN_F4C(PlaneType):
Weapons.BRU_42_with_3_x_Mk_82___500lb_GP_Bombs_LD,
)
Mk_84___2000lb_GP_Bomb_LD = (3, Weapons.Mk_84___2000lb_GP_Bomb_LD)
AGM_45B_Shrike_ARM__Imp_ = (3, Weapons.AGM_45B_Shrike_ARM__Imp_)
AGM_45B_Shrike_ARM = (3, Weapons.AGM_45B_Shrike_ARM)
AGM_45A_Shrike_ARM = (3, Weapons.AGM_45A_Shrike_ARM)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
3,
@@ -653,7 +653,7 @@ class VSN_F4C(PlaneType):
Weapons.BRU_42_with_3_x_Mk_82___500lb_GP_Bombs_LD,
)
Mk_84___2000lb_GP_Bomb_LD = (9, Weapons.Mk_84___2000lb_GP_Bomb_LD)
AGM_45B_Shrike_ARM__Imp_ = (9, Weapons.AGM_45B_Shrike_ARM__Imp_)
AGM_45B_Shrike_ARM = (9, Weapons.AGM_45B_Shrike_ARM)
AGM_45A_Shrike_ARM = (9, Weapons.AGM_45A_Shrike_ARM)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
9,

View File

@@ -0,0 +1 @@
from .fa18efg import *

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@ def init():
if os.path.isfile(THEME_PREFERENCES_FILE_PATH):
try:
with (open(THEME_PREFERENCES_FILE_PATH)) as prefs:
with open(THEME_PREFERENCES_FILE_PATH) as prefs:
pref_data = json.loads(prefs.read())
__theme_index = pref_data["theme_index"]
set_theme_index(__theme_index)
@@ -83,5 +83,5 @@ def get_theme_css_file():
# save current theme index to json file
def save_theme_config():
pref_data = {"theme_index": get_theme_index()}
with (open(THEME_PREFERENCES_FILE_PATH, "w")) as prefs:
with open(THEME_PREFERENCES_FILE_PATH, "w") as prefs:
prefs.write(json.dumps(pref_data))

View File

@@ -1,5 +1,8 @@
from __future__ import annotations
import logging
import typing
from collections.abc import Iterator
LogHook = typing.Callable[[str], None]
@@ -15,6 +18,16 @@ class HookableInMemoryHandler(logging.Handler):
self._log = ""
self._hook = None
@staticmethod
def iter_registered_handlers(
logger: logging.Logger | None = None,
) -> Iterator[HookableInMemoryHandler]:
if logger is None:
logger = logging.getLogger()
for handler in logger.handlers:
if isinstance(handler, HookableInMemoryHandler):
yield handler
@property
def log(self) -> str:
return self._log

View File

@@ -288,7 +288,7 @@ class AtoModel(QAbstractListModel):
return
package_model = self.find_matching_package_model(package)
for flight in package.flights:
for flight in list(package.flights):
if flight.state.cancelable:
package_model.delete_flight(flight)
events.delete_flight(flight)

View File

@@ -54,7 +54,6 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
return waypoints
def find_possible_waypoints(self):
self.wpts = []
model = QStandardItemModel()
i = 0

View File

@@ -285,6 +285,7 @@ class SquadronConfigurationBox(QGroupBox):
)
self.player_list.setAcceptRichText(False)
self.player_list.setEnabled(squadron.player and squadron.aircraft.flyable)
self.player_list.setMaximumHeight(125)
left_column.addWidget(self.player_list)
button_row = QHBoxLayout()
@@ -664,7 +665,7 @@ class OverfullAirbasesDisplay(QGroupBox):
parent: QWidget | None = None,
) -> None:
super().__init__("Overfull airbases", parent)
self.setMaximumHeight(200)
self.setMaximumHeight(125)
self.parking_tracker = parking_tracker
self.parking_tracker.allocation_changed.connect(self.on_allocation_changed)
@@ -790,7 +791,7 @@ class AirWingConfigurationDialog(QDialog):
self.game = game
self.parking_tracker = AirWingConfigParkingTracker(game)
self.setMinimumSize(1024, 768)
self.resize(1024, 900)
self.setWindowTitle(f"Air Wing Configuration")
# TODO: self.setWindowIcon()

View File

@@ -9,7 +9,6 @@ from game.debriefing import Debriefing
class GameUpdateSignal(QObject):
instance = None
gameupdated = Signal(Game)
budgetupdated = Signal(Game)

View File

@@ -27,6 +27,7 @@ from game.theater import ControlPoint, MissionTarget, TheaterGroundObject
from game.turnstate import TurnState
from qt_ui import liberation_install
from qt_ui.dialogs import Dialog
from qt_ui.logging_handler import HookableInMemoryHandler
from qt_ui.models import GameModel
from qt_ui.simcontroller import SimController
from qt_ui.uiflags import UiFlags
@@ -492,6 +493,8 @@ class QLiberationWindow(QMainWindow):
"ColonelAkirNakesh",
"Nosajthedevil",
"kivipe",
"Chilli935",
"DillieKoe",
]
text = (
"<h3>DCS Liberation "
@@ -576,6 +579,10 @@ class QLiberationWindow(QMainWindow):
self._cp_dialog = QBaseMenu2(None, cp, self.game_model)
self._cp_dialog.show()
def _disconnect_log_signals(self) -> None:
for handler in HookableInMemoryHandler.iter_registered_handlers():
handler.clearHook()
def _qsettings(self) -> QSettings:
return QSettings("DCS Liberation", "Qt UI")
@@ -597,6 +604,7 @@ class QLiberationWindow(QMainWindow):
QMessageBox.Yes | QMessageBox.No,
)
if result == QMessageBox.Yes:
self._disconnect_log_signals()
self._save_window_geometry()
super().closeEvent(event)
self.dialog = None

View File

@@ -28,7 +28,6 @@ from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
class DebriefingFileWrittenSignal(QObject):
instance = None
debriefingReceived = Signal(Debriefing)

View File

@@ -16,6 +16,7 @@ from game import Game
from game.ato.flighttype import FlightType
from game.config import RUNWAY_REPAIR_COST
from game.server import EventStream
from game.sim.missionresultsprocessor import MissionResultsProcessor
from game.theater import (
AMMO_DEPOT_FRONTLINE_UNIT_CONTRIBUTION,
ControlPoint,
@@ -156,6 +157,9 @@ class QBaseMenu2(QDialog):
self.cp.capture(
self.game_model.game, events, for_player=not self.cp.captured
)
# Redeploy frontline units, as if the CP capture was done in mission.
results_processor = MissionResultsProcessor(self.game_model.game)
results_processor.redeploy_units(self.cp)
self.close()
@property
@@ -254,19 +258,22 @@ class QBaseMenu2(QDialog):
f" (Up to {ground_unit_limit} deployable, {unit_overage} reserve)"
)
self.intel_summary.setText(
"\n".join(
[
f"{aircraft}/{parking} aircraft",
f"{self.cp.base.total_armor} ground units" + deployable_unit_info,
f"{allocated.total_transferring} more ground units en route, {allocated.total_ordered} ordered",
str(self.cp.runway_status),
f"{self.cp.active_ammo_depots_count}/{self.cp.total_ammo_depots_count} ammo depots",
f"{'Factory can produce units' if self.cp.has_factory else 'Does not have a factory'}",
]
)
intel_lines = [
f"{aircraft}/{parking} aircraft",
f"{self.cp.base.total_armor} ground units" + deployable_unit_info,
f"{allocated.total_transferring} more ground units en route, {allocated.total_ordered} ordered",
]
if (runway_description := self.cp.describe_runway_status()) is not None:
intel_lines.append(runway_description)
intel_lines.extend(
[
f"{self.cp.active_ammo_depots_count}/{self.cp.total_ammo_depots_count} ammo depots",
f"{'Factory can produce units' if self.cp.has_factory else 'Does not have a factory'}",
]
)
self.intel_summary.setText("\n".join(intel_lines))
def generate_intel_tooltip(self) -> str:
tooltip = (
f"Deployable unit limit ({self.cp.frontline_unit_count_limit}) = {FREE_FRONTLINE_UNIT_SUPPLY} (base) + "

View File

@@ -70,7 +70,6 @@ class QGroundObjectMenu(QDialog):
self.init_ui()
def init_ui(self):
self.mainLayout = QVBoxLayout()
self.budget = QBudgetBox(self.game)
self.budget.setGame(self.game)
@@ -105,7 +104,6 @@ class QGroundObjectMenu(QDialog):
self.setLayout(self.mainLayout)
def doLayout(self):
self.update_total_value()
self.intelBox = QGroupBox("Units :")
self.intelLayout = QGridLayout()

View File

@@ -160,7 +160,6 @@ class IntelWindow(QDialog):
self.refresh_layout()
def refresh_layout(self) -> None:
# Clear the existing layout
if self.layout():
idx = 0

View File

@@ -1,14 +1,13 @@
import logging
import typing
from PySide6.QtCore import Signal
from PySide6.QtGui import QTextCursor, QIcon
from PySide6.QtWidgets import (
QDialog,
QPlainTextEdit,
QVBoxLayout,
QPushButton,
)
from PySide6.QtGui import QTextCursor, QIcon
from qt_ui.logging_handler import HookableInMemoryHandler
@@ -50,12 +49,17 @@ class QLogsWindow(QDialog):
self.appendLogSignal.connect(self.appendLog)
self._logging_handler = None
logger = logging.getLogger()
for handler in logger.handlers:
if isinstance(handler, HookableInMemoryHandler):
self._logging_handler = handler
break
try:
# This assumes that there's never more than one in memory handler. We don't
# configure more than one by default, but logging is customizable with
# resources/logging.yaml. If someone adds a second in-memory handler, only
# the first one (in arbitrary order) will be shown.
self._logging_handler = next(
HookableInMemoryHandler.iter_registered_handlers()
)
except StopIteration:
self._logging_handler = None
if self._logging_handler is not None:
self.textbox.setPlainText(self._logging_handler.log)
self.textbox.moveCursor(QTextCursor.End)

View File

@@ -261,7 +261,7 @@ class QNewPackageDialog(QPackageDialog):
def on_cancel(self) -> None:
super().on_cancel()
for flight in self.package_model.package.flights:
for flight in list(self.package_model.package.flights):
self.package_model.cancel_or_abort_flight(flight)

View File

@@ -38,12 +38,12 @@ class FlightMemberSelector(QSpinBox):
def __init__(self, flight: Flight, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.flight = flight
self.setMinimum(0)
self.setMaximum(flight.count - 1)
self.setMinimum(1)
self.setMaximum(flight.count)
@property
def selected_member(self) -> FlightMember:
return self.flight.roster.members[self.value()]
return self.flight.roster.members[self.value() - 1]
class QFlightPayloadTab(QFrame):
@@ -127,6 +127,12 @@ class QFlightPayloadTab(QFrame):
scrolling_layout.addWidget(docsText)
self.setLayout(layout)
# Increase width of tab when there are long loadout names. Add 50px to loadout selector
# to account for padding around the selector.
width = max(
self.sizeHint().width(), self.loadout_selector.sizeHint().width() + 50
)
self.setMinimumWidth(width)
def resize_for_flight(self) -> None:
self.member_selector.setMaximum(self.flight.count - 1)

View File

@@ -14,7 +14,6 @@ class QFlightWaypointInfoBox(QGroupBox):
self.init_ui()
def init_ui(self) -> None:
layout = QVBoxLayout()
x_pos_layout = QHBoxLayout()

View File

@@ -83,7 +83,7 @@ class QFlightWaypointList(QTableView):
self.model.index(current_index, 0), QItemSelectionModel.Select
)
self.resizeColumnsToContents()
total_column_width = self.verticalHeader().width() + self.lineWidth()
total_column_width = self.verticalHeader().sizeHint().width() + self.lineWidth()
for i in range(0, self.model.columnCount()):
total_column_width += self.columnWidth(i) + self.lineWidth()
self.setFixedWidth(total_column_width)

View File

@@ -60,7 +60,6 @@ class QFlightWaypointTab(QFrame):
self.recreate_buttons.clear()
for task in self.package.target.mission_types(for_player=True):
if (
task == FlightType.AIR_ASSAULT
and not self.game.lua_plugin_manager.is_plugin_enabled("ctld")

View File

@@ -27,7 +27,6 @@ PREDEFINED_WAYPOINT_CATEGORIES = [
class QPredefinedWaypointSelectionWindow(QDialog):
# List of FlightWaypoint
waypoints_added = Signal(list)

View File

@@ -142,6 +142,10 @@ class NewGameWizard(QtWidgets.QWizard):
self.setWindowTitle("New Game")
# Resize wizard to the size of the largest page to keep size and position
# consistent.
self.resize(self.theater_page.sizeHint())
def accept(self):
logging.info("New Game Wizard accept")
logging.info("======================")
@@ -204,6 +208,7 @@ class NewGameWizard(QtWidgets.QWizard):
ov10a_bronco=self.field("ov10a_bronco"),
frenchpack=self.field("frenchpack"),
high_digit_sams=self.field("high_digit_sams"),
fa18efg=self.field("fa18efg"),
)
mod_settings.save_player_settings()
@@ -826,6 +831,10 @@ class GeneratorOptions(QtWidgets.QWizardPage):
high_digit_sams.setChecked(mod_settings.high_digit_sams)
self.registerField("high_digit_sams", high_digit_sams)
fa18efg = QtWidgets.QCheckBox()
fa18efg.setChecked(mod_settings.fa18efg)
self.registerField("fa18efg", fa18efg)
modHelpText = QtWidgets.QLabel(
"<p>Select the mods you have installed. If your chosen factions support them, you'll be able to use these mods in your campaign.</p>"
)
@@ -877,6 +886,13 @@ class GeneratorOptions(QtWidgets.QWizardPage):
modLayout.addWidget(QtWidgets.QLabel("High Digit SAMs"), modLayout_row, 0)
modLayout.addWidget(high_digit_sams, modLayout_row, 1)
modSettingsGroup.setLayout(modLayout)
modLayout_row += 1
modLayout.addWidget(
QtWidgets.QLabel("F/A-18EFG Super Hornet (version 2.2.5)"), modLayout_row, 0
)
modLayout.addWidget(fa18efg, modLayout_row, 1)
modSettingsGroup.setLayout(modLayout)
modLayout_row += 1
mlayout = QVBoxLayout()
mlayout.addWidget(generatorSettingsGroup)

View File

@@ -87,7 +87,6 @@ class QLiberationPreferences(QFrame):
self.edit_dcs_install_dir.setText(install_dir)
def apply(self):
print("Applying changes")
self.saved_game_dir = self.edit_saved_game_dir.text()
self.dcs_install_dir = self.edit_dcs_install_dir.text()

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