From dfccc912244c86804f50bd98f15dd178b2d10202 Mon Sep 17 00:00:00 2001 From: SantaSpeen Date: Sat, 13 Jan 2024 11:52:57 +0300 Subject: [PATCH] [+] Version checker [+] cmd .bot info [+] [perms] get_nick --- src/main.py | 96 +++++++++++++++++++++++++---------------- src/modules/__init__.py | 31 ++++++++++--- src/modules/perms.py | 11 ++++- 3 files changed, 94 insertions(+), 44 deletions(-) diff --git a/src/main.py b/src/main.py index 7722e28..2840345 100644 --- a/src/main.py +++ b/src/main.py @@ -1,8 +1,10 @@ +import sys + import requests import vk from loguru import logger -from modules import config, rcon, get_server_status, enter_to_exit, Permissions +from modules import config, rcon, get_server_status, enter_to_exit, Permissions, __version__, new_version class Bot: @@ -23,7 +25,7 @@ class Bot: messages = (len(message) // 4095) for i in range(1, messages + 1): if i > 30: - logger.info("[BOT] Сообщение слишком длинное...") + logger.error("[BOT] Сообщение слишком длинное...") break self.write(peer_id, message[:4095 * i]) else: @@ -44,8 +46,40 @@ class Bot: else: logger.info(f"[BOT] User: {from_id}({r}) in Chat: {peer_id} no have rights RCON cmd: \"{cmd}\".") - def message_handle(self, message): + def _bot_handle(self, message): + from_id = message['from_id'] global perms + if perms.is_allowed(from_id, "bot"): + peer_id = message['peer_id'] + text = message['text'] + logger.info(f"[BOT] {peer_id}:{from_id}:{text}") + tsplit = text.split(" ") + cmds = ("Доступные команды:\n" + " .bot help - Вывести это сообщение.\n" + " .bot info - Выводит краткую информацию о боте." + " .bot perm user <> - Добавить пользователя \n" + " .bot perm reload - Перезагружает пермишины") + if len(tsplit) == 1: + self.write(peer_id, cmds) + return + match tsplit[1]: + case "perm": + match tsplit[2] if len(tsplit) > 2 else None: + case "reload": + perms = Permissions.load() + self.write(peer_id, "Права перезагружены") + case _: + self.write(peer_id, ".bot perm ?") + case "info": + st = get_server_status() + self.write(peer_id, f"RconVkBot\n" + f"Версия бота: {__version__}, последняя: {not new_version}\n" + f"Пинг до сервера: {st.latency:.3f}ms\n" + f"Бедрок: {st.motd.bedrock} ({st.version.protocol})\n") + case _: + self.write(peer_id, cmds) + + def message_handle(self, message): from_id = message['from_id'] peer_id = message['peer_id'] text = message['text'] @@ -53,28 +87,18 @@ class Bot: case i if i.startswith(".rcon "): self.rcon_cmd_handle(i[6:], from_id, peer_id) case i if i.startswith(".bot"): - if perms.is_allowed(peer_id, "bot"): - tsplit = text.split(" ") - if len(tsplit) != 3: - self.write(peer_id, "Доступные команды\n.bot perm reload - Перезагружает пермишины\n") - elif len(tsplit) == 3: - match tsplit[1]: - case "perm": - match tsplit[2]: - case "reload": - perms = Permissions.load() - self.write(peer_id, "Права перезагружены") - case _: - self.write(peer_id, ".bot perm ?") - case _: - self.write(peer_id, ".bot ? ?") + self._bot_handle(message) case "!help": + logger.info(f"[BOT] {peer_id}:{from_id}:{text}") self.write(peer_id, self.help_message) case "!online": + logger.info(f"[BOT] {peer_id}:{from_id}:{text}") players = get_server_status().players self.write(peer_id, f"На сервере сейчас {players.online}/{players.max}") case "!id": - self.write(peer_id, f"Твой ID: {from_id}\nРоль: {perms.get_role(from_id)}") + logger.info(f"[BOT] {peer_id}:{from_id}:{text}") + self.write(peer_id, + f"Твой ID: {from_id}\nРоль: {perms.get_role(from_id)}\nНик: {perms.get_nick(from_id)}") def listen(self): server, key, ts = self.get_lp_server() @@ -88,12 +112,7 @@ class Bot: updates = lp['updates'][0] if updates['type'] == "message_new": self.message_handle(updates['object']['message']) - ts = lp.get('ts') - - except KeyboardInterrupt: - raise KeyboardInterrupt - except Exception as i: ts = lp.get('ts') logger.exception(i) @@ -101,27 +120,28 @@ class Bot: if __name__ == '__main__': perms = Permissions.load() + # Check token if not config.vk.token: logger.error("Токен ВК не найден.") enter_to_exit() + # Test RCON + if rcon("list").startswith("Rcon error"): + logger.error("RCON не отвечает. Проверьте блок \"rcon\" в config.json") + enter_to_exit() + logger.info("RCON доступен.") + # Test Minecraft Server + try: + _players = get_server_status().players + logger.info(f"Проверка сервера. Онлайн: {_players.online}/{_players.max}") + except Exception as e: + logger.exception(e) + logger.info("Сервер не отвечает. Проверьте блок \"minecraft\" в config.json") + enter_to_exit() try: bot = Bot() - # Test RCON - if rcon("list").startswith("Rcon error"): - logger.error("RCON не отвечает. Проверьте блок \"rcon\" в config.json") - enter_to_exit() - logger.info("RCON доступен.") - try: - # Test Minecraft Server - _players = get_server_status().players - logger.info(f"Проверка сервера. Онлайн: {_players.online}/{_players.max}") - except Exception as e: - logger.exception(e) - logger.info("Сервер не отвечает. Проверьте блок \"minecraft\" в config.json") - enter_to_exit() bot.listen() except KeyboardInterrupt: - pass + sys.exit(0) except Exception as e: logger.exception(e) enter_to_exit() diff --git a/src/modules/__init__.py b/src/modules/__init__.py index 0f2fe05..4984b4e 100644 --- a/src/modules/__init__.py +++ b/src/modules/__init__.py @@ -8,10 +8,13 @@ from collections import namedtuple from datetime import datetime from pathlib import Path +import requests from loguru import logger from mcrcon import MCRcon -from .perms import Permissions +from .perms import Permissions, yaml + +__version__ = '1.3.0' raw_config = """\ { @@ -40,7 +43,7 @@ raw_help = """\ """ -def zip_logs(): +def init_logger(): log_file = "./logs/latest.log" log_dir = os.path.dirname(log_file) + "/" if not os.path.exists(log_dir): @@ -65,7 +68,7 @@ def zip_logs(): "{level: <8} | {message}") -zip_logs() +init_logger() if not os.path.exists("config.json"): logger.info("Создание: config.json...") with open("config.json", "w") as f: @@ -107,7 +110,25 @@ def get_server_status(): return server.status() -def enter_to_exit(): +def enter_to_exit(exit_code=1): logger.info("Выход..") input("\nНажмите Enter для продолжения..") - sys.exit(1) + sys.exit(exit_code) + + +def new_version(): + try: + res = requests.get("https://raw.githubusercontent.com/SantaSpeen/Rcon-VK-Bot/master/win/metadata.yml") + data = yaml.load(res.text) + ver = data.get("Version") + if ver and ver != __version__: + logger.info("Обнаружена новая версия: {} -> {}", __version__, ver) + return True + except: + logger.error("Не получилось проверить обновления.") + else: + logger.info("У вас актуальная версия") + return False + + +new_version = new_version() diff --git a/src/modules/perms.py b/src/modules/perms.py index 9838662..71d4c33 100644 --- a/src/modules/perms.py +++ b/src/modules/perms.py @@ -14,6 +14,7 @@ class Permissions: def __init__(self, **kwargs): self._no_role = kwargs.get("noRole") + self._no_nick = kwargs.get("noNick") self.no_rights = kwargs.get("noRights") self._perms = kwargs['perms'] self._members = {} @@ -38,6 +39,7 @@ class Permissions: self._members[member] = { "role": role, "friendly": role_data.get("name", role), + "nick": self._luck_perms['nicks'].get(member) or self._no_nick, "allow": allow } @@ -57,6 +59,12 @@ class Permissions: return u['friendly'] return self._no_role + def get_nick(self, member): + u = self._members.get(member) + if u: + return u.get("nick") + return self._no_nick + @classmethod def load(cls): if os.path.exists(cls.perm_file): @@ -70,6 +78,7 @@ class Permissions: raw = textwrap.dedent("""\ noRole: Нет роли noRights: Нет прав # null для отключения + noNick: Не указан # Используется для !id, ник берётся из LuckPerms.nicks независимо от useLuckPerms perms: admins: # Имя группы name: Админ # Имя группы, которое будет отображаться в боте @@ -89,7 +98,7 @@ class Permissions: # Находится в режиме тестирования # Интеграция с базой данных LuckPerms (Нужна именно внешняя база данных) - useLuckPerms: 1 + useLuckPerms: false LuckPerms: # Таблица соответствия vkID к нику в Майнкрафте