Compare commits

...

880 Commits

Author SHA1 Message Date
MSWS
1ac38dc0ad update: Reduce min requirement for special round 8 -> 5 2025-11-02 01:28:16 -07:00
MSWS
62e57ffa97 fix: Reduce karma grants per round 2025-11-02 01:22:06 -07:00
MSWS
81e6b2e695 revert: Remove unnecessary delay in MapHook 2025-11-02 01:18:13 -07:00
MSWS
2ce0457346 fix: Players identifying themselves (resolves #164) 2025-11-01 19:59:35 -07:00
MSWS
ed90c54e53 update: Update suppressed round to only suppress pistols 2025-11-01 19:58:13 -07:00
MSWS
06d2d71f76 feat: Add suppressed and silent rounds, close shop after purchase 2025-11-01 18:59:54 -07:00
MSWS
c6ba041a6b Adjust detective ratio 2025-11-01 18:19:40 -07:00
MSWS
f283d7407e update: Increase speedround limit 2025-11-01 17:56:10 -07:00
MSWS
51ff4df545 update: Reduce camouflage visibility 2025-11-01 17:42:10 -07:00
MSWS
e0ee4bf325 fix: Don't give glocks by default 2025-11-01 17:21:16 -07:00
MSWS
4a4c7e0782 Reduce cost of body paint 2025-11-01 17:00:41 -07:00
MSWS
d4f67ced0c Reduce cost of compasses 2025-11-01 16:41:12 -07:00
MSWS
33ca0c8385 update: Allow inspect button to be used alongside use 2025-10-31 20:10:46 -07:00
MSWS
ff2e97a3ce update: Don't play hurt sound if Traitor is shifting 2025-10-31 20:06:19 -07:00
MSWS
a56cdc1285 Reformat and Cleanup 2025-10-31 20:01:20 -07:00
MSWS
ceda5cba64 fix: Roles not being assigned on first round of map 2025-10-31 19:59:09 -07:00
MSWS
7c203bcd91 update: Increase prices of stickers and healthshot, impl CS2 healthshot config 2025-10-31 19:53:46 -07:00
MSWS
f91fc54897 update: Increase speedround weight +semver:patch 2025-10-31 18:41:07 -07:00
MSWS
7ca4a6bef4 Update README 2025-10-30 21:46:49 -07:00
MSWS
d589a222c8 Format and Cleanup, make Ts sound like they're being damaged by hurtstation 2025-10-30 21:44:00 -07:00
MSWS
a3fdb590fd fix: Fake traitors getting damaged by hurt stations 2025-10-30 21:00:55 -07:00
MSWS
987df197bc Fix concurrent dictionary issue 2025-10-30 18:14:27 -07:00
MSWS
acb3be9132 Require on actual team to be alive 2025-10-30 18:09:14 -07:00
MSWS
bbcc998559 Up 1 knife item 2025-10-30 17:57:00 -07:00
MSWS
56781c6ae8 More item balancing, name updating, bug fix 2025-10-30 17:56:09 -07:00
MSWS
0ca983943d Revert "Fetch playername from object if available"
This reverts commit 8cd8e14e18.
2025-10-29 16:28:56 -07:00
MSWS
8cd8e14e18 Fetch playername from object if available 2025-10-29 15:27:13 -07:00
MSWS
57ef5e3e24 Use pretty name for rtd reward description 2025-10-28 20:31:04 -07:00
MSWS
9c99d316aa Revert "Revert "fix: Allow typing if dead even with muted roll""
This reverts commit e679c5193b.
2025-10-28 19:26:57 -07:00
MSWS
e679c5193b Revert "fix: Allow typing if dead even with muted roll"
This reverts commit daa24a0e87.
2025-10-28 19:26:43 -07:00
MSWS
6ece0450bb fix: Reduce volume of health station 2025-10-28 19:26:26 -07:00
MSWS
daa24a0e87 fix: Allow typing if dead even with muted roll 2025-10-28 19:20:42 -07:00
MSWS
1c8785b388 Add reminder for vanilla rounds 2025-10-28 18:50:09 -07:00
MSWS
a80c36e3c5 Suppress damage stats 2025-10-28 15:29:10 -07:00
MSWS
ba6b6c448f Change currency name to point 2025-10-28 14:06:29 -07:00
MSWS
d30e916319 Fix role name cleaning 2025-10-28 13:47:43 -07:00
MSWS
9f275fa189 Slight tweaks to logging 2025-10-28 13:39:02 -07:00
MSWS
40bdcac4b0 fix: Address copilot concerns 2025-10-28 13:30:19 -07:00
MSWS
6b3ae03ab3 Require both roles for BAD ACTION 2025-10-28 13:23:37 -07:00
MSWS
9e8e1d1fb0 Add prefix to death action 2025-10-28 13:22:53 -07:00
MSWS
fba875f098 Use prefix 2025-10-28 13:21:40 -07:00
MSWS
38fa801c15 feat: Teleport decoy working (resolves #153) 2025-10-28 13:19:29 -07:00
MSWS
b21fed3ff8 Start work on teleport decoy 2025-10-28 13:03:12 -07:00
MSWS
0e02d66350 Add configs 2025-10-28 12:39:37 -07:00
MSWS
7f6ac62348 fix: Karma events not dispatching 2025-10-28 12:28:26 -07:00
MSWS
f44e57215f fix: Special Round weights 2025-10-28 12:15:42 -07:00
MSWS
ce48f5a5ac Add logs for RTD as well 2025-10-28 12:11:54 -07:00
MSWS
4f258e55dd Log tasers 2025-10-28 11:45:43 -07:00
MSWS
b0ba6baac9 Use contexts 2025-10-28 11:30:46 -07:00
MSWS
4d052f31c6 Revert "Wonky fix for CS specific issues"
This reverts commit 2351ec55ec.
2025-10-28 10:58:51 -07:00
MSWS
7c5e7c3f68 Revert "Updates"
This reverts commit b85a3a415d.
2025-10-28 10:58:50 -07:00
MSWS
23e08134c8 Revert "Add debug"
This reverts commit 70c416bbe6.
2025-10-28 10:58:49 -07:00
MSWS
16d9335292 Revert "More work"
This reverts commit 840e04fd71.
2025-10-28 10:58:47 -07:00
MSWS
840e04fd71 More work 2025-10-28 09:40:57 -07:00
MSWS
70c416bbe6 Add debug 2025-10-28 07:31:29 -07:00
MSWS
b85a3a415d Updates 2025-10-27 23:10:05 -07:00
MSWS
2351ec55ec Wonky fix for CS specific issues 2025-10-27 22:34:35 -07:00
MSWS
4af1be95f4 Working 2025-10-27 22:10:22 -07:00
MSWS
fdb22c1090 Try using logic relay 2025-10-27 21:50:19 -07:00
MSWS
ddc309927f Add context as well for now 2025-10-27 20:51:55 -07:00
MSWS
7b657b1595 Working gamedata method 2025-10-27 20:22:13 -07:00
MSWS
05eed34ffd Try gamedata approach 2025-10-27 19:44:38 -07:00
MSWS
707a967445 Use contexts 2025-10-27 19:10:31 -07:00
MSWS
d6c6562d32 Additional safety check 2025-10-27 17:31:59 -07:00
MSWS
64e9332fa6 Add safety checks to avoid stuck states 2025-10-27 17:23:33 -07:00
MSWS
536f0eafb5 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-27 17:08:08 -07:00
MSWS
3e513cb611 Enhanced debugging 2025-10-27 17:08:02 -07:00
MSWS
cba8470f09 Increment version +semver:minor 2025-10-26 23:17:08 -07:00
MSWS
275404582f Merge branch 'main' into dev 2025-10-26 23:16:34 -07:00
MSWS
76dc717a8b Add settarget debug 2025-10-26 20:16:32 -07:00
Isaac
ff8d4dfc7e fix: Dont afk enforce unalive players (#151) 2025-10-26 18:50:36 -07:00
MSWS
f63acf24c4 Dont afk enforce unalive players 2025-10-26 18:43:03 -07:00
Isaac
678b9b0de6 fix: Map changing causing bugs (#150) 2025-10-26 18:35:05 -07:00
MSWS
18144f5827 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-26 18:21:29 -07:00
MSWS
e590ae2b7a Register map change handlers 2025-10-26 18:21:22 -07:00
Isaac
6bc0f57bed Bump actions/upload-artifact from 4 to 5 (#148)
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<p><strong>BREAKING CHANGE:</strong> this update supports Node
<code>v24.x</code>. This is not a breaking change per-se but we're
treating it as such.</p>
<ul>
<li>Update README.md by <a
href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/681">actions/upload-artifact#681</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/712">actions/upload-artifact#712</a></li>
<li>Readme: spell out the first use of GHES by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/727">actions/upload-artifact#727</a></li>
<li>Update GHES guidance to include reference to Node 20 version by <a
href="https://github.com/patrikpolyak"><code>@​patrikpolyak</code></a>
in <a
href="https://redirect.github.com/actions/upload-artifact/pull/725">actions/upload-artifact#725</a></li>
<li>Bump <code>@actions/artifact</code> to <code>v4.0.0</code></li>
<li>Prepare <code>v5.0.0</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/734">actions/upload-artifact#734</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/681">actions/upload-artifact#681</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/712">actions/upload-artifact#712</a></li>
<li><a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/727">actions/upload-artifact#727</a></li>
<li><a
href="https://github.com/patrikpolyak"><code>@​patrikpolyak</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/725">actions/upload-artifact#725</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v4...v5.0.0">https://github.com/actions/upload-artifact/compare/v4...v5.0.0</a></p>
<h2>v4.6.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Update to use artifact 2.3.2 package &amp; prepare for new
upload-artifact release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/685">actions/upload-artifact#685</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/685">actions/upload-artifact#685</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v4...v4.6.2">https://github.com/actions/upload-artifact/compare/v4...v4.6.2</a></p>
<h2>v4.6.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update to use artifact 2.2.2 package by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/673">actions/upload-artifact#673</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v4...v4.6.1">https://github.com/actions/upload-artifact/compare/v4...v4.6.1</a></p>
<h2>v4.6.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Expose env vars to control concurrency and timeout by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/662">actions/upload-artifact#662</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v4...v4.6.0">https://github.com/actions/upload-artifact/compare/v4...v4.6.0</a></p>
<h2>v4.5.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: deprecated <code>Node.js</code> version in action by <a
href="https://github.com/hamirmahal"><code>@​hamirmahal</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/578">actions/upload-artifact#578</a></li>
<li>Add new <code>artifact-digest</code> output by <a
href="https://github.com/bdehamer"><code>@​bdehamer</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/656">actions/upload-artifact#656</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/hamirmahal"><code>@​hamirmahal</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/578">actions/upload-artifact#578</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="330a01c490"><code>330a01c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/734">#734</a>
from actions/danwkennedy/prepare-5.0.0</li>
<li><a
href="03f2824452"><code>03f2824</code></a>
Update <code>github.dep.yml</code></li>
<li><a
href="905a1ecb59"><code>905a1ec</code></a>
Prepare <code>v5.0.0</code></li>
<li><a
href="2d9f9cdfa9"><code>2d9f9cd</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/725">#725</a>
from patrikpolyak/patch-1</li>
<li><a
href="9687587dec"><code>9687587</code></a>
Merge branch 'main' into patch-1</li>
<li><a
href="2848b2cda0"><code>2848b2c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/727">#727</a>
from danwkennedy/patch-1</li>
<li><a
href="9b511775fd"><code>9b51177</code></a>
Spell out the first use of GHES</li>
<li><a
href="cd231ca1ed"><code>cd231ca</code></a>
Update GHES guidance to include reference to Node 20 version</li>
<li><a
href="de65e23aa2"><code>de65e23</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/712">#712</a>
from actions/nebuk89-patch-1</li>
<li><a
href="8747d8cd76"><code>8747d8c</code></a>
Update README.md</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/upload-artifact/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=4&new-version=5)](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)


</details>
2025-10-26 18:11:56 -07:00
Isaac
83a1d0e3e3 Bump actions/download-artifact from 5 to 6 (#149)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 5 to 6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<p><strong>BREAKING CHANGE:</strong> this update supports Node
<code>v24.x</code>. This is not a breaking change per-se but we're
treating it as such.</p>
<ul>
<li>Update README for download-artifact v5 changes by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/417">actions/download-artifact#417</a></li>
<li>Update README with artifact extraction details by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/424">actions/download-artifact#424</a></li>
<li>Readme: spell out the first use of GHES by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/431">actions/download-artifact#431</a></li>
<li>Bump <code>@actions/artifact</code> to <code>v4.0.0</code></li>
<li>Prepare <code>v6.0.0</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/438">actions/download-artifact#438</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/431">actions/download-artifact#431</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v5...v6.0.0">https://github.com/actions/download-artifact/compare/v5...v6.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="018cc2cf5b"><code>018cc2c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/438">#438</a>
from actions/danwkennedy/prepare-6.0.0</li>
<li><a
href="815651c680"><code>815651c</code></a>
Revert &quot;Remove <code>github.dep.yml</code>&quot;</li>
<li><a
href="bb3a066a8b"><code>bb3a066</code></a>
Remove <code>github.dep.yml</code></li>
<li><a
href="fa1ce46bbd"><code>fa1ce46</code></a>
Prepare <code>v6.0.0</code></li>
<li><a
href="4a24838f3d"><code>4a24838</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/431">#431</a>
from danwkennedy/patch-1</li>
<li><a
href="5e3251c4ff"><code>5e3251c</code></a>
Readme: spell out the first use of GHES</li>
<li><a
href="abefc31eaf"><code>abefc31</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/424">#424</a>
from actions/yacaovsnc/update_readme</li>
<li><a
href="ac43a6070a"><code>ac43a60</code></a>
Update README with artifact extraction details</li>
<li><a
href="de96f4613b"><code>de96f46</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/417">#417</a>
from actions/yacaovsnc/update_readme</li>
<li><a
href="7993cb44e9"><code>7993cb4</code></a>
Remove migration guide for artifact download changes</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/download-artifact/compare/v5...v6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=5&new-version=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)


</details>
2025-10-26 18:11:48 -07:00
dependabot[bot]
4d0fdfa25e Bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 00:26:03 +00:00
dependabot[bot]
9f673f9d8b Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 00:25:38 +00:00
MSWS
3ad4339073 Buff bodypaint 2025-10-25 21:14:27 -07:00
Isaac
890ba71fdf Additional balancing (#147) 2025-10-25 02:50:17 -07:00
MSWS
c6fea1a21e Balances 2025-10-25 02:43:50 -07:00
MSWS
db9ad9303f Reduce M4 cost, reduce station health 2025-10-25 02:25:11 -07:00
Isaac
9224e823c0 Game balances (#146) 2025-10-25 02:05:03 -07:00
MSWS
4ab16d71db Handle map change interrupting rounds 2025-10-25 01:59:16 -07:00
MSWS
627c048183 Delay round effects for speedround due to race condition 2025-10-25 01:47:55 -07:00
MSWS
66d1106d4c Increase time, nerf camo and silent awp 2025-10-25 01:02:46 -07:00
Isaac
39c7a4762d Dev (#145) 2025-10-24 20:08:47 -07:00
MSWS
f2352ede1f Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-24 20:06:20 -07:00
MSWS
f675a87ffd Additional hotpatch 2025-10-24 20:06:04 -07:00
Isaac
7f455d5354 Hotpatch 2025-10-24 19:19:44 -07:00
Isaac
d1972fc556 Merge branch 'main' into dev 2025-10-24 19:12:35 -07:00
MSWS
f2dbc72aee Use squared distance 2025-10-24 19:09:45 -07:00
MSWS
77a2289367 Reset special round on round end 2025-10-24 19:08:55 -07:00
Isaac
456ae22b12 feat: Auto RTD (#142) 2025-10-24 18:23:48 -07:00
Isaac
2616b231dc fix: Use Locale (#141) 2025-10-24 18:20:04 -07:00
MSWS
3cb86aa2f8 Working Auto RTD 2025-10-24 18:19:02 -07:00
MSWS
4c72f3dfff Fix duplicate spaces 2025-10-24 18:00:30 -07:00
MSWS
bc45f3fb74 fix: Use Locale 2025-10-24 17:58:15 -07:00
Isaac
2bcf436677 feat: Auto RTD (resolves #140) (#139) 2025-10-24 17:41:08 -07:00
Isaac
9dfb45583b feat: Special Rounds (resolves #133) (#138) 2025-10-24 17:36:55 -07:00
MSWS
3fa1558011 feat: Auto RTD 2025-10-24 17:36:36 -07:00
MSWS
6c7bc22395 Add vanilla round 2025-10-24 17:06:35 -07:00
MSWS
c95fba0fc5 Send messages 2025-10-24 16:44:09 -07:00
Isaac
40c7a6d471 Fix services (#137) 2025-10-24 16:03:35 -07:00
MSWS
b79519f6b4 Fix services 2025-10-24 16:01:56 -07:00
Isaac
bea87d20f3 Feat/special rounds (#136) 2025-10-24 15:23:48 -07:00
MSWS
5bbc621d86 Fix circular dependencies 2025-10-24 15:21:48 -07:00
MSWS
5ed244f84c Add list of special rounds to feedback 2025-10-24 15:16:54 -07:00
MSWS
31d2354e6f Basic work for special rounds 2025-10-24 15:16:03 -07:00
MSWS
44d9644694 Start work on special rounds 2025-10-24 01:38:14 -07:00
Isaac
f6d1b95a38 Update scope management (#135) 2025-10-22 16:02:12 -07:00
MSWS
cf1d040b44 Update scope management 2025-10-22 15:58:55 -07:00
Isaac
5393920f95 Bug Fixes, Stats API +semver:minor (#134) 2025-10-22 09:18:27 -07:00
MSWS
8158206101 Increase unit test delay again 2025-10-22 09:15:15 -07:00
MSWS
06f8f083df fix: Services typo 2025-10-22 09:12:18 -07:00
Isaac
5c18a046b8 Update TTT/Stats/StatsServiceCollection.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-22 09:11:14 -07:00
Isaac
063813baca Merge branch 'main' into dev 2025-10-22 09:09:57 -07:00
MSWS
a10ce25846 Additional api updates 2025-10-22 03:05:36 -07:00
MSWS
89077c8361 Add api feedback 2025-10-22 01:12:43 -07:00
MSWS
fd3ffc6d59 Revert "Add api feedback"
This reverts commit f9e2734390.
2025-10-22 01:11:55 -07:00
MSWS
f9e2734390 Add api feedback 2025-10-22 01:11:43 -07:00
MSWS
251d8efeaf Add api feedback 2025-10-22 01:04:45 -07:00
MSWS
e83fbdd3fe Working basic API implementation 2025-10-22 00:51:17 -07:00
MSWS
99742efc5b Move stats into its own project: 2025-10-21 21:26:53 -07:00
MSWS
c802f468ed Test out new api 2025-10-21 20:49:27 -07:00
MSWS
43becefb0a Reduce round time 2025-10-20 23:33:24 -07:00
MSWS
f8f2617b09 Fix detective win condition never being met 2025-10-20 23:23:32 -07:00
MSWS
3eb59dec13 Clear role icons on new round instead of on round end 2025-10-20 23:14:58 -07:00
MSWS
792a737102 Update AliveSpoofer dispose handling 2025-10-20 22:58:51 -07:00
MSWS
85dd4edb08 Suppress damage stats 2025-10-20 21:25:07 -07:00
MSWS
2f78a62385 Update credits reward description 2025-10-20 21:16:28 -07:00
Isaac
247f7de49b Shop Balancing, AFK Management, Exploration based rewards (resolves #116) (#132) 2025-10-20 20:08:20 -07:00
MSWS
c523a9f015 Fix afk message 2025-10-20 20:04:52 -07:00
MSWS
8363265e39 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-20 20:04:43 -07:00
MSWS
f3363da9bb Cleanup AfkTimerListener 2025-10-20 19:54:28 -07:00
Isaac
ec2355eb6d Update TTT/Shop/Items/Healthshot/HealthshotItem.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-20 19:50:17 -07:00
MSWS
fd14728a27 Fix lifecycle management issue 2025-10-20 19:44:10 -07:00
MSWS
556657d249 Remove description from shop listings 2025-10-20 19:38:36 -07:00
MSWS
26c5d0e367 Fix additional message formatting 2025-10-20 19:37:45 -07:00
MSWS
536662a500 Remove broken unit test 2025-10-20 19:33:27 -07:00
MSWS
64889de2fa Clarify module classname 2025-10-20 19:32:31 -07:00
MSWS
7a6676e6ac Fix reload module 2025-10-20 19:30:00 -07:00
MSWS
49227e6d37 fix: Update RTD Credit reward to use locale 2025-10-20 19:27:37 -07:00
MSWS
0748114c9a Merge branch 'main' into dev 2025-10-20 18:57:55 -07:00
MSWS
346984f394 Update colors 2025-10-20 18:56:58 -07:00
MSWS
6316f39819 refactor: Refactor config initialization pattern
Refactor configuration initialization and improve code readability across multiple modules

- **GameHandlers/RoundStart_GameStartHandler.cs**: Change `config` initialization to a property to streamline retrieval and improve formatting for better readability.
- **Shop/Items/Traitor/C4/C4ShopItem.cs**: Refactor `config` to enable lazy loading through the Service Provider and remove the `readonly` keyword.
- **Karma/KarmaStorage.cs**: Simplify code by removing the lazy-loaded property `_configStorage` and directly using `_config`.
- **Game/RoundBasedGame.cs**: Implement lazy loading for configuration retrieval, update player initialization logic, and improve method structure for clarity.
- **Shop/Listeners/RoleAssignCreditor.cs**: Change `config` to a read-only property for lazy loading and enhance performance with delayed instantiation.
2025-10-20 18:52:44 -07:00
MSWS
2d572e19b0 Improve feedback on module reload command 2025-10-20 18:46:24 -07:00
MSWS
e4938502f4 feat: Introduce AFK detection and reward enhancements +semver:minor
Implement AFK Management and Enhance Reward and Purchase Systems

- **TTTConfig.cs**: Add `CheckAFKTimespan` configuration to manage player inactivity during game rounds.
- **HealthshotConfig.cs**: Introduce `MaxPurchases` property to limit healthshot item usage per player.
- **Command/Test/TestCommand.cs**: Implement "reload" sub-command with permission checks for restricted execution.
- **CS2ServiceCollection.cs**: Integrate `AfkTimerListener` for handling inactive players and remove conditional compilation for `TestCommand`.
- **Listeners/AfkTimerListener.cs**: Develop an AFK detection system, moving idle players to spectator mode and issuing warnings.

**Additional updates:**

- **ReloadModule.cs**: Implement class to handle reloading of modules with user feedback and error handling.
- **CS2/lang/CS2Msgs.cs**: Add message templates for AFK warnings and notifications.
- **RoundTimerListener.cs**: Streamline TTTConfig access and remove redundant scheduler handling.
- **TeamChangeHandler.cs**: Enhance team change logic with new dependencies and player checks.
- **ShopConfig.cs**: Rework reward distribution system, introducing flexible reward ranges and removing the old fixed interval configuration.
- **HealthshotItem.cs**: Implement purchase tracking and finalize configurations for purchase limits.
- **PeriodicRewarder.cs**: Split reward and update timers, integrate player position tracking, and enhance reward calculation logic based on player movement.
- **GameHandlers/LateSpawnListener.cs**: Add game state checks to improve player respawn logic during specific states.
2025-10-20 18:44:22 -07:00
MSWS
e59b2538ee Dont duplicate death events, buff poison shots 2025-10-20 17:18:53 -07:00
MSWS
7454e5e3f3 feat: Enhance CamoConfig and update role logic +semver:minor
- Increase the price of camo configuration in `CamoConfig.cs` from 55 to 75
- Add `CS2CamoConfig` behavior to `CS2ServiceCollection.cs` for extended configuration options
- Update logic in `PlayerKillListener.cs` to enhance role-based kill classification by checking differing roles
- Introduce `CS2CamoConfig.cs` with configuration variables for camo items and player visibility
- Adjust starting credits in `CS2ShopConfig.cs` for Innocents, Traitors, and Detectives
- Reduce interval reward amount for credits in `ShopConfig.cs` from 8 to 5
2025-10-20 17:09:43 -07:00
Isaac
bdef55428c Balance Changes, make Configs Hot Load 2025-10-19 22:15:54 -07:00
MSWS
4ce453dccd Buff gloves 2025-10-19 22:14:00 -07:00
MSWS
31f1403b9b Bump one shot cost 2025-10-19 22:13:28 -07:00
MSWS
d12cfa5eab Reduce credits given 2025-10-19 22:09:51 -07:00
MSWS
9022416053 refactor: Refactor config init to use expression-bodied properties
Refactor configuration initialization for improved code readability and maintainability

- Update `PoisonSmokeListener.cs` to use a property for `PoisonSmokeConfig` initialization, adding conditional access and null-coalescing logic.
- Adjust `KarmaConfig.cs` to reduce karma gain values, affecting end-of-round and winning scenarios.
- Refactor `HealthshotItem.cs`, using an expression-bodied property for `config` to enhance code clarity.
- Enhance `ArmorItem.cs` with lazy loading for `ArmorConfig` by transitioning `config` to a property using an expression-bodied member.
- Modify `PeriodicRewarder.cs` to initialize `ShopConfig` using a property, ensuring fallback configuration with unchanged core logic.

Other file changes focus on transitioning configuration retrieval to properties, promoting lazy loading and streamlined expressions across items and listeners, thereby refining consistency and readability throughout the codebase.
2025-10-19 21:51:09 -07:00
MSWS
9f45b919e1 Fix ragdolls misbehaving after multiple carriers 2025-10-19 21:29:36 -07:00
MSWS
7d75b867f9 Merge branch 'feat/rtd' 2025-10-19 19:06:54 -07:00
MSWS
35b15c4578 Inherit from IListener 2025-10-19 18:42:10 -07:00
Isaac
9b99adca3f feat: RTD System (#130) 2025-10-19 18:18:41 -07:00
MSWS
3802610b1c feat: Implement player muting system for gameplay control
```markdown
Implement player muting feature and enhance game mechanics

- Add `RTD_MUTED` message in `RtdMsgs.cs` utilizing the existing message creation method.
- Enhance `PlayerMuter.cs` by checking game state before muting players and implementing event handler to unmute players when the game finishes.
- Update `TraitorChatHandler.cs` to handle muted players in chat and prevent dead players from participating in traitor chat.
- Introduce `MuteReward` class in `MuteReward.cs` to mute players for the next round and manage muted player voice events.
- Modify `RewardGenerator.cs` to include `MuteReward` and adjust reward probabilities, enhancing the reward system.

These changes collectively introduce and integrate a system for managing player muting, ensuring robust gameplay dynamics and clarity for players during active game sessions.
```
2025-10-19 18:16:38 -07:00
MSWS
171250382e feat: Introduce RTD feature with reward system +semver:minor
Introduce RTD Project and Enhance Codebase with Localization and Config Improvements

- Introduce a new RTD project with multiple enhancements to reward and command systems:
  - Add new interfaces and classes for `IRtdReward`, `IRewardGenerator`, and several types of rewards like `ShopItemReward`, `CreditReward`, `HealthReward`, and `WeaponReward`.
  - Implement new command functionality through `RtdCommand` and `RtdStatsCommand`.
- Strengthen the code architecture by refactoring configuration access:
  - Convert `config` fields to properties using expression-bodied members across various items and listeners, promoting improved readability and potential lazy loading.
- Integrate localization features:
  - Add and standardize import statements for `TTT.Game.lang` to support upcoming language and localization developments across different game modules.
  - Create new language configuration files, like `en.yml`, and introduce classes such as `RtdMsgs` for localized message handling.
- Improve game mechanics:
  - Enhance poison effect handling within `PoisonShotsListener` with periodic damage application and improved player interaction updates.
  - Extend the `IIconManager` to offer additional player visibility options, enhancing game dynamics through methods like `RevealToAll`.
- Optimize plugin and module management:
  - Add logging features with `ShopPurchaseLogger` and new logging statements for plugin module registration.
  - Ensure cohesive project structure by updating project files and solution configuration for the new RTD module.
- Refactor utility and helper functions for better clarity:
  - Introduce utility classes like `WeaponTranslations` to map internal to user-friendly weapon names.
  - Clean up and streamline namespaces for clarity and consistency, especially within utilities like `GrenadeDataHelper`.

This commit collectively enhances the system's modularity, readability, and capability for future localization and extensibility.
2025-10-19 17:45:58 -07:00
MSWS
6524772d4f Remove player on disconnect 2025-10-19 16:11:13 -07:00
MSWS
bd8125b7a0 Prevent traitor chat metagming 2025-10-19 15:51:09 -07:00
Isaac
9c693059ea Revert "Refresh AliveSpoofer per map" (#129)
This reverts commit 9d3ecbe7fb.
2025-10-19 15:42:57 -07:00
MSWS
695d34c10c Revert "Refresh AliveSpoofer per map"
This reverts commit 9d3ecbe7fb.
2025-10-19 15:35:00 -07:00
Isaac
05aeb53a3c Refresh AliveSpoofer per map (#127) 2025-10-18 01:18:30 -07:00
MSWS
9d3ecbe7fb Refresh AliveSpoofer per map 2025-10-18 01:16:51 -07:00
MSWS
85dac3622a Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-17 23:20:28 -07:00
MSWS
9e4c29e3f7 Bump taser cost 2025-10-17 23:20:22 -07:00
Isaac
c545a10d6f Bug and crash fixes (#126) 2025-10-17 22:05:21 -07:00
Isaac
453ba14126 Update TTT/CS2/Items/PoisonShots/PoisonShotsListener.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-17 22:02:16 -07:00
Isaac
91750a1067 Update TTT/CS2/Items/Station/DamageStation.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-17 22:00:44 -07:00
Isaac
dd6b8c00fe Update TTT/CS2/Utils/DamageDealingHelper.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-17 22:00:38 -07:00
MSWS
d9ad08aa27 Improve alive checks 2025-10-17 21:55:36 -07:00
MSWS
35191f23e1 refactor: Refactor data structures for kill tracking +semver:patch
- Change `killedWithStation` data structure to `Dictionary` for enhanced player interaction tracking in `DamageStation.cs`
- Update `PoisonShotsListener.cs` to use `Dictionary` for poison kill tracking and adjust related logic
- Specify priority levels for event handlers in `GlovesListener.cs` to optimize execution order
2025-10-17 21:45:25 -07:00
MSWS
ad29de1bc5 Revert 2025-10-17 21:33:19 -07:00
MSWS
0a0416bff0 Try using native damage dealing method 2025-10-17 20:28:33 -07:00
MSWS
62c96123d1 Remove verbose debug module: 2025-10-17 19:18:51 -07:00
MSWS
274716267f Add null checks to body spawner 2025-10-16 16:24:41 -07:00
MSWS
c20842575b Merge branch 'dev' 2025-10-16 16:01:00 -07:00
MSWS
cf8169a10e Disable TeamChangeHandler for now 2025-10-16 15:15:05 -07:00
Isaac
3dcc3a7de5 Item Rebalancing, Karma Updates, New Compass, Cluster Grenade | Bug Fixes (#125)
This PR implements a comprehensive set of game balancing changes, bug fixes, and new features for a Trouble in Terrorist Town (TTT) game mode in Counter-Strike 2.

Key Changes:

    Shop item pricing rebalance: Adjusted prices across multiple traitor and detective items to improve game economy balance
    New cluster grenade item: Added a new traitor shop item that splits into multiple grenades on detonation
    Compass system refactor: Split the single compass into two separate items (player compass and body compass) with a shared abstract base class
    Karma system improvements: Updated karma calculation values and added proper storage/disposal patterns
    Bug fixes: Fixed damage application, ragdoll spawning, and team change handling issues
2025-10-16 13:38:34 -07:00
MSWS
65bcafca79 Extra extra delay 2025-10-16 13:33:12 -07:00
MSWS
6cac535e94 Additional unit testing adjustments 2025-10-16 13:24:06 -07:00
Isaac
ab3dfbda45 Update TTT/CS2/Items/PoisonShots/PoisonShotsListener.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-16 13:22:02 -07:00
Isaac
324a19c457 Update TTT/CS2/GameHandlers/BodySpawner.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-16 13:21:34 -07:00
Isaac
fda4c72da5 Update TTT/CS2/Items/PoisonShots/PoisonShotsListener.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-16 13:21:14 -07:00
Isaac
b0a1959a2e Merge branch 'main' into dev 2025-10-16 13:19:28 -07:00
MSWS
8a18b1df9c Fix failing tests 2025-10-16 13:12:49 -07:00
MSWS
c233258efc feat: Overhaul sound events, fix duplicate body issues +semver:minor
Refactor and Enhance Gameplay Mechanics

- Remove unnecessary type checks and modify logic for handling victim HP in `OneHitKnifeListener`.
- Add configurable properties in `HealthStationConfig` for improved control over healing behavior.
- Enhance `BodySpawner` with optional parameters and improve code readability for ragdoll management.
- Simplify array initialization and item sorting logic in `BuyCommand`.
- Refactor health-related variables and update sound effects in `HealthStation` to standardize behavior.
- Introduce `DealPoisonDamage` method and utility imports in `PlayerExtensions` for improved poison damage handling.
- Implement tracking and handling of poison-related events in `PoisonShotsListener` and `PoisonSmokeListener`.
- Update `DamageStation` with tracking mechanisms and improved health adjustment logic.
- Enhance item search logic in `GiveItemCommand` and introduce `DebugMessage` management in `CS2ServiceCollection`.
- Revise communication consistency in `lang/en.yml` and add `DebugMessage` class for handling debug scenarios.
- Streamline damage handling and weapon verification in `DeagleDamageListener`.
2025-10-16 13:02:22 -07:00
MSWS
e13497af76 refactor: Update item prices, make buy menu print to chat
- Increase the price of the Poison Smoke item in `PoisonSmokeConfig.cs` from 30 to 35 and ensure a newline at the end of the file.
- Reduce the price of the gloves in `GlovesConfig.cs` from 65 to 50.
- Refactor `BuyMenuHandler.cs` to improve command management and handling robustness.
- Reduce the default price of armor in `ArmorConfig.cs` from 80 to 60.
- Adjust prices in various Traitor and Detective configurations, including `C4Config.cs`, `PoisonShotsConfig.cs`, and `StickersConfig.cs` for better game balance.
2025-10-16 11:32:57 -07:00
MSWS
e8ccd2dbf8 Update velocity configs 2025-10-16 11:19:47 -07:00
MSWS
c0e95a2254 feat: Add cluster grenade feature +semver:minor (resolves #124)
```
- Add section for `CHEGrenadeProjectile_CreateFunc` in gamedata for new grenade functionality
- Update BuyMenuHandler to recognize "weapon_hegrenade" alias for purchase process
- Enhance ClusterGrenadeListener to implement multi-projectile detonation logic and remove unused fields
- Introduce `GrenadeDataHelper` class for handling grenade projectile creation
- Extend ClusterGrenadeConfig with `UpForce` and `ThrowForce` properties for customization
```
2025-10-16 11:16:23 -07:00
MSWS
5a9fd9da1a feat: Add Cluster Grenade item and adjust item prices +semver:minor
- Increase the price of the One-Shot Deagle item in CS2OneShotDeagleConfig.cs from 100 to 110.
- Reduce item prices in CamoConfig.cs and Detective/DnaScannerConfig.cs, adjusting the game's economy and item valuation.
- Introduce the Cluster Grenade item in ClusterGrenadeItem.cs and implement its related services.
- Create ClusterGrenadeListener.cs to handle events and dependencies for cluster grenades.
- Add the Cluster Grenade item description in en.yml.
- Reduce the price of HealthStationConfig.cs to improve affordability and balance.
- Update BodyPaintConfig.cs to allow for increased usage flexibility.
- Add new configuration for the traitor shop's Cluster Grenade in Traitor/ClusterGrenadeConfig.cs.
- Add the Cluster Grenade to the shop services and adjust service ordering in ShopServiceCollection.cs.
2025-10-16 10:25:55 -07:00
MSWS
fb562563de Sort items before searching 2025-10-16 10:10:57 -07:00
MSWS
161480c1f1 Fix locale usage (resolves #124) 2025-10-16 10:08:23 -07:00
MSWS
cfdffbdb47 feat: Refactor compass items into a modular system +semver:minor
Implement New Compass Item System and Remove Legacy CompassItem

- Remove `CompassItem.cs`, eliminating the legacy radar-like compass functionality for traitors and any associated gameplay mechanics.
- Introduce `InnoCompassItem` class, providing role-specific target identification and implementing extension methods for service collection integration.
- Add `AbstractCompassItem` class as a base for compass-related items, including periodic updates, abstract methods for target logic, and a visual compass display.
- Split and rename `AddCompassServices` to `AddInnoCompassServices` and `AddBodyCompassServices` in `ShopServiceCollection.cs` for better service management.
- Update `CompassMsgs.cs` by refining message identifiers and adding new instances to support expanded in-game functionalities.
- Enhance `StationItem` object spawning logic for more accurate placement based on player orientation.
- Amend `en.yml` to include "Body Compass" item details and adjust existing labels for clarity and consistency.
- Implement `BodyCompassItem` class, extending abstract compass functionality for detective roles, with methods for ownership checks and target retrieval.
2025-10-16 10:01:40 -07:00
MSWS
70e4127ccf Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-16 09:28:05 -07:00
MSWS
5acc57d96e Update to latest CS# 2025-10-16 08:57:26 -07:00
Isaac
a10b83ec4d Update FUNDING 2025-10-15 01:15:45 -07:00
Isaac
0a10cd22ab Update funding information for GitHub Sponsors
Signed-off-by: Isaac <git@msws.xyz>
2025-10-15 01:14:20 -07:00
MSWS
7838e335e4 fix: Avoid failing main pipeline if release already exists 2025-10-15 01:11:52 -07:00
MSWS
3a472bb0bf Reformat & Cleanup 2025-10-15 01:04:03 -07:00
MSWS
1a7943a58e Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-10-15 00:58:29 -07:00
MSWS
b385daf157 Add more M4 shortcuts and AWP shortcut 2025-10-15 00:58:02 -07:00
MSWS
31a1069550 feat: Suppress game stats at all times (resolves #122)
```
- Add JetBrains.Annotations to PlayerStatsTracker and annotate methods with [UsedImplicitly] to enhance code quality and maintainability.
- Reorder logic in CombatHandler's `OnPlayerDeath_Pre` to ensure necessary operations are executed before checking game state.
- Move `info.DontBroadcast` setting in CombatHandler to occur only when game is in progress.
- Modify operation sequence in `OnPlayerDeath_Pre` to spoof player status before dispatching death event.
- Clarify comment in `OnPlayerHurt` method in CombatHandler for better understanding on non-Windows platforms.
```
2025-10-14 18:26:13 -07:00
MSWS
38ef183072 Update logs unit test 2025-10-14 16:41:43 -07:00
MSWS
2c03129e86 Update README 2025-10-14 14:05:54 -07:00
MSWS
6f169ef850 Adjust credit dispersement for good/bad kills and iding bodies 2025-10-14 12:34:58 -07:00
MSWS
6f924a82b0 Fix station spawn positioning (resolves #106) 2025-10-14 11:50:58 -07:00
MSWS
06ae0250d0 Additional tweaks to karma balance 2025-10-14 11:50:03 -07:00
MSWS
bd475edd54 Localize no logs shown msg 2025-10-14 11:43:12 -07:00
MSWS
092a676f97 feat: Implement player muting when dead +semver:minor (resolves #121)
- Introduce `PlayerMuter` class in `GameHandlers` for muting dead players and send appropriate messages
- Add `PlayerMuter` behavior to `CS2ServiceCollection` and organize mod behaviors
- Remove unnecessary debug print and simplify logic in `SilentAWPItem`'s `onWeaponSound` method
- Add reminder message in `en.yml` for dead players indicating they cannot be heard
- Add `DEAD_MUTE_REMINDER` message in `CS2Msgs.cs` to notify muted dead players
2025-10-14 11:41:41 -07:00
MSWS
cebf48a9e6 refactor: Refactor dict to use IDs, fix silent awp (#105)
- Change dictionary key types from `IOnlinePlayer` to `string` in `ListCommand` for consistency, using `executor.Id` as the key.
- Update method calls in `ListCommand` to align with new dictionary key types.
- Update `silentShots` dictionary in `SilentAWPItem` to use player IDs (`string`) instead of `IOnlinePlayer` objects.
- Modify `OnPurchase` method in `SilentAWPItem` to handle weapon management asynchronously.
- Add server logging for debug messages in `SilentAWPItem`.
2025-10-14 11:26:05 -07:00
MSWS
303b6de39c Working MAUL integration 2025-10-14 11:05:11 -07:00
MSWS
9f5e96ce33 Add MAUL compatability 2025-10-14 10:45:23 -07:00
MSWS
83e90deb44 refactor: Rename ChatHandler to TraitorChatHandler +semver:patch
- Update the traitor chat format label to pluralize "TRAITOR" to "TRAITORS" in `en.yml`
- Replace `ChatHandler` with `TraitorChatHandler` in `CS2ServiceCollection.cs` to enhance focus on traitor-specific chat functionality
- Rename `ChatHandler` to `TraitorChatHandler` and update to manage traitor roles in `ChatHandler.cs`
- Ensure message processing occurs only if the game is in progress or finished in `ChatHandler.cs`
- Modify command message handling in `ChatHandler.cs` to strip backslashes from messages
2025-10-14 10:01:25 -07:00
Isaac
658eecef02 feat: Add traitor chat (resolves #112, #114) (#120) 2025-10-14 09:04:42 -07:00
MSWS
c90af8dfcf feat: Implement traitor chat message formatting +semver:minor
- Add new message format function for traitor chat in CS2Msgs.cs
- Update ChatHandler.cs with new API modules and role-checking logic
- Modify onSay method in ChatHandler.cs to support traitor message formatting
- Add new chat format specification for traitors in en.yml
2025-10-14 09:01:03 -07:00
MSWS
6cd1788992 Start workon traitor chat 2025-10-14 08:42:25 -07:00
MSWS
1288ccbd7b Refactor & Reformat, fix Spectators preventing specific roles 2025-10-14 08:33:56 -07:00
MSWS
2596289f58 Fix unit tests 2025-10-14 07:18:37 -07:00
Isaac
59eea4bc6d Simplify perm checks, grammar update +semver:patch (#119) 2025-10-13 22:46:37 -07:00
MSWS
d13403d7a7 Simplify perm checking 2025-10-13 22:44:31 -07:00
MSWS
d4fa621a03 Fix color formatting 2025-10-13 22:16:59 -07:00
Isaac
cf6b42344f Balance Changes, Respawn On Countdown Start (#118)
- Buffed poison shots (3 -> 5 bullets)
- Nerfed healthshot price (25 -> 30 credits)
- Added role indicator in shop list
- Reduced Karma harshness
2025-10-13 21:42:52 -07:00
MSWS
969c872e48 Force logs to be run on main thread 2025-10-13 21:12:59 -07:00
MSWS
b2f19b7ac3 feat: Enhance log viewing with messaging and visibility logic +semver:minor
```
Enhance logging and visibility management in game commands and role handling

- Update `LogsCommand.cs` to integrate messaging and localization with `IMessenger` and `IMsgLocalizer`, and conditionally adjust player visibility using `IIconManager`.
- Add new localized message in `GameMsgs.cs` for player's log viewing activity, using player's name.
- Overload `SetVisiblePlayers` in `IIconManager.cs` to increase flexibility by accepting an `IOnlinePlayer` object.
- Implement `SetVisiblePlayers` in `RoleIconsHandler.cs` to improve player visibility and role management, and integrate rules for specific roles like `DetectiveRole` and `TraitorRole`.
- Modify `en.yml` to include a log message for when a player views logs alive.
```
2025-10-13 21:11:50 -07:00
MSWS
742e407bcf Add shop list footer 2025-10-13 20:55:17 -07:00
MSWS
f8c8e528e2 Buff poison shot amo (resolves #115) 2025-10-13 20:16:21 -07:00
MSWS
24bd3d5f40 Clear recipients of awp sounds 2025-10-13 19:51:49 -07:00
MSWS
f1ff53893f Add karma grants per round 2025-10-13 19:47:15 -07:00
MSWS
54c89e96c0 fix: Respawn players when game actually starts
```
- Improve player respawn logic in RoundTimerListener for better team handling and secure timer disposal.
- Enhance initial setup and end game logic in RoundBasedGame with robust role assignment, game state checks, and localization support.
- Increase default Healthshot item price in HealthshotConfig.
```
2025-10-13 19:19:42 -07:00
MSWS
46514a6016 Change comparator 2025-10-12 19:05:13 -07:00
MSWS
73a8f6a9f5 Restrict logs command behind permission 2025-10-12 18:16:52 -07:00
MSWS
f0c239f08e build: Change DI lifetimes for TExtension and ITerrorModule
- Change dependency injection lifetime for services implementing `TExtension` from scoped to singleton in `ServiceCollectionExtensions.cs`
- Register `ITerrorModule` as a transient service in `ServiceCollectionExtensions.cs`
2025-10-12 18:08:25 -07:00
MSWS
bafad884d9 Dont modify karma if killer is the victim 2025-10-12 17:49:30 -07:00
MSWS
1d7e2f7466 Update compass more frequently 2025-10-12 17:42:15 -07:00
MSWS
f9e3d2d324 perf: Refactor KarmaStorage for thread-safety and reliability
- Replace `Dictionary<IPlayer, int>` with `ConcurrentDictionary<string, int>` in `KarmaStorage.cs` for thread-safe operations.
- Introduce caching logic with semaphore for serialized writes in `KarmaStorage.cs`.
- Add periodic data flushing mechanism to the database with improved error handling in `KarmaStorage.cs`.
- Seal `KarmaStorage` class to prevent inheritance and ensure configuration loading precedes database operations.
- Improve error handling with logging and ensure reliable database connections in `KarmaStorage.cs`.
- Enhance thread safety and performance in `FlushAsync` and `Write` methods, improving idempotency and preventing race conditions.
- Increase robustness with null checks, additional validations, and modular code separation in `KarmaStorage.cs`.
2025-10-12 17:24:19 -07:00
Isaac
9ce90cccaa Additional Shop Items, Synchronous Events (#111) 2025-10-12 14:05:14 -07:00
Isaac
551f6a09ef Update TTT/CS2/Command/PlayerPingShopAlias.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-12 13:59:45 -07:00
MSWS
41db8f9444 Additional awaits 2025-10-12 13:54:56 -07:00
MSWS
361bbb0a49 Wait for async event completion 2025-10-12 13:52:17 -07:00
MSWS
228ea40cec feat: Add item sorting and player ping features +semver:minor
```
- Introduce `IItemSorter` interface across multiple components to enhance item sorting capabilities in shop commands.
- Enhance `ListCommand` with caching mechanisms, improved sorting logic, and item formatting adjustments for better performance and usability.
- Implement `PlayerPingShopAlias` for enhanced player interaction, including command listeners and shop command processing tied to player actions.
- Set default price for Silent AWP in `SilentAWPConfig` to standardize item pricing.
- Conduct significant cleanup and optimization in `PoisonShotsListener` to improve gameplay experience and reduce unnecessary debug messages.
```
2025-10-12 13:22:31 -07:00
MSWS
44f7283145 feat: Refactor PlayerDamagedEvent for enhanced accuracy
```
- Increase delay time in KarmaListenerTests to ensure proper karma update processing.
- Change `Event` class from abstract to concrete, and modify `Id` property implementation.
- Adjust CS2GameConfig timing settings for more balanced gameplay.
- Enhance PoisonShotsListener functionality with player health parameters and item removal.
- Make SimpleLogger methods virtual to improve subclass flexibility.
- Implement new logging capabilities in CS2Logger with Serilog integration.
- Enhance GiveItemCommand with new event handling for item purchases.
- Update DeagleTests for accurate simulation of weapon damage.
- Modify PlayerDamagedEvent structure for more precise damage calculations.
- Improve DamageStation logic to align with new damage handling.
- Refactor DamageCanceler for better code organization and cross-platform support.
```
2025-10-12 12:28:08 -07:00
MSWS
1a52daad7c Fix async event handler 2025-10-12 11:56:20 -07:00
MSWS
7d0d32998e feat: Refactor karma configs and add new settings
- Change database connection string constant name for consistency in `CS2KarmaConfig.cs`
- Extend description of minimum karma for clarification of its impact
- Refine descriptions of player actions related to karma for improved clarity
- Rename karma-related constants to generic terms for simplicity
- Introduce configurable warning window for low karma to prevent repeat warnings
- Add configurable karma delta values for in-game actions
- Update Load method to include new karma-related configurations
2025-10-11 20:53:49 -07:00
MSWS
3cda83932e feat: Refactor karma system for configurability
```
- Add detailed XML documentation comments to `KarmaConfig.cs` to improve code understanding and maintainability.
- Remove the default value of `MinKarma` in `KarmaConfig.cs`, making it a mandatory setting.
- Introduce new properties in `KarmaConfig.cs` for handling different karma scenarios in player interactions.
- Add a dependency on `TTT.API.Storage` in `KarmaListener.cs` for loading configurations.
- Replace hardcoded karma values in `KarmaListener.cs` with configurable options, enhancing flexibility and adaptability.
```
2025-10-11 20:50:24 -07:00
MSWS
7ea57d0a9b Reformat & Cleanup 2025-10-11 20:46:16 -07:00
MSWS
839be785f0 refactor: Refactor shop item removal to use generics
- Update `DeagleDamageListener.cs` to enhance type safety and address edge cases related to item removal and friendly fire logic.
- Improve the purchase validation logic in `Stickers.cs` using a type-specific item check.
- Refactor `Shop.cs` to use generic type parameters in item removal methods, enhancing type safety.
- Simplify `IShop.cs` by removing default implementations and focusing on type-based item checks.
- Enhance overall code clarity and maintainability with type-specific method improvements.
2025-10-11 20:42:40 -07:00
MSWS
8f0a273f79 refactor: Enhance EventBus validation and optimize role assign logic
```
- Introduce validation to `EventBus` listener methods to enforce `void` return type and enhance exception messaging for parameter constraints.
- Refactor `RoleAssignCreditor` to simplify execution path by making `OnRoleAssign` synchronous and handling asynchronous operations with `Task.Run`.
```
2025-10-11 20:23:06 -07:00
MSWS
cb6cb442b1 refactor: Refactor event dispatching to be synchronous +semver:minor
- Remove asynchronous calls and convert to synchronous dispatch in multiple files, improving performance and reducing complexity.
- Refactor `RoundBasedGame.cs` to enhance game state management, implement team victory determination, and ensure resource disposal.
- Update `IEventBus.cs` and `EventBus.cs` to change the dispatch method to synchronous operation, altering method return types.
- Modify karma-related tests and storage in `KarmaListenerTests.cs`, `KarmaStorage.cs`, and `MemoryKarmaStorage.cs` to reflect synchronization changes, ensuring correct behavior.
- Refactor `EventModifiedMessenger.cs` to improve message handling by switching to synchronous calls.
- Implement new karma penalty logic in `KarmaListener.cs` for certain actions, adjusting the handling and calculations of karma.
2025-10-11 20:01:40 -07:00
Isaac
cb2a5a8720 feat: Compass Item (resolves #80) (#108) 2025-10-09 18:55:36 -07:00
MSWS
10be465d33 Resolve merge / build issue 2025-10-09 18:17:10 -07:00
Isaac
a0720376d4 Merge branch 'dev' into feat/shop-compass
Signed-off-by: Isaac <git@msws.xyz>
2025-10-09 18:15:58 -07:00
Isaac
f5cb87d92c feat: Add Silent AWP item +semver:minor (resolves #105) (#110)
- Implement Silent AWP item functionality with
`SilentAWPServiceCollection` and `SilentAWPItem` class for `TraitorRole`
- Add Silent AWP shop item and related localized texts in `en.yml`
- Define message constants for Silent AWP in `SilentAWPMsgs.cs` for
internationalization
- Modify `GiveItemCommand.cs` to incorporate `OnPurchase` logic for item
purchases
- Manage player validity in `CS2AliveSpoofer.cs` by removing players
with null handles
- Enhance player detail replies in `IndexCommand.cs`
- Introduce messaging functionality in `BaseItem.cs` and use via
`Messenger` field
- Add Silent AWP service integration in `ShopServiceCollection.cs` and
`Traitor` config in `SilentAWPConfig.cs`
2025-10-09 18:14:57 -07:00
MSWS
bd6c15aca7 feat: Add Silent AWP item and related services +semver:minor
- Implement Silent AWP item functionality with `SilentAWPServiceCollection` and `SilentAWPItem` class for `TraitorRole`
- Add Silent AWP shop item and related localized texts in `en.yml`
- Define message constants for Silent AWP in `SilentAWPMsgs.cs` for internationalization
- Modify `GiveItemCommand.cs` to incorporate `OnPurchase` logic for item purchases
- Manage player validity in `CS2AliveSpoofer.cs` by removing players with null handles
- Enhance player detail replies in `IndexCommand.cs`
- Introduce messaging functionality in `BaseItem.cs` and use via `Messenger` field
- Add Silent AWP service integration in `ShopServiceCollection.cs` and `Traitor` config in `SilentAWPConfig.cs`
2025-10-09 18:07:05 -07:00
MSWS
7e5e34c500 Merge branch 'feat/shop-compass' of github.com:MSWS/TTT into feat/shop-compass 2025-10-09 15:04:21 -07:00
MSWS
8a886a158c Replace center with HTML specific call 2025-10-09 15:04:15 -07:00
MSWS
fc61682669 Merge branch 'dev' into feat/shop-compass 2025-10-08 21:02:54 -07:00
MSWS
d6e4655674 Update licenses 2025-10-08 21:02:40 -07:00
MSWS
c53a584113 Update licenses 2025-10-08 21:02:26 -07:00
MSWS
c56387d6e4 feat: Enhance compass configuration and logic
- Add new configuration fields in CompassConfig.cs to customize compass FOV and length
- Implement maximum range check and refactor angle calculations in CompassItem.cs
- Update distance descriptions in CompassItem.cs for thematic clarity
- Enhance code readability and maintainability in CompassItem.cs through refactoring
2025-10-08 20:53:30 -07:00
MSWS
1c8d1a5dd5 feat: Implement advanced compass and detection features +semver:minor
- Enhance `CompassItem` in `CompassItem.cs` with refined enemy detection, directional compass, and improved documentation.
- Add `TextCompass` utility class in `TextCompass.cs` featuring static method for compass line generation with direction normalization and cardinal placements.
2025-10-08 20:23:14 -07:00
MSWS
340dae1b16 Optimize role/team-based checks 2025-10-08 18:55:16 -07:00
MSWS
eff58ab2f1 Reformat & Cleanup 2025-10-07 20:54:29 -07:00
MSWS
acababeaf5 feat: Add compass itme +semver:minor (resolves #80)
```
Introduce Compass Item for Traitor Role

- Add a new configuration file `CompassConfig.cs` for the traitor-exclusive compass with default settings, including a price of 70 and a maximum range of 10,000.
- Integrate the `Compass` service into the shop by updating `ShopServiceCollection.cs` to support the new item.
- Extend `BaseItem.cs` with additional dependencies for game management, enhancing item functionality.
- Update localization in `en.yml` to include the "Player Compass" item, ensuring descriptions and structure accommodate the new addition.
- Create `CompassMsgs.cs` to manage compass-related messages with `SHOP_ITEM_COMPASS` and `SHOP_ITEM_COMPASS_DESC` for localization.
- Enhance vector handling in `VectorExtensions.cs` by adding nullability checks and support for nullable objects.
- Implement `CompassItem.cs` to support traitor-specific gameplay features like real-time radar updates and enemy tracking.
```
2025-10-07 20:46:32 -07:00
MSWS
f40b8ebef0 test: Fix BalanceClear unit tests relying on karma 2025-10-07 10:10:52 -07:00
MSWS
9a005c209a Cleanup & Reformat 2025-10-07 10:06:34 -07:00
MSWS
36914d01a5 refactor: Move BuyMenu handler into GameHandlers 2025-10-07 09:59:26 -07:00
MSWS
62e48e6c73 update(traitor): Buff hurt stations 2025-10-07 09:55:43 -07:00
MSWS
82a4c47dfb Merge branch 'main' into dev 2025-10-07 09:48:53 -07:00
MSWS
31f02ec7f0 ci: Cleanup release.yml 2025-10-07 09:48:48 -07:00
MSWS
36be427f56 Crash fixes for TeamChangeHandler 2025-10-05 17:17:53 -07:00
MSWS
8709d633b1 Fix one shot revolver improperly handling detective case 2025-10-05 00:36:33 -07:00
MSWS
1c63b3fbcc feat: Implement karma, team changes, and taser rewards
```
- Update PlayerKillListener to modify balance adjustments and simplify kill log messages.
- Add TeamChangeHandler to CS2ServiceCollection for managing team changes.
- Introduce TaseRewarder to ShopServiceCollection, enabling taser damage event handling.
- Make RoleAssignCreditor asynchronous and integrate karma-based credit adjustments.
- Update SpectatorRole assignment logic with new IRoleAssigner dependency.
- Make player parameter nullable in KarmaConfig's MaxKarma method.
- Refactor BuyListener to remove server chat notifications and streamline armor setting.
```
2025-10-04 22:53:11 -07:00
MSWS
f1521fc499 feat: Implement purchase handling and enhance karma update +semver:minor
- Update `KarmaStorage.cs` to increase karma update frequency and integrate Counter Strike features.
- Enhance `CS2ServiceCollection.cs` with new `BuyListener` behavior for handling purchase activities.
- Add `GetArmor` method in `PlayerExtensions.cs` to retrieve player armor and helmet status.
- Implement `BuyListener.cs` to manage player purchases, logging, and inventory adjustments.
2025-10-04 21:57:04 -07:00
MSWS
986f30c34f Remove all buyzones 2025-10-04 20:35:33 -07:00
MSWS
be6d79dcea test: Refactor damage events and enhance debug logging
- Simplify `PlayerDamagedEvent` instantiation by removing an unused parameter in `DeagleTests.cs` and `PlayerActionsTest.cs`.
- Update `HpLeft` calculation in `PlayerDamagedEvent.cs` to use a new formula for determining remaining health, improving damage calculation accuracy.
- Enhance debugging in `PoisonShotsListener.cs` by adding debug logs and null checks for more reliable damage event tracking.
- Refactor tests in `DeagleTests.cs` to verify unique item kill behavior after the first use.
2025-10-04 20:14:26 -07:00
MSWS
87d55aadd2 refactor: Refactor event handling and improve localization. +semver:minor
- Simplify `PlayerDamagedEvent` constructor and update health calculations for clarity and consistency.
- Add context to damage events in `DamageStation.cs` by including weapon property and streamline damage calculation logic.
- Enhance `PoisonShotsListener.cs` with localization support for weapon names, improve poison effect handling, and cleanup code for better maintainability.
2025-10-04 19:53:21 -07:00
MSWS
9efd37063b refactor: Refactor damage logic and event handling
- Refactor `OneHitKnifeListener` to set victim's health directly to zero for simplified one-hit kill logic.
- Add `PlayerDamagedEvent` in `DamageStation` to allow external interference in damage calculation and consider event modifications.
- Streamline `PlayerDamagedEvent` class by refactoring damage calculation logic and removing unnecessary properties and fields.
- Update `PoisonShotsListener` to include dependency on `IEventBus`, enhance poison effects, and dispatch relevant events such as `PlayerDamagedEvent` and `PlayerDeathEvent`.
- Remove `DamageEventTest` class, indicating a refactor or change in damage event management/testing strategy.
2025-10-04 19:04:24 -07:00
MSWS
3381722e7e feat: Enhance event handling and add player tracking features
```
- Update DamageStation.cs to enhance event handling and player interaction:
  - Integrate `IEventBus` for event dispatching.
  - Improve `onInterval` to provide health boosts, handle player deaths, and ensure sound commands are issued post-death event.
- Modify RoundBasedGame.cs to increase class extensibility:
  - Update variable access levels and rename to maintain consistency.
- Adjust OneHitKnife.cs to change service registration approach and extend functionality.
- Enhance DamageCanceler.cs with OS-specific cleanup logic and streamlined damage handling.
- Update OneHitKnifeListener.cs for improved damage calculation and to incorporate JetBrains annotations.
- Simplify station tracking and ownership in StationItem.cs and StationInfo.cs.
- Introduce EmitSoundCommand.cs to expand command module functionality.
```
2025-10-04 18:50:47 -07:00
Isaac
5565c72b5b Add Karma and One-Hit Knife Item (#103) 2025-10-04 09:53:53 -07:00
MSWS
36f9b7a600 Address unit test issues 2025-10-04 09:17:50 -07:00
MSWS
41c7a788d3 refactor: Refactor codebase for cleanup and async improvements
```
Refactor and optimize multiple components

- Remove obsolete attributes and unused dependencies in `IEventBus.cs`, `KarmaListener.cs`, `KarmaSyncer.cs`, and `ICommandManager.cs` to clean up code and improve maintainability.
- Enhance asynchronous event handling in `EventModifiedMessenger.cs` by integrating `await` for dispatch operations, improving consistency in message processing.
- Refine `CombatHandler.cs` logic with improved null-checking and better statistics handling, enhancing robustness during player events.
- Enable caching by default in `KarmaStorage.cs`, and update karmas asynchronously to boost performance.
- Simplify `Game/RoundBasedGame.cs` by removing unnecessary dependencies and improving state management and role assignment logic, enhancing game flow control.
```
2025-10-04 08:56:58 -07:00
MSWS
5d37e5d1ec feat: Add One-Hit Knife to Traitor shop +semver:minor (resolves #99)
- Add new shop item "One-Hit Knife" with description in `en.yml`
- Introduce `OneHitKnifeMsgs` class for handling localization messages related to "One-Hit Knife" item
- Implement `OneHitKnifeListener` class to handle game events for the "One-Hit Knife" item functionality
- Create `OneHitKnife` class, extending the item functionality for the `TraitorRole` with service integration
- Update `ShopServiceCollection.cs` to include "One-Hit Knife" in the item collection and shop services
- Add `OneHitKnifeConfig.cs` to define configuration settings including price and friendly fire options for the "One Hit Knife" feature
2025-10-04 08:40:19 -07:00
MSWS
741f2b8586 feat: Implement karma system enhancement features (resolves #47)
Implement enhanced Karma system functionalities and refactorings

- Update `KarmaConfig.cs` to make properties non-virtual and add immutability with "init" accessors, and introduce new configuration properties to support additional karma functionalities.
- Add `KarmaSyncer` behavior to `CS2ServiceCollection.cs` for managing Karma-related synchronization tasks.
- Enhance `SpectatorRole.cs` with an `OnAssign` method to facilitate role assignments and automatically convert players to spectators when needed.
- Filter player assignments in `RoundBasedGame.cs` to include only specific roles and refine non-traitor calculations to only consider assigned players.
- Introduce a comprehensive `KarmaSyncer` class in `Listeners/KarmaSyncer.cs` for managing Karma synchronization, including event handling for Karma updates and safe operations checks.
- Refactor `CS2KarmaConfig.cs` by simplifying structure, adding descriptive updates, and altering command usages related to Karma configurations.
- Remove `KarmaSyncer.cs` from `GameHandlers` to accommodate code restructuring and potential modality changes for player data management.
- Refactor and expand methods in `KarmaMsgs.cs` to adopt simpler expression-bodied syntax and create structured warning messages.
- Introduce dependency checks and reward temporal conditions in `PeriodicRewarder.cs` to ensure balanced issuance aligns with game progression.
- Enhance `KarmaBanner.cs` with new dependencies, tracking mechanisms, and advanced event handling for role assignments and karma-related notifications.
- Improve `KarmaListener.cs` by changing class inheritance, adding debugging capabilities, and switching to batch processing for Karma updates.
- Extend language file `en.yml` with additional warning messages targeting users with critically low Karma levels.
2025-10-04 08:27:21 -07:00
Isaac
e08cad21b3 Add remaining karma services / implementations (#102) 2025-10-04 07:09:34 -07:00
MSWS
ff4c8e76ff Reformat & Cleanup 2025-10-04 07:05:31 -07:00
MSWS
e8bb8564ad feat: Introduce Karma feature enhancements and .NET 8 update
```
- Update TTT/Plugin/Plugin.csproj to target .NET 8.0 and add Microsoft.Data.Sqlite reference
- Enhance TTT/CS2/CS2ServiceCollection.cs with new KarmaBanner mod behavior
- Add TTT/Karma/lang/KarmaMsgs.cs for Karma language messages handling
- Introduce configuration command in TTT/CS2/Configs/CS2KarmaConfig.cs for low karma actions
- Add old karma value property in TTT/Karma/Events/KarmaUpdateEvent.cs
- Implement KarmaBanner class in TTT/CS2/Listeners/KarmaBanner.cs for monitoring karma updates
- Develop new KarmaCommand class in TTT/Karma/KarmaCommand.cs for retrieving karma values
- Enhance TTT/Karma/KarmaStorage.cs with cache support and better SQL handling
- Introduce NameDisplayer OS check in TTT/CS2/GameHandlers/NameDisplayer.cs
- Add CommandUponLowKarma configuration in TTT/Karma/KarmaConfig.cs
- Register KarmaCommand in TTT/Karma/KarmaServiceCollection.cs
- Create English language file TTT/Karma/lang/en.yml for Karma messages
```
2025-10-04 07:00:08 -07:00
MSWS
58cb208c1d feat: Add Karma configuration and async event handling +semver:minor
```
Implement Karma Configuration and Improve Event Handling

- Add `IStorage<KarmaConfig>` service registration in `CS2ServiceCollection`, enhancing support for karma configurations.
- Make `KarmaUpdateEvent` dispatch asynchronous in `KarmaStorage`, and improve error checking for database connections.
- Introduce `CS2KarmaConfig`, a new configuration class with settings for managing karma, including connection strings and value limits.
- Convert karma properties and methods to virtual in `KarmaConfig`, allowing for potential overrides in derived classes.
```
2025-10-04 06:03:34 -07:00
MSWS
a546a8b22e feat: Migrate to SQLite and cleanup KarmaSyncer logic +semver:minor
- Update `Karma.csproj` to include Microsoft.Data.Sqlite and SQLite packages.
- Refactor `KarmaSyncer.cs` by removing the unused `IPlayerFinder` initialization, adding the `UsedImplicitly` attribute, and streamlining player validation logic.
- Change database backend in `KarmaStorage.cs` from MySQL to SQLite.
- Define a default value for the `DbString` property in `KarmaConfig.cs`.
- Adjust service configuration in `KarmaServiceCollection.cs` by modifying `IKarmaService` registration and introducing `KarmaListener`.
2025-10-04 05:58:49 -07:00
Isaac
05daee24a4 Shop and gameplay expansion: new items, localization, periodic rewards, command refactor (#94)
**Summary**

This PR delivers a substantial TTT update that expands the shop, refines
gameplay flow, and improves player feedback. It adds multiple new items
with CS2-specific behavior, introduces a periodic reward system,
implements configurable sounds and full localization, and cleans up
internal command and event handling.

**Scope**

* 56 commits
* 117 files changed
* +2,518 −301

**Why**

* Broaden traitor and detective toolkits to increase strategic variety.
* Make messaging consistent and translatable.
* Reduce friction in command handling and event wiring.
* Close a set of outstanding issues.

**Highlights**

New items and features

* C4 item with CS2 configuration (resolves #79).
* M4A1 item and storage support (resolves #71).
* Traitor gloves item (resolves #81).
* Camouflage item with async fix.
* Poison shots with enhanced effects and feedback (resolves #75).
* Poison smoke (resolves #74).
* Armor item (resolves #67).
* Taser item (resolves #69).
* Healthshot and role reveal (resolves #98).
* Body Paint item and service registration with default config.
* Periodic reward system for players (resolves #97).
* Credits granted for kills and identifications with tuned penalties.

Player experience

* Configurable sound support.
* Full localization for commands and messages.
* Increased HUD font size and adjusted text positioning.
* Shop prefix and HUD tweaks. Skull hidden in HUD.

Core refactors

* Command execution support on main thread. Command structure
consolidated and clarified.
* Round timer and C4 event handling refactored. Old C4 listener logic
removed.
* Event namespaces and item handling reorganized.
* Name formatting utilities updated.

Stability and fixes

* Shop events now reliably fire.
* Role assignment logging corrected.
* Credits no longer overridden by balance clearer.
* Various cleanup, reformatting, and unused line removals.

Administrative

* Licenses updated for new dependencies and content.
* Multiple merges and resyncs with main to keep branch current.

**Configuration changes**

* New item configs: C4, M4A1, Gloves, Camouflage, Poison Shots, Poison
Smoke, Armor, Taser, Healthshot, Body Paint.
* Added localization keys for new messages, commands, and out-of-ammo
lines.
* Sound configuration is now user configurable.
* Station role behavior updated to support Poison Smoke changes.

**API and plugin touchpoints**

* Storage and plugin modules extended for M4A1Config.
* PlayerKillListener added and registered.
* BodyPaint service registered and applied by default where configured.

**Testing**

* Unit and runtime checks for:

  * Shop purchase flows for each new item.
  * Command execution on main thread and permission checks.
  * Credits earn and clear at round transitions.
  * Poison effects timing, damage application, particles, and feedback.
  * HUD text size and positions across common resolutions.
  * Localization fallback behavior for missing keys.
* Manual CS2 tests for C4 behavior and item equips.
* Verified shop events fire for buy, equip, and use.
2025-10-04 05:50:51 -07:00
MSWS
84230fd231 Improve prop drag line appeareance (resolves #96) 2025-10-04 05:40:10 -07:00
MSWS
fdfc0cc3bd Update phrasing in role reveals 2025-10-04 05:31:01 -07:00
MSWS
7fc0f21fa4 fix: Poison shots carrying over rounds (resolves #101)
```
Enhance poison effect management and resource disposal

- Improve resource management in `PoisonSmokeListener.cs` by ensuring proper disposal of poison smoke timers, clearing the timer list upon disposal, and ensuring termination of damage effects according to configuration settings. Remove unnecessary debug output for cleaner logs.
- Refactor `PoisonShotsListener.cs` to reset poison shot data and improve disposal logic. Enhance poison shot usage management and streamline game mechanics related to poison damage and effects, ensuring a more efficient game experience.
```
2025-10-04 05:28:56 -07:00
MSWS
ed7ad35b85 Address concurrent modification issue 2025-10-04 05:25:55 -07:00
MSWS
e6009dd75a Price tweaks 2025-10-04 05:22:10 -07:00
MSWS
b295fc45a2 Suppress bomb planting notification 2025-10-04 05:02:38 -07:00
MSWS
385f87ad12 Reformat & Cleanup 2025-10-04 03:47:57 -07:00
MSWS
6aedbeb3fb Adjust shop prefix 2025-10-04 03:38:40 -07:00
MSWS
2d078e4dfa Adjust periodic reward 2025-10-04 03:36:54 -07:00
MSWS
ff3dd9563e feat: Add periodic reward system +semver:minor (resolves #97)
```
- Modify `DamageStation.cs` to check `_Config.TotalHealthGiven` before health comparison and improve `onInterval` method for better clarity and robustness.
- Enhance `ShopServiceCollection.cs` by adding `PeriodicRewarder`, introducing periodic rewards functionality.
- Update `StationConfig.cs` by setting `TotalHealthGiven` to 0 and increasing `StationHealth` from 100 to 1000, enhancing station durability.
- Implement `PeriodicRewarder.cs`, a new class for issuing periodic rewards to players using dependency injection and a timed approach.
- Introduce new properties `CreditRewardInterval` and `IntervalRewardAmount` in `ShopConfig.cs` to define frequency and amount of periodic rewards, supporting a new credit accumulation strategy.
```
2025-10-04 03:36:11 -07:00
MSWS
8126dfea21 Hide skull in HUD 2025-10-04 03:20:56 -07:00
MSWS
e158bbbd77 feat: Add Healthshot and role-reveal +semver:minor (resolves #98)
Enhance Game Messaging and Item Functionality

- Update `GameMsgs.cs` to add new messages for role reveal on death and traitor reveal, ensuring consistency with message factory use.
- Add "Health Shot" item to `en.yml`, enhancing shop content with healing capabilities.
- Refine `RoundBasedGame.cs` to improve game state transitions, event handling, and winning team determination.
- Create `HealthshotConfig.cs` for configuring "Health Shot" item specifics, including pricing and weapon identifiers.
- Modify `BuyCommand.cs` to implement main thread execution and enhance item search logic for partial matches.
- Introduce `TraitorBuddyInformer` class to inform traitors of their allies during rounds.
- Expand `OutOfRoundCanceler.cs` logic to allow damage events in finished game states.
- Add `PlayerDeathInformer` class for revealing player killers, enhancing game event transparency.
- Introduce and register `HealthshotItem` within the shop, defining purchase logic and localized messaging.
- Remove redundant debug information from `PoisonSmokeListener.cs`, optimizing poison effect logic.
2025-10-04 02:55:08 -07:00
MSWS
e382302911 Reformat & Cleanup 2025-10-04 00:45:57 -07:00
MSWS
75690ee64b feat: Add Poison Smoke feature and refactor station roles (resolves #74)
Introduce Poison Smoke Item and Enhance Role Configurations

- Create `CS2PoisonSmokeConfig.cs` to configure the new Poison Smoke item, defining parameters like price, damage, and sound effect.
- Update `CS2ServiceCollection.cs` to handle poison smoke configuration using new implementations.
- Add `PoisonSmokeMsgs.cs` to define messages for the Poison Smoke item, facilitating localization.
- Enhance `DamageStation.cs` with role management by excluding `TraitorRole` from damage and adding sound feedback.
- Implement `PoisonSmokeListener.cs` to manage poison smoke events with dependencies and scheduled effects.
- Refactor `StationItem.cs` to introduce a generic role parameter, increasing flexibility.
- Update `HealthStation.cs` to specify the detective role with the generic `StationItem`.
- Introduce new configuration files for the traitor's poison smoke in `Traitor/PoisonSmokeConfig.cs`, detailing item properties.
- Simplify `ListCommand.cs` by adjusting item formatting logic for consistency.
- Update `PoisonShotsListener.cs` to handle refined poison configurations.
- Create `PoisonSmokeItem.cs` to define and manage the Poison Smoke item with dependency injection and role restrictions.
2025-10-04 00:43:53 -07:00
MSWS
dadd7b31a1 feat: Increase font size and adjust text positioning
- Increase default font size in TextSetting.cs for improved visibility
- Adjust world units per pixel in TextSetting.cs for better text scaling
- Modify text hat positioning in TextSpawner.cs relative to player’s rotation
2025-10-03 23:50:17 -07:00
MSWS
697c7f5d6b refactor: Refactor commands and enhance item handling +semver:minor
- Enhance `BuyCommand` with usage guidance and unified query logic
- Improve `ListCommand` with async task handling, dependency injections, and enhanced filtering and sorting based on player roles and game state
- Introduce a shorthand alias for `ShopCommand` balance and add usage property for better command guidance
- Upgrade `RoleIconsHandler` event handling, visibility management, and hot-reload logic
- Implement standard pricing and new properties in Traitor and Detective configuration files; adjust color mapping for health display
- Improve player equality handling by implementing `IEquatable` in `CS2Player` and `IPlayer` classes
2025-10-03 23:38:21 -07:00
MSWS
559718621f feat: Implement main thread command execution support +semver:minor
- Integrate `CounterStrikeSharp.API` in `BuyCommand.cs` for enhanced shop functionality.
- Refactor health color calculation in `HealthStationConfig.cs` to increase intensity as health increases.
- Revamp `CS2CommandManager.cs` with improved synchronous command processing and robust exception handling.
- Add `MustBeOnMainThread` property in `ICommand.cs` to manage command execution context.
- Update `ShopCommand.cs` to refine execution flow and description formatting.
- Revise logical comment and color calculation in `DamageStationConfig.cs` for correctness.
- Enhance clarity in `PlayerKillListener.cs` by refining event handling messages.
2025-10-03 22:59:25 -07:00
MSWS
d84e581392 feat: Localize balance command messages +semver:minor
```
- Update `BalanceCommand.cs` to include message localization and update reply format
- Refactor `Shop.cs` logging methods and simplify item handling
- Enhance `ShopMsgs.cs` with message prefix logic and credit prefix determination
- Update `en.yml` with consistent shop prefix and add new balance display message
```
2025-10-03 22:29:49 -07:00
MSWS
640924d2a2 fix: Fixed credits being overriden by balance clearer
```
- Modify RoundShopClearer to reset balances and items only when the game state is "FINISHED"
- Add debug logging and correct logic in PlayerKillListener to improve event handling
- Comment out obsolete Roles property in TestPlayer
- Enhance debug logging and initialize item lists correctly in Shop
- Update BalanceClearTest with role-related imports and new test for role assignments
```
2025-10-03 22:09:56 -07:00
MSWS
d6da16e537 Register PlayerKillListener 2025-10-03 21:50:24 -07:00
MSWS
c223f3994b feat: Add Taser item +semver:minor (resolves #69)
```
- Integrate Taser functionality into the Shop module by updating the `ShopServiceCollection.cs` to include the Taser item in the shop services.
- Add a new `TaserConfig` file to define default configurations for the taser item in `TTT/ShopAPI/Configs`.
- Update `en.yml` to include localization for the new Taser item with its description.
- Introduce `CS2TaserConfig` for advanced configuration management of taser items within the CS2 module, and integrate it into `CS2ServiceCollection.cs`.
- Implement the `TaserItem` class in `TTT/Shop/Items/Taser` along with the supporting `TaserMsgs` class for handling messages related to the taser in the shop.
```
2025-10-03 21:47:59 -07:00
MSWS
8d0b4878f1 feat: Add armor item (resolves #67)
```plaintext
Add comprehensive armor functionalities and improvements

- Introduce `ArmorConfig` class to configure shop items with default armor and helmet settings.
- Create `ArmorMsgs` class to handle message creation for armor-related items in the game.
- Enhance `PlayerExtensions` with new `SetArmor` method and improve `SetColor` handling and state management.
- Register armor services within `ShopServiceCollection` to integrate armor features into the shop framework.
- Refactor `RoundTimerListener` for improved readability and consistency in round-ending logic.
- Include "Armor with Helmet" in the language file with its description for better item localization.
- Develop `ArmorItem` class to manage armor items, incorporating configuration, purchase logic, and localization.
```
2025-10-03 21:38:37 -07:00
MSWS
b1155a18ba feat: Enhance poison shot effects and player feedback +semver:minor
- Enhance `PoisonShotsListener.cs` by adding utility functions, refining weapon event handling, and improving player feedback with configurable effects and sounds.
- Update `PoisonShotMsgs.cs` to include personalized messages for poison hit events by leveraging the player's name.
- Refactor `GiveItemCommand.cs` for improved targeting and async item delivery, adding clearer command usage instructions.
- Add a new localization message in `en.yml` for poison shot hit feedback.
- Modify `PoisonShotsConfig.cs` to adjust damage interval and introduce configurable sound and color for poison effects.
2025-10-03 21:22:21 -07:00
MSWS
c134289990 Add locale for running out of shots 2025-10-03 21:10:16 -07:00
MSWS
d8323f4c64 fix: Body Paint and Poison Items
- Remove event handler for item purchases in `BodyPaintListener` and enhance logic for body identification and use tracking
- Integrate `IPluginModule` interface in `PoisonShotsListener` and refactor poison shot handling to improve inventory management and dependency injection
- Update `PoisonShotsItem` to use specific configuration and storage mechanisms
- Register PoisonShots service in `ShopServiceCollection` to expand shop functionalities
2025-10-03 21:06:15 -07:00
MSWS
a1f5c27660 Register poision shots, fix m4a1 internal weapon 2025-10-03 20:34:54 -07:00
MSWS
8ed094b8fc Remerge main 2025-10-03 00:44:11 -07:00
MSWS
07fc47803d Update prompt again 2025-10-03 00:42:47 -07:00
MSWS
e71d255409 feat: Add poison shots +semver:minor (resolves #75)
```
- Add new configuration for poison shots in `Traitor/PoisonShotsConfig.cs` to manage properties like price, damage, and total shots.
- Implement `PoisonShotsListener` in the game to handle item usage, apply poison effects, and ensure resource management.
- Create `PoisonShotsItem` class to introduce a new item restricted to the Traitor role, integrating it with shop functionalities.
- Update `lang/en.yml` to include a new shop item description for "Poison Shots".
- Define message constants for poison shots in `PoisonShotMsgs.cs` to facilitate localization and UI display.
```
2025-10-03 00:39:42 -07:00
MSWS
acc48db327 Resync with main 2025-10-03 00:03:30 -07:00
MSWS
c7b5460b35 Update CONTRIBUTING.md 2025-10-03 00:03:08 -07:00
MSWS
afe44097c3 Change to AGPL License, update README 2025-10-02 23:58:13 -07:00
MSWS
8e9ec76975 Populate dictionary prior to adding 2025-10-02 23:44:45 -07:00
MSWS
63cd3e782f Apply default config to body paint 2025-10-02 23:44:00 -07:00
MSWS
a1acb91151 Register body paint service 2025-10-02 23:42:59 -07:00
MSWS
355f39a12a refactor: Add Body Paint, refactor namespaces +semver:minor (resolves #82)
```
- Add descriptions and labels for "Body Paint" in English language file
- Update Detective's DNA Scanner and Sticker configurations for improved namespace specificity
- Implement BodyPaintMsgs class for handling body paint item messages
- Introduce BodyPaintListener for handling body paint purchase and usage events
- Restructure PlayerEvent files to align with new ShopAPI directory and namespace
- Add BodyPaintConfig for shop item configuration with default settings
```
2025-10-02 23:29:11 -07:00
MSWS
87815d099e Append Item to 1ShotDeagle Class, start work on BodyPaintItem 2025-10-02 23:08:00 -07:00
MSWS
6f904df564 Fix role assignment logging 2025-10-02 21:18:39 -07:00
MSWS
42a2fc2caf Fix gloves item (ref #81) 2025-10-02 18:49:43 -07:00
MSWS
306be07e8f Reformat and Cleanup 2025-10-02 18:30:21 -07:00
MSWS
233396fbd1 refactor: Refactor round timer and remove C4 listener logic
- Adjust handling of round win conditions in `RoundTimerListener.cs` by adding commands to ignore and re-enable conditions during round end process; improve round end subscription logic and add `Dispose` method to clean up resources.
- Remove addition of `C4Listener` from the service collection in `C4ShopItem.cs`.
- Delete `C4Listener.cs`, removing event handlers for bomb-related events.
2025-10-02 15:50:08 -07:00
MSWS
a1194008ad feat: Refactor name formatting and add C4 event handling +semver:minor
```
- Refactor `CS2Player.cs` to improve name formatting with `CreatePaddedName`, eliminating redundant methods and enhancing alignment.
- Integrate `C4Listener` into `C4ShopItem.cs` for improved C4 item handling in the shop.
- Comment out the `RoundEnd_GameEndHandler` registration in `CS2ServiceCollection.cs` to potentially defer its functional roles.
- Refactor `EndRound` method in `RoundUtil.cs` to utilize `VirtualFunctions.TerminateRoundFunc`, comment out obsolete implementations.
- Update `RoundTimerListener.cs` to incorporate `System.Reactive.Concurrency`, optimize round timing logic, and introduce resource disposal to prevent leaks.
- Implement `C4Listener.cs` to handle bomb events and announce activities, enhancing player communication.
- Simplify `StationItem.cs` by removing unused imports and redundant debug announcements while maintaining core functionality.
- Adjust `RoundBasedGame.cs` to ensure the game state is accurately set to `IN_PROGRESS` post player preparation, without changing game flow logic.
```
2025-10-02 15:21:43 -07:00
MSWS
5bc52acf3c Fix shop events not being called 2025-10-02 13:35:42 -07:00
MSWS
9a6af7acab feat: Add M4A1Config support to storage and plugin modules +semver:minor
- Add support for M4A1Config storage in CS2ServiceCollection by including a new `AddModBehavior` for `IStorage<M4A1Config>`
- Implement a new configuration class for the M4A1 shop item in CS2M4A1Config with storage and plugin module interfaces
- Define static configuration variables with validators for price, clear slots, and associated weapons in CS2M4A1Config
- Implement plugin initialization methods and register fake config variables in CS2M4A1Config
- Load configuration in CS2M4A1Config, parsing clear slots and weapons from strings into arrays, with nullable type inference and asynchronous processing
2025-10-02 13:08:31 -07:00
MSWS
8cc241bcca Fix camo applying asynchronously 2025-10-02 13:05:12 -07:00
MSWS
cab156184c Tweak credit penalty 2025-10-02 11:04:09 -07:00
MSWS
9ee69a0b28 feat: Add credits given for killing / identifying +semver:minor
```
- Refactor balance deduction in Shop.cs to use `AddBalance` method for improved consistency and added player notification for successful purchases.
- Enhance BuyCommand.cs by updating Execute method to return Task.FromResult, adding a health check, and modifying item search logic for better accuracy.
- Update PlayerKillListener.cs to extend from BaseListener, integrate ShopAPI, and add methods for handling on-kill and body identification events with balance adjustments.
- Use JetBrains.Annotations in RoleAssignCreditor.cs for potential external or reflective method use, adding UsedImplicitly attribute for OnRoleAssign method.
- Extend ShopMsgs.cs and en.yml with new purchase success messages including item names, improving player feedback.
```
2025-10-02 11:03:03 -07:00
MSWS
e529229200 Update licenses 2025-10-01 23:46:52 -07:00
MSWS
e7dc5c02fe feat: Add camouflage item +semver:minor (resolves #73)
- Add `CamouflageItem` class for managing camouflage items in the game
- Implement `AddCamoServices` in service collection extension for mod behavior
- Introduce configuration loading for camouflage settings with `IStorage<CamoConfig>`
- Provide localization for item name and description
- Implement purchasing logic: visibility settings and ownership check in `CamouflageItem`
- Add "Camouflage" item and description to the language file
- Expand shop services to include camouflage features via `AddCamoServices`
- Establish `CamoConfig` in `ShopAPI` with default pricing and visibility properties
- Create `CamoMsgs` class for managing camouflage item messages
2025-10-01 23:34:05 -07:00
MSWS
522e42a5ff Reformat & Cleanup 2025-10-01 23:26:30 -07:00
MSWS
871500fbdc Cleanup unused lines 2025-10-01 23:21:39 -07:00
MSWS
f023d36aa9 Update CS2 impl 2025-10-01 23:10:58 -07:00
MSWS
a185b217e0 feat: Add traitor gloves item and reorganize configs. (resolves #81)
- Add new "Gloves" item to traitor shop with localization and descriptions
- Allow modification of `Killer` property in `IBody.cs` for enhanced gameplay flexibility
- Reorganize configuration files under relevant directories for better clarity (e.g., HealthStationConfig, DnaScannerConfig)
- Introduce `GlovesListener` class to handle event-driven interactions for the "Gloves" item
- Implement traitor-specific configurations and services for items like C4 and gloves, including default pricing and usage limits
2025-10-01 23:09:43 -07:00
MSWS
dbfd360c6c feat: Add M4A1 shop item +semver:minor (resolves #71)
```
Add M4A1 Item to Shop with Configuration and Localization

- Add TTT/Shop/Items/M4A1/M4A1Msgs.cs to manage localized messages for the M4A1 item.
- Update TTT/Shop/lang/en.yml with a new shop item "M4A1 Rifle and USP-S" and its description.
- Modify TTT/Shop/ShopServiceCollection.cs to include M4A1 services and adjust service ordering for better organization.
- Introduce TTT/ShopAPI/Configs/M4A1Config.cs for setting up the M4A1 item configuration, including price and weapon slots.
- Create TTT/Shop/Items/M4A1/M4A1ShopItem.cs to define the M4A1 shop item with purchase and inventory management logic.
```
2025-10-01 22:47:05 -07:00
MSWS
4a64741a8e Add CS2-specific configuration of C4 item 2025-10-01 22:20:14 -07:00
MSWS
7372ffda45 feat: Add C4 item for TraitorRole in shop +semver:minor (resolves #79)
- Add C4Msgs class for localization of C4 shop item in the Traitor category
- Introduce C4ShopItem class with methods for purchase, limitations, and role restriction handling
- Update ShopServiceCollection to include C4 service for Traitor role
- Introduce C4Config class for configuration of C4 shop items with various properties
- Add English localization entry for "C4 Explosive" shop item with description
2025-10-01 22:16:03 -07:00
MSWS
9ea9c78208 Remove extra spacing in DNA locale 2025-10-01 22:02:59 -07:00
MSWS
85601f1fc0 feat: Implement configurable sound and localization support
- Add configuration for `UseSound` property in `DamageStationConfig` and `HealthStationConfig`
- Implement localization support in `HealthStation.cs` by replacing hardcoded strings with localized messages
- Introduce `UseSound` abstract property in `StationConfig`
- Update localization files with new shop items and descriptions in `lang/en.yml`
- Create `StationMsgs.cs` to manage station-related item messages via a factory pattern
- Enhance `DamageStation.cs` for internationalization and configurable sound settings
- Annotate unused or implicitly used methods in `StickerListener.cs` with `[UsedImplicitly]`
2025-10-01 22:02:12 -07:00
MSWS
ddf52f057d Update from main 2025-10-01 21:50:19 -07:00
MSWS
63c4e9b7d8 Update prompt again 2025-10-01 21:49:59 -07:00
MSWS
e317e9418e Include subsequent merge info when generating release notes 2025-10-01 21:46:48 -07:00
Isaac
e39b19930c Additional Shop Item Implementations 2025-10-01 20:40:16 -07:00
Isaac
c2ecba1847 Merge branch 'main' into dev 2025-10-01 20:39:01 -07:00
Isaac
354ccf2fbe Update TTT/Shop/Items/Detective/Stickers/Stickers.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-10-01 20:38:03 -07:00
Isaac
9d1a7f5618 feat: Integrate ShopAPI and add station item features +semver:minor (resolves #84) (#92)
```
- Integrate ShopAPI into various components including PlayerPurchaseItemEvent, DnaScanner, and multiple stations for improved shop functionalities.
- Introduce new HealthStationConfig and DamageStationConfig for configuring health and damage-related station items.
- Update CS2 project to target .NET 8.0 and enable advanced C# features, while removing outdated folder references for streamlined project structure.
- Correct namespace declarations across multiple files, enhancing consistency and organizational clarity within the codebase.
- Add new or updated commands and extensions, such as SetHealthCommand, to improve player health management and interaction.
- Enhance localization features by importing TTT.Game.lang across various roles, commands, and logging implementations.
- Incorporate new logic in DNA scanning and station interactions, including damage dealing and healing over time based on player proximity.
```
2025-10-01 19:13:36 -07:00
MSWS
ea62b312be Update unit tests 2025-10-01 19:12:10 -07:00
MSWS
6778531312 feat: Integrate ShopAPI and add station item features +semver:minor
```
- Integrate ShopAPI into various components including PlayerPurchaseItemEvent, DnaScanner, and multiple stations for improved shop functionalities.
- Introduce new HealthStationConfig and DamageStationConfig for configuring health and damage-related station items.
- Update CS2 project to target .NET 8.0 and enable advanced C# features, while removing outdated folder references for streamlined project structure.
- Correct namespace declarations across multiple files, enhancing consistency and organizational clarity within the codebase.
- Add new or updated commands and extensions, such as SetHealthCommand, to improve player health management and interaction.
- Enhance localization features by importing TTT.Game.lang across various roles, commands, and logging implementations.
- Incorporate new logic in DNA scanning and station interactions, including damage dealing and healing over time based on player proximity.
```
2025-10-01 19:08:30 -07:00
MSWS
8ab4328d9b Fix YML 2025-10-01 15:01:35 -07:00
MSWS
c5a91f334d refactor: Improve item not found handling and code readability
- Add a new message for item not found in `en.yml` to enhance user error feedback
- Clean up `GiveItemCommand.cs` by importing `TTT.Locale` and removing debug messages
- Improve `CS2AliveSpoofer.cs` readability with better conditional logic and early return handling
- Enhance `BuyCommand.cs` by removing redundant searches and utilizing localization for consistency
- Change `DecayTime` in `DnaScannerConfig.cs` from 3 minutes to 10 seconds for faster testing
2025-10-01 14:55:28 -07:00
MSWS
b2f4474e8f Reformat 2025-10-01 14:39:15 -07:00
Isaac
8aee59a87e Feat/dna (resolves #87) (#91) 2025-10-01 14:21:04 -07:00
MSWS
e27bddf8e2 feat: Implement enhanced DNA scanner messaging +semver:minor
- Clean up `ShopAPI.csproj` by removing redundant project references.
- Remove the DNA Scanner item and its description from the English language file in `Shop`.
- Streamline `DnaScanner.cs` by eliminating an unnecessary using directive.
- Enhance `DnaListener.cs` to improve messaging logic with role information and implement new message templating for DNA scans.
- Refactor `DnaMsgs.cs` by adjusting namespaces and adding message properties for enhanced DNA scan functionalities.
- Update `CS2.csproj` by removing a duplicate project reference.
- Expand `en.yml` in `CS2` with translations for DNA scanner items and messages for DNA scanning, including specific scenarios involving suicide.
2025-10-01 14:17:27 -07:00
MSWS
4514e9baa0 feat: Introduce DNA scanner functionality
- Extend functionality in `DnaListener.cs` by adding dependency injection and enhancing the `OnPropPickup` event handler with player and body checks.
- Add `TimeOfDeath` property to `CS2Body.cs` for improved tracking of body creation time.
- Introduce `DnaScannerServiceCollection` in `DnaScanner.cs` for better service management and mod behavior registration.
- Extend `IBody` interface with `TimeOfDeath` to track deceased player identification time.
- Update `ShopServiceCollection.cs` to integrate `AddDnaScannerServices`, enhancing shop capabilities with DNA scanner features.
2025-10-01 11:23:31 -07:00
MSWS
67755c36c6 Tweak AI prompt and input 2025-09-30 18:25:18 -07:00
MSWS
eaf1ab627e Begin work on adding CS2-specific items
```
- Rename and reorganize directories for DNA-related items to new path under "CS2/Items/DNA"
- Relocate RoleRestrictedItem.cs while maintaining its original functionality
- Move and update DnaListener.cs with a low-priority event handler and add an execution order comment
- Rename BaseItem.cs file path as part of project structure reorganization
- Update CS2.csproj by adding "Items\" folder and correcting duplicate project reference
```
2025-09-30 18:22:13 -07:00
MSWS
57bef00055 Refactor Shop api into its own project, separate from impl 2025-09-30 18:18:07 -07:00
MSWS
7dd6d4dd38 Finalize stickers (resolves #89) 2025-09-30 17:46:52 -07:00
MSWS
f1cce6c230 Fix windows-specific issues 2025-09-30 17:32:42 -07:00
MSWS
922f121009 refactor: Add IIconManager and Sticker features +semver:minor
```
- Rename property `Name` to `Id` across various commands and classes for consistency and clarity, affecting files like `Test/SetRoleCommand.cs`, `GameHandlers/KarmaSyncer.cs`, and `Command/Test/TestCommand.cs`.
- Add new interface `IIconManager` to manage player visibility with methods for handling up to 64 players using a bitmask in `API/Player/IIconManager.cs`.
- Introduce `ShowIconsCommand` and `IndexCommand` classes to enhance game command functionality, leveraging the new `IIconManager` for icon management.
- Implement a new shop item "Stickers" with associated classes `Stickers.cs`, `StickerListener.cs`, and `StickerMsgs.cs`, providing role-revealing capabilities for detective players.
- Refactor shop item and command structures to use a new `BaseItem` abstract class, enhancing code organization and inheritance patterns.
- Update logging in `Plugin/TTT.cs` to use `Id` instead of `Name` for module identification, standardizing log outputs.
- Adjust visibility and color duration settings in `Listeners/ScreenColorApplier.cs` for improved gameplay feedback.
- Refactor service registration and command handling to remove redundancies and improve icon manager integrations in files like `CS2ServiceCollection.cs` and `Command/Test/ScreenColorCommand.cs`.
```
2025-09-30 17:00:57 -07:00
MSWS
2a0924138f Tweak 1-shot weapon defaults 2025-09-30 13:03:30 -07:00
Isaac
a4dc781ee4 Feat/one shot revolver (resolves #66) (#90) 2025-09-30 11:15:24 -07:00
MSWS
935b430769 refactor: Enhance purchase messaging system with localization
- Add new localized messages for shop interactions in `TTT/Shop/lang/en.yml`
- Implement `PurchaseResultExtensions` in `TTT/Shop/Shop/PurchaseResult.cs` to translate purchase outcomes to user-friendly messages
- Streamline and optimize purchase process in `TTT/Shop/Commands/BuyCommand.cs`
- Localize error messages and improve test setup in `TTT/Test/Shop/Commands/BuyTest.cs`
- Update `TTT/Shop/Shop.cs` to use localized messages and enhance error handling logic
2025-09-30 11:13:25 -07:00
MSWS
9dd4414733 Tweak restrictions on deagle config 2025-09-30 10:59:04 -07:00
MSWS
dce4edd6a4 feat: Make friendly fire configurable
```
- Introduce a new configuration variable in `CS2OneShotDeagleConfig.cs` to determine if the shooter should be killed upon friendly fire, and update the `Load` method accordingly.
- Add a static message `SHOP_ITEM_DEAGLE_HIT_FF` in `DeagleMsgs.cs` for handling new Deagle functionality messages.
- Rename "One-Hit Deagle" to "One-Hit Revolver" in `en.yml` and update description and messages for consistency.
- Refactor friendly fire logic in `DeagleDamageListener.cs` by integrating nested conditions and simplifying weapon verification logic for damage events.
- Add `KillShooterOnFF` configuration option in `OneShotDeagle.cs` to manage shooter consequences on friendly fire.
```
2025-09-30 10:57:22 -07:00
MSWS
324711acb9 Working deagle impl +semver:minor 2025-09-30 10:34:47 -07:00
MSWS
85ae2c4210 Add reverse cache to CCPlayerConverter 2025-09-30 09:52:12 -07:00
Isaac
2e6743c25d Miscelleaneous Tweaks
<p dir="auto">This pull request appears to be a development branch merge
 that implements several enhancements and fixes to the TTT (Trouble in 
Terrorist Town) game system. The changes focus on improving weapon 
handling, adding new test coverage, and enhancing player visual
effects.</p>
<ul dir="auto">
<li>Refactors weapon API by renaming <code class="notranslate">Id</code>
property to <code class="notranslate">WeaponId</code> for better
clarity</li>
<li>Implements comprehensive shop and weapon testing infrastructure</li>
<li>Adds screen color effects and player visual enhancements</li>
</ul>
<h3 dir="auto">Reviewed Changes</h3>
<p dir="auto">Copilot reviewed 32 out of 32 changed files in this pull
request and generated 2 comments.</p>
<details open="">
<summary>Show a summary per file</summary>
<markdown-accessiblity-table data-catalyst="">
File | Description
-- | --
TTT/API/IWeapon.cs | Renames weapon identifier property from Id to
WeaponId
TTT/Test/Shop/ShopTests.cs | Adds comprehensive test coverage for shop
functionality
TTT/Test/Shop/Items/DeagleTests.cs | Implements tests for one-shot
deagle weapon behavior
TTT/Test/TestPlayer.cs | Enhances test player with computed IsAlive
property
TTT/CS2/Player/CS2InventoryManager.cs | Adds weapon slot management and
refactors weapon handling
TTT/CS2/Extensions/PlayerExtensions.cs | Implements screen color fade
effects for players
TTT/CS2/Listeners/ScreenColorApplier.cs | Adds role-based screen color
feedback
TTT/Game/Roles/BaseWeapon.cs | Updates weapon class to use WeaponId
property
TTT/Shop/Items/OneShotDeagle/OneShotDeagle.cs | Updates deagle
implementation for new weapon API

</markdown-accessiblity-table></details>
2025-09-28 01:32:07 -07:00
Isaac
5ff27b37e5 Merge branch 'main' into dev 2025-09-28 01:29:38 -07:00
MSWS
1a4e5e3e77 +semver:minor 2025-09-28 01:24:45 -07:00
MSWS
721504f612 Debug out workflow +semver:patch 2025-09-28 01:19:57 -07:00
MSWS
86c24533b5 Test bumping +semver:patch 2025-09-28 01:15:39 -07:00
Isaac
eba49139c2 ci: Implement AI-driven changelog rewriting workflow +ratio (#59)
- Add environment variables and steps for OpenAI API usage in
`.github/workflows/release.yml`
- Retain raw changelog on AI rewrite failure and differentiate naming
- Introduce conditional logic for selective changelog rewriting
- Update GitHub release creation to utilize AI-rewritten changelog when
available
2025-09-28 01:05:24 -07:00
MSWS
d33550a5a4 ci: Enhance release workflow and changelog generation
- Add `fetch-tags: true` to actions/checkout in release workflow to ensure all tags are fetched during checkout.
- Improve tag determination process with lineage-aware strategy and refined pattern matching.
- Change changelog generation to use local git log for better control over commit messages.
- Enhance logic for finding commits for changelog, specifically handling first and subsequent releases.
- Improve error handling and retry mechanism for OpenAI API calls, and refine changelog rewrite logic with fallback strategies.
- Update comment styles for better clarity and organization.
2025-09-28 01:03:57 -07:00
MSWS
453ce77711 ci: Implement AI-driven changelog rewriting workflow +ratio
- Add environment variables and steps for OpenAI API usage in `.github/workflows/release.yml`
- Retain raw changelog on AI rewrite failure and differentiate naming
- Introduce conditional logic for selective changelog rewriting
- Update GitHub release creation to utilize AI-rewritten changelog when available
2025-09-28 00:58:21 -07:00
MSWS
b427dc370e refactor: Remove debug logs and adjust event priorities
- Remove debug logging statements and simplify service registration logic in `ServiceCollectionExtensions.cs`
- Adjust the event handler's priority in `RoundShopClearer.cs` without functional changes
- Update wording in `README.md` for clearer public API usage
- Modify event handler priority in `PlayerStatsTracker.cs` while maintaining existing functionality
- Streamline `IOnlinePlayer.cs` by removing obsolete commented-out code and refining interface properties
- Lower event handler priority in `PlayerActionsLogger.cs` for player kills
2025-09-28 00:46:44 -07:00
MSWS
ede9badbd9 Add additional unit tests for shop 2025-09-28 00:34:55 -07:00
MSWS
5736588484 refactor: Rename Id to WeaponId across the codebase
- Rename property `Id` to `WeaponId` in `IWeapon.cs`, `BaseWeapon.cs`, and `OneShotDeagle.cs` for improved clarity.
- Update weapon removal method in `IInventoryManager.cs` to use `weapon.WeaponId`.
- Refactor `PlayerDamagedEvent.cs` to initialize `Weapon` property with `init` for stricter immutability.
- Revise `IsAlive` logic in `TestPlayer.cs` to adjust `Health` based on `IsAlive` status; deprecate the `Roles` property.
- Add `using` directive and `[UsedImplicitly]` attribute to `DeagleDamageListener.cs` for dependency management and traceability.
- Develop `DeagleTests.cs` to ensure proper functionality of Deagle weapon behaviors using Xunit.
2025-09-28 00:16:28 -07:00
MSWS
8a894c65e8 refactor: Adjust player color handling logic
- Adjust the alpha value handling in `SetColor` method within `PlayerExtensions.cs` to ensure it stays within limits.
- Simplify player color setting in `RoundTimerListener.cs` by using `Color.White` for improved readability.
- Update `BodySpawner.cs` to change player post-death color to fully opaque white and simplify round start color setting using `Color.White`.
2025-09-27 20:30:07 -07:00
MSWS
0634af8ad8 feat: Add weapon slot removal functionality
- Fix typo in comment and clarify kill detection process in `PlayerStatsTracker.cs`
- Add `RemoveWeaponInSlot` method for slot-based weapon removal in `FakeInventoryManager.cs` and update `IInventoryManager.cs` for enhanced functionality
- Reformat `BaseWeapon` constructor for readability and standardize file formatting
- Simplify `CS2Body.cs` API by removing overloaded weapon method and reinforce `IWeapon` interface usage
- Refactor `CS2InventoryManager.cs` for improved weapon management, add methods for slot conversion and weapon removal, and streamline code structure
- Add debug messaging to `DeagleDamageListener.cs` for better runtime clarity on friendly fire and one-shot kill conditions
- Modify `BodySpawner.cs` to incorporate `BaseWeapon` wrapper for improved weapon management without affecting core functionality
- Adjust `OnPlayerKill` event handler priority in `PlayerActionsLogger.cs` to ensure kill logging before game ends
2025-09-27 20:25:53 -07:00
MSWS
9f6c3f7be4 Check player count on round start before starting 2025-09-27 19:07:28 -07:00
MSWS
9eb313e9f1 feat: Introduce screen color features and state command
```
Enhance game management and command structure with new features and optimizations

- Add logic in `PlayerJoinStarting.cs` to handle failure in game instance creation and ensure game starts only upon successful creation.
- Introduce IMessenger service in `CS2GameManager.cs` using dependency injection; add debug logging for the game creation process.
- Implement new behavior for `ScreenColorApplier` in `CS2ServiceCollection.cs` to enhance listening capabilities.
- Create a new `StateCommand` in `StateCommand.cs` to check active game state and implement basic command lifecycle methods.
- Remove "screentext" command and add "state" and "screencolor" commands in `TestCommand.cs` to revamp command options.
- Simplify vector operations in `TextSpawner.cs` by replacing `GetRightVector`; enhance screen text positioning.
- Expand `VectorExtensions.cs` with `ToRight` and `ToUp` methods for better angle-to-vector conversions.
- Remove `ScreenTextCommand.cs` to streamline project and potentially refactor screen text feature.
- Add `ScreenColorApplier` to apply screen color effects upon role assignment, enhancing player interaction experience.
- Introduce `ScreenColorCommand` for player screen color effects with configurable parameters, enriching command functionality.
```
2025-09-26 20:28:35 -07:00
MSWS
9b5563aa8e feat: Refactor text positioning and add screen fade effects
- Refactor `TextSpawner.cs` to improve angle calculations and text positioning with respect to the player.
- Replace static `screenAngle` with local computations for better clarity and maintainability in `TextSpawner.cs`.
- Introduce `angle` object in `TextSpawner.cs` to enhance readability and explicitness in rotation management.
- Add `FadeFlags` enum and implement `ColorScreen` method in `PlayerExtensions.cs` to manage screen color fade effects.
- Enhance color fade handling in `PlayerExtensions.cs` by utilizing `UserMessage` with custom flag settings and improved color configurations.
2025-09-26 18:47:18 -07:00
MSWS
2058d0c780 Start work on screen text 2025-09-26 18:29:59 -07:00
Isaac
ee7f34b435 Bump the nuget group with 1 update (#58)
Pinned System.Text.Json at 8.0.5.

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 <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/MSWS/TTT/network/alerts).

</details>
2025-09-26 18:00:40 -07:00
Isaac
783f6da6dd Merge branch 'main' into dependabot/nuget/Locale/nuget-9df58bc52d 2025-09-26 17:58:41 -07:00
MSWS
f245c61d01 AI is the future! 2025-09-25 22:18:41 -07:00
MSWS
b4076934d8 Fix yml? 2025-09-25 22:15:48 -07:00
MSWS
21b869507b Add GitVersion config, include gamedata in releases 2025-09-25 22:09:43 -07:00
dependabot[bot]
fca81c0577 Bump the nuget group with 1 update
Bumps System.Text.Json from 8.0.0 to 8.0.5

---
updated-dependencies:
- dependency-name: System.Text.Json
  dependency-version: 8.0.5
  dependency-type: direct:production
  dependency-group: nuget
- dependency-name: System.Text.Json
  dependency-version: 8.0.5
  dependency-type: direct:production
  dependency-group: nuget
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-26 04:40:30 +00:00
Isaac
db8fe8f069 Bug Fixes, Foundational Work for Shop and Karma (#57) 2025-09-25 21:37:10 -07:00
Isaac
dce6d759a8 Merge branch 'main' into dev 2025-09-25 21:26:55 -07:00
MSWS
f028074939 Tweak karma update interval 2025-09-25 21:26:34 -07:00
MSWS
1d96be0cb0 Remove verbose debug 2025-09-25 21:22:47 -07:00
MSWS
0cbb931aaa Additional buy test command 2025-09-25 21:22:22 -07:00
MSWS
6c2bd538a9 Fix buy tests 2025-09-25 21:20:58 -07:00
MSWS
6b0dcbd42f Resolve log-based test failures 2025-09-25 21:09:00 -07:00
MSWS
c512b60260 Reformat & Cleanup 2025-09-25 21:01:50 -07:00
MSWS
295f2bcad0 Fix compile error 2025-09-25 19:48:57 -07:00
MSWS
5b46fb1282 feat: Introduce player state spoofing feature
```
Implement player state spoofing and enhance body identification

- Introduce `CS2AliveSpoofer` class and `IAliveSpoofer` interface to manage "fake alive" player states in `CombatHandler` and `ForceAliveCommand`.
- Modify `BODY_IDENTIFIED` logic in `GameMsgs.cs` for nullable identifiers, providing a default "Someone" message when missing.
- Update `ForceAliveCommand` and `IdentifyAllCommand` to use new spoofing and identification utilities.
- Enhance body tracking with `BodyTracker` class, integrating event handling improvements for game state changes and body creation.
- Refine `OneShotDeagle` functionality by clearing player's inventory before assigning the weapon, improving game balance.
- Adjust `BodyPickupListener` to use `IBodyTracker` for efficient body management and consolidate event handling logic.
- Update various components to utilize dependency injection and new APIs, improving service management and system robustness.
```
2025-09-25 19:42:50 -07:00
MSWS
4b3d9335b5 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-09-25 16:36:57 -07:00
MSWS
ec48a9b243 Fix role formatting, pad names (resolves #52 & #56) 2025-09-25 16:36:47 -07:00
MSWS
254e5539b7 Fix role formatting (resolves #52) 2025-09-25 16:35:27 -07:00
MSWS
547228d09a Clarify name in combathandler 2025-09-25 16:23:43 -07:00
MSWS
99e4c6fc07 refactor: Refactor game logic (resolves #51)
- Modify `RoundBasedGame.cs` to improve encapsulation, consistency, and maintainability by refactoring game-ending logic and updating access modifiers for subclassing.
- Implement player data caching in `CS2Player.cs` to enhance performance and improve debug logging capabilities.
- Refactor message formatting in `CS2Messenger.cs` for improved consistency in debug modes.
- Enhance `PlayerConnectionsHandler.cs` by adding asynchronous behavior and a dependency on `IMessenger` for potential future enhancements.
- Add a validity check in `RoundTimerListener.cs` to ensure team scores are only updated with a defined winning role, improving robustness.
- Update `CS2Game.cs` to broadcast notifications for game start states and handle countdowns effectively.
- Introduce `CheckEndConditions()` method in `IGame.cs` interface and deprecate `IsInProgress()` to promote explicit state management.
- Centralize and simplify end game logic in `PlayerCausesEndListener.cs` by implementing `CheckEndConditions()`, eliminating redundant code.
2025-09-25 16:05:48 -07:00
MSWS
52b8d1d2ff refactor: Refactor player leave handling logic and tests (ref: #51)
- Rename test method `Round_EndsWhen_PlayerLeaves` to `Round_EndsWhen_PlayerLeavesAndDies` in `RoundEndingTest.cs` and add `PlayerDiesOnLeaveListener`.
- Improve code efficiency and readability in player iteration and event creation in `PlayerConnectionsHandler.cs`.
- Remove redundant console logging for player disconnections and streamline control flow in `disconnectFromServer` method in `PlayerConnectionsHandler.cs`.
- Move dispatching of `PlayerLeaveEvent` to the next world update for consistency in `PlayerConnectionsHandler.cs`.
2025-09-25 15:37:17 -07:00
MSWS
e901d82153 feat: Refactor spawn logic; add LateSpawnListener
- Reorder `AddModBehavior` entries in `CS2ServiceCollection.cs` for improved readability and logical grouping, adding `BodySpawner`, `DamageCanceler`, and `LateSpawnListener` earlier in their sections and maintaining order consistency by moving various handlers.
- Remove duplicated entries and ensure all necessary handlers and listeners are included in `CS2ServiceCollection.cs`.
- Add new class `LateSpawnListener` in `Listeners/LateSpawnListener.cs` to handle player join events, implementing a respawn mechanism for new players joining when the game is not in progress.
- Remove game state condition and deferred respawn logic in `PlayerConnectionsHandler.cs`, changing player respawn behavior upon joining the server.
2025-09-25 15:28:24 -07:00
MSWS
f56106f125 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-09-25 15:23:09 -07:00
MSWS
57660e0957 Fix kill listener priority conflicting with round states (resolves #55) 2025-09-25 15:23:03 -07:00
MSWS
1ecef5767f Fix kill listener priority conflicting with round states (resolves 55) 2025-09-25 15:22:40 -07:00
MSWS
d1359b79c0 feat: Introduce shop module with event-driven updates (fixes #54)
```
Integrate New Features and Enhance Codebase

- Add a new project reference to `CS2.csproj` for integration with the Shop project.
- Introduce a new configuration class `CS2ShopConfig` to manage shop settings and player interactions.
- Implement new player event handling with `PlayerPurchaseItemEvent` and `PlayerBalanceEvent`, enabling cancellable item purchases and balance updates.
- Enhance the `ShopServiceCollection` with new behaviors for extended functionality, including `RoleAssignCreditor`, `BuyCommand`, and `BalanceCommand`.
- Improve `Shop.cs` by replacing `IPlayer` references with string identifiers, introducing event-driven balance updates, and enhancing messaging logic.
- Comprehensive changes across multiple utilities and configurations to support new team score management and event-driven architecture.
```
2025-09-25 15:02:58 -07:00
Isaac
216d5a9d5a Update issue templates (#50) 2025-09-25 13:43:52 -07:00
Isaac
5d2bead09c Update issue templates 2025-09-25 13:42:42 -07:00
MSWS
a0ce6aa53e Additional cleaning up and unit tests 2025-09-25 08:01:42 -07:00
MSWS
cb626d7cfa Fix README typo 2025-09-24 23:54:26 -07:00
MSWS
d83ac95245 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-09-24 23:49:04 -07:00
MSWS
8db9b3154d Update licenses 2025-09-24 23:48:58 -07:00
Isaac
3abe6153e3 Feat/karma (#48) 2025-09-24 23:47:59 -07:00
MSWS
fc25405a81 Reorganize CS2ServiceCollection 2025-09-24 23:38:40 -07:00
MSWS
da3a94f3b7 Fix TTT/Plugin README link 2025-09-24 23:34:49 -07:00
MSWS
4bf7b0cd13 Merge dev 2025-09-24 23:29:16 -07:00
MSWS
758d3fe13c refactor: Refactor and clean up event and listener logic
Refactor and Simplify Codebase with Improved Readability and Efficiency

- **OneShotDeagle.cs:**
  - Remove event-related dependencies and streamline class to focus on core functionality.

- **PlayerKillListener.cs:**
  - Simplify `OnKill` method, preparing for future enhancements, and clean up unused code.

- **IListener.cs and IEventBus.cs:**
  - Remove `IDisposable` dependency from `IListener`. Add obsolescence message for `RegisterListener` in `IEventBus`.

- **LogsCommand.cs and TTTCommand.cs:**
  - Consolidate logic for game checking and logging, enhancing error handling and readability.

- **RoundTimerListener.cs and CombatHandler.cs:**
  - Refactor event handlers for clear separation of responsibilities and process optimization.

- **Various CS2 Handlers and Commands:**
  - Streamline and modularize event handling and role management with newly introduced helper methods across handlers.
  - Refactor command logic for improved organization and maintenance.

- **Locale/StringLocalizer.cs and EventBus.cs:**
  - Refactor string handling and listener registration for enhanced clarity and performance.
2025-09-24 23:27:05 -07:00
MSWS
9045913074 feat: Implement role management via dependency injection
```
- Simplify and enhance `PlayerActionsLogger.cs` by using pattern matching for game status checks and improve logging calls with a `Provider` parameter.
- Update `DeathAction.cs` to support dependency injection and role management by modifying constructors and formatting methods.
- Add role management in `FakeAction.cs` by introducing `PlayerRole` and `OtherRole` properties.
- Mark `IsGameActive` in `IGameManager.cs` as obsolete to guide towards direct game state checks.
- Modify logging in `BodyIdentifyLogger.cs` to use a `Provider` parameter for better context.
- Improve role management in `IdentifyBodyAction.cs` with new properties and constructor overloads supporting dependency injection.
- Refactor `ActionTest.cs` to accommodate constructor changes in `FakeAction`, ensuring backward compatibility.
- Expand `IAction` interface with role properties and enhance `Format` method.
- Add footer text in `en.yml` and `GameMsgs.cs` for clearer game log outputs.
- Enhance `DamagedAction.cs` with dependency injection and role properties, improving role management.
- Adjust `CombatHandler.cs` to refine player event handling and platform checks.
- Clear up documentation comments in `StringLocalizer.cs`.
- Enhance `SimpleLogger.cs` with role management and improved log formatting.
- Deprecate `IsInProgress()` in `IGame` for more explicit game state checks.
```
2025-09-24 20:04:22 -07:00
MSWS
8748401b6b Basic shop balance giving 2025-09-24 17:06:01 -07:00
MSWS
7d5218914f Merge branch 'dev' into feat/karma 2025-09-24 16:26:45 -07:00
MSWS
137144a052 Reformat Raytrace: 2025-09-24 16:22:00 -07:00
MSWS
61d7f667ff Reformat and cleanup 2025-09-23 18:11:46 -07:00
MSWS
f53c00c4d8 Reformat and cleanup 2025-09-23 18:10:51 -07:00
MSWS
3f5a675af1 Fix unit tests 2025-09-23 18:08:26 -07:00
MSWS
48ec384b38 Fix unit tests 2025-09-23 18:07:21 -07:00
MSWS
2edee31419 Fix EventBus impl 2025-09-23 17:59:18 -07:00
MSWS
d4006e5750 Resolve merge conflicts 2025-09-23 17:57:33 -07:00
MSWS
a1a37452ef refactor: Refactor round end logic and enhance message style.
- Enhance message styling in `en.yml` by adding grey color to `TASER_SCANNED` translation.
- Align logical flow in `RoundTimerListener.cs` by moving the remaining time check in `OnRoundEnd`.
- Clean up `RoundTimerListener.cs` by removing commented-out code related to `EventRoundEnd`.
- Maintain role setting and team switching functionality in `RoundTimerListener.cs` within `OnRoundEnd`.
- Adjust winning team logic and event firing in `RoundTimerListener.cs` based on end reason.
- Ensure correct round transitions in `RoundTimerListener.cs` using scheduled timing logic.
2025-09-23 17:38:03 -07:00
MSWS
d9f002febe Fix body systems 2025-09-23 17:20:26 -07:00
MSWS
26cca670ee Add gamedata 2025-09-23 16:46:51 -07:00
MSWS
cafd050a85 Remove debugs 2025-09-23 16:39:22 -07:00
MSWS
a28c3aa0dd Overhaul raytracing 2025-09-23 13:04:40 -07:00
MSWS
2918a9965d Update raytrace sigs 2025-09-23 12:42:17 -07:00
MSWS
b57630b899 feat: Add taser scan message and role assignment logic
- Add a new translation entry for "TASER_SCANNED" in TTT/CS2/lang/en.yml, ensuring a dynamic message format.
- Enhance TTT/Game/Listeners/BaseListener.cs with dependencies for role assignment and message localization.
- Refactor TTT/Game/Events/Player/PlayerDamagedEvent.cs to improve attacker retrieval logic and robustness.
- Improve TTT/Game/lang/GameMsgs.cs by extracting role prefix determination into a separate method for clarity.
- Introduce new methods and directives in TTT/CS2/lang/CS2Msgs.cs for better integration with TTT API and improved message clarity.
- Update TTT/CS2/GameHandlers/DamageCancelers/TaserListenCanceler.cs to refine event handling logic with taser-specific enhancements.
2025-09-23 12:38:38 -07:00
MSWS
65c12696ed Debug compile on dev 2025-09-23 12:09:57 -07:00
MSWS
3206c30078 Debug 2025-09-23 12:04:04 -07:00
MSWS
f9f0c4e954 Fix failing tests 2025-09-16 21:33:01 -07:00
MSWS
45f492e44e Resolve initial merge conflicts 2025-09-16 21:30:34 -07:00
MSWS
c6f45276c3 refactor: Refactor damage handlers to use events +semver:minor
```
- Add OutOfRoundCanceler and TaserListenCanceler classes for improved damage cancellation in specific scenarios
- Mark RegisterListener method in IEventBus as obsolete
- Update ShopServiceCollection to remove generic type parameter from ShopCommand addition
- Change color representation for DetectiveRole in GameMsgs to DarkBlue
- Enhance ServiceCollectionExtensions with transient service registration and ICommand type handling
- Transition DamageCanceler to an event-driven architecture for improved flexibility
- Allow Player property in PlayerEvent to be set during initialization
- Register new damage cancelers in CS2ServiceCollection and simplify command service addition
- Refactor RoleIconsHandler to improve icon management and refine role assignments
- Update PlayerDamagedEvent for dynamic initialization and error handling
- Remove excessive "Respawning..." message from PlayerConnectionsHandler
- Narrow ShopCommand registration to only the "buy" subcommand
```
2025-09-16 21:20:51 -07:00
MSWS
9eef949501 refactor: Refactor module and listener loading logic
```
Refactor and enhance module management and logging across multiple components

- Update `TTT.cs` to differentiate between base and plugin modules during loading, improve logging for module operations, and revise initialization and activation of plugin modules.
- Enhance debugging and registration in `ServiceCollectionExtensions.cs` by adding diagnostic logs and ensuring proper registration of plugin modules and listeners with transient lifetimes.
- Remove redundant `Name` property from multiple logger and listener classes (`PlayerActionsLogger.cs`, `BodyIdentifyLogger.cs`, and `PlayerCausesEndListener.cs`), cleaning up unused code and simplifying logic for handling game-related events.
- Improve event dispatching efficiency in `EventBus.cs` by optimizing handler checks, and update DEBUG logging to handle nullability issues.
- Simplify `DamageCanceler.cs` by removing incorrect interface implementation and clarifying constructor and method usage.
```
2025-09-16 20:40:13 -07:00
MSWS
f1c6a784d1 refactor: Refactor codebase to remove Name and Version properties
Refactor Codebase for Simplification and Improved Modularization

- **RoundEndHandler.cs**
  - Removed `Name` and `Version` properties to simplify the class.
  - Maintained functionality for handling end-of-round events.

- **BaseListener.cs**
  - Removed `ITerrorModule` interface implementation and unnecessary properties.
  - Updated `Start` method to change listener lifecycle management.

- **CS2GameConfig.cs**
  - Simplified by removing `Name` and `Version` properties, focusing solely on game parameters.

- **GameServiceCollection.cs**
  - Changed listener addition method from `AddListener` to `AddModBehavior`, updated service registration terms.

- **DamageCanceler.cs**
  - Simplified class by removing `Name` and `Version` properties.
  - Enhanced damage processing with additional validity checks.

- Further updates include transitioning from `AddListener` to `AddModBehavior` across files, deprecating old registration methods in `EventBus.cs`, and comprehensive removal of `Name` and `Version` properties from various classes to streamline and refactor code structure. Additionally, obsolete methods were removed, and dependency injection patterns were adopted for intuitive system integration.
2025-09-16 19:53:21 -07:00
MSWS
112422e479 Add debug code to events 2025-09-11 18:01:40 -07:00
MSWS
6abdce7246 Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-09-11 12:51:38 -07:00
MSWS
d3a021f40b Fix init loop 2025-09-11 12:51:27 -07:00
Isaac
f657599a0e Add core TTT shop system with commands and One-Shot Deagle item (#49) 2025-09-11 11:24:49 -07:00
Isaac
4d66afaec9 Update TTT/Test/Shop/Commands/BuyTest.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-09-11 11:22:30 -07:00
Isaac
0667652ed4 Update TTT/Shop/Items/OneShotDeagle/DeagleDamageListener.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-09-11 11:21:55 -07:00
MSWS
b41092fd69 feat: Refactor purchase logic and add BuyCommand tests
```plaintext
Implement comprehensive testing and enhance purchase logic

- Add `BuyTest` class to thoroughly test `BuyCommand` in the shop, covering various scenarios and ensuring correct game rule validation.
- Modify `OneShotDeagle`'s `CanPurchase` method to return a `PurchaseResult` enum for detailed purchasing results.
- Update `IShopItem` interface's `CanPurchase` method signature to use `PurchaseResult` for consistent result handling.
- Add `TestShopItem` class implementing the `IShopItem` interface, complete with properties, methods, and a successful `CanPurchase` implementation for testing.
- Improve `TestMessenger` with a null check for the player parameter and message logging for null player scenarios.
- Move `PurchaseResult.cs` to a new directory within the `Shop` folder for better organization.
- Refactor `CommandManagerTests` to use `ICommandManager` interface, ensuring interface-based testing without functional changes.
- Enhance `BuyCommand` with new aliases, asynchronous `Execute` method, and improved transaction logic, including balance checks and item search refactor.
```
2025-09-11 11:17:40 -07:00
MSWS
cc345ac010 Merge branch 'feat/karma' of github.com:MSWS/TTT into feat/karma 2025-09-09 15:24:29 -07:00
MSWS
fa1d732724 test: Refactor tests and cleanup PropMover code
- Await the `bus.Dispatch(deathEvent)` call in `OnKill_WithoutGame_DoesNothing` test.
- Remove unused import and eliminate the unused `IMessenger` component in `PropMover.cs`.
- Rename `refreshBodies` method to `refreshBody` for clarity in `PropMover.cs`.
- Refactor the iteration over `playersPressingE` to call the updated method in `PropMover.cs`.
- Enhance code readability in `PropMover.cs` through minor code style improvements, including removal of unnecessary exclamation points.
2025-09-09 15:24:23 -07:00
MSWS
4d5109b6be test: Additional unit tests regarding karma stacking 2025-09-09 15:24:23 -07:00
MSWS
00970f6789 feat: Refactor handlers and add KarmaSyncer feature
- Rename `RoundStartHandler` to `RoundStart_GameStartHandler` and update `Dispose()` method in `RoundStartHandler.cs`
- Rename `RoundEndHandler` to `RoundEnd_GameEndHandler` in `RoundEndHandler.cs`
- Update target framework to .NET 8.0 and add project reference to Karma project in `CS2.csproj`
- Update service collection for specific game start/end handlers and add plugin for player karma in `CS2ServiceCollection.cs`
- Introduce `KarmaSyncer` class for handling player karma with appropriate dependencies and event handling in `KarmaSyncer.cs`
2025-09-09 15:24:23 -07:00
MSWS
29d2e8a46c Format & Cleanup 2025-09-09 15:24:22 -07:00
MSWS
1d6526730a All unit tests passing 2025-09-09 15:24:22 -07:00
MSWS
98dc08c667 Overhaul event bus to support async listeners 2025-09-09 15:24:22 -07:00
MSWS
4a50d662af test: Refactor karma handling and enhance test coverage
```
- Remove `KarmaTest.cs`, eliminating a test case for default player karma verification upon creation.
- Introduce `KarmaListenerTests.cs` file, laying the groundwork for future KarmaListener test cases.
- Adjust `KeyedMemoryStorage.cs` to enable subclass access and method overriding by changing `data` dictionary to protected and marking `Load` and `Write` methods as virtual.
- Update `MemoryKarmaStorage.cs` with `Xunit.Internal` import, modify generic type parameter to `int`, refine code with target-typed `new()`, and override `Load` method with default karma value handling.
- Refactor `KarmaStorage.cs` to batch process karma updates asynchronously, simplify default karma handling, enhance error management, and refine karma caching.
```
2025-09-09 15:24:22 -07:00
MSWS
45727da462 Start work on adding unit testing 2025-09-09 15:24:22 -07:00
MSWS
fc2104e71a feat: Introduce Karma module with DI and refactoring
```
- Add `KarmaServiceCollection` for dependency injection setup, facilitating the registration of `IKarmaService` with scoped lifetime.
- Update `TTTServiceCollection` to include new services for Karma management and necessary game services.
- Refactor `KarmaStorage` to implement `IKarmaService`, simplifying interface responsibilities and removing previous interface implementations.
- Configure `Plugin.csproj` with .NET 8.0, implicit usings, nullable reference types, and setup publish output handling.
- Introduce `IKarmaService` interface to streamline access and interaction with karma functionalities.
- Create `KarmaListener` class for managing karma adjustments during game events, implementing event handling and asynchronous tasks.
```
2025-09-09 15:24:22 -07:00
MSWS
375108dd85 Remove unnecessary null check 2025-09-09 15:24:22 -07:00
MSWS
aded3fb6a2 feat: Introduce Karma management system
- Create a new KarmaStorage class to handle player karma with MySQL and caching
- Add the Karma project file with .NET 8.0 target and necessary references
- Include the Karma project in TTT.sln with Debug and Release configurations
- Define a Karma configuration file with database and karma settings
- Introduce a KarmaUpdateEvent class for managing player karma updates with event cancellation support
2025-09-09 15:24:22 -07:00
MSWS
519578dcd9 Merge branch 'feat/shop' of github.com:MSWS/TTT into feat/shop 2025-09-09 15:24:10 -07:00
MSWS
2ebc25a692 refactor: Add Skip method across command classes
- Add a `Skip` method to `CS2CommandInfo` for argument skipping
- Rename `sub` to `subcommands` in `ShopCommand` for clarity and update execution logic
- Make `caller` parameter nullable in `TestCommandInfo` and introduce `Skip` method for better argument handling
- Add `Skip` method to `ICommandInfo` interface for consistent argument skipping functionality
2025-09-09 15:24:03 -07:00
MSWS
1810bd1473 feat: Add shop buy command 2025-09-09 15:24:03 -07:00
MSWS
8ea14e7960 Register services 2025-09-09 15:24:03 -07:00
MSWS
3dc3cd08f4 Manually copy over old work of shop command 2025-09-09 15:24:03 -07:00
MSWS
78e0b64bb3 refactor: Move classes into proper dirs 2025-09-09 15:24:03 -07:00
MSWS
5977d87216 Remove unused test 2025-09-09 15:23:53 -07:00
MSWS
8cdb19f23c refactor: Add Skip method across command classes
- Add a `Skip` method to `CS2CommandInfo` for argument skipping
- Rename `sub` to `subcommands` in `ShopCommand` for clarity and update execution logic
- Make `caller` parameter nullable in `TestCommandInfo` and introduce `Skip` method for better argument handling
- Add `Skip` method to `ICommandInfo` interface for consistent argument skipping functionality
2025-09-09 15:21:08 -07:00
MSWS
a44b5b00a2 feat: Add shop buy command 2025-09-09 14:56:31 -07:00
MSWS
352de1f667 Register services 2025-09-09 11:31:35 -07:00
MSWS
1b8d201567 Manually copy over old work of shop command 2025-09-09 11:28:40 -07:00
MSWS
f753cb01c4 refactor: Move classes into proper dirs 2025-09-09 11:26:08 -07:00
MSWS
529af8c776 test: Refactor tests and cleanup PropMover code
- Await the `bus.Dispatch(deathEvent)` call in `OnKill_WithoutGame_DoesNothing` test.
- Remove unused import and eliminate the unused `IMessenger` component in `PropMover.cs`.
- Rename `refreshBodies` method to `refreshBody` for clarity in `PropMover.cs`.
- Refactor the iteration over `playersPressingE` to call the updated method in `PropMover.cs`.
- Enhance code readability in `PropMover.cs` through minor code style improvements, including removal of unnecessary exclamation points.
2025-09-09 11:07:15 -07:00
MSWS
6016f62931 test: Additional unit tests regarding karma stacking 2025-09-09 11:02:30 -07:00
MSWS
50f5a835de feat: Refactor handlers and add KarmaSyncer feature
- Rename `RoundStartHandler` to `RoundStart_GameStartHandler` and update `Dispose()` method in `RoundStartHandler.cs`
- Rename `RoundEndHandler` to `RoundEnd_GameEndHandler` in `RoundEndHandler.cs`
- Update target framework to .NET 8.0 and add project reference to Karma project in `CS2.csproj`
- Update service collection for specific game start/end handlers and add plugin for player karma in `CS2ServiceCollection.cs`
- Introduce `KarmaSyncer` class for handling player karma with appropriate dependencies and event handling in `KarmaSyncer.cs`
2025-09-09 10:47:59 -07:00
MSWS
46104f142f Format & Cleanup 2025-09-09 10:37:47 -07:00
MSWS
6b7d89dbf0 All unit tests passing 2025-09-09 10:32:02 -07:00
Isaac
332b6e6501 build(deps): Bump actions/setup-dotnet from 4 to 5 (#46)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-dotnet/releases">actions/setup-dotnet's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<h3>Breaking Changes</h3>
<ul>
<li>Upgrade to Node.js 24 and modernize async usage by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/654">actions/setup-dotnet#654</a></li>
</ul>
<p>Make sure your runner is updated to this version or newer to use this
release. v2.327.1 <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<h3>Dependency Updates</h3>
<ul>
<li>Upgrade <code>@​action/cache</code> from 4.0.2 to 4.0.3 by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/622">actions/setup-dotnet#622</a></li>
<li>Upgrade husky from 8.0.3 to 9.1.7 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/591">actions/setup-dotnet#591</a></li>
<li>Upgrade <code>@​actions/glob</code> from 0.4.0 to 0.5.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/594">actions/setup-dotnet#594</a></li>
<li>Upgrade eslint-config-prettier from 9.1.0 to 10.1.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/639">actions/setup-dotnet#639</a></li>
<li>Upgrade undici from 5.28.5 to 5.29.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/641">actions/setup-dotnet#641</a></li>
<li>Upgrade form-data to bring in fix for critical vulnerability by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-dotnet/pull/652">actions/setup-dotnet#652</a></li>
<li>Upgrade actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/662">actions/setup-dotnet#662</a></li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Remove Support for older .NET Versions and Update installers scripts
by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-dotnet/pull/647">actions/setup-dotnet#647</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/647">actions/setup-dotnet#647</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/654">actions/setup-dotnet#654</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-dotnet/compare/v4...v5.0.0">https://github.com/actions/setup-dotnet/compare/v4...v5.0.0</a></p>
<h2>v4.3.1</h2>
<h2>What's Changed</h2>
<ul>
<li><code>v4</code> - Remove <code>azureedge.net</code> fallback logic
and update install scripts by <a
href="https://github.com/zaataylor"><code>@​zaataylor</code></a> in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/572">actions/setup-dotnet#572</a>
As outlined in<a
href="https://devblogs.microsoft.com/dotnet/critical-dotnet-install-links-are-changing/#call-to-action">
Critical .NET Install Links Are Changing</a>, remove the storage account
fallback logic added for v4 in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/566">actions/setup-dotnet#566</a>
and update the install scripts accordingly.
<strong>Related issue</strong>: <a
href="https://redirect.github.com/dotnet/install-scripts/issues/559">dotnet/install-scripts#559</a></li>
<li>upgrade <code>@​actions/cache</code> to 4.0.2 by <a
href="https://github.com/HarithaVattikuti"><code>@​HarithaVattikuti</code></a>
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/615">actions/setup-dotnet#615</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-dotnet/compare/v4...v4.3.1">https://github.com/actions/setup-dotnet/compare/v4...v4.3.1</a></p>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>README update - add permissions section by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/587">actions/setup-dotnet#587</a></li>
<li>Configure Dependabot settings by <a
href="https://github.com/HarithaVattikuti"><code>@​HarithaVattikuti</code></a>
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/585">actions/setup-dotnet#585</a></li>
<li>Upgrade <strong>cache</strong> from 3.2.4 to 4.0.0 by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/586">actions/setup-dotnet#586</a></li>
<li>Upgrade <strong>actions/publish-immutable-action</strong> from 0.0.3
to 0.0.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/590">actions/setup-dotnet#590</a></li>
<li>Upgrade <strong><code>@​actions/http-client</code></strong> from
2.2.1 to 2.2.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/592">actions/setup-dotnet#592</a></li>
<li>Upgrade <strong>undici</strong> from 5.28.4 to 5.28.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/596">actions/setup-dotnet#596</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/benwells"><code>@​benwells</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/587">actions/setup-dotnet#587</a></li>
<li><a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-dotnet/pull/586">actions/setup-dotnet#586</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d4c94342e5"><code>d4c9434</code></a>
Update to Node.js 24 and modernize async usage (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/654">#654</a>)</li>
<li><a
href="5c125af7da"><code>5c125af</code></a>
Bump actions/checkout from 4 to 5 (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/662">#662</a>)</li>
<li><a
href="87c6e11776"><code>87c6e11</code></a>
Bumps form-data (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/652">#652</a>)</li>
<li><a
href="06a5327ecf"><code>06a5327</code></a>
Bump undici from 5.28.5 to 5.29.0 (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/641">#641</a>)</li>
<li><a
href="e8e5b8203e"><code>e8e5b82</code></a>
Bump eslint-config-prettier from 9.1.0 to 10.1.5 (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/639">#639</a>)</li>
<li><a
href="bf4cd79173"><code>bf4cd79</code></a>
Bump <code>@​actions/glob</code> from 0.4.0 to 0.5.0 (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/594">#594</a>)</li>
<li><a
href="4ddad1c881"><code>4ddad1c</code></a>
Bump husky from 8.0.3 to 9.1.7 (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/591">#591</a>)</li>
<li><a
href="0f55b457d2"><code>0f55b45</code></a>
removes end-of-line dotnet versions (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/647">#647</a>)</li>
<li><a
href="267870a9c4"><code>267870a</code></a>
upgrade actions/cache to 4.0.3 (<a
href="https://redirect.github.com/actions/setup-dotnet/issues/622">#622</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/setup-dotnet/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-dotnet&package-manager=github_actions&previous-version=4&new-version=5)](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)


</details>
2025-09-09 09:08:32 -07:00
MSWS
8c385934b3 Overhaul event bus to support async listeners 2025-09-09 09:04:54 -07:00
MSWS
04f79551f7 test: Refactor karma handling and enhance test coverage
```
- Remove `KarmaTest.cs`, eliminating a test case for default player karma verification upon creation.
- Introduce `KarmaListenerTests.cs` file, laying the groundwork for future KarmaListener test cases.
- Adjust `KeyedMemoryStorage.cs` to enable subclass access and method overriding by changing `data` dictionary to protected and marking `Load` and `Write` methods as virtual.
- Update `MemoryKarmaStorage.cs` with `Xunit.Internal` import, modify generic type parameter to `int`, refine code with target-typed `new()`, and override `Load` method with default karma value handling.
- Refactor `KarmaStorage.cs` to batch process karma updates asynchronously, simplify default karma handling, enhance error management, and refine karma caching.
```
2025-09-09 08:19:56 -07:00
MSWS
b08f9234ff Start work on adding unit testing 2025-09-08 21:22:36 -07:00
MSWS
87b83edb55 feat: Introduce Karma module with DI and refactoring
```
- Add `KarmaServiceCollection` for dependency injection setup, facilitating the registration of `IKarmaService` with scoped lifetime.
- Update `TTTServiceCollection` to include new services for Karma management and necessary game services.
- Refactor `KarmaStorage` to implement `IKarmaService`, simplifying interface responsibilities and removing previous interface implementations.
- Configure `Plugin.csproj` with .NET 8.0, implicit usings, nullable reference types, and setup publish output handling.
- Introduce `IKarmaService` interface to streamline access and interaction with karma functionalities.
- Create `KarmaListener` class for managing karma adjustments during game events, implementing event handling and asynchronous tasks.
```
2025-09-08 20:42:02 -07:00
dependabot[bot]
de7639d986 build(deps): Bump actions/setup-dotnet from 4 to 5
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4 to 5.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 00:34:50 +00:00
MSWS
a90e33b69d Remove unnecessary null check 2025-08-19 03:10:58 -07:00
MSWS
700074b130 feat: Introduce Karma management system
- Create a new KarmaStorage class to handle player karma with MySQL and caching
- Add the Karma project file with .NET 8.0 target and necessary references
- Include the Karma project in TTT.sln with Debug and Release configurations
- Define a Karma configuration file with database and karma settings
- Introduce a KarmaUpdateEvent class for managing player karma updates with event cancellation support
2025-08-19 03:09:59 -07:00
Isaac
6c06071d8a PlayerPawn -> Pawn, added DamageCanceler 2025-08-19 02:14:04 -07:00
MSWS
d89c70c41e Fix compilation error 2025-08-19 02:10:19 -07:00
Isaac
58012cb112 Update TTT/Game/Actions/DamagedAction.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <git@msws.xyz>
2025-08-19 02:08:16 -07:00
Isaac
febf34fcda build(deps): Bump actions/checkout from 4 to 5 (#44)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to
5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
<li>Prepare release v4.3.0 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2237">actions/checkout#2237</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/motss"><code>@​motss</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li><a href="https://github.com/mouismail"><code>@​mouismail</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li><a href="https://github.com/benwells"><code>@​benwells</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v4.3.0">https://github.com/actions/checkout/compare/v4...v4.3.0</a></p>
<h2>v4.2.2</h2>
<h2>What's Changed</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4.2.1...v4.2.2">https://github.com/actions/checkout/compare/v4.2.1...v4.2.2</a></p>
<h2>v4.2.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Jcambass"><code>@​Jcambass</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1919">actions/checkout#1919</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4.2.0...v4.2.1">https://github.com/actions/checkout/compare/v4.2.0...v4.2.1</a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be
<code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="08c6903cd8"><code>08c6903</code></a>
Prepare v5.0.0 release (<a
href="https://redirect.github.com/actions/checkout/issues/2238">#2238</a>)</li>
<li><a
href="9f265659d3"><code>9f26565</code></a>
Update actions checkout to use node 24 (<a
href="https://redirect.github.com/actions/checkout/issues/2226">#2226</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4&new-version=5)](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)


</details>
2025-08-19 02:05:21 -07:00
Isaac
44dafdd606 build(deps): Bump softprops/action-gh-release from 1 to 2 (#45)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 1 to 2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's
releases</a>.</em></p>
<blockquote>
<h2>v2.0.0</h2>
<ul>
<li>update actions.yml declaration to node20 to address warnings</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's
changelog</a>.</em></p>
<blockquote>
<h2>0.1.12</h2>
<ul>
<li>fix bug leading to empty strings subsituted for inputs users don't
provide breaking api calls <a
href="https://redirect.github.com/softprops/action-gh-release/pull/144">#144</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="72f2c25fcb"><code>72f2c25</code></a>
release 2.3.2</li>
<li><a
href="552dc5524b"><code>552dc55</code></a>
fix: revert <code>fs:readableWebStream</code> change (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/632">#632</a>)</li>
<li><a
href="f3cad8bcbf"><code>f3cad8b</code></a>
release 2.3.1</li>
<li><a
href="07a2257003"><code>07a2257</code></a>
fix: fix file closing issue (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/629">#629</a>)</li>
<li><a
href="d5382d3e6f"><code>d5382d3</code></a>
release 2.3.0</li>
<li><a
href="a0e2122208"><code>a0e2122</code></a>
feat: migrate from jest to vitest (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/626">#626</a>)</li>
<li><a
href="8836085300"><code>8836085</code></a>
chore: replace <code>mime</code> with <code>mime-types</code> (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/624">#624</a>)</li>
<li><a
href="86463358d8"><code>8646335</code></a>
chore: bump node to 20.19.2</li>
<li><a
href="46b284799f"><code>46b2847</code></a>
chore(deps): bump the npm group across 1 directory with 5 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/623">#623</a>)</li>
<li><a
href="37fd9d0351"><code>37fd9d0</code></a>
chore(deps): bump undici from 5.28.5 to 5.29.0 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/621">#621</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/softprops/action-gh-release/compare/v1...v2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=softprops/action-gh-release&package-manager=github_actions&previous-version=1&new-version=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)


</details>
2025-08-19 02:04:50 -07:00
dependabot[bot]
330db6aef1 build(deps): Bump softprops/action-gh-release from 1 to 2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '2'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 01:15:03 +00:00
dependabot[bot]
cddfdf3ebc build(deps): Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 01:14:28 +00:00
MSWS
deb0d2e825 feat: Refactor death action and add client event notification
```
- Update player death description in DeathAction to ensure clarity in scenarios involving a killer.
- Add Format method in DeathAction for structured death action descriptions.
- Implement client event notification in CombatHandler with conditional checks for attacker presence.
- Remove role initialization constructor in CS2Player to streamline code and refactor formatting.
```
2025-08-14 01:44:38 -07:00
MSWS
089564c4d6 feat: Differentiate win results and update role icons
- Adjust the logic in `RoundTimerListener.cs` to set final event results based on the winning team, assigning 2 for Counter-Terrorist wins and 3 for others, and refine win panel settings.
- Update `README.md` to reflect completed statuses for "Basic Gameplay," including the subcategories Traitors, Detectives, and Innocents, showcasing project progress.
- Reorder operations in `PlayerStatsTracker.cs` to update `PawnIsAlive` earlier in the `revealDeaths` method for clarity and consistent player state updates.
- Expand `RoleIconsHandler.cs` by adding `RevealIconFor` and `HideIconFor` methods to enhance control over traitor visual representation, allowing dynamic updates of player roles.
2025-08-14 01:31:45 -07:00
MSWS
871f47376a refactor: Improve state management and enhance role interactions
```
- Refine game start logic in RoundBasedGame.cs to ensure proper handling of game states and manage player notifications.
- Adjust state management and disposal process in RoundBasedGame.cs for better state handling and resource cleanup.
- Comment out deprecated EventRoundEnd logic in RoundTimerListener.cs and adjust timer settings for improved round transitions.
- Enhance BodyPickupListener.cs with new dependencies and logic for team adjustments during OnPropPickup events.
- Clean up PropMover.cs by removing unnecessary debug logging while maintaining current functionality.
```
2025-08-14 01:04:18 -07:00
MSWS
7621d15bcc feat: Improve round end handling and player status tracking
- Introduce a server command for handling win conditions during round end in `RoundTimerListener.cs`
- Wrap round end logic processing within a server update block in `RoundTimerListener.cs`
- Improve timing logic for round endings using `Observable.Timer` in `RoundTimerListener.cs`
- Ensure events/messages indicate the winner and specifics in `RoundTimerListener.cs`
- Update `PlayerStatsTracker.cs` to enhance pawn alive state tracking and accuracy
2025-08-14 00:42:33 -07:00
MSWS
a0111b5bea refactor: Refactor role logic and refine round timing events
- Modify `GameMsgs.cs` to enhance role identification through improved color coding and type checking for roles.
- Update `RoundTimerListener.cs` to incorporate reactive programming, improve event handling at round end, and refine role assignment logic.
- Enhance version string format in `TTTCommand.cs` by adding a short Git SHA for detailed version information.
- Simplify `EndRound` function in `RoundUtil.cs` by removing unnecessary delay parameter.
2025-08-14 00:33:43 -07:00
MSWS
14c4c85cfd refactor: Refactor connection and add pluralization tests
- Reorganize `connectToServer` method in `PlayerConnectionsHandler.cs` to delay certain operations until the next world update.
- Add player validity check before printing respawn chat message and update respawn logic to occur during the next world update in `PlayerConnectionsHandler.cs`.
- Consolidate respawn message to a generic "Respawning..." in `PlayerConnectionsHandler.cs`.
- Add new test cases in `ColoredRoleTest.cs` to verify pluralization functionality for role names, including special character handling.
- Ensure `HandlePluralization` method in `ColoredRoleTest.cs` correctly manages singular and plural forms with color formatting and dashes.
2025-08-13 23:41:32 -07:00
MSWS
e2383c90a8 fix: Invert game state check in OnDeath handler +semver:patch
- Correct logic in the `OnDeath` event handler by inverting the condition for an active game state check in `TTT/CS2/GameHandlers/BodySpawner.cs`
- Optimize function implementations including `makeGameRagdoll` and `correctRagdoll` in `TTT/CS2/GameHandlers/BodySpawner.cs`
2025-08-13 22:33:56 -07:00
MSWS
9db57d726d ci: Add webhook trigger for GitLab pipeline in nightly build
- Add `post_webhook` job to nightly workflow to trigger GitLab pipeline on `dev` branch
2025-08-13 22:14:18 -07:00
MSWS
47e63bf686 feat: Reuse active game in WAITING state +semver:patch
- Add condition in CS2GameManager to reuse active game if in WAITING state
2025-08-13 22:12:06 -07:00
MSWS
8835a76e67 feat: Enhance game state handling and player feedback
- Add `IGameManager` dependency to `PlayerConnectionsHandler.cs` for enhanced game state management
- Modify `connectToServer` in `PlayerConnectionsHandler.cs` to handle game states and improve player reconnection experience
- Update `DamageCanceler.cs` to improve conditional logic handling during active games
- Simplify player respawn logic and round handling in `RoundTimerListener.cs` by removing `PawnIsAlive` state manipulation and streamlining round start procedures
2025-08-13 20:45:08 -07:00
MSWS
731f58755d feat: Implement damage canceler and refine game logic
```
- Modify `RoundTimerListener` to reorder service initialization
- Add `TTT.API.Game` dependency to `BodySpawner` and improve game state checks and player handling upon death
- Reorder initialization logic in `SimpleLogger` for improved readability
- Introduce `GAME_LOGS_HEADER` and refactor message handling in `GameMsgs`
- Group minor organizational code changes across multiple files, including removing unused imports and restructuring logic for consistency
```
2025-08-13 20:01:48 -07:00
MSWS
824993fb16 refactor: Refactor 'PlayerPawn' references to 'Pawn' +semver:minor
- Improve error handling and modify references from `PlayerPawn` to `Pawn` in `BodySpawner.cs` to enhance robustness and reflect changes in the player object model.
- Update logic in `SimpleLogger.cs` to correctly set the `epoch` variable when the `timestamp` is smaller, fixing potential update issues.
- Refactor `PlayerExtensions.cs` for consistency by renaming variables from `PlayerPawn` to `Pawn` and ensure updated variable usage across player activities.
- Rename member from `PlayerPawn` to `Pawn` in `CS2InventoryManager.cs` to align with updated player data model and improve clarity.
- Update `TextSpawner.cs` references from `PlayerPawn` to `Pawn` for consistency and refactor list handling for better code alignment with new player data access method.
- Simplify `CombatHandler.cs` by changing references to `Pawn`, adjusting health updates, and improving code clarity for handling player events.
- Simplify and improve readability in `CS2Player.cs` by changing how player properties are accessed and set, maintaining debugging capabilities.
2025-08-13 18:38:43 -07:00
MSWS
6a67eb1141 Merge branch 'main' of github.com:MSWS/TTT 2025-08-13 10:55:09 -07:00
MSWS
670643998e Merge branch 'dev' 2025-08-13 10:55:03 -07:00
MSWS
70e2b44941 ci: Update workflows to use full semantic versioning
- Update `.github/workflows/release.yml` to use full semantic version (`fullSemVer`) in workflow steps
2025-08-13 10:52:59 -07:00
Isaac
c5cd646bee feat: Add PlayerStatsTracker and enhance game logic (#42)
- Implement `PlayerStatsTracker` to monitor player statistics using
dependency injection and event handlers for tracking kills, deaths, and
assists.
- Update `CS2ServiceCollection` to add `PlayerStatsTracker` listener for
enhanced player statistics tracking.
- Modify `RoundTimerListener` to incorporate player color settings at
round start and ensure proper player state updates.
- Enhance `CombatHandler` with game activity checks in
`OnPlayerDeath_Pre` and `OnPlayerHurt` methods to ensure efficient and
correct handling of game operations.
2025-08-13 10:49:12 -07:00
MSWS
223daa1085 feat: Add PlayerStatsTracker and enhance game logic
- Implement `PlayerStatsTracker` to monitor player statistics using dependency injection and event handlers for tracking kills, deaths, and assists.
- Update `CS2ServiceCollection` to add `PlayerStatsTracker` listener for enhanced player statistics tracking.
- Modify `RoundTimerListener` to incorporate player color settings at round start and ensure proper player state updates.
- Enhance `CombatHandler` with game activity checks in `OnPlayerDeath_Pre` and `OnPlayerHurt` methods to ensure efficient and correct handling of game operations.
2025-08-13 10:32:39 -07:00
MSWS
fbda4fe38b Merge branch 'dev' 2025-08-13 10:01:35 -07:00
MSWS
a663e556f9 ci: Simplify artifact zipping in release workflow
- Simplify artifact zipping process in release workflow by changing working directory to `build/TTT` before zipping.
2025-08-13 10:00:26 -07:00
Isaac
49d45a12b9 Refactor CS2 roles to use localization for coloring, add beam for prop dragging 2025-08-13 09:54:35 -07:00
MSWS
96b7b64634 Only upload TTT.zip 2025-08-13 09:50:49 -07:00
MSWS
fb00a5be2d ci: Zip artifacts and remove upload action step
- Replace the upload artifact step in `.github/workflows/release.yml` with a new step to zip artifacts using the current version from GitVersion.
2025-08-13 09:50:07 -07:00
MSWS
1374eeae76 feat: Integrate message localization into loggers
- Add dependency on `TTT.Locale` in `SimpleLogger.cs` for message localization
- Introduce `locale` field for localization in `SimpleLogger.cs`
- Update `PrintLogs` methods in `SimpleLogger.cs` to include localized headers
- Add `GAME_LOGS_HEADER` message type in `GameMsgs.cs` for enhanced log management
- Include "GAME_LOGS_HEADER" entry in `en.yml` for game log headers translation
- Adjust player assignment roles in `DamagedAction.cs` by swapping victim and attacker
2025-08-13 09:46:26 -07:00
MSWS
b52ab4b1c5 ci: Add build and release steps to workflows
```
- Update release workflow to build and restore Locale project, compiling for release and copying JSON files
- Add steps to restore and publish Plugin project, specifying output directory
- Introduce artifact upload step for TTT with error handling for missing files
- Update GitHub release creation to include build directory files in release assets
```
2025-08-13 09:35:08 -07:00
MSWS
6de97166b0 refactor: Refactor role locale handling and improve game start logic
- Delete `RoleLocale.cs` file, indicating potential refactoring or change in handling role localization
- Modify `CS2Game.cs` to allow the `Start` method to return a nullable `IObservable<long>`, incorporating early exit logic when state is not `WAITING`
- Adjust game state logic in `CS2Game.cs` to set state to `IN_PROGRESS` or `COUNTDOWN` based on countdown parameter presence
- Update `TTTCommand.cs` to append "-DEBUG" to version string in debug mode and respond with modified version string
2025-08-13 09:23:36 -07:00
MSWS
78f40ea541 feat: Refactor roles; enhance logging and commands +semver:minor
```
- Enhance body identification by setting player clan based on primary role in BodyPickupListener.
- Add a nullable `DateTime` field `epoch` to SimpleLogger for tracking initial log time and refactor log formatting.
- Refactor SetRoleCommand to use non-prefixed role classes and update role assignment mechanism.
- Implement Lerp and Slerp methods in VectorExtensions for advanced vector interpolation.
- Introduce StopCommand class to forcibly stop active games and manage game dependencies.
- Upgrade RoundTimerListener with role assignment logic and new event triggers on round end.
- Refactor RoleIconsHandler to use dictionaries for icon management and rename role classes.
- Remove CS2TraitorRole, CS2DetectiveRole, and CS2InnocentRole, indicating role refactoring.
- Add color formatting to role names in language files and improve message consistency.
- Enhance PropMover with visual effects for entity interactions and refine entity teleportation logic.
- Use C# 8 range indexer syntax in CS2Player for improved readability and concise logic.
```
2025-08-13 09:11:56 -07:00
MSWS
da40708d96 Create Release 2025-08-13 05:53:54 -07:00
MSWS
7a8ea2d6e7 Cleanup and Reformat 2025-08-13 05:44:51 -07:00
MSWS
12de87c6ea ci: Revamp release workflow for automation
- Rename workflow to "Auto Release on SemVer Change" and modify trigger to branch-based for "main" and "dev".
- Change job name to "auto-release" and remove .NET setup to streamline workflow.
- Update GitVersion to 6.3.x and centralize tag management with automatic tagging.
- Revamp changelog generation using GitHub API and update release creation process.
- Implement cleanup process for old pre-releases to maintain repository hygiene.
2025-08-13 05:39:07 -07:00
MSWS
6eb713b0e6 ci: Refactor release workflow for better efficiency.
- Update actions in `.github/workflows/release.yml` to latest versions
- Specify .NET version as 8.0.x for consistency
- Change release tag extraction to MajorMinorPatch format
- Improve logic for checking if tag commit is on the main branch
- Simplify previous tag identification for efficiency
- Implement dynamic range selection for release notes generation
- Ensure correct asset path is used for GitHub release creation
- Differentiate between release and prerelease versions based on branch check results
2025-08-13 05:20:53 -07:00
MSWS
497d5aa514 ci: Simplify versioning & enhance release notes generation.
- Update tag listing format and remove unnecessary comments in `.github/workflows/release.yml`
- Change versioning variables from `FullSemVer` to `MajorMinorPatch` for simpler versioning in `.github/workflows/release.yml`
- Add step to generate `release_notes.md` with a full commit list in `.github/workflows/release.yml`
- Modify release creation to use detailed release notes file in `.github/workflows/release.yml`
- Refine steps for tagged commits, tag range identification, and adjust artifact upload for versioning changes in `.github/workflows/release.yml`
2025-08-13 05:17:23 -07:00
MSWS
20b3b6abfb ci: Enhance version naming in release workflow
- Update GitHub Actions workflow to include full semantic version in ZIP package and artifact naming
- Modify artifact upload step to use `FullSemVer` for naming instead of `SemVer`
- Improve package ZIP step by using a single variable for full semantic version, enhancing consistency
- Introduce a comment to clarify full semantic version usage for asset naming in release creation
- Optimize variable usage by defining a `FULL` variable for full semantic version to reduce redundancy
2025-08-13 05:07:16 -07:00
MSWS
e355e080f9 ci: Enhance release workflow with ZIP packaging
- Remove comments from `release.yml` for brevity.
- Add conditional check in `release.yml` for missing language files.
- Introduce step in `release.yml` to package build directory as a ZIP.
- Modify artifact path in `release.yml` to use ZIP file.
- Change artifact name in `release.yml` to include semantic version.
- Add test to `release.yml` for asset existence before creating GitHub release.
2025-08-13 05:01:48 -07:00
MSWS
27ce64ce6c ci: Update actions and specify release asset path
- Update checkout action to `actions/checkout@v4` in release workflow
- Update .NET setup to `actions/setup-dotnet@v4` targeting .NET `8.0.x`
- Specify release asset to `build/TTT/TTT.zip` in release workflow
2025-08-13 04:57:23 -07:00
MSWS
1af0e86e18 ci: Enhance release workflow with updated actions
- Update checkout action to version 4 in release workflow
- Adjust setup .NET action to latest version 4 in release workflow
- Specify `if-no-files-found` behavior in upload artifact step
- Enhance tag commit check condition for main branch
- Improve logic for finding previous tag with fallback method
- Modify GitHub release creation step to upload artifacts directly from `build/TTT`
2025-08-13 04:55:28 -07:00
MSWS
d18904bcae ci: Refine release workflow configuration
- Update `actions/checkout` to latest version in `release.yml`
- Adjust .NET setup to "8.0.x" in `release.yml`
- Simplify artifact upload naming to `TTT.zip` in `release.yml`
- Refine release asset naming in GitHub release creation in `release.yml`
2025-08-13 04:51:49 -07:00
MSWS
4027782a09 ci: Refactor build and publish process in release workflow
- Modify build process in release workflow to include setting up the Locale project
- Change build step to focus on "Build Locale" and specify output directory for language JSON files
- Revise packaging step to "Publish Plugin" for the TTT Plugin project
- Reorganize upload process by renaming artifact to "TTT" and omitting versioning from file path
- Remove retention-days configuration from workflow artifact upload step
2025-08-13 04:45:09 -07:00
Isaac
28a330ea4d Role assignment overhaul via IRoleAssigner, body identification, text rendering (#40) 2025-08-13 04:31:04 -07:00
MSWS
2029d6e940 Resolve compiler error 2025-08-13 04:27:49 -07:00
Isaac
2db293adbc Update TTT/Game/Roles/RoleAssigner.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <14448584+MSWS@users.noreply.github.com>
2025-08-13 04:25:11 -07:00
Isaac
c84072d705 Update TTT/Game/lang/GameMsgs.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <14448584+MSWS@users.noreply.github.com>
2025-08-13 04:23:36 -07:00
Isaac
2fabe3a680 Update TTT/Shop/PlayerKillListener.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <14448584+MSWS@users.noreply.github.com>
2025-08-13 04:22:57 -07:00
MSWS
9478950da9 ci: Simplify release workflow; trigger on tag push
- Update `.github/workflows/release.yml` to trigger on any tag push, removing dependency on other workflows
- Simplify concurrency settings by using GitHub reference name
- Add permissions section to grant write access to contents
- Combine separate jobs into a single `build-and-release` job
- Update to `actions/checkout@v4`, removing ref specification
- Change GitVersion setup to a lower version (v3) and update version spec
- Streamline versioning by removing detailed semantic checks
- Add build step utilizing .NET to restore packages and publish application
- Create and upload zip package of published artifact as a workflow artifact
- Enhance release creation logic, simplifying tag generation and pre-release handling
- Remove redundant artifact renaming, changelog generation, and old release pruning steps

Overall, these changes simplify and enhance the flexibility of the release process.
2025-08-13 04:22:10 -07:00
MSWS
8952d009fd feat: Enhance player conversion in BodyPickupListener
- Add dependency for `IPlayerConverter<CCSPlayerController>` in `BodyPickupListener.cs`
- Enhance `OnPropPickup` to convert attached player to an online player using the new converter
- Implement validity check for converted online player
- Update online player's pawn state to not alive upon body identification
- Invoke utility function to set `CCSPlayerController` pawn status change
2025-08-13 04:13:43 -07:00
MSWS
5661588e1e refactor: Improve debug messages and role visual feedback
- Reformat debug messages in `CS2Messenger.cs` for improved readability and structure.
- Update color for `ColoredRole` name in `ColoredRoleTest.cs` from red to dark blue.
- Enhance efficiency and clarity in `StringLocalizer.cs` by refining placeholder handling and vowel sound logic.
- Add color-coding to role identification in `GameMsgs.cs` to improve visual feedback during player identification.
- Adjust interaction distance and improve state management in `PropMover.cs` for better control and performance.
2025-08-13 04:09:15 -07:00
MSWS
9667a519f1 feat: Enhance logging and modular command system
```
Enhance Game Functionality and Logging Capabilities

- Update `GameMsgs.cs` to utilize explicit `Name` properties for data retrieval and introduce a new dependency on `CounterStrikeSharp.API.Modules.Utils`.
- Modify `PropMover.cs` to adjust minimum look accuracy, improving precision requirements.
- Extend `SimpleLogger.cs` with new logging methods for individual and all players, enhancing overall logging functionality.
- Revise `CS2CommandManager.cs` to improve code base structure by removing redundancy and ensuring correct method order.
- Update `CommandManager.cs` by implementing `ITerrorModule`, adding modularity and logging command capabilities.
- Enhance `IActionLogger.cs` with new logging methods integrating player functionalities.
- Introduce `LogsCommand.cs` to manage and display active game logs with error handling for inactive games.
- Adjust `StringLocalizer.cs` to refine character evaluation in text handling.
- Revise `en.yml` color schemes for consistency in message display.
- Simplify `GameEndLogsListener.cs` for better efficiency by using `PrintLogs()` method.
- Introduce a new 'MONITOR' priority level in `EventHandlerAttribute.cs` for more granular event handling priorities.
```
2025-08-13 03:06:47 -07:00
MSWS
00c8ad318b feat: Introduce body identification feature
- Rename `GameMsgs.cs` and restructure to `lang` directory; add `BODY_IDENTIFIED` message method for body identification scenarios.
- Implement `IdentifyBodyAction` class for handling body identification events, enhancing game event handling.
- Move CS2 messaging structures to `lang` directories for improved organization.
- Update `SpectatorRole.cs` to reflect new `lang` namespace.
- Replace `GamePlayerActionsListener` with `PlayerActionsLogger` in `PlayerActionsTest.cs`, integrating new logging functionality.
- Enhance game service collections with new listeners, including `PlayerActionsLogger` and `BodyIdentifyLogger`.
- Implement `BodyIdentifyLogger` to log body identification events.
- Enhance `BodyPickupListener` with improved error handling and localized messaging.
- Add new localized message format in `en.yml` for body identification events.
- Transform `GamePlayerActionsListener` to `PlayerActionsLogger` with updated structure and logging focus.
2025-08-13 02:29:26 -07:00
MSWS
e1f2d0e77a refactor: Refactor role management using IRoleAssigner
Refactor role management and simplify codebase

- **RoleAssignerTest.cs**: Update tests to use `assigner.GetRoles(p)` for role retrieval, ensuring consistency across tests.
- **Program.cs**: Remove error handling for YAML parsing, maintaining functionality in argument parsing and JSON conversion.
- **RoundBasedGameTest.cs**: Integrate `IRoleAssigner`, modifying role checks and simplifying test assertions.
- **IGame.cs**: Add `RoleAssigner` property and refactor role retrieval methods to streamline role management.
- **Multiple Files**: Implement `IRoleAssigner` across various components, enhancing role management consistency and simplifying code by removing direct role access.
2025-08-13 02:08:49 -07:00
MSWS
cf7a93925b refactor: Rename GameConfig to TTTConfig for consistency
```
Update configuration handling and improve code consistency

- Update `RoundBasedGame.cs` to use `TTTConfig`, enhancing game lifecycle management and state transitions.
- Rename `GameConfig.cs` to `TTTConfig.cs` for consistency, with no changes to logic or properties.
- Refactor `CS2CommandManager.cs` to clean up command registration and improve readability.
- Adjust `PlayerConnectionsHandler.cs` to simplify server update logic and remove unnecessary checks.
- Improve `RoleAssignListener.cs` for better role assignment handling and ensure proper player role transitions.

Additionally, minor updates are made across multiple files to replace `GameConfig` with `TTTConfig`, ensuring consistent configuration handling throughout the codebase.
```
2025-08-12 23:25:05 -07:00
MSWS
01231d29e6 Update namespaces 2025-08-12 20:56:21 -07:00
MSWS
5237ff1f64 feat: Implement role assignment and weapon handling updates
```
Implement Various Enhancements and Refactoring Across Multiple Modules

- Update RoleAssignListener.cs: Remove unused imports, add module metadata with new public properties, and reorganize method structure for clarity. Implement new Start method and improve efficiency in onTransmit logic.
- Optimize SimpleLogger.cs by utilizing full date and time for dictionary keys, enhancing logging precision.
- Adjust role assignment process in BaseRole.cs, TraitorRole.cs, DetectiveRole.cs, and InnocentRole.cs to conditionally strip weapons based on new GameConfig.cs setting, StripWeaponsPriorToEquipping.
- Refine SetRoleCommand.cs by reorganizing imports and enhancing role assignment logic, ensuring dynamic role selection and clear messaging.
- Enhance RoundBasedGame.cs with new inventory management component to standardize player inventories at the start of each round and leverage dependency injection for external services.
- Conduct miscellaneous refactorings and performance improvements, including test updates, import optimizations, and enhanced logging across multiple files.
```
2025-08-12 02:49:00 -07:00
MSWS
4c4c4290ad Clear cache on round start 2025-08-11 20:31:13 -07:00
MSWS
7b79182fdf feat: Enhance role assignment and command features
```
- Enhance messaging functionality in `BaseRole.cs` with new `IMessenger` dependency and localized player notifications during role assignment.
- Update `CS2CommandManager.cs` to include new `SetRoleCommand` and refine command management namespace.
- Extend `RoleAssignListener` in `RoleAssignListener.cs` to include role identification and icon management for `CS2TraitorRole`, implementing `IPluginModule`.
- Shift role assignment notifications in `RoleAssigner.cs` from player-specific to global messaging for improved game transparency.
- Refactor `CS2ServiceCollection.cs` to use a new `RoleAssignListener` behavior, optimizing role management practices.
```
2025-08-11 20:03:01 -07:00
MSWS
6f61c81bed feat: Introduce text rendering and spawning features +semver:minor
```
- Rename and reorganize several files for improved project structure, including `CS2Messenger.cs`, `CS2InventoryManager.cs`, `CS2CommandInfo.cs`, `CCPlayerConverter.cs`, `CS2Msgs.cs`, `TestCommand.cs`, and `CS2CommandManager.cs`.
- Add new methods to `VectorExtensions.cs` for vector normalization and scaling, and suppress code analysis warnings.
- Introduce `TextSetting.cs` class for text rendering, defining properties like color, font, justification, and orientation.
- Enhance `PropMover.cs` with new utility imports, increase interaction parameters, remove outdated array logic, add logging, and improve teleport logic.
- Expand `RoleAssignListener.cs` with new `using` directives, implement `ITextSpawner`, replace player color settings, and create text hat during role assignments.
- Introduce `TraceFlags` enum in `RayTrace.cs` to improve mask clarity and refactor vector operations for consistency.
- Implement `TextSpawner.cs`, adhering to `ITextSpawner` interface, to create and manage in-game text entities and associated error handling.
- Optimize `BodySpawner.cs` ragdoll correction with efficient update logic and improved rotation use.
- Define `ITextSpawner` interface for flexible text and text hat creation methods, improving in-game text mechanics.
```
2025-08-11 19:17:24 -07:00
MSWS
63bb22fd43 docs: Include discord invite link in README 2025-08-11 04:22:54 -07:00
Isaac
9da822348d build(deps): Bump actions/download-artifact from 4 to 5 (#38)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 4 to 5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/407">actions/download-artifact#407</a></li>
<li>BREAKING fix: inconsistent path behavior for single artifact
downloads by ID by <a
href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/416">actions/download-artifact#416</a></li>
</ul>
<h2>v5.0.0</h2>
<h3>🚨 Breaking Change</h3>
<p>This release fixes an inconsistency in path behavior for single
artifact downloads by ID. <strong>If you're downloading single artifacts
by ID, the output path may change.</strong></p>
<h4>What Changed</h4>
<p>Previously, <strong>single artifact downloads</strong> behaved
differently depending on how you specified the artifact:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (direct)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/my-artifact/</code> (nested)</li>
</ul>
<p>Now both methods are consistent:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (unchanged)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/</code> (fixed - now direct)</li>
</ul>
<h4>Migration Guide</h4>
<h5> No Action Needed If:</h5>
<ul>
<li>You download artifacts by <strong>name</strong></li>
<li>You download <strong>multiple</strong> artifacts by ID</li>
<li>You already use <code>merge-multiple: true</code> as a
workaround</li>
</ul>
<h5>⚠️ Action Required If:</h5>
<p>You download <strong>single artifacts by ID</strong> and your
workflows expect the nested directory structure.</p>
<p><strong>Before v5 (nested structure):</strong></p>
<pre lang="yaml"><code>- uses: actions/download-artifact@v4
  with:
    artifact-ids: 12345
    path: dist
# Files were in: dist/my-artifact/
</code></pre>
<blockquote>
<p>Where <code>my-artifact</code> is the name of the artifact you
previously uploaded</p>
</blockquote>
<p><strong>To maintain old behavior (if needed):</strong></p>
<pre lang="yaml"><code>&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="634f93cb29"><code>634f93c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/416">#416</a>
from actions/single-artifact-id-download-path</li>
<li><a
href="b19ff43027"><code>b19ff43</code></a>
refactor: resolve download path correctly in artifact download tests
(mainly ...</li>
<li><a
href="e262cbee4a"><code>e262cbe</code></a>
bundle dist</li>
<li><a
href="bff23f9308"><code>bff23f9</code></a>
update docs</li>
<li><a
href="fff8c148a8"><code>fff8c14</code></a>
fix download path logic when downloading a single artifact by id</li>
<li><a
href="448e3f862a"><code>448e3f8</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/407">#407</a>
from actions/nebuk89-patch-1</li>
<li><a
href="47225c44b3"><code>47225c4</code></a>
Update README.md</li>
<li>See full diff in <a
href="https://github.com/actions/download-artifact/compare/v4...v5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=4&new-version=5)](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)


</details>
2025-08-11 04:21:26 -07:00
Isaac
4cd18c7ae8 build(deps): Bump GitTools/actions from 4.0.1 to 4.1.0 (#39)
Bumps [GitTools/actions](https://github.com/gittools/actions) from 4.0.1
to 4.1.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gittools/actions/releases">GitTools/actions's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.0</h2>
<p>As part of this release we had <a
href="https://github.com/GitTools/actions/compare/v4.0.1...v4.1.0">64
commits</a> which resulted in <a
href="https://github.com/GitTools/actions/milestone/4?closed=1">6
issues</a> being closed.</p>
<p><strong>Bugs</strong></p>
<ul>
<li>[<strong><a
href="https://redirect.github.com/gittools/actions/issues/1685">#1685</a></strong>](<a
href="https://redirect.github.com/GitTools/actions/issues/1685">GitTools/actions#1685</a>)
[ISSUE]: Release 4.0.0 - Cannot parse local nuget sources</li>
<li><a
href="https://redirect.github.com/GitTools/actions/pull/1716"><strong>!1716</strong></a>
<a
href="https://redirect.github.com/gittools/actions/issues/1676">#1676</a>
- fix -GitVersion configuration file not found at&quot;</li>
<li><a
href="https://redirect.github.com/GitTools/actions/pull/1722"><strong>!1722</strong></a>
<a
href="https://redirect.github.com/gittools/actions/issues/1676">#1676</a>
- Fixes file path validation in dotnet tool</li>
</ul>
<p><strong>Documentation</strong></p>
<ul>
<li><a
href="https://redirect.github.com/GitTools/actions/pull/1693"><strong>!1693</strong></a>
Improved instructions about cloning</li>
<li><a
href="https://redirect.github.com/GitTools/actions/pull/1712"><strong>!1712</strong></a>
Fix typo in setup.md</li>
</ul>
<h3>SHA256 Hashes of the release artifacts</h3>
<ul>

<li><code>0343c0ac8f67bd00d96fbc237051f7fe0b7ad335c75a0b71e4f4a7daba5a1ed8
- gittools.gittools-4.1.0.250805235.vsix</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b82e662a71"><code>b82e662</code></a>
Merge pull request <a
href="https://redirect.github.com/gittools/actions/issues/1722">#1722</a>
from arturcic/fix/1676</li>
<li><a
href="084f803b7a"><code>084f803</code></a>
<a
href="https://redirect.github.com/gittools/actions/issues/1676">#1676</a>
- Fixes file path validation in dotnet tool</li>
<li><a
href="1d898d18d1"><code>1d898d1</code></a>
Merge pull request <a
href="https://redirect.github.com/gittools/actions/issues/1721">#1721</a>
from arturcic/feature/azdo-tasks-updates</li>
<li><a
href="558b87e803"><code>558b87e</code></a>
updates azure tasks and fixes date format</li>
<li><a
href="226eef0291"><code>226eef0</code></a>
Merge pull request <a
href="https://redirect.github.com/gittools/actions/issues/1713">#1713</a>
from GitTools/dependabot/npm_and_yarn/typescript-5.9.2</li>
<li><a
href="ac62f3483b"><code>ac62f34</code></a>
(npm): Bump typescript from 5.8.3 to 5.9.2</li>
<li><a
href="bd57eebbb9"><code>bd57eeb</code></a>
Merge pull request <a
href="https://redirect.github.com/gittools/actions/issues/1720">#1720</a>
from GitTools/dependabot/npm_and_yarn/eslint-801ca537e1</li>
<li><a
href="a5fed8da22"><code>a5fed8d</code></a>
(npm): Bump typescript-eslint from 8.38.0 to 8.39.0 in the eslint
group</li>
<li><a
href="61dcb54ac9"><code>61dcb54</code></a>
Terminal <a
href="https://redirect.github.com/gittools/actions/issues/1676">#1676</a>
- fix -GitVersion configuration file not found at&quot;</li>
<li><a
href="6bac175d2b"><code>6bac175</code></a>
Merge pull request <a
href="https://redirect.github.com/gittools/actions/issues/1717">#1717</a>
from arturcic/main</li>
<li>Additional commits viewable in <a
href="https://github.com/gittools/actions/compare/v4.0.1...v4.1.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=GitTools/actions&package-manager=github_actions&previous-version=4.0.1&new-version=4.1.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)


</details>
2025-08-11 04:19:46 -07:00
MSWS
f09ad09c33 feat: Implement body and prop event systems +semver:minor
```
- Organize and restructure project files by moving core game files to a new "Game" directory.
- Introduce the `BodyEvent` abstract class and multiple body-related event classes such as `BodyIdentifyEvent` and `BodyCreateEvent` for enhanced event handling.
- Implement the `BodySpawner.cs` file, introducing the `BodySpawner` class with robust logic for body spawning, event handling, and game services integration.
- Refactor `VectorExtensions.cs` by changing data types for performance improvements and adding utility methods for vector manipulation.
- Enhance `CombatHandler.cs` with new events `PlayerDeathEvent` and `PlayerDamagedEvent`, correcting spelling errors, and refining player state handling.
- Develop new interface `IBody` and class `CS2Body` to manage game character bodies, including properties and methods for player associations.
- Expand event handling capabilities with the addition of `PropPickupEvent` and `PropDropEvent` classes, supporting cancellable game events.
- Refactor `PropMover.cs` to simplify code, improve efficiency with LINQ, and integrate debug statements and event dispatching.
- Remove the `BodyHider.cs` file, indicating a shift in handling player color changes within the game.
```
2025-08-11 04:12:16 -07:00
dependabot[bot]
3644dfb2bc build(deps): Bump GitTools/actions from 4.0.1 to 4.1.0
Bumps [GitTools/actions](https://github.com/gittools/actions) from 4.0.1 to 4.1.0.
- [Release notes](https://github.com/gittools/actions/releases)
- [Changelog](https://github.com/GitTools/actions/blob/main/GitReleaseManager.yml)
- [Commits](https://github.com/gittools/actions/compare/v4.0.1...v4.1.0)

---
updated-dependencies:
- dependency-name: GitTools/actions
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 01:01:16 +00:00
dependabot[bot]
f8ccdd88af build(deps): Bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 01:01:11 +00:00
Isaac
0b028b4d99 Overhaul CI (#37) 2025-08-10 01:18:08 -07:00
MSWS
3f36a5e8ea Fix indentation 2025-08-10 01:09:19 -07:00
MSWS
d11e4189a1 Attempt to fix workflow issue 2025-08-10 01:07:58 -07:00
MSWS
17527059c0 ci: Revise changelog and release workflows
- Revise the changelog template in `.github/changelogConfig.json` to include contributors, commit details, and sorting capabilities.
- Simplify syntax and modify concurrency setting in `.github/workflows/release.yml`, and add logical enhancements for version comparison and release conditions.
2025-08-10 01:04:53 -07:00
Isaac
90ce56e888 More shop management and game integration (#36) 2025-08-10 00:20:35 -07:00
MSWS
624b405e98 Reformat 2025-08-09 21:49:36 -07:00
MSWS
a73c3752a7 Import regex in Test module 2025-08-09 21:14:54 -07:00
MSWS
26b724fdcb Add Copilot suggestions 2025-08-09 21:11:10 -07:00
Isaac
2c11cc6652 Update TTT/Test/Game/Round/RoundBasedGameTest.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <14448584+MSWS@users.noreply.github.com>
2025-08-09 21:07:54 -07:00
Isaac
ee299846df Update TTT/CS2/Extensions/VectorExtensions.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <14448584+MSWS@users.noreply.github.com>
2025-08-09 21:07:08 -07:00
Isaac
c221a774bb Update TTT/CS2/GameHandlers/PropMover.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Isaac <14448584+MSWS@users.noreply.github.com>
2025-08-09 21:04:07 -07:00
MSWS
bd2ffa951e Reformat & Cleanup, add README to Versioning 2025-08-08 02:03:41 -07:00
MSWS
073634c2f7 feat: Refactor ragdoll management and enhance game handling
- Remove the "body" command case and related functionality from `TestCommand.cs`.
- Update `RoundBasedGame.cs` to finalize game state changes upon disposal.
- Overhaul entity interaction and initialization logic in `PropMover.cs`, refine event handling, and introduce enhanced movement tracking using the new `MovementInfo` class.
- Create `MovementInfo.cs` for data handling of entity movement.
- Experimentally disable player connection event dispatching in `PlayerConnectionsHandler.cs`.
- Re-enable `CombatHandler` and add new `BodyHider` plugin behavior in `CS2ServiceCollection.cs`.
- Implement new `BodyHider` module for altering player visibility and enhancing death event handling.
2025-08-07 22:10:58 -07:00
MSWS
bc5b0b6770 feat: Fix DistanceSquared calc and enhance PropMover interactions +semver:minor
```
- Correct the calculation in the `DistanceSquared` method in `VectorExtensions.cs` to properly compute squared Euclidean distance between two vectors.
- Add new extension and vector utilities in `PropMover.cs`.
- Change type in the dictionary and hashset in `PropMover.cs` from `CEntityInstance` to `CBaseEntity`.
- Revise entity addition condition in `PropMover.cs` using specific logic based on entity type.
- Enhance interaction feedback and implement distance-based detection for player interaction with entities in `PropMover.cs`.
```
2025-08-07 13:38:30 -07:00
MSWS
344e5ebe62 feat: Implement prop movement and ray tracing features +semver:minor
```
- Enhance `PropMover.cs` with new event listeners and interaction logic, including player button handling and entity filtering.
- Enable unsafe code in `CS2.csproj` for potential performance improvements.
- Add vector extension methods in `VectorExtensions.cs` to compute distances, aiding geometric calculations.
- Introduce `PropMover` plugin in `CS2ServiceCollection.cs` and reorder handlers, with a note on missing final newline.
- Implement ray tracing in `RayTrace.cs`, including error handling and low-level API interaction for precision in trace calculations.
```
2025-08-07 12:36:43 -07:00
MSWS
f0b896120f Resolve merge conflicts 2025-08-07 11:39:42 -07:00
MSWS
6901e47fe0 Get scoreboard spoofing working 2025-08-07 11:37:26 -07:00
MSWS
2f5b4c4822 Reformat & Cleanup 2025-08-06 23:38:42 -07:00
MSWS
f295786887 refactor: Refactor round termination logic in utils and listener
- Introduce a new `TerminateRoundFunc` in `RoundUtil.cs` with game data signature and update `EndRound` to use it.
- Simplify null checks in `RoundUtil.cs` by removing redundant variable declarations and handle potential null values for `ServerUtil.GameRulesProxy`.
- Remove inline comments in `RoundUtil.cs` for better readability.
- Add `JetBrains.Annotations` import and `[UsedImplicitly]` annotations in `RoundTimerListener.cs`.
- Remove `IPlayerFinder` dependency and replace `TerminateRoundFunc` with `RoundUtil.EndRound` in `RoundTimerListener.cs`, enhancing readability and simplifying class structure.
2025-08-06 23:19:27 -07:00
MSWS
c52672e2b0 feat: Refactor and enhance round management logic
- Implement respawn mechanism for non-alive players during countdown in `RoundTimerListener.cs`.
- Adjust command execution logic and set dynamic round time based on player count in `RoundTimerListener.cs`.
- Change team assignments for `InnocentRole` players at round end in `RoundTimerListener.cs`.
- Rename `ServerExtensions.cs` to `ServerUtil.cs`, and update class and namespace to match in `ServerUtil.cs`.
- Add new utility imports in `CS2Game.cs` and `RoundUtil.cs`.
2025-08-06 23:11:41 -07:00
MSWS
d5d7a646b1 refactor: Refactor game rules access for improved clarity
- Replace `GetGameRules()` method with `GameRules` property in `ServerExtensions.cs` and introduce caching for improved efficiency.
- Update `RoundTimerListener.cs` to use `GameRulesProxy` property for simplified and direct access to game rules.
- Simplify `RoundUtil.cs` by replacing method calls with property accesses for enhanced clarity and code readability.
2025-08-06 23:08:16 -07:00
MSWS
37b21fd46d feat: Add shop feature with balance clearing test +semver:minor
- Add using directive for `TTT.Shop` and scoped service registration for `IShop` in `Startup.cs`
- Create `BalanceClearTest` class to ensure balances are cleared at game start
- Reformat XAML elements and add code coverage filter in `TTT.sln.DotSettings`
- Add project reference to `Shop.csproj` in `Test.csproj`
- Change type from `IOnlinePlayer` to `IPlayer` in `IShop` and `Shop` classes
2025-08-06 22:59:23 -07:00
MSWS
680bb3789e docs: Add badges to README for clarity and updates
- Add a styled badge link to the top of the README
- Rename code coverage badge to "Code Coverage" for clarity
- Introduce a new badge displaying development time with specific request parameters
2025-08-06 22:37:40 -07:00
MSWS
d92996d11e ci: Prevent CI execution of GitVersion generation +semver:minor
Add condition to GenerateGitVersionInformation target in Versioning.csproj

- Prevent execution in continuous integration environments by adding a condition to the GenerateGitVersionInformation target in Versioning.csproj.
2025-08-06 22:31:06 -07:00
MSWS
7f6e9359aa refactor: Refactor code for readability and maintainability +semver:patch
```
Refactor codebase for improved readability, maintainability, and performance

- TTT/CS2/GameHandlers/CombatHandler.cs: Remove unused directives, reorder methods, and apply minor formatting changes.
- TTT/Game/RoundBasedGame.cs: Optimize `Start` method logic, improve game state transitions, enhance messaging logic, and ensure proper resource cleanup.
- TTT/CS2/CS2InventoryManager.cs: Refine `RemoveWeapon` function by cleaning up parameters and improving weapon removal handling.
- TTT/API/Game/IGame.cs: Rename `GetRole` to `GetOfRole` and enhance `GetAlive` method flexibility with new parameters.
- TTT/Plugin/TTT.cs: Eliminate unused library references for cleaner code.
- Various Files: Remove unused directives, reorder methods for better readability, and improve file organization across multiple files.
```
2025-08-06 22:27:39 -07:00
MSWS
7ec2554bc3 test: Add ColoredRole tests with xUnit for article handling +semver:minor
- Introduce a new test class `ColoredRoleTest` for the `ColoredRole` within a structured namespace.
- Implement the `ColoredRole` class that derives from `IRole` with a red-colored name demonstration.
- Add unit tests using xUnit framework to verify correct article usage in role assignment messages.
- Utilize dependency injection to obtain `IMsgLocalizer` for localization testing.
2025-08-06 22:24:02 -07:00
MSWS
edeb0e08b8 fix: Enable Git version info and fix JSON null handling
- Un-comment the `GenerateGitVersionInformation` target in `Versioning.csproj` to enable version information generation on non-Windows systems.
- Remove the execution command previously used to compile and run the project in `Versioning.csproj`.
- Adjust the path for the generated `gitversion.json` file in `Versioning.csproj`, moving it one directory up.
- Update `Program.cs` to change the handling of null JSON values by assigning an empty string for string type, while keeping other JSON value conversions unchanged.
2025-08-06 22:15:35 -07:00
MSWS
45ad0375e5 Remove WIP 2025-08-06 21:33:16 -07:00
MSWS
e8169a54b1 feat: Remove entity event delay; add player checks & command
- Modify `AddEntityIOEvent` in `CS2InventoryManager.cs` by removing the delay parameter, potentially changing event timing execution
- Add null and validity check for player pawn in `RoleAssignListener.cs` to ensure it exists and is valid before calling `SetModel()`
- Introduce `TestCommand` class in `TestCommand.cs` with command execution logic and asynchronous task handling
- Integrate `TestCommand` in `CS2CommandManager.cs` with `hotReload` parameter and expanded command registration process
2025-08-06 20:04:40 -07:00
MSWS
692d233ac0 feat: Implement game state handling and round logic +semver:minor
```
Introduce new game mechanics and improve resource management

- Update `TTT.cs` to enhance Dispose method, ensuring cleanup of IGameManager resources.
- Add `RoundStartHandler.cs` with essential round start logic and dependency management.
- Expand `PlayerCausesEndListener.cs` with improved role handling and debug logging.
- Modify `CS2Game.cs` to integrate reactive programming for countdowns and state management.
- Optimize `CS2Player.cs` with consolidated logic for player identification and state checks.
- Refactor `RoundBasedGame.cs` to include localized messaging and enhanced game state handling.
- Update multiple game configuration files with new endgame message templates and listener adjustments.
```
2025-08-06 19:13:59 -07:00
MSWS
fa31a6b492 test: Improve message formatting and localization +semver:minor
- Modify `GAME_STATE_STARTED` message in `GameMsgs.cs` for grammatical accuracy and clarity regarding the number of traitors.
- Add new translation entries for "AN_RED_ELEPHANT" and "AN_RED_BALL" in `Test/lang/en.yml`.
- Update `Game/lang/en.yml` to use variable placeholders for role messages.
- Expand locale message templates by adding new constants in `Test/Locale/TestMsgs.cs`.
- Implement additional localization and formatting tests in `LocaleTest.cs`.
- Enhance `RoundBasedGameTest.cs` with tests for role messages, game start scenarios, and end conditions.
- Improve string handling in `StringLocalizer.cs` with utility functions and updated trimming methods.
2025-08-06 18:06:38 -07:00
MSWS
8223e15cc3 Add round start role-inform message 2025-08-06 17:41:37 -07:00
Isaac
09b4c92f3c ci: Enhance changelog generation in release workflow (#35)
- Add step in release workflow to determine base tag for changelog
generation
- Modify Generate Changelog step to include base tag as input parameter
for accurate changelog creation
2025-08-06 17:33:41 -07:00
MSWS
2498dc3d6e ci: Enhance changelog generation in release workflow
- Add step in release workflow to determine base tag for changelog generation
- Modify Generate Changelog step to include base tag as input parameter for accurate changelog creation
2025-08-06 17:12:09 -07:00
Isaac
39a6fd4119 Improve localization and CS2-specific support, additional unit tests (#34) 2025-08-06 16:30:19 -07:00
MSWS
07042301f8 refactor: Refactor timer, services, and article logic +semver:minor
- Enhance `RoundTimerListener` by making `TerminateRoundFunc` a `readonly` static field and using `Server.NextWorldUpdate` for deferred execution.
- Update `OnRoundStart` and `OnRoundEnd` for improved timer functionality and team balance in `RoundTimerListener`.
- Change service lifecycles in `Startup` from transient to scoped for `IScheduler` and `IMsgLocalizer`.
- Simplify vowel sound logic in `StringLocalizer` using switch expressions for article determination.
- Refactor `CombatHandler` to focus on event-driven architecture and simplify damage handling.
- Remove console logging from `IGame`'s `GetAlive` method to streamline and enhance performance.
2025-08-06 16:26:31 -07:00
MSWS
e1ebc71661 Merge branch 'main' into dev 2025-08-06 16:18:26 -07:00
MSWS
7469516667 ci: Fix typo and extend label pattern +semver:patch
- Fix typo in pull request template format by correcting unbalanced braces in changelogConfig.json
- Extend `label_extractor` pattern to include more label types like `cd` and `workflow` for better categorization
2025-08-06 16:17:48 -07:00
MSWS
b1b5409828 refactor: Refactor role and round handling logic
- Simplify `RoleAssignListener` by consolidating conditional logic and updating `SetClan` method signature.
- Remove unnecessary implementation exception from `ListCommand`'s `Dispose` method.
- Clean up comments in `CS2Player`, maintaining current property logic and constructors.
- Streamline round termination logic in `RoundTimerListener` and add TODO for parameter clarification.
- Refactor multiple associated files for enhanced code readability and maintenance.
2025-08-06 15:44:27 -07:00
MSWS
53ceb0baf2 Reformat & Cleanup 2025-08-05 23:59:57 -07:00
MSWS
2f81514e11 feat: Enhance game logic and role management handling
- Update `RoundTimerListener.cs` to enhance player management and control flow, introducing new fields and refining round start and end logic.
- Refine `RoleAssignListener.cs` to adjust clan assignments based on player roles, specifically setting up for `CS2DetectiveRole`.
- Implement `GetRole` method in `IGame.cs` for role-based player retrieval and enhance `GetAlive` for detailed role logging.
- Revise `CS2Game.cs` to manage role list updates, game state transitions, and ensure main thread consistency during operations.
2025-08-05 23:39:58 -07:00
MSWS
e1ab5e45db feat: Implement article handling logic and round updates.
```
- Add new localization strings and variations in `TTT/Test/lang/en.yml` for testing scenarios.
- Remove debug-only command and enhance error logging in `TTT/CS2/CS2CommandManager.cs` for better debugging support.
- Implement player respawn and improve round ending behavior in `TTT/CS2/Listeners/RoundTimerListener.cs`.
- Add article handling support and update methods for `%an%` placeholders in `Locale/StringLocalizer.cs`.
- Expand test message capabilities with new constants and methods in `TTT/Test/Locale/TestMsgs.cs`.
- Simplify role assignment logic by removing event instantiation in `TTT/CS2/Listeners/RoleAssignListener.cs`.
- Enhance access control and fix game state transition logic in `TTT/Game/RoundBasedGame.cs`.
- Update round management with new static method and using directives in `TTT/CS2/RoundUtil.cs`.
- Modify role assignment messages for grammatical accuracy in `TTT/Game/lang/en.yml`.
- Improve round-end logic and add necessary checks in `TTT/CS2/GameHandlers/RoundEndHandler.cs`.
- Clarify role name usage in message creation in `TTT/Game/GameMsgs.cs`.
- Introduce new event handling and state checks in `TTT/CS2/CS2Game.cs`.
- Add comprehensive tests for article localization and substitution in `TTT/Test/Locale/LocaleTest.cs`.
```
2025-08-05 22:52:53 -07:00
MSWS
fbf4bc8c9f feat: Add role features and localize role messages
```
- Add `SetClan` method to `PlayerExtensions` in `PlayerExtensions.cs` for clan management
- Improve command handling and debugging in `CS2CommandManager.cs` with conditional `TestClanCommand` registration and enhanced error logging
- Fix typo in `DebugInform` output in `CS2Messenger.cs` and maintain debug method consistency
- Update role assignment logic in `RoleAssignListener.cs` for team assignment and clan setting based on roles
- Introduce localization support in role assignment messages across `en.yml`, `GameMsgs.cs`, and `RoleAssigner.cs`
```
2025-08-05 21:49:47 -07:00
MSWS
24c7104a01 refactor: Enhance logging and refine role type checks
- Add console logging for player roles in `GetAlive` methods within `IGame.cs` and enhance role type matching logic
- Comment out `CBaseEntity_TakeDamageOldFunc` hooks in `CombatHandler.cs` and add player validation check
- Simplify `GameConfig` instantiation and verify correct game start in `JoinStartTest.cs`
- Rename `ScreenMsg` method to `Message` in `RoleAssigner.cs` without affecting functionality
- Enhance console logging for debugging methods in `CS2Messenger.cs` to include message type
2025-08-05 20:36:37 -07:00
Isaac
3674b025b3 ci: Update release workflow for branch flexibility (#33)
- Reference the triggering branch during checkout in the release
workflow.
2025-08-05 11:30:46 -07:00
MSWS
41b6ac0388 ci: Update release workflow for branch flexibility
- Reference the triggering branch during checkout in the release workflow.
2025-08-05 11:28:45 -07:00
MSWS
7801feaa85 ci: Update release workflow for branch flexibility
- Reference the triggering branch during checkout in the release workflow.
2025-08-05 11:28:09 -07:00
MSWS
40dff5ef0b Re-add debug logging 2025-08-05 11:22:58 -07:00
MSWS
2531d54ba5 test: Refactor game config usage in tests +semver:patch
- Add import statement for `TTT.Game` in `JoinStartTest` to utilize new functionalities
- Introduce `GameConfig` object in `JoinStartTest` for managing configuration settings
- Modify `OnJoin_StartsGame_WhenTwoPlayersJoin` test to use `GameConfig` for countdown, improving flexibility
- Change `IScheduler` lifecycle in `Startup` from `Scoped` to `Transient` for a new instance per request
2025-08-05 11:21:45 -07:00
MSWS
6f02d3b7ea refactor: Enhance thread safety and add null handling support
```
- Enhance thread safety and state consistency in `CS2Game.cs` during game start operations by ensuring main thread execution and enforcing game state consistency.
- Improve role assignment in `RoleAssigner.cs` by clearing existing roles before assigning new ones and randomizing assignments with a shuffled list of players.
- Strengthen null handling in `EventModifiedMessenger.cs` by allowing nullable `IOnlinePlayer` parameters and ensuring actions are executed with null parameters.
- Prevent active game duplication in `CS2GameManager.cs` by adding a check and throwing an exception if a game is already active.
- Introduce asynchronous execution and better synchronization in `RoundTimerListener.cs` to handle round timings in the next world update cycle.
- Refactor `PlayerConnectionsHandler.cs` for improved dependency management by introducing dependency injection for key components.
- Change directory capitalization for consistency in `ActionTest.cs` file path.
- Enhance configurability in `PlayerJoinStarting.cs` by using a configuration value for the minimum player count to start a game.
- Add new tests in `GameTest.cs` to verify the behavior of the `GetAlive` method with various scenarios and role filters.
```
2025-08-05 11:04:57 -07:00
MSWS
b4f77e43f8 Remove unnecessary dependency on IPlayerFinder in RoleAssigner.cs and preserve optional IMessenger use
- Adjust event listener registration in `PlayerConnectionsHandler.cs` to use `OnClientConnected` and simplify function signature
- Activate previously commented-out line in `CombatHandler.cs` for proper `OnTakeDamage` unhooking in `Dispose` method
2025-08-05 10:33:04 -07:00
MSWS
fce31747a1 refactor: Refactor logging and enhance round initiation
```
- Comment out initialization of `msg` and disable debug logging in `SimpleLogger.cs` to reduce dependencies and simplify debugging.
- Add a `Start` method in `CS2Game.cs` to enhance round initiation with an optional countdown and expandability for future features.
- Adjust command execution order in `RoundTimerListener.cs` to correctly manage round win conditions during COUNTDOWN and IN_PROGRESS states.
- Implement dependency injection in `CCPlayerConverter.cs` by switching to `IServiceProvider`, deferring `IMessenger` instantiation with `Lazy<T>`.
- Remove redundant logging in `PlayerConnectionsHandler.cs` to streamline startup messages.
- Update several files to enhance logging and debugging, refactor code, and improve initialization and error handling.
```
2025-08-05 10:26:02 -07:00
MSWS
6a3c7d21bd refactor: Add debug methods and enhance logging
- Add new debugging methods in `CS2Messenger.cs` and ensure they only run in debug mode using preprocessor directives
- Simplify `SimpleLogger` initialization by removing unnecessary service calls in `RoundBasedGame.cs`
- Import `System.Diagnostics` in `EventModifiedMessenger.cs` to enable potential debugging or logging enhancements
- Enhance `CCPlayerConverter.cs` by combining lookup checks, adding null checks, and improving debug messages
- Correct parameter name case in `CS2GameManager.cs` to conform to naming conventions
- Replace `IScheduler` dependency with `IServiceProvider` in `SimpleLogger.cs` and add dependency injection for messenger and scheduler components
2025-08-05 09:44:20 -07:00
MSWS
098e43777c feat: Refactor and enhance gameplay with event-driven setup +semver:patch
- Update color coding for the "game is starting" message in `en.yml` for clarity and aesthetics
- Modify `CCPlayerConverter.cs` to include dependency on `TTT.API.Messages` and refactor constructor for `IMessenger` integration
- Revise `CS2GameManager.cs` to implement event-driven game creation using `GameInitEvent`
- Change access level of `IEventBus` and `ActiveGame` in `GameManager.cs` to protected for better inheritance support
- Enhance `PlayerJoinStarting.cs` with dependency injection and configurable start countdown
- Reinstate and improve error handling for `OnTakeDamage` in `CombatHandler.cs`
2025-08-05 09:34:54 -07:00
MSWS
01aebe12e9 Update README Locale link 2025-08-05 06:27:29 -07:00
MSWS
dfd9b4f3c7 Use markdown for licenses 2025-08-05 05:59:12 -07:00
MSWS
066b6f9fb7 Remove absolute pathing in .envrc 2025-08-05 05:03:03 -07:00
MSWS
0ffd9e3773 Update CS# and licenses 2025-08-05 05:01:01 -07:00
Isaac
294fc9d3d7 Improve messaging / logging internals 2025-08-05 02:50:45 -07:00
MSWS
b34f91219e feat: Enhance message event handling and flexibility.
- Add handling logic for `BackgroundMsg` and `ScreenMsg` in `EventModifiedMessenger.cs`, including event dispatching for player-specific messages
- Update `PlayerBackgroundMessageEvent` to accept additional arguments with a params parameter
- Introduce generic type parameter `T` for `SimpleArgsSubstitution` to enhance flexibility in handling event types
- Modify `SimpleMessageSubstitution` to be generic with a type parameter `<T>`, ensuring `T` is a subclass of `PlayerMessageEvent`
- Add support for additional parameters in `PlayerScreenMessageEvent` constructor for flexible message formatting
- Refine message event handling in `MessageModificationTest`, parameterizing test instances with specific event types
2025-08-05 02:48:06 -07:00
MSWS
f54b1942b0 refactor: Refactor message formatting and substitution logic
- Add formatting functionality to `TestMessenger` and ensure consistency across methods
- Define `SimpleMessageSubstitution` class to modify player messages, with event handling and setup for unregistration
- Refactor `MessageModificationTest` to use new substitution classes, enhance test coverage and readability
- Create `SimpleArgsSubstitution` class for modifying message arguments, and improve event handling clarity
- Enhance `EventModifiedMessenger` with new methods and helper function, improve message broadcasting flexibility
2025-08-05 02:36:35 -07:00
MSWS
eb63152f61 refactor: Enhance message handling with added flexibility +semver:minor
```
Enhance Messaging and Event Handling System

- Expand GameMsgs.cs with new message types and improved structure, including methods for game state notifications and better command organization.
- Refactor PlayerJoinStarting.cs by simplifying messaging logic for cleaner code flow.
- Capitalize configuration descriptions in CS2GameConfig.cs for consistency and readability.
- Improve RoleAssigner.cs through code refactoring, optimizing argument passing for clarity.
- Add flexibility to PlayerMessageEvent.cs by introducing additional parameters for more robust event handling.

Implement Service and Localization Adjustments

- Update EventModifiedMessenger.cs to utilize IServiceProvider, adding conditional debug capabilities and preparing for future messaging enhancements.
- Transition CS2Messenger.cs from ILogger to direct console writes, supporting formatted message delivery.
- Introduce PlayerScreenMessageEvent and PlayerBackgroundMessageEvent classes to enhance player-specific event messaging.
- Leverage localization in RoundBasedGame.cs for message delivery, replacing hardcoded values and improving internationalization support.

Minor Code Enhancements and Cleanups

- Fix method signatures and imports across various files for improved consistency and readability.
- Adjust CS2Player.cs documentation for consistent terminologies.
- Clean diagram in lang/en.yml with the addition of customizable game messages for both start and cancellation scenarios.
```
2025-08-05 02:17:58 -07:00
Isaac
accd310240 Include preleases when determining versions, miscellaneous tweaks (#30) 2025-08-04 23:32:13 -07:00
MSWS
5d49a80a4a Merge branch 'main' into dev 2025-08-04 23:29:26 -07:00
MSWS
6ad656b7b2 refactor: Refactor connection handling in PlayerConnectionsHandler
- Refine settings in `TTT.sln.DotSettings` by consolidating XML tags and maintaining code style rules.
- Document missing parameter in `GiveWeapon` method of `IInventoryManager.cs`.
- Overhaul player connection logic in `PlayerConnectionsHandler.cs` by shifting focus to disconnection, replacing outdated methods, and organizing disposals.
- Note potential crash issue in `CombatHandler.cs` with a TODO, remove `OnTakeDamage` implementation, and prepare for future documentation improvements.
- Clean up `CreateGame` method in `CS2GameManager.cs` by eliminating obsolete code for better clarity.
2025-08-04 23:28:41 -07:00
MSWS
7f5cf07aae Remove unused code 2025-08-04 23:19:00 -07:00
MSWS
ef23b5dc15 Reformat and Cleanup 2025-08-04 23:15:07 -07:00
MSWS
a0c1724184 Include preleases when determining versions 2025-08-04 21:17:12 -07:00
MSWS
810150bdd5 refactor: Refactor damage handling in player events
- Modify `ArmorRemaining` property in `PlayerDamagedEvent.cs` to allow external updates and add validation for `HpLeft` to prevent invalid health values.
- Comment out old damage hooks in `CombatHandler.cs` and replace with new `OnPlayerDeath` and `OnPlayerHurt` handlers to improve event handling and consistency.
2025-08-04 21:08:49 -07:00
MSWS
17ef99bb0c Make debugs slightly more obvious 2025-08-04 20:50:23 -07:00
MSWS
2eeea9501d Remove format tests 2025-08-04 20:38:02 -07:00
MSWS
555fbfe87a Try alternative method of generating localizer 2025-08-04 20:19:13 -07:00
MSWS
0934dc86e0 Reformat 2025-08-04 20:04:03 -07:00
MSWS
aee181e352 Add more format tests 2025-08-04 19:52:23 -07:00
MSWS
740a8c14d1 refactor: Enhance extensibility and integrate CS2 system updates
Enhance Extensibility and Update API Integrations

- Make `Roles` property and `StartRound` method virtual in `RoundBasedGame.cs` to support subclass customization.
- Add logging and improve readability in `CCPlayerConverter.cs` for player conversion processes.
- Update method parameters and usage of `Server.NextWorldUpdateAsync()` in `CS2CommandManager.cs` for API adjustments.
- Add event listener registration and enhance logging in `PlayerConnectionsHandler.cs` for better handling of player connections.
- Integrate new roles and override method logic in `CS2Game.cs` for role management enhancement.

Additional changes:
- Update `CounterStrikeSharp.API` to version `1.0.331`.
- Improve `PlayerDeathEvent.cs` by removing unnecessary dead checks and making the `Victim` property non-nullable.
- Enhance event handling and logging in `Plugin/TTT.cs` for improved module loading and listener support.
- Refactor and enhance exception handling in `CombatHandler.cs` for robustness.
- Minor updates for consistency and readability across multiple files.
2025-08-04 19:07:12 -07:00
MSWS
0a68a0f060 Merge branch 'dev' 2025-08-03 04:34:15 -07:00
Isaac
882e6e70b6 test: Add validation for event listener methods +semver:patch (#29)
```
- Introduce InvalidListeners.cs to define and test invalid event listener scenarios.
- Add validation in EventBus to ensure listeners have valid event handler methods, throwing `InvalidOperationException` if invalid.
- Extend EventBusTest with new test cases for invalid listener registration, covering cases with no methods, no parameters, and incorrect parameters.
```
2025-08-03 04:31:23 -07:00
MSWS
51a95864e1 test: Add validation for event listener methods +semver:patch
```
- Introduce InvalidListeners.cs to define and test invalid event listener scenarios.
- Add validation in EventBus to ensure listeners have valid event handler methods, throwing `InvalidOperationException` if invalid.
- Extend EventBusTest with new test cases for invalid listener registration, covering cases with no methods, no parameters, and incorrect parameters.
```
2025-08-03 04:29:32 -07:00
MSWS
15b4e1c076 ci: Add label pattern extraction to changelog config
- Add new `label_extractor` configuration in `.github/changelogConfig.json` for enhanced label categorization based on title patterns, improving automation and organization in changelog generation.
2025-08-03 04:21:21 -07:00
MSWS
47bb7c3871 ci: Revamp changelog config; update workflows +semver:minor
- Delete `changelogConfig.json` to phase out or relocate changelog configurations.
- Update `.github/workflows/release.yml` to modify the `Generate Changelog` path and introduce a new "HYBRID" mode, improving changelog generation.
- Adjust `.github/workflows/release.yml` to limit the `Create GitHub Release` step to specific branches for a more efficient release process.
- Add `.github/changelogConfig.json` to include new templates and change categorization, refining the changelog structure.
2025-08-03 04:16:46 -07:00
MSWS
77a91c72f9 Fix mv command 2025-08-03 04:02:21 -07:00
MSWS
e2f9e3cd99 ci: Configure changelog generator with json file
- Add configuration for changelog generator in release workflow
2025-08-03 03:57:59 -07:00
MSWS
5c93690ab1 ci: Update release workflow and add changelog config
- Modify the artifact download step in `.github/workflows/release.yml` to skip unpacking and change the path.
- Add a new step in `.github/workflows/release.yml` to rename the artifact by appending the GitVersion output to its name.
- Update the changelog builder action to version 5 in `.github/workflows/release.yml`.
- Adjust the file reference in the release creation step in `.github/workflows/release.yml` to use the newly renamed artifact.
- Add `changelogConfig.json` configuration file with templates and defined categories for changelog items.
- Include logic in `changelogConfig.json` to ignore labels like "wip" and "ignore" and configure sorting order and template for entries.
2025-08-03 03:57:26 -07:00
MSWS
4d7e109ccf ci: Refactor release workflow permissions configuration
- Update release workflow to allow read access to pull requests.
- Modify changelog generation step to use `with:` for token input configuration.
2025-08-03 03:44:38 -07:00
Isaac
950cfa12c8 ci: Use ACTIONS_GET_PR for changelog token retrieval (#28)
- Update token retrieval in release workflow to use `ACTIONS_GET_PR`
secret instead of `GITHUB_TOKEN`.
2025-08-03 03:41:41 -07:00
MSWS
fff14f170c ci: Use ACTIONS_GET_PR for changelog token retrieval
- Update token retrieval in release workflow to use `ACTIONS_GET_PR` secret instead of `GITHUB_TOKEN`.
2025-08-03 03:38:54 -07:00
Isaac
4f3159d9c0 Include github token into changelog generator (#27) 2025-08-03 03:26:36 -07:00
MSWS
f26096c165 Merge branch 'main' into dev 2025-08-03 03:23:35 -07:00
MSWS
4b3fc19a8c Merge branch 'main' of github.com:MSWS/TTT 2025-08-03 03:23:27 -07:00
MSWS
9aa0b13e23 ci: Update release workflow for consistency and clarity
- Adjust workflow trigger condition in `.github/workflows/release.yml` to require a successful previous run.
- Update syntax for branch extraction using GitHub Actions expression in the release workflow.
- Bump `actions/checkout` to version v4.
- Modify GitVersion setup and execution to use version v4.0.1.
- Introduce conditions for creating a GitHub release only from the 'main' or 'dev' branch.
- Enhance the `Create GitHub Release` step with dynamic attributes.
- Apply formatting changes for improved clarity.
2025-08-03 03:22:36 -07:00
Isaac
f1088e458f CI Fixes (#26) 2025-08-03 03:19:43 -07:00
MSWS
3c77d5fdc1 ci: Simplify release workflow and quote names
- Remove .NET setup step in release workflow to reflect changes in dependencies or build process
- Quote workflow name in "Download artifact" step for consistency and to prevent YAML parsing issues
2025-08-03 03:15:54 -07:00
MSWS
685b3c3e61 ci: Correct artifact name in release workflow
- Update artifact download step in release workflow to use 'nightly.yml' for consistency and reference correction
2025-08-03 03:13:59 -07:00
Isaac
dcb7e82796 More CI fixes 2025-08-03 03:10:44 -07:00
MSWS
43f9a81783 ci: Update workflow trigger to 'dev' branch pushes
- Update GitHub Actions workflow to trigger on pushes to 'dev' branch instead of specific path patterns
2025-08-03 03:09:15 -07:00
Isaac
d1fe0ac606 Merge branch 'main' into dev 2025-08-03 03:08:20 -07:00
MSWS
64fceac34f ci: Update release workflow for branch flexibility
- Remove branch specification in 'Download artifact' step in release workflow to allow applicability to any branch
- Update conditional logic for creating GitHub Release to check for 'main' or 'dev' branches only
2025-08-03 03:07:34 -07:00
MSWS
7d5d7d48c3 Update artifact name 2025-08-03 03:05:56 -07:00
Isaac
21dcbf0e5a Merge pull request #24 from MSWS/dev
Fix artifact downloading
2025-08-03 03:02:33 -07:00
MSWS
6eafcb8a8c ci: Trigger nightly on release.yml file changes
- Update nightly workflow to trigger on changes to release.yml file
2025-08-03 02:57:36 -07:00
MSWS
464bad701b Merge branch 'dev' of github.com:MSWS/TTT into dev 2025-08-03 02:56:25 -07:00
MSWS
defb67b2d6 ci: Update artifact download action in release workflow
- Consolidate artifact download step in release workflow by removing duplicate actions and updating to `dawidd6/action-download-artifact`
- Add parameters for branch and workflow in artifact download step for more precise fetching
- Maintain conditional branching for GitHub release creation based on the triggering branch within the workflow
2025-08-03 02:56:07 -07:00
MSWS
7101acbdbc ci: Refine artifact handling in release workflow
- Update `.github/workflows/release.yml` to add new action permissions and refine artifact handling
- Introduce step to download 'ttt-nightly' artifact using `dawidd6/action-download-artifact@v11`
- Modify execution approach in existing build artifact download step
2025-08-03 02:55:30 -07:00
MSWS
47e81268f1 ci: Update artifact download step and permissions
- Update release workflow to improve artifact download process
  - Change artifact download action to `dawidd6/action-download-artifact@v11` and configure additional settings
  - Adjust permissions to include read access for actions
  - Rename download step ID to `download-artifact` for consistency
2025-08-03 02:45:54 -07:00
Isaac
86eab269f7 Add Credit-Based Shop System and Refactor Core TTT APIs
> ## Pull Request Overview
> 
> This is a large development pull request that adds a comprehensive shop system to the TTT plugin and refactors several core components. The changes include implementing a credit-based shop system with purchasable items, updating APIs to be more flexible with nullable types, and improving the command system architecture.
> 
> Key changes:
> 
>     * Added complete shop system with credits, items, and purchase mechanics
> 
>     * Refactored storage interfaces to support nullable return types
> 
>     * Updated messaging and command systems with improved architecture
> 
>     * Enhanced weapon system with ammo management capabilities
> 
> 
> ### Reviewed Changes
> 
> Copilot reviewed 91 out of 91 changed files in this pull request and generated 5 comments.
> Show a summary per file
> File 	Description
> TTT/Shop/* 	New shop module with credit system, purchasable items, and commands
> TTT/API/Storage/* 	Updated storage interfaces to support nullable return types
> TTT/API/Messages/* 	Simplified messenger interface by removing IOnlineMessenger
> TTT/Game/Commands/* 	Added TTT command and refactored CommandManager architecture
> TTT/CS2/* 	Updated CS2-specific implementations for new APIs
> TTT/Test/* 	Updated test infrastructure for new command and storage patterns
2025-08-03 02:40:45 -07:00
MSWS
f1ddaa04d2 Apply a few copilot suggestions, fix concurrent groups again 2025-08-03 02:35:00 -07:00
Isaac
5c34dd820a Merge branch 'main' into dev 2025-08-03 02:29:40 -07:00
Isaac
70dc321f71 Merge pull request #22 from MSWS/fix/ci
ci: Update workflows for branch condition and artifact naming
2025-08-03 02:27:51 -07:00
MSWS
3f3f6cfe0a ci: Update workflows for branch condition and artifact naming
- Update `cancel-in-progress` condition in `dotnet.yml` to exclude `main` branch runs
- Rename artifact to "ttt-nightly" in `release.yml`
2025-08-03 02:25:24 -07:00
Isaac
494c332487 Merge pull request #21 from MSWS/fix/moreReleasing
Add concurrency groups and run builds if release.yml was changed
2025-08-03 02:22:45 -07:00
MSWS
fc99b52073 ci: Update workflow concurrency and push branch settings
- Update `concurrency` configuration in `dotnet.yml` to use new syntax for branch/PR name reference
- Remove explicit `main` branch from `push` event trigger in workflow
2025-08-03 02:19:15 -07:00
MSWS
fb571cb80c ci: Update GitHub workflows for triggers and concurrency
- Restrict `.github/workflows/dotnet.yml` to trigger only on pushes to the "main" branch and expand monitored paths for changes.
- Add concurrency settings to `.github/workflows/dotnet.yml` to prevent overlapping runs.
- Disable automatic cancellation of in-progress runs in `.github/workflows/release.yml`.
- Add a blank line for improved readability in `.github/workflows/nightly.yml`.
2025-08-03 02:18:06 -07:00
Isaac
cfb3cce96b Merge pull request #19 from MSWS/fix/releaseCI
Update release workflow name
2025-08-03 02:11:32 -07:00
Isaac
b788264cd8 Merge branch 'main' into fix/releaseCI 2025-08-03 02:09:55 -07:00
Isaac
00a8b0c38d Merge pull request #20 from MSWS/fix/buildCI
Run dotnet build and test on all PRs
2025-08-03 02:09:27 -07:00
MSWS
b77cf4bbec Grant r/w perms 2025-08-03 02:07:57 -07:00
MSWS
29b45f6984 Run dotnet build and test on all PRs 2025-08-03 02:04:57 -07:00
MSWS
a27a540128 Update release workflow name 2025-08-03 02:02:22 -07:00
MSWS
344ac4a41a Merge branch 'main' into dev 2025-08-03 01:56:51 -07:00
Isaac
8ec80b33d1 Merge pull request #18 from MSWS/feat/releaseCI
Add release workflow
2025-08-03 01:56:13 -07:00
MSWS
9d801de4a1 Clean up README 2025-08-03 01:50:40 -07:00
MSWS
e50558bf4d ci: Add release workflow and update badges for consistency
- Add Discord badge to README for improved accessibility to related resources
- Create new GitHub release workflow with concurrency control, versioning, changelog generation, and artifact uploads
- Update Code Coverage badge styling in dotnet workflow to consistent `for-the-badge` design
2025-08-03 01:50:31 -07:00
MSWS
6ff8988917 refactor: Refactor roles, configs, and credit system logic.
```
Refactor and enhance role configuration, credit system, and kill handling

- **TraitorRole, DetectiveRole, and InnocentRole:** Refactored role initialization to rely on a common `RoleCfg` structure, introduced a `TargetCount` property, and tidied up logic for configuration access and player assignment.
- **CS2 Specific Roles and GameConfig:** Added custom CS2 versions of roles (e.g., CS2TraitorRole, CS2InnocentRole) with color-coded names and introduced refined configuration handling in CS2GameConfig, including improved role and round-related setups.
- **PlayerDeathEvent and Kill Handling:** Standardized player type enforcement in `PlayerDeathEvent` and added a new `PlayerKillListener` to handle credits and assists through `ShopConfig` with localized messaging.
- **Shop and Messaging System:** Enhanced the shop system by adding balance management functionality, credit multipliers, and localization support for credit-related interactions.
- **RatioBasedRole and RoleAssigner:** Refactored ratio-based role logic by replacing parameters with a `TargetCount` property and simplifying role assignment logic for clarity.
```
2025-08-02 21:40:11 -07:00
Isaac
804bd53872 Merge pull request #17 from MSWS/feat/shop
Feat/shop
2025-08-02 18:53:39 -07:00
MSWS
83f126a90b Merge branch 'feat/shop' of github.com:MSWS/TTT into feat/shop 2025-08-02 18:51:51 -07:00
MSWS
f4339ed02c Resolve copilot issues 2025-08-02 18:51:39 -07:00
Isaac
1110b2e63d Update TTT/Game/EventModifiedMessenger.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-02 18:45:11 -07:00
MSWS
b1d4536f55 feat: Refactor Deagle localization and add ShopCommand behavior
- Add `ShopCommand` behavior to `ShopServiceCollection`
- Update localization keys in `OneShotDeagle` to use `DeagleMsgs` instead of `ShopMsgs`
- Modify `ShopCommand` to register with `ICommandManager` and add required `using` directive
- Remove obsolete declarations for deagle messages in `ShopMsgs`
- Introduce `DeagleMsgs` class for managing deagle-related message creation
2025-08-02 18:42:16 -07:00
MSWS
340d2bb8e9 Refactor CommandInfo to include CallingPlayer purely 2025-08-02 18:21:34 -07:00
MSWS
5a28499d43 feat: Refactor game initialization and localization systems
```
Refactor and enhance TTT game logic, localization, and service structure

- Add `CMD_TTT` method in `GameMsgs.cs` to generate a version message; fix missing newline.
- Introduce new `CS2GameManager` class that customizes role list in `CreateGame`.
- Update `CS2ServiceCollection.cs` for dependency injection of `CS2GameManager` and restructure comments.
- Improve localization in `en.yml` with color-coded `PREFIX` and new `CMD_TTT` entry.
- Refactor `TTTCommand.cs` to use `IMsgLocalizer` for localization, replacing `IMessenger`.
- Modify `GameManager.cs` to use an `IServiceProvider` field and mark `CreateGame` as `virtual`.
- Remove `GameInitRoleListener.cs` and update role initialization logic to `CS2GameManager`.
- Adjust `GameServiceCollection.cs` by removing scoped `IGameManager` registration.
```
2025-08-02 18:01:34 -07:00
MSWS
e9ab6c591e Cleanup ShopConfig 2025-08-02 17:45:59 -07:00
MSWS
5718cebefd Reformat & Cleanup 2025-08-02 17:36:19 -07:00
MSWS
38ce3cbd51 refactor: Refactor service and messaging logic across modules
- **Cleaned up unused directives** in `GameServiceCollection.cs` by removing unused alias and using statements.
- **Improved plugin filtering** in `TTT.cs` to exclude `IPluginModule` instances when fetching `ITerrorModule` implementations.
- **Enhanced command injection logic** in `CS2CommandInfo.cs` by leveraging `IServiceProvider` for dependability and updating messaging handling with `IMessenger`.
- **Refactored and improved error handling** in `CS2CommandManager.cs`, including better error logging and updates to `ReplySync` logic with localized messaging.
- **Added a new generic error message** with placeholders for dynamic error details in `GameMsgs.cs` and updated the English language file `lang/en.yml`.

Other minor changes:
- Updated field visibility in `CommandManager.cs` for consistency.
- Added a comment to disable a namespace check in `WeaponType.cs`.
2025-08-02 17:35:11 -07:00
MSWS
4941f02f4b Change plugin to be named TTT.dll 2025-08-02 02:25:46 -07:00
MSWS
a84ff05597 Merge branch 'dev' into feat/shop 2025-08-02 02:22:01 -07:00
MSWS
fff07504db refactor: Get basic command output working with CS2
```
Refactor messaging system and improve modularity across TTT framework

- Updated `ServiceCollectionExtensions` to include a new overloaded method for plugin behavior registration, improving the modularity and reusability of extension types.
- Renamed `TTTCommand.cs` to a new directory structure, replaced `IOnlineMessenger` with `IMessenger`, and updated messaging to include TTT version information.
- Renamed and adjusted fields, logic, and dependency registrations in `CS2CommandManager`, aligning with the new command and messenger system.

Other notable changes:
- Updated `CS2GameConfig` traitor health defaults from 1000 to 100, with a new valid range.
- Cleaned unused imports and updated registration methods for various services, such as `CS2ServiceCollection` and `GameServiceCollection`.
- Improved documentation and comments for clarity while removing unnecessary or outdated elements.
```
2025-08-02 02:17:57 -07:00
MSWS
eb083fe735 feat: Add TTTCommand and enhance command/message handling
- Register new `TTTCommand` in `CS2CommandManager` and adjust command processing flow
- Create `TTTCommand` class with dependency injection, command properties, and stubbed logic
- Update `IOnlineMessenger` to support nullable players and improve type handling logic
- Modify `CS2ServiceCollection` to use `AddPluginBehavior` for `CS2CommandManager` initialization
2025-08-02 00:52:39 -07:00
MSWS
0cfff80b7f feat: Add subcommand system and improve shop command structure
- Add support for the "list" subcommand in `ShopCommand` with proper dependency setup and subcommand initialization
- Make `player` parameter nullable in `IMessenger.Message` and add nullability support
- Add `ListCommand` implementation to list shop items, utilizing dependency injection and adhering to the `ICommand` interface
- Refactor `creditsForKillCache` to `creditsForKillDictionary` in `ShopConfig` for improved naming clarity and cleaner dictionary initialization
2025-08-02 00:13:48 -07:00
MSWS
3b304cba8c feat: Refactor weapon system to use IWeapon interface.
```
Refactor and update TTT weapon, role, and shop systems

- Add `OneShotDeagle` class implementing `IWeapon` and `IShopItem` with dependency injection and localized messages.
- Replace the deprecated `GiveWeapon` method across roles (`DetectiveRole`, `TraitorRole`, `InnocentRole`) to wrap weapons in `BaseWeapon` objects.
- Create `BaseWeapon` class and `IWeapon` interface, standardizing weapon properties such as `Id`, `ReserveAmmo`, and `CurrentAmmo`.
- Refactor inventory systems (`IInventoryManager`, `CS2InventoryManager`, `FakeInventoryManager`) to accept `IWeapon` instead of string `weaponId` and add overloads for handling weapon removal.
- Restructure shop files, adding `ShopConfig` for role-related credit management and renaming/moving configurations (`ShopItemConfig` and `IShopItem`).

Additional changes:
- Update project metadata in `Shop.csproj` to target framework net8.0 and remove redundant references.
- Add `PlayerExtensions` static class to streamline weapon retrieval through LINQ and validation.
```
2025-08-02 00:02:04 -07:00
MSWS
1befb39507 feat: Implement spectator role and refactor role assignment logic
```
- Introduce `SpectatorRole` into game and replace outdated `SpectatorRole` implementation with a new version in `CS2/SpectatorRole.cs`.
- Add dependency injection for improved modularity across several files, including `RoleAssignListener.cs`, `GameManager.cs`, and `GameInitRoleListener.cs`.
- Refactor `ShopConfig.cs` to use a dictionary-based kill credit cache for optimized role-based credit retrieval.
- Update `RoundBasedGame.cs` to use a public `Roles` property and ensure fallback to default `GameConfig` values if null.
- Add new game events, including `GameInitEvent.cs` to enable customization of initialization logic.

- Minor improvements include organizing imports, adding missing newlines, cleaning up unused directives, and refining code structure in several files for better readability and maintainability.
```
2025-08-01 16:13:13 -07:00
MSWS
6ae0f29b03 Fix double-embedding of zip 2025-08-01 15:41:15 -07:00
MSWS
b20c0c2f66 feat: Refactor and expand shop system with storage and commands
```
Refactor and expand shop and storage functionality

- Update `IKeyedStorage` interface to add a `Load` method and remove `IStorage` inheritance.
- Introduce `OneShotDeagle` shop item class and configuration with placeholders for logic.
- Add new `Shop` class with player balance management, item registration, and a stubbed `TryPurchase` method.
- Implement `ShopConfig` for role-based credit logic and default credits for player actions.
- Add `PurchaseResult` enum to define outcomes of purchase operations.
- Relocate and restructure shop-related files, updating namespaces, directory structure, and references.
- Add localization support for shop items with the new `lang/en.yml` file.
- Refactor `IWriteable` and related storage interfaces, adjusting methods for clarity and functionality.
- Introduce tools like `ShopCommand`, `RoundBalanceClearer`, and `ShopMsgs` to support shop extensibility and cleanup.
- Harmonize event priority constants in `EventHandlerAttribute` for improved clarity.
```
2025-08-01 14:57:21 -07:00
MSWS
7246089859 Start work on shop 2025-08-01 13:47:01 -07:00
MSWS
883a211db5 refactor: Refactor and clean up game logic and role assignment
- Refactor `GameEndLogsListener` to replace direct instantiation of `finder` and `messenger` with static/inherited members, and simplify `OnGameEnd` logic for better clarity.
- Improve `RoleAssigner` by changing `players` parameter to `HashSet` for mutability, handling canceled events to prevent reprocessing, and enhancing role assignment error handling.
- Clean up `DetectiveRole` by removing redundant nullable `IMsgLocalizer` and referencing a globally scoped `Localizer` for consistency.
- Update `GameRestartListener` to remove direct `IGameManager` instantiation and standardize property references to align with new conventions.
- Enhance `RoundTimerListener` in CS2 to include `CounterStrikeSharp.API`, update round state commands, and refine conditional logic.
2025-08-01 13:23:33 -07:00
MSWS
5993fe0b5a refactor: Refactor role assignment logic into helper method
- Refactor `RoleAssigner` to extract role assignment logic into `tryAssignRole` helper method for improved readability and modularity
- Simplify role assignment loop by replacing `roleAssigned` flag with `tryAssignRole` return value
- Enhance variable naming for clarity and fix inefficiencies in role processing logic
- Improve code organization and reduce complexity of `AssignRoles` method
2025-08-01 13:01:19 -07:00
Isaac
277063beb0 Merge pull request #16 from MSWS/license
Add license and contributing.md
2025-08-01 05:18:10 -07:00
MSWS
4af22a85c9 Add license and contributing.md 2025-08-01 05:09:20 -07:00
MSWS
a356dea18b Update licenses 2025-08-01 04:28:36 -07:00
Isaac
081aadebb6 Merge pull request #15 from MSWS/MSWS-patch-1
Create dependabot.yml
2025-08-01 04:21:27 -07:00
Isaac
bd7104d79d Create dependabot.yml 2025-08-01 04:19:48 -07:00
MSWS
f3d0840563 Try fix empty version 2025-08-01 03:58:26 -07:00
MSWS
4cd5865381 Just label github output with version 2025-08-01 03:56:11 -07:00
MSWS
97ff684059 Force Nightly build 2025-08-01 03:45:05 -07:00
MSWS
984a235abb refactor: Refactor unused params, add GitVersion, and improve CI
- Update `OnTestEvent` and `AfterOnEvent` methods to use unused variable naming conventions for clarity (`SingleEventListener.cs` and `CancelableEventListener.cs`)
- Add GitVersion integration and improve artifact handling in `.github/workflows/nightly.yml`
- Refactor `CommandManagerTests` constructor for cleaner primary constructor usage
2025-08-01 03:43:18 -07:00
Isaac
bf1a32988e Merge pull request #14 from MSWS/dev
Refactor Game Event Handling and Build Configuration; Improve Listener Architecture and Test Coverage
2025-08-01 03:23:45 -07:00
MSWS
ead89fbba5 build: Optimize build config and improve logging transparency
- Add conditional exclusion for test language files in `Release` builds in `Locale.csproj`
- Simplify `dotnet` commands in GitHub Actions workflow
2025-08-01 02:57:06 -07:00
MSWS
d7a20a75c5 Restore before build 2025-08-01 02:45:20 -07:00
MSWS
a9c332b914 Add Listener-specific registration, include locales in nightly build 2025-08-01 02:44:17 -07:00
MSWS
e4ec9aa7a1 Add JetBrains Annotations, reformat 2025-08-01 02:28:38 -07:00
MSWS
ccb840ebb4 refactor: Refactor code for consistency, readability, and cleanup
```
- Remove unused namespace imports across multiple files to clean up code.
- Reorganize constructors, fields, and method orders for improved readability and consistency in various classes, including `RoundBasedGame`, `PlayerActionsTest`, and `GameTest`.
- Change expression-bodied methods to block-bodied methods in `EndReason`, `IGameManager`, and other API classes for consistency.
- Add, remove, or adjust newlines and braces to improve code structure and maintainability.
- Refactor `CombatHandler` to introduce memory module imports, update event dispatch logic, and improve damage-handling workflows.
```
2025-07-31 22:11:31 -07:00
MSWS
bf1daf374b Resolve compiler warning 2025-07-31 21:40:41 -07:00
MSWS
20b849fb0c refactor: Refactor and extend game round and event handling logic
```
- Add `GameRestartListener` class to handle game restarts upon end events
- Add `GameRestartingTest` to verify `GameRestartListener` functionality, including game state transitions after errors
- Refactor `PlayerActionsTest` for consistency, readability, and inheritance from `GameTest`
- Update `EndReason` constructors to simplify initialization and add overloads for improved flexibility
- Rename and refactor multiple CS2 classes (e.g., `RoundStartTimerListener`, `CombatListeners`, `PlayerListeners`) to align with updated naming conventions and broaden functionality

- Improve balance and configuration settings, including time-between-rounds support in `GameConfig` and `CS2GameConfig`
- Add `RoundEndHandler` to handle game conclusion logic and integrate with dependency injection

- Introduce `GameTest` utility class to streamline test setup and dependency management
- Apply cleanups and naming normalization across multiple files for code consistency and maintainability
```
2025-07-31 21:38:37 -07:00
MSWS
2433476585 refactor: Refactor and expand game listener and test coverage
```
Refactor and enhance game listeners and tests

- Rename `GameEndListener` to `PlayerCausesEndListener` in `GameEndListener.cs` and updated corresponding references.
- Update `RoundEndingTest.cs` to reflect the new `PlayerCausesEndListener` changes, ensuring consistency and adjusting tests for game-ending events.
- Add new test file `PlayerActionsTest.cs` to validate player-related events such as kills, damage, and role assignments, with dependency injection and comprehensive test cases.
- Rename `PlayerJoinBaseStartListener` to `PlayerJoinStarting` in `JoinStartTest.cs` and update related object instantiations.
- Introduce new `GameEndLogsListener` class to handle game-end logging, utilizing dependency injection and sending formatted log messages to players.
```
2025-07-31 20:54:59 -07:00
MSWS
11b78fa378 Update GamePlayerActionsListener to inherit from Base 2025-07-31 20:11:57 -07:00
Isaac
97cdf16f59 Merge pull request #13 from MSWS/feat/cs2Config
Introduce logging, actions, and updated listeners
2025-07-31 20:05:26 -07:00
MSWS
0077ec42ac Merge branch 'feat/cs2Config' of github.com:MSWS/TTT into feat/cs2Config 2025-07-31 19:21:01 -07:00
MSWS
d1bf0950f0 feat: Introduce logging, actions, and updated listeners
```
- Add `GamePlayerActionsListener` to manage player event handling and game actions
- Update `PlayerDamagedEvent` constructor to support fall damage and nullable weapon values
- Introduce `SimpleLogger` and `IActionLogger` for improved action logging capabilities
- Replace `PlayerDeathListener` with `GameEndListener` in tests and rename relevant files
- Add utility classes and extensions (`ServerExtensions`, `RoundUtil`, `RoundStartTimerListener`) for round and server management
```
2025-07-31 19:20:55 -07:00
MSWS
e93b0290e4 feat: Introduce logging, actions, and updated listeners
```
- Add `GamePlayerActionsListener` to manage player event handling and game actions
- Update `PlayerDamagedEvent` constructor to support fall damage and nullable weapon values
- Introduce `SimpleLogger` and `IActionLogger` for improved action logging capabilities
- Replace `PlayerDeathListener` with `GameEndListener` in tests and rename relevant files
- Add utility classes and extensions (`ServerExtensions`, `RoundUtil`, `RoundStartTimerListener`) for round and server management
```
2025-07-31 19:19:47 -07:00
Isaac
c7c2b3e09b Merge pull request #12 from MSWS/feat/cs2Config
Flesh out cs2 config
2025-07-31 17:12:18 -07:00
MSWS
e382d2195e refactor: Refactor game ending logic to use WinningRole concept
- Update `RoundBasedGame` logic to replace `WinningTeam` with `WinningRole` for clarity and consistency.
- Refactor `PlayerDeathListener` to handle draw scenarios with `EndReason` and improve winning role determination logic.
- Rename and enhance `EndReason` in the API to better handle game-ending scenarios, including updated constructors and initialization methods.
2025-07-31 17:09:12 -07:00
Isaac
19548b774d Merge branch 'main' into feat/cs2Config 2025-07-31 16:53:47 -07:00
MSWS
41bba21f9b Flesh out cs2 config 2025-07-31 16:52:19 -07:00
Isaac
a7eb5cadde Merge pull request #11 from MSWS/ms/dev
refactor: Refactor command execution checks with switch statement
2025-07-31 16:19:52 -07:00
Isaac
1707451e72 Merge pull request #8 from MSWS/feat/gameLogic
Game Logic
2025-07-31 16:19:17 -07:00
Isaac
af95f94692 Merge pull request #10 from MSWS/documentation/Locale
Flesh out readmes
2025-07-31 16:07:38 -07:00
Isaac
d78de2dd78 Merge pull request #9 from MSWS/overhaul/LocaleProgram
Overhaul LocaleProgram
2025-07-31 16:06:12 -07:00
MSWS
d8a742b413 Format 2025-07-31 16:05:27 -07:00
MSWS
029cc420a8 Overhaul LocaleProgram 2025-07-31 16:02:48 -07:00
MSWS
85626af7c7 Flesh out readmes 2025-07-31 15:59:26 -07:00
MSWS
7ccc8e886a Add more unit tests for team logic 2025-07-31 15:50:37 -07:00
MSWS
1655287ea7 refactor: Refactor command execution checks with switch statement
Refactor `CommandManager` to use a switch statement for conditional checks, improving readability and structure.
2025-07-31 15:33:29 -07:00
MSWS
02898baac1 Merge branch 'main' into feat/gameLogic 2025-07-31 15:29:22 -07:00
MSWS
5709927810 Reformat & Cleanup 2025-07-31 15:24:50 -07:00
MSWS
707b7082b4 More merge resolultions 2025-07-31 15:03:33 -07:00
MSWS
626b877905 refactor: Refactor player APIs and improve game event handling
```
Refactor player and game handling logic; improve event system robustness

- **CS2PlayerFinder.cs**: Updated return types for `AddPlayer` and `RemovePlayer` methods to ensure consistency with the updated player interfaces; added missing newline.
- **IPlayerFinder.cs**: Adjusted method return types for `AddPlayer` and `RemovePlayer` to match new API requirements.
- **EventBus.cs**: Added detailed exceptions for invalid listener signatures; fixed parameter handling in `Dispatch` to use array-based invocation.
- **TestPlayer.cs**: Removed unused `weapons` collection and methods; dropped constructor and placeholders for unused features.
- **FakePlayerFinder.cs**: Updated `AddPlayer` and `RemovePlayer` methods to include return statements and adjusted their return types.

- Introduced new game logic and event listeners:
  - **IGameManager.cs**: Added `IsGameActive` method to verify ongoing game status.
  - **PlayerDeathListener.cs**: Utilized `IsGameActive()` for game activity checks and added new `OnLeave` handler for `PlayerLeaveEvent`.
  - **PlayerDiesOnLeaveListener.cs**: Implemented new listener to handle player departures by marking them not alive and dispatching corresponding death events.
  - **PlayerDeathEvent.cs**: Refactored class structure with added validation for dead players and improved argument validation in its constructor.

- Enhanced and added new tests:
  - **DeathListenerTest.cs**: Added new test class to verify game end behavior via `PlayerDeathEvent`. Simulated player death scenarios and tested event handling.
  - **RoundBasedGameTest.cs**: Simplified test logic by reworking constructors, consolidating dependencies, and updating method calls to follow API changes.
```
2025-07-31 15:02:08 -07:00
MSWS
fe99fb0be3 refactor: Refactor game listeners and enhance player state handling
```
Refactor game listeners and improve player state management

- Add `PlayerJoinBaseStartListener` to handle game start logic, replacing `PlayerJoinGameStartListener`.
  - Prevent game start if one is already active and ensure at least 2 players are online.
  - Notify players of game start and initialize the game with a delay.
- Replace `PlayerJoinGameStartListener` with a streamlined implementation and delete the outdated class.
- Introduce `PlayerDeathListener` to manage game-ending logic based on alive players and winning roles.
- Update `IGame` interface:
  - Rename `winningTeam` to `winningRole` in the `EndGame` method.
  - Add `GetAlive` methods for player queries, including role-based filtering.
- Add abstract `BaseListener` class to centralize dependency handling and lifecycle management for listeners.
- Simplify `JoinStartTest` by removing unused dependencies and updating tests to reflect listener changes.
```
2025-07-31 15:01:54 -07:00
Isaac
94c8c42274 Merge pull request #5 from MSWS/feat/commands
Command Manager
2025-07-31 14:58:32 -07:00
MSWS
a9d081d1ee Implement FakePermissionManager 2025-07-31 14:56:46 -07:00
MSWS
2d4fb0928b refactor: Refactor command execution and permission management
```
Refactor command execution logic and update permission handling

- Add `CanExecute` method to `ICommandManager` for permission validation of commands.
- Remove `CanExecute` method from `ICommand` to shift permission validation responsibility.
- Update `CS2PermManager` implementation to use generic player types for `HasFlags` and `InGroups` methods.
- Refactor `IPermissionManager` to remove generics and explicitly use `IPlayer` type.
- Update `CommandManager` to use dependency injection for `IPermissionManager` and refactor logic to integrate the new `CanExecute` method.
```
2025-07-31 14:52:51 -07:00
MSWS
9811c5d11d More merge resolution 2025-07-31 14:43:17 -07:00
MSWS
e2a5c3fd2f Rebase main 2025-07-31 14:42:05 -07:00
Isaac
e7736693d3 Merge branch 'main' into feat/commands 2025-07-31 14:39:18 -07:00
Isaac
28268ea9e6 Overhaul/player wrapper (#7)
* Add Admin Data

* Create Command Result Enum

* Prep For Tests

* add TODO

* implement commandinfo

* create command interface

* gAdd Admin Data

# Conflicts:
#	TTT/CS2/CS2Player.cs

* Create Command Result Enum

* Prep For Tests

* add TODO

* implement commandinfo

* create command interface

* Refactor out inventory and permission to their own interfaces

* Resolve reverse group perm check

---------

Co-authored-by: ShookEagle <shookeagle@gmail.com>
2025-07-31 14:37:39 -07:00
Isaac
f01b491f8b Refactor out inventory and permission to their own interfaces (#6)
* Refactor out inventory and permission to their own interfaces

* Resolve reverse group perm check
2025-07-31 14:28:26 -07:00
MSWS
36b74bb8f8 refactor: Refactor player APIs and improve game event handling
```
Refactor player and game handling logic; improve event system robustness

- **CS2PlayerFinder.cs**: Updated return types for `AddPlayer` and `RemovePlayer` methods to ensure consistency with the updated player interfaces; added missing newline.
- **IPlayerFinder.cs**: Adjusted method return types for `AddPlayer` and `RemovePlayer` to match new API requirements.
- **EventBus.cs**: Added detailed exceptions for invalid listener signatures; fixed parameter handling in `Dispatch` to use array-based invocation.
- **TestPlayer.cs**: Removed unused `weapons` collection and methods; dropped constructor and placeholders for unused features.
- **FakePlayerFinder.cs**: Updated `AddPlayer` and `RemovePlayer` methods to include return statements and adjusted their return types.

- Introduced new game logic and event listeners:
  - **IGameManager.cs**: Added `IsGameActive` method to verify ongoing game status.
  - **PlayerDeathListener.cs**: Utilized `IsGameActive()` for game activity checks and added new `OnLeave` handler for `PlayerLeaveEvent`.
  - **PlayerDiesOnLeaveListener.cs**: Implemented new listener to handle player departures by marking them not alive and dispatching corresponding death events.
  - **PlayerDeathEvent.cs**: Refactored class structure with added validation for dead players and improved argument validation in its constructor.

- Enhanced and added new tests:
  - **DeathListenerTest.cs**: Added new test class to verify game end behavior via `PlayerDeathEvent`. Simulated player death scenarios and tested event handling.
  - **RoundBasedGameTest.cs**: Simplified test logic by reworking constructors, consolidating dependencies, and updating method calls to follow API changes.
```
2025-07-31 14:14:33 -07:00
ShookEagle
94218f819c Fix Tests 2025-07-31 11:03:04 -05:00
ShookEagle
af7d267748 Remove unused class 2025-07-31 10:55:34 -05:00
ShookEagle
8746b89d3b Implement FakeLocalizer.cs 2025-07-31 10:52:32 -05:00
ShookEagle
439d3fd84e Collect Services 2025-07-31 09:22:24 -05:00
ShookEagle
bb58d89a95 Unit Test Command Manager 2025-07-31 09:22:17 -05:00
ShookEagle
4008574418 Build Command Manager 2025-07-31 09:22:05 -05:00
ShookEagle
a2613bc96f Add ArgCount 2025-07-31 09:21:52 -05:00
ShookEagle
12acca0427 Create ICommand interface 2025-07-31 09:16:47 -05:00
ShookEagle
8efd5efc10 Update Player Tests 2025-07-31 09:16:27 -05:00
ShookEagle
153b82a3ad Add Command Locales 2025-07-31 09:16:17 -05:00
Reece
c2b6b1aceb Merge pull request #4 from MSWS/feat/commands-update
Feat/commands update
2025-07-31 07:30:25 -05:00
MSWS
a56d2bf8de refactor: Refactor game listeners and enhance player state handling
```
Refactor game listeners and improve player state management

- Add `PlayerJoinBaseStartListener` to handle game start logic, replacing `PlayerJoinGameStartListener`.
  - Prevent game start if one is already active and ensure at least 2 players are online.
  - Notify players of game start and initialize the game with a delay.
- Replace `PlayerJoinGameStartListener` with a streamlined implementation and delete the outdated class.
- Introduce `PlayerDeathListener` to manage game-ending logic based on alive players and winning roles.
- Update `IGame` interface:
  - Rename `winningTeam` to `winningRole` in the `EndGame` method.
  - Add `GetAlive` methods for player queries, including role-based filtering.
- Add abstract `BaseListener` class to centralize dependency handling and lifecycle management for listeners.
- Simplify `JoinStartTest` by removing unused dependencies and updating tests to reflect listener changes.
```
2025-07-30 22:33:36 -07:00
MSWS
040e035717 Refactor out inventory and permission to their own interfaces 2025-07-30 22:02:12 -07:00
MSWS
c20ee525ff Merge branch 'feat/commands-update' of github.com:MSWS/TTT into feat/commands-update 2025-07-30 21:23:34 -07:00
ShookEagle
e0452a0409 create command interface 2025-07-30 21:23:27 -07:00
ShookEagle
f4929f41b9 implement commandinfo 2025-07-30 21:23:27 -07:00
ShookEagle
f76137ab1d add TODO 2025-07-30 21:23:27 -07:00
ShookEagle
88d72c4e21 Prep For Tests 2025-07-30 21:23:27 -07:00
ShookEagle
de89168bfd Create Command Result Enum 2025-07-30 21:23:27 -07:00
ShookEagle
38352aa80c gAdd Admin Data
# Conflicts:
#	TTT/CS2/CS2Player.cs
2025-07-30 21:23:24 -07:00
Isaac
b1076981a3 Ms/dev (#3)
* Overhaul locale structure

* Reformat & Cleanup

* refactor: Refactor roles to use dependency injection.

```
Introduce dependency injection and refactor role architecture

- Refactor `RoleAssignerTest` to use `IServiceProvider` for dependency injection, update role initialization, and align test cases accordingly.
- Update `IOnlinePlayer` and `IGame` interfaces to use the fully qualified namespace for roles and modify method signatures to reflect new role architecture.
- Add `BaseRole` abstract class and refactor role classes (e.g., `InnocentRole`, `DetectiveRole`, `TraitorRole`, `RatioBasedRole`) to inherit from it, implementing dependency injection and overriding key properties and methods.
- Introduce new storage interfaces (`IStorage<T>`, `IWriteable<T>`, `IKeyedStorage<T>`) for improved configuration management and add related test implementations (e.g., `FakeConfig`, `MemoryStorage`).
- Add `GameConfig` class for configurable game and round settings, implement `CS2GameConfig` class to manage configuration storage and plugin module lifecycle, and refactor `RoundBasedGame` to leverage the new configuration structure.
```

* Fix lang copying

* Rename step

* Add debug

* Fix path

* refactor: Refactor roles and role assignment for consistency.

```
Refactor roles and role assignment logic for improved consistency and dependency management

- Refactor `DetectiveRole` to replace `localizer` with `Localizer` property, implement `OnAssign` for player configuration, and improve overall consistency.
- Update `RoleAssigner` to use `IServiceProvider` for dependency injection and call `OnAssign` during role assignment.
- Simplify `RoundBasedGame` constructor and remove redundant fields, improving initialization and readability.
- Adjust `TraitorRole` to use the refactored `Localizer` property, override `OnAssign`, and streamline weapon assignment logic.
- Refactor `BaseRole` to support dependency injection via new protected fields and updated initializations.

Additional: Improved unit tests for `RoleAssigner` and updated `InnocentRole` to align with new role assignment structure.
```

* Reformat and Cleanup
2025-07-30 21:19:12 -07:00
Isaac
c51f85ffd3 Update locale structure, begin config API (#2)
* Overhaul locale structure

* Reformat & Cleanup

* refactor: Refactor roles to use dependency injection.

```
Introduce dependency injection and refactor role architecture

- Refactor `RoleAssignerTest` to use `IServiceProvider` for dependency injection, update role initialization, and align test cases accordingly.
- Update `IOnlinePlayer` and `IGame` interfaces to use the fully qualified namespace for roles and modify method signatures to reflect new role architecture.
- Add `BaseRole` abstract class and refactor role classes (e.g., `InnocentRole`, `DetectiveRole`, `TraitorRole`, `RatioBasedRole`) to inherit from it, implementing dependency injection and overriding key properties and methods.
- Introduce new storage interfaces (`IStorage<T>`, `IWriteable<T>`, `IKeyedStorage<T>`) for improved configuration management and add related test implementations (e.g., `FakeConfig`, `MemoryStorage`).
- Add `GameConfig` class for configurable game and round settings, implement `CS2GameConfig` class to manage configuration storage and plugin module lifecycle, and refactor `RoundBasedGame` to leverage the new configuration structure.
```

* Fix lang copying

* Rename step

* Add debug

* Fix path
2025-07-30 20:10:40 -07:00
ShookEagle
33c0ce5d9a create command interface 2025-07-30 18:27:22 -05:00
ShookEagle
654333c883 implement commandinfo 2025-07-30 18:27:13 -05:00
ShookEagle
dd4291c5d5 add TODO 2025-07-30 18:27:03 -05:00
ShookEagle
9b6c027ce5 Prep For Tests 2025-07-30 18:26:31 -05:00
ShookEagle
93164d9436 Create Command Result Enum 2025-07-30 18:23:40 -05:00
ShookEagle
dadc4a1c2f Add Admin Data 2025-07-30 18:23:27 -05:00
Isaac
8eb09b27e8 Add more locale tests and licenses (#1)
* More localization, add MIT License

* Add all licenses

* Finish up locale tests for now

* Run dotnet on all branches
2025-07-30 16:21:31 -07:00
MSWS
942b46ba72 Add more localization tests 2025-07-30 06:55:50 -07:00
MSWS
9a66dbccf9 Fix compiler warning and Versioning Namespace 2025-07-30 06:08:00 -07:00
MSWS
b44c73cf87 feat: Add IMsgLocalizer and improve localization support
```
Introduce IMsgLocalizer interface and improve localization functionality

- Extend `StringLocalizer` to support `IMsg` object localization and implement the new `IMsgLocalizer` interface.
- Update `.github/workflows/dotnet.yml` to use newer Actions versions, enable coverage tracking, and generate dynamic coverage badges.
- Add `IMsgLocalizer` interface and implement localization indexer in `IMsgLocalizer.cs`.
- Update dependency injection in `Startup.cs` to register `IMsgLocalizer` and refine localization services.
- Improve tests in `LocaleTest.cs` to validate `IMsgLocalizer` usage, placeholder substitution, and remove redundant assertions.

Minor: Adjust `en.yml` formatting by removing unnecessary quotes.
```
2025-07-30 03:59:53 -07:00
MSWS
aa37d6e78a ci: Add step to copy "lang" folder in build output
- Update .NET GitHub Actions workflow to include step for copying "lang" folder to build output directory
2025-07-30 03:41:48 -07:00
MSWS
7d71bcc72e Fix OS specific path again 2025-07-30 03:38:00 -07:00
MSWS
ffc09cc3f4 Add Localization 2025-07-30 03:32:31 -07:00
MSWS
642745b156 refactor: Refactor namespaces, interfaces, and game logic
```
Refactor namespaces, improve naming consistency, and enhance game and role functionality

- **JoinMessageTest.cs**: Updated to use `IPlayerFinder` and fixed method casing.
- **CS2Player.cs and CCPlayerConverter.cs**: Added new `using` directives, introduced nullable checks, and implemented `GetPlayer` functionality in `CCPlayerConverter`.
- **RoundBasedGame.cs**: Renamed methods, improved game state handling, and added `EndGame` and `Dispose` methods.
- **CS2/CS2PlayerFinder.cs**: Added a new class implementing `IPlayerFinder` with methods utilizing `TTT.API.Player`.
- **Test/Game/Roles/RoleAssignerTest.cs**: Refactored to use a new `TestRoles` structure and added a cancellation-based test for role assignment.
- Moved and renamed multiple files (e.g., `IRoleAssigner`, `IGame`, `IGameManager`) to align with updated directory structure.
- Newly created files include `RoleAssignListener`, `RoleAssignCanceler`, and `TestRoles`.

Miscellaneous:
- Changed various method names to follow PascalCase conventions (e.g., `addPlayer` to `AddPlayer`).
- Streamlined imports across multiple files to align with updated namespaces and dependencies.
- Removed and relocated legacy files (`Channel.cs`) to clean up outdated definitions.
```
2025-07-29 22:28:23 -07:00
MSWS
d2ffe04da4 Optimize & Cleanup 2025-07-29 21:36:02 -07:00
MSWS
511afc0dfb Add init tests 2025-07-29 21:34:44 -07:00
MSWS
f6ef176fdd ci: Update .NET workflow to use v4 and add coverage summary
- Update actions/checkout and setup-dotnet to v4 in dotnet.yml
- Target .NET 8.0.x in Setup .NET step
- Modify test execution to run Test.dll directly from build output
- Add step to write code coverage results to GitHub Job Summary
2025-07-29 20:37:32 -07:00
MSWS
2d555ec15b Have dotnet run it 2025-07-29 20:27:59 -07:00
MSWS
0a8d72053d Disable compression 2025-07-29 20:24:43 -07:00
MSWS
348ed914f1 chmod to allow executing the test 2025-07-29 20:23:30 -07:00
MSWS
00be65d9e1 Fix Test dll path 2025-07-29 20:21:13 -07:00
MSWS
ccecc714e1 Keep configuration consistent 2025-07-29 20:18:01 -07:00
MSWS
436b340ea0 Try to fix unit tests 2025-07-29 20:10:16 -07:00
MSWS
e09080253a Fix Test dir again 2025-07-29 20:06:16 -07:00
MSWS
1042dc2647 Separate test 2025-07-29 20:04:30 -07:00
MSWS
6d91642171 Begin work on optimizing build + test 2025-07-29 20:01:40 -07:00
MSWS
4145c40aa1 Add .runsettings 2025-07-29 19:53:42 -07:00
MSWS
4eb61bad05 Adjust namespaces 2025-07-29 19:19:28 -07:00
MSWS
fea28e19f6 ci: Update coverage report paths in dotnet workflow
- Update coverage output path in dotnet workflow to use environment variable
- Simplify filename for Code Coverage Summary Report configuration
2025-07-29 19:13:42 -07:00
MSWS
e4105090f8 Exclude more stuff from code coverage 2025-07-29 19:09:12 -07:00
MSWS
86756df7ce Fix unit test setup, add READMEs 2025-07-29 19:07:45 -07:00
MSWS
b4b960adda Allow publish to build instead 2025-07-29 18:37:15 -07:00
MSWS
6f6e377d3c Try explicitly stating output dir 2025-07-29 18:33:16 -07:00
MSWS
1c2f7a5bc1 Fix Plugin.csproj to reflect deeper placement 2025-07-29 18:28:04 -07:00
MSWS
d33c7ccbad ci: Simplify CI by removing GitVersion and fixing test paths
- Update `.github/workflows/dotnet.yml` to remove GitVersion step and fix test project path
- Adjust `TTT/Directory.Build.props` to exclude certain `ItemGroup` conditions during CI on non-Windows platforms
2025-07-29 18:25:11 -07:00
MSWS
2ebfa68683 Fix || -> Or 2025-07-29 18:21:20 -07:00
MSWS
c8655dc437 Try just allowing it on GitHub CI 2025-07-29 18:20:03 -07:00
MSWS
0fa508b4fb Update CI to reflect new structure 2025-07-29 18:14:05 -07:00
MSWS
31ea9ed6ae Fix path triggers again 2025-07-29 18:12:00 -07:00
MSWS
c62e008a40 Fix includes path 2025-07-29 18:10:49 -07:00
MSWS
ee6649376f Overhaul file structure 2025-07-29 18:06:37 -07:00
MSWS
10118c9123 ci: Add GitVersion steps to build and test workflows
- Add `Run GitVersion` step to build and test jobs in `.github/workflows/dotnet.yml` for version output and consistency
- Include GitVersion installation step in test job
2025-07-29 18:01:53 -07:00
MSWS
df64cd573b ci: Refactor GitVersion handling for cross-platform builds
- Remove `GenerateGitVersionInformation` target block from `Directory.Build.props` for non-Windows OS compatibility.
- Add GitVersion execution step in `.github/workflows/dotnet.yml` test job.
- Comment out custom Git version generation target in `Versioning/Versioning.csproj` for future reference.
2025-07-29 17:59:42 -07:00
MSWS
2ee5b898f9 Fix versioning project name 2025-07-29 17:54:38 -07:00
MSWS
eee7cca182 Follow documentation for gittools 2025-07-29 17:51:39 -07:00
MSWS
7abca18738 Try disabling global flag 2025-07-29 17:46:46 -07:00
MSWS
1f0fc0cc34 ci: Install gitversion in CI 2025-07-29 17:44:42 -07:00
MSWS
528398acd6 Add DirectoryBuildProps to triggers 2025-07-29 17:42:38 -07:00
MSWS
2eeb1a2e93 build: Refactor GitVersion target and clean up build properties
- Refactor `Directory.Build.props`:
  - Add blank line between `<ItemGroup>` elements for clarity.
  - Remove redundant condition from `GitVersion.MsBuild` package reference.
  - Update `GenerateGitVersionInformation` target to execute `BeforeCompile` instead of `BeforeBuild`.
  - Replace `<PropertyGroup>` elements with explicit `<Exec>` commands in the `GenerateGitVersionInformation` target.
  - Modify `<Exec>` command syntax for consistency with other entries.
2025-07-29 17:40:51 -07:00
MSWS
f7e597ec1a Attempt to solve linux-specific issues 2025-07-29 17:37:28 -07:00
MSWS
999ba67d2b Additional unit testing and slight signature update 2025-07-29 16:50:34 -07:00
MSWS
c67bd3b919 feat: Add countdown parameter to game start method
- Update `Start` method across game logic to include a configurable countdown parameter
- Adjust `RoundBasedGameTest` to reflect new countdown logic and validate state transitions during delayed starts
- Modify `PlayerJoinGameStartListener` to pass a 5-second countdown when starting the game
- Update `IGame` interface to support countdown parameter in `Start` method and revise documentation accordingly
2025-07-29 16:31:11 -07:00
MSWS
a02583a800 Add Nix-OS specific files 2025-07-29 16:28:05 -07:00
MSWS
6ada09a37b Fix OS-specific issues 2025-07-29 16:14:10 -07:00
MSWS
c56b9f6e03 Tidy up repo 2025-07-29 15:52:53 -07:00
MSWS
33b8d1678f Format & Optimize 2025-07-28 23:11:38 -07:00
MSWS
905734ac3d test: Add tests and state handling for game start and rounds
- Rename `State.cs` in `TTT.Game` without modifying its content.
- Register `IGameManager` with `GameManager` implementation in `TTT.Test/Startup.cs`.
- Add new tests for joining games in `JoinStartTest.cs` to handle state transitions and messaging.
- Update logic in `RoundBasedGame.cs` to notify players of countdown interruptions and handle insufficient players during round start.
- Add `State` property to `IGame` interface and fix formatting in `TTT.Api/IGame.cs`.
- Simplify `DetectiveRole` constructor logic and clean up formatting in `TTT.Game/Roles/DetectiveRole.cs`.
2025-07-28 23:10:41 -07:00
MSWS
2e0a4e7ca4 Improve role balancing 2025-07-28 22:45:14 -07:00
MSWS
42ab80a350 Always generate code coverage summary 2025-07-28 21:41:34 -07:00
MSWS
4b78f49f08 ci: Simplify code coverage conditions in workflows
- Simplify code coverage conditional checks in dotnet workflow
- Remove conditional execution of export code coverage step based on .NET version
2025-07-28 21:34:38 -07:00
MSWS
7afe4c1445 ci: Update coverage file path in dotnet.yml workflow
Update coverage file path in GitHub Actions workflow

- Update the file path in `.github/workflows/dotnet.yml` to use a specific coverage file instead of a generic pattern.
2025-07-28 21:32:24 -07:00
MSWS
555951f898 ci: Update test coverage file path in dotnet workflow
Update test coverage file path in dotnet.yml workflow
2025-07-28 21:28:57 -07:00
MSWS
8464430503 ci: Add restore and build steps to test job in dotnet CI
Add steps for restoring dependencies and building in test job
2025-07-28 21:25:49 -07:00
MSWS
e92093439c ci: Simplify dotnet.yml test job and fix command syntax
- Update `.github/workflows/dotnet.yml` to streamline the test job by removing the dependency restoration step and unused commented-out build step, and adding quotes around the test command for consistency.
2025-07-28 21:23:40 -07:00
MSWS
f697c1bf43 ci: Update dotnet workflow to refine test job execution
- Update .NET GitHub Actions workflow
  - Comment out the build step in the test job
  - Adjust `dotnet run` command to include explicit `--project` flag
2025-07-28 21:17:20 -07:00
MSWS
7ca9acf195 ci: Align dotnet test workflow with build phase steps
- Update test job in dotnet.yml workflow to align processes with build phase
- Remove explicit project path from dotnet restore command in test job
2025-07-28 21:15:24 -07:00
MSWS
e3a46e4088 Fix path again 2025-07-28 21:11:49 -07:00
MSWS
7a993e81bc ci: Fix project paths in dotnet workflow commands
- Fix project path in restore dependencies command in dotnet.yml
- Update project path in dotnet run command in dotnet.yml
2025-07-28 21:09:54 -07:00
MSWS
9455e204c2 ci: Refactor and enhance project structure and tooling.
```
- Update `TTT.Api.csproj` to target .NET 8.0, add GitVersion.MsBuild reference, and retain existing package references.
- Modify `.github/workflows/dotnet.yml` to split test and build jobs, report code coverage, and introduce conditional tasks.
- Add code coverage badge to `README.md` and improve formatting.
- Remove debug-related properties and add GitVersion.MsBuild reference in `TTT.Game.csproj` and `TTT.CS2.csproj`.
- Clean up unused imports and update namespaces in `IPlayerConverter.cs` and other listener files to align with `TTT.Api.Player`.
```
2025-07-28 21:07:45 -07:00
MSWS
42ec1468a1 Re-enable debug symbols for code coverage 2025-07-28 20:35:34 -07:00
MSWS
08c2a67e4a build: Remove GenerateGitVersion tool and update TTT.Game debug settings
- Remove `GenerateGitVersion` project and related C# program
- Update `TTT.Game.csproj` to disable debug symbols and set debug type to none
2025-07-28 20:03:31 -07:00
MSWS
da569181a3 build: Refactor build configs and remove deprecated projects
```
- Remove "tools" and "GenerateGitVersion" projects from TTT.sln and their associated configuration and mappings.
- Update TTT.Plugin.csproj with improved publish configuration, including new properties, versioned ZIP output, and refined file handling.
- Disable debug symbols and set debug type to none in TTT.CS2.csproj.
```
2025-07-28 20:02:23 -07:00
MSWS
972f647a7a ci: Update workflow triggers for branches and paths
Update trigger configuration in dotnet workflow
2025-07-28 19:44:54 -07:00
MSWS
39b6190902 Disable caching in nightly 2025-07-28 19:44:05 -07:00
MSWS
267059b51b ci: Update GitHub Actions checkout configurations
- Fix formatting in `nightly.yml`
- Update `dotnet.yml` with enhanced `actions/checkout` configuration, including `fetch-depth` set to 0, enabled `fetch-tags`, and `show-progress`.
2025-07-28 19:42:02 -07:00
MSWS
61c059934b Start reworking gitversioning 2025-07-28 19:39:47 -07:00
MSWS
0aecb56de0 Update dotnet path 2025-07-28 19:23:30 -07:00
MSWS
effa2a277c Add workflows 2025-07-28 19:21:54 -07:00
MSWS
5df2a6e5f9 feat: Introduce reactive support and enhance DI across modules
```
Add new features, interfaces, and improve dependency injection across multiple components

- Update `IGameManager` interface to include the `ActiveGame` property and `CreateGame` method.
- Add `DelayAsync` method to the `IDelayer` interface for asynchronous delays utilizing `TimeSpan`.
- Implement dependency injection for `IOnlineMessenger`, `IRoleAssigner`, and `TestScheduler` in `TTT.Test/Startup.cs`.
- Enhance `FakeMessenger` to implement `IOnlineMessenger` and update messaging logic with stricter type validation and new methods.
- Modify `removePlayer` logic in `FakePlayerFinder` to use `Id` for player matching, with improved filtering via `RemoveWhere`.

- Register `IScheduler` in `TTTServiceCollection` and restructure module loading logic in `TTT.Plugin/TTT.cs`.
- Update `IGame` interface to make `Start` method return an `IObservable<long>` for reactive support.
- Implement new tests in `RoundBasedGameTest` to cover game state transitions based on players and delays.
```
2025-07-28 19:12:11 -07:00
MSWS
80201c94d5 Start work on concrete loading 2025-07-28 18:06:41 -07:00
MSWS
caa985023d Figure out time-based unit tests 2025-07-28 17:49:00 -07:00
MSWS
59ff2bd608 Format and add Windows Support 2025-07-28 15:18:52 -07:00
MSWS
e062d77955 feat: Introduce IRoleAssigner for role assignment refactor 2025-07-28 14:31:03 -07:00
MSWS
e4980eca4c Add more player methods 2025-07-28 14:12:22 -07:00
MSWS
c8b5941837 Reformat & Cleanup 2025-07-28 13:26:40 -07:00
MSWS
404fef40b0 More work on events 2025-07-28 13:26:14 -07:00
MSWS
c47851f4c5 Start work on messaging 2025-07-28 09:31:51 -07:00
MSWS
08adb86f65 Rename Test/Core -> Test/Game to match previous reorganization 2025-07-28 08:33:37 -07:00
MSWS
336335a854 Finish reorganizing 2025-07-28 08:29:20 -07:00
MSWS
a52885f586 Reorganize 2025-07-28 08:21:25 -07:00
MSWS
c935acb0a8 Figure out versioning again 2025-07-28 06:31:17 -07:00
MSWS
75af41c922 Move TTT.Core into repo 2025-07-28 05:49:17 -07:00
MSWS
4c76f089d3 Clean up repo, add event stuff 2025-07-28 05:44:29 -07:00
558 changed files with 25798 additions and 830 deletions

3
.envrc Normal file
View File

@@ -0,0 +1,3 @@
use nix
PATH_add ~/.dotnet/tools

15
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# These are supported funding model platforms
github: [msws] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: msws # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

14
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@@ -0,0 +1,14 @@
---
name: Bug Report
about: Report an unintended behavior
title: ''
labels: 'Type: Bug'
assignees: ''
---
**Summary**
**Reproduction**
**Expected Behavior**

76
.github/changelogConfig.json vendored Normal file
View File

@@ -0,0 +1,76 @@
{
"template": "#{{CHANGELOG}}\n\n_#{{CONTRIBUTORS}} contributed across #{{COMMITS}} commits; see #{{RELEASE_DIFF}}_\n",
"pr_template": "- ##{{NUMBER}}: #{{TITLE}} (by @#{{AUTHOR}}) — ##{{URL}}",
"commit_template": "- #{{TITLE}}",
"empty_template": "- No changes",
"sort": { "order": "DESC", "on_property": "mergedAt" },
"ignore_labels": ["skip-changelog"],
"base_branches": ["main", "dev"],
"categories": [
{
"title": "## Breaking Changes",
"empty_content": "",
"rules": [
{ "pattern": "BREAKING CHANGE", "on_property": "body" },
{ "pattern": "!", "on_property": "title" }
],
"mode": "HYBRID"
},
{
"title": "## Features",
"labels": ["feature", "feat"]
},
{
"title": "## Fixes",
"labels": ["fix", "bug"]
},
{
"title": "## Security",
"labels": ["security", "vulnerability"]
},
{
"title": "## Performance",
"labels": ["perf"]
},
{
"title": "## Refactors",
"labels": ["refactor"]
},
{
"title": "## Docs",
"labels": ["docs", "documentation"]
},
{
"title": "## CI / CD",
"labels": ["ci", "cd", "build", "workflow", "test"]
},
{
"title": "## Dependencies",
"labels": ["dependencies", "dependabot"]
},
{
"title": "### Other",
"labels": []
}
],
"label_extractor": [
{
"pattern": "^(build|chore|ci|cd|workflow|docs|feat|feature|fix|bug|perf|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: [\\s\\S]+$",
"on_property": "title",
"target": "$1"
}
],
"duplicate_filter": {
"pattern": "\\(#\\d+\\)$",
"on_property": "title",
"method": "match"
},
"reference": {
"pattern": "\\(#(\\d+)\\)",
"on_property": "body",
"method": "match",
"target": "$1"
},
"trim_values": true,
"max_back_track_time_days": 365
}

17
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "dotnet-sdk" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
target-branch: "dev"
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
target-branch: "dev"

104
.github/workflows/dotnet.yml vendored Normal file
View File

@@ -0,0 +1,104 @@
name: .NET Build and Test
on:
push:
branches:
- dev
pull_request:
concurrency:
group: ${{ github.head_ref || github.ref_name }}
cancel-in-progress: ${{ !( github.ref_name == 'main' || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') ) }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
fetch-tags: true
show-progress: true
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '8.0.x'
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Copy Locales
run: |
mkdir -p build_output/lang/
cp lang/*.json build_output/lang/
- name: Publish Test Project
run: dotnet publish TTT/Test/Test.csproj --no-restore --no-build -o build_output -c Debug
- uses: actions/upload-artifact@v5
with:
name: build_output
path: build_output
retention-days: 1
compression-level: '0'
test:
runs-on: ubuntu-latest
needs: build
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v5
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '8.0.x'
- name: Download Build Output
uses: actions/download-artifact@v6
with:
name: build_output
path: build_output
- name: Run tests
run: "dotnet ./build_output/Test.dll --coverage --coverage-output $GITHUB_WORKSPACE/coverage.xml --coverage-output-format cobertura"
- name: Code Coverage Summary Report
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: 'coverage.xml'
badge: true
format: 'markdown'
output: 'both'
- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request'
with:
recreate: true
path: code-coverage-results.md
- name: Export Code Coverage
run: echo "CODE_COVERAGE=$(tail -n 1 code-coverage-results.md | grep -oP '(?<=\*\*Summary\*\* \|\s\*\*)[0-9]+(?=%)')" >> $GITHUB_ENV
- name: Create Test Coverage Badge
uses: Schneegans/dynamic-badges-action@v1.7.0
id: create_coverage_badge
if: github.ref_name == 'main'
with:
auth: ${{ secrets.GIST_AUTH_TOKEN }}
gistID: 6289e1f34da3b70fbba5f84f5ffb25a1
filename: code-coverage.json
label: 'Code Coverage'
message: ${{ env.CODE_COVERAGE }}%
valColorRange: ${{ env.CODE_COVERAGE }}
maxColorRange: 100
minColorRange: 33
style: 'for-the-badge'
- name: Write to Job Summary
run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY

88
.github/workflows/nightly.yml vendored Normal file
View File

@@ -0,0 +1,88 @@
name: Nightly
on:
push:
branches:
- dev
- main
paths:
- 'TTT/**'
- '.github/workflows/nightly.yml'
- '.github/workflows/release.yml'
schedule:
- cron: '15 0 * * 3' # Every Wednesday at 00:15 UTC
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
show-progress: true
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Install GitVersion
uses: GitTools/actions/gitversion/setup@v4.0.1
with:
versionSpec: '6.3.x'
- name: Run GitVersion
id: gitversion
uses: GitTools/actions/gitversion/execute@v4.0.1
- name: Output Version to Summary
run: "echo \"## GitVersion: ${{ steps.gitversion.outputs.fullSemVer }}\" >> $GITHUB_STEP_SUMMARY"
- name: Build Locale
run: |
mkdir -p build/TTT/lang
dotnet restore Locale/Locale.csproj
dotnet build Locale/Locale.csproj --no-restore -c Release
cp lang/*.json build/TTT/lang
- name: Copy Gamedata
run: |
mkdir -p build/TTT/gamedata
cp -r TTT/CS2/gamedata/* build/TTT/gamedata
- name: Publish Plugin
run: |
dotnet restore TTT/Plugin/Plugin.csproj
if [ "${GITHUB_REF##*/}" = "dev" ]; then
dotnet publish TTT/Plugin/Plugin.csproj --no-restore -c Debug -o build/TTT
elif [ "${GITHUB_REF##*/}" = "main" ]; then
dotnet publish TTT/Plugin/Plugin.csproj --no-restore -c Release -o build/TTT
else
echo "Branch not recognized, skipping publish."
exit 0
fi
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: TTT
path: build/TTT
if-no-files-found: error
post_webhook:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/dev'
steps:
- name: POST Webhook
run: |
curl -X POST \
--fail \
-F token=${{ secrets.GITLAB_SECRET_TOKEN }} \
-F ref=dev \
https://gitlab.edgegamers.io/api/v4/projects/2640/trigger/pipeline

236
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,236 @@
name: Auto Release on SemVer Change
on:
push:
branches:
- main
- dev
permissions:
contents: write
jobs:
auto-release:
runs-on: ubuntu-latest
env:
OPENAI_MODEL: gpt-4o-mini
OPENAI_TEMPERATURE: "0.3"
MAX_CHANGELOG_CHARS: "50000"
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
fetch-tags: true
# 1. Calculate version using GitVersion
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v4
with:
versionSpec: '6.3.x'
- name: Run GitVersion
id: gitversion
uses: gittools/actions/gitversion/execute@v4
# Early exit guard: if tag already exists, mark and skip all following steps
- name: Check if tag exists
id: tag_exists
run: |
set -euo pipefail
git fetch --tags --force
TAG="${{ steps.gitversion.outputs.fullSemVer }}"
if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Tag ${TAG} already exists locally."
elif git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "refs/tags/${TAG}$"; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Tag ${TAG} already exists on origin."
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "Tag ${TAG} does not exist. Continuing."
fi
# Short-circuit info step for logs
- name: Tag exists, nothing to do
if: steps.tag_exists.outputs.exists == 'true'
run: echo "Release already exists for tag ${{ steps.gitversion.outputs.fullSemVer }}. Exiting successfully."
- name: Build Locale
if: steps.tag_exists.outputs.exists != 'true'
run: |
mkdir -p build/TTT/lang
dotnet restore Locale/Locale.csproj
dotnet build Locale/Locale.csproj --no-restore -c Release
cp lang/*.json build/TTT/lang
- name: Copy Gamedata
if: steps.tag_exists.outputs.exists != 'true'
run: |
mkdir -p build/TTT/gamedata
cp -r TTT/CS2/gamedata/* build/TTT/gamedata
- name: Publish Plugin
if: steps.tag_exists.outputs.exists != 'true'
run: |
dotnet restore TTT/Plugin/Plugin.csproj
dotnet publish TTT/Plugin/Plugin.csproj --no-restore -c Release -o build/TTT
- name: Zip Artifacts
if: steps.tag_exists.outputs.exists != 'true'
run: |
cd build/TTT
zip -r TTT-${{ steps.gitversion.outputs.fullSemVer }}.zip *
# 2. Get latest tag
- name: Get latest tag
if: steps.tag_exists.outputs.exists != 'true'
id: latest_tag
run: |
if git describe --tags --abbrev=0 >/dev/null 2>&1; then
echo "tag=$(git describe --tags --abbrev=0)" >> $GITHUB_OUTPUT
else
echo "tag=0.0.0" >> $GITHUB_OUTPUT
fi
- name: Create and push new tag
if: steps.tag_exists.outputs.exists != 'true' && steps.gitversion.outputs.fullSemVer != steps.latest_tag.outputs.tag
run: |
set -euo pipefail
TAG="${{ steps.gitversion.outputs.fullSemVer }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if ! git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
git tag "${TAG}"
fi
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q "refs/tags/${TAG}$"; then
echo "Tag ${TAG} already on origin. Skipping push."
else
git push origin "${TAG}"
fi
- name: Determine previous relevant tag
if: steps.tag_exists.outputs.exists != 'true'
id: prev_tag
run: |
set -euo pipefail
branch="${GITHUB_REF_NAME}"
if git rev-parse --verify -q HEAD^ >/dev/null; then
base_rev="HEAD^"
else
base_rev="HEAD"
fi
if [[ "$branch" == "main" ]]; then
pattern='[0-9]*.[0-9]*.[0-9]*'
else
pattern='[0-9]*.[0-9]*.[0-9]*-*'
fi
prev=$(git describe --tags --abbrev=0 --match "$pattern" --tags "$base_rev" 2>/dev/null || true)
echo "tag=${prev:-0.0.0}" >> "$GITHUB_OUTPUT"
- name: Generate changelog
if: steps.tag_exists.outputs.exists != 'true'
run: |
set -euo pipefail
prev="${{ steps.prev_tag.outputs.tag }}"
curr="${{ steps.gitversion.outputs.fullSemVer }}"
GIT_LOG_FORMAT='%B'
if [[ "$prev" == "0.0.0" ]]; then
git log --no-merges --format="${GIT_LOG_FORMAT}" --reverse "$curr" > CHANGELOG.md
else
git log --no-merges --format="${GIT_LOG_FORMAT}" --reverse "$prev..$curr" > CHANGELOG.md
fi
if [[ ! -s CHANGELOG.md ]]; then
echo "No commits found between $prev and $curr on first-parent. Using full messages without first-parent filter." >&2
if [[ "$prev" == "0.0.0" ]]; then
git log --no-merges --format="${GIT_LOG_FORMAT}" --reverse "$curr" > CHANGELOG.md
else
git log --no-merges --format="${GIT_LOG_FORMAT}" --reverse "$prev..$curr" > CHANGELOG.md
fi
fi
cat CHANGELOG.md
- name: Rewrite changelog with OpenAI
id: ai_changelog
if: steps.tag_exists.outputs.exists != 'true'
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_MODEL: ${{ env.OPENAI_MODEL }}
OPENAI_TEMPERATURE: ${{ env.OPENAI_TEMPERATURE }}
MAX_CHANGELOG_CHARS: ${{ env.MAX_CHANGELOG_CHARS }}
run: |
set -euo pipefail
if [[ ! -s CHANGELOG.md ]]; then
echo "CHANGELOG.md is empty. Skipping AI rewrite."
echo "skipped=true" >> $GITHUB_OUTPUT
exit 0
fi
head -c "${MAX_CHANGELOG_CHARS}" CHANGELOG.md > CHANGELOG_RAW.md
jq -Rs --arg sys "You are an expert release-notes writer. Given a list of changes in various formats (e.g: commits, merges, etc.), write release notes intended for reading by the public, grouping by features, features, and other pertinent groups where appropriate. Do not include a group if it is unnecessary. Remove internal ticket IDs and commit hashes unless essential. Merge duplicates. Use imperative, past tense voice with proper prose. Output valid Markdown only." \
--arg temp "${OPENAI_TEMPERATURE}" \
--arg model "${OPENAI_MODEL}" \
'{model:$model, temperature: ($temp|tonumber), input:[{role:"system", content:$sys},{role:"user", content:.}]}' CHANGELOG_RAW.md > request.json
for i in 1 2 3; do
HTTP_CODE=$(curl -sS -w "%{http_code}" -o ai_response.json \
https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
--data-binary @request.json) && break || true
echo "Call attempt $i failed with HTTP $HTTP_CODE"
sleep $((i*i))
done
if [[ "${HTTP_CODE:-000}" -lt 200 || "${HTTP_CODE:-000}" -ge 300 ]]; then
echo "OpenAI API call failed with HTTP $HTTP_CODE. Keeping raw changelog."
echo "skipped=true" >> $GITHUB_OUTPUT
exit 0
fi
if jq -e '.output_text' ai_response.json >/dev/null; then
jq -r '.output_text' ai_response.json > CHANGELOG.md
else
jq -r '.output[0].content[] | select(.type=="output_text") | .text' ai_response.json | sed '/^[[:space:]]*$/d' > CHANGELOG.md
fi
if [[ ! -s CHANGELOG.md ]]; then
echo "AI returned empty content. Restoring raw changelog."
mv CHANGELOG_RAW.md CHANGELOG.md
echo "skipped=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "skipped=false" >> $GITHUB_OUTPUT
echo "Rewritten changelog:"
cat CHANGELOG.md
- name: Create GitHub release
if: steps.tag_exists.outputs.exists != 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.gitversion.outputs.fullSemVer }}
body_path: CHANGELOG.md
prerelease: ${{ github.ref_name != 'main' }}
files: build/TTT/*.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete old pre-releases
if: steps.tag_exists.outputs.exists != 'true' && github.ref_name != 'main'
run: |
gh release list --limit 100 --json name,isPrerelease \
--jq '.[] | select(.isPrerelease) | .name' | tail -n +11 | \
xargs -r -I {} gh release delete "{}" -y
env:
GH_TOKEN: ${{ github.token }}

61
.gitignore vendored
View File

@@ -1 +1,62 @@
.idea
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# End of https://www.toptal.com/developers/gitignore/api/rider
bin
obj
packages
*.user
build
GitVersionInformation.g.cs
gitversion.json
build_output
**/lang/*.json

24
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,24 @@
# Contributing to this Project
Thank you for considering contributing!
By submitting code, documentation, or other contributions ("Contributions") to this project, you agree that your
Contributions are licensed under the same terms as the projects license.
- This means your Contributions will be freely usable, modifiable, and distributable under that license.
- Please ensure your Contributions are your original work or that you have the necessary rights to submit them.
- Contributions that do not comply with the projects license or infringe third-party rights may be rejected.
---
**Code Formatting Requirement**
Before submitting, please format your code according to the settings provided in the `TTT.sln.DotSettings` file.
---
For substantial contributions, maintainers may request you to sign a Contributor License Agreement (CLA) to clarify
rights and permissions.
If you have questions, please contact the repository owner.
Thank you for helping improve this project!

5
Directory.Build.props Normal file
View File

@@ -0,0 +1,5 @@
<Project>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2025.2.0"/>
</ItemGroup>
</Project>

View File

@@ -1,21 +0,0 @@
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
USER $APP_UID
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["TTT.csproj", "./"]
RUN dotnet restore "TTT.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "./TTT.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./TTT.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TTT.dll"]

View File

@@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDisposable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F15495df23a5f432ab31b9c5df7609208b2e200_003F86_003Fa1f5f67f_003FIDisposable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View File

@@ -1,95 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Built-in: Full Cleanup</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/MODIFIERS_ORDER/@EntryValue">public private override virtual file new abstract internal protected sealed static readonly extern unsafe volatile async required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PARENTHESES_REDUNDANCY_STYLE/@EntryValue">Remove</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_DECLARED_IN/@EntryValue">0</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_OWNER_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALLOW_COMMENT_AFTER_LBRACE/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_BRACES_INSIDE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FIXED_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FOR_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FOREACH_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_LOCK_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_USINGS_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_WHILE_STMT/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_RAW_LITERAL_STRING/@EntryValue">INDENT</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_SIZE/@EntryValue">2</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_ASSIGNMENTS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_COMMENTS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_PROPERTY_PATTERNS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_EXPRESSIONS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_SECTIONS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_VARIABLES/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INVOCABLE_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EMBEDDED_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EXPR_MEMBER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_LIST_PATTERNS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_PRIMARY_CONSTRUCTOR_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_PROPERTY_PATTERNS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ARRAY_INITIALIZER_ELEMENTS_ON_LINE/@EntryValue">10</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ENUM_MEMBERS_ON_LINE/@EntryValue">5</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_FORMAL_PARAMETERS_ON_LINE/@EntryValue">5</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_INVOCATION_ARGUMENTS_ON_LINE/@EntryValue">10</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_PRIMARY_CONSTRUCTOR_PARAMETERS_ON_LINE/@EntryValue">5</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/NESTED_TERNARY_STYLE/@EntryValue">COMPACT</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OTHER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_DOTS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_STATEMENT_LABELS/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_CATCH_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ELSE_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FINALLY_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_LINQ_INTO_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_BLOCK_ON_SAME_LINE/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_METHOD_ON_SINGLE_LINE/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_SWITCH_EXPRESSION_ON_SINGLE_LINE/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/TAB_WIDTH/@EntryValue">2</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/TYPE_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_PRIMARY_CONSTRUCTOR_DECLARATION_LPAR/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_ARROW_WITH_EXPRESSIONS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ENUM_DECLARATION/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_FOR_STMT_HEADER_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">80</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PRIMARY_CONSTRUCTOR_PARAMETERS_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IO/@EntryIndexedValue">IO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LG/@EntryIndexedValue">LG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LR/@EntryIndexedValue">LR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ST/@EntryIndexedValue">ST</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=08582792_002Dd334_002D4f6d_002Db467_002Dfc7b9fd4557b/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private, ProtectedInternal, Internal, PrivateProtected" Description="Non-Public Methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8284009d_002De743_002D4d89_002D9402_002Da5bf9a89b657/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, Public, FileLocal" Description="Public Methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8a85b61a_002D1024_002D4f87_002Db9ef_002D1fdae19930a1/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PARAMETER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ENUM_MEMBER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=c873eafb_002Dd57f_002D481d_002D8c93_002D77f6863c2f88/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>

42
GitVersion.yml Normal file
View File

@@ -0,0 +1,42 @@
mode: ContinuousDeployment
tag-prefix: "" # allow bare numeric tags like 2.0.0
commit-message-incrementing: Enabled
assembly-versioning-scheme: MajorMinorPatch
# Never allow commit messages to trigger a major bump
major-version-bump-message: "(?!)"
# Opt-in bumps via tokens
minor-version-bump-message: \+semver:\s?minor
patch-version-bump-message: \+semver:\s?patch
branches:
main:
label: "" # clears the default prerelease label
increment: None # no automatic bump unless +semver token
prevent-increment:
of-merged-branch: true
when-branch-merged: true
when-current-commit-tagged: true
develop:
label: "dev"
increment: None
prevent-increment:
of-merged-branch: true
when-branch-merged: true
when-current-commit-tagged: true
feature:
label: "feat"
increment: None
release:
label: "rc"
increment: None
hotfix:
label: "hotfix"
increment: None
pull-request:
label: "pr"
increment: None
assembly-informational-format: "{FullSemVer}+Branch.{BranchName}.Sha.{ShortSha}"

View File

@@ -1,39 +0,0 @@
namespace GitVersion
{
internal static class GitVersionInformation
{
public const int Major = 0;
public const int Minor = 1;
public const int Patch = 0;
public const string PreReleaseTag = "";
public const string PreReleaseTagWithDash = "";
public const string PreReleaseLabel = "";
public const string PreReleaseLabelWithDash = "";
// PreReleaseNumber is null and omitted
public const int WeightedPreReleaseNumber = 60000;
public const int BuildMetaData = 0;
public const string BuildMetaDataPadded = "0000";
public const string FullBuildMetaData = "0.Branch.main.Sha.e0f450147592475d2373504f6eee595d4edb9f3a";
public const string MajorMinorPatch = "0.1.0";
public const string SemVer = "0.1.0";
public const string LegacySemVer = "0.1.0";
public const string LegacySemVerPadded = "0.1.0";
public const string AssemblySemVer = "0.1.0.0";
public const string AssemblySemFileVer = "0.1.0.0";
public const string FullSemVer = "0.1.0+0";
public const string InformationalVersion = "0.1.0+0.Branch.main.Sha.e0f450147592475d2373504f6eee595d4edb9f3a";
public const string BranchName = "main";
public const string EscapedBranchName = "main";
public const string Sha = "e0f450147592475d2373504f6eee595d4edb9f3a";
public const string ShortSha = "e0f4501";
public const string NuGetVersionV2 = "0.1.0";
public const string NuGetVersion = "0.1.0";
public const string NuGetPreReleaseTagV2 = "";
public const string NuGetPreReleaseTag = "";
public const string VersionSourceSha = "e0f450147592475d2373504f6eee595d4edb9f3a";
public const int CommitsSinceVersionSource = 0;
public const string CommitsSinceVersionSourcePadded = "0000";
public const int UncommittedChanges = 8;
public const string CommitDate = "2025-07-28";
}
}

660
LICENSE Normal file
View File

@@ -0,0 +1,660 @@
# GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc.
<https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
## Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains
free software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing
under this license.
The precise terms and conditions for copying, distribution and
modification follow.
## TERMS AND CONDITIONS
### 0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public
License.
"Copyright" also means copyright-like laws that apply to other kinds
of works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of
an exact copy. The resulting work is called a "modified version" of
the earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user
through a computer network, with no transfer of a copy, is not
conveying.
An interactive user interface displays "Appropriate Legal Notices" to
the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
### 1. Source Code.
The "source code" for a work means the preferred form of the work for
making modifications to it. "Object code" means any non-source form of
a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users can
regenerate automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same
work.
### 2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey,
without conditions so long as your license otherwise remains in force.
You may convey covered works to others for the sole purpose of having
them make modifications exclusively for you, or provide you with
facilities for running those works, provided that you comply with the
terms of this License in conveying all material for which you do not
control copyright. Those thus making or running the covered works for
you must do so exclusively on your behalf, under your direction and
control, on terms that prohibit them from making any copies of your
copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the
conditions stated below. Sublicensing is not allowed; section 10 makes
it unnecessary.
### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such
circumvention is effected by exercising rights under this License with
respect to the covered work, and you disclaim any intention to limit
operation or modification of the work as a means of enforcing, against
the work's users, your or third parties' legal rights to forbid
circumvention of technological measures.
### 4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
### 5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these
conditions:
- a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
- b) The work must carry prominent notices stating that it is
released under this License and any conditions added under
section 7. This requirement modifies the requirement in section 4
to "keep intact all notices".
- c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
- d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
### 6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of
sections 4 and 5, provided that you also convey the machine-readable
Corresponding Source under the terms of this License, in one of these
ways:
- a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
- b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding
Source from a network server at no charge.
- c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
- d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
- e) Convey the object code using peer-to-peer transmission,
provided you inform other peers where the object code and
Corresponding Source of the work are being offered to the general
public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal,
family, or household purposes, or (2) anything designed or sold for
incorporation into a dwelling. In determining whether a product is a
consumer product, doubtful cases shall be resolved in favor of
coverage. For a particular product received by a particular user,
"normally used" refers to a typical or common use of that class of
product, regardless of the status of the particular user or of the way
in which the particular user actually uses, or expects or is expected
to use, the product. A product is a consumer product regardless of
whether the product has substantial commercial, industrial or
non-consumer uses, unless such uses represent the only significant
mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to
install and execute modified versions of a covered work in that User
Product from a modified version of its Corresponding Source. The
information must suffice to ensure that the continued functioning of
the modified object code is in no case prevented or interfered with
solely because modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or
updates for a work that has been modified or installed by the
recipient, or for the User Product in which it has been modified or
installed. Access to a network may be denied when the modification
itself materially and adversely affects the operation of the network
or violates the rules and protocols for communication across the
network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
### 7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders
of that material) supplement the terms of this License with terms:
- a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
- b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
- c) Prohibiting misrepresentation of the origin of that material,
or requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
- d) Limiting the use for publicity purposes of names of licensors
or authors of the material; or
- e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
- f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions
of it) with contractual assumptions of liability to the recipient,
for any liability that these contractual assumptions directly
impose on those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions; the
above requirements apply either way.
### 8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your license
from a particular copyright holder is reinstated (a) provisionally,
unless and until the copyright holder explicitly and finally
terminates your license, and (b) permanently, if the copyright holder
fails to notify you of the violation by some reasonable means prior to
60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
### 9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run
a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
### 10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
### 11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims owned
or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within the
scope of its coverage, prohibits the exercise of, or is conditioned on
the non-exercise of one or more of the rights that are specifically
granted under this License. You may not convey a covered work if you
are a party to an arrangement with a third party that is in the
business of distributing software, under which you make payment to the
third party based on the extent of your activity of conveying the
work, and under which the third party grants, to any of the parties
who would receive the covered work from you, a discriminatory patent
license (a) in connection with copies of the covered work conveyed by
you (or copies made from those copies), or (b) primarily for and in
connection with specific products or compilations that contain the
covered work, unless you entered into that arrangement, or that patent
license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
### 12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under
this License and any other pertinent obligations, then as a
consequence you may not convey it at all. For example, if you agree to
terms that obligate you to collect a royalty for further conveying
from those to whom you convey the Program, the only way you could
satisfy both those terms and this License would be to refrain entirely
from conveying the Program.
### 13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your
version supports such interaction) an opportunity to receive the
Corresponding Source of your version by providing access to the
Corresponding Source from a network server at no charge, through some
standard or customary means of facilitating copying of software. This
Corresponding Source shall include the Corresponding Source for any
work covered by version 3 of the GNU General Public License that is
incorporated pursuant to the following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
### 14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Affero General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever
published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions
of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
### 15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
### 16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
### 17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
## How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively state
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper
mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for
the specific requirements.
You should also get your employer (if you work as a programmer) or
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. For more information on this, and how to apply and follow
the GNU AGPL, see <https://www.gnu.org/licenses/>.

20
LICENSES.MD Normal file
View File

@@ -0,0 +1,20 @@
| Package | Version | License Information Origin | License Expression | License Url | Copyright | Authors | Package Project Url |
| ----------------------------------------------------- | -------- | -------------------------- | ------------------ | --------------------------------------- | ----------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------ |
| CounterStrikeSharp.API | 1.0.332 | Expression | GPL-3.0-only | https://licenses.nuget.org/GPL-3.0-only | | Roflmuffin | http://docs.cssharp.dev/ |
| CounterStrikeSharp.API | 1.0.340 | Expression | GPL-3.0-only | https://licenses.nuget.org/GPL-3.0-only | | Roflmuffin | http://docs.cssharp.dev/ |
| Dapper | 2.1.66 | Expression | Apache-2.0 | https://licenses.nuget.org/Apache-2.0 | 2019 Stack Exchange, Inc. | Sam Saffron,Marc Gravell,Nick Craver | https://github.com/DapperLib/Dapper |
| JetBrains.Annotations | 2025.2.0 | Expression | MIT | https://licenses.nuget.org/MIT | Copyright (c) 2016-2025 JetBrains s.r.o. | JetBrains | https://www.jetbrains.com/help/resharper/Code_Analysis__Code_Annotations.html |
| Microsoft.Data.Sqlite | 9.0.9 | Expression | MIT | https://licenses.nuget.org/MIT | © Microsoft Corporation. All rights reserved. | Microsoft | https://docs.microsoft.com/dotnet/standard/data/sqlite/ |
| Microsoft.Extensions.DependencyInjection.Abstractions | 9.0.7 | Expression | MIT | https://licenses.nuget.org/MIT | © Microsoft Corporation. All rights reserved. | Microsoft | https://dot.net/ |
| Microsoft.Extensions.Localization.Abstractions | 8.0.3 | Expression | MIT | https://licenses.nuget.org/MIT | © Microsoft Corporation. All rights reserved. | Microsoft | https://asp.net/ |
| Microsoft.NET.Test.Sdk | 17.14.1 | Expression | MIT | https://licenses.nuget.org/MIT | © Microsoft Corporation. All rights reserved. | Microsoft | https://github.com/microsoft/vstest |
| Microsoft.Reactive.Testing | 6.0.1 | Expression | MIT | https://licenses.nuget.org/MIT | Copyright (c) .NET Foundation and Contributors. | .NET Foundation and Contributors | https://github.com/dotnet/reactive |
| Microsoft.Testing.Extensions.CodeCoverage | 17.14.2 | Unknown | | https://aka.ms/deprecateLicenseUrl | © Microsoft Corporation. All rights reserved. | Microsoft | https://github.com/microsoft/codecoverage |
| MySqlConnector | 2.4.0 | Expression | MIT | https://licenses.nuget.org/MIT | Copyright 20162024 Bradley Grainger | Bradley Grainger | https://mysqlconnector.net/ |
| SQLite | 3.13.0 | Unknown | | | Public Domain | SQLite Development Team | |
| System.Reactive | 6.0.1 | Expression | MIT | https://licenses.nuget.org/MIT | Copyright (c) .NET Foundation and Contributors. | .NET Foundation and Contributors | https://github.com/dotnet/reactive |
| System.Text.Json | 8.0.5 | Expression | MIT | https://licenses.nuget.org/MIT | © Microsoft Corporation. All rights reserved. | Microsoft | https://dot.net/ |
| Xunit.DependencyInjection | 10.6.0 | Expression | MIT | https://licenses.nuget.org/MIT | Copyright © 2019 | Wei Peng | https://github.com/pengweiqhca/Xunit.DependencyInjection/tree/main/src/Xunit.DependencyInjection |
| xunit.runner.visualstudio | 3.1.3 | Expression | Apache-2.0 | https://licenses.nuget.org/Apache-2.0 | Copyright (C) .NET Foundation | jnewkirk,bradwilson | |
| xunit.v3 | 3.0.0 | Expression | Apache-2.0 | https://licenses.nuget.org/Apache-2.0 | Copyright (C) .NET Foundation | jnewkirk,bradwilson | |
| YamlDotNet | 16.3.0 | Expression | MIT | https://licenses.nuget.org/MIT | Copyright (c) Antoine Aubry and contributors | Antoine Aubry | https://github.com/aaubry/YamlDotNet/wiki |

6
Locale/IMsg.cs Normal file
View File

@@ -0,0 +1,6 @@
namespace TTT.Locale;
public interface IMsg {
string Key { get; }
object[] Args { get; }
}

7
Locale/IMsgLocalizer.cs Normal file
View File

@@ -0,0 +1,7 @@
using Microsoft.Extensions.Localization;
namespace TTT.Locale;
public interface IMsgLocalizer : IStringLocalizer {
string this[IMsg msg] { get; }
}

View File

@@ -0,0 +1,29 @@
using CounterStrikeSharp.API.Core.Translations;
using Microsoft.Extensions.Localization;
namespace TTT.Locale;
public class JsonLocalizerFactory : IStringLocalizerFactory {
private readonly string langPath;
public JsonLocalizerFactory() {
// Lang folder is in the root of the project
// keep moving up until we find it
var current = Directory.GetCurrentDirectory();
while (!File.Exists(Path.Combine(current, "lang", "en.json"))) {
current = Directory.GetParent(current)?.FullName;
if (current == null)
throw new DirectoryNotFoundException("Could not find lang folder");
}
langPath = Path.Combine(current, "lang");
}
public IStringLocalizer Create(Type resourceSource) {
return new JsonStringLocalizer(langPath);
}
public IStringLocalizer Create(string baseName, string location) {
return new JsonStringLocalizer(langPath);
}
}

38
Locale/Locale.csproj Normal file
View File

@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>TTT.Locale</RootNamespace>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.332"/>
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.3"/>
<PackageReference Include="System.Text.Json" Version="8.0.5"/>
<PackageReference Include="YamlDotNet" Version="16.3.0"/>
</ItemGroup>
<Target Name="PreprocessYaml" AfterTargets="Build;VSTest">
<PropertyGroup>
<LocaleDllPath>$(MSBuildProjectDirectory)\bin\$(Configuration)\net8.0\$(AssemblyName).dll</LocaleDllPath>
<MasterJsonPath>$(MSBuildProjectDirectory)\..\lang\en.json</MasterJsonPath>
</PropertyGroup>
<ItemGroup>
<LangFiles Include="..\**\lang\*.yml"/>
<!-- Exclude Test/lang/en.yml only in Release config -->
<LangFiles Remove="..\TTT\Test\lang\en.yml" Condition="'$(Configuration)' == 'Release'"/>
</ItemGroup>
<Message Importance="high" Text="Combining YAML files into $(MasterJsonPath)"/>
<Message Importance="high" Text="Included YAML files:"/>
<Message Importance="high" Text=" %(LangFiles.FullPath)" Condition="'%(LangFiles.FullPath)' != ''"/>
<Exec Command="dotnet &quot;$(LocaleDllPath)&quot; @(LangFiles->'&quot;%(FullPath)&quot;', ' ') --out &quot;$(MasterJsonPath)&quot;"/>
</Target>
</Project>

9
Locale/MsgFactory.cs Normal file
View File

@@ -0,0 +1,9 @@
namespace TTT.Locale;
public static class MsgFactory {
public static IMsg Create(string key, params object[] args) {
return new Msg(key, args);
}
private sealed record Msg(string Key, object[] Args) : IMsg;
}

97
Locale/Program.cs Normal file
View File

@@ -0,0 +1,97 @@
using System.Text.Json;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace TTT.Locale;
public static class Program {
private static readonly JsonSerializerOptions opts =
new() { WriteIndented = true };
public static void Main(string[] args) {
if (args.Length < 1) {
printUsage();
Environment.Exit(1);
}
var (inputPaths, outputPath) = parseArguments(args);
validateInputFiles(inputPaths);
var merged = mergeYamlFiles(inputPaths);
writeJsonOutput(merged, outputPath);
}
private static void printUsage() {
Console.Error.WriteLine("Usage:");
Console.Error.WriteLine(" YamlToJson <input.yml>");
Console.Error.WriteLine(
" YamlToJson <input1.yml> <input2.yml> ... --out <output.json>");
}
private static (string[] inputPaths, string outputPath) parseArguments(
string[] args) {
string outputPath;
string[] inputPaths;
if (args.Length == 1) {
inputPaths = [args[0]];
outputPath = Path.ChangeExtension(args[0], ".json");
} else {
var outIndex = Array.IndexOf(args, "--out");
if (outIndex == -1 || outIndex == args.Length - 1 || outIndex < 1) {
Console.Error.WriteLine(
"Error: When specifying multiple input files, use: --out <output.json>");
Environment.Exit(1);
}
outputPath = args[outIndex + 1];
inputPaths = args.Take(outIndex).ToArray();
}
return (inputPaths, outputPath);
}
private static void validateInputFiles(string[] inputPaths) {
foreach (var input in inputPaths)
if (!File.Exists(input)) {
Console.Error.WriteLine($"Error: File not found - {input}");
Environment.Exit(2);
}
}
private static Dictionary<string, string>
mergeYamlFiles(string[] inputPaths) {
var deserializer = new DeserializerBuilder()
.WithNamingConvention(NullNamingConvention.Instance)
.Build();
var merged = new Dictionary<string, string>();
foreach (var input in inputPaths) {
var yaml = File.ReadAllText(input);
var parsed = deserializer.Deserialize<Dictionary<string, string>>(yaml);
foreach (var (k, v) in parsed) {
if (merged.TryGetValue(k, out var existing) && existing != v)
Console.Error.WriteLine(
$"Warning: Duplicate key '{k}' found in {input}, overwriting value.");
merged[k] = v; // Overwrite if duplicate
}
}
return merged;
}
private static void writeJsonOutput(Dictionary<string, string> merged,
string outputPath) {
var dir = Path.GetDirectoryName(outputPath);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
var json = JsonSerializer.Serialize(merged, opts);
File.WriteAllText(outputPath, json);
}
}

20
Locale/README.md Normal file
View File

@@ -0,0 +1,20 @@
# TTT - Localizer
Responsible for managing the translations of the different TTT modules.
In and of itself does not provide any translations, but rather provides a framework for other modules to provide their
own translations.
For convenience, Localizer runs as a CLI tool that converts YML files to JSON files, as YML is nicer to work with, but
JSON is the format used for [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp)'s localization
system.
## Usage
1. Build (`dotnet build`)
2. Navigate to where the Localizer.dll is
3. Run `dotnet Localizer.dll [input files...] -o [output file]`
- CS# sources all translations from the single `.json` file; separating the YML files allows for easier management per
module, the localizer will combine them into a single JSON file.
- If you are only providing one input file, you can omit the `-o` flag and it will output to `inputFileName.json` by
default.

168
Locale/StringLocalizer.cs Normal file
View File

@@ -0,0 +1,168 @@
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Localization;
namespace TTT.Locale;
/// <summary>
/// A custom implementation of <see cref="IStringLocalizer" /> that adds support
/// for in-string placeholders like %key% and grammatical pluralization with %s%.
/// </summary>
public partial class StringLocalizer : IMsgLocalizer {
private readonly IStringLocalizer localizer;
public StringLocalizer(IStringLocalizerFactory factory) {
var type = typeof(StringLocalizer);
var assemblyName =
new AssemblyName(type.GetTypeInfo().Assembly.FullName ?? string.Empty);
localizer = factory.Create(string.Empty, assemblyName.FullName);
}
public string this[IMsg msg] => getString(msg.Key, msg.Args);
public LocalizedString this[string name] => getString(name);
public LocalizedString this[string name, params object[] arguments]
=> getString(name, arguments);
public IEnumerable<LocalizedString>
GetAllStrings(bool includeParentCultures) {
return localizer.GetAllStrings(includeParentCultures)
.Select(str => getString(str.Name));
}
[GeneratedRegex("%.*?%")]
private static partial Regex percentRegex();
[GeneratedRegex(@"\b(\w+)%s%")]
private static partial Regex pluralRegex();
[GeneratedRegex(@"%an%", RegexOptions.IgnoreCase)]
private static partial Regex anRegex();
private LocalizedString getString(string name, params object[] arguments) {
// Get the localized value
string value;
try { value = localizer[name].Value; } catch (NullReferenceException) {
return new LocalizedString(name, name, true);
}
// Replace placeholders like %key% with their respective values
var matches = percentRegex().Matches(value);
foreach (Match match in matches) {
var key = match.Value;
var trimmedKey = key[1..^1]; // Trim % symbols
// NullReferenceException catch block if key does not exist
try {
// CS# forces a space before a chat color if the entirety
// of the strong is a color code. This is undesired
// in our case, so we trim the value when we have a prefix.
var replacement = localizer[trimmedKey].Value;
if (replacement == trimmedKey) continue;
value = value.Replace(key,
trimmedKey.Contains("PREFIX", StringComparison.OrdinalIgnoreCase) ?
replacement :
replacement.TrimStart());
} catch (NullReferenceException) {
// Key doesn't exist, move on
}
}
// Format with arguments if provided
if (arguments.Length > 0) value = string.Format(value, arguments);
// Handle pluralization
value = HandlePluralization(value);
value = HandleAn(value);
if (!string.IsNullOrWhiteSpace(value) && hasChatColor(value)) {
var first = value.First(c => !char.IsWhiteSpace(c));
if (char.IsAsciiLetterOrDigit(first)) value = value.TrimStart();
}
return new LocalizedString(name, value);
}
private static bool isChatColor(char c) {
return c is '\x01' or '\x02' or '\x03' or '\x04' or '\x05' or '\x06'
or '\x07' or '\x08' or '\x09' or '\x0A' or '\x0B' or '\x0C' or '\x0D'
or '\x0E' or '\x0F' or '\x10';
}
private static bool hasChatColor(string value) {
return value.Any(isChatColor);
}
public static string HandlePluralization(string value) {
var pluralMatches = pluralRegex().Matches(value);
foreach (Match match in pluralMatches) {
var word = match.Groups[1].Value.ToLower();
var index = match.Index;
var prefix = value[..index].Trim();
var lastWords = prefix.Split(' ')
.Select(w
=> w.Where(c => char.IsLetterOrDigit(c) || c == '-').ToArray());
var previousNumber = lastWords.LastOrDefault(w => int.TryParse(w, out _));
if (previousNumber != null)
value = value[..index] + value[index..]
.Replace("%s%", int.Parse(previousNumber) == 1 ? "" : "s");
else
value = value[..index] + value[index..]
.Replace("%s%", word.EndsWith('s') ? "" : "s");
}
value = value.Replace("%s%", "s");
// We have to do this chicanery due to support colors in the string
value = handleTrailingS(value);
return value;
}
private static string handleTrailingS(string value) {
var trailingIndex = -1;
while ((trailingIndex =
value.IndexOf("'s", trailingIndex + 1, StringComparison.Ordinal)) != -1) {
var startingWordBoundary = value[..trailingIndex].LastIndexOf(' ');
if (startingWordBoundary == -1
|| startingWordBoundary + 2 > value.Length) {
if (value.EndsWith("s's")) value = value[..^1];
break;
}
var endingWordBoundary = value.IndexOf(' ', trailingIndex + 2);
var word = value[(startingWordBoundary + 1)..endingWordBoundary];
var filteredWord = word.Where(c => char.IsLetterOrDigit(c) || c == '\'')
.ToArray();
if (new string(filteredWord).EndsWith("s's",
StringComparison.OrdinalIgnoreCase))
value = value[..(trailingIndex + 1)] + " "
+ value[(trailingIndex + 4)..];
}
return value;
}
public static string HandleAn(string value) {
var anMatches = anRegex().Matches(value);
foreach (Match match in anMatches) {
var anMatch = match.Value[1..^1];
var index = match.Index;
var prefix = value[..index];
var suffix = value[(index + match.Length)..];
// Determine if the next word starts with a vowel sound
var nextChar = char.ToLower(suffix.FirstOrDefault(char.IsLetterOrDigit));
value = nextChar switch {
'a' or 'e' or 'i' or 'o' or 'u' => prefix + anMatch + suffix,
_ => prefix + anMatch[0] + suffix
};
}
return value;
}
}

View File

@@ -1 +1,60 @@
# TTT
# TTT | [![ReadMe](https://img.shields.io/badge/ReadMe-018EF5?logo=readme&logoColor=fff&style=for-the-badge)](./TTT/README.md) ![GitHub Release](https://img.shields.io/github/v/release/MSWS/TTT?style=for-the-badge)
![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/MSWS/6289e1f34da3b70fbba5f84f5ffb25a1/raw/code-coverage.json)
[![Discord](https://img.shields.io/discord/623439460683481091?style=for-the-badge&logo=discord&label=Discord)](https://msws.xyz/s/discord)
![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fwaka.msws.xyz%2Fapi%2Fcompat%2Fshields%2Fv1%2Fmsws%2Fproject%3ATTT%2Finterval%3Aall_time%26label%3DAll%2520time%26color%3Dblue&style=for-the-badge&label=Dev%20Time)
TTT (Trouble in Terrorist Town) is a game mode similar to Among Us where a group of players are attempting to
survive while eliminating the traitors among them.
## Features
- [X] Unit Testing
- [X] Basic Gameplay
- [X] Traitors
- [X] Detectives
- [X] Innocents
- [X] Shop
- [X] Karma
- [X] Statistics
- [X] Map Integrations
- [X] Special Rounds
## Versioning
This project adheres to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html).
The versioning scheme consists of three components:
- **MAJOR** version indicates incompatible API changes,
- **MINOR** version signifies the addition of functionality in a backwards-compatible manner, and
- **PATCH** version reflects backwards-compatible bug fixes.
# Modules
### [TTT](./TTT)
You likely want to read the [TTT README](./TTT/README.md), which covers the structure of its own directory.
### [Versioning](./Versioning)
To allow for `MSBuild.GitVersion` to be used on both Windows and Linux (specifically NixOS), this project manually
converts `dotnet-gitversion` to the `GitVersionInformation` that is used.
### [Locale](./Locale)
Due to this project being primarily developed with Counter-Strike 2 (and more
specifically, [CounterStrikeSharp](https://github.com/roflmuffin/CounterStrikeSharp)) in mind, localization has been
built with flat-file storage based around YML/JSON.
In short, we write our locales in `en.yml`, run `Locale.csproj` to convert and combine all `**/Lang/en.yml` into a master
`lang/en.json`, and then run our tests / release pipelines with it.
It is recommend to read the [Locale README](./Locale/README.md) for more information on how to use it.
## Development
1. `git clone ...`
2. `dotnet restore`
3. `dotnet build`
4. Convert all `lang/en.yml` -> `lang/en.json` (Required for testing, refer to [Locale](./Locale/README.md))
5. `dotnet test` (Optional)

View File

@@ -0,0 +1,26 @@
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using SpecialRoundAPI.Configs;
using TTT.API;
using TTT.API.Events;
using TTT.Game.Events.Game;
using TTT.Game.Listeners;
using TTT.Locale;
namespace SpecialRoundAPI;
public abstract class AbstractSpecialRound(IServiceProvider provider)
: BaseListener(provider) {
protected readonly ISpecialRoundTracker Tracker =
provider.GetRequiredService<ISpecialRoundTracker>();
public abstract string Name { get; }
public abstract IMsg Description { get; }
public abstract SpecialRoundConfig Config { get; }
public abstract void ApplyRoundEffects();
[UsedImplicitly]
[EventHandler]
public abstract void OnGameState(GameStateUpdateEvent ev);
}

View File

@@ -0,0 +1,5 @@
namespace SpecialRoundAPI.Configs;
public record BhopRoundConfig : SpecialRoundConfig {
public override float Weight { get; init; } = 0.2f;
}

View File

@@ -0,0 +1,5 @@
namespace SpecialRoundAPI.Configs;
public record SilentRoundConfig : SpecialRoundConfig {
public override float Weight { get; init; } = 0.1f;
}

View File

@@ -0,0 +1,5 @@
namespace SpecialRoundAPI.Configs;
public abstract record SpecialRoundConfig {
public abstract float Weight { get; init; }
}

View File

@@ -0,0 +1,9 @@
namespace SpecialRoundAPI.Configs;
public record SpeedRoundConfig : SpecialRoundConfig {
public override float Weight { get; init; } = 0.6f;
public TimeSpan InitialSeconds { get; init; } = TimeSpan.FromSeconds(40);
public TimeSpan SecondsPerKill { get; init; } = TimeSpan.FromSeconds(10);
public TimeSpan MaxTimeEver { get; init; } = TimeSpan.FromSeconds(90);
}

View File

@@ -0,0 +1,5 @@
namespace SpecialRoundAPI.Configs;
public record SuppressedRoundConfig : SpecialRoundConfig {
public override float Weight { get; init; } = 0.3f;
}

View File

@@ -0,0 +1,5 @@
namespace SpecialRoundAPI.Configs;
public record VanillaRoundConfig : SpecialRoundConfig {
public override float Weight { get; init; } = 0.2f;
}

View File

@@ -0,0 +1,13 @@
namespace SpecialRoundAPI;
public interface ISpecialRoundStarter {
/// <summary>
/// Attempts to start the given special round.
/// Will bypass most checks, but may still return null if starting the round
/// is not possible.
/// </summary>
/// <param name="round"></param>
/// <returns></returns>
public AbstractSpecialRound?
TryStartSpecialRound(AbstractSpecialRound? round);
}

View File

@@ -0,0 +1,6 @@
namespace SpecialRoundAPI;
public interface ISpecialRoundTracker {
public AbstractSpecialRound? CurrentRound { get; set; }
public int RoundsSinceLastSpecial { get; set; }
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Locale\Locale.csproj"/>
<ProjectReference Include="..\..\TTT\API\API.csproj"/>
<ProjectReference Include="..\..\TTT\Game\Game.csproj"/>
</ItemGroup>
</Project>

View File

@@ -1,5 +0,0 @@
namespace TTT.Api.Events;
public abstract class Event {
public abstract string Id { get; }
}

View File

@@ -1,16 +0,0 @@
namespace TTT.Api.Events;
[AttributeUsage(AttributeTargets.Method)]
public class EventHandlerAttribute : Attribute {
public uint Priority => Events.Priority.PRIORITY_DEFAULT;
public bool IgnoreCanceled => false;
}
public static class Priority {
public const uint PRIORITY_VERY_HIGH = 20;
public const uint PRIORITY_HIGH = 40;
public const uint PRIORITY_NORMAL = 60;
public const uint PRIORITY_LOW = 80;
public const uint PRIORITY_VERY_LOW = 100;
public const uint PRIORITY_DEFAULT = 50;
}

View File

@@ -1,5 +0,0 @@
namespace TTT.Api.Events;
public interface ICancelableEvent {
public bool IsCanceled { get; }
}

View File

@@ -1,3 +0,0 @@
namespace TTT.Api.Events;
public interface IListener;

View File

@@ -1,15 +0,0 @@
namespace TTT.Api;
public interface IAction {
IPlayer Player { get; }
IPlayer? Target { get; }
string Id { get; }
string Verb { get; }
string Details { get; }
string Format() {
return Target is not null ?
$"{Player} {Verb} {Target} {Details}" :
$"{Player} {Verb} {Details}";
}
}

View File

@@ -1,8 +0,0 @@
namespace TTT.Api;
public interface IGame {
ICollection<IPlayer> Players { get; }
DateTime StartedAt { get; }
DateTime? FinishedAt { get; }
IList<IAction> Actions { get; }
}

View File

@@ -1,11 +0,0 @@
namespace TTT.Api;
public interface IMessenger {
/// <summary>
/// Attempt to send a message to a player.
/// </summary>
/// <param name="player">The player to send the message to.</param>
/// <param name="message">The message to send</param>
/// <typeparam name="T"></typeparam>
Task<bool> Message(IPlayer player, string message);
}

View File

@@ -1,13 +0,0 @@
namespace TTT.Api;
public interface IOnlineMessenger : IMessenger {
Task<bool> IMessenger.Message(IPlayer player, string message) {
if (player is not IOnlinePlayer onlinePlayer)
return
Task.FromResult(false); // Cannot send message to non-online players
return Message(onlinePlayer, message);
}
Task<bool> Message(IOnlinePlayer player, string message);
}

View File

@@ -1,5 +0,0 @@
namespace TTT.Api;
public interface IOnlinePlayer : IPlayer {
ICollection<IRole> Roles { get; }
}

View File

@@ -1,11 +0,0 @@
namespace TTT.Api;
public interface IPlayer {
/// <summary>
/// The unique identifier for the player, should
/// be unique across all players at all times.
/// </summary>
string Id { get; }
string Name { get; }
}

View File

@@ -1,18 +0,0 @@
using System.Drawing;
namespace TTT.Api;
/// <summary>
/// Represents a role that can be assigned to a player.
/// Does not necessarily imply they are in the game.
/// </summary>
public interface IRole {
string Id { get; }
string Name { get; }
Color Color { get; }
bool ConflictsWith(IRole other) => false;
bool RequiresRole(IRole other) => false;
T? FindPlayerToAssign<T>(T player);
}

View File

@@ -1,8 +0,0 @@
using GitVersion;
namespace TTT.Api;
public interface ITerrorApi : ITerrorModule {
string ITerrorModule.Name => "Core";
string ITerrorModule.Version => GitVersionInformation.FullSemVer;
}

View File

@@ -1,6 +0,0 @@
namespace TTT.Api;
public interface ITerrorModule : IDisposable {
string Name { get; }
string Version { get; }
}

View File

@@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\GitVersionInformation.g.cs"/>
</ItemGroup>
</Project>

View File

@@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]

View File

@@ -1,22 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("TTT.Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("TTT.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("TTT.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.

View File

@@ -1 +0,0 @@
cdbc441e8749481d9af8e6fbd6ae33eb767c505116c17e79b097343c67721cbf

View File

@@ -1,13 +0,0 @@
is_global = true
build_property.TargetFramework = net8.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = TTT.Api
build_property.ProjectDir = /home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =

View File

@@ -1,8 +0,0 @@
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;

View File

@@ -1,66 +0,0 @@
{
"format": 1,
"restore": {
"/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj": {}
},
"projects": {
"/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj",
"projectName": "TTT.Api",
"projectPath": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj",
"packagesPath": "/home/iboaz/.nuget/packages/",
"outputPath": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/obj/",
"projectStyle": "PackageReference",
"configFilePaths": [
"/home/iboaz/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"net8.0"
],
"sources": {
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "/nix/store/1d8g8d8xrrlxwfgbavgl4snymznfw5r7-dotnet-sdk-8.0.412/share/dotnet/sdk/8.0.412/PortableRuntimeIdentifierGraph.json"
}
}
}
}
}

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/iboaz/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/iboaz/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/home/iboaz/.nuget/packages/" />
</ItemGroup>
</Project>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

View File

@@ -1,71 +0,0 @@
{
"version": 3,
"targets": {
"net8.0": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"net8.0": []
},
"packageFolders": {
"/home/iboaz/.nuget/packages/": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj",
"projectName": "TTT.Api",
"projectPath": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj",
"packagesPath": "/home/iboaz/.nuget/packages/",
"outputPath": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/obj/",
"projectStyle": "PackageReference",
"configFilePaths": [
"/home/iboaz/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"net8.0"
],
"sources": {
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
}
},
"frameworks": {
"net8.0": {
"targetAlias": "net8.0",
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"Microsoft.NETCore.App": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "/nix/store/1d8g8d8xrrlxwfgbavgl4snymznfw5r7-dotnet-sdk-8.0.412/share/dotnet/sdk/8.0.412/PortableRuntimeIdentifierGraph.json"
}
}
}
}

View File

@@ -1,8 +0,0 @@
{
"version": 2,
"dgSpecHash": "zHAlCbUQsJw=",
"success": true,
"projectFilePath": "/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj",
"expectedPackageFiles": [],
"logs": []
}

View File

@@ -1 +0,0 @@
"restore":{"projectUniqueName":"/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj","projectName":"TTT.Api","projectPath":"/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/TTT.Api.csproj","outputPath":"/home/iboaz/Documents/Coding/ego/s2/TTT/TTT.Api/obj/","projectStyle":"PackageReference","originalTargetFrameworks":["net8.0"],"sources":{"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net8.0":{"targetAlias":"net8.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"}}"frameworks":{"net8.0":{"targetAlias":"net8.0","imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"/nix/store/1d8g8d8xrrlxwfgbavgl4snymznfw5r7-dotnet-sdk-8.0.412/share/dotnet/sdk/8.0.412/PortableRuntimeIdentifierGraph.json"}}

View File

@@ -1 +0,0 @@
17536984184998885

View File

@@ -1 +0,0 @@
17536985896526724

Submodule TTT.Core deleted from e0f4501475

102
TTT.sln Normal file
View File

@@ -0,0 +1,102 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API", "TTT\API\API.csproj", "{A7B58A1F-7C15-423B-B008-30E38D0E2135}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin", "TTT\Plugin\Plugin.csproj", "{581DA648-28A9-4E6F-9E1C-7DD19B90C10F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "TTT\Test\Test.csproj", "{D0424929-808F-49F8-9894-DDD770F55B7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS2", "TTT\CS2\CS2.csproj", "{A595E6E3-A881-4524-8E5D-DE65106E1DD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Game", "TTT\Game\Game.csproj", "{C41F5E15-2E28-4D14-A9F8-06FEADD24F2D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Versioning", "Versioning\Versioning.csproj", "{7AABCDC7-14BE-437C-BD41-C765CAB82F0E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Locale", "Locale\Locale.csproj", "{B5F91489-CD1B-42F2-9CF0-889604BD7C7E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shop", "TTT\Shop\Shop.csproj", "{478416D7-4996-41CC-BDDF-5BF50B505D0F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Karma", "TTT\Karma\Karma.csproj", "{AFC791EC-750C-423F-9F35-87636657E990}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShopAPI", "TTT\ShopAPI\ShopAPI.csproj", "{16F720B5-9D45-47BF-8C80-4F91005E36D1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RTD", "TTT\RTD\RTD.csproj", "{8A426E84-45DA-4558-A218-E042F1AC60B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stats", "TTT\Stats\Stats.csproj", "{256473A2-6ACD-440C-83FA-6056147656C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecialRound", "TTT\SpecialRound\SpecialRound.csproj", "{5092069A-3CFA-41C8-B685-341040AB435C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecialRoundAPI", "SpecialRoundAPI\SpecialRoundAPI\SpecialRoundAPI.csproj", "{360FEF16-54DA-42EE-995A-3D31C699287D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7B58A1F-7C15-423B-B008-30E38D0E2135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7B58A1F-7C15-423B-B008-30E38D0E2135}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7B58A1F-7C15-423B-B008-30E38D0E2135}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7B58A1F-7C15-423B-B008-30E38D0E2135}.Release|Any CPU.Build.0 = Release|Any CPU
{581DA648-28A9-4E6F-9E1C-7DD19B90C10F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{581DA648-28A9-4E6F-9E1C-7DD19B90C10F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{581DA648-28A9-4E6F-9E1C-7DD19B90C10F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{581DA648-28A9-4E6F-9E1C-7DD19B90C10F}.Release|Any CPU.Build.0 = Release|Any CPU
{D0424929-808F-49F8-9894-DDD770F55B7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0424929-808F-49F8-9894-DDD770F55B7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0424929-808F-49F8-9894-DDD770F55B7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0424929-808F-49F8-9894-DDD770F55B7C}.Release|Any CPU.Build.0 = Release|Any CPU
{A595E6E3-A881-4524-8E5D-DE65106E1DD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A595E6E3-A881-4524-8E5D-DE65106E1DD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A595E6E3-A881-4524-8E5D-DE65106E1DD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A595E6E3-A881-4524-8E5D-DE65106E1DD5}.Release|Any CPU.Build.0 = Release|Any CPU
{C41F5E15-2E28-4D14-A9F8-06FEADD24F2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C41F5E15-2E28-4D14-A9F8-06FEADD24F2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C41F5E15-2E28-4D14-A9F8-06FEADD24F2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C41F5E15-2E28-4D14-A9F8-06FEADD24F2D}.Release|Any CPU.Build.0 = Release|Any CPU
{7AABCDC7-14BE-437C-BD41-C765CAB82F0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AABCDC7-14BE-437C-BD41-C765CAB82F0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AABCDC7-14BE-437C-BD41-C765CAB82F0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AABCDC7-14BE-437C-BD41-C765CAB82F0E}.Release|Any CPU.Build.0 = Release|Any CPU
{B5F91489-CD1B-42F2-9CF0-889604BD7C7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5F91489-CD1B-42F2-9CF0-889604BD7C7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5F91489-CD1B-42F2-9CF0-889604BD7C7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5F91489-CD1B-42F2-9CF0-889604BD7C7E}.Release|Any CPU.Build.0 = Release|Any CPU
{478416D7-4996-41CC-BDDF-5BF50B505D0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{478416D7-4996-41CC-BDDF-5BF50B505D0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{478416D7-4996-41CC-BDDF-5BF50B505D0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{478416D7-4996-41CC-BDDF-5BF50B505D0F}.Release|Any CPU.Build.0 = Release|Any CPU
{AFC791EC-750C-423F-9F35-87636657E990}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AFC791EC-750C-423F-9F35-87636657E990}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AFC791EC-750C-423F-9F35-87636657E990}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFC791EC-750C-423F-9F35-87636657E990}.Release|Any CPU.Build.0 = Release|Any CPU
{16F720B5-9D45-47BF-8C80-4F91005E36D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16F720B5-9D45-47BF-8C80-4F91005E36D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16F720B5-9D45-47BF-8C80-4F91005E36D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16F720B5-9D45-47BF-8C80-4F91005E36D1}.Release|Any CPU.Build.0 = Release|Any CPU
{8A426E84-45DA-4558-A218-E042F1AC60B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A426E84-45DA-4558-A218-E042F1AC60B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A426E84-45DA-4558-A218-E042F1AC60B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A426E84-45DA-4558-A218-E042F1AC60B2}.Release|Any CPU.Build.0 = Release|Any CPU
{256473A2-6ACD-440C-83FA-6056147656C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{256473A2-6ACD-440C-83FA-6056147656C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{256473A2-6ACD-440C-83FA-6056147656C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{256473A2-6ACD-440C-83FA-6056147656C7}.Release|Any CPU.Build.0 = Release|Any CPU
{5092069A-3CFA-41C8-B685-341040AB435C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5092069A-3CFA-41C8-B685-341040AB435C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5092069A-3CFA-41C8-B685-341040AB435C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5092069A-3CFA-41C8-B685-341040AB435C}.Release|Any CPU.Build.0 = Release|Any CPU
{360FEF16-54DA-42EE-995A-3D31C699287D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{360FEF16-54DA-42EE-995A-3D31C699287D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{360FEF16-54DA-42EE-995A-3D31C699287D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{360FEF16-54DA-42EE-995A-3D31C699287D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
EndGlobal

156
TTT.sln.DotSettings Normal file
View File

@@ -0,0 +1,156 @@
<wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve">
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Built-in: Full Cleanup</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/MODIFIERS_ORDER/@EntryValue">public private override virtual file new abstract internal protected sealed static readonly extern unsafe volatile async required</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/PARENTHESES_REDUNDANCY_STYLE/@EntryValue">Remove</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_DECLARED_IN/@EntryValue">0</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_OWNER_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALLOW_COMMENT_AFTER_LBRACE/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_BRACES_INSIDE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FIXED_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FOR_STMT/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_FOREACH_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_LOCK_STMT/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_USINGS_STMT/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_NESTED_WHILE_STMT/@EntryValue">True</s:Boolean>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_RAW_LITERAL_STRING/@EntryValue">INDENT</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_SIZE/@EntryValue">2</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_ASSIGNMENTS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_COMMENTS/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_PROPERTY_PATTERNS/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_EXPRESSIONS/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_SWITCH_SECTIONS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INT_ALIGN_VARIABLES/@EntryValue">True</s:Boolean>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INVOCABLE_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EMBEDDED_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EXPR_MEMBER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_LIST_PATTERNS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_PRIMARY_CONSTRUCTOR_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_PROPERTY_PATTERNS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">False</s:Boolean>
<s:Int64
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ARRAY_INITIALIZER_ELEMENTS_ON_LINE/@EntryValue">10</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ENUM_MEMBERS_ON_LINE/@EntryValue">5</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_FORMAL_PARAMETERS_ON_LINE/@EntryValue">5</s:Int64>
<s:Int64
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_INVOCATION_ARGUMENTS_ON_LINE/@EntryValue">10</s:Int64>
<s:Int64
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_PRIMARY_CONSTRUCTOR_PARAMETERS_ON_LINE/@EntryValue">5</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/NESTED_TERNARY_STYLE/@EntryValue">COMPACT</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OTHER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_DOTS/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OUTDENT_STATEMENT_LABELS/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_CATCH_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ELSE_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FINALLY_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_LINQ_INTO_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_BLOCK_ON_SAME_LINE/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_METHOD_ON_SINGLE_LINE/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_SWITCH_EXPRESSION_ON_SINGLE_LINE/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/TAB_WIDTH/@EntryValue">2</s:Int64>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/TYPE_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_PRIMARY_CONSTRUCTOR_DECLARATION_LPAR/@EntryValue">False</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_ARROW_WITH_EXPRESSIONS/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue">False</s:Boolean>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ENUM_DECLARATION/@EntryValue">CHOP_IF_LONG</s:String>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_FOR_STMT_HEADER_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">80</s:Int64>
<s:String
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PRIMARY_CONSTRUCTOR_PARAMETERS_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=API/@EntryIndexedValue">API</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IO/@EntryIndexedValue">IO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LG/@EntryIndexedValue">LG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LR/@EntryIndexedValue">LR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ST/@EntryIndexedValue">ST</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=08582792_002Dd334_002D4f6d_002Db467_002Dfc7b9fd4557b/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private, ProtectedInternal, Internal, PrivateProtected" Description="Non-Public Methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8284009d_002De743_002D4d89_002D9402_002Da5bf9a89b657/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, Public, FileLocal" Description="Public Methods"&gt;&lt;ElementKinds&gt;&lt;Kind Name="METHOD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8a85b61a_002D1024_002D4f87_002Db9ef_002D1fdae19930a1/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PARAMETER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ENUM_MEMBER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String
x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=c873eafb_002Dd57f_002D481d_002D8c93_002D77f6863c2f88/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean
x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=CS2_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Plugin_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=TTT_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=Versioning_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean
x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

11
TTT/API/API.csproj Normal file
View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>TTT.API</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="8.0.5"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,45 @@
namespace TTT.API.Command;
public enum CommandResult {
/// <summary>
/// The command ran successfully
/// </summary>
SUCCESS,
/// <summary>
/// The command ran into an error
/// </summary>
ERROR,
/// <summary>
/// The command was improperly formatted or otherwise
/// was not recognized by the command handler
/// </summary>
UNKNOWN_COMMAND,
/// <summary>
/// The command was passed invalid arguments, including
/// incorrect number, or an invalid target
/// </summary>
INVALID_ARGS,
/// <summary>
/// Similar to <see cref="INVALID_ARGS" />, but prompts
/// the Manager to print the usage of the command
/// </summary>
PRINT_USAGE,
/// <summary>
/// The executor of the command did not have
/// the required permissions. This may either
/// be due to a pre-check by the manager, or an
/// "execution" check by the command itself.
/// </summary>
NO_PERMISSION,
/// <summary>
/// This command can only be executed by a player
/// (i.e. not from the console)
/// </summary>
PLAYER_ONLY
}

View File

@@ -0,0 +1,14 @@
using TTT.API.Player;
namespace TTT.API.Command;
public interface ICommand : ITerrorModule {
string? Description => null;
string[] Usage => [];
string[] RequiredFlags => [];
string[] RequiredGroups => [];
string[] Aliases => [Id];
bool MustBeOnMainThread => false;
Task<CommandResult> Execute(IOnlinePlayer? executor, ICommandInfo info);
}

View File

@@ -0,0 +1,14 @@
using CounterStrikeSharp.API.Modules.Commands;
using TTT.API.Player;
namespace TTT.API.Command;
public interface ICommandInfo {
string[] Args { get; }
IOnlinePlayer? CallingPlayer { get; }
CommandCallingContext CallingContext { get; set; }
string CommandString => string.Join(' ', Args);
int ArgCount => Args.Length;
void ReplySync(string message);
ICommandInfo Skip(int count = 1);
}

View File

@@ -0,0 +1,31 @@
using TTT.API.Player;
namespace TTT.API.Command;
/// <summary>
/// An interface that allows for registering and processing commands.
/// </summary>
public interface ICommandManager {
ISet<ICommand> Commands { get; }
/// <summary>
/// Registers a command with the manager.
/// </summary>
/// <param name="command">True if the command was successfully registered.</param>
bool RegisterCommand(ICommand command);
/// <summary>
/// Unregisters a command from the manager.
/// </summary>
/// <param name="command">True if the command was successfully unregistered.</param>
bool UnregisterCommand(ICommand command);
bool CanExecute(IOnlinePlayer? executor, ICommand command);
/// <summary>
/// Attempts to process a command.
/// </summary>
/// <param name="info"></param>
/// <returns>True if the command finished processing successfully.</returns>
Task<CommandResult> ProcessCommand(ICommandInfo info);
}

5
TTT/API/Events/Event.cs Normal file
View File

@@ -0,0 +1,5 @@
namespace TTT.API.Events;
public class Event {
public virtual string Id => GetType().Name.ToLowerInvariant();
}

View File

@@ -0,0 +1,25 @@
namespace TTT.API.Events;
[AttributeUsage(AttributeTargets.Method)]
public class EventHandlerAttribute : Attribute {
public uint Priority { get; set; } = Events.Priority.DEFAULT;
public bool IgnoreCanceled { get; set; }
}
/// <summary>
/// Represents the priority levels for event handlers.
/// The lower the number, the higher the priority.
/// Higher priority handlers are executed before lower priority ones. Thus,
/// if you want a handler to have final say in an event's processing,
/// use a lower priority to be executed last.
/// </summary>
public static class Priority {
public const uint HIGHEST = 10;
public const uint HIGHER = 20;
public const uint HIGH = 40;
public const uint DEFAULT = 60;
public const uint LOW = 80;
public const uint LOWER = 100;
public const uint LOWEST = 200;
public const uint MONITOR = 1000;
}

View File

@@ -0,0 +1,5 @@
namespace TTT.API.Events;
public interface ICancelableEvent {
public bool IsCanceled { get; set; }
}

View File

@@ -1,7 +1,8 @@
namespace TTT.Api.Events;
namespace TTT.API.Events;
public interface IEventBus {
void RegisterListener(IListener listener);
void UnregisterListener(IListener listener);
void Dispatch(Event ev);

View File

@@ -0,0 +1,5 @@
namespace TTT.API.Events;
public interface IListener : ITerrorModule {
void ITerrorModule.Start() { }
}

View File

@@ -0,0 +1,51 @@
using Microsoft.Extensions.DependencyInjection;
using TTT.API.Command;
using TTT.API.Events;
namespace TTT.API.Extensions;
/// <summary>
/// We use this to register all instances of <see cref="ITerrorModule" /> under
/// its interface, allowing us to get the list of all modules simply using ITerrorModule.
/// </summary>
public static class ServiceCollectionExtensions {
public static void AddModBehavior<TExtension>(
this IServiceCollection collection)
where TExtension : class, ITerrorModule {
if (typeof(TExtension).IsAssignableTo(typeof(IPluginModule)))
collection.AddTransient<IPluginModule>(provider
=> (provider.GetRequiredService<TExtension>() as IPluginModule)!);
if (typeof(TExtension).IsAssignableTo(typeof(IListener)))
collection.AddTransient<IListener>(provider
=> (provider.GetRequiredService<TExtension>() as IListener)!);
if (typeof(TExtension).IsAssignableTo(typeof(ICommand)))
collection.AddTransient<ICommand>(provider
=> (provider.GetRequiredService<TExtension>() as ICommand)!);
collection.AddSingleton<TExtension>();
collection.AddTransient<ITerrorModule, TExtension>(provider
=> provider.GetRequiredService<TExtension>());
}
/// <summary>
/// Add a <see cref="ITerrorModule" /> to the global service collection
/// </summary>
/// <param name="collection"></param>
/// <typeparam name="TExtension"></typeparam>
/// <typeparam name="TInterface"></typeparam>
public static void AddModBehavior<TInterface, TExtension>(
this IServiceCollection collection)
where TExtension : class, ITerrorModule, TInterface
where TInterface : class {
// Add the root extension itself as a scoped service.
// This means every time Load is called in the main Jailbreak loader,
// the extension will be fetched and kept as a singleton for the duration
// until "Unload" is called.
collection.AddModBehavior<TExtension>();
collection.AddTransient<TInterface, TExtension>(p
=> p.GetRequiredService<TExtension>());
}
}

13
TTT/API/Game/EndReason.cs Normal file
View File

@@ -0,0 +1,13 @@
using TTT.API.Role;
namespace TTT.API.Game;
public record EndReason(string? Message, IRole? WinningRole = null) {
public EndReason(IRole role) : this(null, role) { }
public static EndReason TIMEOUT(IRole? defaultTeam) {
return new EndReason("Round ended due to timeout", defaultTeam);
}
public static EndReason ERROR(string err) { return new EndReason(err); }
}

27
TTT/API/Game/IAction.cs Normal file
View File

@@ -0,0 +1,27 @@
using TTT.API.Player;
using TTT.API.Role;
namespace TTT.API.Game;
public interface IAction {
IPlayer Player { get; }
IPlayer? Other { get; }
IRole? PlayerRole { get; }
IRole? OtherRole { get; }
string Id { get; }
string Verb { get; }
string Details { get; }
string Prefix => "";
public string Format() {
var pRole = PlayerRole != null ?
$" [{PlayerRole.Name.First(char.IsAsciiLetter)}]" :
"";
var oRole = OtherRole != null ?
$" [{OtherRole.Name.First(char.IsAsciiLetter)}]" :
"";
return Other is not null ?
$"{Prefix}{Player}{pRole} {Verb} {Other}{oRole} {Details}" :
$"{Prefix}{Player}{pRole} {Verb} {Details}";
}
}

View File

@@ -0,0 +1,23 @@
using TTT.API.Player;
namespace TTT.API.Game;
public interface IActionLogger {
/// <summary>
/// Logs an action that has occurred in the game.
/// </summary>
/// <param name="action">The action to log.</param>
void LogAction(IAction action);
IEnumerable<(DateTime, IAction)> GetActions();
/// <summary>
/// Clears all logged actions.
/// </summary>
void ClearActions();
void PrintLogs();
void PrintLogs(IOnlinePlayer? player);
string[] MakeLogs();
}

58
TTT/API/Game/IGame.cs Normal file
View File

@@ -0,0 +1,58 @@
using TTT.API.Player;
using TTT.API.Role;
namespace TTT.API.Game;
public interface IGame : IDisposable {
/// <summary>
/// The list of players in the game.
/// Spectators are not included in this list.
/// </summary>
ICollection<IPlayer> Players { get; }
public IList<IRole> Roles { get; }
IActionLogger Logger { get; }
DateTime? StartedAt { get; }
DateTime? FinishedAt { get; }
IRole? WinningRole { get; set; }
State State { get; set; }
IRoleAssigner RoleAssigner { get; init; }
/// <summary>
/// Attempts to start a game.
/// Depending on implementation, this may start a countdown or immediately start the game.
/// </summary>
/// <param name="countdown">TimeSpan for countdown, null means start immediately</param>
IObservable<long>? Start(TimeSpan? countdown = null);
void EndGame(EndReason? reason = null);
bool CheckEndConditions();
ISet<IOnlinePlayer> GetAlive() {
return Players.OfType<IOnlinePlayer>().Where(p => p.IsAlive).ToHashSet();
}
ISet<IOnlinePlayer> GetAlive(Type roleType, bool loose = true) {
if (!typeof(IRole).IsAssignableFrom(roleType))
throw new ArgumentException(
"roleType must be a type that implements IRole", nameof(roleType));
if (!loose)
return GetAlive()
.Where(p => RoleAssigner.GetRoles(p).Any(r => r.GetType() == roleType))
.ToHashSet();
return GetAlive()
.Where(p => RoleAssigner.GetRoles(p).Any(roleType.IsInstanceOfType))
.ToHashSet();
}
ISet<IOnlinePlayer> GetAlive(IRole role, bool loose = true) {
return GetAlive(role.GetType(), loose);
}
}

View File

@@ -0,0 +1,12 @@
namespace TTT.API.Game;
public interface IGameManager : IDisposable {
IGame? ActiveGame { get; protected set; }
void IDisposable.Dispose() {
ActiveGame?.Dispose();
ActiveGame = null;
}
IGame? CreateGame();
}

23
TTT/API/Game/State.cs Normal file
View File

@@ -0,0 +1,23 @@
namespace TTT.API.Game;
public enum State {
/// <summary>
/// Waiting for players to join.
/// </summary>
WAITING,
/// <summary>
/// Waiting for the countdown to finish before starting the game.
/// </summary>
COUNTDOWN,
/// <summary>
/// Currently playing the game.
/// </summary>
IN_PROGRESS,
/// <summary>
/// Game has finished.
/// </summary>
FINISHED
}

9
TTT/API/IPluginModule.cs Normal file
View File

@@ -0,0 +1,9 @@
using CounterStrikeSharp.API.Core;
namespace TTT.API;
public interface IPluginModule : ITerrorModule {
void Start(BasePlugin? plugin) { Start(); }
void Start(BasePlugin? plugin, bool hotReload) { Start(plugin); }
}

8
TTT/API/ITerrorModule.cs Normal file
View File

@@ -0,0 +1,8 @@
namespace TTT.API;
public interface ITerrorModule : IDisposable {
string Id => GetType().Name;
string Version => GitVersionInformation.FullSemVer;
void Start();
}

18
TTT/API/IWeapon.cs Normal file
View File

@@ -0,0 +1,18 @@
namespace TTT.API;
public interface IWeapon {
/// <summary>
/// The internal ID of the weapon, should match the ID of the weapon in the underlying game.
/// </summary>
public string WeaponId { get; }
/// <summary>
/// The amount of ammo that is in reserve for this weapon.
/// </summary>
public int? ReserveAmmo { get; }
/// <summary>
/// The amount of ammo that is currently in the weapon's magazine or chamber.
/// </summary>
public int? CurrentAmmo { get; }
}

View File

@@ -0,0 +1,43 @@
using TTT.API.Player;
namespace TTT.API.Messages;
public interface IMessenger {
Task<bool> Message(IPlayer? player, string message, params object[] args);
void Debug(string msg, params object[] args);
void DebugInform(string msg, params object[] args) { Debug(msg, args); }
void DebugAnnounce(string msg, params object[] args) { Debug(msg, args); }
Task<bool> MessageAll(string message, params object[] args);
Task<bool> BackgroundMsgAll(string message, params object[] args);
Task<bool> ScreenMsgAll(string message, params object[] args);
/// <summary>
/// Attempt to send a message to a player without showing it on the screen.
/// This could mean sending to console, background file, or just
/// falling back to showing it on the screen.
/// </summary>
/// <param name="player"></param>
/// <param name="message"></param>
/// <param name="args"></param>
/// <returns></returns>
Task<bool> BackgroundMsg(IPlayer? player, string message,
params object[] args) {
return Message(player, message, args);
}
/// <summary>
/// Attempt to send a message to a player that will be shown on the screen using
/// an alternative method, such as a popup or a notification.
/// May just fall back to showing it on the screen if no alternative is available.
/// </summary>
/// <param name="player"></param>
/// <param name="message"></param>
/// <param name="args"></param>
/// <returns></returns>
Task<bool> ScreenMsg(IPlayer? player, string message, params object[] args) {
return Message(player, message, args);
}
}

View File

@@ -0,0 +1,18 @@
namespace TTT.API.Player;
/// <summary>
/// Assumes a maximum of 64 players.
/// Each bit in the bitmask represents whether a player is visible to the client.
/// Bit 0 is unused, bit 1 represents player 1, bit 2 represents player 2, and so on.
/// </summary>
public interface IIconManager {
ulong GetVisiblePlayers(int client);
void SetVisiblePlayers(int client, ulong playersBitmask);
void RevealToAll(int client);
void AddVisiblePlayer(int client, int player);
void RemoveVisiblePlayer(int client, int player);
void SetVisiblePlayers(IOnlinePlayer online, ulong playersBitmask);
void RevealToAll(IOnlinePlayer online);
void ClearAllVisibility();
}

View File

@@ -0,0 +1,29 @@
namespace TTT.API.Player;
public interface IInventoryManager {
/// <summary>
/// Gives a weapon to the player.
/// </summary>
/// <param name="player">The player to give the weapon to.</param>
/// <param name="weapon"></param>
Task GiveWeapon(IOnlinePlayer player, IWeapon weapon);
/// <summary>
/// Removes a weapon from the player.
/// </summary>
/// <param name="player">The player to remove the weapon from.</param>
/// <param name="weaponId">The ID of the weapon to remove.</param>
Task RemoveWeapon(IOnlinePlayer player, string weaponId);
Task RemoveWeapon(IOnlinePlayer player, IWeapon weapon) {
return RemoveWeapon(player, weapon.WeaponId);
}
Task RemoveWeaponInSlot(IOnlinePlayer player, int slot);
/// <summary>
/// Removes all weapons from the player.
/// </summary>
/// <param name="player">The player to remove all weapons from.</param>
Task RemoveAllWeapons(IOnlinePlayer player);
}

3
TTT/API/Player/IMuted.cs Normal file
View File

@@ -0,0 +1,3 @@
namespace TTT.API.Player;
public interface IMuted : ISet<string> { }

View File

@@ -0,0 +1,8 @@
namespace TTT.API.Player;
public interface IOnlinePlayer : IPlayer {
public int Health { get; set; }
public int MaxHealth { get; set; }
public int Armor { get; set; }
public bool IsAlive { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace TTT.API.Player;
public interface IPermissionManager {
bool HasFlags(IPlayer player, params string[] flags);
bool InGroups(IPlayer player, params string[] groups);
}

16
TTT/API/Player/IPlayer.cs Normal file
View File

@@ -0,0 +1,16 @@
namespace TTT.API.Player;
public interface IPlayer : IEquatable<IPlayer> {
/// <summary>
/// The unique identifier for the player, should
/// be unique across all players at all times.
/// </summary>
string Id { get; }
string Name { get; set; }
bool IEquatable<IPlayer>.Equals(IPlayer? other) {
if (other is null) return false;
return Id == other.Id;
}
}

View File

@@ -0,0 +1,6 @@
namespace TTT.API.Player;
public interface IPlayerConverter<T> : ITerrorModule {
public IPlayer GetPlayer(T player);
public T? GetPlayer(IPlayer player);
}

View File

@@ -0,0 +1,24 @@
namespace TTT.API.Player;
public interface IPlayerFinder {
public IOnlinePlayer AddPlayer(IOnlinePlayer player);
public void AddPlayers(params IOnlinePlayer[] players) {
foreach (var p in players) AddPlayer(p);
}
public IPlayer RemovePlayer(IPlayer player);
ISet<IOnlinePlayer> GetOnline();
IOnlinePlayer? GetPlayerById(string id) {
return string.IsNullOrEmpty(id) ?
null :
GetOnline().FirstOrDefault(p => p.Id == id);
}
IOnlinePlayer? GetPlayerByName(string name) {
var matches = GetOnline().Where(p => p.Name.Contains(name)).ToList();
return matches.Count == 1 ? matches[0] : null;
}
}

4
TTT/API/README.md Normal file
View File

@@ -0,0 +1,4 @@
# TTT - API
This project contains the public API for TTT.
No game logic, internal management, etc. is (or ever should be) included here.

24
TTT/API/Role/IRole.cs Normal file
View File

@@ -0,0 +1,24 @@
using System.Drawing;
using TTT.API.Player;
namespace TTT.API.Role;
/// <summary>
/// Represents a role that can be assigned to a player.
/// Does not necessarily imply they are in the game.
/// </summary>
public interface IRole : IEquatable<IRole> {
string Id { get; }
string Name { get; }
Color Color { get; }
bool IEquatable<IRole>.Equals(IRole? other) {
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return Id == other.Id;
}
IOnlinePlayer? FindPlayerToAssign(ISet<IOnlinePlayer> players);
void OnAssign(IOnlinePlayer player) { }
}

View File

@@ -0,0 +1,29 @@
using TTT.API.Player;
using TTT.API.Storage;
namespace TTT.API.Role;
public interface IRoleAssigner : IKeyedStorage<IPlayer, ICollection<IRole>>,
IKeyWritable<IPlayer, ICollection<IRole>> {
/// <summary>
/// Will attempt to assign roles to all players in the set.
/// Note that game-specific behavior and logic will almost certainly
/// change how this behaves.
/// Role assigning will call <see cref="IRole.FindPlayerToAssign" /> on the
/// first role continuously until it returns null, then it will move on to
/// second role, and so on.
/// Thus, the order of roles **does matter**. If you want a role to be assigned
/// first, it should be the first in the list.
/// </summary>
/// <param name="players"></param>
/// <param name="roles"></param>
public void AssignRoles(ISet<IOnlinePlayer> players, IList<IRole> roles);
public void SetRole(IOnlinePlayer player, IRole role) {
Write(player, new List<IRole> { role }).GetAwaiter().GetResult();
}
public ICollection<IRole> GetRoles(IPlayer player) {
return Load(player).GetAwaiter().GetResult() ?? [];
}
}

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