1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Замена входящих сообщений в консоли сервера

Тема в разделе "Разработка плагинов для новичков", создана пользователем normalped, 1 июн 2024.

  1. Автор темы
    normalped

    normalped Участник Пользователь

    Баллы:
    36
    Приветствую! Можно ли отслеживать каждое полученное консолью сообщение, чтобы немного его изменить?

    У меня уже есть слушатели различных пакетов из ProtocolLib, где я редактирую входящий текст в зависимости от игрока, который должен получить этот текст. Проблема в том, что этот новый, отредактированный текст в консоли остается неизменным (если этот текст вообще должен появится в консоли.

    Буду благодарен за ваши ответы.
     
  2. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Можно повесить свой фильтр на апи log4j и в нем менять. И для чата все же удобнее использовать стандартный бакитовский ивент, или бумажный, если нужны компоненты.
     
    Последнее редактирование: 1 июн 2024
  3. Автор темы
    normalped

    normalped Участник Пользователь

    Баллы:
    36
    Можно пожалуйста подробнее про фильтры в log4j? Искал в интернете, все делают как то так:

    Код:
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    ...
    
    Logger rootLogger = LogManager.getRootLogger();
    rootLogger.addFilter(filter);
    
    Но у меня метода addFilter() почему то нету. Как я понял фильтры настраиваются с помощью xml конфигов. Я смогу использовать свой готовый метод который редактирует текст в этих фильтрах?

    Насчет ивентов, они мне не подходят так как я делаю немного другое.
     
  4. Автор темы
    normalped

    normalped Участник Пользователь

    Баллы:
    36
    Разобрался с той проблемой. В фильтре получаю сообщение через e.getMessage().getFormattedMessage(); но как его заменить?
     
  5. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
  6. Автор темы
    normalped

    normalped Участник Пользователь

    Баллы:
    36
    Попробовал варианты из java.util.logging, но к сожалению, с некоторыми сообщения в консоли оно не работает, они просто игнорируются. С фильтрами из org.apache.logging.log4j другая история, вроде оно ловит все сообщения, но способа изменить это сообщение я не нашел.
     
  7. Автор темы
    normalped

    normalped Участник Пользователь

    Баллы:
    36
    Точнее не работает только с логгером самого майнкрафта
     
  8. HauserGrim

    HauserGrim Активный участник Пользователь

    Баллы:
    96
    У меня так
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.core.Logger;
    Код:
           org.apache.logging.log4j.Logger rootLogger = LogManager.getRootLogger();
            if (!(rootLogger instanceof Logger logger)) {
                return;
            }
            logger.addFilter(logFilter);
    Как видишь, есть log4j.Logger и log4j.core.Logger

    Upd
    Но в том случае мне нужно было отменять сообщение, а не менять и я хз что там ещё можно
     
    Последнее редактирование: 3 июн 2024
  9. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Ну, при помощи фильтров, судя по всему, никак и не модифицировать сообщение через log4j. Почитай об альтернативных способах:
    https://stackoverflow.com/questions/40002310/how-to-modify-a-message-in-log4j-2
    https://stackoverflow.com/questions...nder-for-modifying-logevent-before-it-logs-in
     
    Последнее редактирование: 3 июн 2024
  10. Автор темы
    normalped

    normalped Участник Пользователь

    Баллы:
    36
    Да, решил проблему с помощью RewriteAppender и RewritePolicy. Только тогда форматирование майнкрафта не будет работать, придется наверное самому менять его на ansi.

    Код:
    Logger logger = (Logger) LogManager.getRootLogger();
    Configuration config = logger.getContext().getConfiguration();
    
    List<AppenderRef> appenderRefList = new ArrayList<>();
    Map<String, Appender> appenderMap = logger.getAppenders();
    
    for (Map.Entry<String, Appender> entry : appenderMap.entrySet()) {
        appenderRefList.add(AppenderRef.createAppenderRef(entry.getKey(), null, null));
        logger.removeAppender(entry.getValue());
    }
    
    AppenderRef[] appenderRefs = appenderRefList.toArray(new AppenderRef[0]);
    RewriteAppender rewriteAppender = RewriteAppender.createAppender(
            "CustomRewriteAppender", null, appenderRefs, config, new CustomRewritePolicy(), null);
    
    rewriteAppender.start();
    logger.addAppender(rewriteAppender);
    
    ...
    
    public final class CustomRewritePolicy implements RewritePolicy {
        @PluginFactory
        public static CustomRewritePolicy createPolicy() {
            return new CustomRewritePolicy();
        }
    
        @Override
        public LogEvent rewrite(LogEvent e) {
            Log4jLogEvent.Builder builder = new Log4jLogEvent.Builder();
            if (e.getMarker() != null) {
                StringMap contextData = ContextDataFactory.createContextData();
                contextData.putValue("_marker", e.getMarker().getName());
                builder.setContextData(contextData);
            }
            builder.setLoggerName(e.getLoggerName());
            builder.setMarker(e.getMarker());
            builder.setLoggerFqcn(e.getLoggerFqcn());
            builder.setLevel(e.getLevel());
            builder.setMessage(new SimpleMessage(e.getMessage().getFormattedMessage())); // Замена текста
            builder.setThrown(e.getThrown());
            builder.setContextStack(e.getContextStack());
            builder.setThreadName(e.getThreadName());
            builder.setSource(e.getSource());
            builder.setTimeMillis(e.getTimeMillis());
            return builder.build();
        }
    }
    
    Не сильно уверен на счет этой части, но вроде все работает нормально.

    Код:
    for (Map.Entry<String, Appender> entry : appenderMap.entrySet()) {
        appenderRefList.add(AppenderRef.createAppenderRef(entry.getKey(), null, null));
        logger.removeAppender(entry.getValue());
    }
    
     

Поделиться этой страницей