Disconnection class for HighFive.

This commit is contained in:
MobiusDev 2018-04-05 02:46:01 +00:00
parent d13c74be0e
commit abf364f1d0
39 changed files with 678 additions and 780 deletions

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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.");

View File

@ -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

View File

@ -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

View File

@ -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.";

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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))

View File

@ -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;
}

View File

@ -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))
{

View File

@ -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);

View File

@ -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

View File

@ -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.");
}
/**

View File

@ -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())
{

View File

@ -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;

View File

@ -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:

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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());

View File

@ -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());

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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))
{

View File

@ -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;
}
}