Парсинг логов игры Minecraft

Рейтинг: 0Ответов: 1Опубликовано: 16.02.2023

Пытался я создать фильтрацию матов для чата игры Minecraft, поиск слов(матов) должен был проходить через логи(logs), а после отправлять мне сообщение о нарушении, добавляя в буфер обмена команду, по типу: /warn {nickname} foul language

import os
import time
import pyperclip


prohibited_words = ["badword2", "badword3",]


def follow(thefile):
    thefile.seek(0, 2)
    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line


if __name__ == "__main__":
    logfile = open(r"C:/Users/Korisnik/.cristalix/updates/Minigames/logs/latest.log", "r", encoding="utf-8")
    while True:
        loglines = follow(logfile)
        for line in loglines:
            if "[CHAT]" in line:
                chat_message = line.split("]: [CHAT] ")[1].strip()
                print(chat_message)
                violation_detected = False
                for word in prohibited_words:
                    if word in chat_message:
                        # Violation detected. Extract player's nickname and add punish command to clipboard
                        nickname = line.split(" ┃ ")[-1].split(":")[0].strip()
                        pyperclip.copy(f"/warn {nickname} foul language")
                        print(f"Violation detected. Punish command copied to clipboard: /warn {nickname} foul language")
                        violation_detected = True
                        break
                if violation_detected:
                    break
    if not violation_detected:
        print("No violations detected in the log file.")

Проблема заключается в том, что ники имеют всяки префиксы(приставки), после ника может ранг и так далее. Например, мой код в данный момент может сделать всё точно, только, если в рядом возле ника есть префикс в одну буквы, но мне нужно сделать так, чтобы если даже ник будет окружен различными знаками, то копировался бы только он, к примеру:

CHAT: STAFF | Maximilian #1551: Привет, как дела?
CHAT: LLC | Romanio BOSS: Хотел ли кто поиграть вместе?

Ну и к прочему, не так уж важное, хотелось бы, чтобы мне приходило уведомление о нарушении. Пытался добавить его, но так и не вышло, вечно была ошибка в коде.

Ответы

▲ 0

Всё довольно просто. Для поиска ника лучше использовать регулярные выражения и если я корректно понял что есть ник, то код будет иметь следующий вид:

import time
import pyperclip 
import re

prohibited_words = ["badword2", "badword3", ]


class ListenerFile:
    def __init__(self, path_file):
        self._file = open(path_file, "r", encoding="utf-8")

    def listen(self):
        self._file.seek(0, 2)
        while True:
            line = self._file.readline()
            if not line:
                time.sleep(0.1)
                continue
            yield line


def violation_detected(message) -> bool:  # Возвращает True если находит в строке ругательство
    for word in prohibited_words:
        return word in message


def main():
    path = r"C:/Users/Korisnik/.cristalix/updates/Minigames/logs/latest.log"
    follower = ListenerFile(path)
    for line in follower.listen():
        if "[CHAT]" not in line:
            continue
        chat_message = re.search(r"(?<=(\[CHAT]\s)).*", line).group(0)
        print(chat_message)
        if violation_detected(chat_message):
            pattern = {True: r"(?<=(\[CHAT]\s))[^\s]*", "┃" in line: r"(?<=(┃\s))[^\s]*"}[True]
            nickname = re.search(pattern, line).group(0)

            pyperclip.copy(f"/warn {nickname} foul language")
            print(f"Violation detected. Punish command copied to clipboard: /warn {nickname} foul language")


if __name__ == '__main__':
    main()

Я немного подкорректировал ваш код для лучшей читаемости, заодно исправив несколько моментов.