Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

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

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.

Кто знает, подскажите куда копать, чтобы модифицировать эти пакеты для всех получателей а не только отправителю?
 
Код:
@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();
    }
}
 
Код:
                for (Player recipient : event.getPacket().getRecipients()) {
К сожалению такого метода не существует
Qtp0Qc6.png
 
К сожалению такого метода не существует
Qtp0Qc6.png
Тогда возьмем чуть другой метод.

Код:
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();
    }
}
 
Тоже не вариант, ведь не факт что пакет отправляется всем кто онлайн, это может быть локальный чат например или клановый.
Я просто вот не могу понять, почему это так работает, ведь есть у меня другой клас, который обрабатывает
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 ...
 

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

Назад
Верх