Grek 63 Опубликовано 14 февраля, 2022 30 минут назад, MrPacman сказал: Отпиши в ЛС автору поста, а то чувствую появится ещё одна тема в арбитраже) писал у него пока что нету времени, посоветовал тут поискать кто сможет. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
KillMilk 257 Опубликовано 14 февраля, 2022 Ребята адптируйте челу выше либу стрикса к мобиусу Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 14 февраля, 2022 21 минуту назад, Str4he0 сказал: Ребята адптируйте челу выше либу стрикса к мобиусу Я бы одаптировал бы, но пока что сам не разобрался как зайти на сервер с защитой. Дальше вода логина/пароля не идет. Вечная загрузка. ( Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
KillMilk 257 Опубликовано 14 февраля, 2022 2 минуты назад, Yarpi сказал: Я бы одаптировал бы, но пока что сам не разобрался как зайти на сервер с защитой. Дальше вода логина/пароля не идет. Вечная загрузка. ( логи какие ? что менял в коде, распиши по этапно Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 14 февраля, 2022 1 минуту назад, Str4he0 сказал: логи какие ? что менял в коде, распиши по этапно Может в телегу? Писать много. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
KillMilk 257 Опубликовано 14 февраля, 2022 1 минуту назад, Yarpi сказал: Может в телегу? Писать много. нет давай тут, что бы все видели и не задавали мне 100000000 вопросов в лс + аську +тг Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 14 февраля, 2022 1 минуту назад, Str4he0 сказал: нет давай тут, что бы все видели и не задавали мне 100000000 вопросов в лс + аську +тг По ссылке с последних стараниц нашел архив на стрикс с папкой мобиус. Перекинул к себе в ГК от мобиуса (только части кода) без замены файлов. Скомпилил сурс и запускаеться без проблем. При попытке зайти без патча дальше выбора сервера не доходит. В логах сказано про"что то там с чексумами" А вот при попытке зайти с патчем, после ввода пароля и логина А так же нажатия кнопки вход тупо вечная загрузка в логах нечего не пишет. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
KillMilk 257 Опубликовано 14 февраля, 2022 3 минуты назад, Yarpi сказал: По ссылке с последних стараниц нашел архив на стрикс с папкой мобиус. Перекинул к себе в ГК от мобиуса (только части кода) без замены файлов. Скомпилил сурс и запускаеться без проблем. При попытке зайти без патча дальше выбора сервера не доходит. В логах сказано про"что то там с чексумами" А вот при попытке зайти с патчем, после ввода пароля и логина А так же нажатия кнопки вход тупо вечная загрузка в логах нечего не пишет. что откуда кинул и тд, больше инфы взял файл ProtocolVersion.java и адаптировал в сборке был код, стал код такой и тд, так можно? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 14 февраля, 2022 Только что, Str4he0 сказал: что откуда кинул и тд, больше инфы взял файл ProtocolVersion.java и адаптировал в сборке был код, стал код такой и тд, так можно? Сейчас тогда не распешу, не за компом. Завтра распишу все файлы в которых сделал изменения. 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
xDead 0 Опубликовано 14 февраля, 2022 А как файлы клиента адаптировать? например для ессенса 338 протокола Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
KillMilk 257 Опубликовано 15 февраля, 2022 5 часов назад, xDead сказал: А как файлы клиента адаптировать? например для ессенса 338 протокола Ок выложу гайд на днях, просто сегодня привился пфайзером пока бошка не варит. 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 15 февраля, 2022 (изменено) 13 часов назад, Str4he0 сказал: что откуда кинул и тд, больше инфы взял файл ProtocolVersion.java и адаптировал в сборке был код, стал код такой и тд, так можно? И так в продолжении истории. AuthLogin.java был такой Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.network.GameClient; /** * @version $Revision: 1.9.2.3.2.4 $ $Date: 2005/03/27 15:29:30 $ */ public class AuthLogin implements IClientIncomingPacket { // loginName + keys must match what the loginserver used. private String _loginName; /* * private final long _key1; private final long _key2; private final long _key3; private final long _key4; */ private int _playKey1; private int _playKey2; private int _loginKey1; private int _loginKey2; @Override public boolean read(GameClient client, PacketReader packet) { _loginName = packet.readS().toLowerCase(); _playKey2 = packet.readD(); _playKey1 = packet.readD(); _loginKey1 = packet.readD(); _loginKey2 = packet.readD(); return true; } @Override public void run(GameClient client) { if (_loginName.isEmpty() || !client.isProtocolOk()) { client.closeNow(); return; } final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2); // avoid potential exploits if (client.getAccountName() == null) { // Preventing duplicate login in case client login server socket was disconnected or this packet was not sent yet if (LoginServerThread.getInstance().addGameServerLogin(_loginName, client)) { client.setAccountName(_loginName); LoginServerThread.getInstance().addWaitingClientAndSendRequest(_loginName, client, key); } else { client.close(null); } } } } А стал таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import org.strixplatform.StrixPlatform; import org.strixplatform.logging.Log; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.serverpackets.ServerClose; /** * @version $Revision: 1.9.2.3.2.4 $ $Date: 2005/03/27 15:29:30 $ */ public class AuthLogin implements IClientIncomingPacket { // loginName + keys must match what the loginserver used. private String _loginName; /* * private final long _key1; private final long _key2; private final long _key3; private final long _key4; */ private int _playKey1; private int _playKey2; private int _loginKey1; private int _loginKey2; @Override public boolean read(GameClient client, PacketReader packet) { _loginName = packet.readS().toLowerCase(); _playKey2 = packet.readD(); _playKey1 = packet.readD(); _loginKey1 = packet.readD(); _loginKey2 = packet.readD(); return true; } @Override public void run(GameClient client) { if (_loginName.isEmpty() || !client.isProtocolOk()) { client.closeNow(); return; } final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2); // avoid potential exploits if (client.getAccountName() == null) { // Preventing duplicate login in case client login server socket was disconnected or this packet was not sent yet if (LoginServerThread.getInstance().addGameServerLogin(_loginName, client)) { client.setAccountName(_loginName); LoginServerThread.getInstance().addWaitingClientAndSendRequest(_loginName, client, key); } else { client.close(null); } } // TODO[K] - Strix section start if(StrixPlatform.getInstance().isPlatformEnabled()) { if(client.getStrixClientData() != null) { client.getStrixClientData().setClientAccount(_loginName); if(StrixPlatform.getInstance().isAuthLogEnabled()) { Log.auth("Account: [" + _loginName + "] HWID: [" + client.getStrixClientData().getClientHWID() + "] SessionID: [" + client.getStrixClientData().getSessionId() + "] entered to Game Server"); } } else { client.close(ServerClose.STATIC_PACKET); return; } } // TODO[K] - Strix section end } } Файл EnterWorld.java был таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.OfflineTraderTable; import org.l2jmobius.gameserver.data.xml.AdminData; import org.l2jmobius.gameserver.data.xml.BeautyShopData; import org.l2jmobius.gameserver.data.xml.ClanHallData; import org.l2jmobius.gameserver.data.xml.SkillTreeData; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.SubclassInfoType; import org.l2jmobius.gameserver.enums.TeleportWhereType; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.instancemanager.FortSiegeManager; import org.l2jmobius.gameserver.instancemanager.InstanceManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.PetitionManager; import org.l2jmobius.gameserver.instancemanager.PunishmentManager; import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.model.PlayerCondOverride; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.punishment.PunishmentAffect; import org.l2jmobius.gameserver.model.punishment.PunishmentType; import org.l2jmobius.gameserver.model.quest.Quest; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.FortSiege; import org.l2jmobius.gameserver.model.siege.Siege; import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; import org.l2jmobius.gameserver.model.variables.AccountVariables; import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.Disconnection; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.Die; import org.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import org.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; import org.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList; import org.l2jmobius.gameserver.network.serverpackets.ExBeautyItemList; import org.l2jmobius.gameserver.network.serverpackets.ExGetBookMarkInfoPacket; import org.l2jmobius.gameserver.network.serverpackets.ExNoticePostArrived; import org.l2jmobius.gameserver.network.serverpackets.ExNotifyPremiumItem; import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeCount; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeWaitingListAlarm; import org.l2jmobius.gameserver.network.serverpackets.ExQuestItemList; import org.l2jmobius.gameserver.network.serverpackets.ExRotation; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.ExStorageMaxCount; import org.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo; import org.l2jmobius.gameserver.network.serverpackets.ExUnReadMailCount; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoEquipSlot; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight; import org.l2jmobius.gameserver.network.serverpackets.ExVitalityEffectInfo; import org.l2jmobius.gameserver.network.serverpackets.ExVoteSystemInfo; import org.l2jmobius.gameserver.network.serverpackets.HennaInfo; import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListAll; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListUpdate; import org.l2jmobius.gameserver.network.serverpackets.PledgeSkillList; import org.l2jmobius.gameserver.network.serverpackets.QuestList; import org.l2jmobius.gameserver.network.serverpackets.ShortCutInit; import org.l2jmobius.gameserver.network.serverpackets.SkillCoolTime; import org.l2jmobius.gameserver.network.serverpackets.SkillList; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExConnectedTimeAndGettableReward; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList; import org.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList; import org.l2jmobius.gameserver.util.BuilderUtil; /** * Enter World Packet Handler * <p> * <p> * 0000: 03 * <p> * packet format rev87 bddddbdcccccccccccccccccccc * <p> */ public class EnterWorld implements IClientIncomingPacket { private static final Map<String, ClientHardwareInfoHolder> TRACE_HWINFO = new ConcurrentHashMap<>(); private final int[][] _tracert = new int[5][4]; @Override public boolean read(GameClient client, PacketReader packet) { for (int i = 0; i < 5; i++) { for (int o = 0; o < 4; o++) { _tracert[i][o] = packet.readC(); } } packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readB(64); // Unknown Byte Array packet.readD(); // Unknown Value return true; } @Override public void run(GameClient client) { final PlayerInstance player = client.getPlayer(); if (player == null) { LOGGER.warning("EnterWorld failed! player returned 'null'."); Disconnection.of(client).defaultSequence(false); return; } client.setConnectionState(ConnectionState.IN_GAME); final String[] adress = new String[5]; for (int i = 0; i < 5; i++) { adress[i] = _tracert[i][0] + "." + _tracert[i][1] + "." + _tracert[i][2] + "." + _tracert[i][3]; } LoginServerThread.getInstance().sendClientTracert(player.getAccountName(), adress); client.setClientTracert(_tracert); player.broadcastUserInfo(); // Restore to instanced area if enabled if (Config.RESTORE_PLAYER_INSTANCE) { final PlayerVariables vars = player.getVariables(); final Instance instance = InstanceManager.getInstance().getPlayerInstance(player, false); if ((instance != null) && (instance.getId() == vars.getInt("INSTANCE_RESTORE", 0))) { player.setInstance(instance); } vars.remove("INSTANCE_RESTORE"); } player.updatePvpTitleAndColor(false); // Apply special GM properties to the GM when entering if (player.isGM()) { gmStartupProcess: { if (Config.GM_STARTUP_BUILDER_HIDE && AdminData.getInstance().hasAccess("admin_hide", player.getAccessLevel())) { BuilderUtil.setHiding(player, true); BuilderUtil.sendSysMessage(player, "hide is default for builder."); BuilderUtil.sendSysMessage(player, "FriendAddOff is default for builder."); BuilderUtil.sendSysMessage(player, "whisperoff is default for builder."); // It isn't recommend to use the below custom L2J GMStartup functions together with retail-like GMStartupBuilderHide, so breaking the process at that stage. break gmStartupProcess; } if (Config.GM_STARTUP_INVULNERABLE && AdminData.getInstance().hasAccess("admin_invul", player.getAccessLevel())) { player.setInvul(true); } if (Config.GM_STARTUP_INVISIBLE && AdminData.getInstance().hasAccess("admin_invisible", player.getAccessLevel())) { player.setInvisible(true); player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.STEALTH); } if (Config.GM_STARTUP_SILENCE && AdminData.getInstance().hasAccess("admin_silence", player.getAccessLevel())) { player.setSilenceMode(true); } if (Config.GM_STARTUP_DIET_MODE && AdminData.getInstance().hasAccess("admin_diet", player.getAccessLevel())) { player.setDietMode(true); player.refreshOverloaded(true); } } if (Config.GM_STARTUP_AUTO_LIST && AdminData.getInstance().hasAccess("admin_gmliston", player.getAccessLevel())) { AdminData.getInstance().addGm(player, false); } else { AdminData.getInstance().addGm(player, true); } if (Config.GM_GIVE_SPECIAL_SKILLS) { SkillTreeData.getInstance().addSkills(player, false); } if (Config.GM_GIVE_SPECIAL_AURA_SKILLS) { SkillTreeData.getInstance().addSkills(player, true); } } // Set dead status if applies if (player.getCurrentHp() < 0.5) { player.setDead(true); } boolean showClanNotice = false; // Clan related checks are here final Clan clan = player.getClan(); if (clan != null) { notifyClanMembers(player); notifySponsorOrApprentice(player); for (Siege siege : SiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getCastle().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getCastle().getResidenceId()); } } for (FortSiege siege : FortSiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getFort().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getFort().getResidenceId()); } } // Residential skills support if (player.getClan().getCastleId() > 0) { CastleManager.getInstance().getCastleByOwner(clan).giveResidentialSkills(player); } if (player.getClan().getFortId() > 0) { FortManager.getInstance().getFortByOwner(clan).giveResidentialSkills(player); } showClanNotice = clan.isNoticeEnabled(); } if (Config.ENABLE_VITALITY) { player.sendPacket(new ExVitalityEffectInfo(player)); } // Send Macro List player.getMacros().sendAllMacros(); // Send Teleport Bookmark List client.sendPacket(new ExGetBookMarkInfoPacket(player)); // Send Item List client.sendPacket(new ItemList(player, false)); // Send Quest Item List client.sendPacket(new ExQuestItemList(player)); // Send Adena and Inventory Count client.sendPacket(new ExAdenaInvenCount(player)); // Send Shortcuts client.sendPacket(new ShortCutInit(player)); // Send Action list player.sendPacket(ExBasicActionList.STATIC_PACKET); // Send blank skill list player.sendPacket(new SkillList()); // Send GG check // player.queryGameGuard(); // Send Dye Information player.sendPacket(new HennaInfo(player)); // Send Skill list player.sendSkillList(); // Send EtcStatusUpdate player.sendPacket(new EtcStatusUpdate(player)); // Clan packets if (clan != null) { clan.broadcastToOnlineMembers(new PledgeShowMemberListUpdate(player)); PledgeShowMemberListAll.sendAllTo(player); clan.broadcastToOnlineMembers(new ExPledgeCount(clan)); player.sendPacket(new PledgeSkillList(clan)); final ClanHall ch = ClanHallData.getInstance().getClanHallByClan(clan); if ((ch != null) && (ch.getCostFailDay() > 0)) { final SystemMessage sm = new SystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW); sm.addInt(ch.getLease()); player.sendPacket(sm); } } else { player.sendPacket(ExPledgeWaitingListAlarm.STATIC_PACKET); } // Send SubClass Info player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NO_CHANGES)); // Send Inventory Info player.sendPacket(new ExUserInfoInvenWeight(player)); // Send Adena / Inventory Count Info player.sendPacket(new ExAdenaInvenCount(player)); // Send Equipped Items player.sendPacket(new ExUserInfoEquipSlot(player)); // Send Unread Mail Count if (MailManager.getInstance().hasUnreadPost(player)) { player.sendPacket(new ExUnReadMailCount(player)); } // Faction System if (Config.FACTION_SYSTEM_ENABLED) { if (player.isGood()) { player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000)); } else if (player.isEvil()) { player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000)); } } Quest.playerEnter(player); // Send Quest List player.sendPacket(new QuestList(player)); if (Config.PLAYER_SPAWN_PROTECTION > 0) { player.setSpawnProtection(true); } player.spawnMe(player.getX(), player.getY(), player.getZ()); player.sendPacket(new ExRotation(player.getObjectId(), player.getHeading())); if (player.isCursedWeaponEquipped()) { CursedWeaponsManager.getInstance().getCursedWeapon(player.getCursedWeaponEquippedId()).cursedOnLogin(); } if (Config.PC_CAFE_ENABLED) { if (player.getPcCafePoints() > 0) { player.sendPacket(new ExPCCafePointInfo(player.getPcCafePoints(), 0, 1)); } else { player.sendPacket(new ExPCCafePointInfo()); } } // Expand Skill player.sendPacket(new ExStorageMaxCount(player)); // Friend list client.sendPacket(new L2FriendList(player)); SystemMessage sm = new SystemMessage(SystemMessageId.YOUR_FRIEND_S1_JUST_LOGGED_IN); sm.addString(player.getName()); for (int id : player.getFriendList()) { final WorldObject obj = World.getInstance().findObject(id); if (obj != null) { obj.sendPacket(sm); } } player.sendPacket(SystemMessageId.WELCOME_TO_THE_WORLD_OF_LINEAGE_II); AnnouncementsTable.getInstance().showAnnouncements(player); if ((Config.SERVER_RESTART_SCHEDULE_ENABLED) && (Config.SERVER_RESTART_SCHEDULE_MESSAGE)) { player.sendPacket(new CreatureSay(null, ChatType.BATTLEFIELD, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); } if (showClanNotice) { final NpcHtmlMessage notice = new NpcHtmlMessage(); notice.setFile(player, "data/html/clanNotice.htm"); notice.replace("%clan_name%", player.getClan().getName()); notice.replace("%notice_text%", player.getClan().getNotice().replaceAll("\r\n", "<br>")); notice.disableValidation(); client.sendPacket(notice); } else if (Config.SERVER_NEWS) { final String serverNews = HtmCache.getInstance().getHtm(player, "data/html/servnews.htm"); if (serverNews != null) { client.sendPacket(new NpcHtmlMessage(serverNews)); } } if (Config.PETITIONING_ALLOWED) { PetitionManager.getInstance().checkPetitionMessages(player); } if (player.isAlikeDead()) // dead or fake dead { // no broadcast needed since the player will already spawn dead to others client.sendPacket(new Die(player)); } player.onPlayerEnter(); client.sendPacket(new SkillCoolTime(player)); client.sendPacket(new ExVoteSystemInfo(player)); for (ItemInstance item : player.getInventory().getItems()) { if (item.isTimeLimitedItem()) { item.scheduleLifeTimeTask(); } if (item.isShadowItem() && item.isEquipped()) { item.decreaseMana(false); } } for (ItemInstance whItem : player.getWarehouse().getItems()) { if (whItem.isTimeLimitedItem()) { whItem.scheduleLifeTimeTask(); } } if (player.getClanJoinExpiryTime() > Chronos.currentTimeMillis()) { player.sendPacket(SystemMessageId.YOU_HAVE_RECENTLY_BEEN_DISMISSED_FROM_A_CLAN_YOU_ARE_NOT_ALLOWED_TO_JOIN_ANOTHER_CLAN_FOR_24_HOURS); } // remove combat flag before teleporting if (player.getInventory().getItemByItemId(9819) != null) { final Fort fort = FortManager.getInstance().getFort(player); if (fort != null) { FortSiegeManager.getInstance().dropCombatFlag(player, fort.getResidenceId()); } else { final int slot = player.getInventory().getSlotFromItem(player.getInventory().getItemByItemId(9819)); player.getInventory().unEquipItemInBodySlot(slot); player.destroyItem("CombatFlag", player.getInventory().getItemByItemId(9819), null, true); } } // Attacker or spectator logging in to a siege zone. // Actually should be checked for inside castle only? if (!player.canOverrideCond(PlayerCondOverride.ZONE_CONDITIONS) && player.isInsideZone(ZoneId.SIEGE) && (!player.isInSiege() || (player.getSiegeState() < 2))) { player.teleToLocation(TeleportWhereType.TOWN); } // Remove demonic weapon if character is not cursed weapon equipped. if ((player.getInventory().getItemByItemId(8190) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Zariche", player.getInventory().getItemByItemId(8190), null, true); } if ((player.getInventory().getItemByItemId(8689) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Akamanah", player.getInventory().getItemByItemId(8689), null, true); } if (Config.ALLOW_MAIL) { if (MailManager.getInstance().hasUnreadPost(player)) { client.sendPacket(ExNoticePostArrived.valueOf(false)); } } if (Config.WELCOME_MESSAGE_ENABLED) { player.sendPacket(new ExShowScreenMessage(Config.WELCOME_MESSAGE_TEXT, Config.WELCOME_MESSAGE_TIME)); } final int birthday = player.checkBirthDay(); if (birthday == 0) { player.sendPacket(SystemMessageId.HAPPY_BIRTHDAY_ALEGRIA_HAS_SENT_YOU_A_BIRTHDAY_GIFT); // player.sendPacket(new ExBirthdayPopup()); Removed in H5? } else if (birthday != -1) { sm = new SystemMessage(SystemMessageId.THERE_ARE_S1_DAYS_REMAINING_UNTIL_YOUR_BIRTHDAY_ON_YOUR_BIRTHDAY_YOU_WILL_RECEIVE_A_GIFT_THAT_ALEGRIA_HAS_CAREFULLY_PREPARED); sm.addString(Integer.toString(birthday)); player.sendPacket(sm); } if (!player.getPremiumItemList().isEmpty()) { player.sendPacket(ExNotifyPremiumItem.STATIC_PACKET); } if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.STORE_OFFLINE_TRADE_IN_REALTIME) { OfflineTraderTable.onTransaction(player, true, false); } // Check if expoff is enabled. if (player.getVariables().getBoolean("EXPOFF", false)) { player.disableExpGain(); player.sendMessage("Experience gain is disabled."); } player.broadcastUserInfo(); if (BeautyShopData.getInstance().hasBeautyData(player.getRace(), player.getAppearance().getSexType())) { player.sendPacket(new ExBeautyItemList(player)); } // Disabled to give a more Classic feeling. // if (Config.ENABLE_WORLD_CHAT) // { // player.sendPacket(new ExWorldChatCnt(player)); // } player.sendPacket(new ExConnectedTimeAndGettableReward(player)); player.sendPacket(new ExOneDayReceiveRewardList(player, true)); // Handle soulshots, disable all on EnterWorld player.sendPacket(new ExAutoSoulShot(0, true, 0)); player.sendPacket(new ExAutoSoulShot(0, true, 1)); player.sendPacket(new ExAutoSoulShot(0, true, 2)); player.sendPacket(new ExAutoSoulShot(0, true, 3)); // Fix for equipped item skills if (!player.getEffectList().getCurrentAbnormalVisualEffects().isEmpty()) { player.updateAbnormalVisualEffects(); } if (Config.ENABLE_ATTENDANCE_REWARDS) { ThreadPool.schedule(() -> { // Check if player can receive reward today. final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo(); if (attendanceInfo.isRewardAvailable()) { final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1; player.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true)); player.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready."); player.sendMessage("Click on General Menu -> Attendance Check."); if (Config.ATTENDANCE_POPUP_WINDOW) { player.sendPacket(new ExVipAttendanceItemList(player)); } } }, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000); if (Config.ATTENDANCE_POPUP_START) { player.sendPacket(new ExVipAttendanceItemList(player)); } } // Delayed HWID checks. if (Config.HARDWARE_INFO_ENABLED) { ThreadPool.schedule(() -> { // Generate trace string. final StringBuilder sb = new StringBuilder(); for (int[] i : _tracert) { for (int j : i) { sb.append(j); sb.append("."); } } final String trace = sb.toString(); // Get hardware info from client. ClientHardwareInfoHolder hwInfo = client.getHardwareInfo(); if (hwInfo != null) { hwInfo.store(player); TRACE_HWINFO.put(trace, hwInfo); } else { // Get hardware info from stored tracert map. hwInfo = TRACE_HWINFO.get(trace); if (hwInfo != null) { hwInfo.store(player); client.setHardwareInfo(hwInfo); } // Get hardware info from account variables. else { final String storedInfo = player.getAccountVariables().getString(AccountVariables.HWID, ""); if (!storedInfo.isEmpty()) { hwInfo = new ClientHardwareInfoHolder(storedInfo); TRACE_HWINFO.put(trace, hwInfo); client.setHardwareInfo(hwInfo); } } } // Banned? if ((hwInfo != null) && PunishmentManager.getInstance().hasPunishment(hwInfo.getMacAddress(), PunishmentAffect.HWID, PunishmentType.BAN)) { Disconnection.of(client).defaultSequence(false); return; } // Check max players. if (Config.KICK_MISSING_HWID && (hwInfo == null)) { Disconnection.of(client).defaultSequence(false); } else if (Config.MAX_PLAYERS_PER_HWID > 0) { int count = 0; for (PlayerInstance plr : World.getInstance().getPlayers()) { if (plr.isOnlineInt() == 1) { final ClientHardwareInfoHolder hwi = plr.getClient().getHardwareInfo(); if ((hwi != null) && hwi.equals(hwInfo)) { count++; } } } if (count >= Config.MAX_PLAYERS_PER_HWID) { Disconnection.of(client).defaultSequence(false); } } }, 5000); } // Chat banned icon. ThreadPool.schedule(() -> { if (player.isChatBanned()) { player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.NO_CHAT); } }, 5500); } /** * @param player */ private void notifyClanMembers(PlayerInstance player) { final Clan clan = player.getClan(); if (clan != null) { clan.getClanMember(player.getObjectId()).setPlayerInstance(player); final SystemMessage msg = new SystemMessage(SystemMessageId.CLAN_MEMBER_S1_HAS_LOGGED_INTO_GAME); msg.addString(player.getName()); clan.broadcastToOtherOnlineMembers(msg, player); clan.broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(player), player); } } /** * @param player */ private void notifySponsorOrApprentice(PlayerInstance player) { if (player.getSponsor() != 0) { final PlayerInstance sponsor = World.getInstance().getPlayer(player.getSponsor()); if (sponsor != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_APPRENTICE_S1_HAS_LOGGED_IN); msg.addString(player.getName()); sponsor.sendPacket(msg); } } else if (player.getApprentice() != 0) { final PlayerInstance apprentice = World.getInstance().getPlayer(player.getApprentice()); if (apprentice != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_SPONSOR_C1_HAS_LOGGED_IN); msg.addString(player.getName()); apprentice.sendPacket(msg); } } } } А стал таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import org.strixplatform.StrixPlatform; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.l2jmobius.Config; import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.OfflineTraderTable; import org.l2jmobius.gameserver.data.xml.AdminData; import org.l2jmobius.gameserver.data.xml.BeautyShopData; import org.l2jmobius.gameserver.data.xml.ClanHallData; import org.l2jmobius.gameserver.data.xml.SkillTreeData; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.SubclassInfoType; import org.l2jmobius.gameserver.enums.TeleportWhereType; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.instancemanager.FortSiegeManager; import org.l2jmobius.gameserver.instancemanager.InstanceManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.PetitionManager; import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.instancemanager.events.GameEvent; import org.l2jmobius.gameserver.model.PlayerCondOverride; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.quest.Quest; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.sevensigns.SevenSigns; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.FortSiege; import org.l2jmobius.gameserver.model.siege.Siege; import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; import org.l2jmobius.gameserver.model.skills.CommonSkill; import org.l2jmobius.gameserver.model.variables.AccountVariables; import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.Disconnection; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.Die; import org.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import org.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; import org.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList; import org.l2jmobius.gameserver.network.serverpackets.ExBeautyItemList; import org.l2jmobius.gameserver.network.serverpackets.ExGetBookMarkInfoPacket; import org.l2jmobius.gameserver.network.serverpackets.ExNoticePostArrived; import org.l2jmobius.gameserver.network.serverpackets.ExNotifyPremiumItem; import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeCount; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeWaitingListAlarm; import org.l2jmobius.gameserver.network.serverpackets.ExQuestItemList; import org.l2jmobius.gameserver.network.serverpackets.ExRotation; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.ExStorageMaxCount; import org.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo; import org.l2jmobius.gameserver.network.serverpackets.ExUnReadMailCount; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoEquipSlot; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight; import org.l2jmobius.gameserver.network.serverpackets.ExVitalityEffectInfo; import org.l2jmobius.gameserver.network.serverpackets.ExVoteSystemInfo; import org.l2jmobius.gameserver.network.serverpackets.HennaInfo; import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListAll; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListUpdate; import org.l2jmobius.gameserver.network.serverpackets.PledgeSkillList; import org.l2jmobius.gameserver.network.serverpackets.QuestList; import org.l2jmobius.gameserver.network.serverpackets.ServerToClientCommunicationPacket; import org.l2jmobius.gameserver.network.serverpackets.ShortCutInit; import org.l2jmobius.gameserver.network.serverpackets.SkillCoolTime; import org.l2jmobius.gameserver.network.serverpackets.SkillList; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExConnectedTimeAndGettableReward; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList; import org.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList; import org.l2jmobius.gameserver.util.BuilderUtil; /** * Enter World Packet Handler * <p> * <p> * 0000: 03 * <p> * packet format rev87 bddddbdcccccccccccccccccccc * <p> */ public class EnterWorld implements IClientIncomingPacket { private static final Map<String, ClientHardwareInfoHolder> TRACE_HWINFO = new ConcurrentHashMap<>(); private final int[][] _tracert = new int[5][4]; @Override public boolean read(GameClient client, PacketReader packet) { for (int i = 0; i < 5; i++) { for (int o = 0; o < 4; o++) { _tracert[i][o] = packet.readC(); } } packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readB(64); // Unknown Byte Array packet.readD(); // Unknown Value return true; } @Override public void run(GameClient client) { final PlayerInstance player = client.getPlayer(); if(StrixPlatform.getInstance().isPlatformEnabled()) { player.sendPacket(new ServerToClientCommunicationPacket("your text")); } if (player == null) { LOGGER.warning("EnterWorld failed! player returned 'null'."); Disconnection.of(client).defaultSequence(false); return; } client.setConnectionState(ConnectionState.IN_GAME); final String[] adress = new String[5]; for (int i = 0; i < 5; i++) { adress[i] = _tracert[i][0] + "." + _tracert[i][1] + "." + _tracert[i][2] + "." + _tracert[i][3]; } LoginServerThread.getInstance().sendClientTracert(player.getAccountName(), adress); client.setClientTracert(_tracert); player.broadcastUserInfo(); // Restore to instanced area if enabled if (Config.RESTORE_PLAYER_INSTANCE) { final PlayerVariables vars = player.getVariables(); final Instance instance = InstanceManager.getInstance().getPlayerInstance(player, false); if ((instance != null) && (instance.getId() == vars.getInt("INSTANCE_RESTORE", 0))) { player.setInstance(instance); } vars.remove("INSTANCE_RESTORE"); } player.updatePvpTitleAndColor(false); // Apply special GM properties to the GM when entering if (player.isGM()) { gmStartupProcess: { if (Config.GM_STARTUP_BUILDER_HIDE && AdminData.getInstance().hasAccess("admin_hide", player.getAccessLevel())) { BuilderUtil.setHiding(player, true); BuilderUtil.sendSysMessage(player, "hide is default for builder."); BuilderUtil.sendSysMessage(player, "FriendAddOff is default for builder."); BuilderUtil.sendSysMessage(player, "whisperoff is default for builder."); // It isn't recommend to use the below custom L2J GMStartup functions together with retail-like GMStartupBuilderHide, so breaking the process at that stage. break gmStartupProcess; } if (Config.GM_STARTUP_INVULNERABLE && AdminData.getInstance().hasAccess("admin_invul", player.getAccessLevel())) { player.setInvul(true); } if (Config.GM_STARTUP_INVISIBLE && AdminData.getInstance().hasAccess("admin_invisible", player.getAccessLevel())) { player.setInvisible(true); player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.STEALTH); } if (Config.GM_STARTUP_SILENCE && AdminData.getInstance().hasAccess("admin_silence", player.getAccessLevel())) { player.setSilenceMode(true); } if (Config.GM_STARTUP_DIET_MODE && AdminData.getInstance().hasAccess("admin_diet", player.getAccessLevel())) { player.setDietMode(true); player.refreshOverloaded(true); } } if (Config.GM_STARTUP_AUTO_LIST && AdminData.getInstance().hasAccess("admin_gmliston", player.getAccessLevel())) { AdminData.getInstance().addGm(player, false); } else { AdminData.getInstance().addGm(player, true); } if (Config.GM_GIVE_SPECIAL_SKILLS) { SkillTreeData.getInstance().addSkills(player, false); } if (Config.GM_GIVE_SPECIAL_AURA_SKILLS) { SkillTreeData.getInstance().addSkills(player, true); } } // Chat banned icon. if (player.isChatBanned()) { player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.NO_CHAT); } // Set dead status if applies if (player.getCurrentHp() < 0.5) { player.setDead(true); } boolean showClanNotice = false; // Clan related checks are here final Clan clan = player.getClan(); if (clan != null) { notifyClanMembers(player); notifySponsorOrApprentice(player); for (Siege siege : SiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getCastle().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getCastle().getResidenceId()); } } for (FortSiege siege : FortSiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getFort().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getFort().getResidenceId()); } } // Residential skills support if (player.getClan().getCastleId() > 0) { CastleManager.getInstance().getCastleByOwner(clan).giveResidentialSkills(player); } if (player.getClan().getFortId() > 0) { FortManager.getInstance().getFortByOwner(clan).giveResidentialSkills(player); } showClanNotice = clan.isNoticeEnabled(); } // Updating Seal of Strife Buff/Debuff if (SevenSigns.getInstance().isSealValidationPeriod() && (SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_STRIFE) != SevenSigns.CABAL_NULL)) { final int cabal = SevenSigns.getInstance().getPlayerCabal(player.getObjectId()); if (cabal != SevenSigns.CABAL_NULL) { if (cabal == SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_STRIFE)) { player.addSkill(CommonSkill.THE_VICTOR_OF_WAR.getSkill()); } else { player.addSkill(CommonSkill.THE_VANQUISHED_OF_WAR.getSkill()); } } } else { player.removeSkill(CommonSkill.THE_VICTOR_OF_WAR.getSkill()); player.removeSkill(CommonSkill.THE_VANQUISHED_OF_WAR.getSkill()); } if (Config.ENABLE_VITALITY) { player.sendPacket(new ExVitalityEffectInfo(player)); } // Send Macro List player.getMacros().sendAllMacros(); // Send Teleport Bookmark List client.sendPacket(new ExGetBookMarkInfoPacket(player)); // Send Item List client.sendPacket(new ItemList(player, false)); // Send Quest Item List client.sendPacket(new ExQuestItemList(player)); // Send Adena and Inventory Count client.sendPacket(new ExAdenaInvenCount(player)); // Send Shortcuts client.sendPacket(new ShortCutInit(player)); // Send Action list player.sendPacket(ExBasicActionList.STATIC_PACKET); // Send blank skill list player.sendPacket(new SkillList()); // Send GG check // player.queryGameGuard(); // Send Dye Information player.sendPacket(new HennaInfo(player)); // Send Skill list player.sendSkillList(); // Send EtcStatusUpdate player.sendPacket(new EtcStatusUpdate(player)); // Clan packets if (clan != null) { clan.broadcastToOnlineMembers(new PledgeShowMemberListUpdate(player)); PledgeShowMemberListAll.sendAllTo(player); clan.broadcastToOnlineMembers(new ExPledgeCount(clan)); player.sendPacket(new PledgeSkillList(clan)); final ClanHall ch = ClanHallData.getInstance().getClanHallByClan(clan); if ((ch != null) && (ch.getCostFailDay() > 0)) { final SystemMessage sm = new SystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW); sm.addInt(ch.getLease()); player.sendPacket(sm); } } else { player.sendPacket(ExPledgeWaitingListAlarm.STATIC_PACKET); } // Send SubClass Info player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NO_CHANGES)); // Send Inventory Info player.sendPacket(new ExUserInfoInvenWeight(player)); // Send Adena / Inventory Count Info player.sendPacket(new ExAdenaInvenCount(player)); // Send Equipped Items player.sendPacket(new ExUserInfoEquipSlot(player)); // Send Unread Mail Count if (MailManager.getInstance().hasUnreadPost(player)) { player.sendPacket(new ExUnReadMailCount(player)); } // Faction System if (Config.FACTION_SYSTEM_ENABLED) { if (player.isGood()) { player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000)); } else if (player.isEvil()) { player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000)); } } Quest.playerEnter(player); // Send Quest List player.sendPacket(new QuestList(player)); if (Config.PLAYER_SPAWN_PROTECTION > 0) { player.setSpawnProtection(true); } player.spawnMe(player.getX(), player.getY(), player.getZ()); player.sendPacket(new ExRotation(player.getObjectId(), player.getHeading())); player.getInventory().applyItemSkills(); if (GameEvent.isParticipant(player)) { GameEvent.restorePlayerEventStatus(player); } if (player.isCursedWeaponEquipped()) { CursedWeaponsManager.getInstance().getCursedWeapon(player.getCursedWeaponEquippedId()).cursedOnLogin(); } if (Config.PC_CAFE_ENABLED) { if (player.getPcCafePoints() > 0) { player.sendPacket(new ExPCCafePointInfo(player.getPcCafePoints(), 0, 1)); } else { player.sendPacket(new ExPCCafePointInfo()); } } // Expand Skill player.sendPacket(new ExStorageMaxCount(player)); // Friend list client.sendPacket(new L2FriendList(player)); SystemMessage sm = new SystemMessage(SystemMessageId.YOUR_FRIEND_S1_JUST_LOGGED_IN); sm.addString(player.getName()); for (int id : player.getFriendList()) { final WorldObject obj = World.getInstance().findObject(id); if (obj != null) { obj.sendPacket(sm); } } player.sendPacket(SystemMessageId.WELCOME_TO_THE_WORLD_OF_LINEAGE_II); SevenSigns.getInstance().sendCurrentPeriodMsg(player); AnnouncementsTable.getInstance().showAnnouncements(player); if ((Config.SERVER_RESTART_SCHEDULE_ENABLED) && (Config.SERVER_RESTART_SCHEDULE_MESSAGE)) { player.sendPacket(new CreatureSay(null, ChatType.BATTLEFIELD, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); } if (showClanNotice) { final NpcHtmlMessage notice = new NpcHtmlMessage(); notice.setFile(player, "data/html/clanNotice.htm"); notice.replace("%clan_name%", player.getClan().getName()); notice.replace("%notice_text%", player.getClan().getNotice().replaceAll("\r\n", "<br>")); notice.disableValidation(); client.sendPacket(notice); } else if (Config.SERVER_NEWS) { final String serverNews = HtmCache.getInstance().getHtm(player, "data/html/servnews.htm"); if (serverNews != null) { client.sendPacket(new NpcHtmlMessage(serverNews)); } } if (Config.PETITIONING_ALLOWED) { PetitionManager.getInstance().checkPetitionMessages(player); } if (player.isAlikeDead()) // dead or fake dead { // no broadcast needed since the player will already spawn dead to others client.sendPacket(new Die(player)); } player.onPlayerEnter(); client.sendPacket(new SkillCoolTime(player)); client.sendPacket(new ExVoteSystemInfo(player)); for (ItemInstance item : player.getInventory().getItems()) { if (item.isTimeLimitedItem()) { item.scheduleLifeTimeTask(); } if (item.isShadowItem() && item.isEquipped()) { item.decreaseMana(false); } } for (ItemInstance whItem : player.getWarehouse().getItems()) { if (whItem.isTimeLimitedItem()) { whItem.scheduleLifeTimeTask(); } } if (DimensionalRiftManager.getInstance().checkIfInRiftZone(player.getX(), player.getY(), player.getZ(), false)) { DimensionalRiftManager.getInstance().teleportToWaitingRoom(player); } if (player.getClanJoinExpiryTime() > Chronos.currentTimeMillis()) { player.sendPacket(SystemMessageId.YOU_HAVE_RECENTLY_BEEN_DISMISSED_FROM_A_CLAN_YOU_ARE_NOT_ALLOWED_TO_JOIN_ANOTHER_CLAN_FOR_24_HOURS); } // remove combat flag before teleporting if (player.getInventory().getItemByItemId(9819) != null) { final Fort fort = FortManager.getInstance().getFort(player); if (fort != null) { FortSiegeManager.getInstance().dropCombatFlag(player, fort.getResidenceId()); } else { final int slot = player.getInventory().getSlotFromItem(player.getInventory().getItemByItemId(9819)); player.getInventory().unEquipItemInBodySlot(slot); player.destroyItem("CombatFlag", player.getInventory().getItemByItemId(9819), null, true); } } // Attacker or spectator logging in to a siege zone. // Actually should be checked for inside castle only? if (!player.canOverrideCond(PlayerCondOverride.ZONE_CONDITIONS) && player.isInsideZone(ZoneId.SIEGE) && (!player.isInSiege() || (player.getSiegeState() < 2))) { player.teleToLocation(TeleportWhereType.TOWN); } // Remove demonic weapon if character is not cursed weapon equipped. if ((player.getInventory().getItemByItemId(8190) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Zariche", player.getInventory().getItemByItemId(8190), null, true); } if ((player.getInventory().getItemByItemId(8689) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Akamanah", player.getInventory().getItemByItemId(8689), null, true); } if (Config.ALLOW_MAIL) { if (MailManager.getInstance().hasUnreadPost(player)) { client.sendPacket(ExNoticePostArrived.valueOf(false)); } } if (Config.WELCOME_MESSAGE_ENABLED) { player.sendPacket(new ExShowScreenMessage(Config.WELCOME_MESSAGE_TEXT, Config.WELCOME_MESSAGE_TIME)); } final int birthday = player.checkBirthDay(); if (birthday == 0) { player.sendPacket(SystemMessageId.HAPPY_BIRTHDAY_ALEGRIA_HAS_SENT_YOU_A_BIRTHDAY_GIFT); // player.sendPacket(new ExBirthdayPopup()); Removed in H5? } else if (birthday != -1) { sm = new SystemMessage(SystemMessageId.THERE_ARE_S1_DAYS_REMAINING_UNTIL_YOUR_BIRTHDAY_ON_YOUR_BIRTHDAY_YOU_WILL_RECEIVE_A_GIFT_THAT_ALEGRIA_HAS_CAREFULLY_PREPARED); sm.addString(Integer.toString(birthday)); player.sendPacket(sm); } if (!player.getPremiumItemList().isEmpty()) { player.sendPacket(ExNotifyPremiumItem.STATIC_PACKET); } if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.STORE_OFFLINE_TRADE_IN_REALTIME) { OfflineTraderTable.onTransaction(player, true, false); } // Check if expoff is enabled. if (player.getVariables().getBoolean("EXPOFF", false)) { player.disableExpGain(); player.sendMessage("Experience gain is disabled."); } player.broadcastUserInfo(); if (BeautyShopData.getInstance().hasBeautyData(player.getRace(), player.getAppearance().getSexType())) { player.sendPacket(new ExBeautyItemList(player)); } // Disabled to give a more Classic feeling. // if (Config.ENABLE_WORLD_CHAT) // { // player.sendPacket(new ExWorldChatCnt(player)); // } player.sendPacket(new ExConnectedTimeAndGettableReward(player)); player.sendPacket(new ExOneDayReceiveRewardList(player, true)); // Handle soulshots, disable all on EnterWorld player.sendPacket(new ExAutoSoulShot(0, true, 0)); player.sendPacket(new ExAutoSoulShot(0, true, 1)); player.sendPacket(new ExAutoSoulShot(0, true, 2)); player.sendPacket(new ExAutoSoulShot(0, true, 3)); // Fix for equipped item skills if (!player.getEffectList().getCurrentAbnormalVisualEffects().isEmpty()) { player.updateAbnormalVisualEffects(); } if (Config.ENABLE_ATTENDANCE_REWARDS) { ThreadPool.schedule(() -> { // Check if player can receive reward today. final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo(); if (attendanceInfo.isRewardAvailable()) { final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1; player.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true)); player.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready."); player.sendMessage("Click on General Menu -> Attendance Check."); if (Config.ATTENDANCE_POPUP_WINDOW) { player.sendPacket(new ExVipAttendanceItemList(player)); } } }, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000); if (Config.ATTENDANCE_POPUP_START) { player.sendPacket(new ExVipAttendanceItemList(player)); } } if (Config.HARDWARE_INFO_ENABLED) { ThreadPool.schedule(() -> { // Generate trace string. final StringBuilder sb = new StringBuilder(); for (int[] i : _tracert) { for (int j : i) { sb.append(j); sb.append("."); } } final String trace = sb.toString(); // Get hardware info from client. ClientHardwareInfoHolder hwInfo = client.getHardwareInfo(); if (hwInfo != null) { hwInfo.store(player); TRACE_HWINFO.put(trace, hwInfo); } else { // Get hardware info from stored tracert map. hwInfo = TRACE_HWINFO.get(trace); if (hwInfo != null) { hwInfo.store(player); client.setHardwareInfo(hwInfo); } // Get hardware info from account variables. else { final String storedInfo = player.getAccountVariables().getString(AccountVariables.HWID, ""); if (!storedInfo.isEmpty()) { hwInfo = new ClientHardwareInfoHolder(storedInfo); TRACE_HWINFO.put(trace, hwInfo); client.setHardwareInfo(hwInfo); } } } // Check max players. if (Config.KICK_MISSING_HWID && (hwInfo == null)) { Disconnection.of(client).defaultSequence(false); } else if (Config.MAX_PLAYERS_PER_HWID > 0) { int count = 0; for (PlayerInstance plr : World.getInstance().getPlayers()) { if ((plr.isOnlineInt() == 1) && (plr.getClient().getHardwareInfo().equals(hwInfo))) { count++; } } if (count >= Config.MAX_PLAYERS_PER_HWID) { Disconnection.of(client).defaultSequence(false); } } }, 5000); } } /** * @param player */ private void notifyClanMembers(PlayerInstance player) { final Clan clan = player.getClan(); if (clan != null) { clan.getClanMember(player.getObjectId()).setPlayerInstance(player); final SystemMessage msg = new SystemMessage(SystemMessageId.CLAN_MEMBER_S1_HAS_LOGGED_INTO_GAME); msg.addString(player.getName()); clan.broadcastToOtherOnlineMembers(msg, player); clan.broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(player), player); } } /** * @param player */ private void notifySponsorOrApprentice(PlayerInstance player) { if (player.getSponsor() != 0) { final PlayerInstance sponsor = World.getInstance().getPlayer(player.getSponsor()); if (sponsor != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_APPRENTICE_S1_HAS_LOGGED_IN); msg.addString(player.getName()); sponsor.sendPacket(msg); } } else if (player.getApprentice() != 0) { final PlayerInstance apprentice = World.getInstance().getPlayer(player.getApprentice()); if (apprentice != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_SPONSOR_C1_HAS_LOGGED_IN); msg.addString(player.getName()); apprentice.sendPacket(msg); } } } } Файл GameClient.java был таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network; import java.net.InetAddress; import java.net.InetSocketAddress; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; import org.l2jmobius.Config; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.network.ChannelInboundHandler; import org.l2jmobius.commons.network.ICrypt; import org.l2jmobius.commons.network.IIncomingPacket; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.data.sql.ClanTable; import org.l2jmobius.gameserver.data.xml.SecondaryAuthData; import org.l2jmobius.gameserver.enums.CharacterDeleteFailType; import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.MentorManager; import org.l2jmobius.gameserver.model.CharSelectInfoPackage; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld; import org.l2jmobius.gameserver.network.serverpackets.NpcInfo; import org.l2jmobius.gameserver.network.serverpackets.NpcSay; import org.l2jmobius.gameserver.network.serverpackets.ServerClose; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.security.SecondaryPasswordAuth; import org.l2jmobius.gameserver.util.FloodProtectors; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; /** * Represents a client connected on Game Server. * @author KenM */ public class GameClient extends ChannelInboundHandler<GameClient> { protected static final Logger LOGGER = Logger.getLogger(GameClient.class.getName()); protected static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private final FloodProtectors _floodProtectors = new FloodProtectors(this); private final ReentrantLock _playerLock = new ReentrantLock(); private final Crypt _crypt = new Crypt(); private InetAddress _addr; private Channel _channel; private String _accountName; private SessionKey _sessionId; private PlayerInstance _player; private SecondaryPasswordAuth _secondaryAuth; private ClientHardwareInfoHolder _hardwareInfo; private List<CharSelectInfoPackage> _charSlotMapping = null; private volatile boolean _isDetached = false; private boolean _isAuthedGG; private boolean _protocolOk; private int _protocolVersion; private int[][] _trace; @Override public void channelActive(ChannelHandlerContext ctx) { super.channelActive(ctx); setConnectionState(ConnectionState.CONNECTED); final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); _addr = address.getAddress(); _channel = ctx.channel(); LOGGER_ACCOUNTING.finer("Client Connected: " + ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) { LOGGER_ACCOUNTING.finer("Client Disconnected: " + ctx.channel()); LoginServerThread.getInstance().sendLogout(getAccountName()); if ((_player == null) || !_player.isInOfflineMode()) { Disconnection.of(this).onDisconnection(); } } @Override protected void channelRead0(ChannelHandlerContext ctx, IIncomingPacket<GameClient> packet) { try { packet.run(this); } catch (Exception e) { LOGGER.log(Level.WARNING, "Exception for: " + toString() + " on packet.run: " + packet.getClass().getSimpleName(), e); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { } public void closeNow() { if (_channel != null) { _channel.close(); } } public void close(IClientOutgoingPacket packet) { sendPacket(packet); closeNow(); } public void close(boolean toLoginScreen) { close(toLoginScreen ? ServerClose.STATIC_PACKET : LeaveWorld.STATIC_PACKET); } public Channel getChannel() { return _channel; } public byte[] enableCrypt() { final byte[] key = BlowFishKeygen.getRandomKey(); _crypt.setKey(key); return key; } /** * For loaded offline traders returns localhost address. * @return cached connection IP address, for checking detached clients. */ public InetAddress getConnectionAddress() { return _addr; } public PlayerInstance getPlayer() { return _player; } public void setPlayer(PlayerInstance player) { _player = player; } public ReentrantLock getPlayerLock() { return _playerLock; } public FloodProtectors getFloodProtectors() { return _floodProtectors; } public void setGameGuardOk(boolean value) { _isAuthedGG = value; } public boolean isAuthedGG() { return _isAuthedGG; } public void setAccountName(String activeChar) { _accountName = activeChar; if (SecondaryAuthData.getInstance().isEnabled()) { _secondaryAuth = new SecondaryPasswordAuth(this); } } public String getAccountName() { return _accountName; } public void setSessionId(SessionKey sk) { _sessionId = sk; } public SessionKey getSessionId() { return _sessionId; } public void sendPacket(IClientOutgoingPacket packet) { if (_isDetached || (packet == null)) { return; } // TODO: Set as parameter to packets used? if (Config.MULTILANG_ENABLE && (_player != null)) { final String lang = _player.getLang(); if ((lang != null) && !lang.equals("en")) { if (packet instanceof SystemMessage) { ((SystemMessage) packet).setLang(lang); } else if (packet instanceof NpcSay) { ((NpcSay) packet).setLang(lang); } else if (packet instanceof ExShowScreenMessage) { ((ExShowScreenMessage) packet).setLang(lang); } else if (packet instanceof NpcInfo) { ((NpcInfo) packet).setLang(lang); } } } // Write into the channel. _channel.writeAndFlush(packet); // Run packet implementation. packet.runImpl(_player); } /** * @param smId */ public void sendPacket(SystemMessageId smId) { sendPacket(new SystemMessage(smId)); } public boolean isDetached() { return _isDetached; } public void setDetached(boolean value) { _isDetached = value; } /** * Method to handle character deletion * @param characterSlot * @return a byte: * <li>-1: Error: No char was found for such charslot, caught exception, etc... * <li>0: character is not member of any clan, proceed with deletion * <li>1: character is member of a clan, but not clan leader * <li>2: character is clan leader */ public CharacterDeleteFailType markToDeleteChar(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return CharacterDeleteFailType.UNKNOWN; } if (MentorManager.getInstance().isMentor(objectId)) { return CharacterDeleteFailType.MENTOR; } else if (MentorManager.getInstance().isMentee(objectId)) { return CharacterDeleteFailType.MENTEE; } else if (CommissionManager.getInstance().hasCommissionItems(objectId)) { return CharacterDeleteFailType.COMMISSION; } else if (MailManager.getInstance().getMailsInProgress(objectId) > 0) { return CharacterDeleteFailType.MAIL; } else { final int clanId = CharNameTable.getInstance().getClassIdById(objectId); if (clanId > 0) { final Clan clan = ClanTable.getInstance().getClan(clanId); if (clan != null) { if (clan.getLeaderId() == objectId) { return CharacterDeleteFailType.PLEDGE_MASTER; } return CharacterDeleteFailType.PLEDGE_MEMBER; } } } if (Config.DELETE_DAYS == 0) { deleteCharByObjId(objectId); } else { try (Connection con = DatabaseFactory.getConnection(); PreparedStatement ps2 = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?")) { ps2.setLong(1, Chronos.currentTimeMillis() + (Config.DELETE_DAYS * 86400000)); // 24*60*60*1000 = 86400000 ps2.setInt(2, objectId); ps2.execute(); } catch (SQLException e) { LOGGER.log(Level.WARNING, "Failed to update char delete time: ", e); } } LOGGER_ACCOUNTING.info("Delete, " + objectId + ", " + this); return CharacterDeleteFailType.NONE; } public void restore(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return; } try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?")) { statement.setInt(1, objectId); statement.execute(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error restoring character.", e); } LOGGER_ACCOUNTING.info("Restore, " + objectId + ", " + this); } public static void deleteCharByObjId(int objid) { if (objid < 0) { return; } CharNameTable.getInstance().removeName(objid); try (Connection con = DatabaseFactory.getConnection()) { try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_contacts WHERE charId=? OR contactId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR friendId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_hennas WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_macroses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_quests WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_recipebook WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_shortcuts WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills_save WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_subclasses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM heroes WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variations WHERE itemId IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variables WHERE id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM items WHERE owner_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_reco_bonus WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_instance_time WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM characters WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error deleting character.", e); } } public PlayerInstance load(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return null; } PlayerInstance player = World.getInstance().getPlayer(objectId); if (player != null) { // exploit prevention, should not happens in normal way if (player.isOnlineInt() == 1) { LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + _accountName); } if (player.getClient() != null) { Disconnection.of(player).defaultSequence(false); } else { player.storeMe(); player.deleteMe(); } return null; } player = PlayerInstance.load(objectId); if (player == null) { LOGGER.severe("Could not restore in slot: " + characterSlot); } return player; } public void setCharSelection(List<CharSelectInfoPackage> characters) { _charSlotMapping = characters; } public CharSelectInfoPackage getCharSelection(int charslot) { if ((_charSlotMapping == null) || (charslot < 0) || (charslot >= _charSlotMapping.size())) { return null; } return _charSlotMapping.get(charslot); } public SecondaryPasswordAuth getSecondaryAuth() { return _secondaryAuth; } /** * @param characterSlot * @return */ private int getObjectIdForSlot(int characterSlot) { final CharSelectInfoPackage info = getCharSelection(characterSlot); if (info == null) { LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot."); return -1; } return info.getObjectId(); } /** * Produces the best possible string representation of this client. */ @Override public String toString() { try { final InetAddress address = _addr; final ConnectionState state = (ConnectionState) getConnectionState(); switch (state) { case CONNECTED: { return "[IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case AUTHENTICATED: { return "[Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case ENTERING: case IN_GAME: { return "[Character: " + (_player == null ? "disconnected" : _player.getName() + "[" + _player.getObjectId() + "]") + " - Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } default: { throw new IllegalStateException("Missing state on switch"); } } } catch (NullPointerException e) { return "[Character read failed due to disconnect]"; } } public void setProtocolVersion(int version) { _protocolVersion = version; } public int getProtocolVersion() { return _protocolVersion; } public boolean isProtocolOk() { return _protocolOk; } public void setProtocolOk(boolean value) { _protocolOk = value; } public void setClientTracert(int[][] tracert) { _trace = tracert; } public int[][] getTrace() { return _trace; } public void sendActionFailed() { sendPacket(ActionFailed.STATIC_PACKET); } public ICrypt getCrypt() { return _crypt; } /** * @return the hardwareInfo */ public ClientHardwareInfoHolder getHardwareInfo() { return _hardwareInfo; } /** * @param hardwareInfo */ public void setHardwareInfo(ClientHardwareInfoHolder hardwareInfo) { _hardwareInfo = hardwareInfo; } } А стал таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network; import java.net.InetAddress; import java.net.InetSocketAddress; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; import org.strixplatform.StrixPlatform; import org.strixplatform.network.IStrixClientData; import org.strixplatform.network.cipher.StrixGameCrypt; import org.strixplatform.utils.StrixClientData; import org.l2jmobius.Config; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.network.ChannelInboundHandler; import org.l2jmobius.commons.network.ICrypt; import org.l2jmobius.commons.network.IIncomingPacket; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.data.sql.ClanTable; import org.l2jmobius.gameserver.data.xml.SecondaryAuthData; import org.l2jmobius.gameserver.enums.CharacterDeleteFailType; import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.MentorManager; import org.l2jmobius.gameserver.model.CharSelectInfoPackage; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld; import org.l2jmobius.gameserver.network.serverpackets.NpcInfo; import org.l2jmobius.gameserver.network.serverpackets.NpcSay; import org.l2jmobius.gameserver.network.serverpackets.ServerClose; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.security.SecondaryPasswordAuth; import org.l2jmobius.gameserver.util.FloodProtectors; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; /** * Represents a client connected on Game Server. * @author KenM */ public class GameClient extends ChannelInboundHandler<GameClient> implements IStrixClientData { protected static final Logger LOGGER = Logger.getLogger(GameClient.class.getName()); protected static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private final FloodProtectors _floodProtectors = new FloodProtectors(this); private final ReentrantLock _playerLock = new ReentrantLock(); //private final Crypt _crypt; private InetAddress _addr; private Channel _channel; private String _accountName; private SessionKey _sessionId; private PlayerInstance _player; private SecondaryPasswordAuth _secondaryAuth; private ClientHardwareInfoHolder _hardwareInfo; private CharSelectInfoPackage[] _charSlotMapping = null; //TODO[K] - Guard section start public StrixCryptImpl _crypt = null; private StrixClientData clientData; //TODO[K] - Guard section end private volatile boolean _isDetached = false; private boolean _isAuthedGG; private boolean _protocolOk; private int _protocolVersion; private int[][] _trace; public GameClient() { _crypt = new StrixCryptImpl(); } @Override public void channelActive(ChannelHandlerContext ctx) { super.channelActive(ctx); setConnectionState(ConnectionState.CONNECTED); final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); _addr = address.getAddress(); _channel = ctx.channel(); LOGGER_ACCOUNTING.finer("Client Connected: " + ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) { LOGGER_ACCOUNTING.finer("Client Disconnected: " + ctx.channel()); LoginServerThread.getInstance().sendLogout(getAccountName()); if ((_player == null) || !_player.isInOfflineMode()) { Disconnection.of(this).onDisconnection(); } } @Override protected void channelRead0(ChannelHandlerContext ctx, IIncomingPacket<GameClient> packet) { try { packet.run(this); } catch (Exception e) { LOGGER.log(Level.WARNING, "Exception for: " + toString() + " on packet.run: " + packet.getClass().getSimpleName(), e); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { } public void closeNow() { if (_channel != null) { _channel.close(); } } public void close(IClientOutgoingPacket packet) { sendPacket(packet); closeNow(); } public void close(boolean toLoginScreen) { close(toLoginScreen ? ServerClose.STATIC_PACKET : LeaveWorld.STATIC_PACKET); } public Channel getChannel() { return _channel; } public byte[] enableCrypt() { final byte[] key = BlowFishKeygen.getRandomKey(); _crypt.setKey(key); return key; } /** * For loaded offline traders returns localhost address. * @return cached connection IP address, for checking detached clients. */ public InetAddress getConnectionAddress() { return _addr; } public PlayerInstance getPlayer() { return _player; } public void setPlayer(PlayerInstance player) { _player = player; } public ReentrantLock getPlayerLock() { return _playerLock; } public FloodProtectors getFloodProtectors() { return _floodProtectors; } public void setGameGuardOk(boolean value) { _isAuthedGG = value; } public boolean isAuthedGG() { return _isAuthedGG; } public void setAccountName(String activeChar) { _accountName = activeChar; if (SecondaryAuthData.getInstance().isEnabled()) { _secondaryAuth = new SecondaryPasswordAuth(this); } } public String getAccountName() { return _accountName; } public void setSessionId(SessionKey sk) { _sessionId = sk; } public SessionKey getSessionId() { return _sessionId; } public void sendPacket(IClientOutgoingPacket packet) { if (_isDetached || (packet == null)) { return; } // TODO: Set as parameter to packets used? if (Config.MULTILANG_ENABLE && (_player != null)) { final String lang = _player.getLang(); if ((lang != null) && !lang.equals("en")) { if (packet instanceof SystemMessage) { ((SystemMessage) packet).setLang(lang); } else if (packet instanceof NpcSay) { ((NpcSay) packet).setLang(lang); } else if (packet instanceof ExShowScreenMessage) { ((ExShowScreenMessage) packet).setLang(lang); } else if (packet instanceof NpcInfo) { ((NpcInfo) packet).setLang(lang); } } } // Write into the channel. _channel.writeAndFlush(packet); // Run packet implementation. packet.runImpl(_player); } /** * @param smId */ public void sendPacket(SystemMessageId smId) { sendPacket(new SystemMessage(smId)); } public boolean isDetached() { return _isDetached; } public void setDetached(boolean value) { _isDetached = value; } /** * Method to handle character deletion * @param characterSlot * @return a byte: * <li>-1: Error: No char was found for such charslot, caught exception, etc... * <li>0: character is not member of any clan, proceed with deletion * <li>1: character is member of a clan, but not clan leader * <li>2: character is clan leader */ public CharacterDeleteFailType markToDeleteChar(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return CharacterDeleteFailType.UNKNOWN; } if (MentorManager.getInstance().isMentor(objectId)) { return CharacterDeleteFailType.MENTOR; } else if (MentorManager.getInstance().isMentee(objectId)) { return CharacterDeleteFailType.MENTEE; } else if (CommissionManager.getInstance().hasCommissionItems(objectId)) { return CharacterDeleteFailType.COMMISSION; } else if (MailManager.getInstance().getMailsInProgress(objectId) > 0) { return CharacterDeleteFailType.MAIL; } else { final int clanId = CharNameTable.getInstance().getClassIdById(objectId); if (clanId > 0) { final Clan clan = ClanTable.getInstance().getClan(clanId); if (clan != null) { if (clan.getLeaderId() == objectId) { return CharacterDeleteFailType.PLEDGE_MASTER; } return CharacterDeleteFailType.PLEDGE_MEMBER; } } } if (Config.DELETE_DAYS == 0) { deleteCharByObjId(objectId); } else { try (Connection con = DatabaseFactory.getConnection(); PreparedStatement ps2 = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?")) { ps2.setLong(1, Chronos.currentTimeMillis() + (Config.DELETE_DAYS * 86400000)); // 24*60*60*1000 = 86400000 ps2.setInt(2, objectId); ps2.execute(); } catch (SQLException e) { LOGGER.log(Level.WARNING, "Failed to update char delete time: ", e); } } LOGGER_ACCOUNTING.info("Delete, " + objectId + ", " + this); return CharacterDeleteFailType.NONE; } public void restore(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return; } try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?")) { statement.setInt(1, objectId); statement.execute(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error restoring character.", e); } LOGGER_ACCOUNTING.info("Restore, " + objectId + ", " + this); } public static void deleteCharByObjId(int objid) { if (objid < 0) { return; } CharNameTable.getInstance().removeName(objid); try (Connection con = DatabaseFactory.getConnection()) { try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_contacts WHERE charId=? OR contactId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR friendId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_hennas WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_macroses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_quests WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_recipebook WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_shortcuts WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills_save WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_subclasses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM heroes WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variations WHERE itemId IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variables WHERE id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM items WHERE owner_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_reco_bonus WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_instance_time WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM characters WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error deleting character.", e); } } public PlayerInstance load(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return null; } PlayerInstance player = World.getInstance().getPlayer(objectId); if (player != null) { // exploit prevention, should not happens in normal way if (player.isOnlineInt() == 1) { LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + _accountName); } if (player.getClient() != null) { Disconnection.of(player).defaultSequence(false); } else { player.storeMe(); player.deleteMe(); } return null; } player = PlayerInstance.load(objectId); if (player == null) { LOGGER.severe("Could not restore in slot: " + characterSlot); } return player; } /** * @param chars */ public void setCharSelection(CharSelectInfoPackage[] chars) { _charSlotMapping = chars; } public CharSelectInfoPackage getCharSelection(int charslot) { if ((_charSlotMapping == null) || (charslot < 0) || (charslot >= _charSlotMapping.length)) { return null; } return _charSlotMapping[charslot]; } public SecondaryPasswordAuth getSecondaryAuth() { return _secondaryAuth; } /** * @param characterSlot * @return */ private int getObjectIdForSlot(int characterSlot) { final CharSelectInfoPackage info = getCharSelection(characterSlot); if (info == null) { LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot."); return -1; } return info.getObjectId(); } /** * Produces the best possible string representation of this client. */ @Override public String toString() { try { final InetAddress address = _addr; final ConnectionState state = (ConnectionState) getConnectionState(); switch (state) { case CONNECTED: { return "[IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case AUTHENTICATED: { return "[Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case ENTERING: case IN_GAME: { return "[Character: " + (_player == null ? "disconnected" : _player.getName() + "[" + _player.getObjectId() + "]") + " - Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } default: { throw new IllegalStateException("Missing state on switch"); } } } catch (NullPointerException e) { return "[Character read failed due to disconnect]"; } } public void setProtocolVersion(int version) { _protocolVersion = version; } public int getProtocolVersion() { return _protocolVersion; } public boolean isProtocolOk() { return _protocolOk; } public void setProtocolOk(boolean value) { _protocolOk = value; } public void setClientTracert(int[][] tracert) { _trace = tracert; } public int[][] getTrace() { return _trace; } public void sendActionFailed() { sendPacket(ActionFailed.STATIC_PACKET); } public ICrypt getCrypt() { return _crypt; } /** * @return the hardwareInfo */ public ClientHardwareInfoHolder getHardwareInfo() { return _hardwareInfo; } /** * @param hardwareInfo */ public void setHardwareInfo(ClientHardwareInfoHolder hardwareInfo) { _hardwareInfo = hardwareInfo; } //TODO[K] - Guard section start private int revision = 0; public String getIpAddr() { return _addr.getHostAddress(); } public int getRevision() { return revision; } public void setRevision(int revision) { this.revision = revision; } @Override public void setStrixClientData(final StrixClientData clientData) { this.clientData = clientData; } @Override public StrixClientData getStrixClientData() { return clientData; } private class StrixCryptImpl extends StrixGameCrypt implements ICrypt { @Override public void encrypt(ByteBuf buf) { byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(0, bytes); super.encrypt(bytes, 0, bytes.length); buf.setBytes(0, bytes); } @Override public void decrypt(ByteBuf buf) { byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(0, bytes); super.decrypt(bytes, 0, bytes.length); buf.setBytes(0, bytes); } } //TODO[K] - Guard section end } ФАйл KeyPacket.java был таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.serverpackets; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.network.OutgoingPackets; public class KeyPacket implements IClientOutgoingPacket { private final byte[] _key; private final int _result; public KeyPacket(byte[] key, int result) { _key = key; _result = result; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.VERSION_CHECK.writeId(packet); packet.writeC(_result); // 0 - wrong protocol, 1 - protocol ok for (int i = 0; i < 8; i++) { packet.writeC(_key[i]); // key } packet.writeD(0x01); packet.writeD(Config.SERVER_ID); // server id packet.writeC(0x01); packet.writeD(0x00); // obfuscation key packet.writeC((Config.SERVER_LIST_TYPE & 0x400) == 0x400 ? 0x01 : 0x00); // isClassic return true; } } А стал таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.serverpackets; import org.strixplatform.StrixPlatform; import org.strixplatform.utils.StrixClientData; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.network.OutgoingPackets; public class KeyPacket implements IClientOutgoingPacket { private final byte[] _key; private final int _result; //TODO[K] - Guard section start private final StrixClientData clientData; // TODO[K] - Strix section end public KeyPacket(byte[] key, int result) { _key = key; _result = result; //TODO[K] - Guard section start this.clientData = null; // TODO[K] - Strix section end } @Override public boolean write(PacketWriter packet) { OutgoingPackets.VERSION_CHECK.writeId(packet); //TODO[K] - Guard section start if(_key == null) { if (StrixPlatform.getInstance().isBackNotificationEnabled() && clientData != null) { packet.writeC(clientData.getServerResponse().ordinal() + 1); } else { packet.writeC(0x00); } return true; } // TODO[K] - Strix section end packet.writeC(_result); // 0 - wrong protocol, 1 - protocol ok for (int i = 0; i < 8; i++) { packet.writeC(_key[i]); // key } packet.writeD(0x01); packet.writeD(Config.SERVER_ID); // server id packet.writeC(0x01); packet.writeD(0x00); // obfuscation key packet.writeC((Config.SERVER_LIST_TYPE & 0x400) == 0x400 ? 0x01 : 0x00); // isClassic return true; } } Файл ProtocolVersion.java был таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import java.util.logging.Logger; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.serverpackets.KeyPacket; /** * @version $Revision: 1.5.2.8.2.8 $ $Date: 2005/04/02 10:43:04 $ */ public class ProtocolVersion implements IClientIncomingPacket { private static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private int _version; @Override public boolean read(GameClient client, PacketReader packet) { _version = packet.readD(); return true; } @Override public void run(GameClient client) { // this packet is never encrypted if (_version == -2) { // this is just a ping attempt from the new C2 client client.closeNow(); } else if (!Config.PROTOCOL_LIST.contains(_version)) { LOGGER_ACCOUNTING.warning("Wrong protocol version " + _version + ", " + client); client.setProtocolOk(false); client.close(new KeyPacket(client.enableCrypt(), 0)); } else { client.sendPacket(new KeyPacket(client.enableCrypt(), 1)); client.setProtocolVersion(_version); client.setProtocolOk(true); } } } А стал таким Спойлер /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import java.util.logging.Logger; import org.strixplatform.StrixPlatform; import org.strixplatform.logging.Log; import org.strixplatform.managers.ClientGameSessionManager; import org.strixplatform.managers.ClientProtocolDataManager; import org.strixplatform.utils.StrixClientData; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.serverpackets.KeyPacket; /** * @version $Revision: 1.5.2.8.2.8 $ $Date: 2005/04/02 10:43:04 $ */ public class ProtocolVersion implements IClientIncomingPacket { private static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private int _version; //TODO[K] - Guard section start private byte[] data; private int dataChecksum; //TODO[K] - Guard section end @Override public boolean read(GameClient client, PacketReader packet) { _version = packet.readD(); //TODO[K] - Guard section start if(StrixPlatform.getInstance().isPlatformEnabled()) { try { if(packet.getReadableBytes() >= StrixPlatform.getInstance().getProtocolVersionDataSize()) { data = new byte[StrixPlatform.getInstance().getClientDataSize()]; data = packet.readB(StrixPlatform.getInstance().getClientDataSize()); dataChecksum = packet.readD(); } } catch(final Exception e) { Log.error("Client [IP=" + client.getIpAddr() + "] used unprotected client. Disconnect..."); client.close(new KeyPacket(null,0)); return false; } } //TODO[K] - Guard section end return true; } @Override public void run(GameClient client) { // this packet is never encrypted if (_version == -2) { // this is just a ping attempt from the new C2 client client.closeNow(); } else if (!Config.PROTOCOL_LIST.contains(_version)) { LOGGER_ACCOUNTING.warning("Wrong protocol version " + _version + ", " + client); client.setProtocolOk(false); client.close(new KeyPacket(client.enableCrypt(), 0)); } //TODO[K] - Strix section start else if (StrixPlatform.getInstance().isPlatformEnabled()) { if(data == null) { Log.info("Client [IP=%s] used unprotected client. Disconnect..." + client.getIpAddr()); client.close(new KeyPacket(null,0)); return; } else { final StrixClientData clientData = ClientProtocolDataManager.getInstance().getDecodedData(data, dataChecksum); if(clientData != null) { if(!ClientGameSessionManager.getInstance().checkServerResponse(clientData)) { client.close(new KeyPacket(client.enableCrypt(), 0)); return; } client.setStrixClientData(clientData); client.setRevision(_version); client.sendPacket(new KeyPacket(client.enableCrypt(), 1)); client.setProtocolOk(true); return; } Log.info("Decode client data failed. See Strix-Platform log file. Disconected client " + client.getIpAddr()); client.close(new KeyPacket(null,0)); } return; } else { client.sendPacket(new KeyPacket(client.enableCrypt(), 1)); client.setProtocolVersion(_version); client.setProtocolOk(true); } } } Файл ServerToClientCommunicationPacket.java кинул в папку "\org\l2jmobius\gameserver\network\serverpackets" и выглядит он так Спойлер package org.l2jmobius.gameserver.network.serverpackets; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.network.OutgoingPackets; public class ServerToClientCommunicationPacket implements IClientOutgoingPacket { private static boolean IS_OLD_CLIENT = false; // If you use Interlude or older version, set on "true" private ServerRequest serverRequest; private String drawText; private String url; private WarnWindowType warnWindowType; public ServerToClientCommunicationPacket(final String drawText) { this.serverRequest = ServerRequest.SC_SERVER_REQUEST_SET_DRAW_TEXT; this.drawText = drawText; } public ServerToClientCommunicationPacket(final String strValue, ServerRequest serverRequest) { this.serverRequest = serverRequest; if(serverRequest == ServerRequest.SC_SERVER_REQUEST_OPEN_URL) { this.url = strValue; } else if(serverRequest == ServerRequest.SC_SERVER_REQUEST_SET_DRAW_TEXT) { this.drawText = strValue; } } public ServerToClientCommunicationPacket(final WarnWindowType warnWindowType, final String warnMessage) { this.serverRequest = ServerRequest.SC_SERVER_REQUEST_SHOW_CUSTOM_WARN_MESSAGE; this.warnWindowType = warnWindowType; this.drawText = warnMessage; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.DUMMY.writeId(packet); packet.writeC(serverRequest.ordinal()); // Needed server request switch(serverRequest) { case SC_SERVER_REQUEST_SET_DRAW_TEXT: packet.writeS(drawText); break; case SC_SERVER_REQUEST_SHOW_CUSTOM_WARN_MESSAGE: packet.writeC(warnWindowType.ordinal()); packet.writeS(drawText); break; case SC_SERVER_REQUEST_OPEN_URL: packet.writeS(url); break; } return true; } public static enum ServerRequest { SC_SERVER_REQUEST_SET_DRAW_TEXT, SC_SERVER_REQUEST_SHOW_CUSTOM_WARN_MESSAGE, SC_SERVER_REQUEST_OPEN_URL, } public static enum WarnWindowType { UL2CW_DEFAULT, UL2CW_CLOSE_WINDOW, } } Изменено 15 февраля, 2022 пользователем Yarpi 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Grek 63 Опубликовано 16 февраля, 2022 В 15.02.2022 в 11:28, Yarpi сказал: И так в продолжении истории. AuthLogin.java был такой Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.network.GameClient; /** * @version $Revision: 1.9.2.3.2.4 $ $Date: 2005/03/27 15:29:30 $ */ public class AuthLogin implements IClientIncomingPacket { // loginName + keys must match what the loginserver used. private String _loginName; /* * private final long _key1; private final long _key2; private final long _key3; private final long _key4; */ private int _playKey1; private int _playKey2; private int _loginKey1; private int _loginKey2; @Override public boolean read(GameClient client, PacketReader packet) { _loginName = packet.readS().toLowerCase(); _playKey2 = packet.readD(); _playKey1 = packet.readD(); _loginKey1 = packet.readD(); _loginKey2 = packet.readD(); return true; } @Override public void run(GameClient client) { if (_loginName.isEmpty() || !client.isProtocolOk()) { client.closeNow(); return; } final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2); // avoid potential exploits if (client.getAccountName() == null) { // Preventing duplicate login in case client login server socket was disconnected or this packet was not sent yet if (LoginServerThread.getInstance().addGameServerLogin(_loginName, client)) { client.setAccountName(_loginName); LoginServerThread.getInstance().addWaitingClientAndSendRequest(_loginName, client, key); } else { client.close(null); } } } } А стал таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import org.strixplatform.StrixPlatform; import org.strixplatform.logging.Log; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.serverpackets.ServerClose; /** * @version $Revision: 1.9.2.3.2.4 $ $Date: 2005/03/27 15:29:30 $ */ public class AuthLogin implements IClientIncomingPacket { // loginName + keys must match what the loginserver used. private String _loginName; /* * private final long _key1; private final long _key2; private final long _key3; private final long _key4; */ private int _playKey1; private int _playKey2; private int _loginKey1; private int _loginKey2; @Override public boolean read(GameClient client, PacketReader packet) { _loginName = packet.readS().toLowerCase(); _playKey2 = packet.readD(); _playKey1 = packet.readD(); _loginKey1 = packet.readD(); _loginKey2 = packet.readD(); return true; } @Override public void run(GameClient client) { if (_loginName.isEmpty() || !client.isProtocolOk()) { client.closeNow(); return; } final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2); // avoid potential exploits if (client.getAccountName() == null) { // Preventing duplicate login in case client login server socket was disconnected or this packet was not sent yet if (LoginServerThread.getInstance().addGameServerLogin(_loginName, client)) { client.setAccountName(_loginName); LoginServerThread.getInstance().addWaitingClientAndSendRequest(_loginName, client, key); } else { client.close(null); } } // TODO[K] - Strix section start if(StrixPlatform.getInstance().isPlatformEnabled()) { if(client.getStrixClientData() != null) { client.getStrixClientData().setClientAccount(_loginName); if(StrixPlatform.getInstance().isAuthLogEnabled()) { Log.auth("Account: [" + _loginName + "] HWID: [" + client.getStrixClientData().getClientHWID() + "] SessionID: [" + client.getStrixClientData().getSessionId() + "] entered to Game Server"); } } else { client.close(ServerClose.STATIC_PACKET); return; } } // TODO[K] - Strix section end } } Файл EnterWorld.java был таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.OfflineTraderTable; import org.l2jmobius.gameserver.data.xml.AdminData; import org.l2jmobius.gameserver.data.xml.BeautyShopData; import org.l2jmobius.gameserver.data.xml.ClanHallData; import org.l2jmobius.gameserver.data.xml.SkillTreeData; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.SubclassInfoType; import org.l2jmobius.gameserver.enums.TeleportWhereType; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.instancemanager.FortSiegeManager; import org.l2jmobius.gameserver.instancemanager.InstanceManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.PetitionManager; import org.l2jmobius.gameserver.instancemanager.PunishmentManager; import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.model.PlayerCondOverride; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.punishment.PunishmentAffect; import org.l2jmobius.gameserver.model.punishment.PunishmentType; import org.l2jmobius.gameserver.model.quest.Quest; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.FortSiege; import org.l2jmobius.gameserver.model.siege.Siege; import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; import org.l2jmobius.gameserver.model.variables.AccountVariables; import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.Disconnection; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.Die; import org.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import org.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; import org.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList; import org.l2jmobius.gameserver.network.serverpackets.ExBeautyItemList; import org.l2jmobius.gameserver.network.serverpackets.ExGetBookMarkInfoPacket; import org.l2jmobius.gameserver.network.serverpackets.ExNoticePostArrived; import org.l2jmobius.gameserver.network.serverpackets.ExNotifyPremiumItem; import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeCount; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeWaitingListAlarm; import org.l2jmobius.gameserver.network.serverpackets.ExQuestItemList; import org.l2jmobius.gameserver.network.serverpackets.ExRotation; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.ExStorageMaxCount; import org.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo; import org.l2jmobius.gameserver.network.serverpackets.ExUnReadMailCount; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoEquipSlot; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight; import org.l2jmobius.gameserver.network.serverpackets.ExVitalityEffectInfo; import org.l2jmobius.gameserver.network.serverpackets.ExVoteSystemInfo; import org.l2jmobius.gameserver.network.serverpackets.HennaInfo; import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListAll; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListUpdate; import org.l2jmobius.gameserver.network.serverpackets.PledgeSkillList; import org.l2jmobius.gameserver.network.serverpackets.QuestList; import org.l2jmobius.gameserver.network.serverpackets.ShortCutInit; import org.l2jmobius.gameserver.network.serverpackets.SkillCoolTime; import org.l2jmobius.gameserver.network.serverpackets.SkillList; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExConnectedTimeAndGettableReward; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList; import org.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList; import org.l2jmobius.gameserver.util.BuilderUtil; /** * Enter World Packet Handler * <p> * <p> * 0000: 03 * <p> * packet format rev87 bddddbdcccccccccccccccccccc * <p> */ public class EnterWorld implements IClientIncomingPacket { private static final Map<String, ClientHardwareInfoHolder> TRACE_HWINFO = new ConcurrentHashMap<>(); private final int[][] _tracert = new int[5][4]; @Override public boolean read(GameClient client, PacketReader packet) { for (int i = 0; i < 5; i++) { for (int o = 0; o < 4; o++) { _tracert[i][o] = packet.readC(); } } packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readB(64); // Unknown Byte Array packet.readD(); // Unknown Value return true; } @Override public void run(GameClient client) { final PlayerInstance player = client.getPlayer(); if (player == null) { LOGGER.warning("EnterWorld failed! player returned 'null'."); Disconnection.of(client).defaultSequence(false); return; } client.setConnectionState(ConnectionState.IN_GAME); final String[] adress = new String[5]; for (int i = 0; i < 5; i++) { adress[i] = _tracert[i][0] + "." + _tracert[i][1] + "." + _tracert[i][2] + "." + _tracert[i][3]; } LoginServerThread.getInstance().sendClientTracert(player.getAccountName(), adress); client.setClientTracert(_tracert); player.broadcastUserInfo(); // Restore to instanced area if enabled if (Config.RESTORE_PLAYER_INSTANCE) { final PlayerVariables vars = player.getVariables(); final Instance instance = InstanceManager.getInstance().getPlayerInstance(player, false); if ((instance != null) && (instance.getId() == vars.getInt("INSTANCE_RESTORE", 0))) { player.setInstance(instance); } vars.remove("INSTANCE_RESTORE"); } player.updatePvpTitleAndColor(false); // Apply special GM properties to the GM when entering if (player.isGM()) { gmStartupProcess: { if (Config.GM_STARTUP_BUILDER_HIDE && AdminData.getInstance().hasAccess("admin_hide", player.getAccessLevel())) { BuilderUtil.setHiding(player, true); BuilderUtil.sendSysMessage(player, "hide is default for builder."); BuilderUtil.sendSysMessage(player, "FriendAddOff is default for builder."); BuilderUtil.sendSysMessage(player, "whisperoff is default for builder."); // It isn't recommend to use the below custom L2J GMStartup functions together with retail-like GMStartupBuilderHide, so breaking the process at that stage. break gmStartupProcess; } if (Config.GM_STARTUP_INVULNERABLE && AdminData.getInstance().hasAccess("admin_invul", player.getAccessLevel())) { player.setInvul(true); } if (Config.GM_STARTUP_INVISIBLE && AdminData.getInstance().hasAccess("admin_invisible", player.getAccessLevel())) { player.setInvisible(true); player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.STEALTH); } if (Config.GM_STARTUP_SILENCE && AdminData.getInstance().hasAccess("admin_silence", player.getAccessLevel())) { player.setSilenceMode(true); } if (Config.GM_STARTUP_DIET_MODE && AdminData.getInstance().hasAccess("admin_diet", player.getAccessLevel())) { player.setDietMode(true); player.refreshOverloaded(true); } } if (Config.GM_STARTUP_AUTO_LIST && AdminData.getInstance().hasAccess("admin_gmliston", player.getAccessLevel())) { AdminData.getInstance().addGm(player, false); } else { AdminData.getInstance().addGm(player, true); } if (Config.GM_GIVE_SPECIAL_SKILLS) { SkillTreeData.getInstance().addSkills(player, false); } if (Config.GM_GIVE_SPECIAL_AURA_SKILLS) { SkillTreeData.getInstance().addSkills(player, true); } } // Set dead status if applies if (player.getCurrentHp() < 0.5) { player.setDead(true); } boolean showClanNotice = false; // Clan related checks are here final Clan clan = player.getClan(); if (clan != null) { notifyClanMembers(player); notifySponsorOrApprentice(player); for (Siege siege : SiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getCastle().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getCastle().getResidenceId()); } } for (FortSiege siege : FortSiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getFort().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getFort().getResidenceId()); } } // Residential skills support if (player.getClan().getCastleId() > 0) { CastleManager.getInstance().getCastleByOwner(clan).giveResidentialSkills(player); } if (player.getClan().getFortId() > 0) { FortManager.getInstance().getFortByOwner(clan).giveResidentialSkills(player); } showClanNotice = clan.isNoticeEnabled(); } if (Config.ENABLE_VITALITY) { player.sendPacket(new ExVitalityEffectInfo(player)); } // Send Macro List player.getMacros().sendAllMacros(); // Send Teleport Bookmark List client.sendPacket(new ExGetBookMarkInfoPacket(player)); // Send Item List client.sendPacket(new ItemList(player, false)); // Send Quest Item List client.sendPacket(new ExQuestItemList(player)); // Send Adena and Inventory Count client.sendPacket(new ExAdenaInvenCount(player)); // Send Shortcuts client.sendPacket(new ShortCutInit(player)); // Send Action list player.sendPacket(ExBasicActionList.STATIC_PACKET); // Send blank skill list player.sendPacket(new SkillList()); // Send GG check // player.queryGameGuard(); // Send Dye Information player.sendPacket(new HennaInfo(player)); // Send Skill list player.sendSkillList(); // Send EtcStatusUpdate player.sendPacket(new EtcStatusUpdate(player)); // Clan packets if (clan != null) { clan.broadcastToOnlineMembers(new PledgeShowMemberListUpdate(player)); PledgeShowMemberListAll.sendAllTo(player); clan.broadcastToOnlineMembers(new ExPledgeCount(clan)); player.sendPacket(new PledgeSkillList(clan)); final ClanHall ch = ClanHallData.getInstance().getClanHallByClan(clan); if ((ch != null) && (ch.getCostFailDay() > 0)) { final SystemMessage sm = new SystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW); sm.addInt(ch.getLease()); player.sendPacket(sm); } } else { player.sendPacket(ExPledgeWaitingListAlarm.STATIC_PACKET); } // Send SubClass Info player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NO_CHANGES)); // Send Inventory Info player.sendPacket(new ExUserInfoInvenWeight(player)); // Send Adena / Inventory Count Info player.sendPacket(new ExAdenaInvenCount(player)); // Send Equipped Items player.sendPacket(new ExUserInfoEquipSlot(player)); // Send Unread Mail Count if (MailManager.getInstance().hasUnreadPost(player)) { player.sendPacket(new ExUnReadMailCount(player)); } // Faction System if (Config.FACTION_SYSTEM_ENABLED) { if (player.isGood()) { player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000)); } else if (player.isEvil()) { player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000)); } } Quest.playerEnter(player); // Send Quest List player.sendPacket(new QuestList(player)); if (Config.PLAYER_SPAWN_PROTECTION > 0) { player.setSpawnProtection(true); } player.spawnMe(player.getX(), player.getY(), player.getZ()); player.sendPacket(new ExRotation(player.getObjectId(), player.getHeading())); if (player.isCursedWeaponEquipped()) { CursedWeaponsManager.getInstance().getCursedWeapon(player.getCursedWeaponEquippedId()).cursedOnLogin(); } if (Config.PC_CAFE_ENABLED) { if (player.getPcCafePoints() > 0) { player.sendPacket(new ExPCCafePointInfo(player.getPcCafePoints(), 0, 1)); } else { player.sendPacket(new ExPCCafePointInfo()); } } // Expand Skill player.sendPacket(new ExStorageMaxCount(player)); // Friend list client.sendPacket(new L2FriendList(player)); SystemMessage sm = new SystemMessage(SystemMessageId.YOUR_FRIEND_S1_JUST_LOGGED_IN); sm.addString(player.getName()); for (int id : player.getFriendList()) { final WorldObject obj = World.getInstance().findObject(id); if (obj != null) { obj.sendPacket(sm); } } player.sendPacket(SystemMessageId.WELCOME_TO_THE_WORLD_OF_LINEAGE_II); AnnouncementsTable.getInstance().showAnnouncements(player); if ((Config.SERVER_RESTART_SCHEDULE_ENABLED) && (Config.SERVER_RESTART_SCHEDULE_MESSAGE)) { player.sendPacket(new CreatureSay(null, ChatType.BATTLEFIELD, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); } if (showClanNotice) { final NpcHtmlMessage notice = new NpcHtmlMessage(); notice.setFile(player, "data/html/clanNotice.htm"); notice.replace("%clan_name%", player.getClan().getName()); notice.replace("%notice_text%", player.getClan().getNotice().replaceAll("\r\n", "<br>")); notice.disableValidation(); client.sendPacket(notice); } else if (Config.SERVER_NEWS) { final String serverNews = HtmCache.getInstance().getHtm(player, "data/html/servnews.htm"); if (serverNews != null) { client.sendPacket(new NpcHtmlMessage(serverNews)); } } if (Config.PETITIONING_ALLOWED) { PetitionManager.getInstance().checkPetitionMessages(player); } if (player.isAlikeDead()) // dead or fake dead { // no broadcast needed since the player will already spawn dead to others client.sendPacket(new Die(player)); } player.onPlayerEnter(); client.sendPacket(new SkillCoolTime(player)); client.sendPacket(new ExVoteSystemInfo(player)); for (ItemInstance item : player.getInventory().getItems()) { if (item.isTimeLimitedItem()) { item.scheduleLifeTimeTask(); } if (item.isShadowItem() && item.isEquipped()) { item.decreaseMana(false); } } for (ItemInstance whItem : player.getWarehouse().getItems()) { if (whItem.isTimeLimitedItem()) { whItem.scheduleLifeTimeTask(); } } if (player.getClanJoinExpiryTime() > Chronos.currentTimeMillis()) { player.sendPacket(SystemMessageId.YOU_HAVE_RECENTLY_BEEN_DISMISSED_FROM_A_CLAN_YOU_ARE_NOT_ALLOWED_TO_JOIN_ANOTHER_CLAN_FOR_24_HOURS); } // remove combat flag before teleporting if (player.getInventory().getItemByItemId(9819) != null) { final Fort fort = FortManager.getInstance().getFort(player); if (fort != null) { FortSiegeManager.getInstance().dropCombatFlag(player, fort.getResidenceId()); } else { final int slot = player.getInventory().getSlotFromItem(player.getInventory().getItemByItemId(9819)); player.getInventory().unEquipItemInBodySlot(slot); player.destroyItem("CombatFlag", player.getInventory().getItemByItemId(9819), null, true); } } // Attacker or spectator logging in to a siege zone. // Actually should be checked for inside castle only? if (!player.canOverrideCond(PlayerCondOverride.ZONE_CONDITIONS) && player.isInsideZone(ZoneId.SIEGE) && (!player.isInSiege() || (player.getSiegeState() < 2))) { player.teleToLocation(TeleportWhereType.TOWN); } // Remove demonic weapon if character is not cursed weapon equipped. if ((player.getInventory().getItemByItemId(8190) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Zariche", player.getInventory().getItemByItemId(8190), null, true); } if ((player.getInventory().getItemByItemId(8689) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Akamanah", player.getInventory().getItemByItemId(8689), null, true); } if (Config.ALLOW_MAIL) { if (MailManager.getInstance().hasUnreadPost(player)) { client.sendPacket(ExNoticePostArrived.valueOf(false)); } } if (Config.WELCOME_MESSAGE_ENABLED) { player.sendPacket(new ExShowScreenMessage(Config.WELCOME_MESSAGE_TEXT, Config.WELCOME_MESSAGE_TIME)); } final int birthday = player.checkBirthDay(); if (birthday == 0) { player.sendPacket(SystemMessageId.HAPPY_BIRTHDAY_ALEGRIA_HAS_SENT_YOU_A_BIRTHDAY_GIFT); // player.sendPacket(new ExBirthdayPopup()); Removed in H5? } else if (birthday != -1) { sm = new SystemMessage(SystemMessageId.THERE_ARE_S1_DAYS_REMAINING_UNTIL_YOUR_BIRTHDAY_ON_YOUR_BIRTHDAY_YOU_WILL_RECEIVE_A_GIFT_THAT_ALEGRIA_HAS_CAREFULLY_PREPARED); sm.addString(Integer.toString(birthday)); player.sendPacket(sm); } if (!player.getPremiumItemList().isEmpty()) { player.sendPacket(ExNotifyPremiumItem.STATIC_PACKET); } if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.STORE_OFFLINE_TRADE_IN_REALTIME) { OfflineTraderTable.onTransaction(player, true, false); } // Check if expoff is enabled. if (player.getVariables().getBoolean("EXPOFF", false)) { player.disableExpGain(); player.sendMessage("Experience gain is disabled."); } player.broadcastUserInfo(); if (BeautyShopData.getInstance().hasBeautyData(player.getRace(), player.getAppearance().getSexType())) { player.sendPacket(new ExBeautyItemList(player)); } // Disabled to give a more Classic feeling. // if (Config.ENABLE_WORLD_CHAT) // { // player.sendPacket(new ExWorldChatCnt(player)); // } player.sendPacket(new ExConnectedTimeAndGettableReward(player)); player.sendPacket(new ExOneDayReceiveRewardList(player, true)); // Handle soulshots, disable all on EnterWorld player.sendPacket(new ExAutoSoulShot(0, true, 0)); player.sendPacket(new ExAutoSoulShot(0, true, 1)); player.sendPacket(new ExAutoSoulShot(0, true, 2)); player.sendPacket(new ExAutoSoulShot(0, true, 3)); // Fix for equipped item skills if (!player.getEffectList().getCurrentAbnormalVisualEffects().isEmpty()) { player.updateAbnormalVisualEffects(); } if (Config.ENABLE_ATTENDANCE_REWARDS) { ThreadPool.schedule(() -> { // Check if player can receive reward today. final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo(); if (attendanceInfo.isRewardAvailable()) { final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1; player.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true)); player.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready."); player.sendMessage("Click on General Menu -> Attendance Check."); if (Config.ATTENDANCE_POPUP_WINDOW) { player.sendPacket(new ExVipAttendanceItemList(player)); } } }, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000); if (Config.ATTENDANCE_POPUP_START) { player.sendPacket(new ExVipAttendanceItemList(player)); } } // Delayed HWID checks. if (Config.HARDWARE_INFO_ENABLED) { ThreadPool.schedule(() -> { // Generate trace string. final StringBuilder sb = new StringBuilder(); for (int[] i : _tracert) { for (int j : i) { sb.append(j); sb.append("."); } } final String trace = sb.toString(); // Get hardware info from client. ClientHardwareInfoHolder hwInfo = client.getHardwareInfo(); if (hwInfo != null) { hwInfo.store(player); TRACE_HWINFO.put(trace, hwInfo); } else { // Get hardware info from stored tracert map. hwInfo = TRACE_HWINFO.get(trace); if (hwInfo != null) { hwInfo.store(player); client.setHardwareInfo(hwInfo); } // Get hardware info from account variables. else { final String storedInfo = player.getAccountVariables().getString(AccountVariables.HWID, ""); if (!storedInfo.isEmpty()) { hwInfo = new ClientHardwareInfoHolder(storedInfo); TRACE_HWINFO.put(trace, hwInfo); client.setHardwareInfo(hwInfo); } } } // Banned? if ((hwInfo != null) && PunishmentManager.getInstance().hasPunishment(hwInfo.getMacAddress(), PunishmentAffect.HWID, PunishmentType.BAN)) { Disconnection.of(client).defaultSequence(false); return; } // Check max players. if (Config.KICK_MISSING_HWID && (hwInfo == null)) { Disconnection.of(client).defaultSequence(false); } else if (Config.MAX_PLAYERS_PER_HWID > 0) { int count = 0; for (PlayerInstance plr : World.getInstance().getPlayers()) { if (plr.isOnlineInt() == 1) { final ClientHardwareInfoHolder hwi = plr.getClient().getHardwareInfo(); if ((hwi != null) && hwi.equals(hwInfo)) { count++; } } } if (count >= Config.MAX_PLAYERS_PER_HWID) { Disconnection.of(client).defaultSequence(false); } } }, 5000); } // Chat banned icon. ThreadPool.schedule(() -> { if (player.isChatBanned()) { player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.NO_CHAT); } }, 5500); } /** * @param player */ private void notifyClanMembers(PlayerInstance player) { final Clan clan = player.getClan(); if (clan != null) { clan.getClanMember(player.getObjectId()).setPlayerInstance(player); final SystemMessage msg = new SystemMessage(SystemMessageId.CLAN_MEMBER_S1_HAS_LOGGED_INTO_GAME); msg.addString(player.getName()); clan.broadcastToOtherOnlineMembers(msg, player); clan.broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(player), player); } } /** * @param player */ private void notifySponsorOrApprentice(PlayerInstance player) { if (player.getSponsor() != 0) { final PlayerInstance sponsor = World.getInstance().getPlayer(player.getSponsor()); if (sponsor != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_APPRENTICE_S1_HAS_LOGGED_IN); msg.addString(player.getName()); sponsor.sendPacket(msg); } } else if (player.getApprentice() != 0) { final PlayerInstance apprentice = World.getInstance().getPlayer(player.getApprentice()); if (apprentice != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_SPONSOR_C1_HAS_LOGGED_IN); msg.addString(player.getName()); apprentice.sendPacket(msg); } } } } А стал таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import org.strixplatform.StrixPlatform; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.l2jmobius.Config; import org.l2jmobius.commons.concurrent.ThreadPool; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.cache.HtmCache; import org.l2jmobius.gameserver.data.sql.AnnouncementsTable; import org.l2jmobius.gameserver.data.sql.OfflineTraderTable; import org.l2jmobius.gameserver.data.xml.AdminData; import org.l2jmobius.gameserver.data.xml.BeautyShopData; import org.l2jmobius.gameserver.data.xml.ClanHallData; import org.l2jmobius.gameserver.data.xml.SkillTreeData; import org.l2jmobius.gameserver.enums.ChatType; import org.l2jmobius.gameserver.enums.SubclassInfoType; import org.l2jmobius.gameserver.enums.TeleportWhereType; import org.l2jmobius.gameserver.instancemanager.CastleManager; import org.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; import org.l2jmobius.gameserver.instancemanager.FortManager; import org.l2jmobius.gameserver.instancemanager.FortSiegeManager; import org.l2jmobius.gameserver.instancemanager.InstanceManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.PetitionManager; import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.instancemanager.events.GameEvent; import org.l2jmobius.gameserver.model.PlayerCondOverride; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.WorldObject; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.AttendanceInfoHolder; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.model.instancezone.Instance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.quest.Quest; import org.l2jmobius.gameserver.model.residences.ClanHall; import org.l2jmobius.gameserver.model.sevensigns.SevenSigns; import org.l2jmobius.gameserver.model.siege.Fort; import org.l2jmobius.gameserver.model.siege.FortSiege; import org.l2jmobius.gameserver.model.siege.Siege; import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; import org.l2jmobius.gameserver.model.skills.CommonSkill; import org.l2jmobius.gameserver.model.variables.AccountVariables; import org.l2jmobius.gameserver.model.variables.PlayerVariables; import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.network.ConnectionState; import org.l2jmobius.gameserver.network.Disconnection; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.SystemMessageId; import org.l2jmobius.gameserver.network.serverpackets.CreatureSay; import org.l2jmobius.gameserver.network.serverpackets.Die; import org.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import org.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; import org.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList; import org.l2jmobius.gameserver.network.serverpackets.ExBeautyItemList; import org.l2jmobius.gameserver.network.serverpackets.ExGetBookMarkInfoPacket; import org.l2jmobius.gameserver.network.serverpackets.ExNoticePostArrived; import org.l2jmobius.gameserver.network.serverpackets.ExNotifyPremiumItem; import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeCount; import org.l2jmobius.gameserver.network.serverpackets.ExPledgeWaitingListAlarm; import org.l2jmobius.gameserver.network.serverpackets.ExQuestItemList; import org.l2jmobius.gameserver.network.serverpackets.ExRotation; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.ExStorageMaxCount; import org.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo; import org.l2jmobius.gameserver.network.serverpackets.ExUnReadMailCount; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoEquipSlot; import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight; import org.l2jmobius.gameserver.network.serverpackets.ExVitalityEffectInfo; import org.l2jmobius.gameserver.network.serverpackets.ExVoteSystemInfo; import org.l2jmobius.gameserver.network.serverpackets.HennaInfo; import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListAll; import org.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListUpdate; import org.l2jmobius.gameserver.network.serverpackets.PledgeSkillList; import org.l2jmobius.gameserver.network.serverpackets.QuestList; import org.l2jmobius.gameserver.network.serverpackets.ServerToClientCommunicationPacket; import org.l2jmobius.gameserver.network.serverpackets.ShortCutInit; import org.l2jmobius.gameserver.network.serverpackets.SkillCoolTime; import org.l2jmobius.gameserver.network.serverpackets.SkillList; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.attendance.ExVipAttendanceItemList; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExConnectedTimeAndGettableReward; import org.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList; import org.l2jmobius.gameserver.network.serverpackets.friend.L2FriendList; import org.l2jmobius.gameserver.util.BuilderUtil; /** * Enter World Packet Handler * <p> * <p> * 0000: 03 * <p> * packet format rev87 bddddbdcccccccccccccccccccc * <p> */ public class EnterWorld implements IClientIncomingPacket { private static final Map<String, ClientHardwareInfoHolder> TRACE_HWINFO = new ConcurrentHashMap<>(); private final int[][] _tracert = new int[5][4]; @Override public boolean read(GameClient client, PacketReader packet) { for (int i = 0; i < 5; i++) { for (int o = 0; o < 4; o++) { _tracert[i][o] = packet.readC(); } } packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readD(); // Unknown Value packet.readB(64); // Unknown Byte Array packet.readD(); // Unknown Value return true; } @Override public void run(GameClient client) { final PlayerInstance player = client.getPlayer(); if(StrixPlatform.getInstance().isPlatformEnabled()) { player.sendPacket(new ServerToClientCommunicationPacket("your text")); } if (player == null) { LOGGER.warning("EnterWorld failed! player returned 'null'."); Disconnection.of(client).defaultSequence(false); return; } client.setConnectionState(ConnectionState.IN_GAME); final String[] adress = new String[5]; for (int i = 0; i < 5; i++) { adress[i] = _tracert[i][0] + "." + _tracert[i][1] + "." + _tracert[i][2] + "." + _tracert[i][3]; } LoginServerThread.getInstance().sendClientTracert(player.getAccountName(), adress); client.setClientTracert(_tracert); player.broadcastUserInfo(); // Restore to instanced area if enabled if (Config.RESTORE_PLAYER_INSTANCE) { final PlayerVariables vars = player.getVariables(); final Instance instance = InstanceManager.getInstance().getPlayerInstance(player, false); if ((instance != null) && (instance.getId() == vars.getInt("INSTANCE_RESTORE", 0))) { player.setInstance(instance); } vars.remove("INSTANCE_RESTORE"); } player.updatePvpTitleAndColor(false); // Apply special GM properties to the GM when entering if (player.isGM()) { gmStartupProcess: { if (Config.GM_STARTUP_BUILDER_HIDE && AdminData.getInstance().hasAccess("admin_hide", player.getAccessLevel())) { BuilderUtil.setHiding(player, true); BuilderUtil.sendSysMessage(player, "hide is default for builder."); BuilderUtil.sendSysMessage(player, "FriendAddOff is default for builder."); BuilderUtil.sendSysMessage(player, "whisperoff is default for builder."); // It isn't recommend to use the below custom L2J GMStartup functions together with retail-like GMStartupBuilderHide, so breaking the process at that stage. break gmStartupProcess; } if (Config.GM_STARTUP_INVULNERABLE && AdminData.getInstance().hasAccess("admin_invul", player.getAccessLevel())) { player.setInvul(true); } if (Config.GM_STARTUP_INVISIBLE && AdminData.getInstance().hasAccess("admin_invisible", player.getAccessLevel())) { player.setInvisible(true); player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.STEALTH); } if (Config.GM_STARTUP_SILENCE && AdminData.getInstance().hasAccess("admin_silence", player.getAccessLevel())) { player.setSilenceMode(true); } if (Config.GM_STARTUP_DIET_MODE && AdminData.getInstance().hasAccess("admin_diet", player.getAccessLevel())) { player.setDietMode(true); player.refreshOverloaded(true); } } if (Config.GM_STARTUP_AUTO_LIST && AdminData.getInstance().hasAccess("admin_gmliston", player.getAccessLevel())) { AdminData.getInstance().addGm(player, false); } else { AdminData.getInstance().addGm(player, true); } if (Config.GM_GIVE_SPECIAL_SKILLS) { SkillTreeData.getInstance().addSkills(player, false); } if (Config.GM_GIVE_SPECIAL_AURA_SKILLS) { SkillTreeData.getInstance().addSkills(player, true); } } // Chat banned icon. if (player.isChatBanned()) { player.getEffectList().startAbnormalVisualEffect(AbnormalVisualEffect.NO_CHAT); } // Set dead status if applies if (player.getCurrentHp() < 0.5) { player.setDead(true); } boolean showClanNotice = false; // Clan related checks are here final Clan clan = player.getClan(); if (clan != null) { notifyClanMembers(player); notifySponsorOrApprentice(player); for (Siege siege : SiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getCastle().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getCastle().getResidenceId()); } } for (FortSiege siege : FortSiegeManager.getInstance().getSieges()) { if (!siege.isInProgress()) { continue; } if (siege.checkIsAttacker(clan)) { player.setSiegeState((byte) 1); player.setSiegeSide(siege.getFort().getResidenceId()); } else if (siege.checkIsDefender(clan)) { player.setSiegeState((byte) 2); player.setSiegeSide(siege.getFort().getResidenceId()); } } // Residential skills support if (player.getClan().getCastleId() > 0) { CastleManager.getInstance().getCastleByOwner(clan).giveResidentialSkills(player); } if (player.getClan().getFortId() > 0) { FortManager.getInstance().getFortByOwner(clan).giveResidentialSkills(player); } showClanNotice = clan.isNoticeEnabled(); } // Updating Seal of Strife Buff/Debuff if (SevenSigns.getInstance().isSealValidationPeriod() && (SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_STRIFE) != SevenSigns.CABAL_NULL)) { final int cabal = SevenSigns.getInstance().getPlayerCabal(player.getObjectId()); if (cabal != SevenSigns.CABAL_NULL) { if (cabal == SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_STRIFE)) { player.addSkill(CommonSkill.THE_VICTOR_OF_WAR.getSkill()); } else { player.addSkill(CommonSkill.THE_VANQUISHED_OF_WAR.getSkill()); } } } else { player.removeSkill(CommonSkill.THE_VICTOR_OF_WAR.getSkill()); player.removeSkill(CommonSkill.THE_VANQUISHED_OF_WAR.getSkill()); } if (Config.ENABLE_VITALITY) { player.sendPacket(new ExVitalityEffectInfo(player)); } // Send Macro List player.getMacros().sendAllMacros(); // Send Teleport Bookmark List client.sendPacket(new ExGetBookMarkInfoPacket(player)); // Send Item List client.sendPacket(new ItemList(player, false)); // Send Quest Item List client.sendPacket(new ExQuestItemList(player)); // Send Adena and Inventory Count client.sendPacket(new ExAdenaInvenCount(player)); // Send Shortcuts client.sendPacket(new ShortCutInit(player)); // Send Action list player.sendPacket(ExBasicActionList.STATIC_PACKET); // Send blank skill list player.sendPacket(new SkillList()); // Send GG check // player.queryGameGuard(); // Send Dye Information player.sendPacket(new HennaInfo(player)); // Send Skill list player.sendSkillList(); // Send EtcStatusUpdate player.sendPacket(new EtcStatusUpdate(player)); // Clan packets if (clan != null) { clan.broadcastToOnlineMembers(new PledgeShowMemberListUpdate(player)); PledgeShowMemberListAll.sendAllTo(player); clan.broadcastToOnlineMembers(new ExPledgeCount(clan)); player.sendPacket(new PledgeSkillList(clan)); final ClanHall ch = ClanHallData.getInstance().getClanHallByClan(clan); if ((ch != null) && (ch.getCostFailDay() > 0)) { final SystemMessage sm = new SystemMessage(SystemMessageId.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_MAKE_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW); sm.addInt(ch.getLease()); player.sendPacket(sm); } } else { player.sendPacket(ExPledgeWaitingListAlarm.STATIC_PACKET); } // Send SubClass Info player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.NO_CHANGES)); // Send Inventory Info player.sendPacket(new ExUserInfoInvenWeight(player)); // Send Adena / Inventory Count Info player.sendPacket(new ExAdenaInvenCount(player)); // Send Equipped Items player.sendPacket(new ExUserInfoEquipSlot(player)); // Send Unread Mail Count if (MailManager.getInstance().hasUnreadPost(player)) { player.sendPacket(new ExUnReadMailCount(player)); } // Faction System if (Config.FACTION_SYSTEM_ENABLED) { if (player.isGood()) { player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.", 10000)); } else if (player.isEvil()) { player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR); player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR); player.sendMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction."); player.sendPacket(new ExShowScreenMessage("Welcome " + player.getName() + ", you are fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.", 10000)); } } Quest.playerEnter(player); // Send Quest List player.sendPacket(new QuestList(player)); if (Config.PLAYER_SPAWN_PROTECTION > 0) { player.setSpawnProtection(true); } player.spawnMe(player.getX(), player.getY(), player.getZ()); player.sendPacket(new ExRotation(player.getObjectId(), player.getHeading())); player.getInventory().applyItemSkills(); if (GameEvent.isParticipant(player)) { GameEvent.restorePlayerEventStatus(player); } if (player.isCursedWeaponEquipped()) { CursedWeaponsManager.getInstance().getCursedWeapon(player.getCursedWeaponEquippedId()).cursedOnLogin(); } if (Config.PC_CAFE_ENABLED) { if (player.getPcCafePoints() > 0) { player.sendPacket(new ExPCCafePointInfo(player.getPcCafePoints(), 0, 1)); } else { player.sendPacket(new ExPCCafePointInfo()); } } // Expand Skill player.sendPacket(new ExStorageMaxCount(player)); // Friend list client.sendPacket(new L2FriendList(player)); SystemMessage sm = new SystemMessage(SystemMessageId.YOUR_FRIEND_S1_JUST_LOGGED_IN); sm.addString(player.getName()); for (int id : player.getFriendList()) { final WorldObject obj = World.getInstance().findObject(id); if (obj != null) { obj.sendPacket(sm); } } player.sendPacket(SystemMessageId.WELCOME_TO_THE_WORLD_OF_LINEAGE_II); SevenSigns.getInstance().sendCurrentPeriodMsg(player); AnnouncementsTable.getInstance().showAnnouncements(player); if ((Config.SERVER_RESTART_SCHEDULE_ENABLED) && (Config.SERVER_RESTART_SCHEDULE_MESSAGE)) { player.sendPacket(new CreatureSay(null, ChatType.BATTLEFIELD, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); } if (showClanNotice) { final NpcHtmlMessage notice = new NpcHtmlMessage(); notice.setFile(player, "data/html/clanNotice.htm"); notice.replace("%clan_name%", player.getClan().getName()); notice.replace("%notice_text%", player.getClan().getNotice().replaceAll("\r\n", "<br>")); notice.disableValidation(); client.sendPacket(notice); } else if (Config.SERVER_NEWS) { final String serverNews = HtmCache.getInstance().getHtm(player, "data/html/servnews.htm"); if (serverNews != null) { client.sendPacket(new NpcHtmlMessage(serverNews)); } } if (Config.PETITIONING_ALLOWED) { PetitionManager.getInstance().checkPetitionMessages(player); } if (player.isAlikeDead()) // dead or fake dead { // no broadcast needed since the player will already spawn dead to others client.sendPacket(new Die(player)); } player.onPlayerEnter(); client.sendPacket(new SkillCoolTime(player)); client.sendPacket(new ExVoteSystemInfo(player)); for (ItemInstance item : player.getInventory().getItems()) { if (item.isTimeLimitedItem()) { item.scheduleLifeTimeTask(); } if (item.isShadowItem() && item.isEquipped()) { item.decreaseMana(false); } } for (ItemInstance whItem : player.getWarehouse().getItems()) { if (whItem.isTimeLimitedItem()) { whItem.scheduleLifeTimeTask(); } } if (DimensionalRiftManager.getInstance().checkIfInRiftZone(player.getX(), player.getY(), player.getZ(), false)) { DimensionalRiftManager.getInstance().teleportToWaitingRoom(player); } if (player.getClanJoinExpiryTime() > Chronos.currentTimeMillis()) { player.sendPacket(SystemMessageId.YOU_HAVE_RECENTLY_BEEN_DISMISSED_FROM_A_CLAN_YOU_ARE_NOT_ALLOWED_TO_JOIN_ANOTHER_CLAN_FOR_24_HOURS); } // remove combat flag before teleporting if (player.getInventory().getItemByItemId(9819) != null) { final Fort fort = FortManager.getInstance().getFort(player); if (fort != null) { FortSiegeManager.getInstance().dropCombatFlag(player, fort.getResidenceId()); } else { final int slot = player.getInventory().getSlotFromItem(player.getInventory().getItemByItemId(9819)); player.getInventory().unEquipItemInBodySlot(slot); player.destroyItem("CombatFlag", player.getInventory().getItemByItemId(9819), null, true); } } // Attacker or spectator logging in to a siege zone. // Actually should be checked for inside castle only? if (!player.canOverrideCond(PlayerCondOverride.ZONE_CONDITIONS) && player.isInsideZone(ZoneId.SIEGE) && (!player.isInSiege() || (player.getSiegeState() < 2))) { player.teleToLocation(TeleportWhereType.TOWN); } // Remove demonic weapon if character is not cursed weapon equipped. if ((player.getInventory().getItemByItemId(8190) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Zariche", player.getInventory().getItemByItemId(8190), null, true); } if ((player.getInventory().getItemByItemId(8689) != null) && !player.isCursedWeaponEquipped()) { player.destroyItem("Akamanah", player.getInventory().getItemByItemId(8689), null, true); } if (Config.ALLOW_MAIL) { if (MailManager.getInstance().hasUnreadPost(player)) { client.sendPacket(ExNoticePostArrived.valueOf(false)); } } if (Config.WELCOME_MESSAGE_ENABLED) { player.sendPacket(new ExShowScreenMessage(Config.WELCOME_MESSAGE_TEXT, Config.WELCOME_MESSAGE_TIME)); } final int birthday = player.checkBirthDay(); if (birthday == 0) { player.sendPacket(SystemMessageId.HAPPY_BIRTHDAY_ALEGRIA_HAS_SENT_YOU_A_BIRTHDAY_GIFT); // player.sendPacket(new ExBirthdayPopup()); Removed in H5? } else if (birthday != -1) { sm = new SystemMessage(SystemMessageId.THERE_ARE_S1_DAYS_REMAINING_UNTIL_YOUR_BIRTHDAY_ON_YOUR_BIRTHDAY_YOU_WILL_RECEIVE_A_GIFT_THAT_ALEGRIA_HAS_CAREFULLY_PREPARED); sm.addString(Integer.toString(birthday)); player.sendPacket(sm); } if (!player.getPremiumItemList().isEmpty()) { player.sendPacket(ExNotifyPremiumItem.STATIC_PACKET); } if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.STORE_OFFLINE_TRADE_IN_REALTIME) { OfflineTraderTable.onTransaction(player, true, false); } // Check if expoff is enabled. if (player.getVariables().getBoolean("EXPOFF", false)) { player.disableExpGain(); player.sendMessage("Experience gain is disabled."); } player.broadcastUserInfo(); if (BeautyShopData.getInstance().hasBeautyData(player.getRace(), player.getAppearance().getSexType())) { player.sendPacket(new ExBeautyItemList(player)); } // Disabled to give a more Classic feeling. // if (Config.ENABLE_WORLD_CHAT) // { // player.sendPacket(new ExWorldChatCnt(player)); // } player.sendPacket(new ExConnectedTimeAndGettableReward(player)); player.sendPacket(new ExOneDayReceiveRewardList(player, true)); // Handle soulshots, disable all on EnterWorld player.sendPacket(new ExAutoSoulShot(0, true, 0)); player.sendPacket(new ExAutoSoulShot(0, true, 1)); player.sendPacket(new ExAutoSoulShot(0, true, 2)); player.sendPacket(new ExAutoSoulShot(0, true, 3)); // Fix for equipped item skills if (!player.getEffectList().getCurrentAbnormalVisualEffects().isEmpty()) { player.updateAbnormalVisualEffects(); } if (Config.ENABLE_ATTENDANCE_REWARDS) { ThreadPool.schedule(() -> { // Check if player can receive reward today. final AttendanceInfoHolder attendanceInfo = player.getAttendanceInfo(); if (attendanceInfo.isRewardAvailable()) { final int lastRewardIndex = attendanceInfo.getRewardIndex() + 1; player.sendPacket(new ExShowScreenMessage("Your attendance day " + lastRewardIndex + " reward is ready.", ExShowScreenMessage.TOP_CENTER, 7000, 0, true, true)); player.sendMessage("Your attendance day " + lastRewardIndex + " reward is ready."); player.sendMessage("Click on General Menu -> Attendance Check."); if (Config.ATTENDANCE_POPUP_WINDOW) { player.sendPacket(new ExVipAttendanceItemList(player)); } } }, Config.ATTENDANCE_REWARD_DELAY * 60 * 1000); if (Config.ATTENDANCE_POPUP_START) { player.sendPacket(new ExVipAttendanceItemList(player)); } } if (Config.HARDWARE_INFO_ENABLED) { ThreadPool.schedule(() -> { // Generate trace string. final StringBuilder sb = new StringBuilder(); for (int[] i : _tracert) { for (int j : i) { sb.append(j); sb.append("."); } } final String trace = sb.toString(); // Get hardware info from client. ClientHardwareInfoHolder hwInfo = client.getHardwareInfo(); if (hwInfo != null) { hwInfo.store(player); TRACE_HWINFO.put(trace, hwInfo); } else { // Get hardware info from stored tracert map. hwInfo = TRACE_HWINFO.get(trace); if (hwInfo != null) { hwInfo.store(player); client.setHardwareInfo(hwInfo); } // Get hardware info from account variables. else { final String storedInfo = player.getAccountVariables().getString(AccountVariables.HWID, ""); if (!storedInfo.isEmpty()) { hwInfo = new ClientHardwareInfoHolder(storedInfo); TRACE_HWINFO.put(trace, hwInfo); client.setHardwareInfo(hwInfo); } } } // Check max players. if (Config.KICK_MISSING_HWID && (hwInfo == null)) { Disconnection.of(client).defaultSequence(false); } else if (Config.MAX_PLAYERS_PER_HWID > 0) { int count = 0; for (PlayerInstance plr : World.getInstance().getPlayers()) { if ((plr.isOnlineInt() == 1) && (plr.getClient().getHardwareInfo().equals(hwInfo))) { count++; } } if (count >= Config.MAX_PLAYERS_PER_HWID) { Disconnection.of(client).defaultSequence(false); } } }, 5000); } } /** * @param player */ private void notifyClanMembers(PlayerInstance player) { final Clan clan = player.getClan(); if (clan != null) { clan.getClanMember(player.getObjectId()).setPlayerInstance(player); final SystemMessage msg = new SystemMessage(SystemMessageId.CLAN_MEMBER_S1_HAS_LOGGED_INTO_GAME); msg.addString(player.getName()); clan.broadcastToOtherOnlineMembers(msg, player); clan.broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(player), player); } } /** * @param player */ private void notifySponsorOrApprentice(PlayerInstance player) { if (player.getSponsor() != 0) { final PlayerInstance sponsor = World.getInstance().getPlayer(player.getSponsor()); if (sponsor != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_APPRENTICE_S1_HAS_LOGGED_IN); msg.addString(player.getName()); sponsor.sendPacket(msg); } } else if (player.getApprentice() != 0) { final PlayerInstance apprentice = World.getInstance().getPlayer(player.getApprentice()); if (apprentice != null) { final SystemMessage msg = new SystemMessage(SystemMessageId.YOUR_SPONSOR_C1_HAS_LOGGED_IN); msg.addString(player.getName()); apprentice.sendPacket(msg); } } } } Файл GameClient.java был таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network; import java.net.InetAddress; import java.net.InetSocketAddress; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; import org.l2jmobius.Config; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.network.ChannelInboundHandler; import org.l2jmobius.commons.network.ICrypt; import org.l2jmobius.commons.network.IIncomingPacket; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.data.sql.ClanTable; import org.l2jmobius.gameserver.data.xml.SecondaryAuthData; import org.l2jmobius.gameserver.enums.CharacterDeleteFailType; import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.MentorManager; import org.l2jmobius.gameserver.model.CharSelectInfoPackage; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld; import org.l2jmobius.gameserver.network.serverpackets.NpcInfo; import org.l2jmobius.gameserver.network.serverpackets.NpcSay; import org.l2jmobius.gameserver.network.serverpackets.ServerClose; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.security.SecondaryPasswordAuth; import org.l2jmobius.gameserver.util.FloodProtectors; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; /** * Represents a client connected on Game Server. * @author KenM */ public class GameClient extends ChannelInboundHandler<GameClient> { protected static final Logger LOGGER = Logger.getLogger(GameClient.class.getName()); protected static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private final FloodProtectors _floodProtectors = new FloodProtectors(this); private final ReentrantLock _playerLock = new ReentrantLock(); private final Crypt _crypt = new Crypt(); private InetAddress _addr; private Channel _channel; private String _accountName; private SessionKey _sessionId; private PlayerInstance _player; private SecondaryPasswordAuth _secondaryAuth; private ClientHardwareInfoHolder _hardwareInfo; private List<CharSelectInfoPackage> _charSlotMapping = null; private volatile boolean _isDetached = false; private boolean _isAuthedGG; private boolean _protocolOk; private int _protocolVersion; private int[][] _trace; @Override public void channelActive(ChannelHandlerContext ctx) { super.channelActive(ctx); setConnectionState(ConnectionState.CONNECTED); final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); _addr = address.getAddress(); _channel = ctx.channel(); LOGGER_ACCOUNTING.finer("Client Connected: " + ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) { LOGGER_ACCOUNTING.finer("Client Disconnected: " + ctx.channel()); LoginServerThread.getInstance().sendLogout(getAccountName()); if ((_player == null) || !_player.isInOfflineMode()) { Disconnection.of(this).onDisconnection(); } } @Override protected void channelRead0(ChannelHandlerContext ctx, IIncomingPacket<GameClient> packet) { try { packet.run(this); } catch (Exception e) { LOGGER.log(Level.WARNING, "Exception for: " + toString() + " on packet.run: " + packet.getClass().getSimpleName(), e); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { } public void closeNow() { if (_channel != null) { _channel.close(); } } public void close(IClientOutgoingPacket packet) { sendPacket(packet); closeNow(); } public void close(boolean toLoginScreen) { close(toLoginScreen ? ServerClose.STATIC_PACKET : LeaveWorld.STATIC_PACKET); } public Channel getChannel() { return _channel; } public byte[] enableCrypt() { final byte[] key = BlowFishKeygen.getRandomKey(); _crypt.setKey(key); return key; } /** * For loaded offline traders returns localhost address. * @return cached connection IP address, for checking detached clients. */ public InetAddress getConnectionAddress() { return _addr; } public PlayerInstance getPlayer() { return _player; } public void setPlayer(PlayerInstance player) { _player = player; } public ReentrantLock getPlayerLock() { return _playerLock; } public FloodProtectors getFloodProtectors() { return _floodProtectors; } public void setGameGuardOk(boolean value) { _isAuthedGG = value; } public boolean isAuthedGG() { return _isAuthedGG; } public void setAccountName(String activeChar) { _accountName = activeChar; if (SecondaryAuthData.getInstance().isEnabled()) { _secondaryAuth = new SecondaryPasswordAuth(this); } } public String getAccountName() { return _accountName; } public void setSessionId(SessionKey sk) { _sessionId = sk; } public SessionKey getSessionId() { return _sessionId; } public void sendPacket(IClientOutgoingPacket packet) { if (_isDetached || (packet == null)) { return; } // TODO: Set as parameter to packets used? if (Config.MULTILANG_ENABLE && (_player != null)) { final String lang = _player.getLang(); if ((lang != null) && !lang.equals("en")) { if (packet instanceof SystemMessage) { ((SystemMessage) packet).setLang(lang); } else if (packet instanceof NpcSay) { ((NpcSay) packet).setLang(lang); } else if (packet instanceof ExShowScreenMessage) { ((ExShowScreenMessage) packet).setLang(lang); } else if (packet instanceof NpcInfo) { ((NpcInfo) packet).setLang(lang); } } } // Write into the channel. _channel.writeAndFlush(packet); // Run packet implementation. packet.runImpl(_player); } /** * @param smId */ public void sendPacket(SystemMessageId smId) { sendPacket(new SystemMessage(smId)); } public boolean isDetached() { return _isDetached; } public void setDetached(boolean value) { _isDetached = value; } /** * Method to handle character deletion * @param characterSlot * @return a byte: * <li>-1: Error: No char was found for such charslot, caught exception, etc... * <li>0: character is not member of any clan, proceed with deletion * <li>1: character is member of a clan, but not clan leader * <li>2: character is clan leader */ public CharacterDeleteFailType markToDeleteChar(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return CharacterDeleteFailType.UNKNOWN; } if (MentorManager.getInstance().isMentor(objectId)) { return CharacterDeleteFailType.MENTOR; } else if (MentorManager.getInstance().isMentee(objectId)) { return CharacterDeleteFailType.MENTEE; } else if (CommissionManager.getInstance().hasCommissionItems(objectId)) { return CharacterDeleteFailType.COMMISSION; } else if (MailManager.getInstance().getMailsInProgress(objectId) > 0) { return CharacterDeleteFailType.MAIL; } else { final int clanId = CharNameTable.getInstance().getClassIdById(objectId); if (clanId > 0) { final Clan clan = ClanTable.getInstance().getClan(clanId); if (clan != null) { if (clan.getLeaderId() == objectId) { return CharacterDeleteFailType.PLEDGE_MASTER; } return CharacterDeleteFailType.PLEDGE_MEMBER; } } } if (Config.DELETE_DAYS == 0) { deleteCharByObjId(objectId); } else { try (Connection con = DatabaseFactory.getConnection(); PreparedStatement ps2 = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?")) { ps2.setLong(1, Chronos.currentTimeMillis() + (Config.DELETE_DAYS * 86400000)); // 24*60*60*1000 = 86400000 ps2.setInt(2, objectId); ps2.execute(); } catch (SQLException e) { LOGGER.log(Level.WARNING, "Failed to update char delete time: ", e); } } LOGGER_ACCOUNTING.info("Delete, " + objectId + ", " + this); return CharacterDeleteFailType.NONE; } public void restore(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return; } try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?")) { statement.setInt(1, objectId); statement.execute(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error restoring character.", e); } LOGGER_ACCOUNTING.info("Restore, " + objectId + ", " + this); } public static void deleteCharByObjId(int objid) { if (objid < 0) { return; } CharNameTable.getInstance().removeName(objid); try (Connection con = DatabaseFactory.getConnection()) { try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_contacts WHERE charId=? OR contactId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR friendId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_hennas WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_macroses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_quests WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_recipebook WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_shortcuts WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills_save WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_subclasses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM heroes WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variations WHERE itemId IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variables WHERE id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM items WHERE owner_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_reco_bonus WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_instance_time WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM characters WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error deleting character.", e); } } public PlayerInstance load(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return null; } PlayerInstance player = World.getInstance().getPlayer(objectId); if (player != null) { // exploit prevention, should not happens in normal way if (player.isOnlineInt() == 1) { LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + _accountName); } if (player.getClient() != null) { Disconnection.of(player).defaultSequence(false); } else { player.storeMe(); player.deleteMe(); } return null; } player = PlayerInstance.load(objectId); if (player == null) { LOGGER.severe("Could not restore in slot: " + characterSlot); } return player; } public void setCharSelection(List<CharSelectInfoPackage> characters) { _charSlotMapping = characters; } public CharSelectInfoPackage getCharSelection(int charslot) { if ((_charSlotMapping == null) || (charslot < 0) || (charslot >= _charSlotMapping.size())) { return null; } return _charSlotMapping.get(charslot); } public SecondaryPasswordAuth getSecondaryAuth() { return _secondaryAuth; } /** * @param characterSlot * @return */ private int getObjectIdForSlot(int characterSlot) { final CharSelectInfoPackage info = getCharSelection(characterSlot); if (info == null) { LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot."); return -1; } return info.getObjectId(); } /** * Produces the best possible string representation of this client. */ @Override public String toString() { try { final InetAddress address = _addr; final ConnectionState state = (ConnectionState) getConnectionState(); switch (state) { case CONNECTED: { return "[IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case AUTHENTICATED: { return "[Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case ENTERING: case IN_GAME: { return "[Character: " + (_player == null ? "disconnected" : _player.getName() + "[" + _player.getObjectId() + "]") + " - Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } default: { throw new IllegalStateException("Missing state on switch"); } } } catch (NullPointerException e) { return "[Character read failed due to disconnect]"; } } public void setProtocolVersion(int version) { _protocolVersion = version; } public int getProtocolVersion() { return _protocolVersion; } public boolean isProtocolOk() { return _protocolOk; } public void setProtocolOk(boolean value) { _protocolOk = value; } public void setClientTracert(int[][] tracert) { _trace = tracert; } public int[][] getTrace() { return _trace; } public void sendActionFailed() { sendPacket(ActionFailed.STATIC_PACKET); } public ICrypt getCrypt() { return _crypt; } /** * @return the hardwareInfo */ public ClientHardwareInfoHolder getHardwareInfo() { return _hardwareInfo; } /** * @param hardwareInfo */ public void setHardwareInfo(ClientHardwareInfoHolder hardwareInfo) { _hardwareInfo = hardwareInfo; } } А стал таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network; import java.net.InetAddress; import java.net.InetSocketAddress; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; import org.strixplatform.StrixPlatform; import org.strixplatform.network.IStrixClientData; import org.strixplatform.network.cipher.StrixGameCrypt; import org.strixplatform.utils.StrixClientData; import org.l2jmobius.Config; import org.l2jmobius.commons.database.DatabaseFactory; import org.l2jmobius.commons.network.ChannelInboundHandler; import org.l2jmobius.commons.network.ICrypt; import org.l2jmobius.commons.network.IIncomingPacket; import org.l2jmobius.commons.util.Chronos; import org.l2jmobius.gameserver.LoginServerThread; import org.l2jmobius.gameserver.LoginServerThread.SessionKey; import org.l2jmobius.gameserver.data.sql.CharNameTable; import org.l2jmobius.gameserver.data.sql.ClanTable; import org.l2jmobius.gameserver.data.xml.SecondaryAuthData; import org.l2jmobius.gameserver.enums.CharacterDeleteFailType; import org.l2jmobius.gameserver.instancemanager.CommissionManager; import org.l2jmobius.gameserver.instancemanager.MailManager; import org.l2jmobius.gameserver.instancemanager.MentorManager; import org.l2jmobius.gameserver.model.CharSelectInfoPackage; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage; import org.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; import org.l2jmobius.gameserver.network.serverpackets.LeaveWorld; import org.l2jmobius.gameserver.network.serverpackets.NpcInfo; import org.l2jmobius.gameserver.network.serverpackets.NpcSay; import org.l2jmobius.gameserver.network.serverpackets.ServerClose; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.security.SecondaryPasswordAuth; import org.l2jmobius.gameserver.util.FloodProtectors; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; /** * Represents a client connected on Game Server. * @author KenM */ public class GameClient extends ChannelInboundHandler<GameClient> implements IStrixClientData { protected static final Logger LOGGER = Logger.getLogger(GameClient.class.getName()); protected static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private final FloodProtectors _floodProtectors = new FloodProtectors(this); private final ReentrantLock _playerLock = new ReentrantLock(); //private final Crypt _crypt; private InetAddress _addr; private Channel _channel; private String _accountName; private SessionKey _sessionId; private PlayerInstance _player; private SecondaryPasswordAuth _secondaryAuth; private ClientHardwareInfoHolder _hardwareInfo; private CharSelectInfoPackage[] _charSlotMapping = null; //TODO[K] - Guard section start public StrixCryptImpl _crypt = null; private StrixClientData clientData; //TODO[K] - Guard section end private volatile boolean _isDetached = false; private boolean _isAuthedGG; private boolean _protocolOk; private int _protocolVersion; private int[][] _trace; public GameClient() { _crypt = new StrixCryptImpl(); } @Override public void channelActive(ChannelHandlerContext ctx) { super.channelActive(ctx); setConnectionState(ConnectionState.CONNECTED); final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress(); _addr = address.getAddress(); _channel = ctx.channel(); LOGGER_ACCOUNTING.finer("Client Connected: " + ctx.channel()); } @Override public void channelInactive(ChannelHandlerContext ctx) { LOGGER_ACCOUNTING.finer("Client Disconnected: " + ctx.channel()); LoginServerThread.getInstance().sendLogout(getAccountName()); if ((_player == null) || !_player.isInOfflineMode()) { Disconnection.of(this).onDisconnection(); } } @Override protected void channelRead0(ChannelHandlerContext ctx, IIncomingPacket<GameClient> packet) { try { packet.run(this); } catch (Exception e) { LOGGER.log(Level.WARNING, "Exception for: " + toString() + " on packet.run: " + packet.getClass().getSimpleName(), e); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { } public void closeNow() { if (_channel != null) { _channel.close(); } } public void close(IClientOutgoingPacket packet) { sendPacket(packet); closeNow(); } public void close(boolean toLoginScreen) { close(toLoginScreen ? ServerClose.STATIC_PACKET : LeaveWorld.STATIC_PACKET); } public Channel getChannel() { return _channel; } public byte[] enableCrypt() { final byte[] key = BlowFishKeygen.getRandomKey(); _crypt.setKey(key); return key; } /** * For loaded offline traders returns localhost address. * @return cached connection IP address, for checking detached clients. */ public InetAddress getConnectionAddress() { return _addr; } public PlayerInstance getPlayer() { return _player; } public void setPlayer(PlayerInstance player) { _player = player; } public ReentrantLock getPlayerLock() { return _playerLock; } public FloodProtectors getFloodProtectors() { return _floodProtectors; } public void setGameGuardOk(boolean value) { _isAuthedGG = value; } public boolean isAuthedGG() { return _isAuthedGG; } public void setAccountName(String activeChar) { _accountName = activeChar; if (SecondaryAuthData.getInstance().isEnabled()) { _secondaryAuth = new SecondaryPasswordAuth(this); } } public String getAccountName() { return _accountName; } public void setSessionId(SessionKey sk) { _sessionId = sk; } public SessionKey getSessionId() { return _sessionId; } public void sendPacket(IClientOutgoingPacket packet) { if (_isDetached || (packet == null)) { return; } // TODO: Set as parameter to packets used? if (Config.MULTILANG_ENABLE && (_player != null)) { final String lang = _player.getLang(); if ((lang != null) && !lang.equals("en")) { if (packet instanceof SystemMessage) { ((SystemMessage) packet).setLang(lang); } else if (packet instanceof NpcSay) { ((NpcSay) packet).setLang(lang); } else if (packet instanceof ExShowScreenMessage) { ((ExShowScreenMessage) packet).setLang(lang); } else if (packet instanceof NpcInfo) { ((NpcInfo) packet).setLang(lang); } } } // Write into the channel. _channel.writeAndFlush(packet); // Run packet implementation. packet.runImpl(_player); } /** * @param smId */ public void sendPacket(SystemMessageId smId) { sendPacket(new SystemMessage(smId)); } public boolean isDetached() { return _isDetached; } public void setDetached(boolean value) { _isDetached = value; } /** * Method to handle character deletion * @param characterSlot * @return a byte: * <li>-1: Error: No char was found for such charslot, caught exception, etc... * <li>0: character is not member of any clan, proceed with deletion * <li>1: character is member of a clan, but not clan leader * <li>2: character is clan leader */ public CharacterDeleteFailType markToDeleteChar(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return CharacterDeleteFailType.UNKNOWN; } if (MentorManager.getInstance().isMentor(objectId)) { return CharacterDeleteFailType.MENTOR; } else if (MentorManager.getInstance().isMentee(objectId)) { return CharacterDeleteFailType.MENTEE; } else if (CommissionManager.getInstance().hasCommissionItems(objectId)) { return CharacterDeleteFailType.COMMISSION; } else if (MailManager.getInstance().getMailsInProgress(objectId) > 0) { return CharacterDeleteFailType.MAIL; } else { final int clanId = CharNameTable.getInstance().getClassIdById(objectId); if (clanId > 0) { final Clan clan = ClanTable.getInstance().getClan(clanId); if (clan != null) { if (clan.getLeaderId() == objectId) { return CharacterDeleteFailType.PLEDGE_MASTER; } return CharacterDeleteFailType.PLEDGE_MEMBER; } } } if (Config.DELETE_DAYS == 0) { deleteCharByObjId(objectId); } else { try (Connection con = DatabaseFactory.getConnection(); PreparedStatement ps2 = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?")) { ps2.setLong(1, Chronos.currentTimeMillis() + (Config.DELETE_DAYS * 86400000)); // 24*60*60*1000 = 86400000 ps2.setInt(2, objectId); ps2.execute(); } catch (SQLException e) { LOGGER.log(Level.WARNING, "Failed to update char delete time: ", e); } } LOGGER_ACCOUNTING.info("Delete, " + objectId + ", " + this); return CharacterDeleteFailType.NONE; } public void restore(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return; } try (Connection con = DatabaseFactory.getConnection(); PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?")) { statement.setInt(1, objectId); statement.execute(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error restoring character.", e); } LOGGER_ACCOUNTING.info("Restore, " + objectId + ", " + this); } public static void deleteCharByObjId(int objid) { if (objid < 0) { return; } CharNameTable.getInstance().removeName(objid); try (Connection con = DatabaseFactory.getConnection()) { try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_contacts WHERE charId=? OR contactId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR friendId=?")) { ps.setInt(1, objid); ps.setInt(2, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_hennas WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_macroses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_quests WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_recipebook WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_shortcuts WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_skills_save WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_subclasses WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM heroes WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM olympiad_nobles WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM pets WHERE item_obj_id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variations WHERE itemId IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM item_variables WHERE id IN (SELECT object_id FROM items WHERE items.owner_id=?)")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM items WHERE owner_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM merchant_lease WHERE player_id=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_reco_bonus WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_instance_time WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM character_variables WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } try (PreparedStatement ps = con.prepareStatement("DELETE FROM characters WHERE charId=?")) { ps.setInt(1, objid); ps.execute(); } } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error deleting character.", e); } } public PlayerInstance load(int characterSlot) { final int objectId = getObjectIdForSlot(characterSlot); if (objectId < 0) { return null; } PlayerInstance player = World.getInstance().getPlayer(objectId); if (player != null) { // exploit prevention, should not happens in normal way if (player.isOnlineInt() == 1) { LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + _accountName); } if (player.getClient() != null) { Disconnection.of(player).defaultSequence(false); } else { player.storeMe(); player.deleteMe(); } return null; } player = PlayerInstance.load(objectId); if (player == null) { LOGGER.severe("Could not restore in slot: " + characterSlot); } return player; } /** * @param chars */ public void setCharSelection(CharSelectInfoPackage[] chars) { _charSlotMapping = chars; } public CharSelectInfoPackage getCharSelection(int charslot) { if ((_charSlotMapping == null) || (charslot < 0) || (charslot >= _charSlotMapping.length)) { return null; } return _charSlotMapping[charslot]; } public SecondaryPasswordAuth getSecondaryAuth() { return _secondaryAuth; } /** * @param characterSlot * @return */ private int getObjectIdForSlot(int characterSlot) { final CharSelectInfoPackage info = getCharSelection(characterSlot); if (info == null) { LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot."); return -1; } return info.getObjectId(); } /** * Produces the best possible string representation of this client. */ @Override public String toString() { try { final InetAddress address = _addr; final ConnectionState state = (ConnectionState) getConnectionState(); switch (state) { case CONNECTED: { return "[IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case AUTHENTICATED: { return "[Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } case ENTERING: case IN_GAME: { return "[Character: " + (_player == null ? "disconnected" : _player.getName() + "[" + _player.getObjectId() + "]") + " - Account: " + _accountName + " - IP: " + (address == null ? "disconnected" : address.getHostAddress()) + "]"; } default: { throw new IllegalStateException("Missing state on switch"); } } } catch (NullPointerException e) { return "[Character read failed due to disconnect]"; } } public void setProtocolVersion(int version) { _protocolVersion = version; } public int getProtocolVersion() { return _protocolVersion; } public boolean isProtocolOk() { return _protocolOk; } public void setProtocolOk(boolean value) { _protocolOk = value; } public void setClientTracert(int[][] tracert) { _trace = tracert; } public int[][] getTrace() { return _trace; } public void sendActionFailed() { sendPacket(ActionFailed.STATIC_PACKET); } public ICrypt getCrypt() { return _crypt; } /** * @return the hardwareInfo */ public ClientHardwareInfoHolder getHardwareInfo() { return _hardwareInfo; } /** * @param hardwareInfo */ public void setHardwareInfo(ClientHardwareInfoHolder hardwareInfo) { _hardwareInfo = hardwareInfo; } //TODO[K] - Guard section start private int revision = 0; public String getIpAddr() { return _addr.getHostAddress(); } public int getRevision() { return revision; } public void setRevision(int revision) { this.revision = revision; } @Override public void setStrixClientData(final StrixClientData clientData) { this.clientData = clientData; } @Override public StrixClientData getStrixClientData() { return clientData; } private class StrixCryptImpl extends StrixGameCrypt implements ICrypt { @Override public void encrypt(ByteBuf buf) { byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(0, bytes); super.encrypt(bytes, 0, bytes.length); buf.setBytes(0, bytes); } @Override public void decrypt(ByteBuf buf) { byte[] bytes = new byte[buf.readableBytes()]; buf.getBytes(0, bytes); super.decrypt(bytes, 0, bytes.length); buf.setBytes(0, bytes); } } //TODO[K] - Guard section end } ФАйл KeyPacket.java был таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.serverpackets; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.network.OutgoingPackets; public class KeyPacket implements IClientOutgoingPacket { private final byte[] _key; private final int _result; public KeyPacket(byte[] key, int result) { _key = key; _result = result; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.VERSION_CHECK.writeId(packet); packet.writeC(_result); // 0 - wrong protocol, 1 - protocol ok for (int i = 0; i < 8; i++) { packet.writeC(_key[i]); // key } packet.writeD(0x01); packet.writeD(Config.SERVER_ID); // server id packet.writeC(0x01); packet.writeD(0x00); // obfuscation key packet.writeC((Config.SERVER_LIST_TYPE & 0x400) == 0x400 ? 0x01 : 0x00); // isClassic return true; } } А стал таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.serverpackets; import org.strixplatform.StrixPlatform; import org.strixplatform.utils.StrixClientData; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.network.OutgoingPackets; public class KeyPacket implements IClientOutgoingPacket { private final byte[] _key; private final int _result; //TODO[K] - Guard section start private final StrixClientData clientData; // TODO[K] - Strix section end public KeyPacket(byte[] key, int result) { _key = key; _result = result; //TODO[K] - Guard section start this.clientData = null; // TODO[K] - Strix section end } @Override public boolean write(PacketWriter packet) { OutgoingPackets.VERSION_CHECK.writeId(packet); //TODO[K] - Guard section start if(_key == null) { if (StrixPlatform.getInstance().isBackNotificationEnabled() && clientData != null) { packet.writeC(clientData.getServerResponse().ordinal() + 1); } else { packet.writeC(0x00); } return true; } // TODO[K] - Strix section end packet.writeC(_result); // 0 - wrong protocol, 1 - protocol ok for (int i = 0; i < 8; i++) { packet.writeC(_key[i]); // key } packet.writeD(0x01); packet.writeD(Config.SERVER_ID); // server id packet.writeC(0x01); packet.writeD(0x00); // obfuscation key packet.writeC((Config.SERVER_LIST_TYPE & 0x400) == 0x400 ? 0x01 : 0x00); // isClassic return true; } } Файл ProtocolVersion.java был таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import java.util.logging.Logger; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.serverpackets.KeyPacket; /** * @version $Revision: 1.5.2.8.2.8 $ $Date: 2005/04/02 10:43:04 $ */ public class ProtocolVersion implements IClientIncomingPacket { private static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private int _version; @Override public boolean read(GameClient client, PacketReader packet) { _version = packet.readD(); return true; } @Override public void run(GameClient client) { // this packet is never encrypted if (_version == -2) { // this is just a ping attempt from the new C2 client client.closeNow(); } else if (!Config.PROTOCOL_LIST.contains(_version)) { LOGGER_ACCOUNTING.warning("Wrong protocol version " + _version + ", " + client); client.setProtocolOk(false); client.close(new KeyPacket(client.enableCrypt(), 0)); } else { client.sendPacket(new KeyPacket(client.enableCrypt(), 1)); client.setProtocolVersion(_version); client.setProtocolOk(true); } } } А стал таким Показать контент /* * This file is part of the L2J Mobius project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.l2jmobius.gameserver.network.clientpackets; import java.util.logging.Logger; import org.strixplatform.StrixPlatform; import org.strixplatform.logging.Log; import org.strixplatform.managers.ClientGameSessionManager; import org.strixplatform.managers.ClientProtocolDataManager; import org.strixplatform.utils.StrixClientData; import org.l2jmobius.Config; import org.l2jmobius.commons.network.PacketReader; import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.serverpackets.KeyPacket; /** * @version $Revision: 1.5.2.8.2.8 $ $Date: 2005/04/02 10:43:04 $ */ public class ProtocolVersion implements IClientIncomingPacket { private static final Logger LOGGER_ACCOUNTING = Logger.getLogger("accounting"); private int _version; //TODO[K] - Guard section start private byte[] data; private int dataChecksum; //TODO[K] - Guard section end @Override public boolean read(GameClient client, PacketReader packet) { _version = packet.readD(); //TODO[K] - Guard section start if(StrixPlatform.getInstance().isPlatformEnabled()) { try { if(packet.getReadableBytes() >= StrixPlatform.getInstance().getProtocolVersionDataSize()) { data = new byte[StrixPlatform.getInstance().getClientDataSize()]; data = packet.readB(StrixPlatform.getInstance().getClientDataSize()); dataChecksum = packet.readD(); } } catch(final Exception e) { Log.error("Client [IP=" + client.getIpAddr() + "] used unprotected client. Disconnect..."); client.close(new KeyPacket(null,0)); return false; } } //TODO[K] - Guard section end return true; } @Override public void run(GameClient client) { // this packet is never encrypted if (_version == -2) { // this is just a ping attempt from the new C2 client client.closeNow(); } else if (!Config.PROTOCOL_LIST.contains(_version)) { LOGGER_ACCOUNTING.warning("Wrong protocol version " + _version + ", " + client); client.setProtocolOk(false); client.close(new KeyPacket(client.enableCrypt(), 0)); } //TODO[K] - Strix section start else if (StrixPlatform.getInstance().isPlatformEnabled()) { if(data == null) { Log.info("Client [IP=%s] used unprotected client. Disconnect..." + client.getIpAddr()); client.close(new KeyPacket(null,0)); return; } else { final StrixClientData clientData = ClientProtocolDataManager.getInstance().getDecodedData(data, dataChecksum); if(clientData != null) { if(!ClientGameSessionManager.getInstance().checkServerResponse(clientData)) { client.close(new KeyPacket(client.enableCrypt(), 0)); return; } client.setStrixClientData(clientData); client.setRevision(_version); client.sendPacket(new KeyPacket(client.enableCrypt(), 1)); client.setProtocolOk(true); return; } Log.info("Decode client data failed. See Strix-Platform log file. Disconected client " + client.getIpAddr()); client.close(new KeyPacket(null,0)); } return; } else { client.sendPacket(new KeyPacket(client.enableCrypt(), 1)); client.setProtocolVersion(_version); client.setProtocolOk(true); } } } Файл ServerToClientCommunicationPacket.java кинул в папку "\org\l2jmobius\gameserver\network\serverpackets" и выглядит он так Показать контент package org.l2jmobius.gameserver.network.serverpackets; import org.l2jmobius.commons.network.PacketWriter; import org.l2jmobius.gameserver.network.OutgoingPackets; public class ServerToClientCommunicationPacket implements IClientOutgoingPacket { private static boolean IS_OLD_CLIENT = false; // If you use Interlude or older version, set on "true" private ServerRequest serverRequest; private String drawText; private String url; private WarnWindowType warnWindowType; public ServerToClientCommunicationPacket(final String drawText) { this.serverRequest = ServerRequest.SC_SERVER_REQUEST_SET_DRAW_TEXT; this.drawText = drawText; } public ServerToClientCommunicationPacket(final String strValue, ServerRequest serverRequest) { this.serverRequest = serverRequest; if(serverRequest == ServerRequest.SC_SERVER_REQUEST_OPEN_URL) { this.url = strValue; } else if(serverRequest == ServerRequest.SC_SERVER_REQUEST_SET_DRAW_TEXT) { this.drawText = strValue; } } public ServerToClientCommunicationPacket(final WarnWindowType warnWindowType, final String warnMessage) { this.serverRequest = ServerRequest.SC_SERVER_REQUEST_SHOW_CUSTOM_WARN_MESSAGE; this.warnWindowType = warnWindowType; this.drawText = warnMessage; } @Override public boolean write(PacketWriter packet) { OutgoingPackets.DUMMY.writeId(packet); packet.writeC(serverRequest.ordinal()); // Needed server request switch(serverRequest) { case SC_SERVER_REQUEST_SET_DRAW_TEXT: packet.writeS(drawText); break; case SC_SERVER_REQUEST_SHOW_CUSTOM_WARN_MESSAGE: packet.writeC(warnWindowType.ordinal()); packet.writeS(drawText); break; case SC_SERVER_REQUEST_OPEN_URL: packet.writeS(url); break; } return true; } public static enum ServerRequest { SC_SERVER_REQUEST_SET_DRAW_TEXT, SC_SERVER_REQUEST_SHOW_CUSTOM_WARN_MESSAGE, SC_SERVER_REQUEST_OPEN_URL, } public static enum WarnWindowType { UL2CW_DEFAULT, UL2CW_CLOSE_WINDOW, } } а файлы для клиента подскажи как сделать протокол 338 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Grek 63 Опубликовано 17 февраля, 2022 и какие либы итд куда закинуть надо? подскажите Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Davinsga 6 Опубликовано 17 февраля, 2022 12 часов назад, Grek сказал: а файлы для клиента подскажи как сделать протокол 338 Ставим на пк Visual Studio с++ делаем декомпил пишем свою библиотеку или же если она есть то правим ip на себя Dsetup.dll и тд. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 17 февраля, 2022 17 часов назад, Grek сказал: а файлы для клиента подскажи как сделать протокол 338 Как сделать файлы для клиента подскажет скоре всего Str4he0 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Grek 63 Опубликовано 17 февраля, 2022 3 минуты назад, Yarpi сказал: Как сделать файлы для клиента подскажет скоре всего Str4he0 а какие нибудь либы надо кидать в сам сервер? Подскажи если да то какие. Да если у него будет время может сделает. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 17 февраля, 2022 4 минуты назад, Grek сказал: а какие нибудь либы надо кидать в сам сервер? Подскажи если да то какие. Да если у него будет время может сделает. Конечно нужно. Я только расписал что и в каких файлах я изменил. Там же в мануале "стрикс платформ" написано что такие то либы нужно закинуть в папку либс сервера. Ну и подключить их не забудь. 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Grek 63 Опубликовано 17 февраля, 2022 3 минуты назад, Yarpi сказал: Конечно нужно. Я только расписал что и в каких файлах я изменил. Там же в мануале "стрикс платформ" написано что такие то либы нужно закинуть в папку либс сервера. Ну и подключить их не забудь. А можешь пж скинуть либы, в первом посте ссылки не рабочие, тут или в лс спасибо. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 17 февраля, 2022 41 минуту назад, Grek сказал: А можешь пж скинуть либы, в первом посте ссылки не рабочие, тут или в лс спасибо. https://www.mediafire.com/file/3zakz2hxny2j8h9/Strix-Platform-Full.zip/file Ссылку взял с второй страницы данного поста 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Grek 63 Опубликовано 17 февраля, 2022 1 час назад, Yarpi сказал: https://www.mediafire.com/file/3zakz2hxny2j8h9/Strix-Platform-Full.zip/file Ссылку взял с второй страницы данного поста у тебя получилось адаптировать под мобиуса и запустить? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 17 февраля, 2022 37 минут назад, Grek сказал: у тебя получилось адаптировать под мобиуса и запустить? Северную часть вроде бы да. Покрайне мере без клиент защиты не пускает. А с клиент защитой не реагирует на логин и пароль. Делал под ГК 110п. Мб косяк в подключении защиты. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
KillMilk 257 Опубликовано 17 февраля, 2022 (изменено) 36 минут назад, Yarpi сказал: Северную часть вроде бы да. Покрайне мере без клиент защиты не пускает. А с клиент защитой не реагирует на логин и пароль. Делал под ГК 110п. Мб косяк в подключении защиты. за сегодня 22:24 по МСК по серверу обновлений уже 1723 запуска клиента, и люди успешно заходят на сервер. Почему не заходит у Вас ищите причину Изменено 17 февраля, 2022 пользователем Str4he0 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Yarpi 82 Опубликовано 17 февраля, 2022 2 минуты назад, Str4he0 сказал: за сегодня 22:24 по МСК по серверу обновлений уже 1723 запуска клиента, и люди успешно заходят на сервер. Почему не заходит у Вас ищите причину Вот и ищу причину) пока без результатно.) но я руки не опускаю) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
M1SHA 136 Опубликовано 17 февраля, 2022 Как можно юзать такое гавнище предоставленное автором? неужели у людей денег нехватает купить норм продукт от акуму?* Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты