87 lines
2.8 KiB
Python

from aioq3rcon import Client, RCONError
from textual.app import App, ComposeResult
from textual.containers import Grid
from textual.widgets import Button, Input, RichLog
from .configscreen import ConfigScreen
from .settings import settings
from .writable import Writable
class RconApp(App):
CSS_PATH = 'q3rcon_tui.tcss'
def __init__(self):
super().__init__()
self.writable = Writable()
def compose(self) -> ComposeResult:
yield Grid(
Input('status', placeholder='Enter a rcon command', id='command'),
RichLog(id='response'),
Button('Send', variant='success', id='send'),
Button('Config', variant='warning', id='config'),
Button('Quit', variant='primary', id='quit'),
id='dialog',
)
async def on_key(self, event) -> None:
# prevent keypresses from ConfigScreen from triggering actions in RconApp
if self.screen and isinstance(self.screen, ConfigScreen):
return
match event.key:
case 'enter' if self.query_one('#command', Input).has_focus:
self.query_one('#send', Button).press()
case 'f2':
self.query_one('#config', Button).press()
async def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == 'quit':
self.app.exit()
elif event.button.id == 'config':
result = await self.push_screen(
ConfigScreen(settings.host, settings.port, settings.password)
)
if result:
self.query_one('#response', RichLog).write(
f'Configuration updated: {settings.host}:{settings.port}'
)
return
if event.button.id != 'send':
return
if not settings.append:
self.query_one('#response', RichLog).clear()
cmd = self.query_one('#command', Input).value.strip()
if not cmd:
self.app.bell()
return
try:
async with Client(
settings.host, settings.port, settings.password
) as client:
response = await client.send_command(cmd)
self.query_one('#response', RichLog).write(
self.writable.parse(cmd, response)
)
except RCONError:
output = (
f'Unable to execute command {cmd}.',
'It may be due to a map change or a server restart.',
'If the problem persists, please check your connection settings and ensure the server is running.',
)
self.query_one('#response', RichLog).write(
self.writable.error('\n'.join(output))
)
self.query_one('#command', Input).value = ''
def main():
app = RconApp()
app.run()