<commit_before>/*
   Copyright 2017 <NAME>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package pl.kacperduras.protocoltab.manager;

import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import net.md_5.bungee.api.chat.BaseComponent;
import org.apache.commons.lang3.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import pl.kacperduras.protocoltab.ProtocolTabConfig;
import pl.kacperduras.protocoltab.packet.PlayerInfoHeaderFooterPacket;
import pl.kacperduras.protocoltab.packet.PlayerInfoPacket;

import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class ProtocolTab {

    public final static String BLANK_TEXT = " ";
    public final static char[] ALPHABET = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
            'N', 'O', 'P', 'Q', 'R', 'S', 'T'};

    private final Map<Integer, ProtocolSlot> slots = new ConcurrentHashMap<>(80);
    private final UUID uuid;

    private int ping;
    private String header;
    private String footer;

    public ProtocolTab(UUID uuid, ProtocolTabConfig config) {
        Validate.isTrue(uuid != null, "UUID can not be null!");
        Validate.isTrue(config != null, "Config can not be null!");

        this.uuid = uuid;
        this.ping = config.getPing();
    }

    public void update(Player player) {
        Validate.isTrue(player != null, "Player can not be null!");
        Validate.isTrue(player.isOnline(), "Player can not be offline!");

        for (Map.Entry<Integer, ProtocolSlot> entry : this.slots.entrySet()) {
            PlayerInfoPacket packet = new PlayerInfoPacket();
            packet.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);
            packet.setData(Collections.singletonList(
                    new PlayerInfoData(entry.getValue().getProfile(), ping, EnumWrappers.NativeGameMode.NOT_SET,
                                              WrappedChatComponent.fromText(ChatColor.translateAlternateColorCodes(
                                                      '&', entry.getValue().getText())))));

            packet.sendPacket(player);
        }

        PlayerInfoHeaderFooterPacket packet = new PlayerInfoHeaderFooterPacket();
        if (this.header == null) {
            this.header = "";
        }
        if (this.footer == null) {
            this.footer = "";<commit_msg>add optimization when sending packets.<commit_after>/*
   Copyright 2017 <NAME>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package pl.kacperduras.protocoltab.manager;

import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import net.md_5.bungee.api.chat.BaseComponent;
import org.apache.commons.lang3.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import pl.kacperduras.protocoltab.ProtocolTabConfig;
import pl.kacperduras.protocoltab.packet.PlayerInfoHeaderFooterPacket;
import pl.kacperduras.protocoltab.packet.PlayerInfoPacket;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class ProtocolTab {

    public final static String BLANK_TEXT = " ";
    public final static char[] ALPHABET = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
            'N', 'O', 'P', 'Q', 'R', 'S', 'T'};

    private final Map<Integer, ProtocolSlot> slots = new ConcurrentHashMap<>(80);
    private final UUID uuid;

    private int ping;
    private String header;
    private String footer;

    public ProtocolTab(UUID uuid, ProtocolTabConfig config) {
        Validate.isTrue(uuid != null, "UUID can not be null!");
        Validate.isTrue(config != null, "Config can not be null!");

        this.uuid = uuid;
        this.ping = config.getPing();
    }

    public void update(Player player) {
        Validate.isTrue(player != null, "Player can not be null!");
        Validate.isTrue(player.isOnline(), "Player can not be offline!");

        // tab list slots
        PlayerInfoPacket infoPacket = new PlayerInfoPacket();
        infoPacket.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);

        List<PlayerInfoData> infoData = new ArrayList<>();
        for (Map.Entry<Integer, ProtocolSlot> entry : this.slots.entrySet()) {
            infoData.add(
                    new PlayerInfoData(entry.getValue().getProfile(), ping, EnumWrappers.NativeGameMode.NOT_SET,
                                              WrappedChatComponent.fromText(ChatColor.translateAlternateColorCodes(
                                                      '&', entry.getValue().getText())))
            );
        }

        infoPacket.setData(infoData);
        infoPacket.sendPacket(player);

        // header and footer
        PlayerInfoHeaderFooterPacket packet = new PlayerInfoHeaderFooterPacket();
        if (this.header == null) {
            this.header = "";
        }
        if (this.footer == null) {
            this.footer = "";
{'fraction_non_alphanumeric': 0.108300395256917, 'fraction_numerical': 0.003794466403162055, 'mean_word_length': 3.049935979513444, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7150647', 'n_tokens_mistral': 1778, 'n_tokens_neox': 1766, 'n_words': 491}