5 Commits

Author SHA1 Message Date
dd7f9775f2 minor bump 2026-03-21 10:20:11 +00:00
36e54e89b7 add maprestart command 2026-03-21 10:19:01 +00:00
84702a5360 add pre-commit config + update readme script 2026-03-21 10:17:45 +00:00
7ec51293e4 upd .envrc example 2026-03-21 00:45:54 +00:00
0e962e5aa0 run through formatter 2026-03-21 00:43:24 +00:00
7 changed files with 106 additions and 23 deletions

8
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,8 @@
repos:
- repo: local
hooks:
- id: update-readme
name: update-readme
entry: python tools/update_readme_help.py
language: python
pass_filenames: false

View File

@@ -49,8 +49,8 @@ example .envrc:
```env
#!/usr/bin/env bash
export Q3RCON_CLI_HOST="localhost"
export Q3RCON_CLI_PORT="28960"
export Q3RCON_CLI_HOST=localhost
export Q3RCON_CLI_PORT=28960
export Q3RCON_CLI_PASSWORD="<rcon password>"
```
@@ -59,26 +59,27 @@ export Q3RCON_CLI_PASSWORD="<rcon password>"
```console
Usage: q3rcon-cli [OPTIONS] COMMAND
┏━ Subcommands ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
status Prints the status of the server ┃
mapname Prints the current map name of the server ┃
maprotate Rotates the map to the next one in the map rotation list
fastrestart Executes a fast restart of the server
gametype Get or set the current gametype of the server ┃
hostname Get or set the current hostname of the server
┃ map Get the current map or change to a new one
┃ plugins Prints the currently loaded plugins of the server ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Subcommands ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
fastrestart Executes a fast restart of the server
gametype Get or set the current gametype of the server
hostname Get or set the current hostname of the server
map Get the current map or change to a new one
mapname Prints the current map name of the server
maprestart Restarts the current map
┃ maprotate Rotates the map to the next one in the map rotation list
┃ plugins Prints the currently loaded plugins of the server
┃ status Prints the status of the server ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ -i, --interactive Whether to start in interactive mode (defaults to false) ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┃ -i, --interactive Whether to start in interactive mode (defaults to false)
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┏━ Connection options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ -h, --host <HOST> The host to connect to ┃
┃ -p, --port <PORT> The port to connect to ┃
┃ -P, --password <PASSWORD> The password for authentication ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Connection options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┃ -h, --host <HOST> The host to connect to
┃ -p, --port <PORT> The port to connect to
┃ -P, --password <PASSWORD> The password for authentication
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
## Special Thanks

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2026-present onyx-and-iris <code@onyxandiris.online>
#
# SPDX-License-Identifier: MIT
__version__ = "0.1.0"
__version__ = '0.2.0'

View File

@@ -9,6 +9,7 @@ from .commands import (
Hostname,
Map,
Mapname,
Maprestart,
Maprotate,
Plugins,
Status,
@@ -16,7 +17,15 @@ from .commands import (
from .console import Console
Subcommands = (
Status | Mapname | Maprotate | Fastrestart | Gametype | Hostname | Map | Plugins
Fastrestart
| Gametype
| Hostname
| Map
| Mapname
| Maprestart
| Maprotate
| Plugins
| Status
)
@@ -54,7 +63,7 @@ class Q3rconCli(Command):
if self.interactive:
await self.run_interactive()
else:
await Status.run(self)
await Status(self.host, self.port, self.password).run()
async def run_interactive(self):
print(

View File

@@ -3,6 +3,7 @@ from .gametype import Gametype
from .hostname import Hostname
from .map import Map
from .mapname import Mapname
from .maprestart import Maprestart
from .maprotate import Maprotate
from .plugins import Plugins
from .status import Status
@@ -16,4 +17,5 @@ __all__ = [
'Hostname',
'Map',
'Plugins',
'Maprestart',
]

View File

@@ -0,0 +1,22 @@
from aioq3rcon import Client
from clypi import Command, Spinner, arg
from typing_extensions import override
from q3rcon_cli.console import Console
class Maprestart(Command):
"""Restarts the current map."""
host: str = arg(inherited=True)
port: int = arg(inherited=True)
password: str = arg(inherited=True)
@override
async def run(self):
async with Spinner('Restarting map...'):
async with Client(
self.host, self.port, self.password, fragment_read_timeout=1
) as client:
if response := await client.send_command('map_restart'):
Console.print_response(response)

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import re
import subprocess
from pathlib import Path
REPO_ROOT = Path(__file__).parent.parent
README_PATH = REPO_ROOT / 'README.md'
HELP_CMD = ['hatch', 'run', 'q3rcon-cli', '--help']
def get_help_output():
result = subprocess.run(HELP_CMD, capture_output=True, text=True, check=True)
output = result.stdout.strip()
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
output = ansi_escape.sub('', output)
return output
def update_readme(help_text):
readme = README_PATH.read_text()
pattern = re.compile(
r'```console\nUsage: q3rcon-cli \[OPTIONS\] COMMAND.*?```', re.DOTALL
)
new_block = f'```console\n{help_text}\n```'
new_readme, n = pattern.subn(new_block, readme, count=1)
if n == 0:
raise RuntimeError(
'Could not find the q3rcon-cli usage console block to replace in README.md'
)
README_PATH.write_text(new_readme)
print('README.md updated with latest --help output.')
def main():
help_text = get_help_output()
update_readme(help_text)
if __name__ == '__main__':
main()