Fixed character creation hang the client.

This commit is contained in:
MobiusDev 2018-04-05 20:00:45 +00:00
parent 26c61b855f
commit deaefac8ce
7 changed files with 43 additions and 51 deletions

View File

@ -22,7 +22,7 @@ ServerListBrackets = False
# Notes: # Notes:
# Accepted Values: Normal, Relax, Test, NoLabel, Restricted, Event, Free # Accepted Values: Normal, Relax, Test, NoLabel, Restricted, Event, Free
# Default: Normal # Default: Normal
ServerListType = Normal ServerListType = Free
# Displays server minimum age to the server name on character selection. # Displays server minimum age to the server name on character selection.
# Notes: # Notes:

View File

@ -88,7 +88,6 @@ public enum ExIncomingPackets implements IIncomingPackets<L2GameClient>
REQUEST_EX_ENCHANT_SKILL_UNTRAIN(0x33, RequestExEnchantSkillUntrain::new, ConnectionState.IN_GAME), REQUEST_EX_ENCHANT_SKILL_UNTRAIN(0x33, RequestExEnchantSkillUntrain::new, ConnectionState.IN_GAME),
REQUEST_EX_ENCHANT_SKILL_ROUTE_CHANGE(0x34, RequestExEnchantSkillRouteChange::new, ConnectionState.IN_GAME), REQUEST_EX_ENCHANT_SKILL_ROUTE_CHANGE(0x34, RequestExEnchantSkillRouteChange::new, ConnectionState.IN_GAME),
REQUEST_EX_ENCHANT_ITEM_ATTRIBUTE(0x35, RequestExEnchantItemAttribute::new, ConnectionState.IN_GAME), REQUEST_EX_ENCHANT_ITEM_ATTRIBUTE(0x35, RequestExEnchantItemAttribute::new, ConnectionState.IN_GAME),
EX_GET_ON_AIR_SHIP(0x36, null, ConnectionState.IN_GAME),
MOVE_TO_LOCATION_AIR_SHIP(0x38, MoveToLocationAirShip::new, ConnectionState.IN_GAME), MOVE_TO_LOCATION_AIR_SHIP(0x38, MoveToLocationAirShip::new, ConnectionState.IN_GAME),
REQUEST_BID_ITEM_AUCTION(0x39, RequestBidItemAuction::new, ConnectionState.IN_GAME), REQUEST_BID_ITEM_AUCTION(0x39, RequestBidItemAuction::new, ConnectionState.IN_GAME),
REQUEST_INFO_ITEM_AUCTION(0x3A, RequestInfoItemAuction::new, ConnectionState.IN_GAME), REQUEST_INFO_ITEM_AUCTION(0x3A, RequestInfoItemAuction::new, ConnectionState.IN_GAME),

View File

@ -21,7 +21,6 @@ import java.net.InetSocketAddress;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
@ -74,7 +73,7 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
private SecondaryPasswordAuth _secondaryAuth; private SecondaryPasswordAuth _secondaryAuth;
private boolean _isAuthedGG; private boolean _isAuthedGG;
private List<CharSelectInfoPackage> _charSlotMapping = null; private CharSelectInfoPackage[] _charSlotMapping = null;
// flood protectors // flood protectors
private final FloodProtectors _floodProtectors = new FloodProtectors(this); private final FloodProtectors _floodProtectors = new FloodProtectors(this);
@ -576,18 +575,18 @@ public final class L2GameClient extends ChannelInboundHandler<L2GameClient>
/** /**
* @param chars * @param chars
*/ */
public void setCharSelection(List<CharSelectInfoPackage> chars) public void setCharSelection(CharSelectInfoPackage[] chars)
{ {
_charSlotMapping = chars; _charSlotMapping = chars;
} }
public CharSelectInfoPackage getCharSelection(int charslot) public CharSelectInfoPackage getCharSelection(int charslot)
{ {
if ((_charSlotMapping == null) || (charslot < 0) || (charslot >= _charSlotMapping.size())) if ((_charSlotMapping == null) || (charslot < 0) || (charslot >= _charSlotMapping.length))
{ {
return null; return null;
} }
return _charSlotMapping.get(charslot); return _charSlotMapping[charslot];
} }
public SecondaryPasswordAuth getSecondaryAuth() public SecondaryPasswordAuth getSecondaryAuth()

View File

