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

Помогите PacketType.Play.Server.CHAT, обработка

Тема в разделе "Разработка плагинов для новичков", создана пользователем Korvinius, 5 ноя 2023.

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

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

    Баллы:
    88
    Привет Всем!
    В общем я пытаюсь модифицировать пакет PacketType.Play.Server.CHAT, вот класс:

    Код:
    package net.wealth_mc.mystery.listeners.protocol.server;
    
    import com.comphenix.protocol.PacketType;
    import com.comphenix.protocol.ProtocolLibrary;
    import com.comphenix.protocol.ProtocolManager;
    import com.comphenix.protocol.events.PacketAdapter;
    import com.comphenix.protocol.events.PacketContainer;
    import com.comphenix.protocol.events.PacketEvent;
    import com.comphenix.protocol.reflect.StructureModifier;
    import com.comphenix.protocol.wrappers.WrappedChatComponent;
    import com.comphenix.protocol.events.ListenerPriority;
    
    import net.wealth_mc.mystery.ItemLingo;
    import net.wealth_mc.mystery.listeners.protocol.AbstractPacketListener;
    
    public class PacketChat extends AbstractPacketListener {
    
    
        public PacketChat() {
            super(PacketType.Play.Server.CHAT);
    
            ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
          
    
            protocolManager.addPacketListener(this.packetAdapter = new PacketAdapter(itemLingoPlugin, ListenerPriority.NORMAL,
                    PacketType.Play.Server.CHAT) {
              
                @Override
                public void onPacketSending(PacketEvent event) {
                    handlePacket(event);
                }
            });
    
            register();
        }
    
        @Override
        protected void handlePacket(PacketEvent event) {
          
            ModificationState modState = new ModificationState();
            String playerLang = getPlayerLanguage(event.getPlayer());
          
            try {
                Object chatComponents = event.getPacket().getChatComponents().read(0);
                if (chatComponents != null) {
                  
                    WrappedChatComponent wrappedChat = (WrappedChatComponent) chatComponents;
                    String jsonChat = wrappedChat.getJson();
                    String modifiedJson = modifyChat(jsonChat, playerLang, modState, "text");
                  
                    if (modState.isModified() && modifiedJson != null) {
                        WrappedChatComponent modifiedComponent = WrappedChatComponent.fromJson(modifiedJson);
                        event.getPacket().getChatComponents().write(0, modifiedComponent);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    Пакет модифицируется и клиенту отправляется, но не всё так радужно как хотелось-бы, вот проблема в том, что например, если игрок отправляет сообщение в чат, только отправитель видит модифицированную версию, все остальные видят оригинальный текст. ProtocolLib последней версии, ядро: paper-1.20.2.

    Кто знает, подскажите куда копать, чтобы модифицировать эти пакеты для всех получателей а не только отправителю?
     
  2. SlenderMix

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

    Баллы:
    76
    Имя в Minecraft:
    HIDDEN
    Код:
    @Override
    protected void handlePacket(PacketEvent event) {
        ModificationState modState = new ModificationState();
        String playerLang = getPlayerLanguage(event.getPlayer());
     
        try {
            Object chatComponents = event.getPacket().getChatComponents().read(0);
            if (chatComponents != null) {
                WrappedChatComponent wrappedChat = (WrappedChatComponent) chatComponents;
                String jsonChat = wrappedChat.getJson();
                String modifiedJson = modifyChat(jsonChat, playerLang, modState, "text");
             
                if (modState.isModified() && modifiedJson != null) {
                    WrappedChatComponent modifiedComponent = WrappedChatComponent.fromJson(modifiedJson);
    
                    // Модифицируем пакет для отправителя
                    event.getPacket().getChatComponents().write(0, modifiedComponent);
    
                    // Модифицируем пакет для всех других игроков
                    for (Player recipient : event.getPacket().getRecipients()) {
                        if (!recipient.equals(event.getPlayer())) {
                            ProtocolLibrary.getProtocolManager().sendServerPacket(recipient, event.getPacket());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    
     
  3. Автор темы
    Korvinius

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

    Баллы:
    88
    К сожалению такого метода не существует
    [​IMG]
     
  4. SlenderMix

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

    Баллы:
    76
    Имя в Minecraft:
    HIDDEN
    Тогда возьмем чуть другой метод.

    Код:
    private Set<Player> trackedPlayers = new HashSet<>();
    
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        trackedPlayers.add(player);
    }
    
    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent event) {
        Player player = event.getPlayer();
        trackedPlayers.remove(player);
    }
    
    @Override
    protected void handlePacket(PacketEvent event) {
        ModificationState modState = new ModificationState();
        String playerLang = getPlayerLanguage(event.getPlayer());
    
        try {
            Object chatComponents = event.getPacket().getChatComponents().read(0);
            if (chatComponents != null) {
                WrappedChatComponent wrappedChat = (WrappedChatComponent) chatComponents;
                String jsonChat = wrappedChat.getJson();
                String modifiedJson = modifyChat(jsonChat, playerLang, modState, "text");
    
                if (modState.isModified() && modifiedJson != null) {
                    WrappedChatComponent modifiedComponent = WrappedChatComponent.fromJson(modifiedJson);
                    event.getPacket().getChatComponents().write(0, modifiedComponent);
    
                    // Отправить модифицированный пакет всем отслеживаемым игрокам
                    for (Player trackedPlayer : trackedPlayers) {
                        if (!trackedPlayer.equals(event.getPlayer())) {
                            ProtocolLibrary.getProtocolManager().sendServerPacket(trackedPlayer, event.getPacket());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
     
  5. Автор темы
    Korvinius

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

    Баллы:
    88
    Тоже не вариант, ведь не факт что пакет отправляется всем кто онлайн, это может быть локальный чат например или клановый.
    Я просто вот не могу понять, почему это так работает, ведь есть у меня другой клас, который обрабатывает
    PacketType.Play.Server.SYSTEM_CHAT, то-есть системные сообщения или сообщения от плагинов, так там без проблем пакеты модифицируются всем получателям, вот этот клас:

    Код:
    package net.wealth_mc.mystery.listeners.protocol.server;
    
    import java.util.Optional;
    
    import com.comphenix.protocol.PacketType;
    import com.comphenix.protocol.ProtocolLibrary;
    import com.comphenix.protocol.ProtocolManager;
    import com.comphenix.protocol.events.ListenerPriority;
    import com.comphenix.protocol.events.PacketAdapter;
    import com.comphenix.protocol.events.PacketContainer;
    import com.comphenix.protocol.events.PacketEvent;
    import com.comphenix.protocol.reflect.StructureModifier;
    import com.comphenix.protocol.wrappers.EnumWrappers;
    import net.wealth_mc.mystery.utils.PaperUtils;
    import net.kyori.adventure.text.Component;
    import net.wealth_mc.mystery.ItemLingo;
    import net.wealth_mc.mystery.listeners.protocol.AbstractPacketListener;
    
    public class PacketSystemChat extends AbstractPacketListener {
    
    
        public PacketSystemChat() {
            super(PacketType.Play.Server.SYSTEM_CHAT);
    
            ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
           
    
            protocolManager.addPacketListener(this.packetAdapter = new PacketAdapter(itemLingoPlugin, ListenerPriority.NORMAL,
                    PacketType.Play.Server.SYSTEM_CHAT) {
               
                @Override
                public void onPacketSending(PacketEvent event) {
                    handlePacket(event);
                }
            });
        }
    
        @Override
        protected void handlePacket(PacketEvent event) {
           
            ModificationState modState = new ModificationState();
            String playerLang = getPlayerLanguage(event.getPlayer());
           
           
            PacketContainer packet = event.getPacket();
            Optional<Boolean> isFiltered = packet.getMeta("psr_filtered_packet");
            if (!(isFiltered.isPresent() && isFiltered.get())) {
    
                StructureModifier<Boolean> booleans = packet.getBooleans();
                if (booleans.size() == 1) {
                    if (booleans.read(0)) {
                        return;
                    }
                } else if (packet.getIntegers().read(0) == EnumWrappers.ChatType.GAME_INFO.getId()) {
                    if (itemLingoPlugin.getConfigurationManager().isDebug())
                    ItemLingo.warn("packet.getIntegers().read(0) == EnumWrappers.ChatType.GAME_INFO.getId()");
                    return;
                }
    
                StructureModifier<String> stringModifier = packet.getStrings();
                StructureModifier<Component> componentModifier = packet.getModifier().withType(Component.class);
                String contentField = stringModifier.read(0);
    
                String jsonSystemChat;
                String modifiedJson;
                boolean isPaper = false;
               
                if (contentField != null) {
                    if (itemLingoPlugin.getConfigurationManager().isDebug())
                    ItemLingo.info("contentField != null");
                    jsonSystemChat = contentField.toString();
    
                } else {
                    if (itemLingoPlugin.getConfigurationManager().isDebug())
                    ItemLingo.info("contentField == null");
                    Component read = componentModifier.read(0);
                    if (read == null) {
                        return;
                    }
                    jsonSystemChat = PaperUtils.serializeComponent(read);
                    isPaper = true;
                }
    
                modifiedJson = modifyChat(jsonSystemChat, playerLang, modState, "text");
    
                if (modState.isModified() && modifiedJson != null) {
                    if (isPaper) {
                        Component modifiedComponent = PaperUtils.getPaperGsonComponentSerializer().deserialize(modifiedJson);
    
                        componentModifier.write(0, modifiedComponent);
                    } else {
                        stringModifier.write(0, modifiedJson);
                    }
                }
            }
        }
    }
    
    хотелось бы, чтобы также работал и PacketType.Play.Server.CHAT ...
     

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