Compare commits

..

No commits in common. "main" and "v0.2.5" have entirely different histories.
main ... v0.2.5

4 changed files with 13 additions and 38 deletions

View File

@ -10,9 +10,6 @@
## Table of Contents ## Table of Contents
- [Installation](#installation) - [Installation](#installation)
- [Configuration](#configuration)
- [Use](#use)
- [Shell Completion](#shell-completion)
- [License](#license) - [License](#license)
## Installation ## Installation
@ -76,7 +73,6 @@ Usage: q3rcon-cli [OPTIONS] COMMAND
┏━ Options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┏━ Options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ -i, --interactive Whether to start in interactive mode (defaults to false) ┃ ┃ -i, --interactive Whether to start in interactive mode (defaults to false) ┃
┃ -v, --version Show the version and exit ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Connection options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┏━ Connection options ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
@ -86,14 +82,6 @@ Usage: q3rcon-cli [OPTIONS] COMMAND
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
``` ```
## Shell Completion
Shell completion scripts are available for *bash*, *zsh*, and *fish*.
```console
q3rcon-cli --install-autocomplete
```
## Special Thanks ## Special Thanks
- [lapetus-11](https://github.com/Iapetus-11) for writing the [aio-q3-rcon](https://github.com/Iapetus-11/aio-q3-rcon) package. - [lapetus-11](https://github.com/Iapetus-11) for writing the [aio-q3-rcon](https://github.com/Iapetus-11/aio-q3-rcon) package.

View File

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

View File

@ -1,11 +1,9 @@
import clypi import clypi
from aioq3rcon import Client, IncorrectPasswordError from aioq3rcon import Client, IncorrectPasswordError
from clypi import Command, Spinner, arg from clypi import Command, Spinner, arg
from clypi import parsers as cp
from typing_extensions import override from typing_extensions import override
from . import console from . import console
from .__about__ import __version__
from .commands import ( from .commands import (
Fastrestart, Fastrestart,
Gametype, Gametype,
@ -39,7 +37,6 @@ class Q3rconCli(Command):
help='The host to connect to', help='The host to connect to',
env='Q3RCON_CLI_HOST', env='Q3RCON_CLI_HOST',
group='Connection', group='Connection',
parser=cp.Str(min=1),
) )
port: int = arg( port: int = arg(
28960, 28960,
@ -47,7 +44,6 @@ class Q3rconCli(Command):
help='The port to connect to', help='The port to connect to',
env='Q3RCON_CLI_PORT', env='Q3RCON_CLI_PORT',
group='Connection', group='Connection',
parser=cp.Int(min=1, max=65535),
) )
password: str = arg( password: str = arg(
'', '',
@ -55,25 +51,15 @@ class Q3rconCli(Command):
help='The password for authentication', help='The password for authentication',
env='Q3RCON_CLI_PASSWORD', env='Q3RCON_CLI_PASSWORD',
group='Connection', group='Connection',
parser=cp.Str(min=8),
) )
interactive: bool = arg( interactive: bool = arg(
False, False,
short='i', short='i',
help='Whether to start in interactive mode (defaults to false)', help='Whether to start in interactive mode (defaults to false)',
) )
version: bool = arg(
False,
short='v',
help='Show the version and exit',
)
@override @override
async def run(self): async def run(self):
if self.version:
print(f'q3rcon-cli version: {clypi.style(__version__, fg="green")}')
return
if self.interactive: if self.interactive:
await self.run_interactive() await self.run_interactive()
else: else:
@ -82,7 +68,7 @@ class Q3rconCli(Command):
async def run_interactive(self): async def run_interactive(self):
print( print(
clypi.style('Entering interactive mode. Type', fg='blue'), clypi.style('Entering interactive mode. Type', fg='blue'),
clypi.style("'Q'", fg='yellow'), clypi.style("'Q'", fg='red'),
clypi.style('to quit.', fg='blue'), clypi.style('to quit.', fg='blue'),
) )
@ -92,14 +78,14 @@ class Q3rconCli(Command):
if command.lower() == 'q': if command.lower() == 'q':
break break
CMD_CONFIG = { TIMEOUTS = {
'status': (2, 1, False), 'status': (2, 1, False),
'fast_restart': (3, 1, True), 'fast_restart': (3, 1, True),
'map_restart': (3, 1, True), 'map_restart': (3, 1, True),
'map': (3, 1, True), 'map': (3, 1, True),
'map_rotate': (3, 1, True), 'map_rotate': (3, 1, True),
} }
timeout, fragment_read_timeout, interpret = CMD_CONFIG.get( timeout, fragment_read_timeout, interpret = TIMEOUTS.get(
command.split()[0].lower(), command.split()[0].lower(),
(DEFAULT_TIMEOUT, DEFAULT_FRAGMENT_READ_TIMEOUT, False), (DEFAULT_TIMEOUT, DEFAULT_FRAGMENT_READ_TIMEOUT, False),
) )
@ -109,20 +95,20 @@ class Q3rconCli(Command):
self.host, self.host,
self.port, self.port,
self.password, self.password,
timeout=timeout, timeout=timeout or DEFAULT_TIMEOUT,
fragment_read_timeout=fragment_read_timeout, fragment_read_timeout=fragment_read_timeout
or DEFAULT_FRAGMENT_READ_TIMEOUT,
) as client: ) as client:
try: try:
response = await client.send_command( if response := await client.send_command(
command, interpret=interpret command, interpret=interpret
) ):
console.out.print_response(response)
except TimeoutError: except TimeoutError:
console.err.print( console.err.print(
f"Timeout waiting for response for command: '{command}'" f"Timeout waiting for response for command: '{command}'"
) )
console.out.print_response(response)
def main(): def main():
try: try:

View File

@ -50,8 +50,9 @@ class OutConsole(Console):
return OutConsole.COLOUR_CODE_REGEX.sub('', s) return OutConsole.COLOUR_CODE_REGEX.sub('', s)
def print_response(self, response: str): def print_response(self, response: str):
if response := self._remove_colour_codes(response).removeprefix('print\n'): response = self._remove_colour_codes(response).removeprefix('print\n')
cprint(response, fg=self.style)
cprint(f'\n{response}\n', fg=self.style)
def print_status(self, response: str): def print_status(self, response: str):
_slots = [] _slots = []