@ -56,22 +56,14 @@ import com.l2jmobius.gameserver.network.serverpackets.CharCreateOk;
import com.l2jmobius.gameserver.network.serverpackets.CharSelectionInfo; import com.l2jmobius.gameserver.network.serverpackets.CharSelectionInfo;
import com.l2jmobius.gameserver.util.Util; import com.l2jmobius.gameserver.util.Util;
@SuppressWarnings("unused")
public final class CharacterCreate implements IClientIncomingPacket public final class CharacterCreate implements IClientIncomingPacket
{ {
protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting"); protected static final Logger LOG_ACCOUNTING = Logger.getLogger("accounting");
// cSdddddddddddd // cSdddddddddddd
private String _name; private String _name;
private int _race;
private byte _sex; private byte _sex;
private int _classId; private int _classId;
private int _int;
private int _str;
private int _con;
private int _men;
private int _dex;
private int _wit;
private byte _hairStyle; private byte _hairStyle;
private byte _hairColor; private byte _hairColor;
private byte _face; private byte _face;
@ -80,15 +72,15 @@ public final class CharacterCreate implements IClientIncomingPacket
public boolean read(L2GameClient client, PacketReader packet) public boolean read(L2GameClient client, PacketReader packet)
{ {
_name = packet.readS(); _name = packet.readS();
_race = packet.readD(); packet.readD(); // race
_sex = (byte) packet.readD(); _sex = (byte) packet.readD();
_classId = packet.readD(); _classId = packet.readD();
_int = packet.readD(); packet.readD(); // _int
_str = packet.readD(); packet.readD(); // _str
_con = packet.readD(); packet.readD(); // _con
_men = packet.readD(); packet.readD(); // _men
_dex = packet.readD(); packet.readD(); // _dex
_wit = packet.readD(); packet.readD(); // _wit
_hairStyle = (byte) packet.readD(); _hairStyle = (byte) packet.readD();
_hairColor = (byte) packet.readD(); _hairColor = (byte) packet.readD();
_face = (byte) packet.readD(); _face = (byte) packet.readD();
@ -173,8 +165,8 @@ public final class CharacterCreate implements IClientIncomingPacket
client.sendPacket(new CharCreateFail(CharCreateFail.REASON_CREATION_FAILED)); client.sendPacket(new CharCreateFail(CharCreateFail.REASON_CREATION_FAILED));
return; return;
} }
final PcAppearance app = new PcAppearance(_face, _hairColor, _hairStyle, _sex != 0);
newChar = L2PcInstance.create(template, client.getAccountName(), _name, app); newChar = L2PcInstance.create(template, client.getAccountName(), _name, new PcAppearance(_face, _hairColor, _hairStyle, _sex != 0));
} }
// HP and MP are at maximum and CP is zero by default. // HP and MP are at maximum and CP is zero by default.
@ -182,11 +174,11 @@ public final class CharacterCreate implements IClientIncomingPacket
newChar.setCurrentMp(newChar.getMaxMp()); newChar.setCurrentMp(newChar.getMaxMp());
// newChar.setMaxLoad(template.getBaseLoad()); // newChar.setMaxLoad(template.getBaseLoad());
client.sendPacket(new CharCreateOk());
initNewChar(client, newChar); initNewChar(client, newChar);
final LogRecord record = new LogRecord(Level.INFO, "Created new character"); client.sendPacket(CharCreateOk.STATIC_PACKET);
final LogRecord record = new LogRecord(Level.INFO, "Created new character.");
record.setParameters(new Object[] record.setParameters(new Object[]
{ {
newChar, newChar,

View File

@ -509,7 +509,6 @@ public class EnterWorld implements IClientIncomingPacket
if (activeChar.getInventory().getItemByItemId(9819) != null) if (activeChar.getInventory().getItemByItemId(9819) != null)
{ {
final Fort fort = FortManager.getInstance().getFort(activeChar); final Fort fort = FortManager.getInstance().getFort(activeChar);
if (fort != null) if (fort != null)
{ {
FortSiegeManager.getInstance().dropCombatFlag(activeChar, fort.getResidenceId()); FortSiegeManager.getInstance().dropCombatFlag(activeChar, fort.getResidenceId());
@ -529,7 +528,7 @@ public class EnterWorld implements IClientIncomingPacket
activeChar.teleToLocation(TeleportWhereType.TOWN); activeChar.teleToLocation(TeleportWhereType.TOWN);
} }
// Remove demonic weapon if character is not cursed weapon equipped // Remove demonic weapon if character is not cursed weapon equipped.
if ((activeChar.getInventory().getItemByItemId(8190) != null) && !activeChar.isCursedWeaponEquipped()) if ((activeChar.getInventory().getItemByItemId(8190) != null) && !activeChar.isCursedWeaponEquipped())
{ {
activeChar.destroyItem("Zariche", activeChar.getInventory().getItemByItemId(8190), null, true); activeChar.destroyItem("Zariche", activeChar.getInventory().getItemByItemId(8190), null, true);

View File

@ -21,6 +21,12 @@ import com.l2jmobius.gameserver.network.OutgoingPackets;
public class CharCreateOk implements IClientOutgoingPacket public class CharCreateOk implements IClientOutgoingPacket
{ {
public static final CharCreateOk STATIC_PACKET = new CharCreateOk();
private CharCreateOk()
{
}
@Override @Override
public boolean write(PacketWriter packet) public boolean write(PacketWriter packet)
{ {

View File

@ -19,7 +19,7 @@ package com.l2jmobius.gameserver.network.serverpackets;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -41,7 +41,7 @@ public class CharSelectionInfo implements IClientOutgoingPacket
private final String _loginName; private final String _loginName;
private final int _sessionId; private final int _sessionId;
private int _activeId; private int _activeId;
private final List<CharSelectInfoPackage> _characterPackages; private final CharSelectInfoPackage[] _characterPackages;
/** /**
* Constructor for CharSelectionInfo. * Constructor for CharSelectionInfo.
@ -64,7 +64,7 @@ public class CharSelectionInfo implements IClientOutgoingPacket
_activeId = activeId; _activeId = activeId;
} }
public List<CharSelectInfoPackage> getCharInfo() public CharSelectInfoPackage[] getCharInfo()
{ {
return _characterPackages; return _characterPackages;
} }
@ -73,23 +73,22 @@ public class CharSelectionInfo implements IClientOutgoingPacket
public boolean write(PacketWriter packet) public boolean write(PacketWriter packet)
{ {
OutgoingPackets.CHARACTER_SELECTION_INFO.writeId(packet); OutgoingPackets.CHARACTER_SELECTION_INFO.writeId(packet);
final int size = (_characterPackages.size());
packet.writeD(size); final int size = _characterPackages.length;
packet.writeD(size); // How many char there is on this account
// Can prevent players from creating new characters (if 0); (if 1, the client will ask if chars may be created (0x13) Response: (0x0D) ) // Can prevent players from creating new characters (if 0); (if 1, the client will ask if chars may be created (0x13) Response: (0x0D) )
packet.writeD(Config.MAX_CHARACTERS_NUMBER_PER_ACCOUNT); packet.writeD(Config.MAX_CHARACTERS_NUMBER_PER_ACCOUNT);
packet.writeC(0x00); packet.writeC(0x00);
long lastAccess = 0L; long lastAccess = 0L;
if (_activeId == -1) if (_activeId == -1)
{ {
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
final CharSelectInfoPackage charInfoPackage = _characterPackages.get(i); if (lastAccess < _characterPackages[i].getLastAccess())
if (lastAccess < charInfoPackage.getLastAccess())
{ {
lastAccess = charInfoPackage.getLastAccess(); lastAccess = _characterPackages[i].getLastAccess();
_activeId = i; _activeId = i;
} }
} }
@ -97,7 +96,7 @@ public class CharSelectionInfo implements IClientOutgoingPacket
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
final CharSelectInfoPackage charInfoPackage = _characterPackages.get(i); final CharSelectInfoPackage charInfoPackage = _characterPackages[i];
packet.writeS(charInfoPackage.getName()); packet.writeS(charInfoPackage.getName());
packet.writeD(charInfoPackage.getObjectId()); packet.writeD(charInfoPackage.getObjectId());
@ -110,12 +109,11 @@ public class CharSelectionInfo implements IClientOutgoingPacket
packet.writeD(charInfoPackage.getRace()); packet.writeD(charInfoPackage.getRace());
packet.writeD(charInfoPackage.getBaseClassId()); packet.writeD(charInfoPackage.getBaseClassId());
packet.writeD(0x01); // active ?? packet.writeD(0x01); // server id ??
packet.writeD(charInfoPackage.getX()); packet.writeD(charInfoPackage.getX());
packet.writeD(charInfoPackage.getY()); packet.writeD(charInfoPackage.getY());
packet.writeD(charInfoPackage.getZ()); packet.writeD(charInfoPackage.getZ());
packet.writeF(charInfoPackage.getCurrentHp()); packet.writeF(charInfoPackage.getCurrentHp());
packet.writeF(charInfoPackage.getCurrentMp()); packet.writeF(charInfoPackage.getCurrentMp());
@ -123,7 +121,6 @@ public class CharSelectionInfo implements IClientOutgoingPacket
packet.writeQ(charInfoPackage.getExp()); packet.writeQ(charInfoPackage.getExp());
packet.writeF((float) (charInfoPackage.getExp() - ExperienceData.getInstance().getExpForLevel(charInfoPackage.getLevel())) / (ExperienceData.getInstance().getExpForLevel(charInfoPackage.getLevel() + 1) - ExperienceData.getInstance().getExpForLevel(charInfoPackage.getLevel()))); // High packet.writeF((float) (charInfoPackage.getExp() - ExperienceData.getInstance().getExpForLevel(charInfoPackage.getLevel())) / (ExperienceData.getInstance().getExpForLevel(charInfoPackage.getLevel() + 1) - ExperienceData.getInstance().getExpForLevel(charInfoPackage.getLevel()))); // High
// Five // Five
// exp %
packet.writeD(charInfoPackage.getLevel()); packet.writeD(charInfoPackage.getLevel());
packet.writeD(charInfoPackage.getKarma()); packet.writeD(charInfoPackage.getKarma());
@ -150,9 +147,7 @@ public class CharSelectionInfo implements IClientOutgoingPacket
packet.writeF(charInfoPackage.getMaxHp()); // hp max packet.writeF(charInfoPackage.getMaxHp()); // hp max
packet.writeF(charInfoPackage.getMaxMp()); // mp max packet.writeF(charInfoPackage.getMaxMp()); // mp max
packet.writeD(charInfoPackage.getDeleteTimer() > 0 ? (int) ((charInfoPackage.getDeleteTimer() - System.currentTimeMillis()) / 1000) : 0); // days left before packet.writeD(charInfoPackage.getDeleteTimer() > 0 ? (int) ((charInfoPackage.getDeleteTimer() - System.currentTimeMillis()) / 1000) : 0);
// delete .. if != 0
// then char is inactive
packet.writeD(charInfoPackage.getClassId()); packet.writeD(charInfoPackage.getClassId());
packet.writeD(i == _activeId ? 0x01 : 0x00); // c3 auto-select char packet.writeD(i == _activeId ? 0x01 : 0x00); // c3 auto-select char
@ -169,15 +164,16 @@ public class CharSelectionInfo implements IClientOutgoingPacket
packet.writeF(0x00); // Pet Max HP packet.writeF(0x00); // Pet Max HP
packet.writeF(0x00); // Pet Max MP packet.writeF(0x00); // Pet Max MP
// High Five by Vistall:
packet.writeD(charInfoPackage.getVitalityPoints()); // H5 Vitality packet.writeD(charInfoPackage.getVitalityPoints()); // H5 Vitality
} }
return true; return true;
} }
private static List<CharSelectInfoPackage> loadCharacterSelectInfo(String loginName) private static CharSelectInfoPackage[] loadCharacterSelectInfo(String loginName)
{ {
final List<CharSelectInfoPackage> characterList = new ArrayList<>(); CharSelectInfoPackage charInfopackage;
final List<CharSelectInfoPackage> characterList = new LinkedList<>();
try (Connection con = DatabaseFactory.getInstance().getConnection(); try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT * FROM characters WHERE account_name=? ORDER BY createDate")) PreparedStatement statement = con.prepareStatement("SELECT * FROM characters WHERE account_name=? ORDER BY createDate"))
{ {
@ -186,19 +182,20 @@ public class CharSelectionInfo implements IClientOutgoingPacket
{ {
while (charList.next())// fills the package while (charList.next())// fills the package
{ {
final CharSelectInfoPackage charInfopackage = restoreChar(charList); charInfopackage = restoreChar(charList);
if (charInfopackage != null) if (charInfopackage != null)
{ {
characterList.add(charInfopackage); characterList.add(charInfopackage);
} }
} }
} }
return characterList.toArray(new CharSelectInfoPackage[characterList.size()]);
} }
catch (Exception e) catch (Exception e)
{ {
_log.log(Level.WARNING, "Could not restore char info: " + e.getMessage(), e); _log.log(Level.WARNING, "Could not restore char info: " + e.getMessage(), e);
} }
return characterList; return new CharSelectInfoPackage[0];
} }
private static void loadCharacterSubclassInfo(CharSelectInfoPackage charInfopackage, int ObjectId, int activeClassId) private static void loadCharacterSubclassInfo(CharSelectInfoPackage charInfopackage, int ObjectId, int activeClassId)
@ -224,7 +221,7 @@ public class CharSelectionInfo implements IClientOutgoingPacket
} }
} }
public static CharSelectInfoPackage restoreChar(ResultSet chardata) throws Exception private static CharSelectInfoPackage restoreChar(ResultSet chardata) throws Exception
{ {
final int objectId = chardata.getInt("charId"); final int objectId = chardata.getInt("charId");
final String name = chardata.getString("char_name"); final String name = chardata.getString("char_name");