Browse Source

Fix imports and outsource common modules

pull/8/head
Richard Neumann 3 years ago
parent
commit
0cbbf8aaea
  1. 13
      README.md
  2. 63
      rcon/client.py
  3. 0
      rcon/readline.py
  4. 4
      rcon/source/async_rcon.py
  5. 57
      rcon/source/client.py
  6. 2
      rcon/source/config.py
  7. 6
      rcon/source/console.py
  8. 8
      rcon/source/errorhandler.py
  9. 6
      rcon/source/gui.py
  10. 4
      rcon/source/rconclt.py
  11. 6
      rcon/source/rconshell.py

13
README.md

@ -2,7 +2,9 @@
[![Quality Gate Status](https://sonarqube.richard-neumann.de/api/project_badges/measure?project=rcon&metric=alert_status)](https://sonarqube.richard-neumann.de/dashboard?id=rcon)
# rcon
An [RCON protocol](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol) client implementation.
An RCON client implementation.
* [Source RCON protocol](https://developer.valvesoftware.com/wiki/Source_RCON_Protocol)
* [BattlEye RCon protocol](https://www.battleye.com/downloads/BERConProtocol.txt)
## Requirements
`rcon` requires Python 3.8 or higher.
@ -16,11 +18,12 @@ Install rcon from the [AUR](https://aur.archlinux.org/packages/python-rcon/) or
pip install rcon
## Quick start
The `RCON` protocol is used to remotely control a game server, i.e. execute
The `RCON` protocols are used to remotely control game servers, i.e. execute
commands on a game server and receive the respective results.
### Source RCON
```python
from rcon import Client
from rcon.source import Client
with Client('127.0.0.1', 5000, passwd='mysecretpassword') as client:
response = client.run('some_command', 'with', 'some', 'arguments')
@ -28,11 +31,11 @@ with Client('127.0.0.1', 5000, passwd='mysecretpassword') as client:
print(response)
```
## Async support
#### Async support
If you prefer to use `RCON` in an asynchronous environment, you can use `rcon()`.
```python
from rcon import rcon
from rcon.source import rcon
response = await rcon(
'some_command', 'with', 'some', 'arguments',

63
rcon/client.py

@ -0,0 +1,63 @@
"""Common base client."""
from socket import SOCK_STREAM, SocketKind, socket
from typing import Optional
__all__ = ['BaseClient']
class BaseClient:
"""A common RCON client."""
__slots__ = ('_socket', 'host', 'port', 'passwd')
def __init__(
self, host: str, port: int, *,
type: SocketKind = SOCK_STREAM,
timeout: Optional[float] = None,
passwd: Optional[str] = None
):
"""Initializes the base client with the SOCK_STREAM socket type."""
self._socket = socket(type=type)
self.host = host
self.port = port
self.timeout = timeout
self.passwd = passwd
def __enter__(self):
"""Attempts an auto-login if a password is set."""
self._socket.__enter__()
self.connect(login=True)
return self
def __exit__(self, typ, value, traceback):
"""Delegates to the underlying socket's exit method."""
return self._socket.__exit__(typ, value, traceback)
@property
def timeout(self) -> float:
"""Returns the socket timeout."""
return self._socket.gettimeout()
@timeout.setter
def timeout(self, timeout: float):
"""Sets the socket timeout."""
self._socket.settimeout(timeout)
def connect(self, login: bool = False) -> None:
"""Connects the socket and attempts a
login if wanted and a password is set.
"""
self._socket.connect((self.host, self.port))
if login and self.passwd is not None:
self.login(self.passwd)
def close(self) -> None:
"""Closes the socket connection."""
self._socket.close()
def login(self, passwd: str) -> bool:
"""Performs a login."""
raise NotImplementedError()

0
rcon/source/readline.py → rcon/readline.py

4
rcon/source/async_rcon.py

@ -2,8 +2,8 @@
from asyncio import StreamReader, StreamWriter, open_connection
from rcon.exceptions import RequestIdMismatch, WrongPassword
from rcon.proto import Packet, Type
from rcon.source.exceptions import RequestIdMismatch, WrongPassword
from rcon.source.proto import Packet, Type
__all__ = ['rcon']

57
rcon/source/client.py

@ -1,65 +1,16 @@
"""Synchronous client."""
from socket import socket
from typing import Optional
from rcon.exceptions import RequestIdMismatch, WrongPassword
from rcon.proto import Packet, Type
from rcon.client import BaseClient
from rcon.source.exceptions import RequestIdMismatch, WrongPassword
from rcon.source.proto import Packet, Type
__all__ = ['Client']
class Client:
class Client(BaseClient):
"""An RCON client."""
__slots__ = ('_socket', 'host', 'port', 'passwd')
def __init__(
self, host: str, port: int, *,
timeout: Optional[float] = None,
passwd: Optional[str] = None
):
"""Initializes the base client with the SOCK_STREAM socket type."""
self._socket = socket()
self.host = host
self.port = port
self.timeout = timeout
self.passwd = passwd
def __enter__(self):
"""Attempts an auto-login if a password is set."""
self._socket.__enter__()
self.connect(login=True)
return self
def __exit__(self, typ, value, traceback):
"""Delegates to the underlying socket's exit method."""
return self._socket.__exit__(typ, value, traceback)
@property
def timeout(self) -> float:
"""Returns the socket timeout."""
return self._socket.gettimeout()
@timeout.setter
def timeout(self, timeout: float):
"""Sets the socket timeout."""
self._socket.settimeout(timeout)
def connect(self, login: bool = False) -> None:
"""Connects the socket and attempts a
login if wanted and a password is set.
"""
self._socket.connect((self.host, self.port))
if login and self.passwd is not None:
self.login(self.passwd)
def close(self) -> None:
"""Closes the socket connection."""
self._socket.close()
def communicate(self, packet: Packet) -> Packet:
"""Sends and receives a packet."""
with self._socket.makefile('wb') as file:

2
rcon/source/config.py

@ -9,7 +9,7 @@ from os import getenv, name
from pathlib import Path
from typing import Iterable, NamedTuple, Optional, Union
from rcon.exceptions import ConfigReadError, UserAbort
from rcon.source.exceptions import ConfigReadError, UserAbort
__all__ = ['CONFIG_FILES', 'LOG_FORMAT', 'SERVERS', 'Config', 'from_args']

6
rcon/source/console.py

@ -2,9 +2,9 @@
from getpass import getpass
from rcon.client import Client
from rcon.config import Config
from rcon.exceptions import RequestIdMismatch, WrongPassword
from rcon.source.client import Client
from rcon.source.config import Config
from rcon.source.exceptions import RequestIdMismatch, WrongPassword
__all__ = ['PROMPT', 'rconcmd']

8
rcon/source/errorhandler.py

@ -3,10 +3,10 @@
from logging import Logger
from socket import timeout
from rcon.exceptions import ConfigReadError
from rcon.exceptions import RequestIdMismatch
from rcon.exceptions import UserAbort
from rcon.exceptions import WrongPassword
from rcon.source.exceptions import ConfigReadError
from rcon.source.exceptions import RequestIdMismatch
from rcon.source.exceptions import UserAbort
from rcon.source.exceptions import WrongPassword
__all__ = ['ErrorHandler']

6
rcon/source/gui.py

@ -12,9 +12,9 @@ from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk
from rcon.client import Client
from rcon.config import LOG_FORMAT
from rcon.exceptions import RequestIdMismatch, WrongPassword
from rcon.source.client import Client
from rcon.source.config import LOG_FORMAT
from rcon.source.exceptions import RequestIdMismatch, WrongPassword
__all__ = ['main']

4
rcon/source/rconclt.py

@ -4,8 +4,8 @@ from argparse import ArgumentParser, Namespace
from logging import DEBUG, INFO, basicConfig, getLogger
from pathlib import Path
from rcon.client import Client
from rcon.config import CONFIG_FILES, LOG_FORMAT, from_args
from rcon.source.client import Client
from rcon.source.config import CONFIG_FILES, LOG_FORMAT, from_args
from rcon.source.errorhandler import ErrorHandler

6
rcon/source/rconshell.py

@ -4,10 +4,10 @@ from argparse import ArgumentParser, Namespace
from logging import INFO, basicConfig, getLogger
from pathlib import Path
from rcon.config import CONFIG_FILES, LOG_FORMAT, from_args
from rcon.console import PROMPT, rconcmd
from rcon.readline import CommandHistory
from rcon.source.config import CONFIG_FILES, LOG_FORMAT, from_args
from rcon.source.console import PROMPT, rconcmd
from rcon.source.errorhandler import ErrorHandler
from rcon.source.readline import CommandHistory
__all__ = ['get_args', 'main']

Loading…
Cancel
Save