Войти или зарегистрироваться

Помогите Как парсить сообщения в консоли?

  • Автор темы Автор темы Primer
  • Дата начала Дата начала

Primer

Активный участник
Пользователь
Баллы
66
Имя в Minecraft
Primer_Legend
Как парсить сообщения в консоли?
 
А если конкретнее? Какие сообщения? Команды? Если команды, то для этого есть ивет ServerCommandEvent.
 
всю консоль
 
А логи чем не устраивают? Ну тогда можешь читать текущий файл логов каждые N секунд/минут и отправлять куда тебе надо.
 
В РеА реализовано так - создается свой SteamHandler с перезаписанным publish, в нем вызывается своя логика и super.publish(...); далее подвязывается к логгеру баккита. Но неуверен, как хорошо работать будет нынче, просто потому что реализовано было ещё fromgate'ом в бородатые года.
 
PHP:
// Класс.
public class ConsoleFilter implements Filter {
    @Override
    public boolean isLoggable(LogRecord record) {
      //  Тут ты читаешь сообщения.
      record.getMessage();
      // Или даже меняешь его.
      record.setMessage("СТРОКА");
      return true; // false - строка не будет записана в лог.
    }
}

// Подключаем всё это дело.
ConsoleFilter console_filter = new ConsoleFilter();

this.getLogger().setFilter(console_filter);
Bukkit.getLogger().setFilter(console_filter);
Logger.getLogger("Minecraft").setFilter(console_filter)

Это для старых версий. Похожим образом для новых, но там будет использоваться Log4j (там и возможностей побольше).
 
Последнее редактирование:
Собрал все ответы выше в одном сообщении и добавил свой вариант и примеры:

1) Если нужно получать только ответ на команды, выполненные самостоятельно - можно реализовать собственный CommandSender и от его имени выполнять команды. Потребуется написать собственную реализацию всем методам отправки сообщений.

2) Если нужно отслеживать/перехватывать абсолютно все сообщения, то необходимо всем логгерам добавить хендлер или задать фильтр на уровне логгера. Код и примеры:

Прежде всего, потребуется две мавен-зависимости:
org.apache.logging.log4j:log4j-core:VERSION
org.apache.logging.log4j:log4j-api:VERSION

Добавление фильтра:
PHP:
org.apache.logging.log4j.Logger rootLogger = org.apache.logging.log4j.LogManager.getRootLogger();
if (rootLogger instanceof org.apache.logging.log4j.core.Logger) {
    ((org.apache.logging.log4j.core.Logger) rootLogger).addFilter(filter);
}
Совет: обращайте внимание на импорты.

Примеры в плагинах:

AuthMe:
https://github.com/AuthMe/AuthMeRel...3c6b3df4/src/main/java/fr/xephi/authme/output

DiscordSRV:
Фильтр:
https://github.com/DiscordSRV/Disco...carsz/discordsrv/objects/log4j/JdaFilter.java
Регистрация:
https://github.com/DiscordSRV/Disco...github/scarsz/discordsrv/DiscordSRV.java#L692
Снятие регистрации:
https://github.com/DiscordSRV/Disco...ithub/scarsz/discordsrv/DiscordSRV.java#L1530

ConsoleSpamFix:
JAR-файл качать тут: https://spigotmc.org/resources/18410
Декомпилировать можно тут: http://javadecompilers.com

---
Если же нужно не просто отслеживать сообщения, но ещё и модифицировать их - читайте:
1) https://stackoverflow.com/questions/40002310
2) https://stackoverflow.com/questions/22218832

Внимание! По информации из этой темы данный способ НЕ позволяет отслеживать сообщения, отправленные с использованием ванильного логгера Minecraft.

PHP:
StreamHandler streamHandler = new StreamHandler() {
    @Override
    // Подходит для отмены или изменения сообщений
    public boolean isLoggable(LogRecord record) {
        String msg = record.getMessage();
        boolean cancelMessage = false;
        record.setMessage("StreamHandler.isLoggable(): " + msg);
        return !cancelMessage;
    }

    @Override
    // Подходит для получения сообщений, которые не были отменены
    public void publish(LogRecord record) {
        String msg = record.getMessage();
        record.setMessage("StreamHandler.publish(): " + msg);
        super.publish(record);
    }
};
for (Logger logger : loggers) {
    logger.addHandler(streamHandler);
}
PHP:
for (Logger logger : loggers) {
    Filter previousFilter = logger.getFilter();
    logger.setFilter(new Filter() {
        @Override
        // Подходит для отмены или изменения сообщений
        public boolean isLoggable(LogRecord record) {
            String msg = record.getMessage();
            boolean cancelMessage = false;
            record.setMessage("Filter.isLoggable(): " + msg);
            if (cancelMessage) return false;
            return previousFilter == null || previousFilter.isLoggable(record);
        }
    });
}

PHP:
private static List<Logger> getAllLoggers() {
    List<Logger> result = new ArrayList<>();
    result.add(Logger.getGlobal());
    result.add(Logger.getLogger("Minecraft"));
    result.add(Bukkit.getServer().getLogger());
    for (Plugin plugin : Bukkit.getServer().getPluginManager().getPlugins()) {
        result.add(plugin.getLogger());
    }
    return result;
}

Примеры в плагинах:

ReActions:
Фильтр (java.util.logging):
https://github.com/imDaniX/ReAction...eactions/events/listeners/LogHandler.java#L31
Регистрация:
https://github.com/imDaniX/ReAction...e/fromgate/reactions/ReActionsPlugin.java#L94

3) Можно на уровне системы подписаться на изменения файла лога и при его изменении получать все новые строки. Подробнее:
https://docs.oracle.com/javase/tutorial/essential/io/notification.html

Пример (LuckPerms):
https://github.com/LuckPerms/LuckPe...ms/common/storage/implementation/file/watcher
 
Последнее редактирование:
Назад
Верх