lineage2.gameserver.network.clientpackets.Say2C.java Source code

Java tutorial

Introduction

Here is the source code for lineage2.gameserver.network.clientpackets.Say2C.java

Source

/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package lineage2.gameserver.network.clientpackets;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lineage2.gameserver.Config;
import lineage2.gameserver.cache.ItemInfoCache;
import lineage2.gameserver.cache.Msg;
import lineage2.gameserver.handler.voicecommands.IVoicedCommandHandler;
import lineage2.gameserver.handler.voicecommands.VoicedCommandHandler;
import lineage2.gameserver.instancemanager.PetitionManager;
import lineage2.gameserver.model.GameObjectsStorage;
import lineage2.gameserver.model.Player;
import lineage2.gameserver.model.World;
import lineage2.gameserver.model.entity.olympiad.OlympiadGame;
import lineage2.gameserver.model.items.ItemInstance;
import lineage2.gameserver.model.matching.MatchingRoom;
import lineage2.gameserver.network.serverpackets.ActionFail;
import lineage2.gameserver.network.serverpackets.Say2;
import lineage2.gameserver.network.serverpackets.SystemMessage;
import lineage2.gameserver.network.serverpackets.components.ChatType;
import lineage2.gameserver.network.serverpackets.components.CustomMessage;
import lineage2.gameserver.tables.FakePlayersTable;
import lineage2.gameserver.utils.Log;
import lineage2.gameserver.utils.MapUtils;
import lineage2.gameserver.utils.Strings;
import lineage2.gameserver.utils.Util;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.graphbuilder.math.Expression;
import com.graphbuilder.math.ExpressionParseException;
import com.graphbuilder.math.ExpressionTree;
import com.graphbuilder.math.VarMap;

/**
 * @author Mobius
 * @version $Revision: 1.0 $
 */
public class Say2C extends L2GameClientPacket {
    /**
     * Field _log.
     */
    private static final Logger _log = LoggerFactory.getLogger(Say2C.class);
    /**
     * Field EX_ITEM_LINK_PATTERN.
     */
    private static final Pattern EX_ITEM_LINK_PATTERN = Pattern.compile(
            "[\b]\tType=[0-9]+[\\s]+\tID=([0-9]+)[\\s]+\tColor=[0-9]+[\\s]+\tUnderline=[0-9]+[\\s]+\tTitle=\u001B(.[^\u001B]*)[^\b]");
    /**
     * Field SKIP_ITEM_LINK_PATTERN.
     */
    private static final Pattern SKIP_ITEM_LINK_PATTERN = Pattern.compile("[\b]\tType=[0-9]+(.[^\b]*)[\b]");
    /**
     * Field _text.
     */
    private String _text;
    /**
     * Field _type.
     */
    private ChatType _type;
    /**
     * Field _target.
     */
    private String _target;

    /**
     * Method readImpl.
     */
    @Override
    protected void readImpl() {
        _text = readS(Config.CHAT_MESSAGE_MAX_LEN);
        _type = lineage2.commons.lang.ArrayUtils.valid(ChatType.VALUES, readD());
        _target = _type == ChatType.TELL ? readS(Config.CNAME_MAXLEN) : null;
    }

