Перейти к содержанию

DJone

Пользователи
  • Публикаций

    32
  • Зарегистрирован

  • Посещение

  • Отзывы

    0%

Сообщения, опубликованные DJone


  1. В 08.10.2018 в 12:55, lvlkoo сказал:

    Да кучу файлов отвечают за скилы, смотря что вам нужно. Начиная с L2Skill и заканчивая конкретным skillclasses/*

    Алгоритм действий номер 1. Ищите какой метод выбрасывает данное собщение, смотрите что там запроверки, ставьте брейкпоинты, проверяйте

    Алгоритм действий номер 2. Смотрите тип скила, тип цели итд. В L2Skill смотрите методы связаные обраткой этого типа, а также смотрите нужный скилклас, ставьте брейкпоинты, проверяйте

    Вполне вероятно, что все сведется к геоддвижку. Т.к даже при отключенной геодате, геодвижок всеравно выполняет минимальную работу по просчету маршрута, растоянию, высоте итд

    Спасибо, проблему решил установив геодату. 


  2. Файл настроек  защиты

    Спойлер
    
    # Включить защиту?
    AllowGuardSystem = False
    
    # Отображать в клиенте инфо о защите "PROTECTION ON"?
    ShowProtectionInfoInClient = True
    
    # BLACK = 0xFF000000, BLUE = 0xFF0000FF, CYAN = 0xFF00FFFF
    # DKGRAY = 0xFF444444, GRAY = 0xFF888888, GREEN = 0xFF00FF00
    # LTGRAY = 0xFFCCCCCC, MAGENTA = 0xFFFF00FF, RED = 0xFFFF0000
    # TRANSPARENT = 0x00000000, WHITE = 0xFFFFFFFF, YELLOW = 0xFFFFFF00
    ColorProtectionInfoInClient = 0xFFFF0000
    # Позиция Х от правого верхнего края клиента
    PositionXProtectionInfoInClient = 320
    # Позиция Y от правого верхнего края клиента
    PositionYProtectionInfoInClient = 10
    
    # Отображать в клиенте имя сервера?
    ShowNameServerInfoInClient = True
    
    ColorNameServerInfoInClient = 0xFF00FF00
    # Выводимое Имя сервера(только латинские буквы и цыфры)
    NameServerInfoInClient = Test
    # Позиция Х от правого верхнего края клиента
    PositionXNameServerInfoInClient = 320
    # Позиция Y от правого верхнего края клиента
    PositionYNameServerInfoInClient = 25
    
    # Отображать в клиенте общий онлайн?
    ShowOnlineInClient = True
    
    ColorOnlineInClient = 0xFF00FF00
    # Позиция Х от правого верхнего края клиента
    PositionXOnlineInClient = 320
    # Позиция Y от правого верхнего края клиента
    PositionYOnlineInClient = 40
    
    # Отображать в клиенте время сервера?
    ShowServerTimeInClient = True
    
    ColorServerTimeInClient = 0xFF00FF00
    # Позиция Х от правого верхнего края клиента
    PositionXServerTimeInClient = 320
    # Позиция Y от правого верхнего края клиента
    PositionYServerTimeInClient = 55
    
    # Отображать в клиенте реальное время?
    ShowRealTimeInClient = True
    
    ColorRealTimeInClient = 0xFF00FF00
    # Позиция Х от правого верхн
    его края клиента
    PositionXRealTimeInClient = 320
    # Позиция Y от правого верхнего края клиента
    PositionYRealTimeInClient = 70
    
    # Отображать в клиенте пинг до сервера?
    ShowPingInClient = True
    
    # Цвет при пинге 0-150
    ColorPingInClient = 0xFF00FF00
    # Цвет при пинге 150-300
    ColorPingInClientLow = 0xFFFFFF00
    # Цвет при пинге 300-
    ColorPingInClientHigh = 0xFFFF0000
    
    # Позиция Х от правого верхнего края клиента
    PositionXPingInClient = 320
    # Позиция Y от правого верхнего края клиента
    PositionYPingInClient = 85
    
    # Время обновления сообщений - Пинг, время сервера, онлайн.
    TimeRefreshStringToClient = 12000
    
    # Установка HWID клиента
    # 1 = HWID HDD
    # 2 = HWID MAC
    # 3 = HWID CPU
    UseClientHWID = 2
    
    # Включить опрос клиента на запущеный GameGuard?
    # Рекомендуется включить!!!
    AllowSendGGReply = True
    # Промежуток времени между опросами в сек.
    TimeSendGGReply = 10
    
    # Настройка количества открытых окон клиента
    # если = 0 не ограничено
    ClientWindowsCount = 0
    # По какому критерию запрещать запуск нескольких окон?
    # IP - по IP, HWID - по HWID клиента
    ClientWindowsCountSec = HWID
    
    # Действия при обнаружении взлома клиента
    # 1 = kick, 2 = ban на указанное время, 3 - бан пожизненно
    
    # время если пункт выше равен "2" в мин.
    TimeBanAcc = 6000
    
    OnlinePlus = 1
    
    
    EnableHWIDBans = False
    EnableHWIDBonus = False
    StoreHWID = False
    LogHWIDs = False
    
    #UpProtectedIPs = 
    #LogHWIDsTable = 
    #hwids_log = 

     

     


  3. Всем привет. Подскажите, по какой причине дисконектит после выбора сервера?

    Спойлер
    
    #-------------------------------------------------------------
    # Сетевые настройки сервера
    #-------------------------------------------------------------
    # IP на который биндить геймсервер, * - на все возможные
    GameserverHostname = *
    GameserverPort = 7777
    # This is transmitted to the clients connecting from an external network, so it has to be a public IP or resolvable hostname
    ExternalHostname = тут_статик_ip_адресс
    # This is transmitted to the client from the same network, so it has to be a local IP or resolvable hostname
    InternalHostname = 192.168.1.17
    
    AdvIPSystem = False
    
    # Адрес\порт логинсервера
    LoginPort = 9014
    LoginHost = 192.168.1.17
    LoginUseCrypt = True
    # Какой ID запрашивать у логинсервера
    RequestServerID = 1
    # Разрешать брать другой ид, если запрашиваемый занят
    AcceptAlternateID = True
    
    # Максимальное количество соединений с базой
    MaximumDbConnections = 50
    # Через сколько секунд после последней активности будут закрыватся соединения с базой, по умолчанию 600 (10 минут)
    # данный параметр важно согласовывать с настройками в самом mysql сервере, параметр interactive_timeout (по умолчанию 28800 (8 часов))
    MaxIdleConnectionTimeout = 600
    # Интервал проверки неактивных соединений, по умолчанию 60 (1 минута)
    # При условии стабильного соединения с базой и корректной настроки MaxIdleConnectionTimeout, можно выставлять -1 (не проверять)
    IdleConnectionTestPeriod = 60
    
    
    # Автосохранение состояния чара
    Autosave = True
    #-------------------------------------------------------------
    # Настройки шаблонов имен
    #-------------------------------------------------------------
    # Имя персонажа
    CnameTemplate = ([0-9A-Za-z]{2,16})|([0-9\u0410-\u044f]{2,16})
    # Название клана
    ClanNameTemplate = ([0-9A-Za-z]{3,16})|([0-9\u0410-\u044f]{3,16})
    # Титул клана
    ClanTitleTemplate = ([0-9A-Za-z \\p{Punct}]{1,16})|([0-9\u0410-\u044f \\p{Punct}]{1,16})
    # Название альянса
    AllyNameTemplate = ([0-9A-Za-z]{3,16})|([0-9\u0410-\u044f]{3,16})
    
    #-------------------------------------------------------------
    # Настройки отображения сереров
    #-------------------------------------------------------------
    # NORMAL;RELAX;TEST;NO_LABEL;RESTRICTED;EVENT;FREE
    ServerType=NORMAL
    # Лимит по возрасту
    ServerAgeLimit = 0
    # Сервер только для гейм-мастеров
    ServerGMOnly=false
    # Отображать [] перед названием сервреа
    ServerBrackets = False
    # Ли пвп сервер?
    PvPServer = False
    
    #-------------------------------------------------------------
    # Настройки протокола
    #-------------------------------------------------------------
    # Минимальный и максимальный клиентские протоколы для входа на сервер
    # High Five: Part 4 = 267
    MinProtocolRevision = 267
    MaxProtocolRevision = 273
    
    
    # ----------------------------------------------- #
    # Сервис привязки аккаунта к IP и Hwid
    # ----------------------------------------------- #
    # Разрешить игрокам привязывать аккаунт к IP
    # Привязка осуществляется с помощью команды .lock
    AllowLockIP = false
    
    # Разрешить игрокам привязывать аккаунт к HWid
    # Работает только в случае когда стоит LameGuard
    # Привязка осуществляется с помощью команды .lock
    AllowLockHwid = false
    
    # Битовая маска привязки аккаунта по HWid
    # 2 - HDD
    # 4 - BIOS
    # 8 - CPU
    # Пример: HWIDBan = 10 (привязка по HWID будет считатся только по HDD и CPU)
    # Пример: HWIDBan = 14 (привязка по HWID будет считатся по HDD, CPU и BIOS)
    HwidLockMask = 10
    
    
    #-------------------------------------------------------------
    # Настройки размеров пулов
    #-------------------------------------------------------------
    # Размер пула потоков, для выполнения запланированных задач, рекомендуемое значение: CPU x 4
    ScheduledThreadPoolSize = 16
    # Размер пула потоков, для незамедлительного выполнения задач, рекомендуемое значение: CPU x 2
    ExecutorThreadPoolSize = 8
    
    # Сбор статистики запусков, создания и времени выполнения задач. Сбрасывается в файл по заврешению работы сервера либо по команде telnet.
    EnableRunnableStats = False
    
    #-------------------------------------------------------------
    # Настройки сетевого обмена
    #-------------------------------------------------------------
    # Время простоя основного потока обработки соединений, операций чтения/записи
    SelectorSleepTime = 3
    # Задержка перед установкой интересуемого действия
    InterestDelay = 30
    # Максимальное количество пакетов для отправки за один проход
    MaxSendPerPass = 32
    # Размер буфера для чтения
    ReadBufferSize = 65536
    # Размер буфера для записи
    WriteBufferSize = 131072
    # Размер пула для временных буферов чтения/записи
    BufferPoolSize = 64
    # Количество менеджеров для работы с эффектами
    EffectTaskManagers = 1
    
    #-------------------------------------------------------------
    # Настройки языка
    #-------------------------------------------------------------
    # Следующие значения могут быть изменены пользователями из игры командой .lang, устанавливается значение по умолчанию
    # Язык диалогов по умолчанию, возможные варианты ru, en
    DefaultLang = ru
    
    # Таймер на удаление чаров, 0 удалять сразу
    DeleteCharAfterDays = 7
    
    # Директорий датапака
    DatapackRoot = .
    
    #-------------------------------------------------------------
    # Настройки перезагрузки сервера
    #-------------------------------------------------------------
    # Ежедневный авторестарт по расписанию. Время рестарта в формате cron.
    # Если поле пустое, ежедневный авторестарт отключен, по умолчанию 05:00
    AutoRestartAt = 0 5 * * *
    
    #-------------------------------------------------------------
    # Настройки гейм-мастеров
    #-------------------------------------------------------------
    # Скрывать статус гейм-мастеров в /gmlist и Community Board
    HideGMStatus = True
    # Объявлять о входе гейм-мастера в игру, если он не в инвизе
    ShowGMLogin = False
    # Сохранять гейм-мастерам эффекты silence, gmspeed, invul и т.д.
    SaveGMEffects = False
    
    #-------------------------------------------------------------
    # Настройки регионов игрового мира
    #-------------------------------------------------------------
    # Весь мир поделен на регионы, размер региона в клиенте равен размеру карты, а именно 32768x32768, диапазон Z от -32768 до 32767, идентификация карт в клиенте имеет вид XX_YY.
    # Для более удобной работы с объектами на сервере, мир поделен на регионы, как по горизонтали так и по вертикали. Размер региона и ближайших его соседей соотвествует области видимости игрока.
    # При настройке следует помнить: чем меньше размер региона, тем меньше нагрузка на процессор, тем меньше область видимости игрока, тем меньше исходящего трафика, но тем больше потребление памяти
    # Данный параметр определяет размер региона по горизонтали: 1 << n,  при значении n = 15 - соответсвует размеру карты клиента,  при значении 12 размер равен 4096, 11 - 2048
    HShift = 11
    # Данный параметр определяет высоту региона по вертикали, при значении 10 - высота равна 1024
    VShift = 11
    # Ограничение координат по высоте для всего мира, т.к. в мире не используется весь диапазон от -32768 до 32767, его можно сократить до -16384 .. 16383, тем самым сэкономить память
    MapMinZ = -32768
    MapMaxZ = 32767
    
    # Размер сектора территории. По умолчанию - 32.
    LinearTerritoryCellSize = 32
    
    #-------------------------------------------------------------
    # Настройки геодаты
    #-------------------------------------------------------------
    # Получать урон от падения
    DamageFromFalling = False
    # Хост для соединения с L2J-GeoEditor
    GeoEditorHost = 127.0.0.1
    
    #-------------------------------------------------------------
    # Настройки проклятого оружия
    #-------------------------------------------------------------
    # Включены ли они (по умолчанию True)
    AllowCursedWeapons = True
    # Дропать на землю оружие при дисконнекте\кике с сервера
    DropCursedWeaponsOnKick = False
    
    
    #-------------------------------------------------------------
    # Остальное
    #-------------------------------------------------------------
    # Не загружать спавн и квесты на старте сервреа
    StartWithoutSpawn = False
    StartWithoutQuest = False
    
    # Максимальное количество рефлектов
    MaxReflectionsCount = 300
    
    # Проверка геймсервера пингом, время ожидания ответа указывается в секундах
    PingServer = True
    WaitPingTime = 5
    
    # Частота вызова пурджера байпасов, в секундах
    PurgeTaskFrequency = 60
    
    # Задержка на повторное использование пакетов движения и атаки
    MovePacketDelay = 100
    # 200 - максимальное значение, при котором персонаж бьет без пауз на скорости атаки 1500.
    AttackPacketDelay = 200
    # Коррекция времени завершения удара для исключения остановок автоатаки 
    AttackEndDelay = 50
    
    # Интервал отсылки пакета UserInfo
    UserInfoInterval = 100
    # Включить отсылку статов
    BroadcastStatsInterval = True
    # Интервал отсылки CharInfo
    BroadcastCharInfoInterval = 100
    
    # Максимальное количество игроков на сервере
    MaximumOnlineUsers = 3000
    # Умножает общий реальный онлайн на данный параметр
    OnlineUsersPlus = 1
    # Автоудаление лежащих на земле вещей, время в секундах, 0 - не удалять, рекомендуется 600 (10 минут)
    AutoDestroyDroppedItemAfter = 600
    # Отдельная настройка для выброшенного игроком или выпавшего с ПК, по умолчанию 1200 (20 минут)
    AutoDestroyPlayerDroppedItemAfter = 1200
    # Включить склад
    AllowWarehouse = True
    # Включить почту
    AllowMail = True
    # Время отображение примеряемых вещей
    WearDelay = 10
    # Можно ли игрокам кидать вещи на землю
    AllowDiscardItem = True
    # Включена ли вода (если включена геодата обязательно включить)
    AllowWater = True
    # Выдавать ли всем игрокам права администратора (удобно для тестовых серверов)
    # Шаблон с привилегиями находятся в файле GMAccess.xml, для PlayerID set="0"
    EverybodyHasAdminRights = True
    # Разрешать ли всем игрокам специальные команды (начинаются с ///)
    AllowSpecialCommands = False
    #-------------------------------------------------------------
    # 2 - все диалоги кешируются при загрузке сервера
    # 1 - диалоги кешируются по мере обращения
    # 0 - кеширование отключено (только для тестирования)
    HtmCacheMode=0
    
    # The path to generate a static external web server (with / at the end)
    # Путь для генерации статики внешнему вебсерверу (с / в конце)
    WebServerRoot = ./webserver/
    # Generation period, 0 - disable
    # Период генерации, 0 - отключить
    WebServerDelay = 10
    
    #Setting Angel NevitSystem
    AltVitalityNevitUpPoint = 100
    AltVitalityNevitPoint = 100
    
    #-------------------------------------------------------------
    # Альтернативный спавн
    #-------------------------------------------------------------
    # Сохранять спавн админа в таблице add_spawnlist
    SaveGmSpawn = True
    # Загружать спавн из таблицы add_spawnlist
    LoadAddGmSpawn = True
    
    
    # ========================================
    # Настройки установки пароля на персонажа SA (Secondary Auth)
    # Предварительно включать данную опцию в клиенте (UseSecondaryAuth=true)
    # ========================================
    # Включить ли систему SA
    SAEnabled = False
    # Банить аккаунт после того как пользователь превысил число попыток ввода пароля?
    SABanAccEnabled = False
    # Усиленная система паролей, сочетать четные с нечетными обязательно!
    SAStrongPass = False
    # Максимальное количество попыток ввода пароля
    SAMaxAttemps = 5
    # Время бана чара при неудачи ввода пароля (мин)
    SABanTime = 480
    # Ссылка на страницу восстановления пароля
    SARecoveryLink = http://www.my-domain.com/charPassRec.php
    
    
    #-------------------------------------------------------------
    # Проксирование серверов
    #-------------------------------------------------------------
    # Включить проксирование
    ForwardingNet = False
    # IP Proxy Server для проксирования, порт 1080
    ForwardingNetIP = 127.0.0.1
    # ID сервера в игре
    ForwardingNetServerID = 2

     

     

    Спойлер

    12.thumb.png.ee14f409299e61d1afbf148158c7e78d.png

     


  4. 38 минут назад, Demoncool сказал:

    Скорее всего дело в геодате 

    Обработчик вроде как отключили. Если я правильно понял.

    Спойлер
    
    {
    	# Размерность карты
    	"GeoFirstX" : "11",
    	"GeoFirstY" : "10",
    	"GeoLastX" : "26",
    	"GeoLastY" : "26",
    
    	# Обрабатывать ли геодату
    	"AllowGeodata" : "false",
    
    	# Разрешать игроку падать с горизонтальной стены если он кликает по самой стене
    	"AllowFallFromWalls" : "false",
    
    	# Прибавка к Z для пакетов
    	"ClientZShift" : "16",
    
    	# Оптимизация размещение геодаты в памяти, экономит около 150Мб памяти
    	# для оптимизации нужно сначала нужно сгенерировать карты совпадений
    	"CompactGeoData" : "false",
    
    	# Минимальная разница между слоями
    	"MinLayerHeight" : "64",
    
    	# Максимальная высота ступеньки для геодаты
    	"MaxZDiff" : "64",
    
    	# Максимальная высота ступеньки для геодаты на стыке гео-регионов
    	"RegionEdgeMaxZDiff" : "128",
    
    	# Диагональный поиск
    	# Стоит отключать только для отладки
    	"PathFindDiagonal" : "true",
    
    	# Сглаживает путь
    	# Стоит отключать только для отладки
    	"PathClean" : "true",
    
    	# Сильно ускоряет поиск, как влияет на качество неизвестно
    	# 0 - отключить, 1 - только начало пути, 2 - начало и конец пути
    	"PathFindBoost" : "1",
    
    	# Максимальная высота ступеньки для поиска пути
    	"PathFindMaxZDiff" : "32",
    
    	# Множитель для площади поиска пути
    	"PathFindMapMul" : "2",
    
    	# Максимальное время, которое разрешено затратить на поиск пути (в наносекундах)
    	"PathFindMaxTime" : "100000000",
    
    	# Настройка буфферов для поиска пути, количество x размер карты (в клетках геодаты)
    	# Минимальный размер 96, максимальный - 512
    	"PathFindBuffers" : "8x96;8x128;8x160;8x192;8x256;4x288;4x320;2x384;1x512",
    	
    	# Максимальная разница рассинхронизации серверных и клиентских координат, после превышения которой произойдет корректировка позиции (откидывние/перемещение на серверную позицию в клиенте)
    	"maxAsyncCoordDiff" : "500",
    	
    	# Максимальная разница рассинхронизации серверных и клиентских координат перед атакой
    	"maxAsyncCoordDiffBeforeAttack" : "80",
    	
    	# Метод коррекции координат
    	# 0 - коррекция пакетом полета (например блинк сб)
    	# 1 - коррекция специальным пакетом валлидации 
    	# 2 - коррекция пакетом перемещения
    	"correctType" : "1"
    }

     

    Что здесь может еще не так, как кроме что обработка геодаты отключено? И все равно хотелось бы узнать, какой файл отвечает за скилы;)  На будущее, если вдруг необходимо будет что то менять) Если я что то не до понимаю, поправьте) Я новичок, и учусь только)


  5. Всем привет. Подскажите пожалуйста, кто ставил данную сборку, где расположен файл со скилами? Хочу поправить скил Rush, иначе что то он не работает. Баг со скилом, или это мне кажется?  

    Спойлер

    12.png

     


  6. Всем, привет. Подскажите пожалуйста, как можно исправить? Что то не могу понять в чем косяк в этих файлах.

    Спойлер
    
    package l2p.gameserver.utils;
    
    import l2p.gameserver.Config;
    import l2p.gameserver.data.xml.holder.ItemHolder;
    import l2p.gameserver.idfactory.IdFactory;
    import l2p.gameserver.instancemanager.CursedWeaponsManager;
    import l2p.gameserver.model.Playable;
    import l2p.gameserver.model.Player;
    import l2p.gameserver.model.base.Element;
    import l2p.gameserver.model.base.Race;
    import l2p.gameserver.model.instances.PetInstance;
    import l2p.gameserver.model.items.Inventory;
    import l2p.gameserver.model.items.ItemInstance;
    import l2p.gameserver.model.items.ItemInstance.ItemLocation;
    import l2p.gameserver.model.items.attachment.PickableAttachment;
    import l2p.gameserver.model.pledge.Clan;
    import l2p.gameserver.serverpackets.components.SystemMsg;
    import l2p.gameserver.serverpackets.L2GameServerPacket;
    import l2p.gameserver.serverpackets.SystemMessage2;
    import l2p.gameserver.tables.PetDataTable;
    import l2p.gameserver.templates.item.ArmorTemplate.ArmorType;
    import l2p.gameserver.templates.item.ItemTemplate;
    import l2p.gameserver.templates.item.WeaponTemplate.WeaponType;
    
    import org.apache.commons.lang3.ArrayUtils;
    
    public final class ItemFunctions {
    
        /**
         * Возвращает название предмета
         *
         * @param _itemId ID предмета
         * @return название
         */
        public static String getName(int _itemId, boolean isRus) {
            ItemTemplate t = ItemHolder.getInstance().getTemplate(_itemId);
            return (t == null ? "NoItemName" : t.getName());
        }
    
        public static long removeItemByObjectId(Playable playable, ItemInstance item, long count, boolean notify) {
            long removed = 0L;
            if ((playable == null) || (count < 1L)) {
                return removed;
            }
            Playable player = playable.getPlayer();
    
            if (item.getTemplate().isStackable()) {
                if (player.getInventory().destroyItemByObjectId(item.getObjectId(), count)) {
                    removed = count;
                }
            } else {
                for (long i = 0; i < count; i += 1) {
                    if (player.getInventory().destroyItemByObjectId(item.getObjectId(), 1)) {
                        removed += 1;
                    }
                }
            }
            if (removed > 0 && notify) {
                player.sendPacket(SystemMessage2.removeItems(item.getItemId(), removed));
            }
            return removed;
        }
    
        private ItemFunctions() {
        }
    
        public static ItemInstance createItem(int itemId) {
            ItemInstance item = new ItemInstance(IdFactory.getInstance().getNextId(), itemId);
            item.setLocation(ItemLocation.VOID);
            item.setCount(1L);
    
            return item;
        }
    
        public static ItemInstance createItem(int itemId, long itemCount) {
            ItemInstance item = new ItemInstance(IdFactory.getInstance().getNextId(), itemId);
            item.setLocation(ItemLocation.VOID);
            item.setCount(itemCount);
    
            return item;
        }
    
        public static void addItem(Playable playable, int itemId, long count) {
            addItem(playable, itemId, count, true);
        }
    
        /**
         * Добавляет предмет в инвентарь игрока, корректно обрабатывает нестыкуемые
         * вещи
         *
         * @param playable Владелец инвентаря
         * @param itemId ID предмета
         * @param count	количество
         */
        public static void addItem(Playable playable, int itemId, long count, boolean notify) {
            if (playable == null || count < 1) {
                return;
            }
    
            Playable player;
            if (playable.isSummon()) {
                player = playable.getPlayer();
            } else {
                player = playable;
            }
    
            ItemTemplate t = ItemHolder.getInstance().getTemplate(itemId);
            if (t.isStackable()) {
                player.getInventory().addItem(itemId, count);
            } else {
                for (long i = 0; i < count; i++) {
                    player.getInventory().addItem(itemId, 1);
                }
            }
    
            if (notify) {
                player.sendPacket(SystemMessage2.obtainItems(itemId, count, 0));
            }
        }
    
        /**
         * Возвращает количество предметов в инвентаре игрока
         *
         * @param playable Владелец инвентаря
         * @param itemId ID предмета
         * @return количество
         */
        public static long getItemCount(Playable playable, int itemId) {
            if (playable == null) {
                return 0;
            }
            Playable player = playable.getPlayer();
            return player.getInventory().getCountOf(itemId);
        }
    
        /**
         * Удаляет предметы из инвентаря игрока, корректно обрабатывает нестыкуемые
         * предметы
         *
         * @param playable Владелец инвентаря
         * @param itemId ID предмета
         * @param count	количество
         * @return количество удаленных
         */
        public static long removeItem(Playable playable, int itemId, long count, boolean notify) {
            long removed = 0;
            if (playable == null || count < 1) {
                return removed;
            }
    
            Playable player = playable.getPlayer();
    
            ItemTemplate t = ItemHolder.getInstance().getTemplate(itemId);
            if (t.isStackable()) {
                if (player.getInventory().destroyItemByItemId(itemId, count)) {
                    removed = count;
                }
            } else {
                for (long i = 0; i < count; i++) {
                    if (player.getInventory().destroyItemByItemId(itemId, 1)) {
                        removed++;
                    }
                }
            }
    
            if (removed > 0 && notify) {
                player.sendPacket(SystemMessage2.removeItems(itemId, removed));
            }
    
            return removed;
        }
    
        public final static boolean isClanApellaItem(int itemId) {
            return itemId >= 7860 && itemId <= 7879 || itemId >= 9830 && itemId <= 9839;
        }
    
        public final static SystemMessage2 checkIfCanEquip(PetInstance pet, ItemInstance item) {
            if (!item.isEquipable()) {
                return new SystemMessage2(SystemMsg.YOUR_PET_CANNOT_CARRY_THIS_ITEM);
            }
    
            int petId = pet.getNpcId();
    
            if (item.getTemplate().isPendant() //
                    || PetDataTable.isWolf(petId) && item.getTemplate().isForWolf() //
                    || PetDataTable.isHatchling(petId) && item.getTemplate().isForHatchling() //
                    || PetDataTable.isStrider(petId) && item.getTemplate().isForStrider() //
                    || PetDataTable.isGWolf(petId) && item.getTemplate().isForGWolf() //
                    || PetDataTable.isBabyPet(petId) && item.getTemplate().isForPetBaby() //
                    || PetDataTable.isImprovedBabyPet(petId) && item.getTemplate().isForPetBaby() //
                    ) {
                return null;
            }
    
            return new SystemMessage2(SystemMsg.YOUR_PET_CANNOT_CARRY_THIS_ITEM);
        }
    
        /**
         * Проверяет возможность носить эту вещь.
         *
         * @return null, если вещь носить можно, либо SystemMessage, который можно
         * показать игроку
         */
        public final static L2GameServerPacket checkIfCanEquip(Player player, ItemInstance item) {
            //FIXME [G1ta0] черезмерный хардкод, переделать на условия
            int itemId = item.getItemId();
            int targetSlot = item.getTemplate().getBodyPart();
            Clan clan = player.getClan();
    
            // Геройское оружие и Wings of Destiny Circlet
            if ((item.isHeroWeapon() || item.getItemId() == 6842) && !player.isHero()) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            // камаэли и хеви/робы/щиты/сигилы
            if (player.getRace() == Race.kamael && !Config.ALLOW_KAMAEL_ALL_EQUIP && (item.getItemType() == ArmorType.HEAVY || item.getItemType() == ArmorType.MAGIC || item.getItemType() == ArmorType.SIGIL || item.getItemType() == WeaponType.NONE)) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            // не камаэли и рапиры/арбалеты/древние мечи
            if (player.getRace() != Race.kamael && !Config.ALLOW_KAMAEL_ALL_EQUIP && (item.getItemType() == WeaponType.CROSSBOW || item.getItemType() == WeaponType.RAPIER || item.getItemType() == WeaponType.ANCIENTSWORD)) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            if (itemId >= 7850 && itemId <= 7859 && player.getLvlJoinedAcademy() == 0) // Clan Oath Armor
            {
                return new SystemMessage2(SystemMsg.THIS_ITEM_CAN_ONLY_BE_WORN_BY_A_MEMBER_OF_THE_CLAN_ACADEMY);
            }
    
            if (isClanApellaItem(itemId) && player.getPledgeClass() < Player.RANK_WISEMAN) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            if (item.getItemType() == WeaponType.DUALDAGGER && player.getSkillLevel(923) < 1) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            // Замковые короны, доступные для всех членов клана
            if (ArrayUtils.contains(ItemTemplate.ITEM_ID_CASTLE_CIRCLET, itemId) && (clan == null || itemId != ItemTemplate.ITEM_ID_CASTLE_CIRCLET[clan.getCastle()])) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            // Корона лидера клана, владеющего замком
            if (itemId == 6841 && (clan == null || !player.isClanLeader() || clan.getCastle() == 0)) {
                return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
            }
    
            // Нельзя одевать оружие, если уже одето проклятое оружие. Проверка двумя способами, для надежности.
            if (targetSlot == ItemTemplate.SLOT_LR_HAND || targetSlot == ItemTemplate.SLOT_L_HAND || targetSlot == ItemTemplate.SLOT_R_HAND) {
                if (itemId != player.getInventory().getPaperdollItemId(Inventory.PAPERDOLL_RHAND) && CursedWeaponsManager.getInstance().isCursed(player.getInventory().getPaperdollItemId(Inventory.PAPERDOLL_RHAND))) {
                    return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
                }
                if (player.isCursedWeaponEquipped() && itemId != player.getCursedWeaponEquippedId()) {
                    return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
                }
                // Ивентовые флаги в руках
                if (player._event != null && player._event.getName().equalsIgnoreCase("Capture The Flag") && player.getVar("CtF_Flag") != null) {
                    return new SystemMessage2(SystemMsg.THIS_ITEM_CANNOT_BE_MOVED);
                }
            }
    
            // Плащи
            if (item.getTemplate().isCloak()) {
                // Can be worn by Knights or higher ranks who own castle
                if (item.getName().contains("Knight") && (player.getPledgeClass() < Player.RANK_KNIGHT || player.getCastle() == null)) {
                    return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
                }
    
                // Плащи для камаэлей
                if (item.getName().contains("Kamael") && player.getRace() != Race.kamael) {
                    return new SystemMessage2(SystemMsg.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
                }
    
                // Плащи можно носить только с S80 или S84 сетом
                if (!player.getOpenCloak()) {
                    return new SystemMessage2(SystemMsg.THE_CLOAK_CANNOT_BE_EQUIPPED_BECAUSE_A_NECESSARY_ITEM_IS_NOT_EQUIPPED);
                }
            }
    
            if (targetSlot == ItemTemplate.SLOT_DECO) {
                int count = player.getTalismanCount();
                if (count <= 0) {
                    return new SystemMessage2(SystemMsg.YOU_CANNOT_WEAR_S1_BECAUSE_YOU_ARE_NOT_WEARING_A_BRACELET).addItemName(itemId);
                }
    
                ItemInstance deco;
                for (int slot = Inventory.PAPERDOLL_DECO1; slot <= Inventory.PAPERDOLL_DECO6; slot++) {
                    deco = player.getInventory().getPaperdollItem(slot);
                    if (deco != null) {
                        if (deco == item) {
                            return null; // талисман уже одет и количество слотов больше нуля
                        }					// Проверяем на количество слотов и одинаковые талисманы
                        if (--count <= 0 || deco.getItemId() == itemId) {
                            return new SystemMessage2(SystemMsg.YOU_CANNOT_EQUIP_S1_BECAUSE_YOU_DO_NOT_HAVE_ANY_AVAILABLE_SLOTS).addItemName(itemId);
                        }
                    }
                }
            }
            return null;
        }
    
        public static boolean checkIfCanPickup(Playable playable, ItemInstance item) {
            Player player = playable.getPlayer();
            return item.getDropTimeOwner() <= System.currentTimeMillis() || item.getDropPlayers().contains(player.getObjectId());
        }
    
        public static boolean canAddItem(Player player, ItemInstance item) {
            if (!player.getInventory().validateWeight(item)) {
                player.sendPacket(SystemMsg.YOU_HAVE_EXCEEDED_THE_WEIGHT_LIMIT);
                return false;
            }
    
            if (!player.getInventory().validateCapacity(item)) {
                player.sendPacket(SystemMsg.YOUR_INVENTORY_IS_FULL);
                return false;
            }
    
            if (!item.getTemplate().getHandler().pickupItem(player, item)) {
                return false;
            }
    
            PickableAttachment attachment = item.getAttachment() instanceof PickableAttachment ? (PickableAttachment) item.getAttachment() : null;
            if (attachment != null && !attachment.canPickUp(player)) {
                return false;
            }
    
            return true;
        }
    
        /**
         * Проверяет возможность передачи вещи
         *
         * @param player
         * @param item
         * @return
         */
        public static boolean checkIfCanDiscard(Player player, ItemInstance item) {
            if (item.isHeroWeapon()) {
                return false;
            }
    
            if (PetDataTable.isPetControlItem(item) && player.isMounted()) {
                return false;
            }
    
            if (player.getPetControlItem() == item) {
                return false;
            }
    
            if (player.getEnchantScroll() == item) {
                return false;
            }
    
            if (item.isCursed()) {
                return false;
            }
    
            if (item.getTemplate().isQuest()) {
                return false;
            }
    
            return true;
        }
    
        /**
         * Enchant
         */
        /**
         * При фейле эти свитки не ломают вещь, но сбрасывают заточку
         */
        public final static boolean isBlessedEnchantScroll(int itemId) {
            switch (itemId) {
                case 6575: // Wpn D
                case 6576: // Arm D
                case 6573: // Wpn C
                case 6574: // Arm C
                case 6571: // Wpn B
                case 6572: // Arm B
                case 6569: // Wpn A
                case 6570: // Arm A
                case 6577: // Wpn S
                case 6578: // Arm S
                case 21582: // Blessed Enchant Scroll T'Shirt
                    return true;
            }
            return false;
        }
    
        /**
         * При фейле эти свитки не имеют побочных эффектов
         */
        public final static boolean isAncientEnchantScroll(int itemId) {
            switch (itemId) {
                case 22014: // Wpn B
                case 22016: // Arm B
                case 22015: // Wpn A
                case 22017: // Arm A
                case 20519: // Wpn S
                case 20520: // Arm S
                    return true;
            }
            return false;
        }
    
        /**
         * HF5: При неудачной модификации предмет не исчезает и сохраняет уровень
         * модификации за счет силы Богини Разрушения. Не действует на предметы выше
         * +15.
         */
        public final static boolean isDestructionWpnEnchantScroll(int itemId) {
            switch (itemId) {
                case 22221:
                case 22223:
                case 22225:
                case 22227:
                case 22229:
                    return true;
            }
            return false;
        }
    
        /**
         * HF5: При неудачной модификации предмет не исчезает и сохраняет уровень
         * модификации за счет силы Богини Разрушения. Не действует на предметы выше
         * +6.
         */
        public final static boolean isDestructionArmEnchantScroll(int itemId) {
            switch (itemId) {
                case 22222:
                case 22224:
                case 22226:
                case 22228:
                case 22230:
                    return true;
            }
            return false;
        }
    
        /**
         * Эти свитки имеют 10% бонус шанса заточки
         */
        public final static boolean isItemMallEnchantScroll(int itemId) {
            switch (itemId) {
                case 22006: // Wpn D
                case 22010: // Arm D
                case 22007: // Wpn C
                case 22011: // Arm C
                case 22008: // Wpn B
                case 22012: // Arm B
                case 22009: // Wpn A
                case 22013: // Arm A
                case 20517: // Wpn S
                case 20518: // Arm S
                    return true;
                default:
                    return isAncientEnchantScroll(itemId);
            }
        }
    
        /**
         * Эти свитки имеют 100% шанс
         */
        public final static boolean isDivineEnchantScroll(int itemId) {
            switch (itemId) {
                case 22018: // Wpn B
                case 22020: // Arm B
                case 22019: // Wpn A
                case 22021: // Arm A
                case 20521: // Wpn S
                case 20522: // Arm S
                    return true;
            }
            return false;
        }
    
        /**
         * Они не используются официальным серером, но могут быть задействованы
         * альтами
         */
        public final static boolean isCrystallEnchantScroll(int itemId) {
            switch (itemId) {
                case 957: // Wpn D
                case 958: // Arm D
                case 953: // Wpn C
                case 954: // Arm C
                case 949: // Wpn B
                case 950: // Arm B
                case 731: // Wpn A
                case 732: // Arm A
                case 961: // Wpn S
                case 962: // Arm S
                    return true;
            }
            return false;
        }
    
        /**
         * Проверка соответствия свитка и катализатора грейду вещи.
         *
         * @return id кристалла для соответствующих и 0 для несоответствующих.
         */
        public final static int getEnchantCrystalId(ItemInstance item, ItemInstance scroll, ItemInstance catalyst) {
            boolean scrollValid = false, catalystValid = false;
    
            for (int scrollId : getEnchantScrollId(item)) {
                if (scroll.getItemId() == scrollId) {
                    scrollValid = true;
                    break;
                }
            }
    
            if (catalyst == null) {
                catalystValid = true;
            } else {
                for (int catalystId : getEnchantCatalystId(item)) {
                    if (catalystId == catalyst.getItemId()) {
                        catalystValid = true;
                        break;
                    }
                }
            }
    
            if (scrollValid && catalystValid) {
                switch (item.getCrystalType().cry) {
                    case ItemTemplate.CRYSTAL_NONE:
                        return 0;
                    case ItemTemplate.CRYSTAL_D:
                        return 1458;
                    case ItemTemplate.CRYSTAL_C:
                        return 1459;
                    case ItemTemplate.CRYSTAL_B:
                        return 1460;
                    case ItemTemplate.CRYSTAL_A:
                        return 1461;
                    case ItemTemplate.CRYSTAL_S:
                        return 1462;
                }
            }
    
            return -1;
        }
    
        /**
         * Возвращает список свитков, которые подходят для вещи.
         */
        public final static int[] getEnchantScrollId(ItemInstance item) {
            if (item.getTemplate().getType2() == ItemTemplate.TYPE2_WEAPON) {
                switch (item.getCrystalType().cry) {
                    case ItemTemplate.CRYSTAL_NONE:
                        return new int[]{13540};
                    case ItemTemplate.CRYSTAL_D:
                        return new int[]{955, 6575, 957, 22006, 22229};
                    case ItemTemplate.CRYSTAL_C:
                        return new int[]{951, 6573, 953, 22007, 22227};
                    case ItemTemplate.CRYSTAL_B:
                        return new int[]{947, 6571, 949, 22008, 22014, 22018, 22225};
                    case ItemTemplate.CRYSTAL_A:
                        return new int[]{729, 6569, 731, 22009, 22015, 22019, 22223};
                    case ItemTemplate.CRYSTAL_S:
                        return new int[]{959, 6577, 961, 20517, 20519, 20521, 22221};
                }
            } else if (item.getTemplate().getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR || item.getTemplate().getType2() == ItemTemplate.TYPE2_ACCESSORY) {
                switch (item.getCrystalType().cry) {
                    case ItemTemplate.CRYSTAL_NONE:
                        return new int[]{21581, 21582};
                    case ItemTemplate.CRYSTAL_D:
                        return new int[]{956, 6576, 958, 22010, 22230};
                    case ItemTemplate.CRYSTAL_C:
                        return new int[]{952, 6574, 954, 22011, 22228};
                    case ItemTemplate.CRYSTAL_B:
                        return new int[]{948, 6572, 950, 22012, 22016, 22020, 22226};
                    case ItemTemplate.CRYSTAL_A:
                        return new int[]{730, 6570, 732, 22013, 22017, 22021, 22224};
                    case ItemTemplate.CRYSTAL_S:
                        return new int[]{960, 6578, 962, 20518, 20520, 20522, 22222};
                }
            }
            return new int[0];
        }
        public static final int[][] catalyst = {
            // enchant catalyst list
            {12362, 14078, 14702}, // 0 - W D
            {12363, 14079, 14703}, // 1 - W C
            {12364, 14080, 14704}, // 2 - W B
            {12365, 14081, 14705}, // 3 - W A
            {12366, 14082, 14706}, // 4 - W S
            {12367, 14083, 14707}, // 5 - A D
            {12368, 14084, 14708}, // 6 - A C
            {12369, 14085, 14709}, // 7 - A B
            {12370, 14086, 14710}, // 8 - A A
            {12371, 14087, 14711}, // 9 - A S
        };
    
        public final static int[] getEnchantCatalystId(ItemInstance item) {
            if (item.getTemplate().getType2() == ItemTemplate.TYPE2_WEAPON) {
                switch (item.getCrystalType().cry) {
                    case ItemTemplate.CRYSTAL_A:
                        return catalyst[3];
                    case ItemTemplate.CRYSTAL_B:
                        return catalyst[2];
                    case ItemTemplate.CRYSTAL_C:
                        return catalyst[1];
                    case ItemTemplate.CRYSTAL_D:
                        return catalyst[0];
                    case ItemTemplate.CRYSTAL_S:
                        return catalyst[4];
                }
            } else if (item.getTemplate().getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR || item.getTemplate().getType2() == ItemTemplate.TYPE2_ACCESSORY) {
                switch (item.getCrystalType().cry) {
                    case ItemTemplate.CRYSTAL_A:
                        return catalyst[8];
                    case ItemTemplate.CRYSTAL_B:
                        return catalyst[7];
                    case ItemTemplate.CRYSTAL_C:
                        return catalyst[6];
                    case ItemTemplate.CRYSTAL_D:
                        return catalyst[5];
                    case ItemTemplate.CRYSTAL_S:
                        return catalyst[9];
                }
            }
            return new int[]{0, 0, 0};
        }
    
        public final static int getCatalystPower(int itemId) {
            /*
             14702	Agathion Auxiliary Stone: Enchant Weapon (D-Grade)	The Agathion Auxilary Stone raises the ability to enchant a D-Grade weapon by 20%
             14703	Agathion Auxiliary Stone: Enchant Weapon (C-Grade)	The Agathion Auxilary Stone raises the ability to enchant a C-Grade weapon by 18%
             14704	Agathion Auxiliary Stone: Enchant Weapon (B-Grade)	The Agathion Auxilary Stone raises the ability to enchant a B-Grade weapon by 15%
             14705	Agathion Auxiliary Stone: Enchant Weapon (A-Grade)	The Agathion Auxilary Stone raises the ability to enchant a A-Grade weapon by 12%
             14706	Agathion Auxiliary Stone: Enchant Weapon (S-Grade)	The Agathion Auxilary Stone raises the ability to enchant a S-Grade weapon by 10%
             14707	Agathion Auxiliary Stone: Enchant Armor (D-Grade)		The Agathion Auxilary Stone raises the ability to enchant a D-Grade armor by 35%
             14708	Agathion Auxiliary Stone: Enchant Armor (C-Grade)		The Agathion Auxilary Stone raises the ability to enchant a C-Grade armor by 27%
             14709	Agathion Auxiliary Stone: Enchant Armor (B-Grade)		The Agathion Auxilary Stone raises the ability to enchant a B-Grade armor by 23%
             14710	Agathion Auxiliary Stone: Enchant Armor (A-Grade)		The Agathion Auxilary Stone raises the ability to enchant a A-Grade armor by 18%
             14711	Agathion Auxiliary Stone: Enchant Armor (S-Grade)		The Agathion Auxilary Stone raises the ability to enchant a S-Grade armor by 15%
             */
            for (int i = 0; i < catalyst.length; i++) {
                for (int id : catalyst[i]) {
                    if (id == itemId) {
                        switch (i) {
                            case 0:
                                return 20;
                            case 1:
                                return 18;
                            case 2:
                                return 15;
                            case 3:
                                return 12;
                            case 4:
                                return 10;
                            case 5:
                                return 35;
                            case 6:
                                return 27;
                            case 7:
                                return 23;
                            case 8:
                                return 18;
                            case 9:
                                return 15;
                        }
                    }
                }
            }
    
            return 0;
            /*
             switch(_itemId)
             {
             case 14702:
             case 14078:
             case 12362:
             return 20;
             case 14703:
             case 14079:
             case 12363:
             return 18;
             case 14704:
             case 14080:
             case 12364:
             return 15;
             case 14705:
             case 14081:
             case 12365:
             return 12;
             case 14706:
             case 14082:
             case 12366:
             return 10;
             case 14707:
             case 14083:
             case 12367:
             return 35;
             case 14708:
             case 14084:
             case 12368:
             return 27;
             case 14709:
             case 14085:
             case 12369:
             return 23;
             case 14710:
             case 14086:
             case 12370:
             return 18;
             case 14711:
             case 14087:
             case 12371:
             return 15;
             default:
             return 0;
             }
             */
        }
    
        /**
         * Проверяет соответствие уровня заточки и вообще катализатор ли это или
         * левый итем
         *
         * @param item
         * @param catalyst
         * @return true если катализатор соответствует
         */
        public static final boolean checkCatalyst(ItemInstance item, ItemInstance catalyst) {
            if (item == null || catalyst == null) {
                return false;
            }
    
            int current = item.getEnchantLevel();
            if (current < (item.getTemplate().getBodyPart() == ItemTemplate.SLOT_FULL_ARMOR ? 4 : 3) || current > 8) {
                return false;
            }
    
            for (int catalystRequired : getEnchantCatalystId(item)) {
                if (catalystRequired == catalyst.getItemId()) {
                    return true;
                }
            }
    
            return false;
        }
    
        /**
         * Augmentation
         */
        public final static boolean isLifeStone(int itemId) {
            return itemId >= 8723 && itemId <= 8762 || itemId >= 9573 && itemId <= 9576 || itemId >= 10483 && itemId <= 10486 || itemId >= 14166 && itemId <= 14169 || itemId >= 16160 && itemId <= 16167;
        }
    
        public final static boolean isAccessoryLifeStone(int itemId) {
            return itemId >= 12754 && itemId <= 12763 || itemId >= 12840 && itemId <= 12851 || itemId == 12821 || itemId == 12822 || itemId == 14008 || itemId == 16177 || itemId == 16178;
        }
    
        public final static boolean isVisualLifeStone(int itemId) {
            return (ArrayUtils.contains(Config.VISUAL_FROM_AUGMENT_CATALIS_WEAPON, itemId) || ArrayUtils.contains(Config.VISUAL_FROM_AUGMENT_CATALIS_ARMOR, itemId));
        }
        
        public final static boolean isVisualLifeStoneWeapon(int itemId) {
            return (ArrayUtils.contains(Config.VISUAL_FROM_AUGMENT_CATALIS_WEAPON, itemId));
        }
        
        public final static boolean isVisualLifeStoneArmor(int itemId) {
            return (ArrayUtils.contains(Config.VISUAL_FROM_AUGMENT_CATALIS_ARMOR, itemId));
        }
    
        public final static int getLifeStoneGrade(int itemId) {
            switch (itemId) {
                case 8723:
                case 8724:
                case 8725:
                case 8726:
                case 8727:
                case 8728:
                case 8729:
                case 8730:
                case 8731:
                case 8732:
                case 9573:
                case 10483:
                case 14166:
                case 16160:
                case 16164:
                    return 0;
                case 8733:
                case 8734:
                case 8735:
                case 8736:
                case 8737:
                case 8738:
                case 8739:
                case 8740:
                case 8741:
                case 8742:
                case 9574:
                case 10484:
                case 14167:
                case 16161:
                case 16165:
                    return 1;
                case 8743:
                case 8744:
                case 8745:
                case 8746:
                case 8747:
                case 8748:
                case 8749:
                case 8750:
                case 8751:
                case 8752:
                case 9575:
                case 10485:
                case 14168:
                case 16162:
                case 16166:
                    return 2;
                case 8753:
                case 8754:
                case 8755:
                case 8756:
                case 8757:
                case 8758:
                case 8759:
                case 8760:
                case 8761:
                case 8762:
                case 9576:
                case 10486:
                case 14169:
                case 16163:
                case 16167:
                    return 3;
                default:
                    return 0;
            }
        }
    
        public final static int getLifeStoneLevel(int itemId) {
            switch (itemId) {
                case 8723:
                case 8733:
                case 8743:
                case 8753:
                case 12754:
                case 12840:
                    return 1;
                case 8724:
                case 8734:
                case 8744:
                case 8754:
                case 12755:
                case 12841:
                    return 2;
                case 8725:
                case 8735:
                case 8745:
                case 8755:
                case 12756:
                case 12842:
                    return 3;
                case 8726:
                case 8736:
                case 8746:
                case 8756:
                case 12757:
                case 12843:
                    return 4;
                case 8727:
                case 8737:
                case 8747:
                case 8757:
                case 12758:
                case 12844:
                    return 5;
                case 8728:
                case 8738:
                case 8748:
                case 8758:
                case 12759:
                case 12845:
                    return 6;
                case 8729:
                case 8739:
                case 8749:
                case 8759:
                case 12760:
                case 12846:
                    return 7;
                case 8730:
                case 8740:
                case 8750:
                case 8760:
                case 12761:
                case 12847:
                    return 8;
                case 8731:
                case 8741:
                case 8751:
                case 8761:
                case 12762:
                case 12848:
                    return 9;
                case 8732:
                case 8742:
                case 8752:
                case 8762:
                case 12763:
                case 12849:
                    return 10;
                case 9573:
                case 9574:
                case 9575:
                case 9576:
                case 12821:
                case 12850:
                    return 11;
                case 10483:
                case 10484:
                case 10485:
                case 10486:
                case 12822:
                case 12851:
                    return 12;
                case 14008:
                case 14166:
                case 14167:
                case 14168:
                case 14169:
                    return 13;
                case 16160:
                case 16161:
                case 16162:
                case 16163:
                case 16177:
                    return 14;
                case 16164:
                case 16165:
                case 16166:
                case 16167:
                case 16178:
                    return 15;
                default:
                    return 1;
            }
        }
    
        /**
         * Возвращает тип элемента для камня атрибуции
         *
         * @return значение элемента
         */
        public static Element getEnchantAttributeStoneElement(int itemId, boolean isArmor) {
            Element element = Element.NONE;
            switch (itemId) {
                case 9546:
                case 9552:
                case 10521:
                case 9558:
                case 9564:
                    element = Element.FIRE;
                    break;
                case 9547:
                case 9553:
                case 10522:
                case 9559:
                case 9565:
                    element = Element.WATER;
                    break;
                case 9548:
                case 9554:
                case 10523:
                case 9560:
                case 9566:
                    element = Element.EARTH;
                    break;
                case 9549:
                case 9555:
                case 10524:
                case 9561:
                case 9567:
                    element = Element.WIND;
                    break;
                case 9550:
                case 9556:
                case 10525:
                case 9562:
                case 9568:
                    element = Element.UNHOLY;
                    break;
                case 9551:
                case 9557:
                case 10526:
                case 9563:
                case 9569:
                    element = Element.HOLY;
                    break;
            }
    
            if (isArmor) {
                return Element.getReverseElement(element);
            }
    
            return element;
        }
    
        public static boolean deleteItem(Playable playable, int itemId, long count) {
            return deleteItem(playable, itemId, count, true);
        }
    
        public static boolean deleteItem(Playable playable, int itemId, long count, boolean notify) {
            if ((playable == null) || (count < 1)) {
                return false;
            }
            Player player = playable.getPlayer();
    
            player.getInventory().writeLock();
            try {
                ItemTemplate t = ItemHolder.getInstance().getTemplate(itemId);
                boolean bool1;
                if (t == null) {
                    return false;
                }
                if (t.isStackable()) {
                    if (!player.getInventory().destroyItemByItemId(itemId, count)) {
                        return false;
                    }
                } else {
                    if (player.getInventory().getCountOf(itemId) < count) {
                        return false;
                    }
                    for (long i = 0L; i < count; i += 1L) {
                        if (!player.getInventory().destroyItemByItemId(itemId, 1L)) {
                            return false;
                        }
                    }
                }
            } finally {
                player.getInventory().writeUnlock();
            }
            if (notify) {
                player.sendPacket(SystemMessage2.removeItems(itemId, count));
            }
            return true;
        }
    }

     

    Спойлер
    
    package l2p.gameserver.model.actor.listener;
    
    import l2p.commons.listener.Listener;
    import l2p.gameserver.listener.actor.player.OnPlayerBuyPremiumListner;
    import l2p.gameserver.listener.actor.player.OnPlayerEndPremiumListner;
    import l2p.gameserver.listener.actor.player.OnPlayerEnterListener;
    import l2p.gameserver.listener.actor.player.OnPlayerExitListener;
    import l2p.gameserver.listener.actor.player.OnPlayerPartyInviteListener;
    import l2p.gameserver.listener.actor.player.OnPlayerPartyLeaveListener;
    import l2p.gameserver.listener.actor.player.OnPlayerUpLvlListener;
    import l2p.gameserver.listener.actor.player.OnTeleportListener;
    import l2p.gameserver.model.Creature;
    import l2p.gameserver.model.Player;
    import l2p.gameserver.model.entity.Reflection;
    
    public class PlayerListenerList extends CharListenerList {
    
        public PlayerListenerList(Player actor) {
            super(actor);
        }
    
        @Override
        public Player getActor() {
            return (Player) actor;
        }
    
        public void onEnter() {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerEnterListener.class.isInstance(listener)) {
                        ((OnPlayerEnterListener) listener).onPlayerEnter(getActor());
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerEnterListener.class.isInstance(listener)) {
                        ((OnPlayerEnterListener) listener).onPlayerEnter(getActor());
                    }
                }
            }
        }
    
        public void onExit() {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerExitListener.class.isInstance(listener)) {
                        ((OnPlayerExitListener) listener).onPlayerExit(getActor());
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerExitListener.class.isInstance(listener)) {
                        ((OnPlayerExitListener) listener).onPlayerExit(getActor());
                    }
                }
            }
        }
    
        public void onTeleport(int x, int y, int z, Reflection reflection) {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnTeleportListener.class.isInstance(listener)) {
                        ((OnTeleportListener) listener).onTeleport(getActor(), x, y, z, reflection);
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnTeleportListener.class.isInstance(listener)) {
                        ((OnTeleportListener) listener).onTeleport(getActor(), x, y, z, reflection);
                    }
                }
            }
        }
        
        public void onLvlUp(Player player) {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerUpLvlListener.class.isInstance(listener)) {
                        ((OnPlayerUpLvlListener) listener).onLvlUp(player);
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerUpLvlListener.class.isInstance(listener)) {
                        ((OnPlayerUpLvlListener) listener).onLvlUp(player);
                    }
                }
            }
        }
        
        public void onBuyPremium(Player player) {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerBuyPremiumListner.class.isInstance(listener)) {
                        ((OnPlayerBuyPremiumListner) listener).onBuyPremium(player);
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerBuyPremiumListner.class.isInstance(listener)) {
                        ((OnPlayerBuyPremiumListner) listener).onBuyPremium(player);
                    }
                }
            }
        }
        
        public void onEndPremium(Player player) {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerEndPremiumListner.class.isInstance(listener)) {
                        ((OnPlayerEndPremiumListner) listener).onEndPremium(player);
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerEndPremiumListner.class.isInstance(listener)) {
                        ((OnPlayerEndPremiumListner) listener).onEndPremium(player);
                    }
                }
            }
        }
    
        public void onPartyInvite() {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerPartyInviteListener.class.isInstance(listener)) {
                        ((OnPlayerPartyInviteListener) listener).onPartyInvite(getActor());
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerPartyInviteListener.class.isInstance(listener)) {
                        ((OnPlayerPartyInviteListener) listener).onPartyInvite(getActor());
                    }
                }
            }
        }
    
        public void onPartyLeave() {
            if (!global.getListeners().isEmpty()) {
                for (Listener<Creature> listener : global.getListeners()) {
                    if (OnPlayerPartyLeaveListener.class.isInstance(listener)) {
                        ((OnPlayerPartyLeaveListener) listener).onPartyLeave(getActor());
                    }
                }
            }
    
            if (!getListeners().isEmpty()) {
                for (Listener<Creature> listener : getListeners()) {
                    if (OnPlayerPartyLeaveListener.class.isInstance(listener)) {
                        ((OnPlayerPartyLeaveListener) listener).onPartyLeave(getActor());
                    }
                }
            }
        }
    }

     

    Спойлер
    
    package l2p.gameserver.clientpackets;
    
    import ftGuard.ftGuard;
    import ftGuard.network.GuardManager;
    import java.util.Calendar;
    import l2p.gameserver.Announcements;
    import l2p.gameserver.Config;
    import l2p.gameserver.ThreadPoolManager;
    import l2p.gameserver.dao.MailDAO;
    import l2p.gameserver.data.StringHolder;
    import l2p.gameserver.data.xml.holder.ResidenceHolder;
    import l2p.gameserver.instancemanager.BotManager;
    import l2p.gameserver.instancemanager.CoupleManager;
    import l2p.gameserver.instancemanager.CursedWeaponsManager;
    import l2p.gameserver.instancemanager.PetitionManager;
    import l2p.gameserver.instancemanager.PlayerMessageStack;
    import l2p.gameserver.instancemanager.QuestManager;
    import l2p.gameserver.listener.actor.player.OnAnswerListener;
    import l2p.gameserver.listener.actor.player.impl.ReviveAnswerListener;
    import l2p.gameserver.model.AcademList;
    import l2p.gameserver.model.Creature;
    import l2p.gameserver.model.Effect;
    import l2p.gameserver.model.GameObjectTasks;
    import l2p.gameserver.model.GameObjectsStorage;
    import l2p.gameserver.model.Player;
    import l2p.gameserver.model.Skill;
    import l2p.gameserver.model.Summon;
    import l2p.gameserver.model.World;
    import l2p.gameserver.model.base.InvisibleType;
    import l2p.gameserver.model.entity.SevenSigns;
    import l2p.gameserver.model.entity.events.impl.ClanHallAuctionEvent;
    import l2p.gameserver.model.entity.residence.ClanHall;
    import l2p.gameserver.model.items.ItemInstance;
    import l2p.gameserver.model.mail.Mail;
    import l2p.gameserver.model.pledge.Clan;
    import l2p.gameserver.model.pledge.SubUnit;
    import l2p.gameserver.model.pledge.UnitMember;
    import l2p.gameserver.model.premium.PremiumConfig;
    import l2p.gameserver.model.quest.Quest;
    import l2p.gameserver.network.GameClient;
    import l2p.gameserver.serverpackets.ChangeWaitType;
    import l2p.gameserver.serverpackets.ClientSetTime;
    import l2p.gameserver.serverpackets.ConfirmDlg;
    import l2p.gameserver.serverpackets.Die;
    import l2p.gameserver.serverpackets.EtcStatusUpdate;
    import l2p.gameserver.serverpackets.ExAutoSoulShot;
    import l2p.gameserver.serverpackets.ExBR_PremiumState;
    import l2p.gameserver.serverpackets.ExBasicActionList;
    import l2p.gameserver.serverpackets.ExGoodsInventoryChangedNotify;
    import l2p.gameserver.serverpackets.ExMPCCOpen;
    import l2p.gameserver.serverpackets.ExNoticePostArrived;
    import l2p.gameserver.serverpackets.ExNotifyPremiumItem;
    import l2p.gameserver.serverpackets.ExPCCafePointInfo;
    import l2p.gameserver.serverpackets.ExReceiveShowPostFriend;
    import l2p.gameserver.serverpackets.ExSetCompassZoneCode;
    import l2p.gameserver.serverpackets.ExStorageMaxCount;
    import l2p.gameserver.serverpackets.HennaInfo;
    import l2p.gameserver.serverpackets.L2FriendList;
    import l2p.gameserver.serverpackets.L2GameServerPacket;
    import l2p.gameserver.serverpackets.MagicSkillLaunched;
    import l2p.gameserver.serverpackets.MagicSkillUse;
    import l2p.gameserver.serverpackets.ObserverStart;
    import l2p.gameserver.serverpackets.PartySmallWindowAll;
    import l2p.gameserver.serverpackets.PartySpelled;
    import l2p.gameserver.serverpackets.PetInfo;
    import l2p.gameserver.serverpackets.PledgeShowInfoUpdate;
    import l2p.gameserver.serverpackets.PledgeShowMemberListDeleteAll;
    import l2p.gameserver.serverpackets.PledgeShowMemberListUpdate;
    import l2p.gameserver.serverpackets.PledgeSkillList;
    import l2p.gameserver.serverpackets.PrivateStoreMsgBuy;
    import l2p.gameserver.serverpackets.PrivateStoreMsgSell;
    import l2p.gameserver.serverpackets.QuestList;
    import l2p.gameserver.serverpackets.RecipeShopMsg;
    import l2p.gameserver.serverpackets.RelationChanged;
    import l2p.gameserver.serverpackets.Ride;
    import l2p.gameserver.serverpackets.SSQInfo;
    import l2p.gameserver.serverpackets.ShortCutInit;
    import l2p.gameserver.serverpackets.SkillCoolTime;
    import l2p.gameserver.serverpackets.SkillList;
    import l2p.gameserver.serverpackets.SystemMessage2;
    import l2p.gameserver.serverpackets.TeleportToLocation;
    import l2p.gameserver.serverpackets.components.HtmlMessage;
    import l2p.gameserver.serverpackets.components.SystemMsg;
    import l2p.gameserver.skills.AbnormalEffect;
    import l2p.gameserver.tables.SkillTable;
    import l2p.gameserver.templates.item.ItemTemplate;
    import l2p.gameserver.utils.GameStats;
    import l2p.gameserver.utils.ItemFunctions;
    import l2p.gameserver.utils.TradeHelper;
    import org.apache.commons.lang3.tuple.Pair;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class EnterWorld extends L2GameClientPacket {
    
        private static final Object _lock = new Object();
        private static final Logger _log = LoggerFactory.getLogger(EnterWorld.class);
    
        @Override
        protected void readImpl() {
            //readS(); - клиент всегда отправляет строку "narcasse"
        }
    
        @Override
        protected void runImpl() {
            GameClient client = getClient();
            Player activeChar = client.getActiveChar();
    
            if (activeChar == null) {
                client.closeNow(false);
                return;
            }
    
            int MyObjectId = activeChar.getObjectId();
            Long MyStoreId = activeChar.getStoredId();
    
            synchronized (_lock)//TODO [G1ta0] че это за хуйня, и почему она тут
            {
                for (Player cha : GameObjectsStorage.getAllPlayersForIterate()) {
                    if (MyStoreId == cha.getStoredId()) {
                        continue;
                    }
                    try {
                        if (cha.getObjectId() == MyObjectId) {
                            _log.warn("Double EnterWorld for char: " + activeChar.getName());
                            cha.kick();
                        }
                    } catch (Exception e) {
                        _log.error("", e);
                    }
                }
            }
    
            GameStats.incrementPlayerEnterGame();
    
            boolean first = activeChar.entering;
    
            if (first) {
                activeChar.setOnlineStatus(true);
                if (activeChar.getPlayerAccess().GodMode && !Config.SHOW_GM_LOGIN) {
                    activeChar.setInvisibleType(InvisibleType.NORMAL);
                }
    
                activeChar.setNonAggroTime(Long.MAX_VALUE);
                activeChar.spawnMe();
    
                if (activeChar.isInStoreMode()) {
                    if (!TradeHelper.checksIfCanOpenStore(activeChar, activeChar.getPrivateStoreType())) {
                        activeChar.setPrivateStoreType(Player.STORE_PRIVATE_NONE);
                        activeChar.standUp();
                        activeChar.broadcastCharInfo();
                    }
                }
    
                activeChar.setRunning();
                activeChar.standUp();
                activeChar.startTimers();
            }
    
            activeChar.sendPacket(new ExBR_PremiumState(activeChar, activeChar.hasBonus()));
    
            activeChar.getMacroses().sendUpdate();
            activeChar.sendPacket(new SSQInfo(), new HennaInfo(activeChar));
            activeChar.sendItemList(false);
            activeChar.sendPacket(new ShortCutInit(activeChar), new SkillList(activeChar), new SkillCoolTime(activeChar));
            activeChar.sendPacket(SystemMsg.WELCOME_TO_THE_WORLD_OF_LINEAGE_II);
    
            if (Config.SHOW_HTML_WELCOME) {
    
                HtmlMessage html = new HtmlMessage(5).setFile("welcome.htm");
                html.replace("%name%", activeChar.getName());
                activeChar.sendPacket(html);
            }
    
            Announcements.getInstance().showAnnouncements(activeChar);
    
            if (first) {
                activeChar.getListeners().onEnter();
            }
    
            SevenSigns.getInstance().sendCurrentPeriodMsg(activeChar);
    
            if (first && activeChar.getCreateTime() > 0) {
                Calendar create = Calendar.getInstance();
                create.setTimeInMillis(activeChar.getCreateTime());
                Calendar now = Calendar.getInstance();
    
                int day = create.get(Calendar.DAY_OF_MONTH);
                if (create.get(Calendar.MONTH) == Calendar.FEBRUARY && day == 29) {
                    day = 28;
                }
    
                int myBirthdayReceiveYear = activeChar.getVarInt(Player.MY_BIRTHDAY_RECEIVE_YEAR, 0);
                if (create.get(Calendar.MONTH) == now.get(Calendar.MONTH) && create.get(Calendar.DAY_OF_MONTH) == day) {
                    if ((myBirthdayReceiveYear == 0 && create.get(Calendar.YEAR) != now.get(Calendar.YEAR)) || myBirthdayReceiveYear > 0 && myBirthdayReceiveYear != now.get(Calendar.YEAR)) {
                        Mail mail = new Mail();
                        mail.setSenderId(1);
                        mail.setSenderName(StringHolder.getInstance().getNotNull(activeChar, "birthday.npc"));
                        mail.setReceiverId(activeChar.getObjectId());
                        mail.setReceiverName(activeChar.getName());
                        mail.setTopic(StringHolder.getInstance().getNotNull(activeChar, "birthday.title"));
                        mail.setBody(StringHolder.getInstance().getNotNull(activeChar, "birthday.text"));
    
                        ItemInstance item = ItemFunctions.createItem(21169);
                        item.setLocation(ItemInstance.ItemLocation.MAIL);
                        item.setCount(1L);
                        item.save();
    
                        mail.addAttachment(item);
                        mail.setUnread(true);
                        mail.setType(Mail.SenderType.BIRTHDAY);
                        mail.setExpireTime(720 * 3600 + (int) (System.currentTimeMillis() / 1000L));
                        mail.save();
    
                        activeChar.setVar(Player.MY_BIRTHDAY_RECEIVE_YEAR, String.valueOf(now.get(Calendar.YEAR)), -1);
                    }
                }
            }
    
            Clan clan = activeChar.getClan();
            if (activeChar.getClan() != null) {
                notifyClanMembers(activeChar);
    
                activeChar.sendPacket(activeChar.getClan().listAll());
                activeChar.sendPacket(new PledgeShowInfoUpdate(activeChar.getClan()), new PledgeSkillList(activeChar.getClan()));
    
                if (activeChar.getLevel() < 40 && activeChar.getPledgeType() == -1) {
    
                    if (activeChar.getVar("bbsAcadem") != null) {
                        if (System.currentTimeMillis() - Long.parseLong(activeChar.getVar("bbsAcadem")) > (3 * 24 * 60 * 60 * 1000)) {
                            if (clan.getLeader().isOnline()) {
                                AcademList.deleteAcademInDb(clan, activeChar.getObjectId(), false, true);
                            }
    
                            clan.removeClanMember(activeChar.getObjectId());
                            activeChar.setLvlJoinedAcademy(0);
                            activeChar.setClan(null);
                            activeChar.setTitle("");
    
                            activeChar.broadcastUserInfo(true);
                            activeChar.broadcastRelation();
    
                            // disable clan tab
                            activeChar.sendPacket(SystemMsg.YOU_HAVE_RECENTLY_BEEN_DISMISSED_FROM_A_CLAN, new PledgeShowMemberListDeleteAll());
                        } else {
                            ThreadPoolManager.getInstance().schedule(new GameObjectTasks.AcademPlayerTask(activeChar), Long.parseLong(activeChar.getVar("bbsAcadem")) + (3 * 24 * 60 * 60 * 1000));
                        }
                    }
                } else if (activeChar.isClanLeader()) {
                    for (Clan clanTmp : AcademList.getClanList()) {
                        if (clanTmp == clan) {
                            long adenaAcadem = AcademList.findBadAcadem(clan);
                            ItemFunctions.addItem(activeChar, 57, adenaAcadem);
                        }
                    }
                }
            }
    
            // engage and notify Partner
            if (first && Config.ALLOW_WEDDING) {
                CoupleManager.getInstance().engage(activeChar);
                CoupleManager.getInstance().notifyPartner(activeChar);
            }
    
            if (first) {
                activeChar.getFriendList().notifyFriends(true);
                loadTutorial(activeChar);
                activeChar.restoreDisableSkills();
            }
    
            sendPacket(new L2FriendList(activeChar), new ExStorageMaxCount(activeChar), new QuestList(activeChar), new ExBasicActionList(activeChar), new EtcStatusUpdate(activeChar));
    
            activeChar.checkHpMessages(activeChar.getMaxHp(), activeChar.getCurrentHp());
            activeChar.checkDayNightMessages();
    
            if (Config.PETITIONING_ALLOWED) {
                PetitionManager.getInstance().checkPetitionMessages(activeChar);
            }
    
            if (!first) {
                if (activeChar.isCastingNow()) {
                    Creature castingTarget = activeChar.getCastingTarget();
                    Skill castingSkill = activeChar.getCastingSkill();
                    long animationEndTime = activeChar.getAnimationEndTime();
                    if (castingSkill != null && castingTarget != null && castingTarget.isCreature() && activeChar.getAnimationEndTime() > 0) {
                        sendPacket(new MagicSkillUse(activeChar, castingTarget, castingSkill.getId(), castingSkill.getLevel(), (int) (animationEndTime - System.currentTimeMillis()), 0));
                    }
                }
    
                if (activeChar.isInBoat()) {
                    activeChar.sendPacket(activeChar.getBoat().getOnPacket(activeChar, activeChar.getInBoatPosition()));
                }
    
                if (activeChar.isMoving || activeChar.isFollow) {
                    sendPacket(activeChar.movePacket());
                }
    
                if (activeChar.getMountNpcId() != 0) {
                    sendPacket(new Ride(activeChar));
                }
    
                if (activeChar.isFishing()) {
                    activeChar.stopFishing();
                }
            }
    
            activeChar.entering = false;
            activeChar.sendUserInfo(true);
    
            if (activeChar.isSitting()) {
                activeChar.sendPacket(new ChangeWaitType(activeChar, ChangeWaitType.WT_SITTING));
            }
            if (activeChar.getPrivateStoreType() != Player.STORE_PRIVATE_NONE) {
                if (activeChar.getPrivateStoreType() == Player.STORE_PRIVATE_BUY) {
                    sendPacket(new PrivateStoreMsgBuy(activeChar));
                } else if (activeChar.getPrivateStoreType() == Player.STORE_PRIVATE_SELL || activeChar.getPrivateStoreType() == Player.STORE_PRIVATE_SELL_PACKAGE) {
                    sendPacket(new PrivateStoreMsgSell(activeChar));
                } else if (activeChar.getPrivateStoreType() == Player.STORE_PRIVATE_MANUFACTURE) {
                    sendPacket(new RecipeShopMsg(activeChar));
                }
            }
    
            if (activeChar.isDead()) {
                sendPacket(new Die(activeChar));
            }
    
            activeChar.unsetVar("offline");
    
            // на всякий случай
            activeChar.sendActionFailed();
    
            if (first && activeChar.isGM() && Config.SAVE_GM_EFFECTS && activeChar.getPlayerAccess().CanUseGMCommand) {
                //silence
                if (activeChar.getVarB("gm_silence")) {
                    activeChar.setMessageRefusal(true);
                    activeChar.sendPacket(SystemMsg.MESSAGE_REFUSAL_MODE);
                }
                //invul
                if (activeChar.getVarB("gm_invul")) {
                    activeChar.setIsInvul(true);
                    activeChar.startAbnormalEffect(AbnormalEffect.S_INVULNERABLE);
                    activeChar.sendMessage(activeChar.getName() + " is now immortal.");
                }
                //gmspeed
                try {
                    int var_gmspeed = Integer.parseInt(activeChar.getVar("gm_gmspeed"));
                    if (var_gmspeed >= 1 && var_gmspeed <= 4) {
                        activeChar.doCast(SkillTable.getInstance().getInfo(7029, var_gmspeed), activeChar, true);
                    }
                } catch (Exception E) {
                }
            }
    
            // Bot manager punishment
            if (Config.ALT_ENABLE_BOTREPORT) {
                BotManager.getInstance().onEnter(activeChar);
            }
    
            PlayerMessageStack.getInstance().CheckMessages(activeChar);
    
            sendPacket(ClientSetTime.STATIC, new ExSetCompassZoneCode(activeChar));
    
            Pair<Integer, OnAnswerListener> entry = activeChar.getAskListener(false);
            if (entry != null && entry.getValue() instanceof ReviveAnswerListener) {
                sendPacket(new ConfirmDlg(SystemMsg.C1_IS_MAKING_AN_ATTEMPT_TO_RESURRECT_YOU_IF_YOU_CHOOSE_THIS_PATH_S2_EXPERIENCE_WILL_BE_RETURNED_FOR_YOU, 0).addString("Other player").addString("some"));
            }
    
            if (activeChar.isCursedWeaponEquipped()) {
                CursedWeaponsManager.getInstance().showUsageTime(activeChar, activeChar.getCursedWeaponEquippedId());
            }
    
            if (!first) {
                //Персонаж вылетел во время просмотра
                if (activeChar.isInObserverMode()) {
    
                    if (activeChar.getObserverMode() == Player.OBSERVER_STARTING) {
                        if (activeChar.isInOlympiadObserverMode()) {
                            sendPacket(new TeleportToLocation(activeChar, activeChar.getObservePoint().getLoc()));
                        } else {
                            sendPacket(new ObserverStart(activeChar.getObservePoint().getLoc()));
                        }
                    } else if (activeChar.getObserverMode() == Player.OBSERVER_LEAVING) {
                        activeChar.returnFromObserverMode();
                    } else if (activeChar.isInOlympiadObserverMode()) {
                        activeChar.leaveOlympiadObserverMode(true);
                    } else {
                        activeChar.leaveObserverMode();
                    }
    
                } else if (activeChar.isVisible()) {
                    World.showObjectsToPlayer(activeChar, false);
                }
    
                if (activeChar.getPet() != null) {
                    sendPacket(new PetInfo(activeChar.getPet()));
                }
    
                if (activeChar.isInParty()) {
                    Summon member_pet;
                    //sends new member party window for all members
                    //we do all actions before adding member to a list, this speeds things up a little
                    sendPacket(new PartySmallWindowAll(activeChar.getParty(), activeChar));
    
                    for (Player member : activeChar.getParty().getPartyMembers()) {
                        if (member != activeChar) {
                            sendPacket(new PartySpelled(member, true));
                            Summon memberPet;
                            if ((memberPet = member.getPet()) != null) {
                                sendPacket(new PartySpelled(memberPet, true));
                            }
                            sendPacket(new RelationChanged().add(member, activeChar));
                            if (memberPet != null) {
                                memberPet.broadcastCharInfoImpl(activeChar);
                            }
                        }
                    }
    
                    // Если партия уже в СС, то вновь прибывшем посылаем пакет открытия окна СС
                    if (activeChar.getParty().isInCommandChannel()) {
                        sendPacket(ExMPCCOpen.STATIC);
                    }
                }
    
                for (int shotId : activeChar.getAutoSoulShot()) {
                    sendPacket(new ExAutoSoulShot(shotId, true));
                }
    
                for (Effect e : activeChar.getEffectList().getAllFirstEffects()) {
                    if (e.getSkill().isToggle()) {
                        sendPacket(new MagicSkillLaunched(activeChar, e.getSkill().getId(), e.getSkill().getLevel(), activeChar));
                    }
                }
    
                activeChar.broadcastCharInfo();
            } else {
                activeChar.sendUserInfo(); // Отобразит права в клане
            }
            activeChar.updateEffectIcons();
            activeChar.updateStats();
    
            if (Config.ALT_PCBANG_POINTS_ENABLED) {
                activeChar.sendPacket(new ExPCCafePointInfo(activeChar, 0, 1, 2, 12));
            }
    
            if (!activeChar.getPremiumItemList().isEmpty()) {
                activeChar.sendPacket(Config.GOODS_INVENTORY_ENABLED ? ExGoodsInventoryChangedNotify.STATIC : ExNotifyPremiumItem.STATIC);
            }
    
            if (activeChar.hasBonus() ? PremiumConfig.getPremConfigId(activeChar.getBonus().getBonusId()).ALLOW_HERO_AURA : false) {
                activeChar.setHeroAura(true);
            }
    
            if (!activeChar.isHero()) {
                for (ItemInstance item : activeChar.getInventory().getItems()) {
                    if (item.isHeroWeapon()) {
                        activeChar.getInventory().destroyItem(item, 1);
                    }
                }
            }
            activeChar.delOlympiadIp();
            activeChar.sendVoteSystemInfo();
            activeChar.sendPacket(new ExReceiveShowPostFriend(activeChar));
            activeChar.getNevitSystem().onEnterWorld();
            if (ftGuard.isProtectionOn()) {
                GuardManager.SendSpecialSting(client);
            }
            
    
            checkNewMail(activeChar);
        }
    
        private static void notifyClanMembers(Player activeChar) {
            Clan clan = activeChar.getClan();
            SubUnit subUnit = activeChar.getSubUnit();
            if (clan == null || subUnit == null) {
                return;
            }
    
            UnitMember member = subUnit.getUnitMember(activeChar.getObjectId());
            if (member == null) {
                return;
            }
    
            member.setPlayerInstance(activeChar, false);
    
            int sponsor = activeChar.getSponsor();
            int apprentice = activeChar.getApprentice();
            L2GameServerPacket msg = new SystemMessage2(SystemMsg.CLAN_MEMBER_S1_HAS_LOGGED_INTO_GAME).addName(activeChar);
            PledgeShowMemberListUpdate memberUpdate = new PledgeShowMemberListUpdate(activeChar);
            for (Player clanMember : clan.getOnlineMembers(activeChar.getObjectId())) {
                clanMember.sendPacket(memberUpdate);
                if (clanMember.getObjectId() == sponsor) {
                    clanMember.sendPacket(new SystemMessage2(SystemMsg.YOUR_APPRENTICE_C1_HAS_LOGGED_OUT).addName(activeChar));
                } else if (clanMember.getObjectId() == apprentice) {
                    clanMember.sendPacket(new SystemMessage2(SystemMsg.YOUR_SPONSOR_C1_HAS_LOGGED_IN).addName(activeChar));
                } else {
                    clanMember.sendPacket(msg);
                }
            }
    
            if (!activeChar.isClanLeader()) {
                return;
            }
    
            ClanHall clanHall = clan.getHasHideout() > 0 ? ResidenceHolder.getInstance().getResidence(ClanHall.class, clan.getHasHideout()) : null;
            if (clanHall == null || clanHall.getAuctionLength() != 0) {
                return;
            }
    
            if (clanHall.getSiegeEvent().getClass() != ClanHallAuctionEvent.class) {
                return;
            }
    
            if (clan.getWarehouse().getCountOf(ItemTemplate.ITEM_ID_ADENA) < clanHall.getRentalFee()) {
                activeChar.sendPacket(new SystemMessage2(SystemMsg.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_ME_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW).addLong(clanHall.getRentalFee()));
            }
        }
    
        private void loadTutorial(Player player) {
            Quest q = QuestManager.getQuest(255);
            if (q != null) {
                player.processQuestEvent(q.getName(), "UC", null);
            }
        }
    
        private void checkNewMail(Player activeChar) {
            for (Mail mail : MailDAO.getInstance().getReceivedMailByOwnerId(activeChar.getObjectId())) {
                if (mail.isUnread()) {
                    sendPacket(ExNoticePostArrived.STATIC_FALSE);
                    break;
                }
            }
        }
    }

     

    Спойлер
    
    package l2p.gameserver.clientpackets;
    
    import java.nio.BufferUnderflowException;
    import java.util.List;
    
    import l2p.commons.net.nio.impl.ReceivablePacket;
    import l2p.gameserver.GameServer;
    import l2p.gameserver.network.GameClient;
    import l2p.gameserver.serverpackets.L2GameServerPacket;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * Packets received by the game server from clients
     */
    public abstract class L2GameClientPacket extends ReceivablePacket<GameClient> {
    
        private static final Logger _log = LoggerFactory.getLogger(L2GameClientPacket.class);
    
        @Override
        public final boolean read() {
            try {
                readImpl();
                return true;
            } catch (BufferUnderflowException e) {
                _client.onPacketReadFail();
                _log.error("Client: " + _client + " - Failed reading: " + getType() + " - Server Version: " + GameServer.getInstance().getVersion().getRevisionNumber(), e);
            } catch (Exception e) {
                _log.error("Client: " + _client + " - Failed reading: " + getType() + " - Server Version: " + GameServer.getInstance().getVersion().getRevisionNumber(), e);
            }
    
            return false;
        }
    
        protected abstract void readImpl() throws Exception;
    
        @Override
        public final void run() {
            GameClient client = getClient();
            try {
                runImpl();
            } catch (Exception e) {
                _log.error("Client: " + client + " - Failed running: " + getType() + " - Server Version: " + GameServer.getInstance().getVersion().getRevisionNumber(), e);
            }
        }
    
        protected abstract void runImpl() throws Exception;
    
        protected String readS(int len) {
            String ret = readS();
            return ret.length() > len ? ret.substring(0, len) : ret;
        }
    
        protected void sendPacket(L2GameServerPacket packet) {
            getClient().sendPacket(packet);
        }
    
        protected void sendPacket(L2GameServerPacket... packets) {
            getClient().sendPacket(packets);
        }
    
        protected void sendPackets(List<L2GameServerPacket> packets) {
            getClient().sendPackets(packets);
        }
    
        public String getType() {
            return "[C] " + getClass().getSimpleName();
        }
    }

     

     


  7. В 21.09.2018 в 11:45, lvlkoo сказал:

    Прописать нужно в переменных среды, конкретнее в PATH до папки в bin в дерриктории с jdk.

    А так же на всякий случай создать переменную JAVA_HOME и прописать туда путь к дерриктории с jdk.

     

    С линуксом проблем быть не должно. После установки openjdk переменные должны сами заекспортиться

    ПС. Вариант с тем, чтобы прописать непосредственно путь в бат-файле типо C:\Program Files...\jdk...\java -server ..... тоже наверное сработает, но лучше всетаки переменная среды, я не уверен что вирутальная машина берет все ресурсы с корня, а не с той же переменной :)

     Спасибо) Но на Linux я не на виртуалке тестирую, а на норм железе. Вроде как переменные среды добавил.

    Еще такйо вопрос, чтоб не создавать повторно тему. Подскажите, от каких разрабов можно за основу ХФ взять?

    LostWordl или OverWorld?

     


  8. Кто сможет подсказать, как правильно прописать путь в батнике до JDK? Сервер запускается на JRE.

     

    Спойлер
    
    ..
    06:55:24 [main] INFO  Scripts - Scripts: Loading...
    Exception in thread "main" java.lang.ExceptionInInitializerError
            at org.mmocore.gameserver.data.scripts.Scripts.getInstance(Scripts.java:
    51)
            at org.mmocore.gameserver.GameServer.<init>(GameServer.java:145)
            at org.mmocore.gameserver.GameServer.main(GameServer.java:324)
    Caused by: java.lang.RuntimeException: Error: server started by JRE instead JDK!
     Please start server with Java Development Kit.
            at org.mmocore.commons.compiler.Compiler.compile(Compiler.java:32)
            at org.mmocore.gameserver.data.scripts.Scripts.load(Scripts.java:210)
            at org.mmocore.gameserver.data.scripts.Scripts.load(Scripts.java:103)
            at org.mmocore.gameserver.data.scripts.Scripts.<init>(Scripts.java:47)
            at org.mmocore.gameserver.data.scripts.Scripts.<init>(Scripts.java:41)
            at org.mmocore.gameserver.data.scripts.Scripts$SingletonHolder.<clinit>(
    Scripts.java:334)
            ... 3 more

     

     

    Вот батник: 

    Спойлер
    
    @echo off
    title Lineage II GameServer - JTS
    :start
    echo Starting Lineage II - GameServer(High Five).
    echo.
    
    java -Duser.timezone=Europe/Moscow -server -Dfile.encoding=UTF-8 -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -Xms1024m -Xmx1024m -cp config;./lib/* org.mmocore.gameserver.GameServer
    
    REM Debug ...
    REM java -Dfile.encoding=UTF-8 -cp config;./lib/* -Xmx1G -Xnoclassgc -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=7456 org.mmocore.gameserver.GameServer
    
    if ERRORLEVEL 2 goto restart
    if ERRORLEVEL 1 goto error
    goto end
    :restart
    echo.
    echo GameServer restarted ...
    echo.
    goto start
    :error
    echo.
    echo GameServer terminated abnormaly ...
    echo.
    :end
    echo.
    echo GameServer terminated ...
    echo.
    
    pause

     

    Тестирую и на Linux и Windows. Желательно под Linux тоже. 


  9. 29 минут назад, lvlkoo сказал:

    Эмм, судя по всему какаято несовместимость версий ява. Возможно у вас слишком старый ант.

    Попробуй последний ант скачать

     

    Хорошо, спасибо. Проблема была не в совместимости, а ссылки на переменные среды не указаны были. Ант последней версии стоит.


  10. Подскажите, что за ошибка при компиляции сборки Lucera 2 Interlude?

    Спойлер
    
    Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/tools/ant/launch/Launcher : Unsupported major.minor version 52.0
            at java.lang.ClassLoader.defineClass1(Native Method)
            at java.lang.ClassLoader.defineClass(ClassLoader.java:808)
            at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
            at java.net.URLClassLoader.defineClass(URLClassLoader.java:442)
            at java.net.URLClassLoader.access$100(URLClassLoader.java:64)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:354)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:348)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(URLClassLoader.java:347)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:430)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:323)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
            at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
    Compile La2 Server END!

     

     


  11. Все разобрался. JDK все правильно был установлен. Сборку скомпилировал. Просто надо было добавить в 56 строке вот такой параметр:

    includeantruntime="false"

     

    Логин сервер норм поднялся. А вот гейм сервер выдает вот такую штуку.

     

    15:29:49 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано
    15:29:54 [Thread-17] INFO  AuthServerCommunication - Connecting to authserver on 192.168.1.17:9014
    15:29:54 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано
    15:29:59 [Thread-17] INFO  AuthServerCommunication - Connecting to authserver on 192.168.1.17:9014
    15:29:59 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано
    15:30:04 [Thread-17] INFO  AuthServerCommunication - Connecting to authserver on 192.168.1.17:9014
    15:30:04 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано
    15:30:09 [Thread-17] INFO  AuthServerCommunication - Connecting to authserver on 192.168.1.17:9014
    15:30:09 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано
    15:30:14 [Thread-17] INFO  AuthServerCommunication - Connecting to authserver on 192.168.1.17:9014
    15:30:14 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано
    15:30:19 [Thread-17] INFO  AuthServerCommunication - Connecting to authserver on 192.168.1.17:9014
    15:30:19 [Thread-17] ERROR AuthServerCommunication - AuthServer I/O error: В соединении отказано

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

    Гейм сервер:

    #-------------------------------------------------------------
    	# Сетевые настройки сервера  
    	#-------------------------------------------------------------
    	# IP на который биндить геймсервер, * - на все возможные
    	"GameserverHostname" : "192.168.1.17",
    	"GameserverPort" : "7777",
    	# This is transmitted to the clients connecting from an external network, so it has to be a public IP or resolvable hostname
    	"ExternalHostname" : "192.168.1.17",
    	# This is transmitted to the client from the same network, so it has to be a local IP or resolvable hostname
    	"InternalHostname" : "192.168.1.17",
    	
    	# Надстройка для работы в разных сетях если их много. При true 
    	# Настраивается в ipconfig/ipconfig.xml
    	"IpConfigEnable" : "false",
    
    	# Адрес\порт логинсервера
    	"LoginPort" : "9014",
    	"LoginHost" : "127.0.0.1",
    	# Какой ID запрашивать у логинсервера
    	"RequestServerID" : "1",
    	# Разрешать брать другой ид, если запрашиваемый занят
    	"AcceptAlternateID" : "true",
    
    	# Настройки XML-RPC сервера. Создавать ли сервер, Хост и порт сервера, хост допустимого клиента.
    	"XmlRpcServerEnabled" : "false",
    	"XmlRpcServerHost" : "127.0.0.1",
    	"XmlRpcServerPort" : "5601",
    	"XmlRpcClientHost" : "127.0.0.1",

    Логин сервер:

    # ================================================================
    	# Настройки сервера авторизации
    	# ================================================================
    
    	# Хост и порт для клиентских соединений
    	"LoginserverHostname" : "192.168.1.17",
    	"LoginserverPort" : "2106",
    
    	# Хост и порт для игровых серверов
    	"LoginHost" : "127.0.0.1",
    	"LoginPort" : "9014",
    
    	# Настройки XML-RPC сервера. Создавать ли сервер, Хост и порт сервера, хост допустимого клиента.
    	"XmlRpcServerEnabled" : "false",
    	"XmlRpcServerHost" : "127.0.0.1",
    	"XmlRpcServerPort" : "5600",
    	"XmlRpcClientHost" : "127.0.0.1",

    Лучше желательно на внешний ИПшник, чтоб доступ был с инета.


  12. Всем, привет. Подскажите пожалуйста, что за ошибка при компиляции возникает? И как ее решить? Пытаюсь скомпилировать на Java 8 версии.

    CODE\jts_src_last\jts_src_last\commons\src\main\module_commons.xml:56: Error running javac.exe compiler

    Вот 56 строка с данного файла:

    <javac destdir="${commons.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}" memorymaximumsize="${compiler.max.memory}" fork="true">
          <compilerarg line="${compiler.args.commons}"/>
          <bootclasspath refid="commons.module.bootclasspath"/>
          <classpath refid="commons.module.production.classpath"/>
          <src refid="commons.module.sourcepath"/>
          <patternset refid="excluded.from.compilation.commons"/>
        </javac>

    Что может быть тут не так?

    • Upvote 1

  13. https://bitbucket.org/account/user/l2jserver/projects/L2J тут их последние творение

    http://redmine.hellevil.ru/projects/git-l2j_datapack_rus/repository мой перевод

    http://la2hell.ru/superpatch.rar патч "авторега" как это выглядит на их сборке

    У них приват сервер я так понимаю? Т.к скачать невозможно, качаются только геодата и датапак.


  14. Если HTML`ки были взяты из другой сборки, то без исходников ничего не сделаешь. Будет работать только то, что совместимо с твоим ядром. Либо проверяй байпасы, multisell`ы и т.д. - может чего-то не хватает.

    Датапак с исходников, после компила, вроде как настроил бафы и магазин, но другие сервисы щас пробую настроить, но пока не выходит.


  15. Всем привет! Подскажите как поставить CommunityBoard c бафами и тп, файлы неоюходимые есть,и дамп базы тоже. Раскидал по папкам как положено, залил в MySQL дамп баз, не все функции работают, кликабельны только бафер и магазин, точнее функции Телепорт, Карьера, и Сервис.

    post-30500-0-12934400-1484812216_thumb.png


  16. Добрый день всем форумчане!

     

    Подскажите пожалуйста, скомпилировал сервер с исходов, но при запуске RegistrGameServer.bat выдает ошибку. Как ее можно исправить? Исходный код от L2Emu Rebelion Team

     

    @[member='Echo'] off
    title Rebellion-Team: Game Server Registration...
    :start
    echo Starting Game Server Registration.
    echo.
    java -server -Xms64m -Xmx64m -Xbootclasspath/p:./jsr167.jar -cp config/xml;../libs/*; l2r.loginserver.GameServerRegister
    
    
    pause
    

     

    post-30500-0-17596500-1484638720_thumb.png

×
×
  • Создать...