Addition of Disconnection class.
Adapted from: L2jUnity free files.
This commit is contained in:
parent
a117a04126
commit
c5b6a0d7c9
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2AccessLevel;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -129,7 +130,7 @@ public final class AdminChangeAccessLevel implements IAdminCommandHandler
|
||||
{
|
||||
player.setAccessLevel(lvl, false, true);
|
||||
player.sendMessage("Your character has been banned. Bye.");
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package handlers.admincommandhandlers;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* This class handles following admin commands: - character_disconnect = disconnects target player
|
||||
@ -68,7 +69,7 @@ public class AdminDisconnect implements IAdminCommandHandler
|
||||
{
|
||||
activeChar.sendMessage("Character " + player.getName() + " disconnected from server.");
|
||||
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ package handlers.admincommandhandlers;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
public class AdminKick implements IAdminCommandHandler
|
||||
{
|
||||
@ -44,11 +44,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
final L2PcInstance plyr = L2World.getInstance().getPlayer(player);
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
activeChar.sendMessage("You kicked " + plyr.getName() + " from the game.");
|
||||
}
|
||||
}
|
||||
@ -61,7 +57,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
if (!player.isGM())
|
||||
{
|
||||
counter++;
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
activeChar.sendMessage("Kicked " + counter + " players.");
|
||||
|
@ -21,7 +21,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.handler.AdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
@ -31,6 +30,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -170,11 +170,7 @@ public class AdminMenu implements IAdminCommandHandler
|
||||
String text;
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
text = "You kicked " + plyr.getName() + " from the game.";
|
||||
}
|
||||
else
|
||||
|
@ -22,6 +22,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -58,7 +59,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -90,7 +91,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
*/
|
||||
private static void applyToPlayer(L2PcInstance player)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ package handlers.telnethandlers.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.telnet.ITelnetCommand;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -49,7 +50,7 @@ public class Kick implements ITelnetCommand
|
||||
final L2PcInstance player = L2World.getInstance().getPlayer(args[0]);
|
||||
if (player != null)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return "Player has been successfully kicked.";
|
||||
}
|
||||
return "Couldn't find player with such name.";
|
||||
|
@ -562,15 +562,8 @@ public class LoginServerThread extends Thread
|
||||
final L2GameClient client = _accountsInGameServer.get(account);
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.getActiveChar().logout();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
ACCOUNTING_LOGGER.info(getClass().getSimpleName() + ": Kicked by login, " + client);
|
||||
ACCOUNTING_LOGGER.info("Kicked by login, " + client);
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||
import com.l2jmobius.gameserver.model.olympiad.Olympiad;
|
||||
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.EventLoopGroupManager;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
@ -610,27 +609,7 @@ public class Shutdown extends Thread
|
||||
{
|
||||
for (L2PcInstance player : L2World.getInstance().getPlayers())
|
||||
{
|
||||
// Logout Character
|
||||
try
|
||||
{
|
||||
final L2GameClient client = player.getClient();
|
||||
if ((client != null) && !client.isDetached())
|
||||
{
|
||||
client.close(ServerClose.STATIC_PACKET);
|
||||
client.setActiveChar(null);
|
||||
player.setClient(null);
|
||||
}
|
||||
else if ((client == null) || client.isDetached())
|
||||
// player is probably a bot - force logout
|
||||
{
|
||||
player.logout();
|
||||
}
|
||||
player.deleteMe();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed logour char " + player, t);
|
||||
}
|
||||
Disconnection.of(player).defaultSequence(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.TradeItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
public class OfflineTradersTable
|
||||
@ -49,6 +50,10 @@ public class OfflineTradersTable
|
||||
private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
|
||||
private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE `charId`=?";
|
||||
|
||||
protected OfflineTradersTable()
|
||||
{
|
||||
}
|
||||
|
||||
public void storeOffliners()
|
||||
{
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -300,7 +305,7 @@ public class OfflineTradersTable
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error loading trader: " + player, e);
|
||||
if (player != null)
|
||||
{
|
||||
player.deleteMe();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,11 +475,11 @@ public class OfflineTradersTable
|
||||
*/
|
||||
public static OfflineTradersTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final OfflineTradersTable _instance = new OfflineTradersTable();
|
||||
protected static final OfflineTradersTable INSTANCE = new OfflineTradersTable();
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,12 @@ public final class AntiFeedManager
|
||||
return false;
|
||||
}
|
||||
|
||||
// Players in offline mode should't be valid targets.
|
||||
if (targetPlayer.getClient().isDetached())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((Config.ANTIFEED_INTERVAL > 0) && _lastDeathTimes.containsKey(targetPlayer.getObjectId()))
|
||||
{
|
||||
if ((System.currentTimeMillis() - _lastDeathTimes.get(targetPlayer.getObjectId())) < Config.ANTIFEED_INTERVAL)
|
||||
@ -211,7 +217,7 @@ public final class AntiFeedManager
|
||||
*/
|
||||
public final void onDisconnect(L2GameClient client)
|
||||
{
|
||||
if ((client == null) || client.isDetached())
|
||||
if ((client == null) || (client.getConnectionAddress() == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
@ -143,8 +144,8 @@ public final class L2World
|
||||
final L2PcInstance existingPlayer = _allPlayers.putIfAbsent(object.getObjectId(), newPlayer);
|
||||
if (existingPlayer != null)
|
||||
{
|
||||
existingPlayer.logout();
|
||||
newPlayer.logout();
|
||||
Disconnection.of(existingPlayer).defaultSequence(false);
|
||||
Disconnection.of(newPlayer).defaultSequence(false);
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Duplicate character!? Disconnected both characters (" + newPlayer.getName() + ")");
|
||||
}
|
||||
else if (Config.FACTION_SYSTEM_ENABLED)
|
||||
|
@ -131,6 +131,7 @@ import com.l2jmobius.gameserver.model.stats.MoveType;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneRegion;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Attack;
|
||||
@ -3287,7 +3288,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
if (isPlayer())
|
||||
{
|
||||
getActingPlayer().logout();
|
||||
Disconnection.of(getActingPlayer()).defaultSequence(false);
|
||||
}
|
||||
else if (isSummon())
|
||||
{
|
||||
|
@ -257,6 +257,7 @@ import com.l2jmobius.gameserver.model.variables.AccountVariables;
|
||||
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractHtmlPacket;
|
||||
@ -292,7 +293,6 @@ import com.l2jmobius.gameserver.network.serverpackets.HennaInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ItemList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NicknameChanged;
|
||||
@ -311,7 +311,6 @@ import com.l2jmobius.gameserver.network.serverpackets.RecipeShopMsg;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopSellList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RelationChanged;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ride;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SetupGauge;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ShortCutInit;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
|
||||
@ -803,6 +802,8 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
private final Fishing _fishing = new Fishing(this);
|
||||
|
||||
private Future<?> _autoSaveTask = null;
|
||||
|
||||
public void setPvpFlagLasts(long time)
|
||||
{
|
||||
_pvpFlagLasts = time;
|
||||
@ -1253,38 +1254,6 @@ public final class L2PcInstance extends L2Playable
|
||||
_inCraftMode = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Logout Task:
|
||||
* <ul>
|
||||
* <li>Remove player from world</li>
|
||||
* <li>Save player data into DB</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void logout()
|
||||
{
|
||||
logout(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Logout Task:
|
||||
* <ul>
|
||||
* <li>Remove player from world</li>
|
||||
* <li>Save player data into DB</li>
|
||||
* </ul>
|
||||
* @param closeClient
|
||||
*/
|
||||
public void logout(boolean closeClient)
|
||||
{
|
||||
try
|
||||
{
|
||||
closeNetConnection(closeClient);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on logout(): " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a table containing all Common L2RecipeList of the L2PcInstance.
|
||||
*/
|
||||
@ -3975,33 +3944,6 @@ public final class L2PcInstance extends L2Playable
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the active connection with the client.
|
||||
* @param closeClient
|
||||
*/
|
||||
private void closeNetConnection(boolean closeClient)
|
||||
{
|
||||
final L2GameClient client = _client;
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.cleanMe(true);
|
||||
}
|
||||
else if (client.getChannel().isActive())
|
||||
{
|
||||
if (closeClient)
|
||||
{
|
||||
client.close(LeaveWorld.STATIC_PACKET);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(ServerClose.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Location getCurrentSkillWorldPosition()
|
||||
{
|
||||
return _currentSkillWorldPosition;
|
||||
@ -6824,6 +6766,8 @@ public final class L2PcInstance extends L2Playable
|
||||
player.startOnlineTimeUpdateTask();
|
||||
|
||||
player.setOnlineStatus(true, false);
|
||||
|
||||
player.startAutoSaveTask();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -8102,6 +8046,61 @@ public final class L2PcInstance extends L2Playable
|
||||
return isInCategory(CategoryType.SIXTH_CLASS_GROUP);
|
||||
}
|
||||
|
||||
private void startAutoSaveTask()
|
||||
{
|
||||
if ((Config.CHAR_DATA_STORE_INTERVAL > 0) && (_autoSaveTask == null))
|
||||
{
|
||||
_autoSaveTask = ThreadPoolManager.scheduleAtFixedRate(this::autoSave, 300_000L, TimeUnit.MINUTES.toMillis(Config.CHAR_DATA_STORE_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
private void stopAutoSaveTask()
|
||||
{
|
||||
if (_autoSaveTask != null)
|
||||
{
|
||||
_autoSaveTask.cancel(false);
|
||||
_autoSaveTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void autoSave()
|
||||
{
|
||||
storeMe();
|
||||
storeRecommendations();
|
||||
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getInventory().updateDatabase();
|
||||
getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canLogout()
|
||||
{
|
||||
if (hasItemRequest())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLocked())
|
||||
{
|
||||
_log.warning("Player " + getName() + " tried to restart/logout during class change.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(this) && !(isGM() && Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isBlockedFromExit())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if the L2PcInstance is autoAttackable.<br>
|
||||
* <B><U>Actions</U>:</B>
|
||||
@ -10691,28 +10690,19 @@ public final class L2PcInstance extends L2Playable
|
||||
* <li>If the L2PcInstance is in observer mode, set its position to its position before entering in observer mode</li>
|
||||
* <li>Set the online Flag to True or False and update the characters table of the database with online status and lastAccess</li>
|
||||
* <li>Stop the HP/MP/CP Regeneration task</li>
|
||||
* <li>Cancel Crafting, Attak or Cast</li>
|
||||
* <li>Cancel Crafting, Attack or Cast</li>
|
||||
* <li>Remove the L2PcInstance from the world</li>
|
||||
* <li>Stop Party and Unsummon Pet</li>
|
||||
* <li>Update database with items in its inventory and remove them from the world</li>
|
||||
* <li>Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI</li>
|
||||
* <li>Close the connection with the client</li>
|
||||
* </ul>
|
||||
* <br>
|
||||
* Remember this method is not to be used to half-ass disconnect players! This method is dedicated only to erase the player from the world.<br>
|
||||
* If you intend to disconnect a player please use {@link Disconnection}
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
cleanup();
|
||||
storeMe();
|
||||
|
||||
// Stop all passives and augment options without broadcasting changes.
|
||||
getEffectList().stopAllPassives(false, false);
|
||||
getEffectList().stopAllOptions(false, false);
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
private synchronized void cleanup()
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(this), this);
|
||||
|
||||
@ -11093,6 +11083,15 @@ public final class L2PcInstance extends L2Playable
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerMentorStatus(this, false), this);
|
||||
}
|
||||
|
||||
// we store all data from players who are disconnected while in an event in order to restore it in the next login
|
||||
if (L2Event.isParticipant(this))
|
||||
{
|
||||
L2Event.savePlayerEventStatus(this);
|
||||
}
|
||||
|
||||
// Anti Feed
|
||||
AntiFeedManager.getInstance().onDisconnect(getClient());
|
||||
|
||||
try
|
||||
{
|
||||
notifyFriends(L2FriendStatus.MODE_OFFLINE);
|
||||
@ -11102,6 +11101,14 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on deleteMe() notifyFriends: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
// Stop all passives and augment options
|
||||
getEffectList().stopAllPassives(false, false);
|
||||
getEffectList().stopAllOptions(false, false);
|
||||
|
||||
stopAutoSaveTask();
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
public int getInventoryLimit()
|
||||
|
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* Task that handles illegal player actions.
|
||||
@ -86,7 +87,7 @@ public final class IllegalPlayerActionTask implements Runnable
|
||||
}
|
||||
case KICK:
|
||||
{
|
||||
_actor.logout(false);
|
||||
Disconnection.of(_actor).defaultSequence(false);
|
||||
break;
|
||||
}
|
||||
case KICKBAN:
|
||||
|
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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 com.l2jmobius.gameserver.network;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
|
||||
/**
|
||||
* @author NB4L1
|
||||
*/
|
||||
public final class Disconnection
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(Disconnection.class.getName());
|
||||
|
||||
public static L2GameClient getClient(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
if (client != null)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
if (activeChar != null)
|
||||
{
|
||||
return activeChar.getClient();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static L2PcInstance getActiveChar(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
if (activeChar != null)
|
||||
{
|
||||
return activeChar;
|
||||
}
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
return client.getActiveChar();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private final L2GameClient _client;
|
||||
private final L2PcInstance _activeChar;
|
||||
|
||||
private Disconnection(L2GameClient client)
|
||||
{
|
||||
this(client, null);
|
||||
}
|
||||
|
||||
public static Disconnection of(L2GameClient client)
|
||||
{
|
||||
return new Disconnection(client);
|
||||
}
|
||||
|
||||
private Disconnection(L2PcInstance activeChar)
|
||||
{
|
||||
this(null, activeChar);
|
||||
}
|
||||
|
||||
public static Disconnection of(L2PcInstance activeChar)
|
||||
{
|
||||
return new Disconnection(activeChar);
|
||||
}
|
||||
|
||||
private Disconnection(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
_client = getClient(client, activeChar);
|
||||
_activeChar = getActiveChar(client, activeChar);
|
||||
|
||||
if (_client != null)
|
||||
{
|
||||
_client.setActiveChar(null);
|
||||
}
|
||||
|
||||
if (_activeChar != null)
|
||||
{
|
||||
_activeChar.setClient(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static Disconnection of(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
return new Disconnection(client, activeChar);
|
||||
}
|
||||
|
||||
public Disconnection storeMe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
_activeChar.storeMe();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection deleteMe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(_activeChar), _activeChar);
|
||||
_activeChar.deleteMe();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection close(boolean toLoginScreen)
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.close(toLoginScreen);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection close(IClientOutgoingPacket packet)
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.close(packet);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void defaultSequence(boolean toLoginScreen)
|
||||
{
|
||||
defaultSequence();
|
||||
close(toLoginScreen);
|
||||
}
|
||||
|
||||
public void defaultSequence(IClientOutgoingPacket packet)
|
||||
{
|
||||
defaultSequence();
|
||||
close(packet);
|
||||
}
|
||||
|
||||
private void defaultSequence()
|
||||
{
|
||||
storeMe();
|
||||
deleteMe();
|
||||
}
|
||||
|
||||
public void onDisconnection()
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> defaultSequence(), _activeChar.canLogout() ? 0 : AttackStanceTaskManager.COMBAT_TIME);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,9 +21,6 @@ import java.net.InetSocketAddress;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -33,36 +30,28 @@ import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.commons.network.ChannelInboundHandler;
|
||||
import com.l2jmobius.commons.network.ICrypt;
|
||||
import com.l2jmobius.commons.network.IIncomingPacket;
|
||||
import com.l2jmobius.commons.network.IOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.LoginServerThread.SessionKey;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.enums.CharacterDeleteFailType;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.CommissionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MailManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MentorManager;
|
||||
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
import com.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.security.SecondaryPasswordAuth;
|
||||
import com.l2jmobius.gameserver.util.FloodProtectors;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -74,7 +63,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
protected static final Logger LOGGER = Logger.getLogger(L2GameClient.class.getName());
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private final int _objectId;
|
||||
|
||||
@ -88,20 +77,15 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
private SecondaryPasswordAuth _secondaryAuth;
|
||||
private ClientHardwareInfoHolder _hardwareInfo;
|
||||
private boolean _isAuthedGG;
|
||||
private final long _connectionStartTime = System.currentTimeMillis();
|
||||
private CharSelectInfoPackage[] _charSlotMapping = null;
|
||||
|
||||
// flood protectors
|
||||
private final FloodProtectors _floodProtectors = new FloodProtectors(this);
|
||||
|
||||
// Task
|
||||
protected final ScheduledFuture<?> _autoSaveInDB;
|
||||
protected ScheduledFuture<?> _cleanupTask = null;
|
||||
|
||||
// Crypt
|
||||
private final Crypt _crypt;
|
||||
|
||||
private boolean _isDetached = false;
|
||||
private volatile boolean _isDetached = false;
|
||||
|
||||
private boolean _protocol;
|
||||
|
||||
@ -111,14 +95,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
_objectId = IdFactory.getInstance().getNextId();
|
||||
_crypt = new Crypt(this);
|
||||
if (Config.CHAR_DATA_STORE_INTERVAL > 0)
|
||||
{
|
||||
_autoSaveInDB = ThreadPoolManager.scheduleAtFixedRate(new AutoSaveTask(), 300000L, Config.CHAR_DATA_STORE_INTERVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_autoSaveInDB = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getObjectId()
|
||||
@ -135,23 +111,18 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
_addr = address.getAddress();
|
||||
_channel = ctx.channel();
|
||||
LOGGER.finer("Client Connected: " + ctx.channel());
|
||||
LOG_ACCOUNTING.finer("Client Connected: " + ctx.channel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx)
|
||||
{
|
||||
LOGGER.finer("Client Disconnected: " + ctx.channel());
|
||||
LOG_ACCOUNTING.finer("Client Disconnected: " + ctx.channel());
|
||||
|
||||
// no long running tasks here, do it async
|
||||
try
|
||||
{
|
||||
ThreadPoolManager.execute(new DisconnectTask());
|
||||
}
|
||||
catch (RejectedExecutionException e)
|
||||
{
|
||||
// server is closing
|
||||
}
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
|
||||
Disconnection.of(this).onDisconnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -172,6 +143,25 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
@ -193,19 +183,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _addr;
|
||||
}
|
||||
|
||||
public long getConnectionStartTime()
|
||||
{
|
||||
return _connectionStartTime;
|
||||
}
|
||||
|
||||
public L2PcInstance getActiveChar()
|
||||
{
|
||||
return _activeChar;
|
||||
}
|
||||
|
||||
public void setActiveChar(L2PcInstance pActiveChar)
|
||||
public void setActiveChar(L2PcInstance activeChar)
|
||||
{
|
||||
_activeChar = pActiveChar;
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
public ReentrantLock getActiveCharLock()
|
||||
@ -228,9 +213,9 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _isAuthedGG;
|
||||
}
|
||||
|
||||
public void setAccountName(String pAccountName)
|
||||
public void setAccountName(String activeChar)
|
||||
{
|
||||
_accountName = pAccountName;
|
||||
_accountName = activeChar;
|
||||
|
||||
if (SecondaryAuthData.getInstance().isEnabled())
|
||||
{
|
||||
@ -287,16 +272,16 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
|
||||
/**
|
||||
* Method to handle character deletion
|
||||
* @param charslot
|
||||
* @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 charslot)
|
||||
public CharacterDeleteFailType markToDeleteChar(int characterSlot)
|
||||
{
|
||||
final int objectId = getObjectIdForSlot(charslot);
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return CharacterDeleteFailType.UNKNOWN;
|
||||
@ -354,38 +339,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
_logAccounting.info("Delete, " + objectId + ", " + this);
|
||||
LOG_ACCOUNTING.info("Delete, " + objectId + ", " + this);
|
||||
return CharacterDeleteFailType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the L2PcInstance to the database.
|
||||
*/
|
||||
public void saveCharToDisk()
|
||||
public void restore(int characterSlot)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (getActiveChar() != null)
|
||||
{
|
||||
getActiveChar().storeMe();
|
||||
getActiveChar().storeRecommendations();
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getActiveChar().getInventory().updateDatabase();
|
||||
getActiveChar().getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error saving character..", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void markRestoredChar(int charslot)
|
||||
{
|
||||
final int objid = getObjectIdForSlot(charslot);
|
||||
if (objid < 0)
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -393,7 +354,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?"))
|
||||
{
|
||||
statement.setInt(1, objid);
|
||||
statement.setInt(1, objectId);
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -401,7 +362,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
LOGGER.log(Level.SEVERE, "Error restoring character.", e);
|
||||
}
|
||||
|
||||
_logAccounting.info("Restore, " + objid + ", " + this);
|
||||
LOG_ACCOUNTING.info("Restore, " + objectId + ", " + this);
|
||||
}
|
||||
|
||||
public static void deleteCharByObjId(int objid)
|
||||
@ -555,38 +516,30 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
public L2PcInstance loadCharFromDisk(int charslot)
|
||||
public L2PcInstance load(int characterSlot)
|
||||
{
|
||||
final int objId = getObjectIdForSlot(charslot);
|
||||
if (objId < 0)
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
L2PcInstance character = L2World.getInstance().getPlayer(objId);
|
||||
if (character != null)
|
||||
L2PcInstance player = L2World.getInstance().getPlayer(objectId);
|
||||
if (player != null)
|
||||
{
|
||||
// exploit prevention, should not happens in normal way
|
||||
LOGGER.severe("Attempt of double login: " + character.getName() + "(" + objId + ") " + getAccountName());
|
||||
if (character.getClient() != null)
|
||||
{
|
||||
character.getClient().closeNow();
|
||||
}
|
||||
else
|
||||
{
|
||||
character.deleteMe();
|
||||
}
|
||||
LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + getAccountName());
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
character = L2PcInstance.load(objId);
|
||||
if (character == null)
|
||||
player = L2PcInstance.load(objectId);
|
||||
if (player == null)
|
||||
{
|
||||
LOGGER.severe("could not restore in slot: " + charslot);
|
||||
LOGGER.severe("Could not restore in slot: " + characterSlot);
|
||||
}
|
||||
|
||||
// setCharacter(character);
|
||||
return character;
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -611,47 +564,21 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _secondaryAuth;
|
||||
}
|
||||
|
||||
public void close(IOutgoingPacket packet)
|
||||
{
|
||||
if (packet != null)
|
||||
{
|
||||
_channel.writeAndFlush(packet);
|
||||
}
|
||||
_channel.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charslot
|
||||
* @param characterSlot
|
||||
* @return
|
||||
*/
|
||||
private int getObjectIdForSlot(int charslot)
|
||||
private int getObjectIdForSlot(int characterSlot)
|
||||
{
|
||||
final CharSelectInfoPackage info = getCharSelection(charslot);
|
||||
final CharSelectInfoPackage info = getCharSelection(characterSlot);
|
||||
if (info == null)
|
||||
{
|
||||
LOGGER.warning(toString() + " tried to delete Character in slot " + charslot + " but no characters exits at that slot.");
|
||||
LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot.");
|
||||
return -1;
|
||||
}
|
||||
return info.getObjectId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close client connection with {@link ServerClose} packet
|
||||
*/
|
||||
public void closeNow()
|
||||
{
|
||||
_isDetached = true; // prevents more packets execution
|
||||
close(ServerClose.STATIC_PACKET);
|
||||
synchronized (this)
|
||||
{
|
||||
if (_cleanupTask != null)
|
||||
{
|
||||
cancelCleanup();
|
||||
}
|
||||
_cleanupTask = ThreadPoolManager.schedule(new CleanupTask(), 0); // instant
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the best possible string representation of this client.
|
||||
*/
|
||||
@ -688,209 +615,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
protected class DisconnectTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
boolean fast = true;
|
||||
try
|
||||
{
|
||||
if ((getActiveChar() != null) && !isDetached())
|
||||
{
|
||||
setDetached(true);
|
||||
if (offlineMode(getActiveChar()))
|
||||
{
|
||||
getActiveChar().leaveParty();
|
||||
OlympiadManager.getInstance().unRegisterNoble(getActiveChar());
|
||||
|
||||
// If the L2PcInstance has Pet, unsummon it
|
||||
L2Summon pet = getActiveChar().getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(getActiveChar());
|
||||
pet = getActiveChar().getPet();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
getActiveChar().getServitors().values().forEach(s ->
|
||||
{
|
||||
s.setRestoreSummon(true);
|
||||
s.unSummon(getActiveChar());
|
||||
});
|
||||
|
||||
if (Config.OFFLINE_SET_NAME_COLOR)
|
||||
{
|
||||
getActiveChar().getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
|
||||
getActiveChar().broadcastUserInfo();
|
||||
}
|
||||
|
||||
if (getActiveChar().getOfflineStartTime() == 0)
|
||||
{
|
||||
getActiveChar().setOfflineStartTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// Store trade on exit, if realtime saving is enabled.
|
||||
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
|
||||
{
|
||||
OfflineTradersTable.onTransaction(getActiveChar(), false, true);
|
||||
}
|
||||
|
||||
_logAccounting.info("Entering offline mode, " + L2GameClient.this);
|
||||
return;
|
||||
}
|
||||
fast = !getActiveChar().isInCombat() && !getActiveChar().isLocked();
|
||||
}
|
||||
cleanMe(fast);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while disconnecting client.", e1);
|
||||
}
|
||||
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player the player to be check.
|
||||
* @return {@code true} if the player is allowed to remain as off-line shop.
|
||||
*/
|
||||
protected boolean offlineMode(L2PcInstance player)
|
||||
{
|
||||
if (player.isInOlympiadMode() || player.isBlockedFromExit() || player.isJailed() || (player.getVehicle() != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canSetShop = false;
|
||||
switch (player.getPrivateStoreType())
|
||||
{
|
||||
case SELL:
|
||||
case PACKAGE_SELL:
|
||||
case BUY:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
canSetShop = false;
|
||||
}
|
||||
return canSetShop;
|
||||
}
|
||||
|
||||
public void cleanMe(boolean fast)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_cleanupTask == null)
|
||||
{
|
||||
_cleanupTask = ThreadPoolManager.schedule(new CleanupTask(), fast ? 5 : 15000L);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error during cleanup.", e1);
|
||||
}
|
||||
}
|
||||
|
||||
protected class CleanupTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
// we are going to manually save the char bellow thus we can force the cancel
|
||||
if (_autoSaveInDB != null)
|
||||
{
|
||||
_autoSaveInDB.cancel(true);
|
||||
// ThreadPoolManager.getInstance().removeGeneral((Runnable) _autoSaveInDB);
|
||||
}
|
||||
|
||||
if (getActiveChar() != null) // this should only happen on connection loss
|
||||
{
|
||||
if (getActiveChar().isLocked())
|
||||
{
|
||||
LOGGER.warning("Player " + getActiveChar().getName() + " still performing subclass actions during disconnect.");
|
||||
}
|
||||
|
||||
// we store all data from players who are disconnected while in an event in order to restore it in the next login
|
||||
if (L2Event.isParticipant(getActiveChar()))
|
||||
{
|
||||
L2Event.savePlayerEventStatus(getActiveChar());
|
||||
}
|
||||
|
||||
if (getActiveChar().isOnline())
|
||||
{
|
||||
getActiveChar().deleteMe();
|
||||
AntiFeedManager.getInstance().onDisconnect(L2GameClient.this);
|
||||
}
|
||||
|
||||
// prevent closing again
|
||||
getActiveChar().setClient(null);
|
||||
}
|
||||
setActiveChar(null);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while cleanup client.", e1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class AutoSaveTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
final L2PcInstance player = getActiveChar();
|
||||
if ((player != null) && player.isOnline()) // safety precaution
|
||||
{
|
||||
saveCharToDisk();
|
||||
final L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.storeMe();
|
||||
}
|
||||
player.getServitors().values().forEach(L2Summon::storeMe);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error on AutoSaveTask.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProtocolOk()
|
||||
{
|
||||
return _protocol;
|
||||
@ -901,20 +625,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
_protocol = b;
|
||||
}
|
||||
|
||||
public boolean handleCheat(String punishment)
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(_activeChar, toString() + ": " + punishment, Config.DEFAULT_PUNISH);
|
||||
return true;
|
||||
}
|
||||
|
||||
final Logger logAudit = Logger.getLogger("audit");
|
||||
logAudit.info("AUDIT: Client " + toString() + " kicked for reason: " + punishment);
|
||||
closeNow();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setClientTracert(int[][] tracert)
|
||||
{
|
||||
trace = tracert;
|
||||
@ -925,17 +635,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return trace;
|
||||
}
|
||||
|
||||
private boolean cancelCleanup()
|
||||
{
|
||||
final Future<?> task = _cleanupTask;
|
||||
if (task != null)
|
||||
{
|
||||
_cleanupTask = null;
|
||||
return task.cancel(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendActionFailed()
|
||||
{
|
||||
sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
@ -54,7 +54,7 @@ public final class AuthLogin implements IClientIncomingPacket
|
||||
{
|
||||
if (_loginName.isEmpty() || !client.isProtocolOk())
|
||||
{
|
||||
client.close(null);
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerCreate;
|
||||
import com.l2jmobius.gameserver.model.items.PcItemTemplate;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharCreateFail;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharCreateOk;
|
||||
@ -333,7 +334,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
{
|
||||
newChar.getVariables().set("intro_god_video", true);
|
||||
}
|
||||
newChar.deleteMe();
|
||||
Disconnection.of(client, newChar).storeMe().deleteMe();
|
||||
|
||||
final CharSelectionInfo cl = new CharSelectionInfo(client.getAccountName(), client.getSessionId().playOkID1);
|
||||
client.setCharSelection(cl.getCharInfo());
|
||||
|
@ -47,7 +47,7 @@ public final class CharacterRestore implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
client.markRestoredChar(_charSlot);
|
||||
client.restore(_charSlot);
|
||||
final CharSelectionInfo cl = new CharSelectionInfo(client.getAccountName(), client.getSessionId().playOkID1, 0);
|
||||
client.sendPacket(cl);
|
||||
client.setCharSelection(cl.getCharInfo());
|
||||
|
@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharSelected;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
@ -146,7 +147,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
}
|
||||
|
||||
// load up character from disk
|
||||
final L2PcInstance cha = client.loadCharFromDisk(_charSlot);
|
||||
final L2PcInstance cha = client.load(_charSlot);
|
||||
if (cha == null)
|
||||
{
|
||||
return; // handled in L2GameClient
|
||||
@ -161,7 +162,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
final TerminateReturn terminate = EventDispatcher.getInstance().notifyEvent(new OnPlayerSelect(cha, cha.getObjectId(), cha.getName(), client), Containers.Players(), TerminateReturn.class);
|
||||
if ((terminate != null) && terminate.terminate())
|
||||
{
|
||||
cha.deleteMe();
|
||||
Disconnection.of(cha).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
|
||||
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
|
||||
@ -137,7 +138,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
if (activeChar == null)
|
||||
{
|
||||
_log.warning("EnterWorld failed! activeChar returned 'null'.");
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -648,7 +649,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
{
|
||||
if (client.getHardwareInfo() == null)
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
}, 5000);
|
||||
|
@ -18,14 +18,12 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -33,7 +31,7 @@ import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
*/
|
||||
public final class Logout implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@ -47,42 +45,21 @@ public final class Logout implements IClientIncomingPacket
|
||||
final L2PcInstance player = client.getActiveChar();
|
||||
if (player == null)
|
||||
{
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasItemRequest())
|
||||
if (!player.canLogout())
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isLocked())
|
||||
LOG_ACCOUNTING.info("Logged out, " + client);
|
||||
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to logout during class change.");
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
Disconnection.of(client, player).defaultSequence(false);
|
||||
}
|
||||
|
||||
// Don't allow leaving if player is fighting
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player))
|
||||
{
|
||||
if (!player.isGM() || (player.isGM() && !Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_EXIT_THE_GAME_WHILE_IN_COMBAT);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (L2Event.isParticipant(player))
|
||||
{
|
||||
player.sendMessage("A superior power doesn't allow you to leave the event.");
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
_logAccounting.info("Disconnected, " + client);
|
||||
|
||||
player.logout();
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public final class ProtocolVersion implements IClientIncomingPacket
|
||||
if (_version == -2)
|
||||
{
|
||||
// this is just a ping attempt from the new C2 client
|
||||
client.close(null);
|
||||
client.closeNow();
|
||||
}
|
||||
else if (!Config.PROTOCOL_LIST.contains(_version))
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcMenuSelect;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerBypass;
|
||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
@ -86,7 +87,7 @@ public final class RequestBypassToServer implements IClientIncomingPacket
|
||||
if (_command.isEmpty())
|
||||
{
|
||||
_log.warning("Player " + activeChar.getName() + " sent empty bypass!");
|
||||
activeChar.logout();
|
||||
Disconnection.of(client, activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -93,7 +94,7 @@ public final class RequestHardWareInfo implements IClientIncomingPacket
|
||||
}
|
||||
if (count >= Config.MAX_PLAYERS_PER_HWID)
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -18,16 +18,15 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharSelectionInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RestartResponse;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -35,7 +34,7 @@ import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
*/
|
||||
public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@ -52,43 +51,20 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasItemRequest())
|
||||
if (!player.canLogout())
|
||||
{
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isLocked())
|
||||
LOG_ACCOUNTING.info("Logged out, " + client);
|
||||
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to restart during class change.");
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
Disconnection.of(client, player).storeMe().deleteMe();
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) && !(player.isGM() && Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_RESTART_WHILE_IN_COMBAT);
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isBlockedFromExit())
|
||||
{
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
_logAccounting.info("Logged out, " + client);
|
||||
|
||||
player.deleteMe();
|
||||
|
||||
client.setActiveChar(null);
|
||||
|
||||
// detach the client from the char so that the connection isnt closed in the deleteMe
|
||||
player.setClient(null);
|
||||
|
||||
AntiFeedManager.getInstance().onDisconnect(client);
|
||||
|
||||
// return the client to the authed status
|
||||
client.setConnectionState(ConnectionState.AUTHENTICATED);
|
||||
|
||||
|
@ -31,6 +31,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerChat;
|
||||
import com.l2jmobius.gameserver.model.events.returns.ChatFilterReturn;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@ -110,7 +111,7 @@ public final class Say2 implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning("Say2: Invalid type: " + _type + " Player : " + activeChar.getName() + " text: " + _text);
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
activeChar.logout();
|
||||
Disconnection.of(activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,7 +119,7 @@ public final class Say2 implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning(activeChar.getName() + ": sending empty text. Possible packet hack!");
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
activeChar.logout();
|
||||
Disconnection.of(activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import java.util.logging.Logger;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ex2ndPasswordAck;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ex2ndPasswordCheck;
|
||||
@ -104,7 +105,7 @@ public class SecondaryPasswordAuth
|
||||
if (passwordExist())
|
||||
{
|
||||
_log.warning("[SecondaryPasswordAuth]" + _activeClient.getAccountName() + " forced savePassword");
|
||||
_activeClient.closeNow();
|
||||
Disconnection.of(_activeClient).defaultSequence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ public class SecondaryPasswordAuth
|
||||
if (!passwordExist())
|
||||
{
|
||||
_log.warning("[SecondaryPasswordAuth]" + _activeClient.getAccountName() + " forced changePassword");
|
||||
_activeClient.closeNow();
|
||||
Disconnection.of(_activeClient).defaultSequence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,8 @@ public class AttackStanceTaskManager
|
||||
|
||||
protected static final Map<L2Character, Long> _attackStanceTasks = new ConcurrentHashMap<>();
|
||||
|
||||
public static final long COMBAT_TIME = 15_000;
|
||||
|
||||
/**
|
||||
* Instantiates a new attack stance task manager.
|
||||
*/
|
||||
@ -106,7 +108,7 @@ public class AttackStanceTaskManager
|
||||
while (iter.hasNext())
|
||||
{
|
||||
e = iter.next();
|
||||
if ((current - e.getValue()) > 15000)
|
||||
if ((current - e.getValue()) > COMBAT_TIME)
|
||||
{
|
||||
actor = e.getKey();
|
||||
if (actor != null)
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -142,14 +143,7 @@ public final class FloodProtectorAction
|
||||
*/
|
||||
private void kickPlayer()
|
||||
{
|
||||
if (_client.getActiveChar() != null)
|
||||
{
|
||||
_client.getActiveChar().logout(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_client.closeNow();
|
||||
}
|
||||
Disconnection.of(_client).defaultSequence(false);
|
||||
|
||||
if (_log.getLevel() == Level.WARNING)
|
||||
{
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 com.l2jmobius.gameserver.util;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
* @author lord_rex
|
||||
*/
|
||||
public final class OfflineTradeUtil
|
||||
{
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private OfflineTradeUtil()
|
||||
{
|
||||
// utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether player is able to enter offline mode.
|
||||
* @param player the player to be check.
|
||||
* @return {@code true} if the player is allowed to remain as off-line shop.
|
||||
*/
|
||||
private static boolean offlineMode(L2PcInstance player)
|
||||
{
|
||||
if ((player == null) || player.isInOlympiadMode() || player.isBlockedFromExit() || player.isJailed() || (player.getVehicle() != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canSetShop = false;
|
||||
switch (player.getPrivateStoreType())
|
||||
{
|
||||
case SELL:
|
||||
case PACKAGE_SELL:
|
||||
case BUY:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
canSetShop = false;
|
||||
}
|
||||
|
||||
// Check whether client is null or player is already in offline mode.
|
||||
final L2GameClient client = player.getClient();
|
||||
if ((client == null) || client.isDetached())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return canSetShop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the disconnection process of offline traders.
|
||||
* @param player
|
||||
* @return {@code true} when player entered offline mode, otherwise {@code false}
|
||||
*/
|
||||
public static boolean enteredOfflineMode(L2PcInstance player)
|
||||
{
|
||||
if (!OfflineTradeUtil.offlineMode(player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2GameClient client = player.getClient();
|
||||
client.setDetached(true);
|
||||
|
||||
player.leaveParty();
|
||||
OlympiadManager.getInstance().unRegisterNoble(player);
|
||||
|
||||
// If the L2PcInstance has Pet, unsummon it
|
||||
L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(player);
|
||||
pet = player.getPet();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
player.getServitors().values().forEach(s ->
|
||||
{
|
||||
s.setRestoreSummon(true);
|
||||
s.unSummon(player);
|
||||
});
|
||||
|
||||
if (Config.OFFLINE_SET_NAME_COLOR)
|
||||
{
|
||||
player.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
|
||||
player.broadcastUserInfo();
|
||||
}
|
||||
|
||||
if (player.getOfflineStartTime() == 0)
|
||||
{
|
||||
player.setOfflineStartTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// Store trade on exit, if realtime saving is enabled.
|
||||
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
|
||||
{
|
||||
OfflineTradersTable.onTransaction(player, false, true);
|
||||
}
|
||||
|
||||
Disconnection.of(player).storeMe().close(false);
|
||||
LOG_ACCOUNTING.info("Entering offline mode, " + client);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2AccessLevel;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -129,7 +130,7 @@ public final class AdminChangeAccessLevel implements IAdminCommandHandler
|
||||
{
|
||||
player.setAccessLevel(lvl, false, true);
|
||||
player.sendMessage("Your character has been banned. Bye.");
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package handlers.admincommandhandlers;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* This class handles following admin commands: - character_disconnect = disconnects target player
|
||||
@ -68,7 +69,7 @@ public class AdminDisconnect implements IAdminCommandHandler
|
||||
{
|
||||
activeChar.sendMessage("Character " + player.getName() + " disconnected from server.");
|
||||
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ package handlers.admincommandhandlers;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
public class AdminKick implements IAdminCommandHandler
|
||||
{
|
||||
@ -44,11 +44,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
final L2PcInstance plyr = L2World.getInstance().getPlayer(player);
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
activeChar.sendMessage("You kicked " + plyr.getName() + " from the game.");
|
||||
}
|
||||
}
|
||||
@ -61,7 +57,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
if (!player.isGM())
|
||||
{
|
||||
counter++;
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
activeChar.sendMessage("Kicked " + counter + " players.");
|
||||
|
@ -21,7 +21,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.handler.AdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
@ -31,6 +30,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -170,11 +170,7 @@ public class AdminMenu implements IAdminCommandHandler
|
||||
String text;
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
text = "You kicked " + plyr.getName() + " from the game.";
|
||||
}
|
||||
else
|
||||
|
@ -22,6 +22,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -58,7 +59,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -90,7 +91,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
*/
|
||||
private static void applyToPlayer(L2PcInstance player)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ package handlers.telnethandlers.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.telnet.ITelnetCommand;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -49,7 +50,7 @@ public class Kick implements ITelnetCommand
|
||||
final L2PcInstance player = L2World.getInstance().getPlayer(args[0]);
|
||||
if (player != null)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return "Player has been successfully kicked.";
|
||||
}
|
||||
return "Couldn't find player with such name.";
|
||||
|
@ -562,15 +562,8 @@ public class LoginServerThread extends Thread
|
||||
final L2GameClient client = _accountsInGameServer.get(account);
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.getActiveChar().logout();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
ACCOUNTING_LOGGER.info(getClass().getSimpleName() + ": Kicked by login, " + client);
|
||||
ACCOUNTING_LOGGER.info("Kicked by login, " + client);
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||
import com.l2jmobius.gameserver.model.olympiad.Olympiad;
|
||||
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.EventLoopGroupManager;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
@ -610,27 +609,7 @@ public class Shutdown extends Thread
|
||||
{
|
||||
for (L2PcInstance player : L2World.getInstance().getPlayers())
|
||||
{
|
||||
// Logout Character
|
||||
try
|
||||
{
|
||||
final L2GameClient client = player.getClient();
|
||||
if ((client != null) && !client.isDetached())
|
||||
{
|
||||
client.close(ServerClose.STATIC_PACKET);
|
||||
client.setActiveChar(null);
|
||||
player.setClient(null);
|
||||
}
|
||||
else if ((client == null) || client.isDetached())
|
||||
// player is probably a bot - force logout
|
||||
{
|
||||
player.logout();
|
||||
}
|
||||
player.deleteMe();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed logour char " + player, t);
|
||||
}
|
||||
Disconnection.of(player).defaultSequence(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.TradeItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
public class OfflineTradersTable
|
||||
@ -49,6 +50,10 @@ public class OfflineTradersTable
|
||||
private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
|
||||
private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE `charId`=?";
|
||||
|
||||
protected OfflineTradersTable()
|
||||
{
|
||||
}
|
||||
|
||||
public void storeOffliners()
|
||||
{
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -300,7 +305,7 @@ public class OfflineTradersTable
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error loading trader: " + player, e);
|
||||
if (player != null)
|
||||
{
|
||||
player.deleteMe();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,11 +475,11 @@ public class OfflineTradersTable
|
||||
*/
|
||||
public static OfflineTradersTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final OfflineTradersTable _instance = new OfflineTradersTable();
|
||||
protected static final OfflineTradersTable INSTANCE = new OfflineTradersTable();
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,12 @@ public final class AntiFeedManager
|
||||
return false;
|
||||
}
|
||||
|
||||
// Players in offline mode should't be valid targets.
|
||||
if (targetPlayer.getClient().isDetached())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((Config.ANTIFEED_INTERVAL > 0) && _lastDeathTimes.containsKey(targetPlayer.getObjectId()))
|
||||
{
|
||||
if ((System.currentTimeMillis() - _lastDeathTimes.get(targetPlayer.getObjectId())) < Config.ANTIFEED_INTERVAL)
|
||||
@ -211,7 +217,7 @@ public final class AntiFeedManager
|
||||
*/
|
||||
public final void onDisconnect(L2GameClient client)
|
||||
{
|
||||
if ((client == null) || client.isDetached())
|
||||
if ((client == null) || (client.getConnectionAddress() == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
@ -143,8 +144,8 @@ public final class L2World
|
||||
final L2PcInstance existingPlayer = _allPlayers.putIfAbsent(object.getObjectId(), newPlayer);
|
||||
if (existingPlayer != null)
|
||||
{
|
||||
existingPlayer.logout();
|
||||
newPlayer.logout();
|
||||
Disconnection.of(existingPlayer).defaultSequence(false);
|
||||
Disconnection.of(newPlayer).defaultSequence(false);
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Duplicate character!? Disconnected both characters (" + newPlayer.getName() + ")");
|
||||
}
|
||||
else if (Config.FACTION_SYSTEM_ENABLED)
|
||||
|
@ -131,6 +131,7 @@ import com.l2jmobius.gameserver.model.stats.MoveType;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneRegion;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Attack;
|
||||
@ -3287,7 +3288,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
if (isPlayer())
|
||||
{
|
||||
getActingPlayer().logout();
|
||||
Disconnection.of(getActingPlayer()).defaultSequence(false);
|
||||
}
|
||||
else if (isSummon())
|
||||
{
|
||||
|
@ -259,6 +259,7 @@ import com.l2jmobius.gameserver.model.variables.AccountVariables;
|
||||
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractHtmlPacket;
|
||||
@ -294,7 +295,6 @@ import com.l2jmobius.gameserver.network.serverpackets.HennaInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ItemList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NicknameChanged;
|
||||
@ -313,7 +313,6 @@ import com.l2jmobius.gameserver.network.serverpackets.RecipeShopMsg;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopSellList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RelationChanged;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ride;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SetupGauge;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ShortCutInit;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
|
||||
@ -805,6 +804,8 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
private final Fishing _fishing = new Fishing(this);
|
||||
|
||||
private Future<?> _autoSaveTask = null;
|
||||
|
||||
public void setPvpFlagLasts(long time)
|
||||
{
|
||||
_pvpFlagLasts = time;
|
||||
@ -1259,38 +1260,6 @@ public final class L2PcInstance extends L2Playable
|
||||
_inCraftMode = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Logout Task:
|
||||
* <ul>
|
||||
* <li>Remove player from world</li>
|
||||
* <li>Save player data into DB</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void logout()
|
||||
{
|
||||
logout(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Logout Task:
|
||||
* <ul>
|
||||
* <li>Remove player from world</li>
|
||||
* <li>Save player data into DB</li>
|
||||
* </ul>
|
||||
* @param closeClient
|
||||
*/
|
||||
public void logout(boolean closeClient)
|
||||
{
|
||||
try
|
||||
{
|
||||
closeNetConnection(closeClient);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on logout(): " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a table containing all Common L2RecipeList of the L2PcInstance.
|
||||
*/
|
||||
@ -3981,33 +3950,6 @@ public final class L2PcInstance extends L2Playable
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the active connection with the client.
|
||||
* @param closeClient
|
||||
*/
|
||||
private void closeNetConnection(boolean closeClient)
|
||||
{
|
||||
final L2GameClient client = _client;
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.cleanMe(true);
|
||||
}
|
||||
else if (client.getChannel().isActive())
|
||||
{
|
||||
if (closeClient)
|
||||
{
|
||||
client.close(LeaveWorld.STATIC_PACKET);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(ServerClose.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Location getCurrentSkillWorldPosition()
|
||||
{
|
||||
return _currentSkillWorldPosition;
|
||||
@ -6831,6 +6773,8 @@ public final class L2PcInstance extends L2Playable
|
||||
player.startOnlineTimeUpdateTask();
|
||||
|
||||
player.setOnlineStatus(true, false);
|
||||
|
||||
player.startAutoSaveTask();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -8109,6 +8053,61 @@ public final class L2PcInstance extends L2Playable
|
||||
return isInCategory(CategoryType.SIXTH_CLASS_GROUP);
|
||||
}
|
||||
|
||||
private void startAutoSaveTask()
|
||||
{
|
||||
if ((Config.CHAR_DATA_STORE_INTERVAL > 0) && (_autoSaveTask == null))
|
||||
{
|
||||
_autoSaveTask = ThreadPoolManager.scheduleAtFixedRate(this::autoSave, 300_000L, TimeUnit.MINUTES.toMillis(Config.CHAR_DATA_STORE_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
private void stopAutoSaveTask()
|
||||
{
|
||||
if (_autoSaveTask != null)
|
||||
{
|
||||
_autoSaveTask.cancel(false);
|
||||
_autoSaveTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void autoSave()
|
||||
{
|
||||
storeMe();
|
||||
storeRecommendations();
|
||||
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getInventory().updateDatabase();
|
||||
getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canLogout()
|
||||
{
|
||||
if (hasItemRequest())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLocked())
|
||||
{
|
||||
_log.warning("Player " + getName() + " tried to restart/logout during class change.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(this) && !(isGM() && Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isBlockedFromExit())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if the L2PcInstance is autoAttackable.<br>
|
||||
* <B><U>Actions</U>:</B>
|
||||
@ -10698,28 +10697,19 @@ public final class L2PcInstance extends L2Playable
|
||||
* <li>If the L2PcInstance is in observer mode, set its position to its position before entering in observer mode</li>
|
||||
* <li>Set the online Flag to True or False and update the characters table of the database with online status and lastAccess</li>
|
||||
* <li>Stop the HP/MP/CP Regeneration task</li>
|
||||
* <li>Cancel Crafting, Attak or Cast</li>
|
||||
* <li>Cancel Crafting, Attack or Cast</li>
|
||||
* <li>Remove the L2PcInstance from the world</li>
|
||||
* <li>Stop Party and Unsummon Pet</li>
|
||||
* <li>Update database with items in its inventory and remove them from the world</li>
|
||||
* <li>Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI</li>
|
||||
* <li>Close the connection with the client</li>
|
||||
* </ul>
|
||||
* <br>
|
||||
* Remember this method is not to be used to half-ass disconnect players! This method is dedicated only to erase the player from the world.<br>
|
||||
* If you intend to disconnect a player please use {@link Disconnection}
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
cleanup();
|
||||
storeMe();
|
||||
|
||||
// Stop all passives and augment options without broadcasting changes.
|
||||
getEffectList().stopAllPassives(false, false);
|
||||
getEffectList().stopAllOptions(false, false);
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
private synchronized void cleanup()
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(this), this);
|
||||
|
||||
@ -11100,6 +11090,15 @@ public final class L2PcInstance extends L2Playable
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerMentorStatus(this, false), this);
|
||||
}
|
||||
|
||||
// we store all data from players who are disconnected while in an event in order to restore it in the next login
|
||||
if (L2Event.isParticipant(this))
|
||||
{
|
||||
L2Event.savePlayerEventStatus(this);
|
||||
}
|
||||
|
||||
// Anti Feed
|
||||
AntiFeedManager.getInstance().onDisconnect(getClient());
|
||||
|
||||
try
|
||||
{
|
||||
notifyFriends(L2FriendStatus.MODE_OFFLINE);
|
||||
@ -11109,6 +11108,14 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on deleteMe() notifyFriends: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
// Stop all passives and augment options
|
||||
getEffectList().stopAllPassives(false, false);
|
||||
getEffectList().stopAllOptions(false, false);
|
||||
|
||||
stopAutoSaveTask();
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
public int getInventoryLimit()
|
||||
|
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* Task that handles illegal player actions.
|
||||
@ -86,7 +87,7 @@ public final class IllegalPlayerActionTask implements Runnable
|
||||
}
|
||||
case KICK:
|
||||
{
|
||||
_actor.logout(false);
|
||||
Disconnection.of(_actor).defaultSequence(false);
|
||||
break;
|
||||
}
|
||||
case KICKBAN:
|
||||
|
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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 com.l2jmobius.gameserver.network;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
|
||||
/**
|
||||
* @author NB4L1
|
||||
*/
|
||||
public final class Disconnection
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(Disconnection.class.getName());
|
||||
|
||||
public static L2GameClient getClient(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
if (client != null)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
if (activeChar != null)
|
||||
{
|
||||
return activeChar.getClient();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static L2PcInstance getActiveChar(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
if (activeChar != null)
|
||||
{
|
||||
return activeChar;
|
||||
}
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
return client.getActiveChar();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private final L2GameClient _client;
|
||||
private final L2PcInstance _activeChar;
|
||||
|
||||
private Disconnection(L2GameClient client)
|
||||
{
|
||||
this(client, null);
|
||||
}
|
||||
|
||||
public static Disconnection of(L2GameClient client)
|
||||
{
|
||||
return new Disconnection(client);
|
||||
}
|
||||
|
||||
private Disconnection(L2PcInstance activeChar)
|
||||
{
|
||||
this(null, activeChar);
|
||||
}
|
||||
|
||||
public static Disconnection of(L2PcInstance activeChar)
|
||||
{
|
||||
return new Disconnection(activeChar);
|
||||
}
|
||||
|
||||
private Disconnection(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
_client = getClient(client, activeChar);
|
||||
_activeChar = getActiveChar(client, activeChar);
|
||||
|
||||
if (_client != null)
|
||||
{
|
||||
_client.setActiveChar(null);
|
||||
}
|
||||
|
||||
if (_activeChar != null)
|
||||
{
|
||||
_activeChar.setClient(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static Disconnection of(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
return new Disconnection(client, activeChar);
|
||||
}
|
||||
|
||||
public Disconnection storeMe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
_activeChar.storeMe();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection deleteMe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(_activeChar), _activeChar);
|
||||
_activeChar.deleteMe();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection close(boolean toLoginScreen)
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.close(toLoginScreen);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection close(IClientOutgoingPacket packet)
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.close(packet);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void defaultSequence(boolean toLoginScreen)
|
||||
{
|
||||
defaultSequence();
|
||||
close(toLoginScreen);
|
||||
}
|
||||
|
||||
public void defaultSequence(IClientOutgoingPacket packet)
|
||||
{
|
||||
defaultSequence();
|
||||
close(packet);
|
||||
}
|
||||
|
||||
private void defaultSequence()
|
||||
{
|
||||
storeMe();
|
||||
deleteMe();
|
||||
}
|
||||
|
||||
public void onDisconnection()
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> defaultSequence(), _activeChar.canLogout() ? 0 : AttackStanceTaskManager.COMBAT_TIME);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,9 +21,6 @@ import java.net.InetSocketAddress;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -33,36 +30,28 @@ import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.commons.network.ChannelInboundHandler;
|
||||
import com.l2jmobius.commons.network.ICrypt;
|
||||
import com.l2jmobius.commons.network.IIncomingPacket;
|
||||
import com.l2jmobius.commons.network.IOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.LoginServerThread.SessionKey;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.enums.CharacterDeleteFailType;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.CommissionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MailManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MentorManager;
|
||||
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
import com.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.security.SecondaryPasswordAuth;
|
||||
import com.l2jmobius.gameserver.util.FloodProtectors;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -74,7 +63,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
protected static final Logger LOGGER = Logger.getLogger(L2GameClient.class.getName());
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private final int _objectId;
|
||||
|
||||
@ -88,20 +77,15 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
private SecondaryPasswordAuth _secondaryAuth;
|
||||
private ClientHardwareInfoHolder _hardwareInfo;
|
||||
private boolean _isAuthedGG;
|
||||
private final long _connectionStartTime = System.currentTimeMillis();
|
||||
private CharSelectInfoPackage[] _charSlotMapping = null;
|
||||
|
||||
// flood protectors
|
||||
private final FloodProtectors _floodProtectors = new FloodProtectors(this);
|
||||
|
||||
// Task
|
||||
protected final ScheduledFuture<?> _autoSaveInDB;
|
||||
protected ScheduledFuture<?> _cleanupTask = null;
|
||||
|
||||
// Crypt
|
||||
private final Crypt _crypt;
|
||||
|
||||
private boolean _isDetached = false;
|
||||
private volatile boolean _isDetached = false;
|
||||
|
||||
private boolean _protocol;
|
||||
|
||||
@ -111,14 +95,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
_objectId = IdFactory.getInstance().getNextId();
|
||||
_crypt = new Crypt(this);
|
||||
if (Config.CHAR_DATA_STORE_INTERVAL > 0)
|
||||
{
|
||||
_autoSaveInDB = ThreadPoolManager.scheduleAtFixedRate(new AutoSaveTask(), 300000L, Config.CHAR_DATA_STORE_INTERVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_autoSaveInDB = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getObjectId()
|
||||
@ -135,23 +111,18 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
_addr = address.getAddress();
|
||||
_channel = ctx.channel();
|
||||
LOGGER.finer("Client Connected: " + ctx.channel());
|
||||
LOG_ACCOUNTING.finer("Client Connected: " + ctx.channel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx)
|
||||
{
|
||||
LOGGER.finer("Client Disconnected: " + ctx.channel());
|
||||
LOG_ACCOUNTING.finer("Client Disconnected: " + ctx.channel());
|
||||
|
||||
// no long running tasks here, do it async
|
||||
try
|
||||
{
|
||||
ThreadPoolManager.execute(new DisconnectTask());
|
||||
}
|
||||
catch (RejectedExecutionException e)
|
||||
{
|
||||
// server is closing
|
||||
}
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
|
||||
Disconnection.of(this).onDisconnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -172,6 +143,25 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
@ -193,19 +183,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _addr;
|
||||
}
|
||||
|
||||
public long getConnectionStartTime()
|
||||
{
|
||||
return _connectionStartTime;
|
||||
}
|
||||
|
||||
public L2PcInstance getActiveChar()
|
||||
{
|
||||
return _activeChar;
|
||||
}
|
||||
|
||||
public void setActiveChar(L2PcInstance pActiveChar)
|
||||
public void setActiveChar(L2PcInstance activeChar)
|
||||
{
|
||||
_activeChar = pActiveChar;
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
public ReentrantLock getActiveCharLock()
|
||||
@ -228,9 +213,9 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _isAuthedGG;
|
||||
}
|
||||
|
||||
public void setAccountName(String pAccountName)
|
||||
public void setAccountName(String activeChar)
|
||||
{
|
||||
_accountName = pAccountName;
|
||||
_accountName = activeChar;
|
||||
|
||||
if (SecondaryAuthData.getInstance().isEnabled())
|
||||
{
|
||||
@ -287,16 +272,16 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
|
||||
/**
|
||||
* Method to handle character deletion
|
||||
* @param charslot
|
||||
* @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 charslot)
|
||||
public CharacterDeleteFailType markToDeleteChar(int characterSlot)
|
||||
{
|
||||
final int objectId = getObjectIdForSlot(charslot);
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return CharacterDeleteFailType.UNKNOWN;
|
||||
@ -354,38 +339,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
_logAccounting.info("Delete, " + objectId + ", " + this);
|
||||
LOG_ACCOUNTING.info("Delete, " + objectId + ", " + this);
|
||||
return CharacterDeleteFailType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the L2PcInstance to the database.
|
||||
*/
|
||||
public void saveCharToDisk()
|
||||
public void restore(int characterSlot)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (getActiveChar() != null)
|
||||
{
|
||||
getActiveChar().storeMe();
|
||||
getActiveChar().storeRecommendations();
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getActiveChar().getInventory().updateDatabase();
|
||||
getActiveChar().getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error saving character..", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void markRestoredChar(int charslot)
|
||||
{
|
||||
final int objid = getObjectIdForSlot(charslot);
|
||||
if (objid < 0)
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -393,7 +354,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?"))
|
||||
{
|
||||
statement.setInt(1, objid);
|
||||
statement.setInt(1, objectId);
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -401,7 +362,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
LOGGER.log(Level.SEVERE, "Error restoring character.", e);
|
||||
}
|
||||
|
||||
_logAccounting.info("Restore, " + objid + ", " + this);
|
||||
LOG_ACCOUNTING.info("Restore, " + objectId + ", " + this);
|
||||
}
|
||||
|
||||
public static void deleteCharByObjId(int objid)
|
||||
@ -555,38 +516,30 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
public L2PcInstance loadCharFromDisk(int charslot)
|
||||
public L2PcInstance load(int characterSlot)
|
||||
{
|
||||
final int objId = getObjectIdForSlot(charslot);
|
||||
if (objId < 0)
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
L2PcInstance character = L2World.getInstance().getPlayer(objId);
|
||||
if (character != null)
|
||||
L2PcInstance player = L2World.getInstance().getPlayer(objectId);
|
||||
if (player != null)
|
||||
{
|
||||
// exploit prevention, should not happens in normal way
|
||||
LOGGER.severe("Attempt of double login: " + character.getName() + "(" + objId + ") " + getAccountName());
|
||||
if (character.getClient() != null)
|
||||
{
|
||||
character.getClient().closeNow();
|
||||
}
|
||||
else
|
||||
{
|
||||
character.deleteMe();
|
||||
}
|
||||
LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + getAccountName());
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
character = L2PcInstance.load(objId);
|
||||
if (character == null)
|
||||
player = L2PcInstance.load(objectId);
|
||||
if (player == null)
|
||||
{
|
||||
LOGGER.severe("could not restore in slot: " + charslot);
|
||||
LOGGER.severe("Could not restore in slot: " + characterSlot);
|
||||
}
|
||||
|
||||
// setCharacter(character);
|
||||
return character;
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -611,47 +564,21 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _secondaryAuth;
|
||||
}
|
||||
|
||||
public void close(IOutgoingPacket packet)
|
||||
{
|
||||
if (packet != null)
|
||||
{
|
||||
_channel.writeAndFlush(packet);
|
||||
}
|
||||
_channel.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charslot
|
||||
* @param characterSlot
|
||||
* @return
|
||||
*/
|
||||
private int getObjectIdForSlot(int charslot)
|
||||
private int getObjectIdForSlot(int characterSlot)
|
||||
{
|
||||
final CharSelectInfoPackage info = getCharSelection(charslot);
|
||||
final CharSelectInfoPackage info = getCharSelection(characterSlot);
|
||||
if (info == null)
|
||||
{
|
||||
LOGGER.warning(toString() + " tried to delete Character in slot " + charslot + " but no characters exits at that slot.");
|
||||
LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot.");
|
||||
return -1;
|
||||
}
|
||||
return info.getObjectId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close client connection with {@link ServerClose} packet
|
||||
*/
|
||||
public void closeNow()
|
||||
{
|
||||
_isDetached = true; // prevents more packets execution
|
||||
close(ServerClose.STATIC_PACKET);
|
||||
synchronized (this)
|
||||
{
|
||||
if (_cleanupTask != null)
|
||||
{
|
||||
cancelCleanup();
|
||||
}
|
||||
_cleanupTask = ThreadPoolManager.schedule(new CleanupTask(), 0); // instant
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the best possible string representation of this client.
|
||||
*/
|
||||
@ -688,209 +615,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
protected class DisconnectTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
boolean fast = true;
|
||||
try
|
||||
{
|
||||
if ((getActiveChar() != null) && !isDetached())
|
||||
{
|
||||
setDetached(true);
|
||||
if (offlineMode(getActiveChar()))
|
||||
{
|
||||
getActiveChar().leaveParty();
|
||||
OlympiadManager.getInstance().unRegisterNoble(getActiveChar());
|
||||
|
||||
// If the L2PcInstance has Pet, unsummon it
|
||||
L2Summon pet = getActiveChar().getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(getActiveChar());
|
||||
pet = getActiveChar().getPet();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
getActiveChar().getServitors().values().forEach(s ->
|
||||
{
|
||||
s.setRestoreSummon(true);
|
||||
s.unSummon(getActiveChar());
|
||||
});
|
||||
|
||||
if (Config.OFFLINE_SET_NAME_COLOR)
|
||||
{
|
||||
getActiveChar().getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
|
||||
getActiveChar().broadcastUserInfo();
|
||||
}
|
||||
|
||||
if (getActiveChar().getOfflineStartTime() == 0)
|
||||
{
|
||||
getActiveChar().setOfflineStartTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// Store trade on exit, if realtime saving is enabled.
|
||||
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
|
||||
{
|
||||
OfflineTradersTable.onTransaction(getActiveChar(), false, true);
|
||||
}
|
||||
|
||||
_logAccounting.info("Entering offline mode, " + L2GameClient.this);
|
||||
return;
|
||||
}
|
||||
fast = !getActiveChar().isInCombat() && !getActiveChar().isLocked();
|
||||
}
|
||||
cleanMe(fast);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while disconnecting client.", e1);
|
||||
}
|
||||
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player the player to be check.
|
||||
* @return {@code true} if the player is allowed to remain as off-line shop.
|
||||
*/
|
||||
protected boolean offlineMode(L2PcInstance player)
|
||||
{
|
||||
if (player.isInOlympiadMode() || player.isBlockedFromExit() || player.isJailed() || (player.getVehicle() != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canSetShop = false;
|
||||
switch (player.getPrivateStoreType())
|
||||
{
|
||||
case SELL:
|
||||
case PACKAGE_SELL:
|
||||
case BUY:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
canSetShop = false;
|
||||
}
|
||||
return canSetShop;
|
||||
}
|
||||
|
||||
public void cleanMe(boolean fast)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_cleanupTask == null)
|
||||
{
|
||||
_cleanupTask = ThreadPoolManager.schedule(new CleanupTask(), fast ? 5 : 15000L);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error during cleanup.", e1);
|
||||
}
|
||||
}
|
||||
|
||||
protected class CleanupTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
// we are going to manually save the char bellow thus we can force the cancel
|
||||
if (_autoSaveInDB != null)
|
||||
{
|
||||
_autoSaveInDB.cancel(true);
|
||||
// ThreadPoolManager.getInstance().removeGeneral((Runnable) _autoSaveInDB);
|
||||
}
|
||||
|
||||
if (getActiveChar() != null) // this should only happen on connection loss
|
||||
{
|
||||
if (getActiveChar().isLocked())
|
||||
{
|
||||
LOGGER.warning("Player " + getActiveChar().getName() + " still performing subclass actions during disconnect.");
|
||||
}
|
||||
|
||||
// we store all data from players who are disconnected while in an event in order to restore it in the next login
|
||||
if (L2Event.isParticipant(getActiveChar()))
|
||||
{
|
||||
L2Event.savePlayerEventStatus(getActiveChar());
|
||||
}
|
||||
|
||||
if (getActiveChar().isOnline())
|
||||
{
|
||||
getActiveChar().deleteMe();
|
||||
AntiFeedManager.getInstance().onDisconnect(L2GameClient.this);
|
||||
}
|
||||
|
||||
// prevent closing again
|
||||
getActiveChar().setClient(null);
|
||||
}
|
||||
setActiveChar(null);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while cleanup client.", e1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class AutoSaveTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
final L2PcInstance player = getActiveChar();
|
||||
if ((player != null) && player.isOnline()) // safety precaution
|
||||
{
|
||||
saveCharToDisk();
|
||||
final L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.storeMe();
|
||||
}
|
||||
player.getServitors().values().forEach(L2Summon::storeMe);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error on AutoSaveTask.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProtocolOk()
|
||||
{
|
||||
return _protocol;
|
||||
@ -901,20 +625,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
_protocol = b;
|
||||
}
|
||||
|
||||
public boolean handleCheat(String punishment)
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(_activeChar, toString() + ": " + punishment, Config.DEFAULT_PUNISH);
|
||||
return true;
|
||||
}
|
||||
|
||||
final Logger logAudit = Logger.getLogger("audit");
|
||||
logAudit.info("AUDIT: Client " + toString() + " kicked for reason: " + punishment);
|
||||
closeNow();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setClientTracert(int[][] tracert)
|
||||
{
|
||||
trace = tracert;
|
||||
@ -925,17 +635,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return trace;
|
||||
}
|
||||
|
||||
private boolean cancelCleanup()
|
||||
{
|
||||
final Future<?> task = _cleanupTask;
|
||||
if (task != null)
|
||||
{
|
||||
_cleanupTask = null;
|
||||
return task.cancel(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendActionFailed()
|
||||
{
|
||||
sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
@ -54,7 +54,7 @@ public final class AuthLogin implements IClientIncomingPacket
|
||||
{
|
||||
if (_loginName.isEmpty() || !client.isProtocolOk())
|
||||
{
|
||||
client.close(null);
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerCreate;
|
||||
import com.l2jmobius.gameserver.model.items.PcItemTemplate;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharCreateFail;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharCreateOk;
|
||||
@ -333,7 +334,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
{
|
||||
newChar.getVariables().set("intro_god_video", true);
|
||||
}
|
||||
newChar.deleteMe();
|
||||
Disconnection.of(client, newChar).storeMe().deleteMe();
|
||||
|
||||
final CharSelectionInfo cl = new CharSelectionInfo(client.getAccountName(), client.getSessionId().playOkID1);
|
||||
client.setCharSelection(cl.getCharInfo());
|
||||
|
@ -47,7 +47,7 @@ public final class CharacterRestore implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
client.markRestoredChar(_charSlot);
|
||||
client.restore(_charSlot);
|
||||
final CharSelectionInfo cl = new CharSelectionInfo(client.getAccountName(), client.getSessionId().playOkID1, 0);
|
||||
client.sendPacket(cl);
|
||||
client.setCharSelection(cl.getCharInfo());
|
||||
|
@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharSelected;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
@ -146,7 +147,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
}
|
||||
|
||||
// load up character from disk
|
||||
final L2PcInstance cha = client.loadCharFromDisk(_charSlot);
|
||||
final L2PcInstance cha = client.load(_charSlot);
|
||||
if (cha == null)
|
||||
{
|
||||
return; // handled in L2GameClient
|
||||
@ -161,7 +162,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
final TerminateReturn terminate = EventDispatcher.getInstance().notifyEvent(new OnPlayerSelect(cha, cha.getObjectId(), cha.getName(), client), Containers.Players(), TerminateReturn.class);
|
||||
if ((terminate != null) && terminate.terminate())
|
||||
{
|
||||
cha.deleteMe();
|
||||
Disconnection.of(cha).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
|
||||
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
|
||||
@ -142,7 +143,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
if (activeChar == null)
|
||||
{
|
||||
_log.warning("EnterWorld failed! activeChar returned 'null'.");
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -681,7 +682,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
{
|
||||
if (client.getHardwareInfo() == null)
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
}, 5000);
|
||||
|
@ -18,14 +18,12 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -33,7 +31,7 @@ import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
*/
|
||||
public final class Logout implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@ -47,42 +45,21 @@ public final class Logout implements IClientIncomingPacket
|
||||
final L2PcInstance player = client.getActiveChar();
|
||||
if (player == null)
|
||||
{
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasItemRequest())
|
||||
if (!player.canLogout())
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isLocked())
|
||||
LOG_ACCOUNTING.info("Logged out, " + client);
|
||||
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to logout during class change.");
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
Disconnection.of(client, player).defaultSequence(false);
|
||||
}
|
||||
|
||||
// Don't allow leaving if player is fighting
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player))
|
||||
{
|
||||
if (!player.isGM() || (player.isGM() && !Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_EXIT_THE_GAME_WHILE_IN_COMBAT);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (L2Event.isParticipant(player))
|
||||
{
|
||||
player.sendMessage("A superior power doesn't allow you to leave the event.");
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
_logAccounting.info("Disconnected, " + client);
|
||||
|
||||
player.logout();
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public final class ProtocolVersion implements IClientIncomingPacket
|
||||
if (_version == -2)
|
||||
{
|
||||
// this is just a ping attempt from the new C2 client
|
||||
client.close(null);
|
||||
client.closeNow();
|
||||
}
|
||||
else if (!Config.PROTOCOL_LIST.contains(_version))
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcMenuSelect;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerBypass;
|
||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
@ -86,7 +87,7 @@ public final class RequestBypassToServer implements IClientIncomingPacket
|
||||
if (_command.isEmpty())
|
||||
{
|
||||
_log.warning("Player " + activeChar.getName() + " sent empty bypass!");
|
||||
activeChar.logout();
|
||||
Disconnection.of(client, activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -93,7 +94,7 @@ public final class RequestHardWareInfo implements IClientIncomingPacket
|
||||
}
|
||||
if (count >= Config.MAX_PLAYERS_PER_HWID)
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -18,16 +18,15 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharSelectionInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RestartResponse;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -35,7 +34,7 @@ import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
*/
|
||||
public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@ -52,43 +51,20 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasItemRequest())
|
||||
if (!player.canLogout())
|
||||
{
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isLocked())
|
||||
LOG_ACCOUNTING.info("Logged out, " + client);
|
||||
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to restart during class change.");
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
Disconnection.of(client, player).storeMe().deleteMe();
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) && !(player.isGM() && Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_RESTART_WHILE_IN_COMBAT);
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isBlockedFromExit())
|
||||
{
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
_logAccounting.info("Logged out, " + client);
|
||||
|
||||
player.deleteMe();
|
||||
|
||||
client.setActiveChar(null);
|
||||
|
||||
// detach the client from the char so that the connection isnt closed in the deleteMe
|
||||
player.setClient(null);
|
||||
|
||||
AntiFeedManager.getInstance().onDisconnect(client);
|
||||
|
||||
// return the client to the authed status
|
||||
client.setConnectionState(ConnectionState.AUTHENTICATED);
|
||||
|
||||
|
@ -31,6 +31,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerChat;
|
||||
import com.l2jmobius.gameserver.model.events.returns.ChatFilterReturn;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@ -110,7 +111,7 @@ public final class Say2 implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning("Say2: Invalid type: " + _type + " Player : " + activeChar.getName() + " text: " + _text);
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
activeChar.logout();
|
||||
Disconnection.of(activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,7 +119,7 @@ public final class Say2 implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning(activeChar.getName() + ": sending empty text. Possible packet hack!");
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
activeChar.logout();
|
||||
Disconnection.of(activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import java.util.logging.Logger;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ex2ndPasswordAck;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ex2ndPasswordCheck;
|
||||
@ -104,7 +105,7 @@ public class SecondaryPasswordAuth
|
||||
if (passwordExist())
|
||||
{
|
||||
_log.warning("[SecondaryPasswordAuth]" + _activeClient.getAccountName() + " forced savePassword");
|
||||
_activeClient.closeNow();
|
||||
Disconnection.of(_activeClient).defaultSequence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ public class SecondaryPasswordAuth
|
||||
if (!passwordExist())
|
||||
{
|
||||
_log.warning("[SecondaryPasswordAuth]" + _activeClient.getAccountName() + " forced changePassword");
|
||||
_activeClient.closeNow();
|
||||
Disconnection.of(_activeClient).defaultSequence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,8 @@ public class AttackStanceTaskManager
|
||||
|
||||
protected static final Map<L2Character, Long> _attackStanceTasks = new ConcurrentHashMap<>();
|
||||
|
||||
public static final long COMBAT_TIME = 15_000;
|
||||
|
||||
/**
|
||||
* Instantiates a new attack stance task manager.
|
||||
*/
|
||||
@ -106,7 +108,7 @@ public class AttackStanceTaskManager
|
||||
while (iter.hasNext())
|
||||
{
|
||||
e = iter.next();
|
||||
if ((current - e.getValue()) > 15000)
|
||||
if ((current - e.getValue()) > COMBAT_TIME)
|
||||
{
|
||||
actor = e.getKey();
|
||||
if (actor != null)
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -142,14 +143,7 @@ public final class FloodProtectorAction
|
||||
*/
|
||||
private void kickPlayer()
|
||||
{
|
||||
if (_client.getActiveChar() != null)
|
||||
{
|
||||
_client.getActiveChar().logout(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_client.closeNow();
|
||||
}
|
||||
Disconnection.of(_client).defaultSequence(false);
|
||||
|
||||
if (_log.getLevel() == Level.WARNING)
|
||||
{
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 com.l2jmobius.gameserver.util;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
* @author lord_rex
|
||||
*/
|
||||
public final class OfflineTradeUtil
|
||||
{
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private OfflineTradeUtil()
|
||||
{
|
||||
// utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether player is able to enter offline mode.
|
||||
* @param player the player to be check.
|
||||
* @return {@code true} if the player is allowed to remain as off-line shop.
|
||||
*/
|
||||
private static boolean offlineMode(L2PcInstance player)
|
||||
{
|
||||
if ((player == null) || player.isInOlympiadMode() || player.isBlockedFromExit() || player.isJailed() || (player.getVehicle() != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canSetShop = false;
|
||||
switch (player.getPrivateStoreType())
|
||||
{
|
||||
case SELL:
|
||||
case PACKAGE_SELL:
|
||||
case BUY:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
canSetShop = false;
|
||||
}
|
||||
|
||||
// Check whether client is null or player is already in offline mode.
|
||||
final L2GameClient client = player.getClient();
|
||||
if ((client == null) || client.isDetached())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return canSetShop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the disconnection process of offline traders.
|
||||
* @param player
|
||||
* @return {@code true} when player entered offline mode, otherwise {@code false}
|
||||
*/
|
||||
public static boolean enteredOfflineMode(L2PcInstance player)
|
||||
{
|
||||
if (!OfflineTradeUtil.offlineMode(player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2GameClient client = player.getClient();
|
||||
client.setDetached(true);
|
||||
|
||||
player.leaveParty();
|
||||
OlympiadManager.getInstance().unRegisterNoble(player);
|
||||
|
||||
// If the L2PcInstance has Pet, unsummon it
|
||||
L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(player);
|
||||
pet = player.getPet();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
player.getServitors().values().forEach(s ->
|
||||
{
|
||||
s.setRestoreSummon(true);
|
||||
s.unSummon(player);
|
||||
});
|
||||
|
||||
if (Config.OFFLINE_SET_NAME_COLOR)
|
||||
{
|
||||
player.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
|
||||
player.broadcastUserInfo();
|
||||
}
|
||||
|
||||
if (player.getOfflineStartTime() == 0)
|
||||
{
|
||||
player.setOfflineStartTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// Store trade on exit, if realtime saving is enabled.
|
||||
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
|
||||
{
|
||||
OfflineTradersTable.onTransaction(player, false, true);
|
||||
}
|
||||
|
||||
Disconnection.of(player).storeMe().close(false);
|
||||
LOG_ACCOUNTING.info("Entering offline mode, " + client);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2AccessLevel;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -129,7 +130,7 @@ public final class AdminChangeAccessLevel implements IAdminCommandHandler
|
||||
{
|
||||
player.setAccessLevel(lvl, false, true);
|
||||
player.sendMessage("Your character has been banned. Bye.");
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package handlers.admincommandhandlers;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* This class handles following admin commands: - character_disconnect = disconnects target player
|
||||
@ -68,7 +69,7 @@ public class AdminDisconnect implements IAdminCommandHandler
|
||||
{
|
||||
activeChar.sendMessage("Character " + player.getName() + " disconnected from server.");
|
||||
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ package handlers.admincommandhandlers;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
public class AdminKick implements IAdminCommandHandler
|
||||
{
|
||||
@ -44,11 +44,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
final L2PcInstance plyr = L2World.getInstance().getPlayer(player);
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
activeChar.sendMessage("You kicked " + plyr.getName() + " from the game.");
|
||||
}
|
||||
}
|
||||
@ -61,7 +57,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
if (!player.isGM())
|
||||
{
|
||||
counter++;
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
activeChar.sendMessage("Kicked " + counter + " players.");
|
||||
|
@ -21,7 +21,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.handler.AdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
@ -31,6 +30,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -170,11 +170,7 @@ public class AdminMenu implements IAdminCommandHandler
|
||||
String text;
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
text = "You kicked " + plyr.getName() + " from the game.";
|
||||
}
|
||||
else
|
||||
|
@ -22,6 +22,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -58,7 +59,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -90,7 +91,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
*/
|
||||
private static void applyToPlayer(L2PcInstance player)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ package handlers.telnethandlers.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.telnet.ITelnetCommand;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -49,7 +50,7 @@ public class Kick implements ITelnetCommand
|
||||
final L2PcInstance player = L2World.getInstance().getPlayer(args[0]);
|
||||
if (player != null)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return "Player has been successfully kicked.";
|
||||
}
|
||||
return "Couldn't find player with such name.";
|
||||
|
@ -565,15 +565,8 @@ public class LoginServerThread extends Thread
|
||||
final L2GameClient client = _accountsInGameServer.get(account);
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.getActiveChar().logout();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
ACCOUNTING_LOGGER.info(getClass().getSimpleName() + ": Kicked by login, " + client);
|
||||
ACCOUNTING_LOGGER.info("Kicked by login, " + client);
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,10 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||
import com.l2jmobius.gameserver.model.olympiad.Olympiad;
|
||||
import com.l2jmobius.gameserver.network.ClientNetworkManager;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.EventLoopGroupManager;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.loginserverpackets.game.ServerStatus;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.network.telnet.TelnetServer;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
@ -610,27 +609,7 @@ public class Shutdown extends Thread
|
||||
{
|
||||
for (L2PcInstance player : L2World.getInstance().getPlayers())
|
||||
{
|
||||
// Logout Character
|
||||
try
|
||||
{
|
||||
final L2GameClient client = player.getClient();
|
||||
if ((client != null) && !client.isDetached())
|
||||
{
|
||||
client.close(ServerClose.STATIC_PACKET);
|
||||
client.setActiveChar(null);
|
||||
player.setClient(null);
|
||||
}
|
||||
else if ((client == null) || client.isDetached())
|
||||
// player is probably a bot - force logout
|
||||
{
|
||||
player.logout();
|
||||
}
|
||||
player.deleteMe();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed logour char " + player, t);
|
||||
}
|
||||
Disconnection.of(player).defaultSequence(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.TradeItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SellBuffHolder;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
public class OfflineTradersTable
|
||||
@ -49,6 +50,10 @@ public class OfflineTradersTable
|
||||
private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
|
||||
private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE `charId`=?";
|
||||
|
||||
protected OfflineTradersTable()
|
||||
{
|
||||
}
|
||||
|
||||
public void storeOffliners()
|
||||
{
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
@ -300,7 +305,7 @@ public class OfflineTradersTable
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error loading trader: " + player, e);
|
||||
if (player != null)
|
||||
{
|
||||
player.deleteMe();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,11 +475,11 @@ public class OfflineTradersTable
|
||||
*/
|
||||
public static OfflineTradersTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final OfflineTradersTable _instance = new OfflineTradersTable();
|
||||
protected static final OfflineTradersTable INSTANCE = new OfflineTradersTable();
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,12 @@ public final class AntiFeedManager
|
||||
return false;
|
||||
}
|
||||
|
||||
// Players in offline mode should't be valid targets.
|
||||
if (targetPlayer.getClient().isDetached())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((Config.ANTIFEED_INTERVAL > 0) && _lastDeathTimes.containsKey(targetPlayer.getObjectId()))
|
||||
{
|
||||
if ((System.currentTimeMillis() - _lastDeathTimes.get(targetPlayer.getObjectId())) < Config.ANTIFEED_INTERVAL)
|
||||
@ -211,7 +217,7 @@ public final class AntiFeedManager
|
||||
*/
|
||||
public final void onDisconnect(L2GameClient client)
|
||||
{
|
||||
if ((client == null) || client.isDetached())
|
||||
if ((client == null) || (client.getConnectionAddress() == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
@ -143,8 +144,8 @@ public final class L2World
|
||||
final L2PcInstance existingPlayer = _allPlayers.putIfAbsent(object.getObjectId(), newPlayer);
|
||||
if (existingPlayer != null)
|
||||
{
|
||||
existingPlayer.logout();
|
||||
newPlayer.logout();
|
||||
Disconnection.of(existingPlayer).defaultSequence(false);
|
||||
Disconnection.of(newPlayer).defaultSequence(false);
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Duplicate character!? Disconnected both characters (" + newPlayer.getName() + ")");
|
||||
}
|
||||
else if (Config.FACTION_SYSTEM_ENABLED)
|
||||
|
@ -131,6 +131,7 @@ import com.l2jmobius.gameserver.model.stats.MoveType;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneRegion;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Attack;
|
||||
@ -3287,7 +3288,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
if (isPlayer())
|
||||
{
|
||||
getActingPlayer().logout();
|
||||
Disconnection.of(getActingPlayer()).defaultSequence(false);
|
||||
}
|
||||
else if (isSummon())
|
||||
{
|
||||
|
@ -260,6 +260,7 @@ import com.l2jmobius.gameserver.model.variables.AccountVariables;
|
||||
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractHtmlPacket;
|
||||
@ -296,7 +297,6 @@ import com.l2jmobius.gameserver.network.serverpackets.HennaInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ItemList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MyTargetSelected;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NicknameChanged;
|
||||
@ -315,7 +315,6 @@ import com.l2jmobius.gameserver.network.serverpackets.RecipeShopMsg;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RecipeShopSellList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RelationChanged;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ride;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SetupGauge;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ShortCutInit;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
|
||||
@ -807,6 +806,8 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
private final Fishing _fishing = new Fishing(this);
|
||||
|
||||
private Future<?> _autoSaveTask = null;
|
||||
|
||||
public void setPvpFlagLasts(long time)
|
||||
{
|
||||
_pvpFlagLasts = time;
|
||||
@ -1261,38 +1262,6 @@ public final class L2PcInstance extends L2Playable
|
||||
_inCraftMode = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Logout Task:
|
||||
* <ul>
|
||||
* <li>Remove player from world</li>
|
||||
* <li>Save player data into DB</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void logout()
|
||||
{
|
||||
logout(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Logout Task:
|
||||
* <ul>
|
||||
* <li>Remove player from world</li>
|
||||
* <li>Save player data into DB</li>
|
||||
* </ul>
|
||||
* @param closeClient
|
||||
*/
|
||||
public void logout(boolean closeClient)
|
||||
{
|
||||
try
|
||||
{
|
||||
closeNetConnection(closeClient);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on logout(): " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a table containing all Common L2RecipeList of the L2PcInstance.
|
||||
*/
|
||||
@ -3983,33 +3952,6 @@ public final class L2PcInstance extends L2Playable
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the active connection with the client.
|
||||
* @param closeClient
|
||||
*/
|
||||
private void closeNetConnection(boolean closeClient)
|
||||
{
|
||||
final L2GameClient client = _client;
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.cleanMe(true);
|
||||
}
|
||||
else if (client.getChannel().isActive())
|
||||
{
|
||||
if (closeClient)
|
||||
{
|
||||
client.close(LeaveWorld.STATIC_PACKET);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(ServerClose.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Location getCurrentSkillWorldPosition()
|
||||
{
|
||||
return _currentSkillWorldPosition;
|
||||
@ -6833,6 +6775,8 @@ public final class L2PcInstance extends L2Playable
|
||||
player.startOnlineTimeUpdateTask();
|
||||
|
||||
player.setOnlineStatus(true, false);
|
||||
|
||||
player.startAutoSaveTask();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -8111,6 +8055,61 @@ public final class L2PcInstance extends L2Playable
|
||||
return isInCategory(CategoryType.SIXTH_CLASS_GROUP);
|
||||
}
|
||||
|
||||
private void startAutoSaveTask()
|
||||
{
|
||||
if ((Config.CHAR_DATA_STORE_INTERVAL > 0) && (_autoSaveTask == null))
|
||||
{
|
||||
_autoSaveTask = ThreadPoolManager.scheduleAtFixedRate(this::autoSave, 300_000L, TimeUnit.MINUTES.toMillis(Config.CHAR_DATA_STORE_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
private void stopAutoSaveTask()
|
||||
{
|
||||
if (_autoSaveTask != null)
|
||||
{
|
||||
_autoSaveTask.cancel(false);
|
||||
_autoSaveTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void autoSave()
|
||||
{
|
||||
storeMe();
|
||||
storeRecommendations();
|
||||
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getInventory().updateDatabase();
|
||||
getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canLogout()
|
||||
{
|
||||
if (hasItemRequest())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLocked())
|
||||
{
|
||||
_log.warning("Player " + getName() + " tried to restart/logout during class change.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(this) && !(isGM() && Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isBlockedFromExit())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if the L2PcInstance is autoAttackable.<br>
|
||||
* <B><U>Actions</U>:</B>
|
||||
@ -10708,28 +10707,19 @@ public final class L2PcInstance extends L2Playable
|
||||
* <li>If the L2PcInstance is in observer mode, set its position to its position before entering in observer mode</li>
|
||||
* <li>Set the online Flag to True or False and update the characters table of the database with online status and lastAccess</li>
|
||||
* <li>Stop the HP/MP/CP Regeneration task</li>
|
||||
* <li>Cancel Crafting, Attak or Cast</li>
|
||||
* <li>Cancel Crafting, Attack or Cast</li>
|
||||
* <li>Remove the L2PcInstance from the world</li>
|
||||
* <li>Stop Party and Unsummon Pet</li>
|
||||
* <li>Update database with items in its inventory and remove them from the world</li>
|
||||
* <li>Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI</li>
|
||||
* <li>Close the connection with the client</li>
|
||||
* </ul>
|
||||
* <br>
|
||||
* Remember this method is not to be used to half-ass disconnect players! This method is dedicated only to erase the player from the world.<br>
|
||||
* If you intend to disconnect a player please use {@link Disconnection}
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
cleanup();
|
||||
storeMe();
|
||||
|
||||
// Stop all passives and augment options without broadcasting changes.
|
||||
getEffectList().stopAllPassives(false, false);
|
||||
getEffectList().stopAllOptions(false, false);
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
private synchronized void cleanup()
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(this), this);
|
||||
|
||||
@ -11110,6 +11100,15 @@ public final class L2PcInstance extends L2Playable
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerMentorStatus(this, false), this);
|
||||
}
|
||||
|
||||
// we store all data from players who are disconnected while in an event in order to restore it in the next login
|
||||
if (L2Event.isParticipant(this))
|
||||
{
|
||||
L2Event.savePlayerEventStatus(this);
|
||||
}
|
||||
|
||||
// Anti Feed
|
||||
AntiFeedManager.getInstance().onDisconnect(getClient());
|
||||
|
||||
try
|
||||
{
|
||||
notifyFriends(L2FriendStatus.MODE_OFFLINE);
|
||||
@ -11119,6 +11118,14 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on deleteMe() notifyFriends: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
// Stop all passives and augment options
|
||||
getEffectList().stopAllPassives(false, false);
|
||||
getEffectList().stopAllOptions(false, false);
|
||||
|
||||
stopAutoSaveTask();
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
public int getInventoryLimit()
|
||||
|
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* Task that handles illegal player actions.
|
||||
@ -86,7 +87,7 @@ public final class IllegalPlayerActionTask implements Runnable
|
||||
}
|
||||
case KICK:
|
||||
{
|
||||
_actor.logout(false);
|
||||
Disconnection.of(_actor).defaultSequence(false);
|
||||
break;
|
||||
}
|
||||
case KICKBAN:
|
||||
|
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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 com.l2jmobius.gameserver.network;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
|
||||
/**
|
||||
* @author NB4L1
|
||||
*/
|
||||
public final class Disconnection
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(Disconnection.class.getName());
|
||||
|
||||
public static L2GameClient getClient(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
if (client != null)
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
if (activeChar != null)
|
||||
{
|
||||
return activeChar.getClient();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static L2PcInstance getActiveChar(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
if (activeChar != null)
|
||||
{
|
||||
return activeChar;
|
||||
}
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
return client.getActiveChar();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private final L2GameClient _client;
|
||||
private final L2PcInstance _activeChar;
|
||||
|
||||
private Disconnection(L2GameClient client)
|
||||
{
|
||||
this(client, null);
|
||||
}
|
||||
|
||||
public static Disconnection of(L2GameClient client)
|
||||
{
|
||||
return new Disconnection(client);
|
||||
}
|
||||
|
||||
private Disconnection(L2PcInstance activeChar)
|
||||
{
|
||||
this(null, activeChar);
|
||||
}
|
||||
|
||||
public static Disconnection of(L2PcInstance activeChar)
|
||||
{
|
||||
return new Disconnection(activeChar);
|
||||
}
|
||||
|
||||
private Disconnection(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
_client = getClient(client, activeChar);
|
||||
_activeChar = getActiveChar(client, activeChar);
|
||||
|
||||
if (_client != null)
|
||||
{
|
||||
_client.setActiveChar(null);
|
||||
}
|
||||
|
||||
if (_activeChar != null)
|
||||
{
|
||||
_activeChar.setClient(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static Disconnection of(L2GameClient client, L2PcInstance activeChar)
|
||||
{
|
||||
return new Disconnection(client, activeChar);
|
||||
}
|
||||
|
||||
public Disconnection storeMe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
_activeChar.storeMe();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection deleteMe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(_activeChar), _activeChar);
|
||||
_activeChar.deleteMe();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection close(boolean toLoginScreen)
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.close(toLoginScreen);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disconnection close(IClientOutgoingPacket packet)
|
||||
{
|
||||
if (_client != null)
|
||||
{
|
||||
_client.close(packet);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void defaultSequence(boolean toLoginScreen)
|
||||
{
|
||||
defaultSequence();
|
||||
close(toLoginScreen);
|
||||
}
|
||||
|
||||
public void defaultSequence(IClientOutgoingPacket packet)
|
||||
{
|
||||
defaultSequence();
|
||||
close(packet);
|
||||
}
|
||||
|
||||
private void defaultSequence()
|
||||
{
|
||||
storeMe();
|
||||
deleteMe();
|
||||
}
|
||||
|
||||
public void onDisconnection()
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> defaultSequence(), _activeChar.canLogout() ? 0 : AttackStanceTaskManager.COMBAT_TIME);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,9 +21,6 @@ import java.net.InetSocketAddress;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -33,36 +30,28 @@ import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.commons.network.ChannelInboundHandler;
|
||||
import com.l2jmobius.commons.network.ICrypt;
|
||||
import com.l2jmobius.commons.network.IIncomingPacket;
|
||||
import com.l2jmobius.commons.network.IOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.LoginServerThread.SessionKey;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.enums.CharacterDeleteFailType;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.CommissionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MailManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MentorManager;
|
||||
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
import com.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.LeaveWorld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.security.SecondaryPasswordAuth;
|
||||
import com.l2jmobius.gameserver.util.FloodProtectors;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -74,7 +63,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
protected static final Logger LOGGER = Logger.getLogger(L2GameClient.class.getName());
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private final int _objectId;
|
||||
|
||||
@ -88,20 +77,15 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
private SecondaryPasswordAuth _secondaryAuth;
|
||||
private ClientHardwareInfoHolder _hardwareInfo;
|
||||
private boolean _isAuthedGG;
|
||||
private final long _connectionStartTime = System.currentTimeMillis();
|
||||
private CharSelectInfoPackage[] _charSlotMapping = null;
|
||||
|
||||
// flood protectors
|
||||
private final FloodProtectors _floodProtectors = new FloodProtectors(this);
|
||||
|
||||
// Task
|
||||
protected final ScheduledFuture<?> _autoSaveInDB;
|
||||
protected ScheduledFuture<?> _cleanupTask = null;
|
||||
|
||||
// Crypt
|
||||
private final Crypt _crypt;
|
||||
|
||||
private boolean _isDetached = false;
|
||||
private volatile boolean _isDetached = false;
|
||||
|
||||
private boolean _protocol;
|
||||
|
||||
@ -111,14 +95,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
_objectId = IdFactory.getInstance().getNextId();
|
||||
_crypt = new Crypt(this);
|
||||
if (Config.CHAR_DATA_STORE_INTERVAL > 0)
|
||||
{
|
||||
_autoSaveInDB = ThreadPoolManager.scheduleAtFixedRate(new AutoSaveTask(), 300000L, Config.CHAR_DATA_STORE_INTERVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_autoSaveInDB = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getObjectId()
|
||||
@ -135,23 +111,18 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
final InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
_addr = address.getAddress();
|
||||
_channel = ctx.channel();
|
||||
LOGGER.finer("Client Connected: " + ctx.channel());
|
||||
LOG_ACCOUNTING.finer("Client Connected: " + ctx.channel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx)
|
||||
{
|
||||
LOGGER.finer("Client Disconnected: " + ctx.channel());
|
||||
LOG_ACCOUNTING.finer("Client Disconnected: " + ctx.channel());
|
||||
|
||||
// no long running tasks here, do it async
|
||||
try
|
||||
{
|
||||
ThreadPoolManager.execute(new DisconnectTask());
|
||||
}
|
||||
catch (RejectedExecutionException e)
|
||||
{
|
||||
// server is closing
|
||||
}
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
|
||||
Disconnection.of(this).onDisconnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -172,6 +143,25 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
@ -193,19 +183,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _addr;
|
||||
}
|
||||
|
||||
public long getConnectionStartTime()
|
||||
{
|
||||
return _connectionStartTime;
|
||||
}
|
||||
|
||||
public L2PcInstance getActiveChar()
|
||||
{
|
||||
return _activeChar;
|
||||
}
|
||||
|
||||
public void setActiveChar(L2PcInstance pActiveChar)
|
||||
public void setActiveChar(L2PcInstance activeChar)
|
||||
{
|
||||
_activeChar = pActiveChar;
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
public ReentrantLock getActiveCharLock()
|
||||
@ -228,9 +213,9 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _isAuthedGG;
|
||||
}
|
||||
|
||||
public void setAccountName(String pAccountName)
|
||||
public void setAccountName(String activeChar)
|
||||
{
|
||||
_accountName = pAccountName;
|
||||
_accountName = activeChar;
|
||||
|
||||
if (SecondaryAuthData.getInstance().isEnabled())
|
||||
{
|
||||
@ -287,16 +272,16 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
|
||||
/**
|
||||
* Method to handle character deletion
|
||||
* @param charslot
|
||||
* @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 charslot)
|
||||
public CharacterDeleteFailType markToDeleteChar(int characterSlot)
|
||||
{
|
||||
final int objectId = getObjectIdForSlot(charslot);
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return CharacterDeleteFailType.UNKNOWN;
|
||||
@ -354,38 +339,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
_logAccounting.info("Delete, " + objectId + ", " + this);
|
||||
LOG_ACCOUNTING.info("Delete, " + objectId + ", " + this);
|
||||
return CharacterDeleteFailType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the L2PcInstance to the database.
|
||||
*/
|
||||
public void saveCharToDisk()
|
||||
public void restore(int characterSlot)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (getActiveChar() != null)
|
||||
{
|
||||
getActiveChar().storeMe();
|
||||
getActiveChar().storeRecommendations();
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getActiveChar().getInventory().updateDatabase();
|
||||
getActiveChar().getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error saving character..", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void markRestoredChar(int charslot)
|
||||
{
|
||||
final int objid = getObjectIdForSlot(charslot);
|
||||
if (objid < 0)
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -393,7 +354,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("UPDATE characters SET deletetime=0 WHERE charId=?"))
|
||||
{
|
||||
statement.setInt(1, objid);
|
||||
statement.setInt(1, objectId);
|
||||
statement.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -401,7 +362,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
LOGGER.log(Level.SEVERE, "Error restoring character.", e);
|
||||
}
|
||||
|
||||
_logAccounting.info("Restore, " + objid + ", " + this);
|
||||
LOG_ACCOUNTING.info("Restore, " + objectId + ", " + this);
|
||||
}
|
||||
|
||||
public static void deleteCharByObjId(int objid)
|
||||
@ -555,38 +516,30 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
public L2PcInstance loadCharFromDisk(int charslot)
|
||||
public L2PcInstance load(int characterSlot)
|
||||
{
|
||||
final int objId = getObjectIdForSlot(charslot);
|
||||
if (objId < 0)
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
if (objectId < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
L2PcInstance character = L2World.getInstance().getPlayer(objId);
|
||||
if (character != null)
|
||||
L2PcInstance player = L2World.getInstance().getPlayer(objectId);
|
||||
if (player != null)
|
||||
{
|
||||
// exploit prevention, should not happens in normal way
|
||||
LOGGER.severe("Attempt of double login: " + character.getName() + "(" + objId + ") " + getAccountName());
|
||||
if (character.getClient() != null)
|
||||
{
|
||||
character.getClient().closeNow();
|
||||
}
|
||||
else
|
||||
{
|
||||
character.deleteMe();
|
||||
}
|
||||
LOGGER.severe("Attempt of double login: " + player.getName() + "(" + objectId + ") " + getAccountName());
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
character = L2PcInstance.load(objId);
|
||||
if (character == null)
|
||||
player = L2PcInstance.load(objectId);
|
||||
if (player == null)
|
||||
{
|
||||
LOGGER.severe("could not restore in slot: " + charslot);
|
||||
LOGGER.severe("Could not restore in slot: " + characterSlot);
|
||||
}
|
||||
|
||||
// setCharacter(character);
|
||||
return character;
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -611,47 +564,21 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return _secondaryAuth;
|
||||
}
|
||||
|
||||
public void close(IOutgoingPacket packet)
|
||||
{
|
||||
if (packet != null)
|
||||
{
|
||||
_channel.writeAndFlush(packet);
|
||||
}
|
||||
_channel.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charslot
|
||||
* @param characterSlot
|
||||
* @return
|
||||
*/
|
||||
private int getObjectIdForSlot(int charslot)
|
||||
private int getObjectIdForSlot(int characterSlot)
|
||||
{
|
||||
final CharSelectInfoPackage info = getCharSelection(charslot);
|
||||
final CharSelectInfoPackage info = getCharSelection(characterSlot);
|
||||
if (info == null)
|
||||
{
|
||||
LOGGER.warning(toString() + " tried to delete Character in slot " + charslot + " but no characters exits at that slot.");
|
||||
LOGGER.warning(toString() + " tried to delete Character in slot " + characterSlot + " but no characters exits at that slot.");
|
||||
return -1;
|
||||
}
|
||||
return info.getObjectId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close client connection with {@link ServerClose} packet
|
||||
*/
|
||||
public void closeNow()
|
||||
{
|
||||
_isDetached = true; // prevents more packets execution
|
||||
close(ServerClose.STATIC_PACKET);
|
||||
synchronized (this)
|
||||
{
|
||||
if (_cleanupTask != null)
|
||||
{
|
||||
cancelCleanup();
|
||||
}
|
||||
_cleanupTask = ThreadPoolManager.schedule(new CleanupTask(), 0); // instant
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the best possible string representation of this client.
|
||||
*/
|
||||
@ -688,209 +615,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
protected class DisconnectTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
boolean fast = true;
|
||||
try
|
||||
{
|
||||
if ((getActiveChar() != null) && !isDetached())
|
||||
{
|
||||
setDetached(true);
|
||||
if (offlineMode(getActiveChar()))
|
||||
{
|
||||
getActiveChar().leaveParty();
|
||||
OlympiadManager.getInstance().unRegisterNoble(getActiveChar());
|
||||
|
||||
// If the L2PcInstance has Pet, unsummon it
|
||||
L2Summon pet = getActiveChar().getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(getActiveChar());
|
||||
pet = getActiveChar().getPet();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
getActiveChar().getServitors().values().forEach(s ->
|
||||
{
|
||||
s.setRestoreSummon(true);
|
||||
s.unSummon(getActiveChar());
|
||||
});
|
||||
|
||||
if (Config.OFFLINE_SET_NAME_COLOR)
|
||||
{
|
||||
getActiveChar().getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
|
||||
getActiveChar().broadcastUserInfo();
|
||||
}
|
||||
|
||||
if (getActiveChar().getOfflineStartTime() == 0)
|
||||
{
|
||||
getActiveChar().setOfflineStartTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// Store trade on exit, if realtime saving is enabled.
|
||||
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
|
||||
{
|
||||
OfflineTradersTable.onTransaction(getActiveChar(), false, true);
|
||||
}
|
||||
|
||||
_logAccounting.info("Entering offline mode, " + L2GameClient.this);
|
||||
return;
|
||||
}
|
||||
fast = !getActiveChar().isInCombat() && !getActiveChar().isLocked();
|
||||
}
|
||||
cleanMe(fast);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while disconnecting client.", e1);
|
||||
}
|
||||
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player the player to be check.
|
||||
* @return {@code true} if the player is allowed to remain as off-line shop.
|
||||
*/
|
||||
protected boolean offlineMode(L2PcInstance player)
|
||||
{
|
||||
if (player.isInOlympiadMode() || player.isBlockedFromExit() || player.isJailed() || (player.getVehicle() != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canSetShop = false;
|
||||
switch (player.getPrivateStoreType())
|
||||
{
|
||||
case SELL:
|
||||
case PACKAGE_SELL:
|
||||
case BUY:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
canSetShop = false;
|
||||
}
|
||||
return canSetShop;
|
||||
}
|
||||
|
||||
public void cleanMe(boolean fast)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_cleanupTask == null)
|
||||
{
|
||||
_cleanupTask = ThreadPoolManager.schedule(new CleanupTask(), fast ? 5 : 15000L);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error during cleanup.", e1);
|
||||
}
|
||||
}
|
||||
|
||||
protected class CleanupTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
// we are going to manually save the char bellow thus we can force the cancel
|
||||
if (_autoSaveInDB != null)
|
||||
{
|
||||
_autoSaveInDB.cancel(true);
|
||||
// ThreadPoolManager.getInstance().removeGeneral((Runnable) _autoSaveInDB);
|
||||
}
|
||||
|
||||
if (getActiveChar() != null) // this should only happen on connection loss
|
||||
{
|
||||
if (getActiveChar().isLocked())
|
||||
{
|
||||
LOGGER.warning("Player " + getActiveChar().getName() + " still performing subclass actions during disconnect.");
|
||||
}
|
||||
|
||||
// we store all data from players who are disconnected while in an event in order to restore it in the next login
|
||||
if (L2Event.isParticipant(getActiveChar()))
|
||||
{
|
||||
L2Event.savePlayerEventStatus(getActiveChar());
|
||||
}
|
||||
|
||||
if (getActiveChar().isOnline())
|
||||
{
|
||||
getActiveChar().deleteMe();
|
||||
AntiFeedManager.getInstance().onDisconnect(L2GameClient.this);
|
||||
}
|
||||
|
||||
// prevent closing again
|
||||
getActiveChar().setClient(null);
|
||||
}
|
||||
setActiveChar(null);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while cleanup client.", e1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class AutoSaveTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
final L2PcInstance player = getActiveChar();
|
||||
if ((player != null) && player.isOnline()) // safety precaution
|
||||
{
|
||||
saveCharToDisk();
|
||||
final L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.storeMe();
|
||||
}
|
||||
player.getServitors().values().forEach(L2Summon::storeMe);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error on AutoSaveTask.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProtocolOk()
|
||||
{
|
||||
return _protocol;
|
||||
@ -901,20 +625,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
_protocol = b;
|
||||
}
|
||||
|
||||
public boolean handleCheat(String punishment)
|
||||
{
|
||||
if (_activeChar != null)
|
||||
{
|
||||
Util.handleIllegalPlayerAction(_activeChar, toString() + ": " + punishment, Config.DEFAULT_PUNISH);
|
||||
return true;
|
||||
}
|
||||
|
||||
final Logger logAudit = Logger.getLogger("audit");
|
||||
logAudit.info("AUDIT: Client " + toString() + " kicked for reason: " + punishment);
|
||||
closeNow();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setClientTracert(int[][] tracert)
|
||||
{
|
||||
trace = tracert;
|
||||
@ -925,17 +635,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
return trace;
|
||||
}
|
||||
|
||||
private boolean cancelCleanup()
|
||||
{
|
||||
final Future<?> task = _cleanupTask;
|
||||
if (task != null)
|
||||
{
|
||||
_cleanupTask = null;
|
||||
return task.cancel(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendActionFailed()
|
||||
{
|
||||
sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
@ -54,7 +54,7 @@ public final class AuthLogin implements IClientIncomingPacket
|
||||
{
|
||||
if (_loginName.isEmpty() || !client.isProtocolOk())
|
||||
{
|
||||
client.close(null);
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerCreate;
|
||||
import com.l2jmobius.gameserver.model.items.PcItemTemplate;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharCreateFail;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharCreateOk;
|
||||
@ -333,7 +334,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
{
|
||||
newChar.getVariables().set("intro_god_video", true);
|
||||
}
|
||||
newChar.deleteMe();
|
||||
Disconnection.of(client, newChar).storeMe().deleteMe();
|
||||
|
||||
final CharSelectionInfo cl = new CharSelectionInfo(client.getAccountName(), client.getSessionId().playOkID1);
|
||||
client.setCharSelection(cl.getCharInfo());
|
||||
|
@ -47,7 +47,7 @@ public final class CharacterRestore implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
client.markRestoredChar(_charSlot);
|
||||
client.restore(_charSlot);
|
||||
final CharSelectionInfo cl = new CharSelectionInfo(client.getAccountName(), client.getSessionId().playOkID1, 0);
|
||||
client.sendPacket(cl);
|
||||
client.setCharSelection(cl.getCharInfo());
|
||||
|
@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharSelected;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
@ -146,7 +147,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
}
|
||||
|
||||
// load up character from disk
|
||||
final L2PcInstance cha = client.loadCharFromDisk(_charSlot);
|
||||
final L2PcInstance cha = client.load(_charSlot);
|
||||
if (cha == null)
|
||||
{
|
||||
return; // handled in L2GameClient
|
||||
@ -161,7 +162,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
final TerminateReturn terminate = EventDispatcher.getInstance().notifyEvent(new OnPlayerSelect(cha, cha.getObjectId(), cha.getName(), client), Containers.Players(), TerminateReturn.class);
|
||||
if ((terminate != null) && terminate.terminate())
|
||||
{
|
||||
cha.deleteMe();
|
||||
Disconnection.of(cha).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
|
||||
import com.l2jmobius.gameserver.model.variables.PlayerVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
|
||||
@ -142,7 +143,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
if (activeChar == null)
|
||||
{
|
||||
_log.warning("EnterWorld failed! activeChar returned 'null'.");
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -681,7 +682,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
{
|
||||
if (client.getHardwareInfo() == null)
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
}, 5000);
|
||||
|
@ -18,14 +18,12 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -33,7 +31,7 @@ import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
*/
|
||||
public final class Logout implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@ -47,42 +45,21 @@ public final class Logout implements IClientIncomingPacket
|
||||
final L2PcInstance player = client.getActiveChar();
|
||||
if (player == null)
|
||||
{
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasItemRequest())
|
||||
if (!player.canLogout())
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isLocked())
|
||||
LOG_ACCOUNTING.info("Logged out, " + client);
|
||||
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to logout during class change.");
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
Disconnection.of(client, player).defaultSequence(false);
|
||||
}
|
||||
|
||||
// Don't allow leaving if player is fighting
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player))
|
||||
{
|
||||
if (!player.isGM() || (player.isGM() && !Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_EXIT_THE_GAME_WHILE_IN_COMBAT);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (L2Event.isParticipant(player))
|
||||
{
|
||||
player.sendMessage("A superior power doesn't allow you to leave the event.");
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
_logAccounting.info("Disconnected, " + client);
|
||||
|
||||
player.logout();
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public final class ProtocolVersion implements IClientIncomingPacket
|
||||
if (_version == -2)
|
||||
{
|
||||
// this is just a ping attempt from the new C2 client
|
||||
client.close(null);
|
||||
client.closeNow();
|
||||
}
|
||||
else if (!Config.PROTOCOL_LIST.contains(_version))
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcMenuSelect;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerBypass;
|
||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
@ -86,7 +87,7 @@ public final class RequestBypassToServer implements IClientIncomingPacket
|
||||
if (_command.isEmpty())
|
||||
{
|
||||
_log.warning("Player " + activeChar.getName() + " sent empty bypass!");
|
||||
activeChar.logout();
|
||||
Disconnection.of(client, activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ClientHardwareInfoHolder;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -93,7 +94,7 @@ public final class RequestHardWareInfo implements IClientIncomingPacket
|
||||
}
|
||||
if (count >= Config.MAX_PLAYERS_PER_HWID)
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -18,16 +18,15 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharSelectionInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.RestartResponse;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -35,7 +34,7 @@ import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
*/
|
||||
public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
@Override
|
||||
public boolean read(L2GameClient client, PacketReader packet)
|
||||
@ -52,43 +51,20 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasItemRequest())
|
||||
if (!player.canLogout())
|
||||
{
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isLocked())
|
||||
LOG_ACCOUNTING.info("Logged out, " + client);
|
||||
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to restart during class change.");
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
Disconnection.of(client, player).storeMe().deleteMe();
|
||||
}
|
||||
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) && !(player.isGM() && Config.GM_RESTART_FIGHTING))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_RESTART_WHILE_IN_COMBAT);
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isBlockedFromExit())
|
||||
{
|
||||
client.sendPacket(RestartResponse.FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
_logAccounting.info("Logged out, " + client);
|
||||
|
||||
player.deleteMe();
|
||||
|
||||
client.setActiveChar(null);
|
||||
|
||||
// detach the client from the char so that the connection isnt closed in the deleteMe
|
||||
player.setClient(null);
|
||||
|
||||
AntiFeedManager.getInstance().onDisconnect(client);
|
||||
|
||||
// return the client to the authed status
|
||||
client.setConnectionState(ConnectionState.AUTHENTICATED);
|
||||
|
||||
|
@ -31,6 +31,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerChat;
|
||||
import com.l2jmobius.gameserver.model.events.returns.ChatFilterReturn;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@ -110,7 +111,7 @@ public final class Say2 implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning("Say2: Invalid type: " + _type + " Player : " + activeChar.getName() + " text: " + _text);
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
activeChar.logout();
|
||||
Disconnection.of(activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,7 +119,7 @@ public final class Say2 implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning(activeChar.getName() + ": sending empty text. Possible packet hack!");
|
||||
activeChar.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
activeChar.logout();
|
||||
Disconnection.of(activeChar).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import java.util.logging.Logger;
|
||||
import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ex2ndPasswordAck;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Ex2ndPasswordCheck;
|
||||
@ -104,7 +105,7 @@ public class SecondaryPasswordAuth
|
||||
if (passwordExist())
|
||||
{
|
||||
_log.warning("[SecondaryPasswordAuth]" + _activeClient.getAccountName() + " forced savePassword");
|
||||
_activeClient.closeNow();
|
||||
Disconnection.of(_activeClient).defaultSequence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ public class SecondaryPasswordAuth
|
||||
if (!passwordExist())
|
||||
{
|
||||
_log.warning("[SecondaryPasswordAuth]" + _activeClient.getAccountName() + " forced changePassword");
|
||||
_activeClient.closeNow();
|
||||
Disconnection.of(_activeClient).defaultSequence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,8 @@ public class AttackStanceTaskManager
|
||||
|
||||
protected static final Map<L2Character, Long> _attackStanceTasks = new ConcurrentHashMap<>();
|
||||
|
||||
public static final long COMBAT_TIME = 15_000;
|
||||
|
||||
/**
|
||||
* Instantiates a new attack stance task manager.
|
||||
*/
|
||||
@ -106,7 +108,7 @@ public class AttackStanceTaskManager
|
||||
while (iter.hasNext())
|
||||
{
|
||||
e = iter.next();
|
||||
if ((current - e.getValue()) > 15000)
|
||||
if ((current - e.getValue()) > COMBAT_TIME)
|
||||
{
|
||||
actor = e.getKey();
|
||||
if (actor != null)
|
||||
|
@ -28,6 +28,7 @@ import com.l2jmobius.gameserver.model.punishment.PunishmentAffect;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.ConnectionState;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -142,14 +143,7 @@ public final class FloodProtectorAction
|
||||
*/
|
||||
private void kickPlayer()
|
||||
{
|
||||
if (_client.getActiveChar() != null)
|
||||
{
|
||||
_client.getActiveChar().logout(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_client.closeNow();
|
||||
}
|
||||
Disconnection.of(_client).defaultSequence(false);
|
||||
|
||||
if (_log.getLevel() == Level.WARNING)
|
||||
{
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 com.l2jmobius.gameserver.util;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadManager;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
* @author lord_rex
|
||||
*/
|
||||
public final class OfflineTradeUtil
|
||||
{
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private OfflineTradeUtil()
|
||||
{
|
||||
// utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether player is able to enter offline mode.
|
||||
* @param player the player to be check.
|
||||
* @return {@code true} if the player is allowed to remain as off-line shop.
|
||||
*/
|
||||
private static boolean offlineMode(L2PcInstance player)
|
||||
{
|
||||
if ((player == null) || player.isInOlympiadMode() || player.isBlockedFromExit() || player.isJailed() || (player.getVehicle() != null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canSetShop = false;
|
||||
switch (player.getPrivateStoreType())
|
||||
{
|
||||
case SELL:
|
||||
case PACKAGE_SELL:
|
||||
case BUY:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
case MANUFACTURE:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_TRADE_ENABLE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
canSetShop = false;
|
||||
}
|
||||
|
||||
// Check whether client is null or player is already in offline mode.
|
||||
final L2GameClient client = player.getClient();
|
||||
if ((client == null) || client.isDetached())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return canSetShop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the disconnection process of offline traders.
|
||||
* @param player
|
||||
* @return {@code true} when player entered offline mode, otherwise {@code false}
|
||||
*/
|
||||
public static boolean enteredOfflineMode(L2PcInstance player)
|
||||
{
|
||||
if (!OfflineTradeUtil.offlineMode(player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2GameClient client = player.getClient();
|
||||
client.setDetached(true);
|
||||
|
||||
player.leaveParty();
|
||||
OlympiadManager.getInstance().unRegisterNoble(player);
|
||||
|
||||
// If the L2PcInstance has Pet, unsummon it
|
||||
L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(player);
|
||||
pet = player.getPet();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
player.getServitors().values().forEach(s ->
|
||||
{
|
||||
s.setRestoreSummon(true);
|
||||
s.unSummon(player);
|
||||
});
|
||||
|
||||
if (Config.OFFLINE_SET_NAME_COLOR)
|
||||
{
|
||||
player.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
|
||||
player.broadcastUserInfo();
|
||||
}
|
||||
|
||||
if (player.getOfflineStartTime() == 0)
|
||||
{
|
||||
player.setOfflineStartTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// Store trade on exit, if realtime saving is enabled.
|
||||
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
|
||||
{
|
||||
OfflineTradersTable.onTransaction(player, false, true);
|
||||
}
|
||||
|
||||
Disconnection.of(player).storeMe().close(false);
|
||||
LOG_ACCOUNTING.info("Entering offline mode, " + client);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2AccessLevel;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -129,7 +130,7 @@ public final class AdminChangeAccessLevel implements IAdminCommandHandler
|
||||
{
|
||||
player.setAccessLevel(lvl, false, true);
|
||||
player.sendMessage("Your character has been banned. Bye.");
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package handlers.admincommandhandlers;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
/**
|
||||
* This class handles following admin commands: - character_disconnect = disconnects target player
|
||||
@ -68,7 +69,7 @@ public class AdminDisconnect implements IAdminCommandHandler
|
||||
{
|
||||
activeChar.sendMessage("Character " + player.getName() + " disconnected from server.");
|
||||
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ package handlers.admincommandhandlers;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
public class AdminKick implements IAdminCommandHandler
|
||||
{
|
||||
@ -44,11 +44,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
final L2PcInstance plyr = L2World.getInstance().getPlayer(player);
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
activeChar.sendMessage("You kicked " + plyr.getName() + " from the game.");
|
||||
}
|
||||
}
|
||||
@ -61,7 +57,7 @@ public class AdminKick implements IAdminCommandHandler
|
||||
if (!player.isGM())
|
||||
{
|
||||
counter++;
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
activeChar.sendMessage("Kicked " + counter + " players.");
|
||||
|
@ -21,7 +21,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.handler.AdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
@ -31,6 +30,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
@ -170,11 +170,7 @@ public class AdminMenu implements IAdminCommandHandler
|
||||
String text;
|
||||
if (plyr != null)
|
||||
{
|
||||
if (plyr.getOfflineStartTime() > 0)
|
||||
{
|
||||
OfflineTradersTable.removeTrader(plyr.getObjectId());
|
||||
}
|
||||
plyr.logout();
|
||||
Disconnection.of(plyr).defaultSequence(false);
|
||||
text = "You kicked " + plyr.getName() + " from the game.";
|
||||
}
|
||||
else
|
||||
|
@ -22,6 +22,7 @@ import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentTask;
|
||||
import com.l2jmobius.gameserver.model.punishment.PunishmentType;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
/**
|
||||
@ -58,7 +59,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -90,7 +91,7 @@ public class BanHandler implements IPunishmentHandler
|
||||
*/
|
||||
private static void applyToPlayer(L2PcInstance player)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ package handlers.telnethandlers.player;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.telnet.ITelnetCommand;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -49,7 +50,7 @@ public class Kick implements ITelnetCommand
|
||||
final L2PcInstance player = L2World.getInstance().getPlayer(args[0]);
|
||||
if (player != null)
|
||||
{
|
||||
player.logout();
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
return "Player has been successfully kicked.";
|
||||
}
|
||||
return "Couldn't find player with such name.";
|
||||
|
@ -565,15 +565,8 @@ public class LoginServerThread extends Thread
|
||||
final L2GameClient client = _accountsInGameServer.get(account);
|
||||
if (client != null)
|
||||
{
|
||||
if (client.isDetached())
|
||||
{
|
||||
client.getActiveChar().logout();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
ACCOUNTING_LOGGER.info(getClass().getSimpleName() + ": Kicked by login, " + client);
|
||||
ACCOUNTING_LOGGER.info("Kicked by login, " + client);
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_LOGGED_IN_TO_TWO_PLACES_IF_YOU_SUSPECT_ACCOUNT_THEFT_WE_RECOMMEND_CHANGING_YOUR_PASSWORD_SCANNING_YOUR_COMPUTER_FOR_VIRUSES_AND_USING_AN_ANTI_VIRUS_SOFTWARE));
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user