    /**
     * Method runImpl.
     */
    @Override
    protected void runImpl() {
        Player activeChar = getClient().getActiveChar();
        if (activeChar == null) {
            return;
        }
        if ((_type == null) || (_text == null) || (_text.length() == 0)) {
            activeChar.sendActionFailed();
            return;
        }
        _text = _text.replaceAll("\\\\n", "\n");
        if (_text.contains("\n")) {
            String[] lines = _text.split("\n");
            _text = StringUtils.EMPTY;
            for (int i = 0; i < lines.length; i++) {
                lines[i] = lines[i].trim();
                if (lines[i].length() == 0) {
                    continue;
                }
                if (_text.length() > 0) {
                    _text += "\n  >";
                }
                _text += lines[i];
            }
        }
        if (_text.length() == 0) {
            activeChar.sendActionFailed();
            return;
        }
        if ((_text.length() > 0) && (_text.charAt(0) == '.')) {
            String fullcmd = _text.substring(1).trim();
            String command = fullcmd.split("\\s+")[0];
            String args = fullcmd.substring(command.length()).trim();
            if (command.length() > 0) {
                IVoicedCommandHandler vch = VoicedCommandHandler.getInstance().getVoicedCommandHandler(command);
                if (vch != null) {
                    vch.useVoicedCommand(command, activeChar, args);
                    return;
                }
            }
            activeChar.sendMessage(new CustomMessage("common.command404", activeChar));
            return;
        } else if (_text.startsWith("==")) {
            String expression = _text.substring(2);
            Expression expr = null;
            if (!expression.isEmpty()) {
                try {
                    expr = ExpressionTree.parse(expression);
                } catch (ExpressionParseException ignored) {
                }
                if (expr != null) {
                    double result;
                    try {
                        VarMap vm = new VarMap();
                        vm.setValue("adena", activeChar.getAdena());
                        result = expr.eval(vm, null);
                        activeChar.sendMessage(expression);
                        activeChar.sendMessage("=" + Util.formatDouble(result, "NaN", false));
                    } catch (Exception ignored) {
                    }
                }
            }
            return;
        }
        if ((Config.CHATFILTER_MIN_LEVEL > 0) && ArrayUtils.contains(Config.CHATFILTER_CHANNELS, _type.ordinal())
                && (activeChar.getLevel() < Config.CHATFILTER_MIN_LEVEL)) {
            if (Config.CHATFILTER_WORK_TYPE == 1) {
                _type = ChatType.ALL;
            } else if (Config.CHATFILTER_WORK_TYPE == 2) {
                activeChar.sendMessage(new CustomMessage("chat.NotHavePermission", activeChar)
                        .addNumber(Config.CHATFILTER_MIN_LEVEL));
                return;
            }
        }
        boolean globalchat = (_type != ChatType.ALLIANCE) && (_type != ChatType.CLAN) && (_type != ChatType.PARTY);
        if ((globalchat || ArrayUtils.contains(Config.BAN_CHANNEL_LIST, _type.ordinal()))
                && (activeChar.getNoChannel() != 0)) {
            if ((activeChar.getNoChannelRemained() > 0) || (activeChar.getNoChannel() < 0)) {
                if (activeChar.getNoChannel() > 0) {
                    int timeRemained = Math.round(activeChar.getNoChannelRemained() / 60000);
                    activeChar.sendMessage(
                            new CustomMessage("common.ChatBanned", activeChar).addNumber(timeRemained));
                } else {
                    activeChar.sendMessage(new CustomMessage("common.ChatBannedPermanently", activeChar));
                }
                activeChar.sendActionFailed();
                return;
            }
            activeChar.updateNoChannel(0);
        }
        if (globalchat) {
            if (Config.ABUSEWORD_REPLACE) {
                if (Config.containsAbuseWord(_text)) {
                    _text = Config.ABUSEWORD_REPLACE_STRING;
                    activeChar.sendActionFailed();
                }
            } else if (Config.ABUSEWORD_BANCHAT && Config.containsAbuseWord(_text)) {
                activeChar.sendMessage(new CustomMessage("common.ChatBanned", activeChar)
                        .addNumber(Config.ABUSEWORD_BANTIME * 60));
                Log.add(activeChar + ": " + _text, "abuse");
                activeChar.updateNoChannel(Config.ABUSEWORD_BANTIME * 60000);
                activeChar.sendActionFailed();
                return;
            }
        }
        Matcher m = EX_ITEM_LINK_PATTERN.matcher(_text);
        ItemInstance item;
        int objectId;
        while (m.find()) {
            objectId = Integer.parseInt(m.group(1));
            item = activeChar.getInventory().getItemByObjectId(objectId);
            if (item == null) {
                activeChar.sendActionFailed();
                break;
            }
            ItemInfoCache.getInstance().put(item);
        }
        String translit = activeChar.getVar("translit");
        if (translit != null) {
            m = SKIP_ITEM_LINK_PATTERN.matcher(_text);
            StringBuilder sb = new StringBuilder();
            int end = 0;
            while (m.find()) {
                sb.append(
                        Strings.fromTranslit(_text.substring(end, end = m.start()), translit.equals("tl") ? 1 : 2));
                sb.append(_text.substring(end, end = m.end()));
            }
            _text = sb.append(
                    Strings.fromTranslit(_text.substring(end, _text.length()), translit.equals("tl") ? 1 : 2))
                    .toString();
        }
        Log.LogChat(_type.name(), activeChar.getName(), _target, _text);
        Say2 cs = new Say2(activeChar.getObjectId(), _type, activeChar.getName(), _text);
        switch (_type) {
        case TELL:
            Player receiver = World.getPlayer(_target);
            if ((receiver == null) && Config.ALLOW_FAKE_PLAYERS
                    && FakePlayersTable.getActiveFakePlayers().contains(_target)) {
                cs = new Say2(activeChar.getObjectId(), _type, "->" + _target, _text);
                activeChar.sendPacket(cs);
                return;
            } else if ((receiver != null) && receiver.isInOfflineMode()) {
                activeChar.sendMessage("The person is in offline trade mode.");
                activeChar.sendActionFailed();
            } else if ((receiver != null) && !receiver.isInBlockList(activeChar) && !receiver.isBlockAll()) {
                if (!receiver.getMessageRefusal()) {
                    if (activeChar.antiFlood.canTell(receiver.getObjectId(), _text)) {
                        receiver.sendPacket(cs);
                    }
                    cs = new Say2(activeChar.getObjectId(), _type, "->" + receiver.getName(), _text);
                    activeChar.sendPacket(cs);
                } else {
                    activeChar.sendPacket(Msg.THE_PERSON_IS_IN_A_MESSAGE_REFUSAL_MODE);
                }
            } else if (receiver == null) {
                activeChar.sendPacket(
                        new SystemMessage(SystemMessage.S1_IS_NOT_CURRENTLY_LOGGED_IN).addString(_target),
                        ActionFail.STATIC);
            } else {
                activeChar.sendPacket(Msg.YOU_HAVE_BEEN_BLOCKED_FROM_THE_CONTACT_YOU_SELECTED, ActionFail.STATIC);
            }
            break;
        case SHOUT:
            if (activeChar.isCursedWeaponEquipped()) {
                activeChar.sendPacket(Msg.SHOUT_AND_TRADE_CHATING_CANNOT_BE_USED_SHILE_POSSESSING_A_CURSED_WEAPON);
                return;
            }
            if (activeChar.isInObserverMode()) {
                activeChar.sendPacket(Msg.YOU_CANNOT_CHAT_LOCALLY_WHILE_OBSERVING);
                return;
            }
            if (!activeChar.isGM() && !activeChar.antiFlood.canShout(_text)) {
                activeChar.sendMessage("Shout chat is allowed once per 5 seconds.");
                return;
            }
            if (Config.GLOBAL_SHOUT) {
                announce(activeChar, cs);
            } else {
                shout(activeChar, cs);
            }
            activeChar.sendPacket(cs);
            break;
        case TRADE:
            if (activeChar.isCursedWeaponEquipped()) {
                activeChar.sendPacket(Msg.SHOUT_AND_TRADE_CHATING_CANNOT_BE_USED_SHILE_POSSESSING_A_CURSED_WEAPON);
                return;
            }
            if (activeChar.isInObserverMode()) {
                activeChar.sendPacket(Msg.YOU_CANNOT_CHAT_LOCALLY_WHILE_OBSERVING);
                return;
            }
            if (!activeChar.isGM() && !activeChar.antiFlood.canTrade(_text)) {
                activeChar.sendMessage("Trade chat is allowed once per 5 seconds.");
                return;
            }
            if (Config.GLOBAL_TRADE_CHAT) {
                announce(activeChar, cs);
            } else {
                shout(activeChar, cs);
            }
            activeChar.sendPacket(cs);
            break;
        case ALL:
            if (activeChar.isCursedWeaponEquipped()) {
                cs = new Say2(activeChar.getObjectId(), _type, activeChar.getTransformationName(), _text);
            }
            List<Player> list = null;
            if (activeChar.isInObserverMode() && (activeChar.getObserverRegion() != null)
                    && (activeChar.getOlympiadObserveGame() != null)) {
                OlympiadGame game = activeChar.getOlympiadObserveGame();
                if (game != null) {
                    list = game.getAllPlayers();
                }
            } else if (activeChar.isInOlympiadMode()) {
                OlympiadGame game = activeChar.getOlympiadGame();
                if (game != null) {
                    list = game.getAllPlayers();
                }
            } else {
                list = World.getAroundPlayers(activeChar);
            }
            if (list != null) {
                for (Player player : list) {
                    if ((player == activeChar) || (player.getReflection() != activeChar.getReflection())
                            || player.isBlockAll() || player.isInBlockList(activeChar)) {
                        continue;
                    }
                    player.sendPacket(cs);
                }
            }
            activeChar.sendPacket(cs);
            break;
        case CLAN:
            if (activeChar.getClan() != null) {
                activeChar.getClan().broadcastToOnlineMembers(cs);
            }
            break;
        case ALLIANCE:
            if ((activeChar.getClan() != null) && (activeChar.getClan().getAlliance() != null)) {
                activeChar.getClan().getAlliance().broadcastToOnlineMembers(cs);
            }
            break;
        case PARTY:
            if (activeChar.isInParty()) {
                activeChar.getParty().broadCast(cs);
            }
            break;
        case PARTY_ROOM:
            MatchingRoom r = activeChar.getMatchingRoom();
            if ((r != null) && (r.getType() == MatchingRoom.PARTY_MATCHING)) {
                r.broadCast(cs);
            }
            break;
        case COMMANDCHANNEL_ALL:
            if (!activeChar.isInParty() || !activeChar.getParty().isInCommandChannel()) {
                activeChar.sendPacket(Msg.YOU_DO_NOT_HAVE_AUTHORITY_TO_USE_THE_COMMAND_CHANNEL);
                return;
            }
            if (activeChar.getParty().getCommandChannel().getChannelLeader() == activeChar) {
                activeChar.getParty().getCommandChannel().broadCast(cs);
            } else {
                activeChar.sendPacket(Msg.ONLY_CHANNEL_OPENER_CAN_GIVE_ALL_COMMAND);
            }
            break;
        case COMMANDCHANNEL_COMMANDER:
            if (!activeChar.isInParty() || !activeChar.getParty().isInCommandChannel()) {
                activeChar.sendPacket(Msg.YOU_DO_NOT_HAVE_AUTHORITY_TO_USE_THE_COMMAND_CHANNEL);
                return;
            }
            if (activeChar.getParty().isLeader(activeChar)) {
                activeChar.getParty().getCommandChannel().broadcastToChannelPartyLeaders(cs);
            } else {
                activeChar.sendPacket(Msg.ONLY_A_PARTY_LEADER_CAN_ACCESS_THE_COMMAND_CHANNEL);
            }
            break;
        case HERO_VOICE:
            boolean PremiumHeroChat = false;
            if (Config.PREMIUM_HEROCHAT && (activeChar.getNetConnection().getBonus() > 1)) {
                long endtime = activeChar.getNetConnection().getBonusExpire();
                if (endtime >= 0) {
                    PremiumHeroChat = true;
                }
            }
            if (activeChar.isHero() || activeChar.getPlayerAccess().CanAnnounce || PremiumHeroChat) {
                if (!activeChar.getPlayerAccess().CanAnnounce) {
                    if (!activeChar.antiFlood.canHero(_text)) {
                        activeChar.sendMessage("Hero chat is allowed once per 10 seconds.");
                        return;
                    }
                }
                for (Player player : GameObjectsStorage.getAllPlayersForIterate()) {
                    if (!player.isInBlockList(activeChar) && !player.isBlockAll()) {
                        player.sendPacket(cs);
                    }
                }
            }
            break;
        case PETITION_PLAYER:
        case PETITION_GM:
            if (!PetitionManager.getInstance().isPlayerInConsultation(activeChar)) {
                activeChar.sendPacket(new SystemMessage(SystemMessage.YOU_ARE_CURRENTLY_NOT_IN_A_PETITION_CHAT));
                return;
            }
            PetitionManager.getInstance().sendActivePetitionMessage(activeChar, _text);
            break;
        case BATTLEFIELD:
            if (activeChar.getBattlefieldChatId() == 0) {
                return;
            }
            for (Player player : GameObjectsStorage.getAllPlayersForIterate()) {
                if (!player.isInBlockList(activeChar) && !player.isBlockAll()
                        && (player.getBattlefieldChatId() == activeChar.getBattlefieldChatId())) {
                    player.sendPacket(cs);
                }
            }
            break;
        case MPCC_ROOM:
            MatchingRoom r2 = activeChar.getMatchingRoom();
            if ((r2 != null) && (r2.getType() == MatchingRoom.CC_MATCHING)) {
                r2.broadCast(cs);
            }
            break;
        default:
            _log.warn("Character " + activeChar.getName() + " used unknown chat type: " + _type.ordinal() + ".");
        }
    }

