Disconnection class for HighFive.
This commit is contained in:
parent
d13c74be0e
commit
abf364f1d0
@ -1,184 +0,0 @@
|
||||
/*
|
||||
* 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 custom.listeners;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.events.Containers;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.Id;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.NpcLevelRange;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.Priority;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.Range;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureKill;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerDlgAnswer;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogin;
|
||||
import com.l2jmobius.gameserver.model.events.impl.item.OnItemCreate;
|
||||
import com.l2jmobius.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
|
||||
import com.l2jmobius.gameserver.model.events.listeners.ConsumerEventListener;
|
||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* An example usage of Listeners.
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class ListenerTest extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] ELPIES =
|
||||
{
|
||||
20432,
|
||||
22228
|
||||
};
|
||||
|
||||
private ListenerTest()
|
||||
{
|
||||
super(ListenerTest.class.getSimpleName(), "ai/npc");
|
||||
|
||||
// Method preset listener registration
|
||||
// An set function which is a Consumer it has one parameter and doesn't returns anything!
|
||||
setAttackableAttackId(this::onAttackableAttack, ELPIES);
|
||||
|
||||
// Manual listener registration
|
||||
Containers.Global().addListener(new ConsumerEventListener(Containers.Global(), EventType.ON_PLAYER_DLG_ANSWER, (OnPlayerDlgAnswer event) ->
|
||||
{
|
||||
_log.log(Level.INFO, ListenerTest.class.getSimpleName() + ": " + event.getActiveChar() + " OnPlayerDlgAnswer: Answer: " + event.getAnswer() + " MessageId: " + event.getMessageId());
|
||||
}, this));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be invoked as soon as an L2Attackable (Rabbits 20432 and 22228) is being attacked from L2PcInstance (a player)
|
||||
* @param event
|
||||
*/
|
||||
public void onAttackableAttack(OnAttackableAttack event)
|
||||
{
|
||||
_log.log(Level.INFO, getClass().getSimpleName() + ": " + event.getClass().getSimpleName() + " invoked attacker: " + event.getAttacker() + " target: " + event.getTarget() + " damage: " + event.getDamage() + " skill: " + event.getSkill());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be invoked as soon as L2Attackable (Rabbits 20432 and 22228) are being killed by L2PcInstance (a player)<br>
|
||||
* This listener is registered into individual npcs container.
|
||||
* @param event
|
||||
*/
|
||||
// Annotation listener registration
|
||||
@RegisterEvent(EventType.ON_CREATURE_KILL)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(20432)
|
||||
@Id(22228)
|
||||
public void onCreatureKill(OnCreatureKill event)
|
||||
{
|
||||
_log.log(Level.INFO, getClass().getSimpleName() + ": " + event.getClass().getSimpleName() + " invoked attacker: " + event.getAttacker() + " target: " + event.getTarget());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be invoked as soon as Siege of castle ids 1-9 starts<br>
|
||||
* This listener is registered into individual castle container.
|
||||
* @param event
|
||||
*/
|
||||
@RegisterEvent(EventType.ON_CASTLE_SIEGE_START)
|
||||
@RegisterType(ListenerRegisterType.CASTLE)
|
||||
@Range(from = 1, to = 9)
|
||||
public void onSiegeStart(OnCastleSiegeStart event)
|
||||
{
|
||||
_log.log(Level.INFO, getClass().getSimpleName() + ": The siege of " + event.getSiege().getCastle().getName() + " (" + event.getSiege().getCastle().getResidenceId() + ") has started!");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be invoked as soon as Ancient Adena (5575) item is created on player's inventory (As new item!).<br>
|
||||
* This listener is registered into individual items container.
|
||||
* @param event
|
||||
*/
|
||||
@RegisterEvent(EventType.ON_ITEM_CREATE)
|
||||
@RegisterType(ListenerRegisterType.ITEM)
|
||||
@Id(5575)
|
||||
public void onItemCreate(OnItemCreate event)
|
||||
{
|
||||
_log.log(Level.INFO, getClass().getSimpleName() + ": Item [" + event.getItem() + "] has been created actor: " + event.getActiveChar() + " process: " + event.getProcess() + " reference: " + event.getReference());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prioritized event notification <br>
|
||||
* This method will be invoked as soon as creature from level range between 1 and 10 dies.<br>
|
||||
* This listener is registered into individual npcs container.
|
||||
* @param event
|
||||
*/
|
||||
@RegisterEvent(EventType.ON_CREATURE_KILL)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@NpcLevelRange(from = 1, to = 10)
|
||||
@Priority(100)
|
||||
public void OnCreatureKill(OnCreatureKill event)
|
||||
{
|
||||
// 70% chance to drop
|
||||
if (Rnd.get(100) >= 70)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure a player killed this monster.
|
||||
if ((event.getAttacker() != null) && event.getAttacker().isPlayable() && event.getTarget().isAttackable())
|
||||
{
|
||||
final L2Attackable monster = (L2Attackable) event.getTarget();
|
||||
monster.dropItem(event.getAttacker().getActingPlayer(), new ItemHolder(57, Rnd.get(100, 1000)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be invoked as soon a a player logs into the game.<br>
|
||||
* This listener is registered into global players container.
|
||||
* @param event
|
||||
*/
|
||||
@RegisterEvent(EventType.ON_PLAYER_LOGIN)
|
||||
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
|
||||
public void onPlayerLogin(OnPlayerLogin event)
|
||||
{
|
||||
_log.log(Level.INFO, getClass().getSimpleName() + ": Player: " + event.getActiveChar() + " has logged in!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prioritized event notification - Ensuring that this listener will be the first to receive notification.<br>
|
||||
* Also this method interrupts notification to other listeners and taking over return if somehow it wasn't the first one to set.<br>
|
||||
* This method will be invoked as soon a a creature dies.<br>
|
||||
* This listener is registered into global players container.
|
||||
* @param event
|
||||
* @return termination return preventing the base code execution if needed.
|
||||
*/
|
||||
@RegisterEvent(EventType.ON_CREATURE_KILL)
|
||||
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
|
||||
@Priority(Integer.MAX_VALUE)
|
||||
public TerminateReturn onPlayerDeath(OnCreatureKill event)
|
||||
{
|
||||
if (event.getTarget().isGM())
|
||||
{
|
||||
_log.log(Level.INFO, getClass().getSimpleName() + ": Player: " + event.getTarget() + " was prevented from dying!");
|
||||
return new TerminateReturn(true, true, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new ListenerTest();
|
||||
}
|
||||
}
|
@ -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);
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -172,11 +172,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.";
|
||||
|
@ -557,12 +557,23 @@ public class LoginServerThread extends Thread
|
||||
* Kick player for the given account.
|
||||
* @param account the account
|
||||
*/
|
||||
public void doKickPlayer(String account)
|
||||
private void doKickPlayer(String account)
|
||||
{
|
||||
final L2GameClient client = _accountsInGameServer.get(account);
|
||||
if (client != null)
|
||||
{
|
||||
ACCOUNTING_LOGGER.info("Kicked by login, " + client);
|
||||
if (client.isDetached())
|
||||
{
|
||||
if (client.getActiveChar() != null)
|
||||
{
|
||||
client.getActiveChar().deleteMe();
|
||||
}
|
||||
sendLogout(account);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACCOUNTING_LOGGER.info("Kicked by login, " + client);
|
||||
}
|
||||
client.close(SystemMessage.getSystemMessage(SystemMessageId.ANOTHER_PERSON_HAS_LOGGED_IN_WITH_THE_SAME_ACCOUNT));
|
||||
}
|
||||
}
|
||||
|
@ -40,11 +40,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.util.Broadcast;
|
||||
|
||||
@ -616,27 +615,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 (!player.isInOfflineMode())
|
||||
// player is probably a bot - force logout
|
||||
{
|
||||
player.logout();
|
||||
}
|
||||
player.deleteMe();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed logout char " + player, t);
|
||||
}
|
||||
Disconnection.of(player).defaultSequence(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ import com.l2jmobius.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.TradeItem;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
|
||||
public class OfflineTradersTable
|
||||
@ -48,6 +49,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();
|
||||
@ -64,7 +69,7 @@ public class OfflineTradersTable
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((pc.getPrivateStoreType() != PrivateStoreType.NONE) && pc.isInOfflineMode())
|
||||
if ((pc.getPrivateStoreType() != PrivateStoreType.NONE) && ((pc.getClient() == null) || pc.getClient().isDetached()))
|
||||
{
|
||||
stm3.setInt(1, pc.getObjectId()); // Char Id
|
||||
stm3.setLong(2, pc.getOfflineStartTime());
|
||||
@ -192,7 +197,6 @@ public class OfflineTradersTable
|
||||
client.setActiveChar(player);
|
||||
player.setOnlineStatus(true, false);
|
||||
client.setAccountName(player.getAccountNamePlayer());
|
||||
L2World.getInstance().addPlayerToWorld(player);
|
||||
player.setClient(client);
|
||||
player.setOfflineStartTime(time);
|
||||
player.spawnMe(player.getX(), player.getY(), player.getZ());
|
||||
@ -260,11 +264,7 @@ public class OfflineTradersTable
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error loading trader: " + player, e);
|
||||
if (player != null)
|
||||
{
|
||||
player.deleteMe();
|
||||
if (player.getClient() != null)
|
||||
{
|
||||
player.getClient().closeNow();
|
||||
}
|
||||
Disconnection.of(player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -419,11 +419,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();
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ public class ItemTable
|
||||
}
|
||||
|
||||
// Add the L2ItemInstance object to _allObjects of L2world
|
||||
L2World.getInstance().storeObject(item);
|
||||
L2World.getInstance().addObject(item);
|
||||
|
||||
// Set Item parameters
|
||||
if (item.isStackable() && (count > 1))
|
||||
|
@ -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.L2JMOD_ANTIFEED_INTERVAL > 0) && _lastDeathTimes.containsKey(targetPlayer.getObjectId()))
|
||||
{
|
||||
if ((System.currentTimeMillis() - _lastDeathTimes.get(targetPlayer.getObjectId())) < Config.L2JMOD_ANTIFEED_INTERVAL)
|
||||
@ -211,7 +217,7 @@ public final class AntiFeedManager
|
||||
*/
|
||||
public final void onDisconnect(L2GameClient client)
|
||||
{
|
||||
if (client == null)
|
||||
if ((client == null) || (client.getConnectionAddress() == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ public final class ItemsOnGroundManager implements Runnable
|
||||
while (rs.next())
|
||||
{
|
||||
item = new L2ItemInstance(rs.getInt(1), rs.getInt(2));
|
||||
L2World.getInstance().storeObject(item);
|
||||
L2World.getInstance().addObject(item);
|
||||
// this check and..
|
||||
if (item.isStackable() && (rs.getInt(3) > 1))
|
||||
{
|
||||
|
@ -190,7 +190,7 @@ public final class MercTicketManager
|
||||
dropticket.setItemLocation(ItemLocation.VOID);
|
||||
dropticket.dropMe(null, x, y, z);
|
||||
dropticket.setDropTime(0); // avoids it from being removed by the auto item destroyer
|
||||
L2World.getInstance().storeObject(dropticket);
|
||||
L2World.getInstance().addObject(dropticket);
|
||||
DROPPED_TICKETS.add(dropticket);
|
||||
}
|
||||
break;
|
||||
@ -326,7 +326,7 @@ public final class MercTicketManager
|
||||
dropticket.setItemLocation(ItemLocation.VOID);
|
||||
dropticket.dropMe(null, x, y, z);
|
||||
dropticket.setDropTime(0); // avoids it from beeing removed by the auto item destroyer
|
||||
L2World.getInstance().storeObject(dropticket); // add to the world
|
||||
L2World.getInstance().addObject(dropticket); // add to the world
|
||||
// and keep track of this ticket in the list
|
||||
DROPPED_TICKETS.add(dropticket);
|
||||
|
||||
|
@ -190,7 +190,7 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
||||
setWorldRegion(L2World.getInstance().getRegion(getLocation()));
|
||||
|
||||
// Add the L2Object spawn in the _allobjects of L2World
|
||||
L2World.getInstance().storeObject(this);
|
||||
L2World.getInstance().addObject(this);
|
||||
|
||||
// Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
|
||||
getWorldRegion().addVisibleObject(this);
|
||||
@ -237,7 +237,7 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
||||
// Add the L2Object spawn in the _allobjects of L2World
|
||||
}
|
||||
|
||||
L2World.getInstance().storeObject(this);
|
||||
L2World.getInstance().addObject(this);
|
||||
|
||||
// these can synchronize on others instances, so they're out of
|
||||
// synchronized, to avoid deadlocks
|
||||
|
@ -24,18 +24,19 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
|
||||
public final class L2World
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(L2World.class.getName());
|
||||
private static final Logger LOGGER = Logger.getLogger(L2World.class.getName());
|
||||
/** Gracia border Flying objects not allowed to the east of it. */
|
||||
public static final int GRACIA_MAX_X = -166168;
|
||||
public static final int GRACIA_MAX_Z = 6105;
|
||||
@ -91,16 +92,29 @@ public final class L2World
|
||||
* </ul>
|
||||
* @param object
|
||||
*/
|
||||
public void storeObject(L2Object object)
|
||||
public void addObject(L2Object object)
|
||||
{
|
||||
if (_allObjects.containsKey(object.getObjectId()))
|
||||
if (_allObjects.putIfAbsent(object.getObjectId(), object) != null)
|
||||
{
|
||||
_log.log(Level.WARNING, getClass().getSimpleName() + ": Current object: " + object + " already exist in OID map!");
|
||||
_log.log(Level.WARNING, "---------------------- End ---------------------");
|
||||
return;
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Object " + object + " already exists in the world. Stack Trace: " + CommonUtil.getTraceString(Thread.currentThread().getStackTrace()));
|
||||
}
|
||||
|
||||
_allObjects.put(object.getObjectId(), object);
|
||||
if (object.isPlayer())
|
||||
{
|
||||
final L2PcInstance newPlayer = (L2PcInstance) object;
|
||||
if (newPlayer.isTeleporting()) // TODO: drop when we stop removing player from the world while teleporting.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance existingPlayer = _allPlayers.putIfAbsent(object.getObjectId(), newPlayer);
|
||||
if (existingPlayer != null)
|
||||
{
|
||||
Disconnection.of(existingPlayer).defaultSequence(false);
|
||||
Disconnection.of(newPlayer).defaultSequence(false);
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Duplicate character!? Disconnected both characters (" + newPlayer.getName() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,6 +130,15 @@ public final class L2World
|
||||
public void removeObject(L2Object object)
|
||||
{
|
||||
_allObjects.remove(object.getObjectId());
|
||||
if (object.isPlayer())
|
||||
{
|
||||
final L2PcInstance player = (L2PcInstance) object;
|
||||
if (player.isTeleporting()) // TODO: drop when we stop removing player from the world while teleportingq.
|
||||
{
|
||||
return;
|
||||
}
|
||||
_allPlayers.remove(object.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,24 +304,6 @@ public final class L2World
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the player to the world.
|
||||
* @param player the player to add
|
||||
*/
|
||||
public void addPlayerToWorld(L2PcInstance player)
|
||||
{
|
||||
_allPlayers.put(player.getObjectId(), player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the player from the world.
|
||||
* @param player the player to remove
|
||||
*/
|
||||
public void removeFromAllPlayers(L2PcInstance player)
|
||||
{
|
||||
_allPlayers.remove(player.getObjectId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object from the world.<br>
|
||||
* <B><U> Concept</U> :</B> L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
|
||||
@ -558,7 +563,7 @@ public final class L2World
|
||||
}
|
||||
}
|
||||
|
||||
_log.info("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
|
||||
LOGGER.info("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -566,7 +571,7 @@ public final class L2World
|
||||
*/
|
||||
public void deleteVisibleNpcSpawns()
|
||||
{
|
||||
_log.info("Deleting all visible NPCs.");
|
||||
LOGGER.info("Deleting all visible NPCs.");
|
||||
for (int i = 0; i <= REGIONS_X; i++)
|
||||
{
|
||||
for (int j = 0; j <= REGIONS_Y; j++)
|
||||
@ -574,7 +579,7 @@ public final class L2World
|
||||
_worldRegions[i][j].deleteVisibleNpcSpawns();
|
||||
}
|
||||
}
|
||||
_log.info("All visible NPCs deleted.");
|
||||
LOGGER.info("All visible NPCs deleted.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,6 +124,7 @@ import com.l2jmobius.gameserver.model.stats.Formulas;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.model.stats.functions.AbstractFunction;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractNpcInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@ -4384,7 +4385,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())
|
||||
{
|
||||
|
@ -252,6 +252,7 @@ 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.model.zone.type.L2BossZone;
|
||||
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;
|
||||
@ -282,7 +283,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;
|
||||
@ -303,7 +303,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;
|
||||
@ -826,6 +825,8 @@ public final class L2PcInstance extends L2Playable
|
||||
|
||||
private volatile int _actionMask;
|
||||
|
||||
private Future<?> _autoSaveTask = null;
|
||||
|
||||
/**
|
||||
* Creates a player.
|
||||
* @param objectId the object ID
|
||||
@ -1267,38 +1268,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.
|
||||
*/
|
||||
@ -3947,33 +3916,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;
|
||||
@ -6967,6 +6909,10 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
player.setOverrideCond(player.getVariables().getLong(COND_OVERRIDE_KEY, PcCondOverride.getAllExceptionsMask()));
|
||||
}
|
||||
|
||||
player.setOnlineStatus(true, false);
|
||||
|
||||
player.startAutoSaveTask();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -8165,6 +8111,56 @@ public final class L2PcInstance extends L2Playable
|
||||
return _hennaDEX;
|
||||
}
|
||||
|
||||
private void startAutoSaveTask()
|
||||
{
|
||||
if ((Config.CHAR_DATA_STORE_INTERVAL > 0) && (_autoSaveTask == null))
|
||||
{
|
||||
_autoSaveTask = ThreadPool.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(false);
|
||||
|
||||
if (Config.UPDATE_ITEMS_ON_CHAR_STORE)
|
||||
{
|
||||
getInventory().updateDatabase();
|
||||
getWarehouse().updateDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canLogout()
|
||||
{
|
||||
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>
|
||||
@ -11039,23 +11035,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();
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
private synchronized void cleanup()
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLogout(this), this);
|
||||
|
||||
@ -11452,9 +11444,17 @@ public final class L2PcInstance extends L2Playable
|
||||
player.removeSnooped(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());
|
||||
|
||||
// Remove L2Object object from _allObjects of L2World
|
||||
L2World.getInstance().removeObject(this);
|
||||
L2World.getInstance().removeFromAllPlayers(this);
|
||||
|
||||
try
|
||||
{
|
||||
@ -11465,6 +11465,10 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
_log.log(Level.WARNING, "Exception on deleteMe() notifyFriends: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
stopAutoSaveTask();
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
private L2Fish _fish;
|
||||
|
@ -28,6 +28,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.
|
||||
@ -93,7 +94,7 @@ public final class IllegalPlayerActionTask implements Runnable
|
||||
}
|
||||
case KICK:
|
||||
{
|
||||
_actor.logout(false);
|
||||
Disconnection.of(_actor).defaultSequence(false);
|
||||
break;
|
||||
}
|
||||
case KICKBAN:
|
||||
|
@ -1820,7 +1820,7 @@ public abstract class Inventory extends ItemContainer
|
||||
}
|
||||
}
|
||||
|
||||
L2World.getInstance().storeObject(item);
|
||||
L2World.getInstance().addObject(item);
|
||||
|
||||
// If stackable item is found in inventory just add to current quantity
|
||||
if (item.isStackable() && (getItemByItemId(item.getId()) != null))
|
||||
|
@ -636,7 +636,7 @@ public abstract class ItemContainer
|
||||
continue;
|
||||
}
|
||||
|
||||
L2World.getInstance().storeObject(item);
|
||||
L2World.getInstance().addObject(item);
|
||||
|
||||
// If stackable item is found in inventory just add to current quantity
|
||||
if (item.isStackable() && (getItemByItemId(item.getId()) != null))
|
||||
|
@ -133,7 +133,7 @@ public class Mail extends ItemContainer
|
||||
continue;
|
||||
}
|
||||
|
||||
L2World.getInstance().storeObject(item);
|
||||
L2World.getInstance().addObject(item);
|
||||
|
||||
// If stackable item is found just add to current quantity
|
||||
if (item.isStackable() && (getItemByItemId(item.getId()) != null))
|
||||
|
@ -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.commons.concurrent.ThreadPool;
|
||||
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)
|
||||
{
|
||||
ThreadPool.schedule(() -> defaultSequence(), _activeChar.canLogout() ? 0 : AttackStanceTaskManager.COMBAT_TIME);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,43 +22,33 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
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.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
||||
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.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.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.L2Event;
|
||||
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;
|
||||
@ -70,7 +60,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;
|
||||
|
||||
@ -84,20 +74,15 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
private SecondaryPasswordAuth _secondaryAuth;
|
||||
|
||||
private boolean _isAuthedGG;
|
||||
private final long _connectionStartTime = System.currentTimeMillis();
|
||||
private List<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;
|
||||
|
||||
@ -107,14 +92,6 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
_objectId = IdFactory.getInstance().getNextId();
|
||||
_crypt = new Crypt(this);
|
||||
if (Config.CHAR_DATA_STORE_INTERVAL > 0)
|
||||
{
|
||||
_autoSaveInDB = ThreadPool.scheduleAtFixedRate(new AutoSaveTask(), 300000L, Config.CHAR_DATA_STORE_INTERVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
_autoSaveInDB = null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getObjectId()
|
||||
@ -131,23 +108,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
|
||||
{
|
||||
ThreadPool.execute(new DisconnectTask());
|
||||
}
|
||||
catch (RejectedExecutionException e)
|
||||
{
|
||||
// server is closing
|
||||
}
|
||||
LoginServerThread.getInstance().sendLogout(getAccountName());
|
||||
IdFactory.getInstance().releaseId(getObjectId());
|
||||
|
||||
Disconnection.of(this).onDisconnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -168,6 +140,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;
|
||||
@ -189,19 +180,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()
|
||||
@ -224,9 +210,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())
|
||||
{
|
||||
@ -283,18 +269,18 @@ 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 byte markToDeleteChar(int charslot)
|
||||
public byte markToDeleteChar(int characterSlot)
|
||||
{
|
||||
final int objid = getObjectIdForSlot(charslot);
|
||||
final int objectId = getObjectIdForSlot(characterSlot);
|
||||
|
||||
if (objid < 0)
|
||||
if (objectId < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -302,7 +288,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
try (Connection con = DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT clanId FROM characters WHERE charId=?"))
|
||||
{
|
||||
statement.setInt(1, objid);
|
||||
statement.setInt(1, objectId);
|
||||
byte answer = 0;
|
||||
try (ResultSet rs = statement.executeQuery())
|
||||
{
|
||||
@ -315,7 +301,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
answer = 0; // jeezes!
|
||||
}
|
||||
else if (clan.getLeaderId() == objid)
|
||||
else if (clan.getLeaderId() == objectId)
|
||||
{
|
||||
answer = 2;
|
||||
}
|
||||
@ -330,14 +316,14 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
{
|
||||
if (Config.DELETE_DAYS == 0)
|
||||
{
|
||||
deleteCharByObjId(objid);
|
||||
deleteCharByObjId(objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
try (PreparedStatement ps2 = con.prepareStatement("UPDATE characters SET deletetime=? WHERE charId=?"))
|
||||
{
|
||||
ps2.setLong(1, System.currentTimeMillis() + (Config.DELETE_DAYS * 86400000L)); // 24*60*60*1000 = 86400000
|
||||
ps2.setInt(2, objid);
|
||||
ps2.setInt(2, objectId);
|
||||
ps2.execute();
|
||||
}
|
||||
}
|
||||
@ -345,10 +331,10 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
final LogRecord record = new LogRecord(Level.WARNING, "Delete");
|
||||
record.setParameters(new Object[]
|
||||
{
|
||||
objid,
|
||||
objectId,
|
||||
this
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
@ -360,34 +346,10 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the L2PcInstance to the database.
|
||||
*/
|
||||
public void saveCharToDisk()
|
||||
public void restore(int characterSlot)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (getActiveChar() != null)
|
||||
{
|
||||
getActiveChar().storeMe();
|
||||
getActiveChar().storeRecommendations(false);
|
||||
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;
|
||||
}
|
||||
@ -395,7 +357,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)
|
||||
@ -406,10 +368,10 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
|
||||
final LogRecord record = new LogRecord(Level.WARNING, "Restore");
|
||||
record.setParameters(new Object[]
|
||||
{
|
||||
objid,
|
||||
objectId,
|
||||
this
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
}
|
||||
|
||||
public static void deleteCharByObjId(int objid)
|
||||
@ -573,48 +535,42 @@ 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)
|
||||
if (player.isOnlineInt() == 1)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// preinit some values for each login
|
||||
character.setRunning(); // running is default
|
||||
character.standUp(); // standing is default
|
||||
// prevent some values for each login
|
||||
player.setRunning(); // running is default
|
||||
player.standUp(); // standing is default
|
||||
|
||||
character.refreshOverloaded();
|
||||
character.refreshExpertisePenalty();
|
||||
character.setOnlineStatus(true, false);
|
||||
player.refreshOverloaded();
|
||||
player.refreshExpertisePenalty();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.severe("could not restore in slot: " + charslot);
|
||||
LOGGER.severe("Could not restore in slot: " + characterSlot);
|
||||
}
|
||||
|
||||
// setCharacter(character);
|
||||
return character;
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -639,47 +595,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 = ThreadPool.schedule(new CleanupTask(), 0); // instant
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the best possible string representation of this client.
|
||||
*/
|
||||
@ -716,204 +646,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
|
||||
if (getActiveChar().hasSummon())
|
||||
{
|
||||
getActiveChar().getSummon().setRestoreSummon(true);
|
||||
|
||||
getActiveChar().getSummon().unSummon(getActiveChar());
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (getActiveChar().getSummon() != null)
|
||||
{
|
||||
getActiveChar().getSummon().broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
final LogRecord record = new LogRecord(Level.INFO, "Entering offline mode");
|
||||
record.setParameters(new Object[]
|
||||
{
|
||||
L2GameClient.this
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
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.isFestivalParticipant() || 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 = ThreadPool.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);
|
||||
// ThreadPool.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();
|
||||
if (player.hasSummon())
|
||||
{
|
||||
player.getSummon().storeMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, "Error on AutoSaveTask.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProtocolOk()
|
||||
{
|
||||
return _protocol;
|
||||
@ -924,20 +656,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;
|
||||
@ -948,17 +666,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);
|
||||
|
@ -20,7 +20,6 @@ import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.LoginServerThread;
|
||||
import com.l2jmobius.gameserver.LoginServerThread.SessionKey;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -54,9 +53,10 @@ public final class AuthLogin implements IClientIncomingPacket
|
||||
{
|
||||
if (_loginName.isEmpty() || !client.isProtocolOk())
|
||||
{
|
||||
client.close((IClientOutgoingPacket) null);
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
final SessionKey key = new SessionKey(_loginKey1, _loginKey2, _playKey1, _playKey2);
|
||||
|
||||
// avoid potential exploits
|
||||
@ -70,7 +70,7 @@ public final class AuthLogin implements IClientIncomingPacket
|
||||
}
|
||||
else
|
||||
{
|
||||
client.close((IClientOutgoingPacket) null);
|
||||
client.close(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.quest.State;
|
||||
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;
|
||||
@ -58,7 +59,7 @@ import com.l2jmobius.gameserver.util.Util;
|
||||
@SuppressWarnings("unused")
|
||||
public final class CharacterCreate implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
// cSdddddddddddd
|
||||
private String _name;
|
||||
@ -104,7 +105,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.FORBIDDEN_NAMES.length > 1)
|
||||
if (Config.FORBIDDEN_NAMES.length > 0)
|
||||
{
|
||||
for (String st : Config.FORBIDDEN_NAMES)
|
||||
{
|
||||
@ -191,7 +192,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
newChar,
|
||||
client
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
}
|
||||
|
||||
private boolean isValidName(String text)
|
||||
@ -219,7 +220,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
|
||||
private void initNewChar(L2GameClient client, L2PcInstance newChar)
|
||||
{
|
||||
L2World.getInstance().storeObject(newChar);
|
||||
L2World.getInstance().addObject(newChar);
|
||||
|
||||
if (Config.STARTING_ADENA > 0)
|
||||
{
|
||||
@ -238,7 +239,6 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
final Location createLoc = template.getCreationPoint();
|
||||
newChar.setXYZInvisible(createLoc.getX(), createLoc.getY(), createLoc.getZ());
|
||||
}
|
||||
|
||||
newChar.setTitle("");
|
||||
|
||||
if (Config.ENABLE_VITALITY)
|
||||
@ -289,7 +289,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
EventDispatcher.getInstance().notifyEvent(new OnPlayerCreate(newChar, newChar.getObjectId(), newChar.getName(), client), Containers.Players());
|
||||
|
||||
newChar.setOnlineStatus(true, false);
|
||||
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());
|
||||
|
@ -27,7 +27,6 @@ import com.l2jmobius.gameserver.data.xml.impl.SecondaryAuthData;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.PunishmentManager;
|
||||
import com.l2jmobius.gameserver.model.CharSelectInfoPackage;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.Containers;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
@ -36,6 +35,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;
|
||||
@ -48,7 +48,7 @@ import com.l2jmobius.gameserver.network.serverpackets.ServerClose;
|
||||
*/
|
||||
public class CharacterSelect implements IClientIncomingPacket
|
||||
{
|
||||
protected static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
// cd
|
||||
private int _charSlot;
|
||||
@ -127,12 +127,12 @@ 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
|
||||
}
|
||||
L2World.getInstance().addPlayerToWorld(cha);
|
||||
|
||||
CharNameTable.getInstance().addName(cha);
|
||||
|
||||
cha.setClient(client);
|
||||
@ -142,15 +142,14 @@ 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;
|
||||
}
|
||||
|
||||
client.sendPacket(new SSQInfo());
|
||||
|
||||
client.setConnectionState(ConnectionState.IN_GAME);
|
||||
final CharSelected cs = new CharSelected(cha, client.getSessionId().playOkID1);
|
||||
client.sendPacket(cs);
|
||||
client.sendPacket(new CharSelected(cha, client.getSessionId().playOkID1));
|
||||
}
|
||||
}
|
||||
finally
|
||||
@ -163,7 +162,7 @@ public class CharacterSelect implements IClientIncomingPacket
|
||||
{
|
||||
client
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.skills.CommonSkill;
|
||||
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.ActionFailed;
|
||||
@ -129,7 +130,7 @@ public class EnterWorld implements IClientIncomingPacket
|
||||
if (activeChar == null)
|
||||
{
|
||||
_log.warning("EnterWorld failed! activeChar returned 'null'.");
|
||||
client.closeNow();
|
||||
Disconnection.of(client).defaultSequence(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,13 @@ import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.SevenSignsFestival;
|
||||
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.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
import com.l2jmobius.gameserver.util.OfflineTradeUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -37,7 +39,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)
|
||||
@ -51,6 +53,7 @@ public final class Logout implements IClientIncomingPacket
|
||||
final L2PcInstance player = client.getActiveChar();
|
||||
if (player == null)
|
||||
{
|
||||
client.closeNow();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -113,8 +116,11 @@ public final class Logout implements IClientIncomingPacket
|
||||
{
|
||||
client
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
|
||||
player.logout();
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
Disconnection.of(client, player).defaultSequence(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import java.util.logging.Logger;
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.KeyPacket;
|
||||
|
||||
/**
|
||||
@ -32,7 +31,7 @@ import com.l2jmobius.gameserver.network.serverpackets.KeyPacket;
|
||||
*/
|
||||
public final class ProtocolVersion implements IClientIncomingPacket
|
||||
{
|
||||
private static final Logger _logAccounting = Logger.getLogger("accounting");
|
||||
private static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
|
||||
|
||||
private int _version;
|
||||
|
||||
@ -50,7 +49,7 @@ public final class ProtocolVersion implements IClientIncomingPacket
|
||||
if (_version == -2)
|
||||
{
|
||||
// this is just a ping attempt from the new C2 client
|
||||
client.close((IClientOutgoingPacket) null);
|
||||
client.closeNow();
|
||||
}
|
||||
else if (!Config.PROTOCOL_LIST.contains(_version))
|
||||
{
|
||||
@ -60,7 +59,7 @@ public final class ProtocolVersion implements IClientIncomingPacket
|
||||
_version,
|
||||
client
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
final KeyPacket pk = new KeyPacket(client.enableCrypt(), 0);
|
||||
client.setProtocolOk(false);
|
||||
client.close(pk);
|
||||
|
@ -87,7 +87,7 @@ public final class RequestActionUse implements IClientIncomingPacket
|
||||
_ctrlPressed = (packet.readD() == 1);
|
||||
_shiftPressed = (packet.readC() == 1);
|
||||
_client = client;
|
||||
return (_actionId != 10) && (_actionId != 28);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,6 +40,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcManorBypass;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerBypass;
|
||||
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.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@ -89,7 +90,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;
|
||||
}
|
||||
|
||||
|
@ -24,15 +24,17 @@ import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.SevenSignsFestival;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.instancemanager.AntiFeedManager;
|
||||
import com.l2jmobius.gameserver.model.L2Party;
|
||||
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 ...
|
||||
@ -40,7 +42,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)
|
||||
@ -61,6 +63,7 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
if ((player.getActiveEnchantItemId() != L2PcInstance.ID_NONE) || (player.getActiveEnchantAttrItemId() != L2PcInstance.ID_NONE))
|
||||
{
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -68,12 +71,13 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
_log.warning("Player " + player.getName() + " tried to restart during class change.");
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getPrivateStoreType() != PrivateStoreType.NONE)
|
||||
{
|
||||
player.sendMessage("Cannot restart while trading");
|
||||
player.sendMessage("Cannot restart while trading.");
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
return;
|
||||
}
|
||||
@ -82,6 +86,7 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_RESTART_WHILE_IN_COMBAT);
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -94,6 +99,7 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
player.sendMessage("You cannot restart while you are a participant in a festival.");
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -108,6 +114,14 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
if (player.isBlockedFromExit())
|
||||
{
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.canLogout())
|
||||
{
|
||||
client.sendPacket(RestartResponse.valueOf(false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -119,15 +133,12 @@ public final class RequestRestart implements IClientIncomingPacket
|
||||
{
|
||||
client
|
||||
});
|
||||
_logAccounting.log(record);
|
||||
LOG_ACCOUNTING.log(record);
|
||||
|
||||
// detach the client from the char so that the connection isnt closed in the deleteMe
|
||||
player.setClient(null);
|
||||
|
||||
player.deleteMe();
|
||||
|
||||
client.setActiveChar(null);
|
||||
AntiFeedManager.getInstance().onDisconnect(client);
|
||||
if (!OfflineTradeUtil.enteredOfflineMode(player))
|
||||
{
|
||||
Disconnection.of(client, player).storeMe().deleteMe();
|
||||
}
|
||||
|
||||
// return the client to the authed status
|
||||
client.setConnectionState(ConnectionState.AUTHENTICATED);
|
||||
|
@ -33,6 +33,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
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.network.Disconnection;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
@ -112,7 +113,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;
|
||||
}
|
||||
|
||||
@ -120,7 +121,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;
|
||||
}
|
||||
|
||||
@ -231,7 +232,14 @@ public class SecondaryPasswordAuth
|
||||
|
||||
public void openDialog()
|
||||
{
|
||||
_activeClient.sendPacket(passwordExist() ? new Ex2ndPasswordCheck(Ex2ndPasswordCheck.PASSWORD_PROMPT) : new Ex2ndPasswordCheck(Ex2ndPasswordCheck.PASSWORD_NEW));
|
||||
if (passwordExist())
|
||||
{
|
||||
_activeClient.sendPacket(new Ex2ndPasswordCheck(Ex2ndPasswordCheck.PASSWORD_PROMPT));
|
||||
}
|
||||
else
|
||||
{
|
||||
_activeClient.sendPacket(new Ex2ndPasswordCheck(Ex2ndPasswordCheck.PASSWORD_NEW));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAuthed()
|
||||
@ -243,7 +251,10 @@ public class SecondaryPasswordAuth
|
||||
{
|
||||
try
|
||||
{
|
||||
return Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA").digest(password.getBytes("UTF-8")));
|
||||
final MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
final byte[] raw = password.getBytes("UTF-8");
|
||||
final byte[] hash = md.digest(raw);
|
||||
return Base64.getEncoder().encodeToString(hash);
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
@ -258,6 +269,16 @@ public class SecondaryPasswordAuth
|
||||
|
||||
private boolean validatePassword(String password)
|
||||
{
|
||||
return Util.isDigit(password) && (password.length() >= 6) && (password.length() <= 8) && !SecondaryAuthData.getInstance().isForbiddenPassword(password);
|
||||
if (!Util.isDigit(password))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((password.length() < 6) || (password.length() > 8))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !SecondaryAuthData.getInstance().isForbiddenPassword(password);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.taskmanager;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -37,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.
|
||||
*/
|
||||
@ -74,15 +77,14 @@ public class AttackStanceTaskManager
|
||||
*/
|
||||
public void removeAttackStanceTask(L2Character actor)
|
||||
{
|
||||
if (actor == null)
|
||||
if (actor != null)
|
||||
{
|
||||
return;
|
||||
if (actor.isSummon())
|
||||
{
|
||||
actor = actor.getActingPlayer();
|
||||
}
|
||||
_attackStanceTasks.remove(actor);
|
||||
}
|
||||
if (actor.isSummon())
|
||||
{
|
||||
actor = actor.getActingPlayer();
|
||||
}
|
||||
_attackStanceTasks.remove(actor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,15 +94,15 @@ public class AttackStanceTaskManager
|
||||
*/
|
||||
public boolean hasAttackStanceTask(L2Character actor)
|
||||
{
|
||||
if (actor == null)
|
||||
if (actor != null)
|
||||
{
|
||||
return false;
|
||||
if (actor.isSummon())
|
||||
{
|
||||
actor = actor.getActingPlayer();
|
||||
}
|
||||
return _attackStanceTasks.containsKey(actor);
|
||||
}
|
||||
if (actor.isSummon())
|
||||
{
|
||||
actor = actor.getActingPlayer();
|
||||
}
|
||||
return _attackStanceTasks.containsKey(actor);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected class FightModeScheduler implements Runnable
|
||||
@ -111,10 +113,13 @@ public class AttackStanceTaskManager
|
||||
final long current = System.currentTimeMillis();
|
||||
try
|
||||
{
|
||||
final Iterator<Entry<L2Character, Long>> iter = _attackStanceTasks.entrySet().iterator();
|
||||
Entry<L2Character, Long> e;
|
||||
L2Character actor;
|
||||
for (Entry<L2Character, Long> e : _attackStanceTasks.entrySet())
|
||||
while (iter.hasNext())
|
||||
{
|
||||
if ((current - e.getValue()) > 15000)
|
||||
e = iter.next();
|
||||
if ((current - e.getValue()) > COMBAT_TIME)
|
||||
{
|
||||
actor = e.getKey();
|
||||
if (actor != null)
|
||||
@ -126,7 +131,7 @@ public class AttackStanceTaskManager
|
||||
actor.getSummon().broadcastPacket(new AutoAttackStop(actor.getSummon().getObjectId()));
|
||||
}
|
||||
}
|
||||
_attackStanceTasks.remove(e.getKey());
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
@ -139,14 +140,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.isLoggable(Level.WARNING))
|
||||
{
|
||||
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.getSummon();
|
||||
if (pet != null)
|
||||
{
|
||||
pet.setRestoreSummon(true);
|
||||
|
||||
pet.unSummon(player);
|
||||
pet = player.getSummon();
|
||||
// Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
|
||||
if (pet != null)
|
||||
{
|
||||
pet.broadcastNpcInfo(0);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user