    /**
     * Method shout.
     * @param activeChar Player
     * @param cs Say2
     */
    private static void shout(Player activeChar, Say2 cs) {
        int rx = MapUtils.regionX(activeChar);
        int ry = MapUtils.regionY(activeChar);
        int offset = Config.SHOUT_OFFSET;
        for (Player player : GameObjectsStorage.getAllPlayersForIterate()) {
            if ((player == activeChar) || (activeChar.getReflection() != player.getReflection())
                    || player.isBlockAll() || player.isInBlockList(activeChar)) {
                continue;
            }
            int tx = MapUtils.regionX(player);
            int ty = MapUtils.regionY(player);
            if (((tx >= (rx - offset)) && (tx <= (rx + offset)) && (ty >= (ry - offset)) && (ty <= (ry + offset)))
                    || activeChar.isInRangeZ(player, Config.CHAT_RANGE)) {
                player.sendPacket(cs);
            }
        }
    }

    /**
     * Method announce.
     * @param activeChar Player
     * @param cs Say2
     */
    private static void announce(Player activeChar, Say2 cs) {
        for (Player player : GameObjectsStorage.getAllPlayersForIterate()) {
            if ((player == activeChar) || (activeChar.getReflection() != player.getReflection())
                    || player.isBlockAll() || player.isInBlockList(activeChar)) {
                continue;
            }
            player.sendPacket(cs);
        }
    }
}